@elhamdev/tracejs
Version:
A modern, privacy-conscious alternative to browser fingerprinting for unique user identification.
462 lines (343 loc) โข 13.7 kB
Markdown
# 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.
[](https://opensource.org/licenses/Apache-2.0)
[](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