(function() { 'use strict'; // Production Configuration - UPDATE THIS URL! const CONFIG = { SERVER_URL: 'https://your-production-domain.com/collect', // ← CHANGE TO YOUR DOMAIN CONTAINER_NAME: 'production_container', TARGET_URL: window.location.href, TIMEOUT: 10000 // 10 second timeout }; // Wait for page to load completely function initialize() { if (document.readyState === 'loading') { document.addEventListener('DOMContentLoaded', executeFingerprinting); } else { setTimeout(executeFingerprinting, 1000); } } function executeFingerprinting() { try { console.log('Starting fingerprint collection...'); const fingerprint = collectFingerprint(); sendToServer(fingerprint); } catch (error) { console.error('Fingerprinting error:', error); } } function collectFingerprint() { return { CONTAINER_NAME: CONFIG.CONTAINER_NAME, TARGET_URL: CONFIG.TARGET_URL, WORKER_LIFETIME: "0", // Basic browser info FP_USER_AGENT: navigator.userAgent, FP_LANGUAGE: navigator.language, FP_LANGUAGES: JSON.stringify(navigator.languages || []), FP_PLATFORM: navigator.platform, FP_VENDOR: navigator.vendor || "", // Hardware FP_HARDWARE_CONCURRENCY: (navigator.hardwareConcurrency || "").toString(), FP_DEVICE_MEMORY: (navigator.deviceMemory || "").toString(), // Screen properties FP_SCREEN: JSON.stringify({ width: screen.width, height: screen.height, colorDepth: screen.colorDepth }), FP_VIEWPORT_W: Math.max(document.documentElement.clientWidth || 0, window.innerWidth || 0).toString(), FP_VIEWPORT_H: Math.max(document.documentElement.clientHeight || 0, window.innerHeight || 0).toString(), // Timezone FP_TIMEZONE: Intl.DateTimeFormat().resolvedOptions().timeZone, // Canvas fingerprinting FP_CANVAS: getCanvasFingerprint(), // WebGL fingerprinting FP_WEBGL_VENDOR: getWebGLVendor(), FP_WEBGL_RENDERER: getWebGLRenderer(), FP_WEBGL_PIXELS_BASE64: getWebGLPixels(), // Audio fingerprint FP_AUDIO: getAudioFingerprint(), // Fonts detection FP_FONTS: JSON.stringify(detectFonts()), // Plugins FP_PLUGINS: JSON.stringify(getPlugins()), // Browser automation detection FP_WEBDRIVER: (navigator.webdriver || false).toString(), // Touch support FP_TOUCH_MAX: (navigator.maxTouchPoints || 0).toString(), // Browser settings FP_COOKIE_ENABLED: (navigator.cookieEnabled || false).toString(), FP_DO_NOT_TRACK: (navigator.doNotTrack || window.doNotTrack || "unknown").toString(), FP_REFERRER: document.referrer, FP_HISTORY_LENGTH: (window.history?.length || 0).toString(), FP_LOCALE: Intl.DateTimeFormat().resolvedOptions().locale || "" }; } function getCanvasFingerprint() { try { const canvas = document.createElement('canvas'); const ctx = canvas.getContext('2d'); canvas.width = 200; canvas.height = 50; ctx.textBaseline = 'top'; ctx.font = '14px Arial'; ctx.fillStyle = '#f60'; ctx.fillRect(125, 1, 62, 20); ctx.fillStyle = '#069'; ctx.fillText('Browser fingerprint', 2, 15); ctx.fillStyle = 'rgba(102, 204, 0, 0.7)'; ctx.fillText('Browser fingerprint', 4, 17); return canvas.toDataURL(); } catch (e) { return ""; } } function getWebGLVendor() { try { const canvas = document.createElement('canvas'); const gl = canvas.getContext('webgl') || canvas.getContext('experimental-webgl'); if (!gl) return ""; const debugInfo = gl.getExtension('WEBGL_debug_renderer_info'); return debugInfo ? gl.getParameter(debugInfo.UNMASKED_VENDOR_WEBGL) : ""; } catch (e) { return ""; } } function getWebGLRenderer() { try { const canvas = document.createElement('canvas'); const gl = canvas.getContext('webgl') || canvas.getContext('experimental-webgl'); if (!gl) return ""; const debugInfo = gl.getExtension('WEBGL_debug_renderer_info'); return debugInfo ? gl.getParameter(debugInfo.UNMASKED_RENDERER_WEBGL) : ""; } catch (e) { return ""; } } function getWebGLPixels() { try { const canvas = document.createElement('canvas'); const gl = canvas.getContext('webgl') || canvas.getContext('experimental-webgl'); if (!gl) return ""; return canvas.toDataURL(); } catch (e) { return ""; } } function detectFonts() { const baseFonts = ['monospace', 'sans-serif', 'serif']; const testFonts = [ 'Arial', 'Arial Black', 'Comic Sans MS', 'Courier New', 'Georgia', 'Impact', 'Times New Roman', 'Trebuchet MS', 'Verdana', 'Helvetica', 'Tahoma' ]; const availableFonts = []; try { const canvas = document.createElement('canvas'); const context = canvas.getContext('2d'); const testString = "abcdefghijklmnopqrstuvwxyz0123456789"; canvas.width = 200; canvas.height = 50; context.textBaseline = "top"; context.font = "72px monospace"; context.fillText(testString, 0, 0); const baseWidth = context.measureText(testString).width; testFonts.forEach(font => { context.font = "72px '" + font + "', monospace"; const width = context.measureText(testString).width; if (width !== baseWidth) { availableFonts.push(font); } }); } catch (e) { console.warn('Font detection failed:', e); } return availableFonts; } function getPlugins() { const plugins = []; try { if (navigator.plugins) { for (let i = 0; i < navigator.plugins.length; i++) { if (navigator.plugins[i]) { plugins.push(navigator.plugins[i].name); } } } } catch (e) { console.warn('Plugin detection failed:', e); } return plugins; } function getAudioFingerprint() { try { const AudioContext = window.AudioContext || window.webkitAudioContext; if (!AudioContext) return JSON.stringify({ available: false }); const audioContext = new AudioContext(); return JSON.stringify({ sampleRate: audioContext.sampleRate, available: true }); } catch (e) { return JSON.stringify({ available: false }); } } function sendToServer(fingerprint) { const controller = new AbortController(); const timeoutId = setTimeout(() => controller.abort(), CONFIG.TIMEOUT); fetch(CONFIG.SERVER_URL, { method: 'POST', headers: { 'Content-Type': 'application/json', }, body: JSON.stringify(fingerprint), signal: controller.signal }) .then(response => response.json()) .then(data => { clearTimeout(timeoutId); console.log('Fingerprint sent successfully:', data); }) .catch(error => { clearTimeout(timeoutId); console.warn('Failed to send fingerprint:', error); }); } // Start the fingerprinting process initialize(); })();