66 lines
1.7 KiB
JavaScript
66 lines
1.7 KiB
JavaScript
async function sha256Hex(value) {
|
|
if (!window.crypto?.subtle) {
|
|
return ''
|
|
}
|
|
|
|
const encoded = new TextEncoder().encode(value)
|
|
const digest = await window.crypto.subtle.digest('SHA-256', encoded)
|
|
return Array.from(new Uint8Array(digest))
|
|
.map((part) => part.toString(16).padStart(2, '0'))
|
|
.join('')
|
|
}
|
|
|
|
function readWebglVendor() {
|
|
try {
|
|
const canvas = document.createElement('canvas')
|
|
const gl = canvas.getContext('webgl') || canvas.getContext('experimental-webgl')
|
|
if (!gl) {
|
|
return 'no-webgl'
|
|
}
|
|
|
|
const extension = gl.getExtension('WEBGL_debug_renderer_info')
|
|
if (!extension) {
|
|
return 'webgl-hidden'
|
|
}
|
|
|
|
return [
|
|
gl.getParameter(extension.UNMASKED_VENDOR_WEBGL),
|
|
gl.getParameter(extension.UNMASKED_RENDERER_WEBGL),
|
|
].join(':')
|
|
} catch {
|
|
return 'webgl-error'
|
|
}
|
|
}
|
|
|
|
export async function buildBotFingerprint() {
|
|
const timezone = Intl.DateTimeFormat().resolvedOptions().timeZone || 'unknown'
|
|
const screenSize = typeof window.screen !== 'undefined'
|
|
? `${window.screen.width}x${window.screen.height}x${window.devicePixelRatio || 1}`
|
|
: 'no-screen'
|
|
|
|
const payload = [
|
|
navigator.userAgent || 'unknown-ua',
|
|
navigator.language || 'unknown-language',
|
|
navigator.platform || 'unknown-platform',
|
|
timezone,
|
|
screenSize,
|
|
readWebglVendor(),
|
|
].join('|')
|
|
|
|
return sha256Hex(payload)
|
|
}
|
|
|
|
export async function populateBotFingerprint(form) {
|
|
if (!form) {
|
|
return ''
|
|
}
|
|
|
|
const fingerprint = await buildBotFingerprint()
|
|
const field = form.querySelector('input[name="_bot_fingerprint"]')
|
|
if (field && fingerprint !== '') {
|
|
field.value = fingerprint
|
|
}
|
|
|
|
return fingerprint
|
|
}
|