@prosopo/datasets 2.5.5 → 2.6.2

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 ADDED
@@ -0,0 +1,32 @@
1
+ # @prosopo/datasets
2
+
3
+ ## 2.6.2
4
+
5
+ ### Patch Changes
6
+
7
+ - 6ff193a: Change settings type
8
+ - Updated dependencies [6ff193a]
9
+ - @prosopo/types@2.6.2
10
+ - @prosopo/types-database@2.6.2
11
+
12
+ ## 2.6.1
13
+
14
+ ### Patch Changes
15
+
16
+ - 52feffc: Adjustable difficulty img captcha
17
+ - Updated dependencies [52feffc]
18
+ - @prosopo/types-database@2.6.1
19
+ - @prosopo/types@2.6.1
20
+
21
+ ## 2.6.0
22
+
23
+ ### Minor Changes
24
+
25
+ - a0bfc8a: bump all pkg versions since independent versioning applied
26
+
27
+ ### Patch Changes
28
+
29
+ - Updated dependencies [a0bfc8a]
30
+ - @prosopo/common@2.6.0
31
+ - @prosopo/types@2.6.0
32
+ - @prosopo/util@2.6.0
@@ -1,4 +1,5 @@
1
1
  import { type AssetsResolver, type Captcha, type CaptchaSolution, type CaptchaWithoutId, type DatasetRaw, type HashedItem, type HashedSolution, type Item, type RawSolution } from "@prosopo/types";
2
+ import type { SolutionRecord } from "@prosopo/types-database";
2
3
  export declare const NO_SOLUTION_VALUE = "NO_SOLUTION";
3
4
  export declare function parseCaptchaDataset(datasetJSON: JSON): DatasetRaw;
4
5
  export declare function parseAndSortCaptchaSolutions(captchaJSON: CaptchaSolution[]): CaptchaSolution[];
@@ -9,7 +10,7 @@ export declare function sortAndComputeHashes(received: CaptchaSolution[], stored
9
10
  captchaId: string;
10
11
  hash: string;
11
12
  }[];
12
- export declare function compareCaptchaSolutions(received: CaptchaSolution[], stored: Captcha[]): boolean;
13
+ export declare function compareCaptchaSolutions(received: CaptchaSolution[], solutions: SolutionRecord[], totalImages: number, threshold: number): boolean;
13
14
  export declare function computeCaptchaHash(captcha: CaptchaWithoutId, includeSolution: boolean, includeSalt: boolean, sortItemHashes: boolean): string;
14
15
  export declare function getSolutionValueToHash(solution?: HashedSolution[] | RawSolution[]): string[] | number[];
15
16
  export declare function computeItemHash(item: Item): Promise<HashedItem>;
@@ -1 +1 @@
1
- {"version":3,"file":"captcha.d.ts","sourceRoot":"","sources":["../../src/captcha/captcha.ts"],"names":[],"mappings":"AAqBA,OAAO,EACN,KAAK,cAAc,EACnB,KAAK,OAAO,EACZ,KAAK,eAAe,EAEpB,KAAK,gBAAgB,EACrB,KAAK,UAAU,EAEf,KAAK,UAAU,EACf,KAAK,cAAc,EACnB,KAAK,IAAI,EACT,KAAK,WAAW,EAChB,MAAM,gBAAgB,CAAC;AAIxB,eAAO,MAAM,iBAAiB,gBAAgB,CAAC;AAO/C,wBAAgB,mBAAmB,CAAC,WAAW,EAAE,IAAI,GAAG,UAAU,CA+BjE;AAOD,wBAAgB,4BAA4B,CAC3C,WAAW,EAAE,eAAe,EAAE,GAC5B,eAAe,EAAE,CAWnB;AAED,wBAAgB,WAAW,CAAC,CAAC,SAAS;IAAE,SAAS,EAAE,MAAM,CAAA;CAAE,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,UAEtE;AAED,wBAAgB,oBAAoB,CACnC,QAAQ,EAAE,eAAe,EAAE,EAC3B,MAAM,EAAE,OAAO,EAAE,GACf;IAAE,SAAS,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,EAAE,CA2BvC;AAQD,wBAAgB,uBAAuB,CACtC,QAAQ,EAAE,eAAe,EAAE,EAC3B,MAAM,EAAE,OAAO,EAAE,GACf,OAAO,CAOT;AAUD,wBAAgB,kBAAkB,CACjC,OAAO,EAAE,gBAAgB,EACzB,eAAe,EAAE,OAAO,EACxB,WAAW,EAAE,OAAO,EACpB,cAAc,EAAE,OAAO,GACrB,MAAM,CA0BR;AAMD,wBAAgB,sBAAsB,CACrC,QAAQ,CAAC,EAAE,cAAc,EAAE,GAAG,WAAW,EAAE,uBAG3C;AAMD,wBAAsB,eAAe,CAAC,IAAI,EAAE,IAAI,GAAG,OAAO,CAAC,UAAU,CAAC,CAQrE;AAQD,wBAAgB,qBAAqB,CACpC,SAAS,EAAE,WAAW,EAAE,GAAG,cAAc,EAAE,EAC3C,KAAK,EAAE,UAAU,EAAE,GAAG,SAAS,GAC7B,cAAc,EAAE,CAsBlB;AAOD,wBAAgB,0BAA0B,CAAC,OAAO,EAAE,eAAe,UAOlE;AASD,wBAAgB,yBAAyB,CACxC,UAAU,EAAE,MAAM,EAAE,EACpB,WAAW,EAAE,MAAM,GAAG,MAAM,EAAE,EAC9B,IAAI,EAAE,MAAM,GACV,MAAM,CAER;AAOD,wBAAgB,kBAAkB,CACjC,IAAI,EAAE,IAAI,EACV,cAAc,EAAE,cAAc,GAAG,SAAS,GACxC,IAAI,CAKN"}
1
+ {"version":3,"file":"captcha.d.ts","sourceRoot":"","sources":["../../src/captcha/captcha.ts"],"names":[],"mappings":"AAqBA,OAAO,EACN,KAAK,cAAc,EACnB,KAAK,OAAO,EACZ,KAAK,eAAe,EAEpB,KAAK,gBAAgB,EACrB,KAAK,UAAU,EAEf,KAAK,UAAU,EACf,KAAK,cAAc,EACnB,KAAK,IAAI,EACT,KAAK,WAAW,EAChB,MAAM,gBAAgB,CAAC;AACxB,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,yBAAyB,CAAC;AAI9D,eAAO,MAAM,iBAAiB,gBAAgB,CAAC;AAO/C,wBAAgB,mBAAmB,CAAC,WAAW,EAAE,IAAI,GAAG,UAAU,CA+BjE;AAOD,wBAAgB,4BAA4B,CAC3C,WAAW,EAAE,eAAe,EAAE,GAC5B,eAAe,EAAE,CAWnB;AAED,wBAAgB,WAAW,CAAC,CAAC,SAAS;IAAE,SAAS,EAAE,MAAM,CAAA;CAAE,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,UAEtE;AAED,wBAAgB,oBAAoB,CACnC,QAAQ,EAAE,eAAe,EAAE,EAC3B,MAAM,EAAE,OAAO,EAAE,GACf;IAAE,SAAS,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,EAAE,CA2BvC;AAUD,wBAAgB,uBAAuB,CACtC,QAAQ,EAAE,eAAe,EAAE,EAC3B,SAAS,EAAE,cAAc,EAAE,EAC3B,WAAW,EAAE,MAAM,EACnB,SAAS,EAAE,MAAM,GACf,OAAO,CAkDT;AAUD,wBAAgB,kBAAkB,CACjC,OAAO,EAAE,gBAAgB,EACzB,eAAe,EAAE,OAAO,EACxB,WAAW,EAAE,OAAO,EACpB,cAAc,EAAE,OAAO,GACrB,MAAM,CA0BR;AAMD,wBAAgB,sBAAsB,CACrC,QAAQ,CAAC,EAAE,cAAc,EAAE,GAAG,WAAW,EAAE,uBAG3C;AAMD,wBAAsB,eAAe,CAAC,IAAI,EAAE,IAAI,GAAG,OAAO,CAAC,UAAU,CAAC,CAQrE;AAQD,wBAAgB,qBAAqB,CACpC,SAAS,EAAE,WAAW,EAAE,GAAG,cAAc,EAAE,EAC3C,KAAK,EAAE,UAAU,EAAE,GAAG,SAAS,GAC7B,cAAc,EAAE,CAsBlB;AAOD,wBAAgB,0BAA0B,CAAC,OAAO,EAAE,eAAe,GAAG,MAAM,CAO3E;AASD,wBAAgB,yBAAyB,CACxC,UAAU,EAAE,MAAM,EAAE,EACpB,WAAW,EAAE,MAAM,GAAG,MAAM,EAAE,EAC9B,IAAI,EAAE,MAAM,GACV,MAAM,CAER;AAOD,wBAAgB,kBAAkB,CACjC,IAAI,EAAE,IAAI,EACV,cAAc,EAAE,cAAc,GAAG,SAAS,GACxC,IAAI,CAKN"}
@@ -72,12 +72,32 @@ export function sortAndComputeHashes(received, stored) {
72
72
  };
73
73
  });
74
74
  }
75
- export function compareCaptchaSolutions(received, stored) {
76
- if (received.length && stored.length && received.length === stored.length) {
77
- const hashes = sortAndComputeHashes(received, stored);
78
- return hashes.every(({ hash, captchaId }) => hash === captchaId);
75
+ export function compareCaptchaSolutions(received, solutions, totalImages, threshold) {
76
+ received.sort(captchaSort);
77
+ solutions.sort(captchaSort);
78
+ if (received.length !== solutions.length) {
79
+ return false;
80
+ }
81
+ if (received.length &&
82
+ solutions.length &&
83
+ received.length === solutions.length) {
84
+ const captchaIdMismatch = received.some((captcha, index) => solutions[index] && captcha.captchaId !== solutions[index].captchaId);
85
+ if (captchaIdMismatch) {
86
+ return false;
87
+ }
79
88
  }
80
- return false;
89
+ return received.every((captcha, index) => {
90
+ const sortedReceivedSolution = captcha.solution.sort();
91
+ const targetSolution = solutions[index]?.solution.sort();
92
+ if (!targetSolution) {
93
+ return false;
94
+ }
95
+ const incorrectCount = sortedReceivedSolution.filter((solution) => !targetSolution.includes(solution)).length;
96
+ const missingCount = targetSolution.filter((solution) => !sortedReceivedSolution.includes(solution)).length;
97
+ const totalIncorrect = incorrectCount + missingCount;
98
+ const percentageCorrect = 1 - totalIncorrect / totalImages;
99
+ return percentageCorrect >= threshold;
100
+ });
81
101
  }
82
102
  export function computeCaptchaHash(captcha, includeSolution, includeSalt, sortItemHashes) {
83
103
  try {
@@ -1 +1 @@
1
- {"version":3,"file":"captcha.js","sourceRoot":"","sources":["../../src/captcha/captcha.ts"],"names":[],"mappings":"AAcA,OAAO,EAAE,KAAK,EAAE,MAAM,gBAAgB,CAAC;AACvC,OAAO,EACN,mBAAmB,EACnB,eAAe,EACf,OAAO,EACP,YAAY,GACZ,MAAM,iBAAiB,CAAC;AACzB,OAAO,EAIN,0BAA0B,EAG1B,gCAAgC,GAKhC,MAAM,gBAAgB,CAAC;AACxB,OAAO,EAAE,EAAE,EAAE,MAAM,eAAe,CAAC;AACnC,OAAO,EAAE,aAAa,EAAE,MAAM,WAAW,CAAC;AAE1C,MAAM,CAAC,MAAM,iBAAiB,GAAG,aAAa,CAAC;AAO/C,MAAM,UAAU,mBAAmB,CAAC,WAAiB;IACpD,IAAI,CAAC;QACJ,MAAM,MAAM,GAAG,gCAAgC,CAAC,KAAK,CAAC,WAAW,CAAC,CAAC;QAEnE,MAAM,OAAO,GAAe;YAC3B,MAAM,EAAE,MAAM,CAAC,MAAM;YACrB,QAAQ,EAAE,MAAM,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,OAAO,EAAE,EAAE;gBACzC,OAAO;oBACN,GAAG,OAAO;oBACV,QAAQ,EAAE,OAAO,CAAC,QAAQ;wBACzB,CAAC,CAAC,qBAAqB,CAAC,OAAO,CAAC,QAAQ,EAAE,OAAO,CAAC,KAAK,CAAC;wBACxD,CAAC,CAAC,EAAE;oBACL,UAAU,EAAE,OAAO,CAAC,UAAU;wBAC7B,CAAC,CAAC,qBAAqB,CAAC,OAAO,CAAC,UAAU,EAAE,OAAO,CAAC,KAAK,CAAC;wBAC1D,CAAC,CAAC,EAAE;iBACL,CAAC;YACH,CAAC,CAAC;SACF,CAAC;QACF,IAAI,MAAM,CAAC,SAAS,KAAK,SAAS;YAAE,OAAO,CAAC,SAAS,GAAG,MAAM,CAAC,SAAS,CAAC;QACzE,IAAI,MAAM,CAAC,WAAW,KAAK,SAAS;YACnC,OAAO,CAAC,WAAW,GAAG,MAAM,CAAC,WAAW,CAAC;QAC1C,IAAI,MAAM,CAAC,gBAAgB,KAAK,SAAS;YACxC,OAAO,CAAC,gBAAgB,GAAG,MAAM,CAAC,gBAAgB,CAAC;QACpD,IAAI,MAAM,CAAC,YAAY,KAAK,SAAS;YACpC,OAAO,CAAC,YAAY,GAAG,MAAM,CAAC,YAAY,CAAC;QAC5C,OAAO,OAAO,CAAC;IAChB,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACd,MAAM,IAAI,mBAAmB,CAAC,6BAA6B,EAAE;YAC5D,OAAO,EAAE,EAAE,KAAK,EAAE,GAAG,EAAE;SACvB,CAAC,CAAC;IACJ,CAAC;AACF,CAAC;AAOD,MAAM,UAAU,4BAA4B,CAC3C,WAA8B;IAE9B,IAAI,CAAC;QACJ,OAAO,0BAA0B,CAAC,KAAK,CAAC,WAAW,CAAC,CAAC,GAAG,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC;YACtE,GAAG,OAAO;YACV,QAAQ,EAAE,OAAO,CAAC,QAAQ,CAAC,IAAI,EAAE;SACjC,CAAC,CAAC,CAAC;IACL,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACd,MAAM,IAAI,mBAAmB,CAAC,8BAA8B,EAAE;YAC7D,OAAO,EAAE,EAAE,KAAK,EAAE,GAAG,EAAE;SACvB,CAAC,CAAC;IACJ,CAAC;AACF,CAAC;AAED,MAAM,UAAU,WAAW,CAAkC,CAAI,EAAE,CAAI;IACtE,OAAO,CAAC,CAAC,SAAS,CAAC,aAAa,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC;AAC/C,CAAC;AAED,MAAM,UAAU,oBAAoB,CACnC,QAA2B,EAC3B,MAAiB;IAEjB,QAAQ,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC;IAC3B,MAAM,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC;IAEzB,OAAO,MAAM,CAAC,GAAG,CAChB,CAAC,EAAE,IAAI,EAAE,KAAK,GAAG,EAAE,EAAE,MAAM,GAAG,EAAE,EAAE,SAAS,EAAE,MAAM,EAAE,EAAE,KAAK,EAAE,EAAE;QAC/D,MAAM,IAAI,GAAG,EAAE,CAAC,QAAQ,EAAE,KAAK,CAAC,CAAC;QACjC,IAAI,SAAS,KAAK,IAAI,CAAC,SAAS,EAAE,CAAC;YAClC,MAAM,IAAI,eAAe,CAAC,qBAAqB,CAAC,CAAC;QAClD,CAAC;QAED,OAAO;YACN,IAAI,EAAE,kBAAkB,CACvB;gBACC,QAAQ,EAAE,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE;gBACrC,IAAI;gBACJ,KAAK;gBACL,MAAM;aACN,EACD,IAAI,EACJ,IAAI,EACJ,KAAK,CACL;YACD,SAAS;SACT,CAAC;IACH,CAAC,CACD,CAAC;AACH,CAAC;AAQD,MAAM,UAAU,uBAAuB,CACtC,QAA2B,EAC3B,MAAiB;IAEjB,IAAI,QAAQ,CAAC,MAAM,IAAI,MAAM,CAAC,MAAM,IAAI,QAAQ,CAAC,MAAM,KAAK,MAAM,CAAC,MAAM,EAAE,CAAC;QAC3E,MAAM,MAAM,GAAG,oBAAoB,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAC;QACtD,OAAO,MAAM,CAAC,KAAK,CAAC,CAAC,EAAE,IAAI,EAAE,SAAS,EAAE,EAAE,EAAE,CAAC,IAAI,KAAK,SAAS,CAAC,CAAC;IAClE,CAAC;IAED,OAAO,KAAK,CAAC;AACd,CAAC;AAUD,MAAM,UAAU,kBAAkB,CACjC,OAAyB,EACzB,eAAwB,EACxB,WAAoB,EACpB,cAAuB;IAEvB,IAAI,CAAC;QACJ,MAAM,UAAU,GAAa,OAAO,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,KAAK,EAAE,EAAE;YAC9D,IAAI,IAAI,CAAC,IAAI,EAAE,CAAC;gBACf,OAAO,IAAI,CAAC,IAAI,CAAC;YAClB,CAAC;YACD,MAAM,IAAI,mBAAmB,CAAC,2BAA2B,EAAE;gBAC1D,OAAO,EAAE;oBACR,sBAAsB,EAAE,kBAAkB,CAAC,IAAI;oBAC/C,KAAK;iBACL;aACD,CAAC,CAAC;QACJ,CAAC,CAAC,CAAC;QACH,OAAO,YAAY,CAAC;YACnB,OAAO,CAAC,MAAM;YAGd,GAAG,CAAC,eAAe,CAAC,CAAC,CAAC,sBAAsB,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;YACpE,WAAW,CAAC,CAAC,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE;YAC/B,cAAc,CAAC,CAAC,CAAC,UAAU,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,UAAU;SAC/C,CAAC,CAAC;IACJ,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACd,MAAM,IAAI,mBAAmB,CAAC,oBAAoB,EAAE;YACnD,OAAO,EAAE,EAAE,KAAK,EAAE,GAAG,EAAE;SACvB,CAAC,CAAC;IACJ,CAAC;AACF,CAAC;AAMD,MAAM,UAAU,sBAAsB,CACrC,QAA2C;IAE3C,OAAO,QAAQ,KAAK,SAAS,CAAC,CAAC,CAAC,QAAQ,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC,iBAAiB,CAAC,CAAC;AACvE,CAAC;AAMD,MAAM,CAAC,KAAK,UAAU,eAAe,CAAC,IAAU;IAC/C,IAAI,IAAI,CAAC,IAAI,KAAK,MAAM,EAAE,CAAC;QAC1B,OAAO,EAAE,GAAG,IAAI,EAAE,IAAI,EAAE,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC;IAC9C,CAAC;IACD,IAAI,IAAI,CAAC,IAAI,KAAK,OAAO,EAAE,CAAC;QAC3B,OAAO,EAAE,GAAG,IAAI,EAAE,IAAI,EAAE,OAAO,CAAC,MAAM,aAAa,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,EAAE,CAAC;IACnE,CAAC;IACD,MAAM,IAAI,mBAAmB,CAAC,6BAA6B,CAAC,CAAC;AAC9D,CAAC;AAQD,MAAM,UAAU,qBAAqB,CACpC,SAA2C,EAC3C,KAA+B;IAE/B,IAAI,CAAC,KAAK,EAAE,CAAC;QACZ,OAAO,EAAE,CAAC;IACX,CAAC;IACD,OAAO,SAAS,CAAC,GAAG,CAAC,CAAC,QAAyB,EAAE,EAAE;QAClD,IAAI,OAAO,QAAQ,KAAK,QAAQ,IAAI,KAAK,CAAC,QAAQ,CAAC,EAAE,CAAC;YAGrD,IAAI,CAAC,KAAK,EAAE,IAAI,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,IAAI,KAAK,QAAQ,CAAC,EAAE,CAAC;gBACpD,MAAM,IAAI,mBAAmB,CAAC,2BAA2B,CAAC,CAAC;YAC5D,CAAC;YACD,OAAO,QAAQ,CAAC;QACjB,CAAC;QACD,IAAI,OAAO,QAAQ,KAAK,QAAQ,EAAE,CAAC;YAGlC,MAAM,IAAI,GAAG,EAAE,CAAC,KAAK,EAAE,QAAQ,CAAC,CAAC;YAEjC,OAAO,IAAI,CAAC,IAAI,CAAC;QAClB,CAAC;QACD,MAAM,IAAI,mBAAmB,CAAC,+BAA+B,CAAC,CAAC;IAChE,CAAC,CAAC,CAAC;AACJ,CAAC;AAOD,MAAM,UAAU,0BAA0B,CAAC,OAAwB;IAClE,OAAO,YAAY,CAAC;QACnB,OAAO,CAAC,SAAS;QACjB,OAAO,CAAC,gBAAgB;QACxB,CAAC,GAAG,OAAO,CAAC,QAAQ,CAAC,CAAC,IAAI,EAAE;QAC5B,OAAO,CAAC,IAAI;KACZ,CAAC,CAAC;AACJ,CAAC;AASD,MAAM,UAAU,yBAAyB,CACxC,UAAoB,EACpB,WAA8B,EAC9B,IAAY;IAEZ,OAAO,YAAY,CAAC,CAAC,GAAG,UAAU,CAAC,IAAI,EAAE,EAAE,WAAW,EAAE,IAAI,CAAC,CAAC,CAAC;AAChE,CAAC;AAOD,MAAM,UAAU,kBAAkB,CACjC,IAAU,EACV,cAA0C;IAE1C,OAAO;QACN,GAAG,IAAI;QACP,IAAI,EAAE,cAAc,EAAE,YAAY,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,MAAM,EAAE,IAAI,IAAI,CAAC,IAAI;KACnE,CAAC;AACH,CAAC"}
1
+ {"version":3,"file":"captcha.js","sourceRoot":"","sources":["../../src/captcha/captcha.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,194 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
3
+ const util$2 = require("@polkadot/util");
4
+ const common = require("@prosopo/common");
5
+ const types = require("@prosopo/types");
6
+ const util = require("@prosopo/util");
7
+ const util$1 = require("./util.cjs");
8
+ const NO_SOLUTION_VALUE = "NO_SOLUTION";
9
+ function parseCaptchaDataset(datasetJSON) {
10
+ try {
11
+ const result = types.DatasetWithNumericSolutionSchema.parse(datasetJSON);
12
+ const result2 = {
13
+ format: result.format,
14
+ captchas: result.captchas.map((captcha) => {
15
+ return {
16
+ ...captcha,
17
+ solution: captcha.solution ? matchItemsToSolutions(captcha.solution, captcha.items) : [],
18
+ unlabelled: captcha.unlabelled ? matchItemsToSolutions(captcha.unlabelled, captcha.items) : []
19
+ };
20
+ })
21
+ };
22
+ if (result.datasetId !== void 0) result2.datasetId = result.datasetId;
23
+ if (result.contentTree !== void 0)
24
+ result2.contentTree = result.contentTree;
25
+ if (result.datasetContentId !== void 0)
26
+ result2.datasetContentId = result.datasetContentId;
27
+ if (result.solutionTree !== void 0)
28
+ result2.solutionTree = result.solutionTree;
29
+ return result2;
30
+ } catch (err) {
31
+ throw new common.ProsopoDatasetError("DATASET.DATASET_PARSE_ERROR", {
32
+ context: { error: err }
33
+ });
34
+ }
35
+ }
36
+ function parseAndSortCaptchaSolutions(captchaJSON) {
37
+ try {
38
+ return types.CaptchaSolutionArraySchema.parse(captchaJSON).map((captcha) => ({
39
+ ...captcha,
40
+ solution: captcha.solution.sort()
41
+ }));
42
+ } catch (err) {
43
+ throw new common.ProsopoDatasetError("DATASET.SOLUTION_PARSE_ERROR", {
44
+ context: { error: err }
45
+ });
46
+ }
47
+ }
48
+ function captchaSort(a, b) {
49
+ return a.captchaId.localeCompare(b.captchaId);
50
+ }
51
+ function sortAndComputeHashes(received, stored) {
52
+ received.sort(captchaSort);
53
+ stored.sort(captchaSort);
54
+ return stored.map(
55
+ ({ salt, items = [], target = "", captchaId, solved }, index) => {
56
+ const item = util.at(received, index);
57
+ if (captchaId !== item.captchaId) {
58
+ throw new common.ProsopoEnvError("CAPTCHA.ID_MISMATCH");
59
+ }
60
+ return {
61
+ hash: computeCaptchaHash(
62
+ {
63
+ solution: solved ? item.solution : [],
64
+ salt,
65
+ items,
66
+ target
67
+ },
68
+ true,
69
+ true,
70
+ false
71
+ ),
72
+ captchaId
73
+ };
74
+ }
75
+ );
76
+ }
77
+ function compareCaptchaSolutions(received, solutions, totalImages, threshold) {
78
+ received.sort(captchaSort);
79
+ solutions.sort(captchaSort);
80
+ if (received.length !== solutions.length) {
81
+ return false;
82
+ }
83
+ if (received.length && solutions.length && received.length === solutions.length) {
84
+ const captchaIdMismatch = received.some(
85
+ (captcha, index) => solutions[index] && captcha.captchaId !== solutions[index].captchaId
86
+ );
87
+ if (captchaIdMismatch) {
88
+ return false;
89
+ }
90
+ }
91
+ return received.every((captcha, index) => {
92
+ const sortedReceivedSolution = captcha.solution.sort();
93
+ const targetSolution = solutions[index]?.solution.sort();
94
+ if (!targetSolution) {
95
+ return false;
96
+ }
97
+ const incorrectCount = sortedReceivedSolution.filter(
98
+ (solution) => !targetSolution.includes(solution)
99
+ ).length;
100
+ const missingCount = targetSolution.filter(
101
+ (solution) => !sortedReceivedSolution.includes(solution)
102
+ ).length;
103
+ const totalIncorrect = incorrectCount + missingCount;
104
+ const percentageCorrect = 1 - totalIncorrect / totalImages;
105
+ return percentageCorrect >= threshold;
106
+ });
107
+ }
108
+ function computeCaptchaHash(captcha, includeSolution, includeSalt, sortItemHashes) {
109
+ try {
110
+ const itemHashes = captcha.items.map((item, index) => {
111
+ if (item.hash) {
112
+ return item.hash;
113
+ }
114
+ throw new common.ProsopoDatasetError("CAPTCHA.MISSING_ITEM_HASH", {
115
+ context: {
116
+ computeCaptchaHashName: computeCaptchaHash.name,
117
+ index
118
+ }
119
+ });
120
+ });
121
+ return common.hexHashArray([
122
+ captcha.target,
123
+ // empty array hashes as empty string, undefined solution results in the array [`NO_SOLUTION`]
124
+ // [undefined] also hashes as empty string, which is why we don't use it
125
+ ...includeSolution ? getSolutionValueToHash(captcha.solution) : [],
126
+ includeSalt ? captcha.salt : "",
127
+ sortItemHashes ? itemHashes.sort() : itemHashes
128
+ ]);
129
+ } catch (err) {
130
+ throw new common.ProsopoDatasetError("DATASET.HASH_ERROR", {
131
+ context: { error: err }
132
+ });
133
+ }
134
+ }
135
+ function getSolutionValueToHash(solution) {
136
+ return solution !== void 0 ? solution.sort() : [NO_SOLUTION_VALUE];
137
+ }
138
+ async function computeItemHash(item) {
139
+ if (item.type === "text") {
140
+ return { ...item, hash: common.hexHash(item.data) };
141
+ }
142
+ if (item.type === "image") {
143
+ return { ...item, hash: common.hexHash(await util$1.downloadImage(item.data)) };
144
+ }
145
+ throw new common.ProsopoDatasetError("CAPTCHA.INVALID_ITEM_FORMAT");
146
+ }
147
+ function matchItemsToSolutions(solutions, items) {
148
+ if (!items) {
149
+ return [];
150
+ }
151
+ return solutions.map((solution) => {
152
+ if (typeof solution === "string" && util$2.isHex(solution)) {
153
+ if (!items?.some((item) => item.hash === solution)) {
154
+ throw new common.ProsopoDatasetError("CAPTCHA.INVALID_ITEM_HASH");
155
+ }
156
+ return solution;
157
+ }
158
+ if (typeof solution === "number") {
159
+ const item = util.at(items, solution);
160
+ return item.hash;
161
+ }
162
+ throw new common.ProsopoDatasetError("CAPTCHA.INVALID_SOLUTION_TYPE");
163
+ });
164
+ }
165
+ function computeCaptchaSolutionHash(captcha) {
166
+ return common.hexHashArray([
167
+ captcha.captchaId,
168
+ captcha.captchaContentId,
169
+ [...captcha.solution].sort(),
170
+ captcha.salt
171
+ ]);
172
+ }
173
+ function computePendingRequestHash(captchaIds, userAccount, salt) {
174
+ return common.hexHashArray([...captchaIds.sort(), userAccount, salt]);
175
+ }
176
+ function parseCaptchaAssets(item, assetsResolver) {
177
+ return {
178
+ ...item,
179
+ data: assetsResolver?.resolveAsset(item.data).getURL() || item.data
180
+ };
181
+ }
182
+ exports.NO_SOLUTION_VALUE = NO_SOLUTION_VALUE;
183
+ exports.captchaSort = captchaSort;
184
+ exports.compareCaptchaSolutions = compareCaptchaSolutions;
185
+ exports.computeCaptchaHash = computeCaptchaHash;
186
+ exports.computeCaptchaSolutionHash = computeCaptchaSolutionHash;
187
+ exports.computeItemHash = computeItemHash;
188
+ exports.computePendingRequestHash = computePendingRequestHash;
189
+ exports.getSolutionValueToHash = getSolutionValueToHash;
190
+ exports.matchItemsToSolutions = matchItemsToSolutions;
191
+ exports.parseAndSortCaptchaSolutions = parseAndSortCaptchaSolutions;
192
+ exports.parseCaptchaAssets = parseCaptchaAssets;
193
+ exports.parseCaptchaDataset = parseCaptchaDataset;
194
+ exports.sortAndComputeHashes = sortAndComputeHashes;
@@ -0,0 +1,93 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
3
+ const common = require("@prosopo/common");
4
+ const util = require("@prosopo/util");
5
+ const captcha = require("./captcha.cjs");
6
+ const merkle = require("./merkle.cjs");
7
+ const logger = common.getLogger("Info", "dataset.ts");
8
+ async function hashDatasetItems(datasetRaw) {
9
+ return datasetRaw.captchas.map(async (captcha$1) => {
10
+ const items = await Promise.all(
11
+ captcha$1.items.map(async (item) => captcha.computeItemHash(item))
12
+ );
13
+ return {
14
+ ...captcha$1,
15
+ items
16
+ };
17
+ });
18
+ }
19
+ async function validateDatasetContent(datasetOriginal) {
20
+ const captchaPromises = await hashDatasetItems(datasetOriginal);
21
+ const captchas = await Promise.all(captchaPromises);
22
+ const dataset = {
23
+ ...datasetOriginal,
24
+ captchas
25
+ };
26
+ const hashes = dataset.captchas.map((captcha2) => {
27
+ const captchaRaw = datasetOriginal.captchas.find(
28
+ (captchaRaw2) => "captchaId" in captchaRaw2 ? captchaRaw2.captchaId === captcha2.captchaId : false
29
+ );
30
+ if (captchaRaw) {
31
+ return captcha2.items.every(
32
+ (item, index) => item.hash === util.at(captchaRaw.items, index).hash
33
+ );
34
+ }
35
+ return false;
36
+ });
37
+ return hashes.every((hash) => hash);
38
+ }
39
+ async function buildDataset(datasetRaw) {
40
+ logger.debug("Adding solution hashes to dataset");
41
+ const dataset = await addSolutionHashesToDataset(datasetRaw);
42
+ logger.debug("Building dataset merkle trees");
43
+ const contentTree = await buildCaptchaTree(dataset, false, false, true);
44
+ const solutionTree = await buildCaptchaTree(dataset, true, true, false);
45
+ dataset.captchas = dataset.captchas.map(
46
+ (captcha2, index) => ({
47
+ ...captcha2,
48
+ captchaId: util.at(solutionTree.leaves, index).hash,
49
+ captchaContentId: util.at(contentTree.leaves, index).hash,
50
+ datasetId: solutionTree.root?.hash,
51
+ datasetContentId: contentTree.root?.hash
52
+ })
53
+ );
54
+ dataset.solutionTree = solutionTree.layers;
55
+ dataset.contentTree = contentTree.layers;
56
+ dataset.datasetId = solutionTree.root?.hash;
57
+ dataset.datasetContentId = contentTree.root?.hash;
58
+ return dataset;
59
+ }
60
+ async function buildCaptchaTree(dataset, includeSolution, includeSalt, sortItemHashes) {
61
+ try {
62
+ const tree = new merkle.CaptchaMerkleTree();
63
+ const datasetWithItemHashes = { ...dataset };
64
+ const captchaHashes = datasetWithItemHashes.captchas.map(
65
+ (captcha$1) => captcha.computeCaptchaHash(captcha$1, includeSolution, includeSalt, sortItemHashes)
66
+ );
67
+ tree.build(captchaHashes);
68
+ return tree;
69
+ } catch (err) {
70
+ throw new common.ProsopoEnvError("DATASET.HASH_ERROR");
71
+ }
72
+ }
73
+ function addSolutionHashesToDataset(datasetRaw) {
74
+ const captchas = datasetRaw.captchas.map((captcha$1) => {
75
+ return {
76
+ ...captcha$1,
77
+ items: captcha$1.items,
78
+ // some captcha challenges will not have a solution
79
+ ...captcha$1.solution !== void 0 && {
80
+ solution: captcha.matchItemsToSolutions(captcha$1.solution, captcha$1.items)
81
+ }
82
+ };
83
+ });
84
+ return {
85
+ ...datasetRaw,
86
+ captchas
87
+ };
88
+ }
89
+ exports.addSolutionHashesToDataset = addSolutionHashesToDataset;
90
+ exports.buildCaptchaTree = buildCaptchaTree;
91
+ exports.buildDataset = buildDataset;
92
+ exports.hashDatasetItems = hashDatasetItems;
93
+ exports.validateDatasetContent = validateDatasetContent;
@@ -0,0 +1,27 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
3
+ const captcha = require("./captcha.cjs");
4
+ const merkle = require("./merkle.cjs");
5
+ const util = require("./util.cjs");
6
+ const dataset = require("./dataset.cjs");
7
+ exports.NO_SOLUTION_VALUE = captcha.NO_SOLUTION_VALUE;
8
+ exports.captchaSort = captcha.captchaSort;
9
+ exports.compareCaptchaSolutions = captcha.compareCaptchaSolutions;
10
+ exports.computeCaptchaHash = captcha.computeCaptchaHash;
11
+ exports.computeCaptchaSolutionHash = captcha.computeCaptchaSolutionHash;
12
+ exports.computeItemHash = captcha.computeItemHash;
13
+ exports.computePendingRequestHash = captcha.computePendingRequestHash;
14
+ exports.getSolutionValueToHash = captcha.getSolutionValueToHash;
15
+ exports.matchItemsToSolutions = captcha.matchItemsToSolutions;
16
+ exports.parseAndSortCaptchaSolutions = captcha.parseAndSortCaptchaSolutions;
17
+ exports.parseCaptchaAssets = captcha.parseCaptchaAssets;
18
+ exports.parseCaptchaDataset = captcha.parseCaptchaDataset;
19
+ exports.sortAndComputeHashes = captcha.sortAndComputeHashes;
20
+ exports.CaptchaMerkleTree = merkle.CaptchaMerkleTree;
21
+ exports.verifyProof = merkle.verifyProof;
22
+ exports.downloadImage = util.downloadImage;
23
+ exports.addSolutionHashesToDataset = dataset.addSolutionHashesToDataset;
24
+ exports.buildCaptchaTree = dataset.buildCaptchaTree;
25
+ exports.buildDataset = dataset.buildDataset;
26
+ exports.hashDatasetItems = dataset.hashDatasetItems;
27
+ exports.validateDatasetContent = dataset.validateDatasetContent;
@@ -0,0 +1,127 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
3
+ const common = require("@prosopo/common");
4
+ const util = require("@prosopo/util");
5
+ class MerkleNode {
6
+ constructor(hash) {
7
+ this.hash = hash;
8
+ this.parent = null;
9
+ }
10
+ }
11
+ class CaptchaMerkleTree {
12
+ constructor() {
13
+ this.leaves = [];
14
+ this.layers = [];
15
+ }
16
+ getRoot() {
17
+ if (this.root === void 0) {
18
+ throw new common.ProsopoError("DATASET.MERKLE_ERROR", {
19
+ context: {
20
+ error: "root undefined",
21
+ failedFuncName: this.getRoot.name
22
+ }
23
+ });
24
+ }
25
+ return this.root;
26
+ }
27
+ build(leaves) {
28
+ if (this.layers.length) {
29
+ this.layers = [];
30
+ }
31
+ const layerZero = [];
32
+ for (const leaf of leaves) {
33
+ const node = new MerkleNode(leaf);
34
+ this.leaves.push(node);
35
+ layerZero.push(node.hash);
36
+ }
37
+ this.layers.push(layerZero);
38
+ this.root = this.buildMerkleTree(this.leaves)[0];
39
+ }
40
+ buildMerkleTree(leaves) {
41
+ const numLeaves = leaves.length;
42
+ if (numLeaves === 1) {
43
+ return leaves;
44
+ }
45
+ const parents = [];
46
+ let leafIndex = 0;
47
+ const newLayer = [];
48
+ while (leafIndex < numLeaves) {
49
+ const leftChild = leaves[leafIndex];
50
+ if (leftChild === void 0) {
51
+ throw new common.ProsopoError("DEVELOPER.GENERAL", {
52
+ context: { error: "leftChild undefined" }
53
+ });
54
+ }
55
+ const rightChild = leafIndex + 1 < numLeaves ? util.at(leaves, leafIndex + 1) : leftChild;
56
+ const parentNode = this.createParent(leftChild, rightChild);
57
+ newLayer.push(parentNode.hash);
58
+ parents.push(parentNode);
59
+ leafIndex += 2;
60
+ }
61
+ this.layers.push(newLayer);
62
+ return this.buildMerkleTree(parents);
63
+ }
64
+ createParent(leftChild, rightChild) {
65
+ const parent = new MerkleNode(
66
+ common.hexHashArray([leftChild.hash, rightChild.hash])
67
+ );
68
+ leftChild.parent = parent.hash;
69
+ rightChild.parent = parent.hash;
70
+ return parent;
71
+ }
72
+ proof(leafHash) {
73
+ const proofTree = [];
74
+ let layerNum = 0;
75
+ while (layerNum < this.layers.length - 1) {
76
+ const layer = this.layers[layerNum];
77
+ if (layer === void 0) {
78
+ throw new common.ProsopoError("DATASET.MERKLE_ERROR", {
79
+ context: {
80
+ error: "layer undefined",
81
+ failedFuncName: this.proof.name,
82
+ layerNum
83
+ }
84
+ });
85
+ }
86
+ const leafIndex = layer.indexOf(leafHash);
87
+ let partnerIndex = leafIndex % 2 && leafIndex > 0 ? leafIndex - 1 : leafIndex + 1;
88
+ if (partnerIndex > layer.length - 1) {
89
+ partnerIndex = leafIndex;
90
+ }
91
+ const pair = [leafHash];
92
+ const partner = util.at(layer, partnerIndex);
93
+ if (partnerIndex > leafIndex) {
94
+ pair.push(partner);
95
+ } else {
96
+ pair.unshift(partner);
97
+ }
98
+ proofTree.push([util.at(pair, 0), util.at(pair, 1)]);
99
+ layerNum += 1;
100
+ leafHash = common.hexHashArray(pair);
101
+ }
102
+ const last = util.at(this.layers, this.layers.length - 1);
103
+ return [...proofTree, [util.at(last, 0)]];
104
+ }
105
+ }
106
+ function verifyProof(leaf, proof) {
107
+ try {
108
+ if (util.at(proof, 0).indexOf(leaf) === -1) {
109
+ return false;
110
+ }
111
+ for (const [layerIndex, layer] of proof.entries()) {
112
+ leaf = common.hexHashArray(layer);
113
+ if (util.at(proof, layerIndex + 1).indexOf(leaf) === -1) {
114
+ return false;
115
+ }
116
+ const last = util.at(proof, proof.length - 1);
117
+ if (leaf === util.at(last, 0)) {
118
+ return true;
119
+ }
120
+ }
121
+ return false;
122
+ } catch (err) {
123
+ return false;
124
+ }
125
+ }
126
+ exports.CaptchaMerkleTree = CaptchaMerkleTree;
127
+ exports.verifyProof = verifyProof;
@@ -0,0 +1,23 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
3
+ const common = require("@prosopo/common");
4
+ async function downloadImage(url) {
5
+ try {
6
+ const response = await fetch(url);
7
+ if (!response.ok) {
8
+ throw new common.ProsopoDatasetError("API.BAD_REQUEST", {
9
+ context: {
10
+ error: `Network response was not ok, status: ${response.status}`,
11
+ url
12
+ }
13
+ });
14
+ }
15
+ const buffer = await response.arrayBuffer();
16
+ return new Uint8Array(buffer);
17
+ } catch (err) {
18
+ throw new common.ProsopoEnvError("DATABASE.IMAGE_GET_FAILED", {
19
+ context: { error: err }
20
+ });
21
+ }
22
+ }
23
+ exports.downloadImage = downloadImage;
@@ -0,0 +1,31 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
3
+ require("./captcha/index.cjs");
4
+ const captchas = require("./tests/mocks/data/captchas.cjs");
5
+ const captcha = require("./captcha/captcha.cjs");
6
+ const merkle = require("./captcha/merkle.cjs");
7
+ const util = require("./captcha/util.cjs");
8
+ const dataset = require("./captcha/dataset.cjs");
9
+ exports.datasetWithIndexSolutions = captchas.datasetWithIndexSolutions;
10
+ exports.datasetWithSolutionHashes = captchas.datasetWithSolutionHashes;
11
+ exports.NO_SOLUTION_VALUE = captcha.NO_SOLUTION_VALUE;
12
+ exports.captchaSort = captcha.captchaSort;
13
+ exports.compareCaptchaSolutions = captcha.compareCaptchaSolutions;
14
+ exports.computeCaptchaHash = captcha.computeCaptchaHash;
15
+ exports.computeCaptchaSolutionHash = captcha.computeCaptchaSolutionHash;
16
+ exports.computeItemHash = captcha.computeItemHash;
17
+ exports.computePendingRequestHash = captcha.computePendingRequestHash;
18
+ exports.getSolutionValueToHash = captcha.getSolutionValueToHash;
19
+ exports.matchItemsToSolutions = captcha.matchItemsToSolutions;
20
+ exports.parseAndSortCaptchaSolutions = captcha.parseAndSortCaptchaSolutions;
21
+ exports.parseCaptchaAssets = captcha.parseCaptchaAssets;
22
+ exports.parseCaptchaDataset = captcha.parseCaptchaDataset;
23
+ exports.sortAndComputeHashes = captcha.sortAndComputeHashes;
24
+ exports.CaptchaMerkleTree = merkle.CaptchaMerkleTree;
25
+ exports.verifyProof = merkle.verifyProof;
26
+ exports.downloadImage = util.downloadImage;
27
+ exports.addSolutionHashesToDataset = dataset.addSolutionHashesToDataset;
28
+ exports.buildCaptchaTree = dataset.buildCaptchaTree;
29
+ exports.buildDataset = dataset.buildDataset;
30
+ exports.hashDatasetItems = dataset.hashDatasetItems;
31
+ exports.validateDatasetContent = dataset.validateDatasetContent;