get-browser-fingerprint 3.2.0 → 3.2.3
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/README.md +1 -1
- package/package.json +10 -8
- package/src/index.d.ts +14 -0
- package/src/index.js +31 -48
package/README.md
CHANGED
package/package.json
CHANGED
|
@@ -1,24 +1,26 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "get-browser-fingerprint",
|
|
3
|
-
"version": "3.2.
|
|
3
|
+
"version": "3.2.3",
|
|
4
4
|
"author": "Damiano Barbati <damiano.barbati@gmail.com> (https://github.com/damianobarbati)",
|
|
5
5
|
"repository": "https://github.com/damianobarbati/get-browser-fingerprint",
|
|
6
6
|
"license": "MIT",
|
|
7
7
|
"main": "src/index.js",
|
|
8
|
+
"type": "module",
|
|
8
9
|
"files": [
|
|
9
10
|
"README.md",
|
|
10
11
|
"package.json",
|
|
11
|
-
"src/index.js"
|
|
12
|
+
"src/index.js",
|
|
13
|
+
"src/index.d.ts"
|
|
12
14
|
],
|
|
13
|
-
"
|
|
15
|
+
"types": "./src/index.d.ts",
|
|
14
16
|
"scripts": {
|
|
15
|
-
"
|
|
17
|
+
"lint": "biome check --write",
|
|
16
18
|
"test": "vitest run"
|
|
17
19
|
},
|
|
18
20
|
"devDependencies": {
|
|
19
|
-
"
|
|
20
|
-
"
|
|
21
|
-
"
|
|
22
|
-
"vitest": "^0.
|
|
21
|
+
"@biomejs/biome": "^1.8.3",
|
|
22
|
+
"@playwright/test": "^1.47.0",
|
|
23
|
+
"serve": "^14.2.3",
|
|
24
|
+
"vitest": "^2.0.5"
|
|
23
25
|
}
|
|
24
26
|
}
|
package/src/index.d.ts
ADDED
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
export interface FingerprintOptions {
|
|
2
|
+
hardwareOnly?: boolean;
|
|
3
|
+
enableWebgl?: boolean;
|
|
4
|
+
enableScreen?: boolean;
|
|
5
|
+
debug?: boolean;
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
export default function getBrowserFingerprint(options?: FingerprintOptions): number;
|
|
9
|
+
|
|
10
|
+
declare global {
|
|
11
|
+
interface Window {
|
|
12
|
+
getBrowserFingerprint: typeof getBrowserFingerprint;
|
|
13
|
+
}
|
|
14
|
+
}
|
package/src/index.js
CHANGED
|
@@ -1,26 +1,10 @@
|
|
|
1
|
-
const getBrowserFingerprint = ({
|
|
2
|
-
|
|
3
|
-
enableWebgl = false,
|
|
4
|
-
enableScreen = true,
|
|
5
|
-
debug = false,
|
|
6
|
-
} = {}) => {
|
|
7
|
-
const {
|
|
8
|
-
cookieEnabled,
|
|
9
|
-
deviceMemory,
|
|
10
|
-
doNotTrack,
|
|
11
|
-
hardwareConcurrency,
|
|
12
|
-
language,
|
|
13
|
-
languages,
|
|
14
|
-
maxTouchPoints,
|
|
15
|
-
platform,
|
|
16
|
-
userAgent,
|
|
17
|
-
vendor,
|
|
18
|
-
} = window.navigator;
|
|
1
|
+
const getBrowserFingerprint = ({ hardwareOnly = false, enableWebgl = false, enableScreen = true, debug = false } = {}) => {
|
|
2
|
+
const { cookieEnabled, deviceMemory, doNotTrack, hardwareConcurrency, language, languages, maxTouchPoints, platform, userAgent, vendor } = window.navigator;
|
|
19
3
|
|
|
20
4
|
const { width, height, colorDepth, pixelDepth } = enableScreen ? window.screen : {}; // undefined will remove this from the stringify down here
|
|
21
5
|
const timezoneOffset = new Date().getTimezoneOffset();
|
|
22
6
|
const timezone = Intl.DateTimeFormat().resolvedOptions().timeZone;
|
|
23
|
-
const touchSupport =
|
|
7
|
+
const touchSupport = "ontouchstart" in window;
|
|
24
8
|
const devicePixelRatio = window.devicePixelRatio;
|
|
25
9
|
|
|
26
10
|
const canvas = getCanvasID(debug);
|
|
@@ -69,25 +53,25 @@ const getBrowserFingerprint = ({
|
|
|
69
53
|
|
|
70
54
|
const datastring = JSON.stringify(data, null, 4);
|
|
71
55
|
|
|
72
|
-
if (debug) console.log(
|
|
56
|
+
if (debug) console.log("fingerprint data", datastring);
|
|
73
57
|
|
|
74
58
|
const result = murmurhash3_32_gc(datastring);
|
|
75
59
|
return result;
|
|
76
60
|
};
|
|
77
61
|
|
|
78
|
-
|
|
62
|
+
const getCanvasID = (debug) => {
|
|
79
63
|
try {
|
|
80
|
-
const canvas = document.createElement(
|
|
81
|
-
const ctx = canvas.getContext(
|
|
64
|
+
const canvas = document.createElement("canvas");
|
|
65
|
+
const ctx = canvas.getContext("2d");
|
|
82
66
|
const text = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ`~1!2@3#4$5%6^7&8*9(0)-_=+[{]}|;:',<.>/?";
|
|
83
|
-
ctx.textBaseline =
|
|
67
|
+
ctx.textBaseline = "top";
|
|
84
68
|
ctx.font = "14px 'Arial'";
|
|
85
|
-
ctx.textBaseline =
|
|
86
|
-
ctx.fillStyle =
|
|
69
|
+
ctx.textBaseline = "alphabetic";
|
|
70
|
+
ctx.fillStyle = "#f60";
|
|
87
71
|
ctx.fillRect(125, 1, 62, 20);
|
|
88
|
-
ctx.fillStyle =
|
|
72
|
+
ctx.fillStyle = "#069";
|
|
89
73
|
ctx.fillText(text, 2, 15);
|
|
90
|
-
ctx.fillStyle =
|
|
74
|
+
ctx.fillStyle = "rgba(102, 204, 0, 0.7)";
|
|
91
75
|
ctx.fillText(text, 4, 17);
|
|
92
76
|
|
|
93
77
|
const result = canvas.toDataURL();
|
|
@@ -104,24 +88,25 @@ export const getCanvasID = (debug) => {
|
|
|
104
88
|
}
|
|
105
89
|
};
|
|
106
90
|
|
|
107
|
-
|
|
91
|
+
const getWebglID = (debug) => {
|
|
108
92
|
try {
|
|
109
|
-
const canvas = document.createElement(
|
|
110
|
-
const ctx = canvas.getContext(
|
|
93
|
+
const canvas = document.createElement("canvas");
|
|
94
|
+
const ctx = canvas.getContext("webgl");
|
|
111
95
|
canvas.width = 256;
|
|
112
96
|
canvas.height = 128;
|
|
113
97
|
|
|
114
98
|
const f =
|
|
115
|
-
|
|
116
|
-
const g =
|
|
117
|
-
'precision mediump float;varying vec2 varyinTexCoordinate;void main() {gl_FragColor=vec4(varyinTexCoordinate,0,1);}';
|
|
99
|
+
"attribute vec2 attrVertex;varying vec2 varyinTexCoordinate;uniform vec2 uniformOffset;void main(){varyinTexCoordinate=attrVertex+uniformOffset;gl_Position=vec4(attrVertex,0,1);}";
|
|
100
|
+
const g = "precision mediump float;varying vec2 varyinTexCoordinate;void main() {gl_FragColor=vec4(varyinTexCoordinate,0,1);}";
|
|
118
101
|
const h = ctx.createBuffer();
|
|
119
102
|
|
|
120
103
|
ctx.bindBuffer(ctx.ARRAY_BUFFER, h);
|
|
121
104
|
|
|
122
105
|
const i = new Float32Array([-0.2, -0.9, 0, 0.4, -0.26, 0, 0, 0.7321, 0]);
|
|
123
106
|
|
|
124
|
-
ctx.bufferData(ctx.ARRAY_BUFFER, i, ctx.STATIC_DRAW)
|
|
107
|
+
ctx.bufferData(ctx.ARRAY_BUFFER, i, ctx.STATIC_DRAW);
|
|
108
|
+
h.itemSize = 3;
|
|
109
|
+
h.numItems = 3;
|
|
125
110
|
|
|
126
111
|
const j = ctx.createProgram();
|
|
127
112
|
const k = ctx.createShader(ctx.VERTEX_SHADER);
|
|
@@ -138,8 +123,8 @@ export const getWebglID = (debug) => {
|
|
|
138
123
|
ctx.linkProgram(j);
|
|
139
124
|
ctx.useProgram(j);
|
|
140
125
|
|
|
141
|
-
j.vertexPosAttrib = ctx.getAttribLocation(j,
|
|
142
|
-
j.offsetUniform = ctx.getUniformLocation(j,
|
|
126
|
+
j.vertexPosAttrib = ctx.getAttribLocation(j, "attrVertex");
|
|
127
|
+
j.offsetUniform = ctx.getUniformLocation(j, "uniformOffset");
|
|
143
128
|
|
|
144
129
|
ctx.enableVertexAttribArray(j.vertexPosArray);
|
|
145
130
|
ctx.vertexAttribPointer(j.vertexPosAttrib, h.itemSize, ctx.FLOAT, !1, 0, 0);
|
|
@@ -149,7 +134,7 @@ export const getWebglID = (debug) => {
|
|
|
149
134
|
const n = new Uint8Array(canvas.width * canvas.height * 4);
|
|
150
135
|
ctx.readPixels(0, 0, canvas.width, canvas.height, ctx.RGBA, ctx.UNSIGNED_BYTE, n);
|
|
151
136
|
|
|
152
|
-
const result = JSON.stringify(n).replace(/,?"[0-9]+":/g,
|
|
137
|
+
const result = JSON.stringify(n).replace(/,?"[0-9]+":/g, "");
|
|
153
138
|
|
|
154
139
|
if (debug) {
|
|
155
140
|
document.body.appendChild(canvas);
|
|
@@ -163,9 +148,9 @@ export const getWebglID = (debug) => {
|
|
|
163
148
|
}
|
|
164
149
|
};
|
|
165
150
|
|
|
166
|
-
|
|
151
|
+
const getWebglInfo = () => {
|
|
167
152
|
try {
|
|
168
|
-
const ctx = document.createElement(
|
|
153
|
+
const ctx = document.createElement("canvas").getContext("webgl");
|
|
169
154
|
|
|
170
155
|
const result = {
|
|
171
156
|
VERSION: String(ctx.getParameter(ctx.VERSION)),
|
|
@@ -180,20 +165,18 @@ export const getWebglInfo = () => {
|
|
|
180
165
|
}
|
|
181
166
|
};
|
|
182
167
|
|
|
183
|
-
|
|
168
|
+
const murmurhash3_32_gc = (key) => {
|
|
184
169
|
const remainder = key.length & 3; // key.length % 4
|
|
185
170
|
const bytes = key.length - remainder;
|
|
186
171
|
const c1 = 0xcc9e2d51;
|
|
187
172
|
const c2 = 0x1b873593;
|
|
188
173
|
|
|
189
|
-
let h1
|
|
174
|
+
let h1;
|
|
175
|
+
let h1b;
|
|
176
|
+
let k1;
|
|
190
177
|
|
|
191
178
|
for (let i = 0; i < bytes; i++) {
|
|
192
|
-
k1 =
|
|
193
|
-
(key.charCodeAt(i) & 0xff) |
|
|
194
|
-
((key.charCodeAt(++i) & 0xff) << 8) |
|
|
195
|
-
((key.charCodeAt(++i) & 0xff) << 16) |
|
|
196
|
-
((key.charCodeAt(++i) & 0xff) << 24);
|
|
179
|
+
k1 = (key.charCodeAt(i) & 0xff) | ((key.charCodeAt(++i) & 0xff) << 8) | ((key.charCodeAt(++i) & 0xff) << 16) | ((key.charCodeAt(++i) & 0xff) << 24);
|
|
197
180
|
++i;
|
|
198
181
|
|
|
199
182
|
k1 = ((k1 & 0xffff) * c1 + ((((k1 >>> 16) * c1) & 0xffff) << 16)) & 0xffffffff;
|
|
@@ -241,7 +224,7 @@ export const murmurhash3_32_gc = (key) => {
|
|
|
241
224
|
return h1 >>> 0;
|
|
242
225
|
};
|
|
243
226
|
|
|
244
|
-
if (typeof window !==
|
|
227
|
+
if (typeof window !== "undefined") {
|
|
245
228
|
window.getBrowserFingerprint = getBrowserFingerprint;
|
|
246
229
|
}
|
|
247
230
|
|