@prosopo/fingerprint 2.6.28 → 2.7.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.
@@ -1,15 +1,33 @@
1
1
 
2
- > @prosopo/fingerprint@2.6.28 build:cjs
2
+ > @prosopo/fingerprint@2.7.0 build:cjs
3
3
  > NODE_ENV=${NODE_ENV:-development}; vite build --config vite.cjs.config.ts --mode $NODE_ENV
4
4
 
5
5
  ViteCommonJSConfig: .
6
- { tsConfigPaths: [] }
7
- { externals: [] }
6
+ {
7
+ tsConfigPaths: [
8
+ '/home/runner/work/captcha/captcha/packages/fingerprintjs/tsconfig.json',
9
+ '/home/runner/work/captcha/captcha/packages/types/tsconfig.json',
10
+ '/home/runner/work/captcha/captcha/packages/locale/tsconfig.json',
11
+ '/home/runner/work/captcha/captcha/packages/util/tsconfig.json',
12
+ '/home/runner/work/captcha/captcha/packages/util-crypto/tsconfig.json'
13
+ ]
14
+ }
15
+ {
16
+ externals: [
17
+ '@prosopo/fingerprintjs',
18
+ '@prosopo/types',
19
+ '@prosopo/locale',
20
+ '@prosopo/util',
21
+ '@prosopo/util-crypto'
22
+ ]
23
+ }
8
24
  vite v6.4.1 building SSR bundle for production...
9
25
  Bundle build started
10
26
  transforming...
11
27
  Build end
12
- ✓ 1 modules transformed.
28
+ ✓ 3 modules transformed.
13
29
  rendering chunks...
14
- dist/cjs/index.cjs 1.58 kB
15
- ✓ built in 153ms
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 163ms
@@ -1,14 +1,29 @@
1
1
 
2
- > @prosopo/fingerprint@2.6.28 build:tsc
2
+ > @prosopo/fingerprint@2.7.0 build:tsc
3
3
  > tsc --build --verbose
4
4
 
5
- 4:56:26 PM - Projects in this build:
5
+ 12:05:39 PM - Projects in this build:
6
6
  * ../../dev/config/tsconfig.json
7
+ * ../fingerprintjs/tsconfig.json
8
+ * ../locale/tsconfig.json
9
+ * ../util/tsconfig.json
10
+ * ../util-crypto/tsconfig.json
11
+ * ../types/tsconfig.json
7
12
  * tsconfig.json
8
13
 
9
- 4:56:27 PM - Project '../../dev/config/tsconfig.json' is up to date because newest input '../../dev/config/src/dependencies.ts' is older than output '../../dev/config/tsconfig.tsbuildinfo'
14
+ 12:05:39 PM - Project '../../dev/config/tsconfig.json' is up to date because newest input '../../dev/config/src/vite/NodejsPolarsNativeFilePlugin.ts' is older than output '../../dev/config/tsconfig.tsbuildinfo'
10
15
 
11
- 4:56:27 PM - Project 'tsconfig.json' is out of date because output file 'tsconfig.tsbuildinfo' does not exist
16
+ 12:05:39 PM - Project '../fingerprintjs/tsconfig.json' is up to date because newest input '../fingerprintjs/src/utils/async.ts' is older than output '../fingerprintjs/tsconfig.tsbuildinfo'
12
17
 
13
- 4:56:27 PM - Building project '/home/runner/work/captcha/captcha/packages/fingerprint/tsconfig.json'...
18
+ 12:05:39 PM - Project '../locale/tsconfig.json' is up to date because newest input '../locale/src/translationKey.ts' is older than output '../locale/tsconfig.tsbuildinfo'
19
+
20
+ 12:05:39 PM - Project '../util/tsconfig.json' is up to date because newest input '../util/src/url.ts' is older than output '../util/tsconfig.tsbuildinfo'
21
+
22
+ 12:05:39 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
+
24
+ 12:05:39 PM - Project '../types/tsconfig.json' is up to date because newest input '../types/src/keyring/keyring/types.ts' is older than output '../types/tsconfig.tsbuildinfo'
25
+
26
+ 12:05:39 PM - Project 'tsconfig.json' is out of date because output file 'tsconfig.tsbuildinfo' does not exist
27
+
28
+ 12:05:39 PM - Building project '/home/runner/work/captcha/captcha/packages/fingerprint/tsconfig.json'...
14
29
 
@@ -1,19 +1,37 @@
1
1
 
2
- > @prosopo/fingerprint@2.6.28 build
2
+ > @prosopo/fingerprint@2.7.0 build
3
3
  > npm run build:cross-env -- --mode ${NODE_ENV:-development}
4
4
 
5
5
 
6
- > @prosopo/fingerprint@2.6.28 build:cross-env
6
+ > @prosopo/fingerprint@2.7.0 build:cross-env
7
7
  > vite build --config vite.esm.config.ts --mode production
8
8
 
9
9
  ViteEsmConfig: .
10
- { tsConfigPaths: [] }
11
- { externals: [] }
10
+ {
11
+ tsConfigPaths: [
12
+ '/home/runner/work/captcha/captcha/packages/fingerprintjs/tsconfig.json',
13
+ '/home/runner/work/captcha/captcha/packages/types/tsconfig.json',
14
+ '/home/runner/work/captcha/captcha/packages/locale/tsconfig.json',
15
+ '/home/runner/work/captcha/captcha/packages/util/tsconfig.json',
16
+ '/home/runner/work/captcha/captcha/packages/util-crypto/tsconfig.json'
17
+ ]
18
+ }
19
+ {
20
+ externals: [
21
+ '@prosopo/fingerprintjs',
22
+ '@prosopo/types',
23
+ '@prosopo/locale',
24
+ '@prosopo/util',
25
+ '@prosopo/util-crypto'
26
+ ]
27
+ }
12
28
  vite v6.4.1 building SSR bundle for production...
13
29
  Bundle build started
14
30
  transforming...
15
31
  Build end
16
- ✓ 1 modules transformed.
32
+ ✓ 3 modules transformed.
17
33
  rendering chunks...
18
- dist/index.js 0.32 kB
19
- ✓ built in 129ms
34
+ dist/index.js 1.92 kB
35
+ dist/merkle.js 2.50 kB
36
+ dist/proof.js 2.92 kB
37
+ ✓ built in 148ms
package/CHANGELOG.md CHANGED
@@ -1,5 +1,50 @@
1
1
  # @prosopo/fingerprint
2
2
 
3
+ ## 2.7.0
4
+ ### Minor Changes
5
+
6
+ - dde23e8: Internal bot-detection signal improvements.
7
+
8
+ ### Patch Changes
9
+
10
+ - Updated dependencies [3a46191]
11
+ - Updated dependencies [dde23e8]
12
+ - @prosopo/types@4.7.0
13
+
14
+ ## 2.6.31
15
+ ### Patch Changes
16
+
17
+ - 642d064: Bump `@prosopo/fingerprintjs` to 5.2.0 to mirror the upstream v5.2.0
18
+ release brought into the fork by the earlier upstream merge. Also
19
+ aligns the fork's `@prosopo/config` devDependency with the workspace
20
+ pin (3.3.0 → 3.3.1).
21
+ - Updated dependencies [642d064]
22
+ - @prosopo/fingerprintjs@5.3.0
23
+
24
+ ## 2.6.30
25
+ ### Patch Changes
26
+
27
+ - 4aae4e6: Drop `webGlExtensions` from the FpJS visitorId source list to remove the
28
+ 1.5–2s WebGL extension/parameter walk from the account-creation critical
29
+ path. Done at the wrapper level — `@prosopo/fingerprint` now calls
30
+ `loadSources(sources, opts, ['webGlExtensions'])` directly instead of the
31
+ default `FingerprintJS.load().get()`, so the fork's source list is
32
+ unchanged. `webGlBasics` (vendor + `UNMASKED_RENDERER_WEBGL`) is kept
33
+ because that's where most of WebGL's entropy lives; the slow extension
34
+ walk is largely redundant with the basics + canvas signals already in the
35
+ hash. Existing visitorIds will rotate once on first load.
36
+
37
+ Also merges upstream FpJS v5.2.0 into the fork, picking up the new
38
+ `userAgentData` entropy source, Firefox zoom fix for font preferences,
39
+ and dep bumps.
40
+ - Updated dependencies [4aae4e6]
41
+ - @prosopo/fingerprintjs@5.2.0
42
+
43
+ ## 2.6.29
44
+ ### Patch Changes
45
+
46
+ - 730c61e: Speed up captcha
47
+
3
48
  ## 2.6.28
4
49
  ### Patch Changes
5
50
 
@@ -22,11 +22,61 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
22
22
  mod
23
23
  ));
24
24
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
25
- const FingerprintJSImport = async () => (await import("@fingerprintjs/fingerprintjs")).default;
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;
53
+ };
26
54
  const getFingerprint = async () => {
27
- const FingerprintJS = await FingerprintJSImport();
28
- const fp = await FingerprintJS.load();
29
- const result = await fp.get();
30
- return result.visitorId;
55
+ const [{ hashComponents }, components] = await Promise.all([
56
+ FingerprintJSImport(),
57
+ loadComponents()
58
+ ]);
59
+ return hashComponents(components);
60
+ };
61
+ const getFingerprintProof = async (discloseKeys) => {
62
+ const components = await loadComponents();
63
+ return proof.buildFingerprintProofFromComponents(components, discloseKeys);
64
+ };
65
+ const prefetchFingerprint = () => {
66
+ loadComponents().catch(() => {
67
+ });
31
68
  };
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;
32
80
  exports.getFingerprint = getFingerprint;
81
+ exports.getFingerprintProof = getFingerprintProof;
82
+ exports.prefetchFingerprint = prefetchFingerprint;
@@ -0,0 +1,83 @@
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;
12
+ };
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;
31
+ };
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)]];
52
+ };
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
+ }
78
+ };
79
+ exports.buildMerkleLayers = buildMerkleLayers;
80
+ exports.hashMerklePair = hashMerklePair;
81
+ exports.merkleProofFromLayers = merkleProofFromLayers;
82
+ exports.merkleRootFromLayers = merkleRootFromLayers;
83
+ exports.verifyMerkleProof = verifyMerkleProof;
@@ -0,0 +1,84 @@
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"
15
+ ];
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}`;
20
+ };
21
+ const disclosureLeafContent = (disclosure) => {
22
+ const serialized = disclosure.error ? "error" : JSON.stringify(disclosure.value);
23
+ return `${escapeKey(disclosure.key)}:${serialized}`;
24
+ };
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 };
58
+ };
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;
77
+ };
78
+ const encodeFingerprintProof = (proof) => JSON.stringify(proof);
79
+ exports.FINGERPRINT_DISCLOSURE_KEYS = FINGERPRINT_DISCLOSURE_KEYS;
80
+ exports.FINGERPRINT_PROOF_VERSION = FINGERPRINT_PROOF_VERSION;
81
+ exports.buildFingerprintProofFromComponents = buildFingerprintProofFromComponents;
82
+ exports.encodeFingerprintProof = encodeFingerprintProof;
83
+ exports.leafHashForContent = leafHashForContent;
84
+ exports.verifyFingerprintProofStructure = verifyFingerprintProofStructure;
package/dist/index.d.ts CHANGED
@@ -1,2 +1,8 @@
1
+ import { type FingerprintProof } from "./proof.js";
1
2
  export declare const getFingerprint: () => Promise<string>;
3
+ export declare const getFingerprintProof: (discloseKeys?: readonly string[]) => Promise<FingerprintProof>;
4
+ export declare const prefetchFingerprint: () => void;
5
+ export type { FingerprintLeafDisclosure, FingerprintProof } from "./proof.js";
6
+ export { FINGERPRINT_DISCLOSURE_KEYS, FINGERPRINT_PROOF_VERSION, buildFingerprintProofFromComponents, encodeFingerprintProof, leafHashForContent, verifyFingerprintProofStructure, } from "./proof.js";
7
+ export { buildMerkleLayers, hashMerklePair, merkleProofFromLayers, merkleRootFromLayers, verifyMerkleProof, } from "./merkle.js";
2
8
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAiBA,eAAO,MAAM,cAAc,uBAK1B,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAeA,OAAO,EACN,KAAK,gBAAgB,EAErB,MAAM,YAAY,CAAC;AA2CpB,eAAO,MAAM,cAAc,QAAa,OAAO,CAAC,MAAM,CAMrD,CAAC;AASF,eAAO,MAAM,mBAAmB,kBAChB,SAAS,MAAM,EAAE,KAC9B,OAAO,CAAC,gBAAgB,CAG1B,CAAC;AAEF,eAAO,MAAM,mBAAmB,QAAO,IAItC,CAAC;AAEF,YAAY,EAAE,yBAAyB,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAC;AAC9E,OAAO,EACN,2BAA2B,EAC3B,yBAAyB,EACzB,mCAAmC,EACnC,sBAAsB,EACtB,kBAAkB,EAClB,+BAA+B,GAC/B,MAAM,YAAY,CAAC;AACpB,OAAO,EACN,iBAAiB,EACjB,cAAc,EACd,qBAAqB,EACrB,oBAAoB,EACpB,iBAAiB,GACjB,MAAM,aAAa,CAAC"}
package/dist/index.js CHANGED
@@ -1,10 +1,61 @@
1
- const FingerprintJSImport = async () => (await import("@fingerprintjs/fingerprintjs")).default;
1
+ import { buildFingerprintProofFromComponents } from "./proof.js";
2
+ import { FINGERPRINT_DISCLOSURE_KEYS, FINGERPRINT_PROOF_VERSION, encodeFingerprintProof, leafHashForContent, verifyFingerprintProofStructure } from "./proof.js";
3
+ import { buildMerkleLayers, hashMerklePair, merkleProofFromLayers, merkleRootFromLayers, verifyMerkleProof } from "./merkle.js";
4
+ const EXCLUDED_SOURCES = ["webGlExtensions"];
5
+ const FingerprintJSImport = async () => import("@prosopo/fingerprintjs");
6
+ let componentsCache = null;
7
+ const loadComponents = () => {
8
+ if (!componentsCache) {
9
+ const pending = (async () => {
10
+ const { sources, loadSources, prepareForSources } = await FingerprintJSImport();
11
+ await prepareForSources();
12
+ const sourceOptions = {
13
+ cache: {}
14
+ };
15
+ const getComponents = loadSources(
16
+ sources,
17
+ sourceOptions,
18
+ EXCLUDED_SOURCES
19
+ );
20
+ return getComponents();
21
+ })();
22
+ componentsCache = pending;
23
+ pending.catch(() => {
24
+ if (componentsCache === pending) {
25
+ componentsCache = null;
26
+ }
27
+ });
28
+ }
29
+ return componentsCache;
30
+ };
2
31
  const getFingerprint = async () => {
3
- const FingerprintJS = await FingerprintJSImport();
4
- const fp = await FingerprintJS.load();
5
- const result = await fp.get();
6
- return result.visitorId;
32
+ const [{ hashComponents }, components] = await Promise.all([
33
+ FingerprintJSImport(),
34
+ loadComponents()
35
+ ]);
36
+ return hashComponents(components);
37
+ };
38
+ const getFingerprintProof = async (discloseKeys) => {
39
+ const components = await loadComponents();
40
+ return buildFingerprintProofFromComponents(components, discloseKeys);
41
+ };
42
+ const prefetchFingerprint = () => {
43
+ loadComponents().catch(() => {
44
+ });
7
45
  };
8
46
  export {
9
- getFingerprint
47
+ FINGERPRINT_DISCLOSURE_KEYS,
48
+ FINGERPRINT_PROOF_VERSION,
49
+ buildFingerprintProofFromComponents,
50
+ buildMerkleLayers,
51
+ encodeFingerprintProof,
52
+ getFingerprint,
53
+ getFingerprintProof,
54
+ hashMerklePair,
55
+ leafHashForContent,
56
+ merkleProofFromLayers,
57
+ merkleRootFromLayers,
58
+ prefetchFingerprint,
59
+ verifyFingerprintProofStructure,
60
+ verifyMerkleProof
10
61
  };
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAcA,MAAM,mBAAmB,GAAG,KAAK,IAAI,EAAE,CACtC,CAAC,MAAM,MAAM,CAAC,8BAA8B,CAAC,CAAC,CAAC,OAAO,CAAC;AAExD,MAAM,CAAC,MAAM,cAAc,GAAG,KAAK,IAAI,EAAE;IACxC,MAAM,aAAa,GAAG,MAAM,mBAAmB,EAAE,CAAC;IAClD,MAAM,EAAE,GAAG,MAAM,aAAa,CAAC,IAAI,EAAE,CAAC;IACtC,MAAM,MAAM,GAAG,MAAM,EAAE,CAAC,GAAG,EAAE,CAAC;IAC9B,OAAO,MAAM,CAAC,SAAS,CAAC;AACzB,CAAC,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAeA,OAAO,EAEN,mCAAmC,GACnC,MAAM,YAAY,CAAC;AAKpB,MAAM,gBAAgB,GAAG,CAAC,iBAAiB,CAAU,CAAC;AAEtD,MAAM,mBAAmB,GAAG,KAAK,IAAI,EAAE,CAAC,MAAM,CAAC,wBAAwB,CAAC,CAAC;AAIzE,IAAI,eAAe,GAAsC,IAAI,CAAC;AAE9D,MAAM,cAAc,GAAG,GAA+B,EAAE;IACvD,IAAI,CAAC,eAAe,EAAE,CAAC;QACtB,MAAM,OAAO,GAAG,CAAC,KAAK,IAAI,EAAE;YAC3B,MAAM,EAAE,OAAO,EAAE,WAAW,EAAE,iBAAiB,EAAE,GAChD,MAAM,mBAAmB,EAAE,CAAC;YAC7B,MAAM,iBAAiB,EAAE,CAAC;YAG1B,MAAM,aAAa,GAClB;gBACC,KAAK,EAAE,EAAE;aACT,CAAC;YACH,MAAM,aAAa,GAAG,WAAW,CAChC,OAAO,EACP,aAAa,EACb,gBAAgB,CAChB,CAAC;YACF,OAAO,aAAa,EAAE,CAAC;QACxB,CAAC,CAAC,EAAE,CAAC;QACL,eAAe,GAAG,OAAO,CAAC;QAE1B,OAAO,CAAC,KAAK,CAAC,GAAG,EAAE;YAClB,IAAI,eAAe,KAAK,OAAO,EAAE,CAAC;gBACjC,eAAe,GAAG,IAAI,CAAC;YACxB,CAAC;QACF,CAAC,CAAC,CAAC;IACJ,CAAC;IACD,OAAO,eAAe,CAAC;AACxB,CAAC,CAAC;AAEF,MAAM,CAAC,MAAM,cAAc,GAAG,KAAK,IAAqB,EAAE;IACzD,MAAM,CAAC,EAAE,cAAc,EAAE,EAAE,UAAU,CAAC,GAAG,MAAM,OAAO,CAAC,GAAG,CAAC;QAC1D,mBAAmB,EAAE;QACrB,cAAc,EAAE;KAChB,CAAC,CAAC;IACH,OAAO,cAAc,CAAC,UAAU,CAAC,CAAC;AACnC,CAAC,CAAC;AASF,MAAM,CAAC,MAAM,mBAAmB,GAAG,KAAK,EACvC,YAAgC,EACJ,EAAE;IAC9B,MAAM,UAAU,GAAG,MAAM,cAAc,EAAE,CAAC;IAC1C,OAAO,mCAAmC,CAAC,UAAU,EAAE,YAAY,CAAC,CAAC;AACtE,CAAC,CAAC;AAEF,MAAM,CAAC,MAAM,mBAAmB,GAAG,GAAS,EAAE;IAC7C,cAAc,EAAE,CAAC,KAAK,CAAC,GAAG,EAAE;IAE5B,CAAC,CAAC,CAAC;AACJ,CAAC,CAAC;AAGF,OAAO,EACN,2BAA2B,EAC3B,yBAAyB,EACzB,mCAAmC,EACnC,sBAAsB,EACtB,kBAAkB,EAClB,+BAA+B,GAC/B,MAAM,YAAY,CAAC;AACpB,OAAO,EACN,iBAAiB,EACjB,cAAc,EACd,qBAAqB,EACrB,oBAAoB,EACpB,iBAAiB,GACjB,MAAM,aAAa,CAAC"}
@@ -0,0 +1,7 @@
1
+ import type { MerkleLeaf, MerkleProof } from "@prosopo/types";
2
+ export declare const hashMerklePair: (left: string, right: string) => string;
3
+ export declare const buildMerkleLayers: (leafHashes: string[]) => string[][];
4
+ export declare const merkleRootFromLayers: (layers: string[][]) => string;
5
+ export declare const merkleProofFromLayers: (layers: string[][], leafHash: MerkleLeaf) => MerkleProof;
6
+ export declare const verifyMerkleProof: (leafHash: MerkleLeaf, proof: MerkleProof) => boolean;
7
+ //# sourceMappingURL=merkle.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"merkle.d.ts","sourceRoot":"","sources":["../src/merkle.ts"],"names":[],"mappings":"AAcA,OAAO,KAAK,EAAE,UAAU,EAAE,WAAW,EAAoB,MAAM,gBAAgB,CAAC;AAqBhF,eAAO,MAAM,cAAc,SAAU,MAAM,SAAS,MAAM,KAAG,MACjC,CAAC;AAO7B,eAAO,MAAM,iBAAiB,eAAgB,MAAM,EAAE,KAAG,MAAM,EAAE,EAiBhE,CAAC;AAEF,eAAO,MAAM,oBAAoB,WAAY,MAAM,EAAE,EAAE,KAAG,MACrB,CAAC;AAGtC,eAAO,MAAM,qBAAqB,WACzB,MAAM,EAAE,EAAE,YACR,UAAU,KAClB,WAqBF,CAAC;AAGF,eAAO,MAAM,iBAAiB,aACnB,UAAU,SACb,WAAW,KAChB,OA0BF,CAAC"}
package/dist/merkle.js ADDED
@@ -0,0 +1,83 @@
1
+ import { hexHashArray } from "@prosopo/util-crypto";
2
+ const at = (arr, index) => {
3
+ const value = arr[index];
4
+ if (value === void 0) {
5
+ throw new Error(
6
+ `merkle: index ${index} out of range (length ${arr.length})`
7
+ );
8
+ }
9
+ return value;
10
+ };
11
+ const hashMerklePair = (left, right) => hexHashArray([left, right]);
12
+ const buildMerkleLayers = (leafHashes) => {
13
+ if (leafHashes.length === 0) {
14
+ throw new Error("merkle: cannot build a tree with no leaves");
15
+ }
16
+ const layers = [[...leafHashes]];
17
+ let current = leafHashes;
18
+ while (current.length > 1) {
19
+ const next = [];
20
+ for (let i = 0; i < current.length; i += 2) {
21
+ const left = at(current, i);
22
+ const right = i + 1 < current.length ? at(current, i + 1) : left;
23
+ next.push(hashMerklePair(left, right));
24
+ }
25
+ layers.push(next);
26
+ current = next;
27
+ }
28
+ return layers;
29
+ };
30
+ const merkleRootFromLayers = (layers) => at(at(layers, layers.length - 1), 0);
31
+ const merkleProofFromLayers = (layers, leafHash) => {
32
+ const proof = [];
33
+ let hash = leafHash;
34
+ for (let layerNum = 0; layerNum < layers.length - 1; layerNum++) {
35
+ const layer = at(layers, layerNum);
36
+ const index = layer.indexOf(hash);
37
+ if (index === -1) {
38
+ throw new Error("merkle: leaf hash not present in layer");
39
+ }
40
+ let partnerIndex = index % 2 === 1 ? index - 1 : index + 1;
41
+ if (partnerIndex > layer.length - 1) {
42
+ partnerIndex = index;
43
+ }
44
+ const partner = at(layer, partnerIndex);
45
+ const pair = partnerIndex > index ? [hash, partner] : [partner, hash];
46
+ proof.push(pair);
47
+ hash = hashMerklePair(pair[0], pair[1]);
48
+ }
49
+ return [...proof, [merkleRootFromLayers(layers)]];
50
+ };
51
+ const verifyMerkleProof = (leafHash, proof) => {
52
+ try {
53
+ const firstLayer = proof[0];
54
+ if (firstLayer === void 0 || firstLayer.indexOf(leafHash) === -1) {
55
+ return false;
56
+ }
57
+ if (proof.length === 1) {
58
+ return at(firstLayer, 0) === leafHash;
59
+ }
60
+ const root = at(at(proof, proof.length - 1), 0);
61
+ let hash = leafHash;
62
+ for (let i = 0; i < proof.length - 1; i++) {
63
+ const layer = at(proof, i);
64
+ if (layer.indexOf(hash) === -1) {
65
+ return false;
66
+ }
67
+ hash = hashMerklePair(at(layer, 0), at(layer, 1));
68
+ if (at(proof, i + 1).indexOf(hash) === -1) {
69
+ return false;
70
+ }
71
+ }
72
+ return hash === root;
73
+ } catch {
74
+ return false;
75
+ }
76
+ };
77
+ export {
78
+ buildMerkleLayers,
79
+ hashMerklePair,
80
+ merkleProofFromLayers,
81
+ merkleRootFromLayers,
82
+ verifyMerkleProof
83
+ };
@@ -0,0 +1 @@
1
+ {"version":3,"file":"merkle.js","sourceRoot":"","sources":["../src/merkle.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,20 @@
1
+ import type { UnknownComponents } from "@prosopo/fingerprintjs";
2
+ import type { MerkleProof } from "@prosopo/types";
3
+ export declare const FINGERPRINT_PROOF_VERSION = 1;
4
+ export declare const FINGERPRINT_DISCLOSURE_KEYS: readonly string[];
5
+ export interface FingerprintLeafDisclosure {
6
+ key: string;
7
+ value?: unknown;
8
+ error?: boolean;
9
+ proof: MerkleProof;
10
+ }
11
+ export interface FingerprintProof {
12
+ v: number;
13
+ root: string;
14
+ disclosures: FingerprintLeafDisclosure[];
15
+ }
16
+ export declare const leafHashForContent: (content: string) => string;
17
+ export declare const buildFingerprintProofFromComponents: (components: UnknownComponents, discloseKeys?: readonly string[]) => FingerprintProof;
18
+ export declare const verifyFingerprintProofStructure: (proof: FingerprintProof) => boolean;
19
+ export declare const encodeFingerprintProof: (proof: FingerprintProof) => string;
20
+ //# sourceMappingURL=proof.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"proof.d.ts","sourceRoot":"","sources":["../src/proof.ts"],"names":[],"mappings":"AAcA,OAAO,KAAK,EAAa,iBAAiB,EAAE,MAAM,wBAAwB,CAAC;AAC3E,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAC;AASlD,eAAO,MAAM,yBAAyB,IAAI,CAAC;AAa3C,eAAO,MAAM,2BAA2B,EAAE,SAAS,MAAM,EASxD,CAAC;AASF,MAAM,WAAW,yBAAyB;IACzC,GAAG,EAAE,MAAM,CAAC;IACZ,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,KAAK,EAAE,WAAW,CAAC;CACnB;AASD,MAAM,WAAW,gBAAgB;IAChC,CAAC,EAAE,MAAM,CAAC;IACV,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,yBAAyB,EAAE,CAAC;CACzC;AA2BD,eAAO,MAAM,kBAAkB,YAAa,MAAM,KAAG,MAA0B,CAAC;AAShF,eAAO,MAAM,mCAAmC,eACnC,iBAAiB,iBACd,SAAS,MAAM,EAAE,KAC9B,gBAsCF,CAAC;AAQF,eAAO,MAAM,+BAA+B,UACpC,gBAAgB,KACrB,OAkBF,CAAC;AAEF,eAAO,MAAM,sBAAsB,UAAW,gBAAgB,KAAG,MAC3C,CAAC"}