UNPKG

@elhamdev/tracejs

Version:

A modern, privacy-conscious alternative to browser fingerprinting for unique user identification.

107 lines (106 loc) 3.94 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.StableFingerprint = void 0; const BaseFingerprint_1 = require("./BaseFingerprint"); class StableFingerprint extends BaseFingerprint_1.BaseFingerprint { async getCharacteristics() { try { const stableData = { // Browser/OS specific - doesn't change during session userAgent: navigator.userAgent, platform: navigator.platform, language: navigator.language, hardwareConcurrency: navigator.hardwareConcurrency, deviceMemory: navigator.deviceMemory, // Timezone - stable during session timezone: Intl.DateTimeFormat().resolvedOptions().timeZone, // Hardware capabilities - stable touchPoints: navigator.maxTouchPoints, // Screen properties that don't change with multiple monitors colorDepth: window.screen.colorDepth, pixelDepth: window.screen.pixelDepth, devicePixelRatio: window.devicePixelRatio, // WebGL information - hardware specific ...await this.getWebGLInfo(), // Audio capabilities - hardware specific ...await this.getAudioInfo(), // Canvas fingerprint - based on hardware rendering ...await this.getCanvasInfo() }; return stableData; } catch (e) { console.error('Stable fingerprinting failed:', e); return {}; } } async getWebGLInfo() { try { const canvas = document.createElement('canvas'); const gl = canvas.getContext('webgl') || canvas.getContext('experimental-webgl'); if (gl) { const debugInfo = gl.getExtension('WEBGL_debug_renderer_info'); if (debugInfo) { return { gpuVendor: gl.getParameter(debugInfo.UNMASKED_VENDOR_WEBGL), gpuRenderer: gl.getParameter(debugInfo.UNMASKED_RENDERER_WEBGL) }; } } } catch (e) { console.error('WebGL fingerprinting failed:', e); } return {}; } async getAudioInfo() { try { const audioContext = new (window.AudioContext || window.webkitAudioContext)(); const sampleRate = audioContext.sampleRate; audioContext.close(); return { audio: sampleRate.toString() }; } catch (e) { console.error('Audio fingerprinting failed:', e); return {}; } } async getCanvasInfo() { try { const canvas = document.createElement('canvas'); const ctx = canvas.getContext('2d'); if (!ctx) return {}; canvas.width = 200; canvas.height = 50; // Use a consistent drawing that depends on hardware rendering ctx.textBaseline = 'alphabetic'; ctx.fillStyle = '#f60'; ctx.fillRect(125, 1, 62, 20); ctx.fillStyle = '#069'; ctx.fillText('TraceJS!', 2, 15); ctx.fillStyle = 'rgba(102, 204, 0, 0.7)'; ctx.fillText('Stable', 4, 45); return { canvas: canvas.toDataURL() }; } catch (e) { console.error('Canvas fingerprinting failed:', e); return {}; } } getStrengthScore() { return { score: 10, details: [ 'Hardware-specific characteristics', 'Browser-specific information', 'Stable during session' ] }; } } exports.StableFingerprint = StableFingerprint;