@prosopo/procaptcha 0.2.25 → 0.2.32

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.
@@ -6,13 +6,11 @@ require("./types/index.cjs");
6
6
  require("./utils/index.cjs");
7
7
  const Manager = require("./modules/Manager.cjs");
8
8
  const ProsopoCaptchaApi = require("./modules/ProsopoCaptchaApi.cjs");
9
- const collector = require("./modules/collector.cjs");
10
9
  const manager = require("./types/manager.cjs");
11
10
  const utils = require("./utils/utils.cjs");
12
11
  exports.Manager = Manager.Manager;
13
12
  exports.defaultState = Manager.defaultState;
14
13
  exports.getNetwork = Manager.getNetwork;
15
14
  exports.ProsopoCaptchaApi = ProsopoCaptchaApi.ProsopoCaptchaApi;
16
- exports.startCollector = collector.startCollector;
17
15
  exports.ProcapchaEventNames = manager.ProcapchaEventNames;
18
16
  exports.sleep = utils.sleep;
@@ -8,7 +8,7 @@ const keyring = require("@polkadot/keyring");
8
8
  const contract = require("@prosopo/contract");
9
9
  const common = require("@prosopo/common");
10
10
  const ws = require("@polkadot/rpc-provider/ws");
11
- const contractInfo = require("@prosopo/captcha-contract/contract-info");
11
+ const captcha = require("../contracts/captcha/dist/contract-info/captcha.cjs");
12
12
  const util = require("@prosopo/util");
13
13
  const random = require("@polkadot/util-crypto/random");
14
14
  const utils = require("../utils/utils.cjs");
@@ -57,14 +57,12 @@ function Manager(configOptional, state, onStateUpdate, callbacks) {
57
57
  onError: alertError,
58
58
  onHuman: (output) => {
59
59
  console.log("onHuman event triggered", output);
60
- updateState({ sendData: !state.sendData });
61
60
  },
62
61
  onExtensionNotFound: () => {
63
62
  alert("No extension found");
64
63
  },
65
64
  onFailed: () => {
66
65
  alert("Captcha challenge failed. Please try again");
67
- updateState({ sendData: !state.sendData });
68
66
  },
69
67
  onExpired: () => {
70
68
  alert("Completed challenge has expired, please try again");
@@ -74,7 +72,6 @@ function Manager(configOptional, state, onStateUpdate, callbacks) {
74
72
  },
75
73
  onOpen: () => {
76
74
  console.log("onOpen event triggered");
77
- updateState({ sendData: !state.sendData });
78
75
  },
79
76
  onClose: () => {
80
77
  console.log("onClose event triggered");
@@ -149,12 +146,7 @@ function Manager(configOptional, state, onStateUpdate, callbacks) {
149
146
  if (providerUrlFromStorage) {
150
147
  providerApi = await loadProviderApi(providerUrlFromStorage);
151
148
  try {
152
- const verifyDappUserResponse = await providerApi.verifyDappUser(
153
- getDappAccount(),
154
- account.account.address,
155
- void 0,
156
- configOptional.challengeValidLength
157
- );
149
+ const verifyDappUserResponse = await providerApi.verifyDappUser(account.account.address);
158
150
  if (verifyDappUserResponse.solutionApproved) {
159
151
  updateState({ isHuman: true, loading: false });
160
152
  events.onHuman({
@@ -193,7 +185,7 @@ function Manager(configOptional, state, onStateUpdate, callbacks) {
193
185
  if (challenge.captchas.length <= 0) {
194
186
  throw new Error("No captchas returned from provider");
195
187
  }
196
- const timeMillis = challenge.captchas.map((captcha) => captcha.captcha.timeLimitMs || 30 * 1e3).reduce((a, b) => a + b);
188
+ const timeMillis = challenge.captchas.map((captcha2) => captcha2.captcha.timeLimitMs || 30 * 1e3).reduce((a, b) => a + b);
197
189
  const timeout = setTimeout(() => {
198
190
  console.log("challenge expired after " + timeMillis + "ms");
199
191
  events.onChallengeExpired();
@@ -219,11 +211,11 @@ function Manager(configOptional, state, onStateUpdate, callbacks) {
219
211
  updateState({ showModal: false });
220
212
  const challenge = state.challenge;
221
213
  const salt = random.randomAsHex();
222
- const captchaSolution = state.challenge.captchas.map((captcha, index) => {
214
+ const captchaSolution = state.challenge.captchas.map((captcha2, index) => {
223
215
  const solution = util.at(state.solutions, index);
224
216
  return {
225
- captchaId: captcha.captcha.captchaId,
226
- captchaContentId: captcha.captcha.captchaContentId,
217
+ captchaId: captcha2.captcha.captchaId,
218
+ captchaContentId: captcha2.captcha.captchaContentId,
227
219
  salt,
228
220
  solution
229
221
  };
@@ -387,29 +379,19 @@ function Manager(configOptional, state, onStateUpdate, callbacks) {
387
379
  const keyring$1 = new keyring.Keyring({ type, ss58Format: api2.registry.chainSS58 });
388
380
  return new contract.ProsopoCaptchaContract(
389
381
  api2,
390
- JSON.parse(contractInfo.ContractAbi),
382
+ JSON.parse(captcha.ContractAbi),
391
383
  network.contract.address,
392
384
  "prosopo",
393
385
  0,
394
386
  keyring$1.addFromAddress(getAccount().account.address)
395
387
  );
396
388
  };
397
- const exportData = async (events2) => {
398
- var _a;
399
- const providerUrl = storage.getProviderUrl() || ((_a = state.captchaApi) == null ? void 0 : _a.provider.provider.url.toString());
400
- if (!providerUrl) {
401
- return;
402
- }
403
- const providerApi = await loadProviderApi(providerUrl);
404
- await providerApi.submitUserEvents(events2, getAccount().account.address);
405
- };
406
389
  return {
407
390
  start,
408
391
  cancel,
409
392
  submit,
410
393
  select,
411
- nextRound,
412
- exportData
394
+ nextRound
413
395
  };
414
396
  }
415
397
  exports.Manager = Manager;
@@ -1,10 +1,12 @@
1
1
  "use strict";
2
2
  Object.defineProperties(exports, { __esModule: { value: true }, [Symbol.toStringTag]: { value: "Module" } });
3
- const datasets = require("@prosopo/datasets");
3
+ require("../packages/datasets/dist/index.cjs");
4
4
  const handlers = require("../api/handlers.cjs");
5
5
  const common = require("@prosopo/common");
6
6
  const util = require("@prosopo/util");
7
7
  const string = require("@polkadot/util/string");
8
+ const merkle = require("../packages/datasets/dist/captcha/merkle.cjs");
9
+ const captcha = require("../packages/datasets/dist/captcha/captcha.cjs");
8
10
  class ProsopoCaptchaApi {
9
11
  constructor(userAccount, contract, provider, providerApi, web2, dappAccount) {
10
12
  this.userAccount = userAccount;
@@ -35,7 +37,7 @@ class ProsopoCaptchaApi {
35
37
  if (!verifyCaptchaData(captchaWithProof)) {
36
38
  throw new common.ProsopoEnvError("CAPTCHA.INVALID_CAPTCHA_CHALLENGE");
37
39
  }
38
- if (!datasets.verifyProof(captchaWithProof.captcha.captchaContentId, captchaWithProof.proof)) {
40
+ if (!merkle.verifyProof(captchaWithProof.captcha.captchaContentId, captchaWithProof.proof)) {
39
41
  throw new common.ProsopoEnvError("CAPTCHA.INVALID_CAPTCHA_CHALLENGE");
40
42
  }
41
43
  }
@@ -43,8 +45,8 @@ class ProsopoCaptchaApi {
43
45
  return;
44
46
  }
45
47
  async submitCaptchaSolution(signer, requestHash, datasetId, solutions, salt) {
46
- const tree = new datasets.CaptchaMerkleTree();
47
- const captchasHashed = solutions.map((captcha) => datasets.computeCaptchaSolutionHash(captcha));
48
+ const tree = new merkle.CaptchaMerkleTree();
49
+ const captchasHashed = solutions.map((captcha$1) => captcha.computeCaptchaSolutionHash(captcha$1));
48
50
  tree.build(captchasHashed);
49
51
  const commitmentId = tree.root.hash;
50
52
  console.log("solveCaptchaChallenge commitmentId", commitmentId);
@@ -77,15 +79,15 @@ class ProsopoCaptchaApi {
77
79
  }
78
80
  }
79
81
  async function verifyCaptchaData(captchaWithProof) {
80
- const captcha = captchaWithProof.captcha;
82
+ const captcha$1 = captchaWithProof.captcha;
81
83
  const proof = captchaWithProof.proof;
82
- if (!(await Promise.all(captcha.items.map(async (item) => (await datasets.computeItemHash(item)).hash === item.hash))).every(
84
+ if (!(await Promise.all(captcha$1.items.map(async (item) => (await captcha.computeItemHash(item)).hash === item.hash))).every(
83
85
  (hash) => hash === true
84
86
  )) {
85
87
  return false;
86
88
  }
87
- const captchaHash = datasets.computeCaptchaHash(captcha, false, false, false);
88
- if (captchaHash !== captcha.captchaContentId) {
89
+ const captchaHash = captcha.computeCaptchaHash(captcha$1, false, false, false);
90
+ if (captchaHash !== captcha$1.captchaContentId) {
89
91
  return false;
90
92
  }
91
93
  return util.at(proof, 0).indexOf(captchaHash) !== -1;
@@ -2,9 +2,7 @@
2
2
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
3
3
  const Manager = require("./Manager.cjs");
4
4
  const ProsopoCaptchaApi = require("./ProsopoCaptchaApi.cjs");
5
- const collector = require("./collector.cjs");
6
5
  exports.Manager = Manager.Manager;
7
6
  exports.defaultState = Manager.defaultState;
8
7
  exports.getNetwork = Manager.getNetwork;
9
8
  exports.ProsopoCaptchaApi = ProsopoCaptchaApi.ProsopoCaptchaApi;
10
- exports.startCollector = collector.startCollector;
@@ -0,0 +1,143 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
3
+ const types = require("@prosopo/types");
4
+ const common = require("@prosopo/common");
5
+ const util = require("@prosopo/util");
6
+ const util$1 = require("./util.cjs");
7
+ const NO_SOLUTION_VALUE = "NO_SOLUTION";
8
+ function parseCaptchaDataset(datasetJSON) {
9
+ try {
10
+ const result = types.DatasetWithNumericSolutionSchema.parse(datasetJSON);
11
+ const result2 = {
12
+ format: result.format,
13
+ captchas: result.captchas.map((captcha) => {
14
+ return {
15
+ ...captcha,
16
+ solution: captcha.solution ? matchItemsToSolutions(captcha.solution, captcha.items) : [],
17
+ unlabelled: captcha.unlabelled ? matchItemsToSolutions(captcha.unlabelled, captcha.items) : []
18
+ };
19
+ })
20
+ };
21
+ if (result.datasetId !== void 0)
22
+ 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.ProsopoEnvError(err);
32
+ }
33
+ }
34
+ function parseAndSortCaptchaSolutions(captchaJSON) {
35
+ try {
36
+ return types.CaptchaSolutionArraySchema.parse(captchaJSON).map((captcha) => ({
37
+ ...captcha,
38
+ solution: captcha.solution.sort()
39
+ }));
40
+ } catch (err) {
41
+ throw new common.ProsopoEnvError(err);
42
+ }
43
+ }
44
+ function captchaSort(a, b) {
45
+ return a.captchaId.localeCompare(b.captchaId);
46
+ }
47
+ function sortAndComputeHashes(received, stored) {
48
+ received.sort(captchaSort);
49
+ stored.sort(captchaSort);
50
+ return stored.map(({ salt, items = [], target = "", captchaId, solved }, index) => {
51
+ const item = util.at(received, index);
52
+ if (captchaId != item.captchaId) {
53
+ throw new common.ProsopoEnvError("CAPTCHA.ID_MISMATCH");
54
+ }
55
+ return {
56
+ hash: computeCaptchaHash({
57
+ solution: solved ? item.solution : [],
58
+ salt,
59
+ items,
60
+ target
61
+ }, true, true, false),
62
+ captchaId
63
+ };
64
+ });
65
+ }
66
+ function compareCaptchaSolutions(received, stored) {
67
+ if (received.length && stored.length && received.length === stored.length) {
68
+ const hashes = sortAndComputeHashes(received, stored);
69
+ return hashes.every(({ hash, captchaId }) => hash === captchaId);
70
+ }
71
+ return false;
72
+ }
73
+ function computeCaptchaHash(captcha, includeSolution = false, includeSalt = false, sortItemHashes) {
74
+ try {
75
+ const itemHashes = captcha.items.map((item, index) => {
76
+ if (item.hash) {
77
+ return item.hash;
78
+ } else {
79
+ throw new common.ProsopoEnvError("CAPTCHA.MISSING_ITEM_HASH", computeCaptchaHash.name, void 0, index);
80
+ }
81
+ });
82
+ return common.hexHashArray([
83
+ captcha.target,
84
+ // empty array hashes as empty string, undefined solution results in the array [`NO_SOLUTION`]
85
+ // [undefined] also hashes as empty string, which is why we don't use it
86
+ ...includeSolution ? getSolutionValueToHash(captcha.solution) : [],
87
+ includeSalt ? captcha.salt : "",
88
+ sortItemHashes ? itemHashes.sort() : itemHashes
89
+ ]);
90
+ } catch (err) {
91
+ throw new common.ProsopoEnvError(err);
92
+ }
93
+ }
94
+ function getSolutionValueToHash(solution) {
95
+ return solution !== void 0 ? solution.sort() : [NO_SOLUTION_VALUE];
96
+ }
97
+ async function computeItemHash(item) {
98
+ if (item.type === "text") {
99
+ return { ...item, hash: common.hexHash(item.data) };
100
+ } else if (item.type === "image") {
101
+ return { ...item, hash: common.hexHash(await util$1.downloadImage(item.data)) };
102
+ } else {
103
+ throw new common.ProsopoEnvError("CAPTCHA.INVALID_ITEM_FORMAT");
104
+ }
105
+ }
106
+ function matchItemsToSolutions(solutions, items) {
107
+ if (!items) {
108
+ return [];
109
+ }
110
+ return solutions.map((solution) => {
111
+ if (typeof solution === "string") {
112
+ if (!(items == null ? void 0 : items.some((item2) => item2.hash === solution))) {
113
+ throw new common.ProsopoEnvError("CAPTCHA.INVALID_ITEM_HASH");
114
+ }
115
+ return solution;
116
+ }
117
+ const item = util.at(items, solution);
118
+ const hash = item.hash;
119
+ return hash;
120
+ });
121
+ }
122
+ function computeCaptchaSolutionHash(captcha) {
123
+ return common.hexHashArray([captcha.captchaId, captcha.captchaContentId, [...captcha.solution].sort(), captcha.salt]);
124
+ }
125
+ function computePendingRequestHash(captchaIds, userAccount, salt) {
126
+ return common.hexHashArray([...captchaIds.sort(), userAccount, salt]);
127
+ }
128
+ function parseCaptchaAssets(item, assetsResolver) {
129
+ return { ...item, path: (assetsResolver == null ? void 0 : assetsResolver.resolveAsset(item.data).getURL()) || item.data };
130
+ }
131
+ exports.NO_SOLUTION_VALUE = NO_SOLUTION_VALUE;
132
+ exports.captchaSort = captchaSort;
133
+ exports.compareCaptchaSolutions = compareCaptchaSolutions;
134
+ exports.computeCaptchaHash = computeCaptchaHash;
135
+ exports.computeCaptchaSolutionHash = computeCaptchaSolutionHash;
136
+ exports.computeItemHash = computeItemHash;
137
+ exports.computePendingRequestHash = computePendingRequestHash;
138
+ exports.getSolutionValueToHash = getSolutionValueToHash;
139
+ exports.matchItemsToSolutions = matchItemsToSolutions;
140
+ exports.parseAndSortCaptchaSolutions = parseAndSortCaptchaSolutions;
141
+ exports.parseCaptchaAssets = parseCaptchaAssets;
142
+ exports.parseCaptchaDataset = parseCaptchaDataset;
143
+ exports.sortAndComputeHashes = sortAndComputeHashes;
@@ -0,0 +1,87 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
3
+ const merkle = require("./merkle.cjs");
4
+ const common = require("@prosopo/common");
5
+ const util = require("@prosopo/util");
6
+ const captcha = require("./captcha.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(captcha$1.items.map(async (item) => captcha.computeItemHash(item)));
11
+ return {
12
+ ...captcha$1,
13
+ items
14
+ };
15
+ });
16
+ }
17
+ async function validateDatasetContent(datasetOriginal) {
18
+ const captchaPromises = await hashDatasetItems(datasetOriginal);
19
+ const captchas = await Promise.all(captchaPromises);
20
+ const dataset = {
21
+ ...datasetOriginal,
22
+ captchas
23
+ };
24
+ const hashes = dataset.captchas.map((captcha2) => {
25
+ const captchaRaw = datasetOriginal.captchas.find((captchaRaw2) => "captchaId" in captchaRaw2 ? captchaRaw2.captchaId === captcha2.captchaId : false);
26
+ if (captchaRaw) {
27
+ return captcha2.items.every((item, index) => item.hash === util.at(captchaRaw.items, index).hash);
28
+ } else {
29
+ return false;
30
+ }
31
+ });
32
+ return hashes.every((hash) => hash);
33
+ }
34
+ async function buildDataset(datasetRaw) {
35
+ var _a, _b;
36
+ logger.info(`Adding solution hashes to dataset`);
37
+ const dataset = await addSolutionHashesToDataset(datasetRaw);
38
+ logger.info(`Building dataset merkle trees`);
39
+ const contentTree = await buildCaptchaTree(dataset, false, false, true);
40
+ const solutionTree = await buildCaptchaTree(dataset, true, true, false);
41
+ dataset.captchas = dataset.captchas.map((captcha2, index) => {
42
+ var _a2, _b2;
43
+ return {
44
+ ...captcha2,
45
+ captchaId: util.at(solutionTree.leaves, index).hash,
46
+ captchaContentId: util.at(contentTree.leaves, index).hash,
47
+ datasetId: (_a2 = solutionTree.root) == null ? void 0 : _a2.hash,
48
+ datasetContentId: (_b2 = contentTree.root) == null ? void 0 : _b2.hash
49
+ };
50
+ });
51
+ dataset.solutionTree = solutionTree.layers;
52
+ dataset.contentTree = contentTree.layers;
53
+ dataset.datasetId = (_a = solutionTree.root) == null ? void 0 : _a.hash;
54
+ dataset.datasetContentId = (_b = contentTree.root) == null ? void 0 : _b.hash;
55
+ return dataset;
56
+ }
57
+ async function buildCaptchaTree(dataset, includeSolution, includeSalt, sortItemHashes) {
58
+ try {
59
+ const tree = new merkle.CaptchaMerkleTree();
60
+ const datasetWithItemHashes = { ...dataset };
61
+ const captchaHashes = datasetWithItemHashes.captchas.map((captcha$1) => captcha.computeCaptchaHash(captcha$1, includeSolution, includeSalt, sortItemHashes));
62
+ tree.build(captchaHashes);
63
+ return tree;
64
+ } catch (err) {
65
+ throw new common.ProsopoEnvError("DATASET.HASH_ERROR");
66
+ }
67
+ }
68
+ async function addSolutionHashesToDataset(datasetRaw) {
69
+ const captchaPromises = datasetRaw.captchas.map(async (captcha$1) => {
70
+ return {
71
+ ...captcha$1,
72
+ items: captcha$1.items,
73
+ // some captcha challenges will not have a solution
74
+ ...captcha$1.solution !== void 0 && { solution: captcha.matchItemsToSolutions(captcha$1.solution, captcha$1.items) }
75
+ };
76
+ });
77
+ const captchas = await Promise.all(captchaPromises);
78
+ return {
79
+ ...datasetRaw,
80
+ captchas
81
+ };
82
+ }
83
+ exports.addSolutionHashesToDataset = addSolutionHashesToDataset;
84
+ exports.buildCaptchaTree = buildCaptchaTree;
85
+ exports.buildDataset = buildDataset;
86
+ exports.hashDatasetItems = hashDatasetItems;
87
+ 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,106 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
3
+ const util = require("@prosopo/util");
4
+ const common = require("@prosopo/common");
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
+ build(leaves) {
17
+ if (this.layers.length) {
18
+ this.layers = [];
19
+ }
20
+ const layerZero = [];
21
+ for (const leaf of leaves) {
22
+ const node = new MerkleNode(leaf);
23
+ this.leaves.push(node);
24
+ layerZero.push(node.hash);
25
+ }
26
+ this.layers.push(layerZero);
27
+ this.root = this.buildMerkleTree(this.leaves)[0];
28
+ }
29
+ buildMerkleTree(leaves) {
30
+ const numLeaves = leaves.length;
31
+ if (numLeaves === 1) {
32
+ return leaves;
33
+ }
34
+ const parents = [];
35
+ let leafIndex = 0;
36
+ const newLayer = [];
37
+ while (leafIndex < numLeaves) {
38
+ const leftChild = leaves[leafIndex];
39
+ if (leftChild === void 0) {
40
+ throw new Error("leftChild undefined");
41
+ }
42
+ const rightChild = leafIndex + 1 < numLeaves ? util.at(leaves, leafIndex + 1) : leftChild;
43
+ const parentNode = this.createParent(leftChild, rightChild);
44
+ newLayer.push(parentNode.hash);
45
+ parents.push(parentNode);
46
+ leafIndex += 2;
47
+ }
48
+ this.layers.push(newLayer);
49
+ return this.buildMerkleTree(parents);
50
+ }
51
+ createParent(leftChild, rightChild) {
52
+ const parent = new MerkleNode(common.hexHashArray([leftChild.hash, rightChild.hash]));
53
+ leftChild.parent = parent.hash;
54
+ rightChild.parent = parent.hash;
55
+ return parent;
56
+ }
57
+ proof(leafHash) {
58
+ const proofTree = [];
59
+ let layerNum = 0;
60
+ while (layerNum < this.layers.length - 1) {
61
+ const layer = this.layers[layerNum];
62
+ if (layer === void 0) {
63
+ throw new Error("layer undefined");
64
+ }
65
+ const leafIndex = layer.indexOf(leafHash);
66
+ let partnerIndex = leafIndex % 2 && leafIndex > 0 ? leafIndex - 1 : leafIndex + 1;
67
+ if (partnerIndex > layer.length - 1) {
68
+ partnerIndex = leafIndex;
69
+ }
70
+ const pair = [leafHash];
71
+ const partner = util.at(layer, partnerIndex);
72
+ if (partnerIndex > leafIndex) {
73
+ pair.push(partner);
74
+ } else {
75
+ pair.unshift(partner);
76
+ }
77
+ proofTree.push([util.at(pair, 0), util.at(pair, 1)]);
78
+ layerNum += 1;
79
+ leafHash = common.hexHashArray(pair);
80
+ }
81
+ const last = util.at(this.layers, this.layers.length - 1);
82
+ return [...proofTree, [util.at(last, 0)]];
83
+ }
84
+ }
85
+ function verifyProof(leaf, proof) {
86
+ try {
87
+ if (util.at(proof, 0).indexOf(leaf) === -1) {
88
+ return false;
89
+ }
90
+ for (const [layerIndex, layer] of proof.entries()) {
91
+ leaf = common.hexHashArray(layer);
92
+ if (util.at(proof, layerIndex + 1).indexOf(leaf) === -1) {
93
+ return false;
94
+ }
95
+ const last = util.at(proof, proof.length - 1);
96
+ if (leaf === util.at(last, 0)) {
97
+ return true;
98
+ }
99
+ }
100
+ return false;
101
+ } catch (err) {
102
+ return false;
103
+ }
104
+ }
105
+ exports.CaptchaMerkleTree = CaptchaMerkleTree;
106
+ exports.verifyProof = verifyProof;
@@ -0,0 +1,16 @@
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 Error(`Network response was not ok, status: ${response.status}`);
9
+ }
10
+ const buffer = await response.arrayBuffer();
11
+ return new Uint8Array(buffer);
12
+ } catch (error) {
13
+ throw new common.ProsopoEnvError(error);
14
+ }
15
+ }
16
+ exports.downloadImage = downloadImage;
@@ -0,0 +1,2 @@
1
+ "use strict";
2
+ require("./captcha/index.cjs");
@@ -1 +1 @@
1
- {"version":3,"file":"Manager.d.ts","sourceRoot":"","sources":["../../src/modules/Manager.ts"],"names":[],"mappings":"AAaA,OAAO,EAEH,mBAAmB,EACnB,wBAAwB,EAExB,eAAe,EACf,uBAAuB,EAC1B,MAAM,qBAAqB,CAAA;AAG5B,OAAO,EAGH,4BAA4B,EAE5B,YAAY,EACf,MAAM,gBAAgB,CAAA;AAmBvB,eAAO,MAAM,YAAY,QAAO,QAAQ,eAAe,CAatD,CAAA;AAgBD,eAAO,MAAM,UAAU,WAAY,4BAA4B;;;;;;;;CAM9D,CAAA;AAKD,wBAAgB,OAAO,CACnB,cAAc,EAAE,wBAAwB,EACxC,KAAK,EAAE,eAAe,EACtB,aAAa,EAAE,uBAAuB,EACtC,SAAS,EAAE,mBAAmB;;;;mBA2TR,MAAM;;yBAwKM,YAAY;EAiBjD"}
1
+ {"version":3,"file":"Manager.d.ts","sourceRoot":"","sources":["../../src/modules/Manager.ts"],"names":[],"mappings":"AAaA,OAAO,EAEH,mBAAmB,EACnB,wBAAwB,EAExB,eAAe,EACf,uBAAuB,EAC1B,MAAM,qBAAqB,CAAA;AAG5B,OAAO,EAGH,4BAA4B,EAE5B,YAAY,EACf,MAAM,gBAAgB,CAAA;AA0BvB,eAAO,MAAM,YAAY,QAAO,QAAQ,eAAe,CAatD,CAAA;AAgBD,eAAO,MAAM,UAAU,WAAY,4BAA4B;;;;;;;;CAQ9D,CAAA;AAKD,wBAAgB,OAAO,CACnB,cAAc,EAAE,wBAAwB,EACxC,KAAK,EAAE,eAAe,EACtB,aAAa,EAAE,uBAAuB,EACtC,SAAS,EAAE,mBAAmB;;;;mBA+TR,MAAM;;yBAkLM,YAAY;EAiBjD"}