@anonympins/fingerprint 0.3.8 → 0.4.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/CHANGELOG.md +331 -256
- package/README.md +62 -53
- package/composer.json +38 -38
- package/index.js +4 -4
- package/package.json +103 -103
- package/phpunit.xml +20 -20
- package/public/fp.js +1 -1
- package/public/fp.wasm +0 -0
- package/src/js/build-client.js +1 -1
- package/src/js/fingerprint.client.js +2 -0
- package/src/js/fingerprint.js +4429 -4381
- package/src/js/mongodb-store.js +79 -79
- package/src/js/pow.solver.inline.js +31 -0
- package/src/js/pow.solver.js +31 -0
- package/src/js/tests/fingerprint.builder.test.js +79 -0
- package/src/js/tests/fingerprint.client.init.test.js +120 -0
- package/src/js/tests/fingerprint.client.test.js +105 -0
- package/src/js/tests/fingerprint.engine.test.js +371 -0
- package/src/js/tests/fingerprint.isMalicious.test.js +117 -0
- package/src/js/tests/fingerprint.test.js +2319 -0
- package/src/js/tests/ip-reputation.test.js +132 -0
- package/src/js/tests/ja3AnomalyDetector.test.js +135 -0
- package/src/js/tests/library.test.js +96 -0
- package/src/js/tests/metrics.test.js +104 -0
- package/src/js/tests/pow.solver.test.js +198 -0
- package/src/js/tests/problem-manager.test.js +323 -0
- package/src/js/tests/stores.test.js +118 -0
- package/src/php/Challenge/ChallengeUtils.php +361 -361
- package/src/php/Config/SecurityProfiles.php +271 -266
- package/src/php/FingerprintBuilder.php +185 -185
- package/src/php/FingerprintClient.php +131 -131
- package/src/php/FingerprintEngine.php +1006 -1006
- package/src/php/Ja3AnomalyDetector.php +227 -227
- package/src/php/Optimization/FunctionRegistry.php +62 -62
- package/src/php/Optimization/Optimization.php +255 -255
- package/src/php/Optimization/OptimizationOperators.php +304 -304
- package/src/php/Store/InMemoryStore.php +66 -66
- package/src/php/Store/MongoDbStore.php +104 -104
- package/src/php/Store/RedisStore.php +53 -53
- package/src/php/Tests/ChallengeUtilsTest.php +81 -81
- package/src/php/Tests/FingerprintBuilderTest.php +57 -57
- package/src/php/Tests/FingerprintClientTest.php +71 -0
- package/src/php/Tests/FingerprintEngineTest.php +299 -299
- package/src/php/Tests/IpReputationTest.php +156 -156
- package/src/php/Tests/Ja3AnomalyDetectorTest.php +179 -179
- package/src/php/Tests/MetricsTest.php +45 -45
- package/src/php/Tests/PowTest.php +39 -39
- package/src/php/Tests/ProblemManagerTest.php +296 -296
- package/src/php/Tests/RequestUtilsTest.php +253 -145
- package/src/php/Tests/TLSClientHelloParserTest.php +118 -0
- package/src/php/Tests/problems.config.json +8 -8
- package/src/php/Utils/BigInt.php +144 -144
- package/src/php/Utils/Logger.php +29 -29
- package/src/php/Utils/MaliciousPatterns.php +58 -58
- package/src/php/Utils/MetricsManager.php +166 -166
- package/src/php/Utils/RequestUtils.php +1169 -1169
- package/src/php/Utils/TLSClientHelloParser.php +117 -0
- package/src/php/bin/auto-tune.php +117 -117
package/README.md
CHANGED
|
@@ -1,54 +1,63 @@
|
|
|
1
|
-
# Fingerprint anti-bot protection
|
|
2
|
-
|
|
3
|
-
NodeJS tests : [](https://github.com/anonympins/fingerprint/actions/workflows/ci.yml)
|
|
4
|
-
|
|
5
|
-
PHP tests : [](https://github.com/anonympins/fingerprint/actions/workflows/ci.yml)
|
|
6
|
-
|
|
7
|
-
[](https://github.com/anonympins/fingerprint/releases)
|
|
8
|
-
[](https://github.com/anonympins/fingerprint/blob/main/LICENSE)
|
|
9
|
-

|
|
10
|
-
|
|
11
|
-
A multi-layered behavioral, cryptographic, and network analysis engine designed to identify and mitigate malicious requests (bots, scrapers, session hijacking) in real-time. Supports both **Node.js** and **PHP** environments.
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
- **
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
```
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
```
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
1
|
+
# Fingerprint anti-bot protection
|
|
2
|
+
|
|
3
|
+
NodeJS tests : [](https://github.com/anonympins/fingerprint/actions/workflows/ci.yml)
|
|
4
|
+
|
|
5
|
+
PHP tests : [](https://github.com/anonympins/fingerprint/actions/workflows/ci.yml)
|
|
6
|
+
|
|
7
|
+
[](https://github.com/anonympins/fingerprint/releases)
|
|
8
|
+
[](https://github.com/anonympins/fingerprint/blob/main/LICENSE)
|
|
9
|
+

|
|
10
|
+
|
|
11
|
+
A multi-layered behavioral, cryptographic, and network analysis engine designed to identify and mitigate malicious requests (bots, scrapers, session hijacking) in real-time. Supports both **Node.js** and **PHP** environments.
|
|
12
|
+
|
|
13
|
+

|
|
14
|
+
|
|
15
|
+
## Key Features
|
|
16
|
+
|
|
17
|
+
- **Multi-Layered Detection**: Combines TLS/JA3/JA4 analysis, HTTP header consistency checks, IP reputation, and behavioral tracking (mouse movements, keystrokes).
|
|
18
|
+
- **Adaptive Mitigation**: Imposes progressive cryptographic Proof-of-Work (PoW) challenges to block automated clients without impacting legitimate human users.
|
|
19
|
+
- **Predefined Profiles**: Ready-to-use security profiles (`balanced`, `strict`, `api`, `blog`, `ecommerce`) tailored to your specific use case.
|
|
20
|
+
|
|
21
|
+
## Quick Start
|
|
22
|
+
|
|
23
|
+
### Node.js
|
|
24
|
+
|
|
25
|
+
```bash
|
|
26
|
+
npm install @anonympins/fingerprint
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
### PHP
|
|
30
|
+
|
|
31
|
+
```bash
|
|
32
|
+
composer require anonympins/fingerprint
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
## Documentation
|
|
36
|
+
|
|
37
|
+
To prevent documentation drift, all detailed guides and reference materials are maintained in the `doc/` directory. Please refer to [these resources](https://github.com/anonympins/fingerprint/wiki/home) to configure and integrate the engine:
|
|
38
|
+
|
|
39
|
+
1. **[Key Concepts & Suspicion Vectors](https://github.com/anonympins/fingerprint/wiki/concepts)**: Learn how the engine calculates suspicion scores across the 15 distinct vectors and manages the Proof-of-Work mitigation layers.
|
|
40
|
+
2. **[Node.js Integration Guide](https://github.com/anonympins/fingerprint/wiki/nodejs_integration)**: Step-by-step instructions for Express.js middleware and raw HTTP server integrations.
|
|
41
|
+
3. **[PHP Integration Guide](https://github.com/anonympins/fingerprint/wiki/php_integration)**: Configuration details for direct PHP integration, TLS fingerprinting forwarding via Nginx/Apache, and securing Prometheus metrics.
|
|
42
|
+
4. **[Full Configuration Options](https://github.com/anonympins/fingerprint/wiki/full_options)**: Complete parameter list for fine-tuning weights, custom honeypots, and security profile overrides.
|
|
43
|
+
5. **[API Reference](https://github.com/anonympins/fingerprint/wiki/api_reference)**: Public API signatures and guides on substituting the in-memory datastore with Redis or MongoDB.
|
|
44
|
+
|
|
45
|
+
Start with the **[Documentation Portal](https://github.com/anonympins/fingerprint/wiki/home)** for a complete index.
|
|
46
|
+
|
|
47
|
+
## Contributing
|
|
48
|
+
|
|
49
|
+
We welcome community contributions! Please read our **[Contributing Guidelines](https://github.com/anonympins/fingerprint/blob/main/CONTRIBUTING.md)** for information on:
|
|
50
|
+
- Setting up your local environment (Node.js and PHP).
|
|
51
|
+
- Running the test suites (`Vitest` and `PHPUnit`).
|
|
52
|
+
- Coding and pull request standards.
|
|
53
|
+
|
|
54
|
+
Thanks to our contributors :
|
|
55
|
+
- [anonympins](https://github.com/anonympins)
|
|
56
|
+
|
|
57
|
+
## Used actively on
|
|
58
|
+
|
|
59
|
+
- https://primals.net and sub-sites
|
|
60
|
+
|
|
61
|
+
## License
|
|
62
|
+
|
|
54
63
|
This project is licensed under the MIT License.
|
package/composer.json
CHANGED
|
@@ -1,39 +1,39 @@
|
|
|
1
|
-
{
|
|
2
|
-
"name": "anonympins/fingerprint",
|
|
3
|
-
"description": "Advanced anti-bot library for Node.js and PHP using multi-layer fingerprinting, behavioral analysis, and adaptive Proof-of-Work (PoW) challenges.",
|
|
4
|
-
"type": "library",
|
|
5
|
-
"license": "MIT",
|
|
6
|
-
"authors": [
|
|
7
|
-
{
|
|
8
|
-
"name": "anonympins",
|
|
9
|
-
"homepage": "https://github.com/anonympins"
|
|
10
|
-
}
|
|
11
|
-
],
|
|
12
|
-
"require": {
|
|
13
|
-
"php": ">=8.0",
|
|
14
|
-
"ext-json": "*",
|
|
15
|
-
"ext-bcmath": "*"
|
|
16
|
-
},
|
|
17
|
-
"require-dev": {
|
|
18
|
-
"phpunit/phpunit": "^9.5"
|
|
19
|
-
},
|
|
20
|
-
"autoload": {
|
|
21
|
-
"psr-4": {
|
|
22
|
-
"Anonympins\\Fingerprint\\": "src/php/"
|
|
23
|
-
}
|
|
24
|
-
},
|
|
25
|
-
"autoload-dev": {
|
|
26
|
-
"psr-4": {
|
|
27
|
-
"Anonympins\\Fingerprint\\Tests\\": "src/php/Tests/"
|
|
28
|
-
}
|
|
29
|
-
},
|
|
30
|
-
"suggest": {
|
|
31
|
-
"ext-gmp": "Recommended for high-performance big integer arithmetic in cryptographic challenges.",
|
|
32
|
-
"ext-redis": "Required to use the Redis store adapter.",
|
|
33
|
-
"ext-pdo": "Required to use SQL store adapters (e.g., for PostgreSQL, MySQL)."
|
|
34
|
-
},
|
|
35
|
-
"config": {
|
|
36
|
-
"sort-packages": true
|
|
37
|
-
},
|
|
38
|
-
"minimum-stability": "stable"
|
|
1
|
+
{
|
|
2
|
+
"name": "anonympins/fingerprint",
|
|
3
|
+
"description": "Advanced anti-bot library for Node.js and PHP using multi-layer fingerprinting, behavioral analysis, and adaptive Proof-of-Work (PoW) challenges.",
|
|
4
|
+
"type": "library",
|
|
5
|
+
"license": "MIT",
|
|
6
|
+
"authors": [
|
|
7
|
+
{
|
|
8
|
+
"name": "anonympins",
|
|
9
|
+
"homepage": "https://github.com/anonympins"
|
|
10
|
+
}
|
|
11
|
+
],
|
|
12
|
+
"require": {
|
|
13
|
+
"php": ">=8.0",
|
|
14
|
+
"ext-json": "*",
|
|
15
|
+
"ext-bcmath": "*"
|
|
16
|
+
},
|
|
17
|
+
"require-dev": {
|
|
18
|
+
"phpunit/phpunit": "^9.5"
|
|
19
|
+
},
|
|
20
|
+
"autoload": {
|
|
21
|
+
"psr-4": {
|
|
22
|
+
"Anonympins\\Fingerprint\\": "src/php/"
|
|
23
|
+
}
|
|
24
|
+
},
|
|
25
|
+
"autoload-dev": {
|
|
26
|
+
"psr-4": {
|
|
27
|
+
"Anonympins\\Fingerprint\\Tests\\": "src/php/Tests/"
|
|
28
|
+
}
|
|
29
|
+
},
|
|
30
|
+
"suggest": {
|
|
31
|
+
"ext-gmp": "Recommended for high-performance big integer arithmetic in cryptographic challenges.",
|
|
32
|
+
"ext-redis": "Required to use the Redis store adapter.",
|
|
33
|
+
"ext-pdo": "Required to use SQL store adapters (e.g., for PostgreSQL, MySQL)."
|
|
34
|
+
},
|
|
35
|
+
"config": {
|
|
36
|
+
"sort-packages": true
|
|
37
|
+
},
|
|
38
|
+
"minimum-stability": "stable"
|
|
39
39
|
}
|
package/index.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Point d'entrée principal pour le package Node.js.
|
|
3
|
-
* Ré-exporte toutes les fonctionnalités de la bibliothèque principale.
|
|
4
|
-
*/
|
|
1
|
+
/**
|
|
2
|
+
* Point d'entrée principal pour le package Node.js.
|
|
3
|
+
* Ré-exporte toutes les fonctionnalités de la bibliothèque principale.
|
|
4
|
+
*/
|
|
5
5
|
export * from './src/js/fingerprint.js';
|
package/package.json
CHANGED
|
@@ -1,103 +1,103 @@
|
|
|
1
|
-
{
|
|
2
|
-
"name": "@anonympins/fingerprint",
|
|
3
|
-
"version": "0.
|
|
4
|
-
"description": "Advanced anti-bot library for Node.js using multi-layer fingerprinting (JA3, client-side, headers), behavioral analysis, and adaptive Proof-of-Work (PoW) challenges to mitigate scraping, scalping, and automated threats.",
|
|
5
|
-
"main": "index.js",
|
|
6
|
-
"type": "module",
|
|
7
|
-
"engines": {
|
|
8
|
-
"node": ">=20.0.0"
|
|
9
|
-
},
|
|
10
|
-
"scripts": {
|
|
11
|
-
"test": "vitest run --reporter=verbose",
|
|
12
|
-
"build": "node src/js/build-client.js"
|
|
13
|
-
},
|
|
14
|
-
"exports": {
|
|
15
|
-
".": "./index.js",
|
|
16
|
-
"./client": {
|
|
17
|
-
"import": "./src/js/fingerprint.client.obfuscated.js",
|
|
18
|
-
"require": "./src/js/fingerprint.client.obfuscated.js",
|
|
19
|
-
"browser": "./src/js/fingerprint.client.obfuscated.js"
|
|
20
|
-
},
|
|
21
|
-
"./client/src/*": "./src/js/*",
|
|
22
|
-
"./fp.wasm": "./public/fp.wasm",
|
|
23
|
-
"./fp.js": "./public/fp.js",
|
|
24
|
-
"./package.json": "./package.json"
|
|
25
|
-
},
|
|
26
|
-
"files": [
|
|
27
|
-
"index.js",
|
|
28
|
-
"src/js/",
|
|
29
|
-
"public/",
|
|
30
|
-
"README.md",
|
|
31
|
-
"LICENSE",
|
|
32
|
-
"CHANGELOG.md",
|
|
33
|
-
"src/php/",
|
|
34
|
-
"composer.json",
|
|
35
|
-
"phpunit.xml"
|
|
36
|
-
],
|
|
37
|
-
"repository": {
|
|
38
|
-
"type": "git",
|
|
39
|
-
"url": "git+https://github.com/anonympins/fingerprint.git"
|
|
40
|
-
},
|
|
41
|
-
"keywords": [
|
|
42
|
-
"anti-bot",
|
|
43
|
-
"bot-detection",
|
|
44
|
-
"security",
|
|
45
|
-
"middleware",
|
|
46
|
-
"express",
|
|
47
|
-
"nodejs",
|
|
48
|
-
"fingerprint",
|
|
49
|
-
"device-fingerprinting",
|
|
50
|
-
"ja3",
|
|
51
|
-
"tls-fingerprinting",
|
|
52
|
-
"proof-of-work",
|
|
53
|
-
"pow",
|
|
54
|
-
"useful-proof-of-work",
|
|
55
|
-
"upow",
|
|
56
|
-
"waf",
|
|
57
|
-
"scraping",
|
|
58
|
-
"scalping",
|
|
59
|
-
"mitigation",
|
|
60
|
-
"rate-limiting",
|
|
61
|
-
"honeypot",
|
|
62
|
-
"behavioral-analysis"
|
|
63
|
-
],
|
|
64
|
-
"author": "anonympins",
|
|
65
|
-
"license": "MIT",
|
|
66
|
-
"bugs": {
|
|
67
|
-
"url": "https://github.com/anonympins/fingerprint/issues"
|
|
68
|
-
},
|
|
69
|
-
"homepage": "https://github.com/anonympins/fingerprint#readme",
|
|
70
|
-
"devDependencies": {
|
|
71
|
-
"cookie-parser": "^1.4.6",
|
|
72
|
-
"express": "^4.22.2",
|
|
73
|
-
"javascript-obfuscator": "^4.1.0",
|
|
74
|
-
"jsdom": "^24.0.0",
|
|
75
|
-
"prom-client": "^15.1.2",
|
|
76
|
-
"terser": "^5.30.3",
|
|
77
|
-
"vitest": "^4.1.11"
|
|
78
|
-
},
|
|
79
|
-
"overrides": {
|
|
80
|
-
"body-parser": "2.3.0",
|
|
81
|
-
"qs": "6.16.0"
|
|
82
|
-
},
|
|
83
|
-
"peerDependencies": {
|
|
84
|
-
"ioredis": "^5.3.2",
|
|
85
|
-
"knex": ">=3.0.0",
|
|
86
|
-
"mongodb": "^6.3.0",
|
|
87
|
-
"sqlite3": "^5.1.7"
|
|
88
|
-
},
|
|
89
|
-
"peerDependenciesMeta": {
|
|
90
|
-
"ioredis": {
|
|
91
|
-
"optional": true
|
|
92
|
-
},
|
|
93
|
-
"mongodb": {
|
|
94
|
-
"optional": true
|
|
95
|
-
},
|
|
96
|
-
"knex": {
|
|
97
|
-
"optional": true
|
|
98
|
-
},
|
|
99
|
-
"sqlite3": {
|
|
100
|
-
"optional": true
|
|
101
|
-
}
|
|
102
|
-
}
|
|
103
|
-
}
|
|
1
|
+
{
|
|
2
|
+
"name": "@anonympins/fingerprint",
|
|
3
|
+
"version": "0.4.0",
|
|
4
|
+
"description": "Advanced anti-bot library for Node.js using multi-layer fingerprinting (JA3, client-side, headers), behavioral analysis, and adaptive Proof-of-Work (PoW) challenges to mitigate scraping, scalping, and automated threats.",
|
|
5
|
+
"main": "index.js",
|
|
6
|
+
"type": "module",
|
|
7
|
+
"engines": {
|
|
8
|
+
"node": ">=20.0.0"
|
|
9
|
+
},
|
|
10
|
+
"scripts": {
|
|
11
|
+
"test": "vitest run --reporter=verbose",
|
|
12
|
+
"build": "node src/js/build-client.js"
|
|
13
|
+
},
|
|
14
|
+
"exports": {
|
|
15
|
+
".": "./index.js",
|
|
16
|
+
"./client": {
|
|
17
|
+
"import": "./src/js/fingerprint.client.obfuscated.js",
|
|
18
|
+
"require": "./src/js/fingerprint.client.obfuscated.js",
|
|
19
|
+
"browser": "./src/js/fingerprint.client.obfuscated.js"
|
|
20
|
+
},
|
|
21
|
+
"./client/src/*": "./src/js/*",
|
|
22
|
+
"./fp.wasm": "./public/fp.wasm",
|
|
23
|
+
"./fp.js": "./public/fp.js",
|
|
24
|
+
"./package.json": "./package.json"
|
|
25
|
+
},
|
|
26
|
+
"files": [
|
|
27
|
+
"index.js",
|
|
28
|
+
"src/js/",
|
|
29
|
+
"public/",
|
|
30
|
+
"README.md",
|
|
31
|
+
"LICENSE",
|
|
32
|
+
"CHANGELOG.md",
|
|
33
|
+
"src/php/",
|
|
34
|
+
"composer.json",
|
|
35
|
+
"phpunit.xml"
|
|
36
|
+
],
|
|
37
|
+
"repository": {
|
|
38
|
+
"type": "git",
|
|
39
|
+
"url": "git+https://github.com/anonympins/fingerprint.git"
|
|
40
|
+
},
|
|
41
|
+
"keywords": [
|
|
42
|
+
"anti-bot",
|
|
43
|
+
"bot-detection",
|
|
44
|
+
"security",
|
|
45
|
+
"middleware",
|
|
46
|
+
"express",
|
|
47
|
+
"nodejs",
|
|
48
|
+
"fingerprint",
|
|
49
|
+
"device-fingerprinting",
|
|
50
|
+
"ja3",
|
|
51
|
+
"tls-fingerprinting",
|
|
52
|
+
"proof-of-work",
|
|
53
|
+
"pow",
|
|
54
|
+
"useful-proof-of-work",
|
|
55
|
+
"upow",
|
|
56
|
+
"waf",
|
|
57
|
+
"scraping",
|
|
58
|
+
"scalping",
|
|
59
|
+
"mitigation",
|
|
60
|
+
"rate-limiting",
|
|
61
|
+
"honeypot",
|
|
62
|
+
"behavioral-analysis"
|
|
63
|
+
],
|
|
64
|
+
"author": "anonympins",
|
|
65
|
+
"license": "MIT",
|
|
66
|
+
"bugs": {
|
|
67
|
+
"url": "https://github.com/anonympins/fingerprint/issues"
|
|
68
|
+
},
|
|
69
|
+
"homepage": "https://github.com/anonympins/fingerprint#readme",
|
|
70
|
+
"devDependencies": {
|
|
71
|
+
"cookie-parser": "^1.4.6",
|
|
72
|
+
"express": "^4.22.2",
|
|
73
|
+
"javascript-obfuscator": "^4.1.0",
|
|
74
|
+
"jsdom": "^24.0.0",
|
|
75
|
+
"prom-client": "^15.1.2",
|
|
76
|
+
"terser": "^5.30.3",
|
|
77
|
+
"vitest": "^4.1.11"
|
|
78
|
+
},
|
|
79
|
+
"overrides": {
|
|
80
|
+
"body-parser": "2.3.0",
|
|
81
|
+
"qs": "6.16.0"
|
|
82
|
+
},
|
|
83
|
+
"peerDependencies": {
|
|
84
|
+
"ioredis": "^5.3.2",
|
|
85
|
+
"knex": ">=3.0.0",
|
|
86
|
+
"mongodb": "^6.3.0",
|
|
87
|
+
"sqlite3": "^5.1.7"
|
|
88
|
+
},
|
|
89
|
+
"peerDependenciesMeta": {
|
|
90
|
+
"ioredis": {
|
|
91
|
+
"optional": true
|
|
92
|
+
},
|
|
93
|
+
"mongodb": {
|
|
94
|
+
"optional": true
|
|
95
|
+
},
|
|
96
|
+
"knex": {
|
|
97
|
+
"optional": true
|
|
98
|
+
},
|
|
99
|
+
"sqlite3": {
|
|
100
|
+
"optional": true
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
}
|
package/phpunit.xml
CHANGED
|
@@ -1,21 +1,21 @@
|
|
|
1
|
-
<?xml version="1.0" encoding="UTF-8"?>
|
|
2
|
-
<phpunit xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
|
3
|
-
xsi:noNamespaceSchemaLocation="https://schema.phpunit.de/9.6/phpunit.xsd"
|
|
4
|
-
bootstrap="vendor/autoload.php"
|
|
5
|
-
colors="true">
|
|
6
|
-
<testsuites>
|
|
7
|
-
<testsuite name="default">
|
|
8
|
-
<directory suffix="Test.php">src/php/Tests</directory>
|
|
9
|
-
</testsuite>
|
|
10
|
-
</testsuites>
|
|
11
|
-
|
|
12
|
-
<coverage>
|
|
13
|
-
<include>
|
|
14
|
-
<directory suffix=".php">./src/php</directory>
|
|
15
|
-
</include>
|
|
16
|
-
<exclude>
|
|
17
|
-
<directory>./src/php/Tests/*</directory>
|
|
18
|
-
<directory>./src/php/Tests</directory>
|
|
19
|
-
</exclude>
|
|
20
|
-
</coverage>
|
|
1
|
+
<?xml version="1.0" encoding="UTF-8"?>
|
|
2
|
+
<phpunit xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
|
3
|
+
xsi:noNamespaceSchemaLocation="https://schema.phpunit.de/9.6/phpunit.xsd"
|
|
4
|
+
bootstrap="vendor/autoload.php"
|
|
5
|
+
colors="true">
|
|
6
|
+
<testsuites>
|
|
7
|
+
<testsuite name="default">
|
|
8
|
+
<directory suffix="Test.php">src/php/Tests</directory>
|
|
9
|
+
</testsuite>
|
|
10
|
+
</testsuites>
|
|
11
|
+
|
|
12
|
+
<coverage>
|
|
13
|
+
<include>
|
|
14
|
+
<directory suffix=".php">./src/php</directory>
|
|
15
|
+
</include>
|
|
16
|
+
<exclude>
|
|
17
|
+
<directory>./src/php/Tests/*</directory>
|
|
18
|
+
<directory>./src/php/Tests</directory>
|
|
19
|
+
</exclude>
|
|
20
|
+
</coverage>
|
|
21
21
|
</phpunit>
|
package/public/fp.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
var createFingerprintModule=(()=>{var _scriptName=globalThis.document?.currentScript?.src;return async function(moduleArg={}){var Module=moduleArg;var ENVIRONMENT_IS_WEB=!!globalThis.window;var ENVIRONMENT_IS_WORKER=!!globalThis.WorkerGlobalScope;var ENVIRONMENT_IS_NODE=globalThis.process?.versions?.node&&globalThis.process?.type!="renderer";var programArgs=[];var thisProgram="./this.program";var quit_=(status,toThrow)=>{throw toThrow};if(typeof __filename!="undefined"){_scriptName=__filename}else if(ENVIRONMENT_IS_WORKER){_scriptName=self.location.href}var scriptDirectory="";function locateFile(path){if(Module["locateFile"]){return Module["locateFile"](path,scriptDirectory)}return scriptDirectory+path}var readAsync,readBinary;if(ENVIRONMENT_IS_NODE){var fs=require("node:fs");scriptDirectory=__dirname+"/";readBinary=filename=>{filename=isFileURI(filename)?new URL(filename):filename;var ret=fs.readFileSync(filename);return ret};readAsync=async(filename,binary=true)=>{filename=isFileURI(filename)?new URL(filename):filename;var ret=fs.readFileSync(filename,binary?undefined:"utf8");return ret};if(process.argv.length>1){thisProgram=process.argv[1].replace(/\\/g,"/")}programArgs=process.argv.slice(2);quit_=(status,toThrow)=>{process.exitCode=status;throw toThrow}}else if(ENVIRONMENT_IS_WEB||ENVIRONMENT_IS_WORKER){try{scriptDirectory=new URL(".",_scriptName).href}catch{}{if(ENVIRONMENT_IS_WORKER){readBinary=url=>{var xhr=new XMLHttpRequest;xhr.open("GET",url,false);xhr.responseType="arraybuffer";xhr.send(null);return new Uint8Array(xhr.response)}}readAsync=async url=>{if(isFileURI(url)){return new Promise((resolve,reject)=>{var xhr=new XMLHttpRequest;xhr.open("GET",url,true);xhr.responseType="arraybuffer";xhr.onload=()=>{if(xhr.status==200||xhr.status==0&&xhr.response){resolve(xhr.response);return}reject(xhr.status)};xhr.onerror=reject;xhr.send(null)})}var response=await fetch(url,{credentials:"same-origin"});if(response.ok){return response.arrayBuffer()}throw new Error(response.status+" : "+response.url)}}}else{}var out=console.log.bind(console);var err=console.error.bind(console);var wasmBinary;var ABORT=false;var isFileURI=filename=>filename.startsWith("file://");class EmscriptenEH{}class EmscriptenSjLj extends EmscriptenEH{}var runtimeInitialized=false;function updateMemoryViews(){var b=wasmMemory.buffer;HEAP8=new Int8Array(b);HEAPU8=new Uint8Array(b);HEAPU32=new Uint32Array(b)}function preRun(){var preRun=Module["preRun"];if(preRun){if(typeof preRun=="function")preRun=[preRun];onPreRuns.push(...preRun)}callRuntimeCallbacks(onPreRuns)}function initRuntime(){runtimeInitialized=true;wasmExports["e"]()}function postRun(){var postRun=Module["postRun"];if(postRun){if(typeof postRun=="function")postRun=[postRun];onPostRuns.push(...postRun)}callRuntimeCallbacks(onPostRuns)}function abort(what){Module["onAbort"]?.(what);what=`Aborted(${what})`;err(what);ABORT=true;what+=". Build with -sASSERTIONS for more info.";var e=new WebAssembly.RuntimeError(what);throw e}var wasmBinaryFile;function findWasmBinary(){return locateFile("fp.wasm")}function getBinarySync(file){if(readBinary){return readBinary(file)}throw"both async and sync fetching of the wasm failed"}async function getWasmBinary(binaryFile){if(!wasmBinary){try{var response=await readAsync(binaryFile);return new Uint8Array(response)}catch{}}return getBinarySync(binaryFile)}async function instantiateArrayBuffer(binaryFile,imports){try{var binary=await getWasmBinary(binaryFile);var instance=await WebAssembly.instantiate(binary,imports);return instance}catch(reason){err(`failed to asynchronously prepare wasm: ${reason}`);abort(reason)}}async function instantiateAsync(binary,binaryFile,imports){if(!binary&&!isFileURI(binaryFile)&&!ENVIRONMENT_IS_NODE){try{var response=fetch(binaryFile,{credentials:"same-origin"});var instantiationResult=await WebAssembly.instantiateStreaming(response,imports);return instantiationResult}catch(reason){err(`wasm streaming compile failed: ${reason}`);err("falling back to ArrayBuffer instantiation")}}return instantiateArrayBuffer(binaryFile,imports)}function getWasmImports(){var imports={a:wasmImports};return imports}async function createWasm(){function receiveInstance(instance){wasmExports=instance.exports;assignWasmExports(wasmExports);updateMemoryViews();return wasmExports}function receiveInstantiationResult(result){return receiveInstance(result["instance"])}var info=getWasmImports();var instantiateWasm=Module["instantiateWasm"];if(instantiateWasm){return new Promise(resolve=>{instantiateWasm(info,inst=>resolve(receiveInstance(inst)))})}wasmBinaryFile??=findWasmBinary();var result=await instantiateAsync(wasmBinary,wasmBinaryFile,info);var exports=receiveInstantiationResult(result);return exports}class ExitStatus{name="ExitStatus";constructor(status){this.message=`Program terminated with exit(${status})`;this.status=status}}var callRuntimeCallbacks=callbacks=>{while(callbacks.length>0){callbacks.shift()(Module)}};var onPostRuns=[];var onPreRuns=[];var noExitRuntime=true;var HEAP8;var HEAPU32;class ExceptionInfo{constructor(excPtr){this.excPtr=excPtr;this.ptr=excPtr-24}set_type(type){HEAPU32[this.ptr+4>>2]=type}get_type(){return HEAPU32[this.ptr+4>>2]}set_destructor(destructor){HEAPU32[this.ptr+8>>2]=destructor}get_destructor(){return HEAPU32[this.ptr+8>>2]}set_caught(caught){caught=caught?1:0;HEAP8[this.ptr+12]=caught}get_caught(){return HEAP8[this.ptr+12]!=0}set_rethrown(rethrown){rethrown=rethrown?1:0;HEAP8[this.ptr+13]=rethrown}get_rethrown(){return HEAP8[this.ptr+13]!=0}init(type,destructor){this.set_adjusted_ptr(0);this.set_type(type);this.set_destructor(destructor)}set_adjusted_ptr(adjustedPtr){HEAPU32[this.ptr+16>>2]=adjustedPtr}get_adjusted_ptr(){return HEAPU32[this.ptr+16>>2]}}var uncaughtExceptionCount=0;var __Unwind_RaiseException=ex=>{abort()};var ___cxa_throw=(ptr,type,destructor)=>{var info=new ExceptionInfo(ptr);info.init(type,destructor);uncaughtExceptionCount++;__Unwind_RaiseException(ptr)};var __abort_js=()=>abort("");var abortOnCannotGrowMemory=requestedSize=>{abort("OOM")};var HEAPU8;var _emscripten_resize_heap=requestedSize=>{var oldSize=HEAPU8.length;requestedSize>>>=0;abortOnCannotGrowMemory(requestedSize)};{if(Module["noExitRuntime"])noExitRuntime=Module["noExitRuntime"];if(Module["print"])out=Module["print"];if(Module["printErr"])err=Module["printErr"];if(Module["arguments"])programArgs=Module["arguments"];if(Module["thisProgram"])thisProgram=Module["thisProgram"];var preInit=Module["preInit"];if(preInit){if(typeof preInit=="function")Module["preInit"]=preInit=[preInit];while(preInit.length>0){preInit.shift()()}}}var _hash_string,memory,__indirect_function_table,wasmMemory;function assignWasmExports(wasmExports){_hash_string=Module["_hash_string"]=wasmExports["f"];memory=wasmMemory=wasmExports["d"];__indirect_function_table=wasmExports["__indirect_function_table"]}var wasmImports={c:___cxa_throw,a:__abort_js,b:_emscripten_resize_heap};async function run(){preRun();var setStatus=Module["setStatus"];if(setStatus){setStatus("Running...");await new Promise(resolve=>setTimeout(resolve,1));setTimeout(setStatus,1,"")}if(ABORT)return;initRuntime();Module["onRuntimeInitialized"]?.();postRun()}var wasmExports;wasmExports=await createWasm();await run();
|
|
1
|
+
var createFingerprintModule=(()=>{var _scriptName=globalThis.document?.currentScript?.src;return async function(moduleArg={}){var Module=moduleArg;var ENVIRONMENT_IS_WEB=!!globalThis.window;var ENVIRONMENT_IS_WORKER=!!globalThis.WorkerGlobalScope;var ENVIRONMENT_IS_NODE=globalThis.process?.versions?.node&&globalThis.process?.type!="renderer";var programArgs=[];var thisProgram="./this.program";var quit_=(status,toThrow)=>{throw toThrow};if(typeof __filename!="undefined"){_scriptName=__filename}else if(ENVIRONMENT_IS_WORKER){_scriptName=self.location.href}var scriptDirectory="";function locateFile(path){if(Module["locateFile"]){return Module["locateFile"](path,scriptDirectory)}return scriptDirectory+path}var readAsync,readBinary;if(ENVIRONMENT_IS_NODE){var fs=require("node:fs");scriptDirectory=__dirname+"/";readBinary=filename=>{filename=isFileURI(filename)?new URL(filename):filename;var ret=fs.readFileSync(filename);return ret};readAsync=async(filename,binary=true)=>{filename=isFileURI(filename)?new URL(filename):filename;var ret=fs.readFileSync(filename,binary?undefined:"utf8");return ret};if(process.argv.length>1){thisProgram=process.argv[1].replace(/\\/g,"/")}programArgs=process.argv.slice(2);quit_=(status,toThrow)=>{process.exitCode=status;throw toThrow}}else if(ENVIRONMENT_IS_WEB||ENVIRONMENT_IS_WORKER){try{scriptDirectory=new URL(".",_scriptName).href}catch{}{if(ENVIRONMENT_IS_WORKER){readBinary=url=>{var xhr=new XMLHttpRequest;xhr.open("GET",url,false);xhr.responseType="arraybuffer";xhr.send(null);return new Uint8Array(xhr.response)}}readAsync=async url=>{if(isFileURI(url)){return new Promise((resolve,reject)=>{var xhr=new XMLHttpRequest;xhr.open("GET",url,true);xhr.responseType="arraybuffer";xhr.onload=()=>{if(xhr.status==200||xhr.status==0&&xhr.response){resolve(xhr.response);return}reject(xhr.status)};xhr.onerror=reject;xhr.send(null)})}var response=await fetch(url,{credentials:"same-origin"});if(response.ok){return response.arrayBuffer()}throw new Error(response.status+" : "+response.url)}}}else{}var out=console.log.bind(console);var err=console.error.bind(console);var wasmBinary;var ABORT=false;var isFileURI=filename=>filename.startsWith("file://");class EmscriptenEH{}class EmscriptenSjLj extends EmscriptenEH{}var runtimeInitialized=false;function updateMemoryViews(){var b=wasmMemory.buffer;HEAP8=new Int8Array(b);HEAPU8=new Uint8Array(b);HEAPU32=new Uint32Array(b)}function preRun(){var preRun=Module["preRun"];if(preRun){if(typeof preRun=="function")preRun=[preRun];onPreRuns.push(...preRun)}callRuntimeCallbacks(onPreRuns)}function initRuntime(){runtimeInitialized=true;wasmExports["e"]()}function postRun(){var postRun=Module["postRun"];if(postRun){if(typeof postRun=="function")postRun=[postRun];onPostRuns.push(...postRun)}callRuntimeCallbacks(onPostRuns)}function abort(what){Module["onAbort"]?.(what);what=`Aborted(${what})`;err(what);ABORT=true;what+=". Build with -sASSERTIONS for more info.";var e=new WebAssembly.RuntimeError(what);throw e}var wasmBinaryFile;function findWasmBinary(){return locateFile("fp.wasm")}function getBinarySync(file){if(readBinary){return readBinary(file)}throw"both async and sync fetching of the wasm failed"}async function getWasmBinary(binaryFile){if(!wasmBinary){try{var response=await readAsync(binaryFile);return new Uint8Array(response)}catch{}}return getBinarySync(binaryFile)}async function instantiateArrayBuffer(binaryFile,imports){try{var binary=await getWasmBinary(binaryFile);var instance=await WebAssembly.instantiate(binary,imports);return instance}catch(reason){err(`failed to asynchronously prepare wasm: ${reason}`);abort(reason)}}async function instantiateAsync(binary,binaryFile,imports){if(!binary&&!isFileURI(binaryFile)&&!ENVIRONMENT_IS_NODE){try{var response=fetch(binaryFile,{credentials:"same-origin"});var instantiationResult=await WebAssembly.instantiateStreaming(response,imports);return instantiationResult}catch(reason){err(`wasm streaming compile failed: ${reason}`);err("falling back to ArrayBuffer instantiation")}}return instantiateArrayBuffer(binaryFile,imports)}function getWasmImports(){var imports={a:wasmImports};return imports}async function createWasm(){function receiveInstance(instance){wasmExports=instance.exports;assignWasmExports(wasmExports);updateMemoryViews();return wasmExports}function receiveInstantiationResult(result){return receiveInstance(result["instance"])}var info=getWasmImports();var instantiateWasm=Module["instantiateWasm"];if(instantiateWasm){return new Promise(resolve=>{instantiateWasm(info,inst=>resolve(receiveInstance(inst)))})}wasmBinaryFile??=findWasmBinary();var result=await instantiateAsync(wasmBinary,wasmBinaryFile,info);var exports=receiveInstantiationResult(result);return exports}class ExitStatus{name="ExitStatus";constructor(status){this.message=`Program terminated with exit(${status})`;this.status=status}}var callRuntimeCallbacks=callbacks=>{while(callbacks.length>0){callbacks.shift()(Module)}};var onPostRuns=[];var onPreRuns=[];var noExitRuntime=true;var HEAP8;var HEAPU32;class ExceptionInfo{constructor(excPtr){this.excPtr=excPtr;this.ptr=excPtr-24}set_type(type){HEAPU32[this.ptr+4>>2]=type}get_type(){return HEAPU32[this.ptr+4>>2]}set_destructor(destructor){HEAPU32[this.ptr+8>>2]=destructor}get_destructor(){return HEAPU32[this.ptr+8>>2]}set_caught(caught){caught=caught?1:0;HEAP8[this.ptr+12]=caught}get_caught(){return HEAP8[this.ptr+12]!=0}set_rethrown(rethrown){rethrown=rethrown?1:0;HEAP8[this.ptr+13]=rethrown}get_rethrown(){return HEAP8[this.ptr+13]!=0}init(type,destructor){this.set_adjusted_ptr(0);this.set_type(type);this.set_destructor(destructor)}set_adjusted_ptr(adjustedPtr){HEAPU32[this.ptr+16>>2]=adjustedPtr}get_adjusted_ptr(){return HEAPU32[this.ptr+16>>2]}}var uncaughtExceptionCount=0;var __Unwind_RaiseException=ex=>{abort()};var ___cxa_throw=(ptr,type,destructor)=>{var info=new ExceptionInfo(ptr);info.init(type,destructor);uncaughtExceptionCount++;__Unwind_RaiseException(ptr)};var __abort_js=()=>abort("");var abortOnCannotGrowMemory=requestedSize=>{abort("OOM")};var HEAPU8;var _emscripten_resize_heap=requestedSize=>{var oldSize=HEAPU8.length;requestedSize>>>=0;abortOnCannotGrowMemory(requestedSize)};{if(Module["noExitRuntime"])noExitRuntime=Module["noExitRuntime"];if(Module["print"])out=Module["print"];if(Module["printErr"])err=Module["printErr"];if(Module["arguments"])programArgs=Module["arguments"];if(Module["thisProgram"])thisProgram=Module["thisProgram"];var preInit=Module["preInit"];if(preInit){if(typeof preInit=="function")Module["preInit"]=preInit=[preInit];while(preInit.length>0){preInit.shift()()}}}var _hash_string,_solve_cpu_target,_solve_memory_challenge,memory,__indirect_function_table,wasmMemory;function assignWasmExports(wasmExports){_hash_string=Module["_hash_string"]=wasmExports["f"];_solve_cpu_target=Module["_solve_cpu_target"]=wasmExports["g"];_solve_memory_challenge=Module["_solve_memory_challenge"]=wasmExports["h"];memory=wasmMemory=wasmExports["d"];__indirect_function_table=wasmExports["__indirect_function_table"]}var wasmImports={c:___cxa_throw,a:__abort_js,b:_emscripten_resize_heap};async function run(){preRun();var setStatus=Module["setStatus"];if(setStatus){setStatus("Running...");await new Promise(resolve=>setTimeout(resolve,1));setTimeout(setStatus,1,"")}if(ABORT)return;initRuntime();Module["onRuntimeInitialized"]?.();postRun()}var wasmExports;wasmExports=await createWasm();await run();
|
|
2
2
|
;return Module}})();if(typeof exports==="object"&&typeof module==="object"){module.exports=createFingerprintModule;module.exports.default=createFingerprintModule}else if(typeof define==="function"&&define["amd"])define([],()=>createFingerprintModule);
|
package/public/fp.wasm
CHANGED
|
Binary file
|
package/src/js/build-client.js
CHANGED
|
@@ -14,7 +14,7 @@ const __dirname = dirname(__filename);
|
|
|
14
14
|
function buildWasm() {
|
|
15
15
|
return new Promise((resolve) => {
|
|
16
16
|
console.log('Attempting to build WASM module (optional)...');
|
|
17
|
-
const command = "em++ src/cpp/main.cpp src/cpp/utils.cpp -o public/fp.js -s WASM=1 -s MODULARIZE=1 -s EXPORT_NAME='createFingerprintModule' -s \"EXPORTED_FUNCTIONS=['_hash_string']\" -O3 --no-entry";
|
|
17
|
+
const command = "em++ src/cpp/main.cpp src/cpp/utils.cpp -o public/fp.js -s WASM=1 -s MODULARIZE=1 -s EXPORT_NAME='createFingerprintModule' -s \"EXPORTED_FUNCTIONS=['_hash_string','_solve_cpu_target','_solve_memory_challenge']\" -O3 --no-entry";
|
|
18
18
|
|
|
19
19
|
exec(command, (error, stdout, stderr) => {
|
|
20
20
|
if (error) {
|
|
@@ -553,6 +553,8 @@ const ClientLibrary = {
|
|
|
553
553
|
if (typeof wasmModule._hash_string !== 'function') {
|
|
554
554
|
throw new Error('WASM module did not export _hash_string.');
|
|
555
555
|
}
|
|
556
|
+
window.wasmModule = wasmModule;
|
|
557
|
+
ClientLibrary.wasmModule = wasmModule;
|
|
556
558
|
|
|
557
559
|
// 4. Remplacer la fonction de hachage par la version WASM
|
|
558
560
|
activeCyrb53 = (str) => {
|