UNPKG

@elhamdev/tracejs

Version:

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

462 lines (343 loc) โ€ข 13.7 kB
# TraceJS A modern, privacy-conscious alternative to browser fingerprinting for unique user identification. TraceJS provides a robust and ethical approach to device identification while respecting user privacy. [![License](https://img.shields.io/badge/license-Apache--2.0-blue.svg)](https://opensource.org/licenses/Apache-2.0) [![npm version](https://badge.fury.io/js/@elhamdev/tracejs.svg)](https://badge.fury.io/js/@elhamdev/tracejs) ## Features - ๐Ÿ”’ Privacy-focused device identification - ๐ŸŽจ Advanced canvas fingerprinting - ๐Ÿ–ฅ๏ธ Hardware-specific characteristics detection - ๐ŸŒ Browser and OS information gathering - ๐ŸŽต Audio capabilities fingerprinting - ๐Ÿ“Š Detailed fingerprint strength scoring - ๐Ÿงช Real-time entropy analysis - ๐Ÿ” Behavioral fingerprinting - ๐Ÿ“ฑ Cross-browser compatibility - ๐Ÿ›ก๏ธ GDPR/CCPA compliant consent management - โšก Asynchronous and performant - ๐Ÿ“– TypeScript support - ๐Ÿ”„ **Consistent fingerprinting** for authentication workflows - ๐Ÿ’พ Smart caching system for stable identification ## Installation Install TraceJS using npm: ```bash npm install @elhamdev/tracejs ``` Or using yarn: ```bash yarn add @elhamdev/tracejs ``` ## Usage ### Basic Usage ```typescript import { FingerprintService } from 'tracejs'; // Initialize the fingerprint service const fingerprintService = new FingerprintService(); // Generate a simple fingerprint const fingerprint = await fingerprintService.generateFingerprint(); console.log('Device Fingerprint:', fingerprint); // Get detailed fingerprint information const detailedFingerprint = await fingerprintService.getDetailedFingerprint(); console.log('Detailed Information:', detailedFingerprint); ``` ### Configuration Options You can customize the fingerprinting process by passing options to the constructor: ```typescript const options = { battery: false, // Disable battery fingerprinting screen: false // Disable screen fingerprinting }; const fingerprintService = new FingerprintService(options); ``` ### Advanced Customization TraceJS now provides enhanced customization capabilities for specific fingerprinting modules. #### Battery Fingerprinting Options Control exactly which battery data is collected and how it's processed: ```typescript import { FingerprintService, BatteryOptions, BatteryData } from 'tracejs'; const batteryOptions: BatteryOptions = { // Select which properties to include (all true by default) includeCharging: true, includeLevel: true, includeChargingTime: true, includeDischargingTime: true, // Privacy enhancement - round battery level to nearest 10% anonymizeLevel: true, // Enable real-time battery status tracking trackStatusChanges: true, // Optional callback for battery changes onBatteryChange: (batteryData: BatteryData) => { console.log('Battery status changed:', batteryData); }, // Override the fingerprint strength score (optional) customStrengthScore: 5 }; const fingerprintService = new FingerprintService({ battery: batteryOptions }); // Alternatively, you can listen for battery changes after initialization const removeListener = fingerprintService.onBatteryChange((batteryData: BatteryData) => { console.log('Battery update:', batteryData); }); // Later, to stop listening: removeListener(); ``` #### Behavioral Fingerprinting TraceJS can now create fingerprints based on user behavior patterns, providing much stronger identification: ```typescript import { FingerprintService, BehaviorOptions, BehaviorProfile } from 'tracejs'; const behaviorOptions: BehaviorOptions = { // Enable specific tracking methods trackMouse: true, trackKeyboard: true, trackTouch: true, // Configure privacy level privacyMode: 'balanced', // 'minimal', 'balanced', or 'full' // Configure data collection sampleRate: 100, // milliseconds between samples trainingDuration: 10000, // how long to collect data before generating profile (ms) // Receive updates when profile is created onProfileUpdate: (profile: BehaviorProfile) => { console.log('User behavior profile updated:', profile); } }; const fingerprintService = new FingerprintService({ behavior: behaviorOptions }); // Or listen for profile updates separately const cleanup = fingerprintService.onBehaviorProfileUpdate((profile) => { console.log('New behavior profile:', profile); // Access specific metrics if (profile.mouse?.averageSpeed) { console.log('Mouse speed:', profile.mouse.averageSpeed); } if (profile.keyboard?.typingSpeed) { console.log('Typing speed:', profile.keyboard.typingSpeed); } }); // Call cleanup when done to remove event listeners cleanup(); ``` #### Entropy Analysis Assess the quality and uniqueness of your fingerprint: ```typescript import { FingerprintService } from 'tracejs'; const fingerprintService = new FingerprintService(); // Generate a fingerprint const fingerprint = await fingerprintService.generateFingerprint(); // Analyze its entropy and uniqueness const analysis = await fingerprintService.analyzeFingerprint(); console.log(`Entropy: ${analysis.entropyBits} bits`); console.log(`Quality: ${analysis.quality.rating}`); console.log(`Description: ${analysis.quality.description}`); // Adjust your fingerprinting methods based on the analysis if (analysis.entropyBits < 40) { console.log('Consider enabling additional fingerprinting methods for stronger identification'); } ``` #### Consistent Fingerprinting for Authentication TraceJS provides fingerprint consistency suitable for authentication workflows: ```typescript import { FingerprintService } from 'tracejs'; // Initialize the fingerprint service const fingerprintService = new FingerprintService(); // On user login, generate a fingerprint const loginFingerprint = await fingerprintService.generateFingerprint(); console.log('Login Fingerprint:', loginFingerprint); // Send to your backend along with credentials await loginUser(username, password, loginFingerprint); // Later, on the same device (even days/weeks later) // The fingerprint will remain consistent const logoutFingerprint = await fingerprintService.generateFingerprint(); console.log('Logout Fingerprint:', logoutFingerprint); // loginFingerprint === logoutFingerprint (unless hardware/browser changes significantly) // Use for logout authentication await logoutUser(sessionToken, logoutFingerprint); ``` How the consistency system works: - Fingerprints are cached locally for 30 days by default - Behavioral profiles remain stable between sessions - Hardware-specific characteristics provide long-term stability - Cache is safely invalidated if hardware or browser changes significantly - Origin-specific cache keys prevent cross-site tracking #### Consent Management Ensure GDPR, CCPA, and other privacy regulation compliance: ```typescript import { FingerprintService, ConsentOptions, ConsentCategory } from 'tracejs'; const consentOptions: ConsentOptions = { // Automatically detect user's region based on locale autoDetectRegion: true, // Map fingerprinting methods to consent categories categoryMapping: { battery: 'functionality', screen: 'functionality', canvas: 'analytics', audio: 'analytics', behavior: 'personalization' }, // Define required categories that don't need consent requiredCategories: ['essential'], // Get notifications when consent changes onConsentChange: (categories) => { console.log('Consent updated:', categories); } }; const fingerprintService = new FingerprintService({ battery: true, screen: true, behavior: true, consent: consentOptions }); // Get the consent manager to interact with it const consentManager = fingerprintService.getConsentManager(); // Check if consent has expired if (consentManager?.needsConsentRenewal()) { // Show consent UI to user showConsentForm(); } // Update consent when user makes choices function onUserConsentFormSubmit(choices) { consentManager?.updateMultipleConsent({ functionality: choices.includes('functionality'), analytics: choices.includes('analytics'), advertising: choices.includes('advertising'), personalization: choices.includes('personalization') }); } // Get current consent state const consentState = consentManager?.getConsentState(); console.log('Current consent:', consentState); ``` ## API Documentation ### FingerprintService #### Constructor ```typescript constructor(options: FingerprintOptions = {}) ``` Options: - `battery`: boolean | BatteryOptions (default: true) - Enable/disable battery fingerprinting or customize it - `screen`: boolean (default: true) - Enable/disable screen fingerprinting #### Methods ##### generateFingerprint() ```typescript async generateFingerprint(): Promise<string> ``` Returns a unique hash representing the device fingerprint. ##### getDetailedFingerprint() ```typescript async getDetailedFingerprint(): Promise<{ fingerprint: string; characteristics: Partial<BrowserCharacteristics>; strength: FingerprintStrength; }> ``` Returns detailed information about the fingerprint, including: - The fingerprint hash - Collected characteristics - Fingerprint strength assessment ##### onBatteryChange() ```typescript onBatteryChange(listener: (data: BatteryData) => void): (() => void) | null ``` Registers a listener for battery status changes. Returns a function to remove the listener, or null if battery fingerprinting is disabled. ### BatteryOptions Configure the battery fingerprinting module: ```typescript interface BatteryOptions { // Which battery properties to include in fingerprinting includeCharging?: boolean; // Include charging status includeLevel?: boolean; // Include battery level includeChargingTime?: boolean; // Include time until fully charged includeDischargingTime?: boolean; // Include time until battery depleted // Optional anonymization settings anonymizeLevel?: boolean; // Round battery level to nearest 10% // Event tracking options trackStatusChanges?: boolean; // Track battery status changes onBatteryChange?: (batteryData: BatteryData) => void; // Callback for changes // Custom strength scoring customStrengthScore?: number; // Override default strength score } // The BatteryData type provides a type-safe structure for battery information interface BatteryData { charging?: boolean; // Whether the device is charging level?: number; // Battery level between 0 and 1 chargingTime?: number; // Seconds until fully charged dischargingTime?: number; // Seconds until battery depleted } ``` ### BrowserCharacteristics The following characteristics may be collected: - `userAgent`: Browser user agent string - `language`: Browser language - `platform`: Operating system platform - `hardwareConcurrency`: Number of logical processors - `deviceMemory`: Amount of device memory - `timezone`: User's timezone - `touchPoints`: Maximum touch points - `gpuVendor`: GPU vendor information - `gpuRenderer`: GPU renderer information - `canvas`: Canvas fingerprint - `audio`: Audio capabilities - And more... ### Caching Utilities TraceJS provides utilities to maintain consistency in fingerprints: ```typescript // These are typically used internally, but can be accessed for custom implementations import { saveToCache, getFromCache, generateCacheKey } from 'tracejs/utils/cache'; // Generate a consistent cache key for your application const cacheKey = generateCacheKey('my_feature'); // Save data to the cache (persists for 30 days by default) saveToCache(cacheKey, { userData: 'example' }); // Retrieve cached data const cachedData = getFromCache(cacheKey); console.log(cachedData); // { userData: 'example' } or null if expired/not found // Retrieve with custom validity period (in milliseconds) const cachedDataWithCustomValidity = getFromCache(cacheKey, 60 * 60 * 1000); // 1 hour ``` ## Privacy Considerations TraceJS is designed with privacy in mind: - No personal data collection - No cross-site tracking - No persistent storage - Transparent fingerprinting methods - Compliant with privacy regulations ## Contributing We welcome contributions to TraceJS! Here's how you can help: 1. Fork the repository 2. Create your feature branch (`git checkout -b feature/amazing-feature`) 3. Install dependencies (`npm install`) 4. Make your changes 5. Run tests (`npm test`) 6. Ensure linting passes (`npm run lint`) 7. Commit your changes (`git commit -m 'Add amazing feature'`) 8. Push to the branch (`git push origin feature/amazing-feature`) 9. Open a Pull Request ### Development Setup ```bash # Clone the repository git clone https://github.com/ElhamDevelopmentStudio/tracejs.git # Install dependencies npm install # Build the project npm run build # Run tests npm test # Run linting npm run lint ``` ### Code Style - Follow TypeScript best practices - Use ESLint for code linting - Write comprehensive tests for new features - Document new functionality - Follow semantic versioning ## License This project is licensed under the Apache License 2.0 - see the [LICENSE](LICENSE) file for details. ## Author Elhamullah Hossaini ## Support - Report issues on [GitHub Issues](https://github.com/ElhamDevelopmentStudio/tracejs/issues) - For security issues, please email security@tracejs.com - Join our community discussions on [GitHub Discussions](https://github.com/ElhamDevelopmentStudio/tracejs/discussions) ## Acknowledgments - Thanks to all contributors who have helped shape TraceJS - Special thanks to the open-source community for their valuable feedback and contributions