@auralogiclabs/client-uuid-gen 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +209 -0
- package/dist/index.d.mts +63 -0
- package/dist/index.d.ts +63 -0
- package/dist/index.global.js +6875 -0
- package/dist/index.js +261 -0
- package/dist/index.mjs +223 -0
- package/package.json +53 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2025 Auralogic Labs
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,209 @@
|
|
|
1
|
+
# @auralogiclabs/client-uuid-gen
|
|
2
|
+
|
|
3
|
+
[](https://www.npmjs.com/package/@auralogiclabs/client-uuid-gen)
|
|
4
|
+
[](https://opensource.org/licenses/MIT)
|
|
5
|
+
[](https://bundlephobia.com/package/@auralogiclabs/client-uuid-gen)
|
|
6
|
+
[](https://www.typescriptlang.org/)
|
|
7
|
+
|
|
8
|
+
A robust, browser-based device UUID generator that creates unique fingerprints using multiple browser attributes including Canvas, WebGL, AudioContext, and LocalStorage estimates.
|
|
9
|
+
|
|
10
|
+
## Key Benefits
|
|
11
|
+
|
|
12
|
+
| Feature | Description |
|
|
13
|
+
| :--------------------- | :------------------------------------------------------------------------------------------------- |
|
|
14
|
+
| 🛡️ **Privacy-First** | Generates a hash, never stores raw PII. Cookies are NOT used. |
|
|
15
|
+
| 🕵️♂️ **Incognito-Proof** | **Stable Mode** (default) ensures the same Device ID is generated in Normal and Incognito windows. |
|
|
16
|
+
| 🚀 **High Entropy** | Combines 8+ hardware/software signals (Canvas, WebGL, Audio, Storage, etc.) for high uniqueness. |
|
|
17
|
+
| 📦 **Universal** | Works everywhere: Browser (ESM/IIFE), Node.js, and Bundlers (Webpack/Vite). |
|
|
18
|
+
| 💎 **TypeScript** | Written in TypeScript with full type definitions included. |
|
|
19
|
+
|
|
20
|
+
## Browser Support
|
|
21
|
+
|
|
22
|
+
| Browser | Version | Status |
|
|
23
|
+
| :---------------- | :------ | :----------- |
|
|
24
|
+
| **Chrome** | 60+ | ✅ Supported |
|
|
25
|
+
| **Firefox** | 60+ | ✅ Supported |
|
|
26
|
+
| **Safari** | 12+ | ✅ Supported |
|
|
27
|
+
| **Edge** | 79+ | ✅ Supported |
|
|
28
|
+
| **iOS / Android** | Modern | ✅ Supported |
|
|
29
|
+
|
|
30
|
+
## Installation
|
|
31
|
+
|
|
32
|
+
```bash
|
|
33
|
+
npm install @auralogiclabs/client-uuid-gen
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
## Usage
|
|
37
|
+
|
|
38
|
+
### Basic Usage (ES Modules / TypeScript)
|
|
39
|
+
|
|
40
|
+
```typescript
|
|
41
|
+
import { getFingerprint } from '@auralogiclabs/client-uuid-gen';
|
|
42
|
+
|
|
43
|
+
async function identifyDevice() {
|
|
44
|
+
try {
|
|
45
|
+
// Default: MD5 hash, Stable Mode enabled
|
|
46
|
+
const deviceId = await getFingerprint();
|
|
47
|
+
console.log('Device UUID (Stable):', deviceId);
|
|
48
|
+
|
|
49
|
+
// Option: SHA-256 hash (64 chars)
|
|
50
|
+
const deviceIdStrong = await getFingerprint({ algo: 'sha256' });
|
|
51
|
+
console.log('Device UUID (SHA-256):', deviceIdStrong);
|
|
52
|
+
} catch (error) {
|
|
53
|
+
console.error('Failed to generate fingerprint:', error);
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
### Stable Fingerprinting (Incognito Mode)
|
|
59
|
+
|
|
60
|
+
Browsers often intentionally alter fingerprinting data in Incognito/Private windows to prevent tracking (e.g., hiding real screen height, adding noise to audio signals).
|
|
61
|
+
|
|
62
|
+
**This library handles this automatically.**
|
|
63
|
+
|
|
64
|
+
#### Configuration: `enableStableFingerprinting`
|
|
65
|
+
|
|
66
|
+
- `true` (Default): Treats Normal and Incognito windows as the **SAME** user.
|
|
67
|
+
- _How?_ It neutralizes unstable components (e.g., ignores screen height, skips audio fingerprinting) to ensure the hash remains consistent.
|
|
68
|
+
- `false`: Treats Normal and Incognito windows as **DIFFERENT** users.
|
|
69
|
+
- _How?_ It uses all available data, which means the noise injected by the browser will cause the hash to change.
|
|
70
|
+
|
|
71
|
+
```typescript
|
|
72
|
+
// Treat Incognito as a unique/different user (Strict Mode)
|
|
73
|
+
const strictId = await getFingerprint({
|
|
74
|
+
enableStableFingerprinting: false,
|
|
75
|
+
});
|
|
76
|
+
|
|
77
|
+
// Treat Incognito as the same user (Stable Mode - Default)
|
|
78
|
+
const stableId = await getFingerprint({
|
|
79
|
+
enableStableFingerprinting: true,
|
|
80
|
+
});
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
### Advanced Usage (Class Access)
|
|
84
|
+
|
|
85
|
+
You can access the `EnhancedDeviceFingerprint` class directly to inspect individual components.
|
|
86
|
+
|
|
87
|
+
```typescript
|
|
88
|
+
import { EnhancedDeviceFingerprint } from '@auralogiclabs/client-uuid-gen';
|
|
89
|
+
|
|
90
|
+
async function fullAnalysis() {
|
|
91
|
+
const fingerprinter = new EnhancedDeviceFingerprint();
|
|
92
|
+
|
|
93
|
+
// 1. Generate the hash
|
|
94
|
+
const uuid = await fingerprinter.get();
|
|
95
|
+
console.log('UUID:', uuid);
|
|
96
|
+
|
|
97
|
+
// 2. Access internal components (populated after get/generateFingerprint)
|
|
98
|
+
console.log('Detailed Components:', fingerprinter.components);
|
|
99
|
+
/* Output example:
|
|
100
|
+
{
|
|
101
|
+
basic: { userAgent: "...", screenResolution: "1920x(Authored)", ... },
|
|
102
|
+
canvas: "data:image/png;base64,...",
|
|
103
|
+
webgl: "...",
|
|
104
|
+
audio: "audio-omitted-for-stability",
|
|
105
|
+
storage: "..."
|
|
106
|
+
}
|
|
107
|
+
*/
|
|
108
|
+
}
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
### Browser Usage (Script Tag)
|
|
112
|
+
|
|
113
|
+
For direct use in the browser without a bundler, use the global build.
|
|
114
|
+
|
|
115
|
+
```html
|
|
116
|
+
<!-- Load crypto-js dependency (standard hashing support) -->
|
|
117
|
+
<script src="https://cdnjs.cloudflare.com/ajax/libs/crypto-js/4.1.1/crypto-js.min.js"></script>
|
|
118
|
+
|
|
119
|
+
<!-- Load the library -->
|
|
120
|
+
<script src="https://unpkg.com/@auralogiclabs/client-uuid-gen/dist/index.global.js"></script>
|
|
121
|
+
|
|
122
|
+
<script>
|
|
123
|
+
const { getFingerprint } = window.ClientUUIDGen;
|
|
124
|
+
|
|
125
|
+
getFingerprint().then((uuid) => {
|
|
126
|
+
console.log('Generated UUID:', uuid);
|
|
127
|
+
});
|
|
128
|
+
</script>
|
|
129
|
+
```
|
|
130
|
+
|
|
131
|
+
## How It Works
|
|
132
|
+
|
|
133
|
+
This library generates a "fingerprint" by collecting stable characteristics of the user's browser environment:
|
|
134
|
+
|
|
135
|
+
1. **Basic Info:** User Agent, OS, Browser, Device Type, Language, Screen Resolution, Timezone.
|
|
136
|
+
2. **Canvas Fingerprinting:** Renders a hidden canvas with specific text and colors. Differences in graphics hardware produce unique data URLs.
|
|
137
|
+
3. **WebGL Fingerprinting:** Queries WebGL vendor and renderer information.
|
|
138
|
+
4. **Audio Fingerprinting:** Uses an OfflineAudioContext to render a specific oscillator tone. Differences in audio hardware/drivers produce unique signal processing results.
|
|
139
|
+
5. **Storage Fingerprinting:** Estimates available storage quota to bucket users (e.g., "fast device with lots of space" vs "budget device").
|
|
140
|
+
|
|
141
|
+
All these components are combined into a JSON string and hashed to produce a short, unique identifier.
|
|
142
|
+
|
|
143
|
+
## Privacy Note
|
|
144
|
+
|
|
145
|
+
Fingerprinting allows identification without cookies. Ensure you comply with **GDPR**, **CCPA**, and other privacy regulations.
|
|
146
|
+
|
|
147
|
+
- Inform users that device characteristics are being used for identification/fraud prevention.
|
|
148
|
+
- Obtain necessary consents if required in your jurisdiction.
|
|
149
|
+
|
|
150
|
+
## Development
|
|
151
|
+
|
|
152
|
+
### Prerequisites
|
|
153
|
+
|
|
154
|
+
- Node.js 18+
|
|
155
|
+
|
|
156
|
+
### Setup
|
|
157
|
+
|
|
158
|
+
```bash
|
|
159
|
+
git clone https://github.com/auralogiclabs/client-uuid-gen.git
|
|
160
|
+
cd client-uuid-gen
|
|
161
|
+
npm install
|
|
162
|
+
```
|
|
163
|
+
|
|
164
|
+
### Build
|
|
165
|
+
|
|
166
|
+
Generates `dist/` folder with CJS, ESM, and IIFE formats.
|
|
167
|
+
|
|
168
|
+
```bash
|
|
169
|
+
npm run build
|
|
170
|
+
```
|
|
171
|
+
|
|
172
|
+
### Test
|
|
173
|
+
|
|
174
|
+
Runs unit tests using Vitest.
|
|
175
|
+
|
|
176
|
+
```bash
|
|
177
|
+
npm test
|
|
178
|
+
```
|
|
179
|
+
|
|
180
|
+
### Lint & Format
|
|
181
|
+
|
|
182
|
+
```bash
|
|
183
|
+
npm run lint
|
|
184
|
+
npm run format
|
|
185
|
+
```
|
|
186
|
+
|
|
187
|
+
### Running Example
|
|
188
|
+
|
|
189
|
+
To run the example page locally:
|
|
190
|
+
|
|
191
|
+
> **Important:** Run the server from the **project root**, not inside the `examples/` folder. This ensures the browser can correct access the `dist/` folder.
|
|
192
|
+
|
|
193
|
+
```bash
|
|
194
|
+
# 1. Build the library first
|
|
195
|
+
npm run build
|
|
196
|
+
|
|
197
|
+
# 2. Serve from project root
|
|
198
|
+
npx serve .
|
|
199
|
+
|
|
200
|
+
# 3. Visit http://localhost:3000/examples/
|
|
201
|
+
```
|
|
202
|
+
|
|
203
|
+
| Example Output |
|
|
204
|
+
| :------------------------------------------------------------------: |
|
|
205
|
+
| <img src="assets/example.png" width="800" alt="Example Interface" /> |
|
|
206
|
+
|
|
207
|
+
## License
|
|
208
|
+
|
|
209
|
+
MIT © [Auralogic Labs](https://auralogiclabs.com)
|
package/dist/index.d.mts
ADDED
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Client UUID Generation
|
|
3
|
+
* (c) Auralogic Labs, 2025
|
|
4
|
+
*/
|
|
5
|
+
interface FingerprintComponents {
|
|
6
|
+
basic: Record<string, unknown>;
|
|
7
|
+
canvas: string;
|
|
8
|
+
webgl: string;
|
|
9
|
+
audio: string;
|
|
10
|
+
storage: string;
|
|
11
|
+
}
|
|
12
|
+
type HashingAlgorithm = 'md5' | 'sha256';
|
|
13
|
+
interface FingerprintOptions {
|
|
14
|
+
algo?: HashingAlgorithm;
|
|
15
|
+
enableStableFingerprinting?: boolean;
|
|
16
|
+
}
|
|
17
|
+
interface WebGLFingerprint {
|
|
18
|
+
vendor: string | null;
|
|
19
|
+
renderer: string | null;
|
|
20
|
+
version: string | null;
|
|
21
|
+
shadingLanguageVersion: string | null;
|
|
22
|
+
maxTextureSize: number | null;
|
|
23
|
+
maxViewportDims: string | null;
|
|
24
|
+
}
|
|
25
|
+
interface StorageFingerprint {
|
|
26
|
+
quotaMB: number;
|
|
27
|
+
usageMB: number;
|
|
28
|
+
usageRatio: string;
|
|
29
|
+
usageBucket: string;
|
|
30
|
+
}
|
|
31
|
+
interface ExtendedNavigator extends Navigator {
|
|
32
|
+
userLanguage?: string;
|
|
33
|
+
deviceMemory?: number;
|
|
34
|
+
}
|
|
35
|
+
interface ExtendedWindow extends Window {
|
|
36
|
+
webkitOfflineAudioContext?: typeof OfflineAudioContext;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
/**
|
|
40
|
+
* Client UUID Generation
|
|
41
|
+
* (c) Auralogic Labs, 2025
|
|
42
|
+
*/
|
|
43
|
+
|
|
44
|
+
declare class EnhancedDeviceFingerprint {
|
|
45
|
+
components: Partial<FingerprintComponents>;
|
|
46
|
+
getBasicFingerprint(isStable?: boolean): Record<string, unknown>;
|
|
47
|
+
getCanvasFingerprint(isStable?: boolean): string;
|
|
48
|
+
getWebGLFingerprint(isStable?: boolean): string;
|
|
49
|
+
getAudioFingerprint(isStable?: boolean): Promise<string>;
|
|
50
|
+
getStorageFingerprint(): Promise<string>;
|
|
51
|
+
hashString(str: string, algo?: string): string;
|
|
52
|
+
generateFingerprint(options?: FingerprintOptions): Promise<string>;
|
|
53
|
+
get(options?: FingerprintOptions): Promise<string>;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
/**
|
|
57
|
+
* Client UUID Generation
|
|
58
|
+
* (c) Auralogic Labs, 2025
|
|
59
|
+
*/
|
|
60
|
+
|
|
61
|
+
declare const getFingerprint: (options?: FingerprintOptions) => Promise<string>;
|
|
62
|
+
|
|
63
|
+
export { EnhancedDeviceFingerprint, type ExtendedNavigator, type ExtendedWindow, type FingerprintComponents, type FingerprintOptions, type HashingAlgorithm, type StorageFingerprint, type WebGLFingerprint, getFingerprint };
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Client UUID Generation
|
|
3
|
+
* (c) Auralogic Labs, 2025
|
|
4
|
+
*/
|
|
5
|
+
interface FingerprintComponents {
|
|
6
|
+
basic: Record<string, unknown>;
|
|
7
|
+
canvas: string;
|
|
8
|
+
webgl: string;
|
|
9
|
+
audio: string;
|
|
10
|
+
storage: string;
|
|
11
|
+
}
|
|
12
|
+
type HashingAlgorithm = 'md5' | 'sha256';
|
|
13
|
+
interface FingerprintOptions {
|
|
14
|
+
algo?: HashingAlgorithm;
|
|
15
|
+
enableStableFingerprinting?: boolean;
|
|
16
|
+
}
|
|
17
|
+
interface WebGLFingerprint {
|
|
18
|
+
vendor: string | null;
|
|
19
|
+
renderer: string | null;
|
|
20
|
+
version: string | null;
|
|
21
|
+
shadingLanguageVersion: string | null;
|
|
22
|
+
maxTextureSize: number | null;
|
|
23
|
+
maxViewportDims: string | null;
|
|
24
|
+
}
|
|
25
|
+
interface StorageFingerprint {
|
|
26
|
+
quotaMB: number;
|
|
27
|
+
usageMB: number;
|
|
28
|
+
usageRatio: string;
|
|
29
|
+
usageBucket: string;
|
|
30
|
+
}
|
|
31
|
+
interface ExtendedNavigator extends Navigator {
|
|
32
|
+
userLanguage?: string;
|
|
33
|
+
deviceMemory?: number;
|
|
34
|
+
}
|
|
35
|
+
interface ExtendedWindow extends Window {
|
|
36
|
+
webkitOfflineAudioContext?: typeof OfflineAudioContext;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
/**
|
|
40
|
+
* Client UUID Generation
|
|
41
|
+
* (c) Auralogic Labs, 2025
|
|
42
|
+
*/
|
|
43
|
+
|
|
44
|
+
declare class EnhancedDeviceFingerprint {
|
|
45
|
+
components: Partial<FingerprintComponents>;
|
|
46
|
+
getBasicFingerprint(isStable?: boolean): Record<string, unknown>;
|
|
47
|
+
getCanvasFingerprint(isStable?: boolean): string;
|
|
48
|
+
getWebGLFingerprint(isStable?: boolean): string;
|
|
49
|
+
getAudioFingerprint(isStable?: boolean): Promise<string>;
|
|
50
|
+
getStorageFingerprint(): Promise<string>;
|
|
51
|
+
hashString(str: string, algo?: string): string;
|
|
52
|
+
generateFingerprint(options?: FingerprintOptions): Promise<string>;
|
|
53
|
+
get(options?: FingerprintOptions): Promise<string>;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
/**
|
|
57
|
+
* Client UUID Generation
|
|
58
|
+
* (c) Auralogic Labs, 2025
|
|
59
|
+
*/
|
|
60
|
+
|
|
61
|
+
declare const getFingerprint: (options?: FingerprintOptions) => Promise<string>;
|
|
62
|
+
|
|
63
|
+
export { EnhancedDeviceFingerprint, type ExtendedNavigator, type ExtendedWindow, type FingerprintComponents, type FingerprintOptions, type HashingAlgorithm, type StorageFingerprint, type WebGLFingerprint, getFingerprint };
|