get-browser-fingerprint 3.0.0 → 3.2.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/README.md +3 -2
- package/package.json +9 -4
- package/src/index.js +34 -11
- package/.eslintrc +0 -5
- package/.github/workflows/commit.yml +0 -24
- package/.github/workflows/tag.yml +0 -28
- package/.nvmrc +0 -1
- package/src/index.html +0 -47
- package/src/index.spec.js +0 -53
package/README.md
CHANGED
|
@@ -13,7 +13,8 @@ console.log(fingerprint);
|
|
|
13
13
|
|
|
14
14
|
Options available:
|
|
15
15
|
- `hardwareOnly` (default `false`): leverage only hardware info about device
|
|
16
|
-
- `enableWebgl` (default `false`): enable webgl renderer, ~4x times slower but adds another deadly powerful hardware detection layer on top of canvas
|
|
16
|
+
- `enableWebgl` (default `false`): enable webgl renderer, ~4x times slower but adds another deadly powerful hardware detection layer on top of canvas
|
|
17
|
+
- `enableScreen` (default `true`): enable screen resolution detection, disable it if your userbase may use multiple screens
|
|
17
18
|
- `debug`: log data used to generate fingerprint to console and add canvas/webgl canvas to body to see rendered image (default `false`)
|
|
18
19
|
|
|
19
20
|
⚠️ Be careful: the strongest discriminating factor is canvas token which can't be computed on old devices (eg: iPhone 6), deal accordingly ⚠️
|
|
@@ -30,4 +31,4 @@ yarn test
|
|
|
30
31
|
To run example locally:
|
|
31
32
|
```sh
|
|
32
33
|
yarn http-server src -o -c-1 -p 80
|
|
33
|
-
```
|
|
34
|
+
```
|
package/package.json
CHANGED
|
@@ -1,19 +1,24 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "get-browser-fingerprint",
|
|
3
|
-
"version": "3.
|
|
3
|
+
"version": "3.2.0",
|
|
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
|
+
"files": [
|
|
9
|
+
"README.md",
|
|
10
|
+
"package.json",
|
|
11
|
+
"src/index.js"
|
|
12
|
+
],
|
|
8
13
|
"type": "module",
|
|
9
14
|
"scripts": {
|
|
10
15
|
"eslint": "eslint --ignore-path .gitignore --fix",
|
|
11
16
|
"test": "vitest run"
|
|
12
17
|
},
|
|
13
18
|
"devDependencies": {
|
|
14
|
-
"eslint-config-xs": "^
|
|
19
|
+
"eslint-config-xs": "^2.6.1",
|
|
15
20
|
"http-server": "^14.1.1",
|
|
16
|
-
"puppeteer": "^
|
|
17
|
-
"vitest": "^0.
|
|
21
|
+
"puppeteer": "^21.4.1",
|
|
22
|
+
"vitest": "^0.34.6"
|
|
18
23
|
}
|
|
19
24
|
}
|
package/src/index.js
CHANGED
|
@@ -1,7 +1,23 @@
|
|
|
1
|
-
const getBrowserFingerprint = ({
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
1
|
+
const getBrowserFingerprint = ({
|
|
2
|
+
hardwareOnly = false,
|
|
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;
|
|
19
|
+
|
|
20
|
+
const { width, height, colorDepth, pixelDepth } = enableScreen ? window.screen : {}; // undefined will remove this from the stringify down here
|
|
5
21
|
const timezoneOffset = new Date().getTimezoneOffset();
|
|
6
22
|
const timezone = Intl.DateTimeFormat().resolvedOptions().timeZone;
|
|
7
23
|
const touchSupport = 'ontouchstart' in window;
|
|
@@ -97,7 +113,8 @@ export const getWebglID = (debug) => {
|
|
|
97
113
|
|
|
98
114
|
const f =
|
|
99
115
|
'attribute vec2 attrVertex;varying vec2 varyinTexCoordinate;uniform vec2 uniformOffset;void main(){varyinTexCoordinate=attrVertex+uniformOffset;gl_Position=vec4(attrVertex,0,1);}';
|
|
100
|
-
const g =
|
|
116
|
+
const g =
|
|
117
|
+
'precision mediump float;varying vec2 varyinTexCoordinate;void main() {gl_FragColor=vec4(varyinTexCoordinate,0,1);}';
|
|
101
118
|
const h = ctx.createBuffer();
|
|
102
119
|
|
|
103
120
|
ctx.bindBuffer(ctx.ARRAY_BUFFER, h);
|
|
@@ -151,10 +168,10 @@ export const getWebglInfo = () => {
|
|
|
151
168
|
const ctx = document.createElement('canvas').getContext('webgl');
|
|
152
169
|
|
|
153
170
|
const result = {
|
|
154
|
-
VERSION: ctx.getParameter(ctx.VERSION),
|
|
155
|
-
SHADING_LANGUAGE_VERSION: ctx.getParameter(ctx.SHADING_LANGUAGE_VERSION),
|
|
156
|
-
VENDOR: ctx.getParameter(ctx.VENDOR),
|
|
157
|
-
SUPORTED_EXTENSIONS: ctx.getSupportedExtensions(),
|
|
171
|
+
VERSION: String(ctx.getParameter(ctx.VERSION)),
|
|
172
|
+
SHADING_LANGUAGE_VERSION: String(ctx.getParameter(ctx.SHADING_LANGUAGE_VERSION)),
|
|
173
|
+
VENDOR: String(ctx.getParameter(ctx.VENDOR)),
|
|
174
|
+
SUPORTED_EXTENSIONS: String(ctx.getSupportedExtensions()),
|
|
158
175
|
};
|
|
159
176
|
|
|
160
177
|
return result;
|
|
@@ -172,7 +189,11 @@ export const murmurhash3_32_gc = (key) => {
|
|
|
172
189
|
let h1, h1b, k1;
|
|
173
190
|
|
|
174
191
|
for (let i = 0; i < bytes; i++) {
|
|
175
|
-
k1 =
|
|
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);
|
|
176
197
|
++i;
|
|
177
198
|
|
|
178
199
|
k1 = ((k1 & 0xffff) * c1 + ((((k1 >>> 16) * c1) & 0xffff) << 16)) & 0xffffffff;
|
|
@@ -220,6 +241,8 @@ export const murmurhash3_32_gc = (key) => {
|
|
|
220
241
|
return h1 >>> 0;
|
|
221
242
|
};
|
|
222
243
|
|
|
223
|
-
window
|
|
244
|
+
if (typeof window !== 'undefined') {
|
|
245
|
+
window.getBrowserFingerprint = getBrowserFingerprint;
|
|
246
|
+
}
|
|
224
247
|
|
|
225
248
|
export default getBrowserFingerprint;
|
package/.eslintrc
DELETED
|
@@ -1,24 +0,0 @@
|
|
|
1
|
-
name: commit
|
|
2
|
-
|
|
3
|
-
on:
|
|
4
|
-
push:
|
|
5
|
-
branches:
|
|
6
|
-
- main
|
|
7
|
-
|
|
8
|
-
jobs:
|
|
9
|
-
test:
|
|
10
|
-
runs-on: ubuntu-22.04
|
|
11
|
-
timeout-minutes: 3
|
|
12
|
-
steps:
|
|
13
|
-
- name: checkout
|
|
14
|
-
uses: actions/checkout@v2
|
|
15
|
-
|
|
16
|
-
- name: setup node
|
|
17
|
-
uses: actions/setup-node@v2
|
|
18
|
-
with:
|
|
19
|
-
node-version-file: '.nvmrc'
|
|
20
|
-
|
|
21
|
-
- name: test
|
|
22
|
-
run: |
|
|
23
|
-
yarn install
|
|
24
|
-
yarn test
|
|
@@ -1,28 +0,0 @@
|
|
|
1
|
-
name: tag
|
|
2
|
-
|
|
3
|
-
on:
|
|
4
|
-
push:
|
|
5
|
-
tags:
|
|
6
|
-
- v*
|
|
7
|
-
|
|
8
|
-
jobs:
|
|
9
|
-
release:
|
|
10
|
-
runs-on: ubuntu-22.04
|
|
11
|
-
timeout-minutes: 3
|
|
12
|
-
steps:
|
|
13
|
-
- name: checkout
|
|
14
|
-
uses: actions/checkout@v2
|
|
15
|
-
|
|
16
|
-
- name: setup node
|
|
17
|
-
uses: actions/setup-node@v2
|
|
18
|
-
with:
|
|
19
|
-
node-version-file: '.nvmrc'
|
|
20
|
-
registry-url: https://registry.npmjs.org/
|
|
21
|
-
|
|
22
|
-
- name: release
|
|
23
|
-
env:
|
|
24
|
-
NODE_AUTH_TOKEN: ${{secrets.NPM_TOKEN}}
|
|
25
|
-
run: |
|
|
26
|
-
yarn install
|
|
27
|
-
yarn test
|
|
28
|
-
npm publish
|
package/.nvmrc
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
v16.16
|
package/src/index.html
DELETED
|
@@ -1,47 +0,0 @@
|
|
|
1
|
-
<!DOCTYPE html>
|
|
2
|
-
<html>
|
|
3
|
-
<head>
|
|
4
|
-
<title>get-browser-fingerprint demo</title>
|
|
5
|
-
</head>
|
|
6
|
-
<body>
|
|
7
|
-
<h1>get-browser-fingerprint</h1>
|
|
8
|
-
|
|
9
|
-
<h2 id="default"></h2>
|
|
10
|
-
<h2 id="hardwareOnly"></h2>
|
|
11
|
-
<h2 id="enableWebgl"></h2>
|
|
12
|
-
|
|
13
|
-
<script type="module">
|
|
14
|
-
import getFingerprint from './index.js';
|
|
15
|
-
|
|
16
|
-
args_default: {
|
|
17
|
-
const t0 = performance.now();
|
|
18
|
-
const fingerprint = getFingerprint({ debug: true });
|
|
19
|
-
const t1 = performance.now();
|
|
20
|
-
|
|
21
|
-
const result = `Fingerprint: ${fingerprint} (computed in ${(t1 - t0).toFixed(0)} ms)`;
|
|
22
|
-
console.log(result);
|
|
23
|
-
document.getElementById('default').innerText = result;
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
args_hardwareOnly: {
|
|
27
|
-
const t0 = performance.now();
|
|
28
|
-
const fingerprint = getFingerprint({ hardwareOnly: true, debug: true });
|
|
29
|
-
const t1 = performance.now();
|
|
30
|
-
|
|
31
|
-
const result = `Fingerprint with hardwareOnly=true: ${fingerprint} (computed in ${(t1 - t0).toFixed(0)} ms)`;
|
|
32
|
-
console.log(result);
|
|
33
|
-
document.getElementById('hardwareOnly').innerText = result;
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
args_enableWebgl: {
|
|
37
|
-
const t0 = performance.now();
|
|
38
|
-
const fingerprint = getFingerprint({ enableWebgl: true, debug: true });
|
|
39
|
-
const t1 = performance.now();
|
|
40
|
-
|
|
41
|
-
const result = `Fingerprint with enableWebgl=true: ${fingerprint} (computed in ${(t1 - t0).toFixed(0)} ms)`;
|
|
42
|
-
console.log(result);
|
|
43
|
-
document.getElementById('enableWebgl').innerText = result;
|
|
44
|
-
}
|
|
45
|
-
</script>
|
|
46
|
-
</body>
|
|
47
|
-
</html>
|
package/src/index.spec.js
DELETED
|
@@ -1,53 +0,0 @@
|
|
|
1
|
-
import { describe, it, beforeAll, afterAll, expect } from 'vitest';
|
|
2
|
-
import puppeteer from 'puppeteer';
|
|
3
|
-
|
|
4
|
-
describe('getBrowserFingerprint', () => {
|
|
5
|
-
let browser, page;
|
|
6
|
-
|
|
7
|
-
beforeAll(async () => {
|
|
8
|
-
browser = await puppeteer.launch({
|
|
9
|
-
// headless: false,
|
|
10
|
-
// devtools: true,
|
|
11
|
-
});
|
|
12
|
-
page = await browser.newPage();
|
|
13
|
-
|
|
14
|
-
await page.addScriptTag({
|
|
15
|
-
type: 'module',
|
|
16
|
-
path: './src/index.js',
|
|
17
|
-
});
|
|
18
|
-
});
|
|
19
|
-
|
|
20
|
-
afterAll(async () => {
|
|
21
|
-
await browser.close();
|
|
22
|
-
});
|
|
23
|
-
|
|
24
|
-
it('works without args', async () => {
|
|
25
|
-
const result = await page.evaluate(() => {
|
|
26
|
-
const result = window.getBrowserFingerprint();
|
|
27
|
-
return result;
|
|
28
|
-
});
|
|
29
|
-
|
|
30
|
-
expect(typeof result).toBe('number');
|
|
31
|
-
expect(String(result).length).toBeGreaterThanOrEqual(7);
|
|
32
|
-
});
|
|
33
|
-
|
|
34
|
-
it('works without hardwareOnly=true', async () => {
|
|
35
|
-
const result = await page.evaluate(() => {
|
|
36
|
-
const result = window.getBrowserFingerprint();
|
|
37
|
-
return result;
|
|
38
|
-
});
|
|
39
|
-
|
|
40
|
-
expect(typeof result).toBe('number');
|
|
41
|
-
expect(String(result).length).toBeGreaterThanOrEqual(7);
|
|
42
|
-
});
|
|
43
|
-
|
|
44
|
-
it('works with enableWebgl=true', async () => {
|
|
45
|
-
const result = await page.evaluate(() => {
|
|
46
|
-
const result = window.getBrowserFingerprint({ enableWebgl: true });
|
|
47
|
-
return result;
|
|
48
|
-
});
|
|
49
|
-
|
|
50
|
-
expect(typeof result).toBe('number');
|
|
51
|
-
expect(String(result).length).toBeGreaterThanOrEqual(7);
|
|
52
|
-
});
|
|
53
|
-
});
|