1
1
import telemetryContext from '../context' ;
2
2
import type { TelemetryContextType } from '../context' ;
3
- import {
4
- getWindowStorageItem ,
5
- setWindowStorageItem ,
6
- isWindowStorageAvailable ,
7
- } from './window-storage' ;
3
+ import { getWindowStorageItem , setWindowStorageItem } from './window-storage' ;
8
4
9
5
function generateId ( length : number ) : string {
10
6
let result = '' ;
@@ -18,62 +14,109 @@ function generateId(length: number): string {
18
14
return result ;
19
15
}
20
16
21
- const getMachineId =
17
+ function pick ( obj : any , keys : string [ ] ) {
18
+ return keys . reduce ( ( acc , key ) => {
19
+ acc [ key ] = obj [ key ] ;
20
+ return acc ;
21
+ } , { } as any ) ;
22
+ }
23
+
24
+ const getBrowserFingerprint =
22
25
typeof window === 'undefined' || process . env . NODE_ENV === 'test'
23
- ? ( ) => ''
26
+ ? ( ) => undefined
24
27
: async ( ) => {
25
- const FingerprintJS = await import ( '@fingerprintjs/fingerprintjs' ) ;
26
- const fpPromise = FingerprintJS . load ( ) ;
27
- const fp = await fpPromise ;
28
- const result = await fp . get ( ) ;
29
- return result . visitorId ;
28
+ const fingerprintLCKey = 'fingerprint' ;
29
+
30
+ try {
31
+ const existingFingerprint = getWindowStorageItem ( 'localStorage' , fingerprintLCKey ) ;
32
+ if ( existingFingerprint ) {
33
+ return JSON . parse ( existingFingerprint ) ;
34
+ }
35
+
36
+ const FingerprintJS = await import ( '@fingerprintjs/fingerprintjs' ) ;
37
+ const fp = await FingerprintJS . load ( { monitoring : false } as any ) ;
38
+ const fpResult = await fp . get ( ) ;
39
+
40
+ const components : any = { ...fpResult . components } ;
41
+ delete components . cookiesEnabled ;
42
+
43
+ const fullHash = FingerprintJS . hashComponents ( components ) ;
44
+ const coreHash = FingerprintJS . hashComponents ( {
45
+ ...pick ( components , [
46
+ 'fonts' ,
47
+ 'audio' ,
48
+ 'languages' ,
49
+ 'deviceMemory' ,
50
+ 'timezone' ,
51
+ 'sessionStorage' ,
52
+ 'localStorage' ,
53
+ 'indexedDB' ,
54
+ 'openDatabase' ,
55
+ 'platform' ,
56
+ 'canvas' ,
57
+ 'vendor' ,
58
+ 'vendorFlavors' ,
59
+ 'colorGamut' ,
60
+ 'forcedColors' ,
61
+ 'monochrome' ,
62
+ 'contrast' ,
63
+ 'reducedMotion' ,
64
+ 'math' ,
65
+ 'videoCard' ,
66
+ 'architecture' ,
67
+ ] ) ,
68
+ } ) ;
69
+
70
+ const result = { fullHash, coreHash } ;
71
+ setWindowStorageItem ( 'localStorage' , fingerprintLCKey , JSON . stringify ( result ) ) ;
72
+ return result ;
73
+ } catch ( _ ) {
74
+ return null ;
75
+ }
30
76
} ;
31
77
32
78
function getAnonymousId ( ) : string {
33
- if ( isWindowStorageAvailable ( 'localStorage' ) ) {
34
- const localStorageKey = 'anonymous_id' ;
35
- const existingAnonymousId = getWindowStorageItem ( 'localStorage' , localStorageKey ) ;
36
- if ( existingAnonymousId ) {
37
- return existingAnonymousId ;
38
- }
39
-
40
- const generated = generateId ( 32 ) ;
41
- if ( setWindowStorageItem ( 'localStorage' , localStorageKey , generated ) ) {
42
- return generated ;
43
- }
79
+ const localStorageKey = 'anonymous_id' ;
80
+ const existingAnonymousId = getWindowStorageItem ( 'localStorage' , localStorageKey ) ;
81
+ if ( existingAnonymousId ) {
82
+ return existingAnonymousId ;
83
+ }
84
+
85
+ const generated = `anid_${ generateId ( 32 ) } ` ;
86
+ if ( setWindowStorageItem ( 'localStorage' , localStorageKey , generated ) ) {
87
+ return generated ;
44
88
}
45
89
46
90
return '' ;
47
91
}
48
92
49
93
function getSessionId ( ) : string {
50
- if ( isWindowStorageAvailable ( 'sessionStorage' ) ) {
51
- const localStorageKey = 'session_id' ;
52
- const existingSessionId = getWindowStorageItem ( 'sessionStorage' , localStorageKey ) ;
53
- if ( existingSessionId ) {
54
- return existingSessionId ;
55
- }
56
-
57
- const generated = generateId ( 32 ) ;
58
- if ( setWindowStorageItem ( 'sessionStorage' , localStorageKey , generated ) ) {
59
- return generated ;
60
- }
94
+ const localStorageKey = 'session_id' ;
95
+ const existingSessionId = getWindowStorageItem ( 'sessionStorage' , localStorageKey ) ;
96
+ if ( existingSessionId ) {
97
+ return existingSessionId ;
61
98
}
62
99
63
- return generateId ( 32 ) ;
100
+ const generated = `sesid_${ generateId ( 32 ) } ` ;
101
+ if ( setWindowStorageItem ( 'sessionStorage' , localStorageKey , generated ) ) {
102
+ return generated ;
103
+ }
104
+
105
+ return `sestp_${ generateId ( 32 ) } ` ;
64
106
}
65
107
66
108
async function getTelemetryContext ( ) : Promise < TelemetryContextType > {
109
+ telemetryContext . traits . sessionId = getSessionId ( ) ;
110
+
67
111
// Initialize the context if it hasn't been initialized yet
68
112
// (e.g. postinstall not run)
69
113
if ( ! telemetryContext . config . isInitialized ) {
70
114
telemetryContext . traits . anonymousId = getAnonymousId ( ) ;
71
- telemetryContext . traits . sessionId = getSessionId ( ) ;
72
115
telemetryContext . config . isInitialized = true ;
73
116
}
74
117
75
- if ( ! telemetryContext . traits . machineId ) {
76
- telemetryContext . traits . machineId = await getMachineId ( ) ;
118
+ if ( ! telemetryContext . traits . fingerprint ) {
119
+ telemetryContext . traits . fingerprint = await getBrowserFingerprint ( ) ;
77
120
}
78
121
79
122
return telemetryContext ;
0 commit comments