@prosopo/fingerprint 2.7.17 → 2.7.19

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.
@@ -1,5 +1,5 @@
1
1
 
2
- > @prosopo/fingerprint@2.7.17 build:cjs
2
+ > @prosopo/fingerprint@2.7.19 build:cjs
3
3
  > NODE_ENV=${NODE_ENV:-development}; vite build --config vite.cjs.config.ts --mode $NODE_ENV
4
4
 
5
5
  ViteCommonJSConfig: .
@@ -21,13 +21,15 @@ ViteCommonJSConfig: .
21
21
  '@prosopo/util-crypto'
22
22
  ]
23
23
  }
24
- vite v6.4.1 building SSR bundle for production...
24
+ The plugin "vite-tsconfig-paths" is detected. Vite now supports tsconfig paths resolution natively via the resolve.tsconfigPaths option. You can remove the plugin and set resolve.tsconfigPaths: true in your Vite config instead.
25
+ vite v8.1.5 building ssr environment for production...
25
26
  Bundle build started
26
- transforming...
27
- Build end
28
- ✓ 3 modules transformed.
27
+ 
28
+ ✓ 4 modules transformed.
29
29
  rendering chunks...
30
- dist/cjs/merkle.cjs 2.72 kB
31
- dist/cjs/proof.cjs 3.17 kB
32
- dist/cjs/index.cjs 3.38 kB
33
- ✓ built in 179ms
30
+ computing gzip size...
31
+ dist/cjs/index.cjs 2.50 kB │ gzip: 0.89 kB
32
+ dist/cjs/merkle.cjs 2.84 kB │ gzip: 1.09 kB
33
+ dist/cjs/proof.cjs 4.31 kB │ gzip: 1.70 kB
34
+
35
+ ✓ built in 56ms
@@ -1,8 +1,8 @@
1
1
 
2
- > @prosopo/fingerprint@2.7.17 build:tsc
2
+ > @prosopo/fingerprint@2.7.19 build:tsc
3
3
  > tsc --build --verbose
4
4
 
5
- 12:16:59 PM - Projects in this build:
5
+ 8:59:03 PM - Projects in this build:
6
6
  * ../../dev/config/tsconfig.json
7
7
  * ../fingerprintjs/tsconfig.json
8
8
  * ../locale/tsconfig.json
@@ -11,19 +11,19 @@
11
11
  * ../types/tsconfig.json
12
12
  * tsconfig.json
13
13
 
14
- 12:16:59 PM - Project '../../dev/config/tsconfig.json' is up to date because newest input '../../dev/config/src/index.ts' is older than output '../../dev/config/tsconfig.tsbuildinfo'
14
+ 8:59:03 PM - Project '../../dev/config/tsconfig.json' is up to date because newest input '../../dev/config/src/webpack/webpack.config.ts' is older than output '../../dev/config/tsconfig.tsbuildinfo'
15
15
 
16
- 12:16:59 PM - Project '../fingerprintjs/tsconfig.json' is up to date because newest input '../fingerprintjs/src/utils/browser.ts' is older than output '../fingerprintjs/tsconfig.tsbuildinfo'
16
+ 8:59:03 PM - Project '../fingerprintjs/tsconfig.json' is up to date because newest input '../fingerprintjs/src/utils/browser.ts' is older than output '../fingerprintjs/tsconfig.tsbuildinfo'
17
17
 
18
- 12:16:59 PM - Project '../locale/tsconfig.json' is up to date because newest input '../locale/src/translationKey.ts' is older than output '../locale/tsconfig.tsbuildinfo'
18
+ 8:59:03 PM - Project '../locale/tsconfig.json' is up to date because newest input '../locale/src/translationKey.ts' is older than output '../locale/tsconfig.tsbuildinfo'
19
19
 
20
- 12:17:00 PM - Project '../util/tsconfig.json' is up to date because newest input '../util/src/url.ts' is older than output '../util/tsconfig.tsbuildinfo'
20
+ 8:59:03 PM - Project '../util/tsconfig.json' is up to date because newest input '../util/src/url.ts' is older than output '../util/tsconfig.tsbuildinfo'
21
21
 
22
- 12:17:00 PM - Project '../util-crypto/tsconfig.json' is up to date because newest input '../util-crypto/src/types.ts' is older than output '../util-crypto/tsconfig.tsbuildinfo'
22
+ 8:59:03 PM - Project '../util-crypto/tsconfig.json' is up to date because newest input '../util-crypto/src/types.ts' is older than output '../util-crypto/tsconfig.tsbuildinfo'
23
23
 
24
- 12:17:00 PM - Project '../types/tsconfig.json' is up to date because newest input '../types/src/provider/api.ts' is older than output '../types/tsconfig.tsbuildinfo'
24
+ 8:59:03 PM - Project '../types/tsconfig.json' is up to date because newest input '../types/src/provider/api.ts' is older than output '../types/tsconfig.tsbuildinfo'
25
25
 
26
- 12:17:00 PM - Project 'tsconfig.json' is out of date because output file 'tsconfig.tsbuildinfo' does not exist
26
+ 8:59:03 PM - Project 'tsconfig.json' is out of date because output file 'tsconfig.tsbuildinfo' does not exist
27
27
 
28
- 12:17:00 PM - Building project '/home/runner/work/captcha/captcha/packages/fingerprint/tsconfig.json'...
28
+ 8:59:03 PM - Building project '/home/runner/work/captcha/captcha/packages/fingerprint/tsconfig.json'...
29
29
 
@@ -1,9 +1,9 @@
1
1
 
2
- > @prosopo/fingerprint@2.7.17 build
2
+ > @prosopo/fingerprint@2.7.19 build
3
3
  > npm run build:cross-env -- --mode ${NODE_ENV:-development}
4
4
 
5
5
 
6
- > @prosopo/fingerprint@2.7.17 build:cross-env
6
+ > @prosopo/fingerprint@2.7.19 build:cross-env
7
7
  > vite build --config vite.esm.config.ts --mode production
8
8
 
9
9
  ViteEsmConfig: .
@@ -25,13 +25,16 @@ ViteEsmConfig: .
25
25
  '@prosopo/util-crypto'
26
26
  ]
27
27
  }
28
- vite v6.4.1 building SSR bundle for production...
28
+ The plugin "vite-tsconfig-paths" is detected. Vite now supports tsconfig paths resolution natively via the resolve.tsconfigPaths option. You can remove the plugin and set resolve.tsconfigPaths: true in your Vite config instead.
29
+ vite v8.1.5 building ssr environment for production...
29
30
  Bundle build started
30
- transforming...
31
- Build end
32
- ✓ 3 modules transformed.
31
+ 
32
+ ✓ 4 modules transformed.
33
33
  rendering chunks...
34
- dist/index.js 1.92 kB
35
- dist/merkle.js 2.50 kB
36
- dist/proof.js 2.92 kB
37
- ✓ built in 199ms
34
+ computing gzip size...
35
+ dist/_virtual/_rolldown/runtime.js 0.04 kB │ gzip: 0.06 kB
36
+ dist/index.js 2.06 kB │ gzip: 0.81 kB
37
+ dist/merkle.js 2.68 kB │ gzip: 1.06 kB
38
+ dist/proof.js 4.03 kB │ gzip: 1.66 kB
39
+
40
+ ✓ built in 68ms
package/CHANGELOG.md CHANGED
@@ -1,5 +1,20 @@
1
1
  # @prosopo/fingerprint
2
2
 
3
+ ## 2.7.19
4
+ ### Patch Changes
5
+
6
+ - e14fce6: chore(deps): bump vite to 6.4.3 and mongoose to 8.24.1, and adjust types for the mongoose 8.24 Document/ObjectId changes
7
+ - Updated dependencies [103318c]
8
+ - Updated dependencies [270a8d8]
9
+ - Updated dependencies [e14fce6]
10
+ - @prosopo/types@4.10.0
11
+
12
+ ## 2.7.18
13
+ ### Patch Changes
14
+
15
+ - Updated dependencies [a0cb39e]
16
+ - @prosopo/types@4.9.12
17
+
3
18
  ## 2.7.17
4
19
  ### Patch Changes
5
20
 
@@ -0,0 +1,3 @@
1
+ import "node:module";
2
+ //#endregion
3
+ export {};
@@ -1,82 +1,54 @@
1
- "use strict";
2
- var __create = Object.create;
3
- var __defProp = Object.defineProperty;
4
- var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
5
- var __getOwnPropNames = Object.getOwnPropertyNames;
6
- var __getProtoOf = Object.getPrototypeOf;
7
- var __hasOwnProp = Object.prototype.hasOwnProperty;
8
- var __copyProps = (to, from, except, desc) => {
9
- if (from && typeof from === "object" || typeof from === "function") {
10
- for (let key of __getOwnPropNames(from))
11
- if (!__hasOwnProp.call(to, key) && key !== except)
12
- __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
13
- }
14
- return to;
15
- };
16
- var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
17
- // If the importer is in node compatibility mode or this is not an ESM
18
- // file that has been converted to a CommonJS file using a Babel-
19
- // compatible transform (i.e. "__esModule" has not been set), then set
20
- // "default" to the CommonJS "module.exports" for node compatibility.
21
- isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
22
- mod
23
- ));
24
1
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
25
- const proof = require("./proof.cjs");
26
- const merkle = require("./merkle.cjs");
27
- const EXCLUDED_SOURCES = ["webGlExtensions"];
28
- const FingerprintJSImport = async () => import("@prosopo/fingerprintjs");
29
- let componentsCache = null;
30
- const loadComponents = () => {
31
- if (!componentsCache) {
32
- const pending = (async () => {
33
- const { sources, loadSources, prepareForSources } = await FingerprintJSImport();
34
- await prepareForSources();
35
- const sourceOptions = {
36
- cache: {}
37
- };
38
- const getComponents = loadSources(
39
- sources,
40
- sourceOptions,
41
- EXCLUDED_SOURCES
42
- );
43
- return getComponents();
44
- })();
45
- componentsCache = pending;
46
- pending.catch(() => {
47
- if (componentsCache === pending) {
48
- componentsCache = null;
49
- }
50
- });
51
- }
52
- return componentsCache;
2
+ const require_merkle = require("./merkle.cjs");
3
+ const require_proof = require("./proof.cjs");
4
+ //#region src/index.ts
5
+ var EXCLUDED_SOURCES = ["webGlExtensions"];
6
+ var FingerprintJSImport = async () => import("@prosopo/fingerprintjs");
7
+ var componentsCache = null;
8
+ var loadComponents = () => {
9
+ if (!componentsCache) {
10
+ const pending = (async () => {
11
+ const { sources, loadSources, prepareForSources } = await FingerprintJSImport();
12
+ await prepareForSources();
13
+ return loadSources(sources, { cache: {} }, EXCLUDED_SOURCES)();
14
+ })();
15
+ componentsCache = pending;
16
+ pending.catch(() => {
17
+ if (componentsCache === pending) componentsCache = null;
18
+ });
19
+ }
20
+ return componentsCache;
53
21
  };
54
- const getFingerprint = async () => {
55
- const [{ hashComponents }, components] = await Promise.all([
56
- FingerprintJSImport(),
57
- loadComponents()
58
- ]);
59
- return hashComponents(components);
22
+ var getFingerprint = async () => {
23
+ const [{ hashComponents }, components] = await Promise.all([FingerprintJSImport(), loadComponents()]);
24
+ return hashComponents(components);
60
25
  };
61
- const getFingerprintProof = async (discloseKeys) => {
62
- const components = await loadComponents();
63
- return proof.buildFingerprintProofFromComponents(components, discloseKeys);
26
+ /**
27
+ * Produce a proof of fingerprint: a Merkle commitment to the full component set
28
+ * plus a selective disclosure of the requested components. Callers should pass
29
+ * {@link FINGERPRINT_DISCLOSURE_KEYS} — omitting `discloseKeys` discloses every
30
+ * component, which produces a very large payload. Derived from the same
31
+ * component run as {@link getFingerprint}.
32
+ */
33
+ var getFingerprintProof = async (discloseKeys) => {
34
+ const components = await loadComponents();
35
+ return require_proof.buildFingerprintProofFromComponents(components, discloseKeys);
64
36
  };
65
- const prefetchFingerprint = () => {
66
- loadComponents().catch(() => {
67
- });
37
+ var prefetchFingerprint = () => {
38
+ loadComponents().catch(() => {});
68
39
  };
69
- exports.FINGERPRINT_DISCLOSURE_KEYS = proof.FINGERPRINT_DISCLOSURE_KEYS;
70
- exports.FINGERPRINT_PROOF_VERSION = proof.FINGERPRINT_PROOF_VERSION;
71
- exports.buildFingerprintProofFromComponents = proof.buildFingerprintProofFromComponents;
72
- exports.encodeFingerprintProof = proof.encodeFingerprintProof;
73
- exports.leafHashForContent = proof.leafHashForContent;
74
- exports.verifyFingerprintProofStructure = proof.verifyFingerprintProofStructure;
75
- exports.buildMerkleLayers = merkle.buildMerkleLayers;
76
- exports.hashMerklePair = merkle.hashMerklePair;
77
- exports.merkleProofFromLayers = merkle.merkleProofFromLayers;
78
- exports.merkleRootFromLayers = merkle.merkleRootFromLayers;
79
- exports.verifyMerkleProof = merkle.verifyMerkleProof;
40
+ //#endregion
41
+ exports.FINGERPRINT_DISCLOSURE_KEYS = require_proof.FINGERPRINT_DISCLOSURE_KEYS;
42
+ exports.FINGERPRINT_PROOF_VERSION = require_proof.FINGERPRINT_PROOF_VERSION;
43
+ exports.buildFingerprintProofFromComponents = require_proof.buildFingerprintProofFromComponents;
44
+ exports.buildMerkleLayers = require_merkle.buildMerkleLayers;
45
+ exports.encodeFingerprintProof = require_proof.encodeFingerprintProof;
80
46
  exports.getFingerprint = getFingerprint;
81
47
  exports.getFingerprintProof = getFingerprintProof;
48
+ exports.hashMerklePair = require_merkle.hashMerklePair;
49
+ exports.leafHashForContent = require_proof.leafHashForContent;
50
+ exports.merkleProofFromLayers = require_merkle.merkleProofFromLayers;
51
+ exports.merkleRootFromLayers = require_merkle.merkleRootFromLayers;
82
52
  exports.prefetchFingerprint = prefetchFingerprint;
53
+ exports.verifyFingerprintProofStructure = require_proof.verifyFingerprintProofStructure;
54
+ exports.verifyMerkleProof = require_merkle.verifyMerkleProof;
@@ -1,81 +1,71 @@
1
- "use strict";
2
- Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
3
- const utilCrypto = require("@prosopo/util-crypto");
4
- const at = (arr, index) => {
5
- const value = arr[index];
6
- if (value === void 0) {
7
- throw new Error(
8
- `merkle: index ${index} out of range (length ${arr.length})`
9
- );
10
- }
11
- return value;
1
+ let _prosopo_util_crypto = require("@prosopo/util-crypto");
2
+ //#region src/merkle.ts
3
+ var at = (arr, index) => {
4
+ const value = arr[index];
5
+ if (value === void 0) throw new Error(`merkle: index ${index} out of range (length ${arr.length})`);
6
+ return value;
12
7
  };
13
- const hashMerklePair = (left, right) => utilCrypto.hexHashArray([left, right]);
14
- const buildMerkleLayers = (leafHashes) => {
15
- if (leafHashes.length === 0) {
16
- throw new Error("merkle: cannot build a tree with no leaves");
17
- }
18
- const layers = [[...leafHashes]];
19
- let current = leafHashes;
20
- while (current.length > 1) {
21
- const next = [];
22
- for (let i = 0; i < current.length; i += 2) {
23
- const left = at(current, i);
24
- const right = i + 1 < current.length ? at(current, i + 1) : left;
25
- next.push(hashMerklePair(left, right));
26
- }
27
- layers.push(next);
28
- current = next;
29
- }
30
- return layers;
8
+ /** Hash a pair of child hashes into their parent. */
9
+ var hashMerklePair = (left, right) => (0, _prosopo_util_crypto.hexHashArray)([left, right]);
10
+ /**
11
+ * Build every layer of the Merkle tree, bottom-up. Layer 0 is the leaf hashes,
12
+ * the final layer is `[root]`. An odd node at the end of a layer is paired with
13
+ * itself.
14
+ */
15
+ var buildMerkleLayers = (leafHashes) => {
16
+ if (leafHashes.length === 0) throw new Error("merkle: cannot build a tree with no leaves");
17
+ const layers = [[...leafHashes]];
18
+ let current = leafHashes;
19
+ while (current.length > 1) {
20
+ const next = [];
21
+ for (let i = 0; i < current.length; i += 2) {
22
+ const left = at(current, i);
23
+ const right = i + 1 < current.length ? at(current, i + 1) : left;
24
+ next.push(hashMerklePair(left, right));
25
+ }
26
+ layers.push(next);
27
+ current = next;
28
+ }
29
+ return layers;
31
30
  };
32
- const merkleRootFromLayers = (layers) => at(at(layers, layers.length - 1), 0);
33
- const merkleProofFromLayers = (layers, leafHash) => {
34
- const proof = [];
35
- let hash = leafHash;
36
- for (let layerNum = 0; layerNum < layers.length - 1; layerNum++) {
37
- const layer = at(layers, layerNum);
38
- const index = layer.indexOf(hash);
39
- if (index === -1) {
40
- throw new Error("merkle: leaf hash not present in layer");
41
- }
42
- let partnerIndex = index % 2 === 1 ? index - 1 : index + 1;
43
- if (partnerIndex > layer.length - 1) {
44
- partnerIndex = index;
45
- }
46
- const partner = at(layer, partnerIndex);
47
- const pair = partnerIndex > index ? [hash, partner] : [partner, hash];
48
- proof.push(pair);
49
- hash = hashMerklePair(pair[0], pair[1]);
50
- }
51
- return [...proof, [merkleRootFromLayers(layers)]];
31
+ var merkleRootFromLayers = (layers) => at(at(layers, layers.length - 1), 0);
32
+ /** Produce the sibling path proving `leafHash` belongs to the tree. */
33
+ var merkleProofFromLayers = (layers, leafHash) => {
34
+ const proof = [];
35
+ let hash = leafHash;
36
+ for (let layerNum = 0; layerNum < layers.length - 1; layerNum++) {
37
+ const layer = at(layers, layerNum);
38
+ const index = layer.indexOf(hash);
39
+ if (index === -1) throw new Error("merkle: leaf hash not present in layer");
40
+ let partnerIndex = index % 2 === 1 ? index - 1 : index + 1;
41
+ if (partnerIndex > layer.length - 1) partnerIndex = index;
42
+ const partner = at(layer, partnerIndex);
43
+ const pair = partnerIndex > index ? [hash, partner] : [partner, hash];
44
+ proof.push(pair);
45
+ hash = hashMerklePair(pair[0], pair[1]);
46
+ }
47
+ return [...proof, [merkleRootFromLayers(layers)]];
52
48
  };
53
- const verifyMerkleProof = (leafHash, proof) => {
54
- try {
55
- const firstLayer = proof[0];
56
- if (firstLayer === void 0 || firstLayer.indexOf(leafHash) === -1) {
57
- return false;
58
- }
59
- if (proof.length === 1) {
60
- return at(firstLayer, 0) === leafHash;
61
- }
62
- const root = at(at(proof, proof.length - 1), 0);
63
- let hash = leafHash;
64
- for (let i = 0; i < proof.length - 1; i++) {
65
- const layer = at(proof, i);
66
- if (layer.indexOf(hash) === -1) {
67
- return false;
68
- }
69
- hash = hashMerklePair(at(layer, 0), at(layer, 1));
70
- if (at(proof, i + 1).indexOf(hash) === -1) {
71
- return false;
72
- }
73
- }
74
- return hash === root;
75
- } catch {
76
- return false;
77
- }
49
+ /** Verify a leaf + sibling path recomputes to the proof's embedded root. */
50
+ var verifyMerkleProof = (leafHash, proof) => {
51
+ try {
52
+ const firstLayer = proof[0];
53
+ if (firstLayer === void 0 || firstLayer.indexOf(leafHash) === -1) return false;
54
+ if (proof.length === 1) return at(firstLayer, 0) === leafHash;
55
+ const root = at(at(proof, proof.length - 1), 0);
56
+ let hash = leafHash;
57
+ for (let i = 0; i < proof.length - 1; i++) {
58
+ const layer = at(proof, i);
59
+ if (layer.indexOf(hash) === -1) return false;
60
+ hash = hashMerklePair(at(layer, 0), at(layer, 1));
61
+ if (at(proof, i + 1).indexOf(hash) === -1) return false;
62
+ }
63
+ return hash === root;
64
+ } catch {
65
+ return false;
66
+ }
78
67
  };
68
+ //#endregion
79
69
  exports.buildMerkleLayers = buildMerkleLayers;
80
70
  exports.hashMerklePair = hashMerklePair;
81
71
  exports.merkleProofFromLayers = merkleProofFromLayers;
@@ -1,81 +1,99 @@
1
- "use strict";
2
- Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
3
- const utilCrypto = require("@prosopo/util-crypto");
4
- const merkle = require("./merkle.cjs");
5
- const FINGERPRINT_PROOF_VERSION = 1;
6
- const FINGERPRINT_DISCLOSURE_KEYS = [
7
- "colorDepth",
8
- "cookiesEnabled",
9
- "sessionStorage",
10
- "localStorage",
11
- "timezone",
12
- "hardwareConcurrency",
13
- "languages",
14
- "architecture"
1
+ const require_merkle = require("./merkle.cjs");
2
+ let _prosopo_util_crypto = require("@prosopo/util-crypto");
3
+ //#region src/proof.ts
4
+ var FINGERPRINT_PROOF_VERSION = 1;
5
+ /**
6
+ * The fixed set of components the client discloses in a proof of fingerprint.
7
+ * Disclosing every component (the previous default) made the proof enormous —
8
+ * each disclosure carries a full Merkle path and its raw value, and components
9
+ * like webgl/audio/fonts have very large values. Selective disclosure keeps the
10
+ * commitment (`root`) over the whole component set while only these cheap,
11
+ * stable scalar components carry a path + value, shrinking the payload ~10x.
12
+ *
13
+ * The provider-side validator's bounds MUST be a subset of these keys: a bounded
14
+ * key that isn't disclosed would always fail validation as `missing:<key>`.
15
+ */
16
+ var FINGERPRINT_DISCLOSURE_KEYS = [
17
+ "colorDepth",
18
+ "cookiesEnabled",
19
+ "sessionStorage",
20
+ "localStorage",
21
+ "timezone",
22
+ "hardwareConcurrency",
23
+ "languages",
24
+ "architecture"
15
25
  ];
16
- const escapeKey = (key) => key.replace(/([:|\\])/g, "\\$1");
17
- const componentLeafContent = (key, component) => {
18
- const serialized = "error" in component ? "error" : JSON.stringify(component.value);
19
- return `${escapeKey(key)}:${serialized}`;
26
+ var escapeKey = (key) => key.replace(/([:|\\])/g, "\\$1");
27
+ var componentLeafContent = (key, component) => {
28
+ const serialized = "error" in component ? "error" : JSON.stringify(component.value);
29
+ return `${escapeKey(key)}:${serialized}`;
20
30
  };
21
- const disclosureLeafContent = (disclosure) => {
22
- const serialized = disclosure.error ? "error" : JSON.stringify(disclosure.value);
23
- return `${escapeKey(disclosure.key)}:${serialized}`;
31
+ var disclosureLeafContent = (disclosure) => {
32
+ const serialized = disclosure.error ? "error" : JSON.stringify(disclosure.value);
33
+ return `${escapeKey(disclosure.key)}:${serialized}`;
24
34
  };
25
- const leafHashForContent = (content) => utilCrypto.hexHash(content);
26
- const buildFingerprintProofFromComponents = (components, discloseKeys) => {
27
- const keys = Object.keys(components).sort();
28
- if (keys.length === 0) {
29
- throw new Error("fingerprint proof: no components to commit to");
30
- }
31
- const leafHashes = keys.map((key) => {
32
- const component = components[key];
33
- if (component === void 0) {
34
- throw new Error(`fingerprint proof: missing component ${key}`);
35
- }
36
- return leafHashForContent(componentLeafContent(key, component));
37
- });
38
- const layers = merkle.buildMerkleLayers(leafHashes);
39
- const root = merkle.merkleRootFromLayers(layers);
40
- const disclose = discloseKeys ?? keys;
41
- const disclosures = [];
42
- for (const key of disclose) {
43
- const index = keys.indexOf(key);
44
- if (index === -1) {
45
- continue;
46
- }
47
- const component = components[key];
48
- const leafHash = leafHashes[index];
49
- if (component === void 0 || leafHash === void 0) {
50
- continue;
51
- }
52
- const proof = merkle.merkleProofFromLayers(layers, leafHash);
53
- disclosures.push(
54
- "error" in component ? { key, error: true, proof } : { key, value: component.value, proof }
55
- );
56
- }
57
- return { v: FINGERPRINT_PROOF_VERSION, root, disclosures };
35
+ var leafHashForContent = (content) => (0, _prosopo_util_crypto.hexHash)(content);
36
+ /**
37
+ * Build a {@link FingerprintProof} from an already-resolved FingerprintJS
38
+ * components map. The commitment always covers every component (in sorted key
39
+ * order); `discloseKeys` selects which components are revealed (defaulting to
40
+ * all). Keys that are not present in the fingerprint are skipped — a validator
41
+ * should treat an expected-but-absent disclosure as a failure.
42
+ */
43
+ var buildFingerprintProofFromComponents = (components, discloseKeys) => {
44
+ const keys = Object.keys(components).sort();
45
+ if (keys.length === 0) throw new Error("fingerprint proof: no components to commit to");
46
+ const leafHashes = keys.map((key) => {
47
+ const component = components[key];
48
+ if (component === void 0) throw new Error(`fingerprint proof: missing component ${key}`);
49
+ return leafHashForContent(componentLeafContent(key, component));
50
+ });
51
+ const layers = require_merkle.buildMerkleLayers(leafHashes);
52
+ const root = require_merkle.merkleRootFromLayers(layers);
53
+ const disclose = discloseKeys ?? keys;
54
+ const disclosures = [];
55
+ for (const key of disclose) {
56
+ const index = keys.indexOf(key);
57
+ if (index === -1) continue;
58
+ const component = components[key];
59
+ const leafHash = leafHashes[index];
60
+ if (component === void 0 || leafHash === void 0) continue;
61
+ const proof = require_merkle.merkleProofFromLayers(layers, leafHash);
62
+ disclosures.push("error" in component ? {
63
+ key,
64
+ error: true,
65
+ proof
66
+ } : {
67
+ key,
68
+ value: component.value,
69
+ proof
70
+ });
71
+ }
72
+ return {
73
+ v: 1,
74
+ root,
75
+ disclosures
76
+ };
58
77
  };
59
- const verifyFingerprintProofStructure = (proof) => {
60
- if (proof.v !== FINGERPRINT_PROOF_VERSION) {
61
- return false;
62
- }
63
- if (typeof proof.root !== "string" || proof.disclosures.length === 0) {
64
- return false;
65
- }
66
- for (const disclosure of proof.disclosures) {
67
- const leafHash = leafHashForContent(disclosureLeafContent(disclosure));
68
- if (!merkle.verifyMerkleProof(leafHash, disclosure.proof)) {
69
- return false;
70
- }
71
- const rootLayer = disclosure.proof[disclosure.proof.length - 1];
72
- if (rootLayer === void 0 || rootLayer[0] !== proof.root) {
73
- return false;
74
- }
75
- }
76
- return true;
78
+ /**
79
+ * Structural verification of a proof: every disclosed `(key, value)` re-hashes
80
+ * to a leaf that is proven to belong to the single committed `root`. This is
81
+ * the non-secret half of validation — the value-bounding rules live in the
82
+ * provider-side (closed-source) validator and are layered on top of this.
83
+ */
84
+ var verifyFingerprintProofStructure = (proof) => {
85
+ if (proof.v !== 1) return false;
86
+ if (typeof proof.root !== "string" || proof.disclosures.length === 0) return false;
87
+ for (const disclosure of proof.disclosures) {
88
+ const leafHash = leafHashForContent(disclosureLeafContent(disclosure));
89
+ if (!require_merkle.verifyMerkleProof(leafHash, disclosure.proof)) return false;
90
+ const rootLayer = disclosure.proof[disclosure.proof.length - 1];
91
+ if (rootLayer === void 0 || rootLayer[0] !== proof.root) return false;
92
+ }
93
+ return true;
77
94
  };
78
- const encodeFingerprintProof = (proof) => JSON.stringify(proof);
95
+ var encodeFingerprintProof = (proof) => JSON.stringify(proof);
96
+ //#endregion
79
97
  exports.FINGERPRINT_DISCLOSURE_KEYS = FINGERPRINT_DISCLOSURE_KEYS;
80
98
  exports.FINGERPRINT_PROOF_VERSION = FINGERPRINT_PROOF_VERSION;
81
99
  exports.buildFingerprintProofFromComponents = buildFingerprintProofFromComponents;