Press n or j to go to the next uncovered block, b, p or k for the previous block.
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 | 2x 738x 738x 348x 390x 390x 6x 6x 6x 6x 6x 6x 6x 390x 390x 395x 738x 738x 395x 395x 6x 6x 6x 6x 6x | import { PatcherContext } from '../context'
import { SIGNALS_KEY } from '../../../../shared/const'
import { logger } from '../../../shared/logger'
const REMOVE_LISTENER_SYMBOL = Symbol('removeListener')
/**
* Patches a given HTML form to include additional fingerprinting signals during submission.
*
* @param {HTMLFormElement} form The form element to be patched.
* @param {PatcherContext} ctx The context used for retrieving signals and additional operations.
*/
export function injectSignalsElement(form: HTMLFormElement, ctx: PatcherContext) {
// Always remove the existing listener before adding a new one to prevent duplicates
removeSubmitListener(form)
if (!ctx.isProtectedUrl(form.action, form.method) || form.enctype === 'text/plain') {
return
}
Iif (form.method?.toLowerCase() === 'get') {
logger.warn('Forms with method "get" are currently not supported.')
return
}
const handleSubmit = async (event: SubmitEvent) => {
// Ignore form submissions if they were prevented by another handler (since this patcher is only for native submissions)
Iif (event.defaultPrevented) {
logger.debug('Form submission prevented by another handler')
return
}
const signals = await ctx.getSignals()
try {
Iif (!signals) {
logger.debug('No signals found for form submission')
return
}
// If signals are already present, we don't need to add them again
Iif (form.querySelector(`input[name="${SIGNALS_KEY}"]`)) {
return
}
const field = createSignalsField(signals)
form.appendChild(field)
} catch (e) {
logger.error('Error getting signals during form submission:', e)
}
}
form.addEventListener('submit', handleSubmit)
Object.assign(form, {
// Attach a custom property to the form element to store the remove listener function if needed.
[REMOVE_LISTENER_SYMBOL]: () => {
form.removeEventListener('submit', handleSubmit)
},
})
}
/**
* Removes a previously attached submit event listener from a given form element, if it exists.
*
* @param {HTMLFormElement & { [REMOVE_LISTENER_SYMBOL]?: () => void }} form - The form element from which the submit event listener is to be removed. It may include the custom property defined by REMOVE_LISTENER_SYMBOL.
*/
function removeSubmitListener(form: HTMLFormElement & { [REMOVE_LISTENER_SYMBOL]?: () => void }) {
const removeListener = form[REMOVE_LISTENER_SYMBOL]
if (typeof removeListener === 'function') {
logger.debug('Removing existing submit listener from form')
removeListener()
}
}
/**
* Creates a hidden input field with the specified signal value.
*
* @param {string} signals - The value to be assigned to the hidden input field.
* @return {HTMLInputElement} The created hidden input field with the specified signal value.
*/
function createSignalsField(signals: string): HTMLInputElement {
const field = document.createElement('input')
field.hidden = true
field.value = signals
field.name = SIGNALS_KEY
return field
}
|