@reclaimprotocol/js-sdk 5.0.0-dev.0 → 5.0.0-dev.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/README.md +175 -34
- package/dist/index.d.ts +406 -66
- package/dist/index.js +1354 -254
- package/dist/index.js.map +1 -1
- package/package.json +6 -2
package/dist/index.js
CHANGED
|
@@ -22,6 +22,18 @@ var __spreadValues = (a, b) => {
|
|
|
22
22
|
return a;
|
|
23
23
|
};
|
|
24
24
|
var __spreadProps = (a, b) => __defProps(a, __getOwnPropDescs(b));
|
|
25
|
+
var __objRest = (source, exclude) => {
|
|
26
|
+
var target = {};
|
|
27
|
+
for (var prop in source)
|
|
28
|
+
if (__hasOwnProp.call(source, prop) && exclude.indexOf(prop) < 0)
|
|
29
|
+
target[prop] = source[prop];
|
|
30
|
+
if (source != null && __getOwnPropSymbols)
|
|
31
|
+
for (var prop of __getOwnPropSymbols(source)) {
|
|
32
|
+
if (exclude.indexOf(prop) < 0 && __propIsEnum.call(source, prop))
|
|
33
|
+
target[prop] = source[prop];
|
|
34
|
+
}
|
|
35
|
+
return target;
|
|
36
|
+
};
|
|
25
37
|
var __commonJS = (cb, mod) => function __require() {
|
|
26
38
|
return mod || (0, cb[__getOwnPropNames(cb)[0]])((mod = { exports: {} }).exports, mod), mod.exports;
|
|
27
39
|
};
|
|
@@ -72,7 +84,7 @@ var require_package = __commonJS({
|
|
|
72
84
|
"package.json"(exports2, module2) {
|
|
73
85
|
module2.exports = {
|
|
74
86
|
name: "@reclaimprotocol/js-sdk",
|
|
75
|
-
version: "5.0.0-dev.
|
|
87
|
+
version: "5.0.0-dev.2",
|
|
76
88
|
description: "Designed to request proofs from the Reclaim protocol and manage the flow of claims and witness interactions.",
|
|
77
89
|
main: "dist/index.js",
|
|
78
90
|
types: "dist/index.d.ts",
|
|
@@ -148,6 +160,8 @@ var require_package = __commonJS({
|
|
|
148
160
|
"@commitlint/config-conventional": "^17.7.0",
|
|
149
161
|
"@release-it/conventional-changelog": "10.0.6",
|
|
150
162
|
"@types/jest": "^30.0.0",
|
|
163
|
+
"@types/node-forge": "^1.3.14",
|
|
164
|
+
"@types/qrcode": "^1.5.5",
|
|
151
165
|
"@types/qs": "^6.9.11",
|
|
152
166
|
"@types/url-parse": "^1.4.11",
|
|
153
167
|
"@types/uuid": "^9.0.7",
|
|
@@ -163,6 +177,8 @@ var require_package = __commonJS({
|
|
|
163
177
|
canonicalize: "^2.0.0",
|
|
164
178
|
ethers: "^6.9.1",
|
|
165
179
|
"fetch-retry": "^6.0.0",
|
|
180
|
+
"node-forge": "^1.3.3",
|
|
181
|
+
qrcode: "^1.5.4",
|
|
166
182
|
"url-parse": "^1.5.10",
|
|
167
183
|
uuid: "^9.0.1"
|
|
168
184
|
},
|
|
@@ -177,13 +193,33 @@ var require_package = __commonJS({
|
|
|
177
193
|
var index_exports = {};
|
|
178
194
|
__export(index_exports, {
|
|
179
195
|
ReclaimProofRequest: () => ReclaimProofRequest,
|
|
196
|
+
assertValidProofsByHash: () => assertValidProofsByHash,
|
|
197
|
+
assertValidateProof: () => assertValidateProof,
|
|
198
|
+
assertVerifiedProof: () => assertVerifiedProof,
|
|
180
199
|
clearDeviceCache: () => clearDeviceCache,
|
|
200
|
+
createLinkWithTemplateData: () => createLinkWithTemplateData,
|
|
201
|
+
fetchProviderConfigs: () => fetchProviderConfigs,
|
|
202
|
+
fetchProviderHashRequirementsBy: () => fetchProviderHashRequirementsBy,
|
|
203
|
+
fetchStatusUrl: () => fetchStatusUrl,
|
|
204
|
+
generateSpecsFromRequestSpecTemplate: () => generateSpecsFromRequestSpecTemplate,
|
|
205
|
+
getAttestors: () => getAttestors,
|
|
181
206
|
getDeviceType: () => getDeviceType,
|
|
207
|
+
getHttpProviderClaimParamsFromProof: () => getHttpProviderClaimParamsFromProof,
|
|
182
208
|
getMobileDeviceType: () => getMobileDeviceType,
|
|
209
|
+
getProviderHashRequirementsFromSpec: () => getProviderHashRequirementsFromSpec,
|
|
210
|
+
getShortenedUrl: () => getShortenedUrl,
|
|
211
|
+
hashRequestSpec: () => hashRequestSpec,
|
|
212
|
+
initSession: () => initSession,
|
|
183
213
|
isDesktopDevice: () => isDesktopDevice,
|
|
214
|
+
isHttpProviderClaimParams: () => isHttpProviderClaimParams,
|
|
184
215
|
isMobileDevice: () => isMobileDevice,
|
|
216
|
+
recoverSignersOfSignedClaim: () => recoverSignersOfSignedClaim,
|
|
217
|
+
takePairsWhereValueIsArray: () => takePairsWhereValueIsArray,
|
|
218
|
+
takeTemplateParametersFromProofs: () => takeTemplateParametersFromProofs,
|
|
185
219
|
transformForOnchain: () => transformForOnchain,
|
|
186
|
-
|
|
220
|
+
updateSession: () => updateSession,
|
|
221
|
+
verifyProof: () => verifyProof,
|
|
222
|
+
verifyTeeAttestation: () => verifyTeeAttestation
|
|
187
223
|
});
|
|
188
224
|
module.exports = __toCommonJS(index_exports);
|
|
189
225
|
|
|
@@ -196,20 +232,20 @@ var RECLAIM_EXTENSION_ACTIONS = {
|
|
|
196
232
|
};
|
|
197
233
|
|
|
198
234
|
// src/Reclaim.ts
|
|
199
|
-
var
|
|
235
|
+
var import_ethers5 = require("ethers");
|
|
200
236
|
var import_canonicalize3 = __toESM(require("canonicalize"));
|
|
201
237
|
|
|
202
238
|
// src/utils/errors.ts
|
|
203
239
|
function createErrorClass(name) {
|
|
204
240
|
return class extends Error {
|
|
205
241
|
constructor(message, innerError) {
|
|
206
|
-
const fullMessage = innerError ? `${message || ""} caused by ${innerError.name}: ${innerError.message}` : message;
|
|
242
|
+
const fullMessage = innerError ? `${message || ""} caused by ${innerError && typeof innerError === "object" && "name" in innerError ? innerError.name : "Error"}: ${innerError && typeof innerError === "object" && "message" in innerError ? innerError.message : String(innerError)}` : message;
|
|
207
243
|
super(fullMessage);
|
|
208
244
|
this.innerError = innerError;
|
|
209
245
|
this.name = name;
|
|
210
246
|
if (innerError) {
|
|
211
247
|
this.stack += `
|
|
212
|
-
Caused by: ${innerError.stack}`;
|
|
248
|
+
Caused by: ${innerError && typeof innerError === "object" && "stack" in innerError ? innerError.stack : String(innerError)}`;
|
|
213
249
|
}
|
|
214
250
|
}
|
|
215
251
|
};
|
|
@@ -217,6 +253,7 @@ Caused by: ${innerError.stack}`;
|
|
|
217
253
|
var TimeoutError = createErrorClass("TimeoutError");
|
|
218
254
|
var ProofNotVerifiedError = createErrorClass("ProofNotVerifiedError");
|
|
219
255
|
var ProofNotValidatedError = createErrorClass("ProofNotValidatedError");
|
|
256
|
+
var InvalidRequestSpecError = createErrorClass("InvalidRequestSpecError");
|
|
220
257
|
var UnknownProofsNotValidatedError = createErrorClass("UnknownProofsNotValidatedError");
|
|
221
258
|
var SessionNotStartedError = createErrorClass("SessionNotStartedError");
|
|
222
259
|
var ProviderNotFoundError = createErrorClass("ProviderNotFoundError");
|
|
@@ -337,15 +374,13 @@ var constants = {
|
|
|
337
374
|
get DEFAULT_ATTESTORS_URL() {
|
|
338
375
|
return `${BACKEND_BASE_URL}/api/attestors`;
|
|
339
376
|
},
|
|
340
|
-
|
|
341
|
-
return `${BACKEND_BASE_URL}/api/providers/${providerId}?versionNumber=${exactProviderVersionString}`;
|
|
377
|
+
DEFAULT_PROVIDER_CONFIGS_URL(providerId, exactProviderVersionString, allowedTags) {
|
|
378
|
+
return `${BACKEND_BASE_URL}/api/providers/${providerId}/configs?versionNumber=${exactProviderVersionString || ""}&allowedTags=${(allowedTags == null ? void 0 : allowedTags.join(",")) || ""}`;
|
|
342
379
|
},
|
|
343
380
|
// URL for sharing Reclaim templates
|
|
344
381
|
RECLAIM_SHARE_URL: "https://share.reclaimprotocol.org/verifier/?template=",
|
|
345
382
|
// Chrome extension URL for Reclaim Protocol
|
|
346
|
-
CHROME_EXTENSION_URL: "https://chromewebstore.google.com/detail/reclaim-extension/oafieibbbcepkmenknelhmgaoahamdeh"
|
|
347
|
-
// QR Code API base URL
|
|
348
|
-
QR_CODE_API_URL: "https://api.qrserver.com/v1/create-qr-code/"
|
|
383
|
+
CHROME_EXTENSION_URL: "https://chromewebstore.google.com/detail/reclaim-extension/oafieibbbcepkmenknelhmgaoahamdeh"
|
|
349
384
|
};
|
|
350
385
|
|
|
351
386
|
// src/utils/validationUtils.ts
|
|
@@ -586,92 +621,6 @@ var http = {
|
|
|
586
621
|
}
|
|
587
622
|
};
|
|
588
623
|
|
|
589
|
-
// src/witness.ts
|
|
590
|
-
var import_ethers2 = require("ethers");
|
|
591
|
-
function createSignDataForClaim(data) {
|
|
592
|
-
const identifier = getIdentifierFromClaimInfo(data);
|
|
593
|
-
const lines = [
|
|
594
|
-
identifier,
|
|
595
|
-
data.owner.toLowerCase(),
|
|
596
|
-
data.timestampS.toString(),
|
|
597
|
-
data.epoch.toString()
|
|
598
|
-
];
|
|
599
|
-
return lines.join("\n");
|
|
600
|
-
}
|
|
601
|
-
function getIdentifierFromClaimInfo(info) {
|
|
602
|
-
let canonicalContext = info.context || "";
|
|
603
|
-
if (canonicalContext.length > 0) {
|
|
604
|
-
try {
|
|
605
|
-
const ctx = JSON.parse(canonicalContext);
|
|
606
|
-
canonicalContext = canonicalStringify(ctx);
|
|
607
|
-
} catch (e) {
|
|
608
|
-
throw new Error("unable to parse non-empty context. Must be JSON");
|
|
609
|
-
}
|
|
610
|
-
}
|
|
611
|
-
const str = `${info.provider}
|
|
612
|
-
${info.parameters}
|
|
613
|
-
${canonicalContext}`;
|
|
614
|
-
return import_ethers2.ethers.keccak256(strToUint8Array(str)).toLowerCase();
|
|
615
|
-
}
|
|
616
|
-
function hashProofClaimParams(params) {
|
|
617
|
-
const serializedParams = getProviderParamsAsCanonicalizedString(params);
|
|
618
|
-
return import_ethers2.ethers.keccak256(
|
|
619
|
-
strToUint8Array(serializedParams)
|
|
620
|
-
).toLowerCase();
|
|
621
|
-
}
|
|
622
|
-
function strToUint8Array(str) {
|
|
623
|
-
return new TextEncoder().encode(str);
|
|
624
|
-
}
|
|
625
|
-
function getProviderParamsAsCanonicalizedString(params) {
|
|
626
|
-
var _a, _b, _c, _d, _e, _f, _g;
|
|
627
|
-
const filteredParams = {
|
|
628
|
-
url: (_a = params == null ? void 0 : params.url) != null ? _a : "",
|
|
629
|
-
// METHOD needs to be explicitly specified and absence or unknown method should cause error, but we're choosing to ignore it in this case
|
|
630
|
-
method: (_b = params == null ? void 0 : params.method) != null ? _b : "GET",
|
|
631
|
-
body: (_c = params == null ? void 0 : params.body) != null ? _c : "",
|
|
632
|
-
responseMatches: (_e = (_d = params == null ? void 0 : params.responseMatches) == null ? void 0 : _d.map((it) => {
|
|
633
|
-
var _a2, _b2;
|
|
634
|
-
return {
|
|
635
|
-
value: (_a2 = it.value) != null ? _a2 : "",
|
|
636
|
-
// This needs to be explicitly specified and absence should cause error, but we're choosing to ignore it in this case
|
|
637
|
-
type: (_b2 = it.type) != null ? _b2 : "contains",
|
|
638
|
-
invert: it.invert || void 0,
|
|
639
|
-
isOptional: it.isOptional || void 0
|
|
640
|
-
};
|
|
641
|
-
})) != null ? _e : [],
|
|
642
|
-
responseRedactions: (_g = (_f = params == null ? void 0 : params.responseRedactions) == null ? void 0 : _f.map((it) => {
|
|
643
|
-
var _a2, _b2, _c2;
|
|
644
|
-
return {
|
|
645
|
-
xPath: (_a2 = it.xPath) != null ? _a2 : "",
|
|
646
|
-
jsonPath: (_b2 = it.jsonPath) != null ? _b2 : "",
|
|
647
|
-
regex: (_c2 = it.regex) != null ? _c2 : "",
|
|
648
|
-
hash: it.hash || void 0
|
|
649
|
-
};
|
|
650
|
-
})) != null ? _g : []
|
|
651
|
-
};
|
|
652
|
-
const serializedParams = canonicalStringify(filteredParams);
|
|
653
|
-
return serializedParams;
|
|
654
|
-
}
|
|
655
|
-
|
|
656
|
-
// src/utils/providerUtils.ts
|
|
657
|
-
function getProviderHashRequirementsFromSpec(spec) {
|
|
658
|
-
var _a;
|
|
659
|
-
return {
|
|
660
|
-
hashes: ((_a = spec == null ? void 0 : spec.requests) == null ? void 0 : _a.map(hashRequestSpec)) || []
|
|
661
|
-
};
|
|
662
|
-
}
|
|
663
|
-
function hashRequestSpec(request) {
|
|
664
|
-
const hash = hashProofClaimParams(__spreadProps(__spreadValues({}, request), {
|
|
665
|
-
// Body is strictly empty unless body sniff is explicitly enabled
|
|
666
|
-
body: request.bodySniff.enabled ? request.bodySniff.template : ""
|
|
667
|
-
}));
|
|
668
|
-
return {
|
|
669
|
-
value: hash,
|
|
670
|
-
required: request.required,
|
|
671
|
-
multiple: request.multiple
|
|
672
|
-
};
|
|
673
|
-
}
|
|
674
|
-
|
|
675
624
|
// src/utils/sessionUtils.ts
|
|
676
625
|
var logger4 = logger_default.logger;
|
|
677
626
|
function initSession(providerId, appId, timestamp, signature, versionNumber) {
|
|
@@ -748,17 +697,24 @@ function fetchStatusUrl(sessionId) {
|
|
|
748
697
|
}
|
|
749
698
|
});
|
|
750
699
|
}
|
|
751
|
-
function
|
|
700
|
+
function fetchProviderConfigs(providerId, exactProviderVersionString, allowedTags) {
|
|
752
701
|
return __async(this, null, function* () {
|
|
753
702
|
validateFunctionParams(
|
|
754
703
|
[
|
|
755
|
-
{ input: providerId, paramName: "providerId", isString: true }
|
|
756
|
-
{ input: exactProviderVersionString, paramName: "exactProviderVersionString", isString: true }
|
|
704
|
+
{ input: providerId, paramName: "providerId", isString: true }
|
|
757
705
|
],
|
|
758
|
-
"
|
|
706
|
+
"fetchProviderConfigs"
|
|
759
707
|
);
|
|
708
|
+
if (exactProviderVersionString != null && exactProviderVersionString != void 0) {
|
|
709
|
+
validateFunctionParams(
|
|
710
|
+
[
|
|
711
|
+
{ input: exactProviderVersionString, paramName: "exactProviderVersionString", isString: true }
|
|
712
|
+
],
|
|
713
|
+
"fetchProviderConfigs"
|
|
714
|
+
);
|
|
715
|
+
}
|
|
760
716
|
try {
|
|
761
|
-
const response = yield http.client(constants.
|
|
717
|
+
const response = yield http.client(constants.DEFAULT_PROVIDER_CONFIGS_URL(providerId, exactProviderVersionString, allowedTags), {
|
|
762
718
|
method: "GET",
|
|
763
719
|
headers: { "Content-Type": "application/json" }
|
|
764
720
|
});
|
|
@@ -776,19 +732,116 @@ function fetchProviderConfig(providerId, exactProviderVersionString) {
|
|
|
776
732
|
}
|
|
777
733
|
});
|
|
778
734
|
}
|
|
779
|
-
function fetchProviderHashRequirementsBy(providerId, exactProviderVersion) {
|
|
780
|
-
return __async(this, null, function* () {
|
|
781
|
-
var _a, _b;
|
|
782
|
-
const providerResponse = yield fetchProviderConfig(providerId, exactProviderVersion);
|
|
783
|
-
const providerConfig = providerResponse.providers;
|
|
784
|
-
return getProviderHashRequirementsFromSpec({
|
|
785
|
-
requests: [...(_a = providerConfig == null ? void 0 : providerConfig.requestData) != null ? _a : [], ...(_b = providerConfig == null ? void 0 : providerConfig.allowedInjectedRequestData) != null ? _b : []]
|
|
786
|
-
});
|
|
787
|
-
});
|
|
788
|
-
}
|
|
789
735
|
|
|
790
736
|
// src/utils/proofUtils.ts
|
|
791
737
|
var import_ethers3 = require("ethers");
|
|
738
|
+
|
|
739
|
+
// src/witness.ts
|
|
740
|
+
var import_ethers2 = require("ethers");
|
|
741
|
+
function createSignDataForClaim(data) {
|
|
742
|
+
const identifier = getIdentifierFromClaimInfo(data);
|
|
743
|
+
const lines = [
|
|
744
|
+
identifier,
|
|
745
|
+
data.owner.toLowerCase(),
|
|
746
|
+
data.timestampS.toString(),
|
|
747
|
+
data.epoch.toString()
|
|
748
|
+
];
|
|
749
|
+
return lines.join("\n");
|
|
750
|
+
}
|
|
751
|
+
function getIdentifierFromClaimInfo(info) {
|
|
752
|
+
let canonicalContext = info.context || "";
|
|
753
|
+
if (canonicalContext.length > 0) {
|
|
754
|
+
try {
|
|
755
|
+
const ctx = JSON.parse(canonicalContext);
|
|
756
|
+
canonicalContext = canonicalStringify(ctx);
|
|
757
|
+
} catch (e) {
|
|
758
|
+
throw new Error("unable to parse non-empty context. Must be JSON");
|
|
759
|
+
}
|
|
760
|
+
}
|
|
761
|
+
const str = `${info.provider}
|
|
762
|
+
${info.parameters}
|
|
763
|
+
${canonicalContext}`;
|
|
764
|
+
return import_ethers2.ethers.keccak256(strToUint8Array(str)).toLowerCase();
|
|
765
|
+
}
|
|
766
|
+
function hashProofClaimParams(params) {
|
|
767
|
+
const serializedParams = getProviderParamsAsCanonicalizedString(params);
|
|
768
|
+
if (Array.isArray(serializedParams)) {
|
|
769
|
+
return serializedParams.map(
|
|
770
|
+
(serialized) => import_ethers2.ethers.keccak256(strToUint8Array(serialized)).toLowerCase()
|
|
771
|
+
);
|
|
772
|
+
}
|
|
773
|
+
return import_ethers2.ethers.keccak256(
|
|
774
|
+
strToUint8Array(serializedParams)
|
|
775
|
+
).toLowerCase();
|
|
776
|
+
}
|
|
777
|
+
function strToUint8Array(str) {
|
|
778
|
+
return new TextEncoder().encode(str);
|
|
779
|
+
}
|
|
780
|
+
function getProviderParamsAsCanonicalizedString(params) {
|
|
781
|
+
var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l, _m, _n, _o;
|
|
782
|
+
const pairsCount = (_b = (_a = params == null ? void 0 : params.responseMatches) == null ? void 0 : _a.length) != null ? _b : 0;
|
|
783
|
+
const validCanonicalizedStrings = [];
|
|
784
|
+
const totalCombinations = 1 << pairsCount;
|
|
785
|
+
for (let i = 0; i < totalCombinations; i++) {
|
|
786
|
+
let isValidCombination = true;
|
|
787
|
+
let includedCount = 0;
|
|
788
|
+
const currentMatches = [];
|
|
789
|
+
const currentRedactions = [];
|
|
790
|
+
for (let j = 0; j < pairsCount; j++) {
|
|
791
|
+
const isIncluded = (i & 1 << j) !== 0;
|
|
792
|
+
const match = (_c = params == null ? void 0 : params.responseMatches) == null ? void 0 : _c[j];
|
|
793
|
+
const redaction = (_d = params == null ? void 0 : params.responseRedactions) == null ? void 0 : _d[j];
|
|
794
|
+
if (isIncluded) {
|
|
795
|
+
if (match) {
|
|
796
|
+
currentMatches.push({
|
|
797
|
+
value: (_e = match.value) != null ? _e : "",
|
|
798
|
+
// This needs to be explicitly specified and absence should cause error, but we're choosing to ignore it in this case
|
|
799
|
+
type: (_f = match.type) != null ? _f : "contains",
|
|
800
|
+
invert: match.invert || void 0
|
|
801
|
+
});
|
|
802
|
+
}
|
|
803
|
+
if (redaction) {
|
|
804
|
+
currentRedactions.push({
|
|
805
|
+
xPath: (_g = redaction.xPath) != null ? _g : "",
|
|
806
|
+
jsonPath: (_h = redaction.jsonPath) != null ? _h : "",
|
|
807
|
+
regex: (_i = redaction.regex) != null ? _i : "",
|
|
808
|
+
hash: redaction.hash || void 0
|
|
809
|
+
});
|
|
810
|
+
}
|
|
811
|
+
includedCount++;
|
|
812
|
+
} else {
|
|
813
|
+
if (match && !match.isOptional) {
|
|
814
|
+
isValidCombination = false;
|
|
815
|
+
break;
|
|
816
|
+
}
|
|
817
|
+
}
|
|
818
|
+
}
|
|
819
|
+
if (isValidCombination && includedCount > 0) {
|
|
820
|
+
const filteredParams = {
|
|
821
|
+
url: (_j = params == null ? void 0 : params.url) != null ? _j : "",
|
|
822
|
+
// METHOD needs to be explicitly specified and absence or unknown method should cause error, but we're choosing to ignore it in this case
|
|
823
|
+
method: (_k = params == null ? void 0 : params.method) != null ? _k : "GET",
|
|
824
|
+
body: (_l = params == null ? void 0 : params.body) != null ? _l : "",
|
|
825
|
+
responseMatches: currentMatches,
|
|
826
|
+
responseRedactions: currentRedactions
|
|
827
|
+
};
|
|
828
|
+
validCanonicalizedStrings.push(canonicalStringify(filteredParams));
|
|
829
|
+
}
|
|
830
|
+
}
|
|
831
|
+
if (validCanonicalizedStrings.length === 0) {
|
|
832
|
+
const filteredParams = {
|
|
833
|
+
url: (_m = params == null ? void 0 : params.url) != null ? _m : "",
|
|
834
|
+
method: (_n = params == null ? void 0 : params.method) != null ? _n : "GET",
|
|
835
|
+
body: (_o = params == null ? void 0 : params.body) != null ? _o : "",
|
|
836
|
+
responseMatches: [],
|
|
837
|
+
responseRedactions: []
|
|
838
|
+
};
|
|
839
|
+
return canonicalStringify(filteredParams);
|
|
840
|
+
}
|
|
841
|
+
return validCanonicalizedStrings.length === 1 ? validCanonicalizedStrings[0] : validCanonicalizedStrings;
|
|
842
|
+
}
|
|
843
|
+
|
|
844
|
+
// src/utils/proofUtils.ts
|
|
792
845
|
var logger5 = logger_default.logger;
|
|
793
846
|
function getShortenedUrl(url) {
|
|
794
847
|
return __async(this, null, function* () {
|
|
@@ -865,6 +918,7 @@ function assertVerifiedProof(proof, attestors) {
|
|
|
865
918
|
}
|
|
866
919
|
|
|
867
920
|
// src/utils/modalUtils.ts
|
|
921
|
+
var import_qrcode = __toESM(require("qrcode"));
|
|
868
922
|
var logger6 = logger_default.logger;
|
|
869
923
|
var QRCodeModal = class {
|
|
870
924
|
constructor(options = {}) {
|
|
@@ -1075,17 +1129,22 @@ var QRCodeModal = class {
|
|
|
1075
1129
|
generateQRCode(text, containerId) {
|
|
1076
1130
|
return __async(this, null, function* () {
|
|
1077
1131
|
try {
|
|
1078
|
-
const
|
|
1132
|
+
const dataUrl = yield import_qrcode.default.toDataURL(text, {
|
|
1133
|
+
width: 200,
|
|
1134
|
+
margin: 1,
|
|
1135
|
+
color: {
|
|
1136
|
+
dark: "#000000",
|
|
1137
|
+
light: "#ffffff"
|
|
1138
|
+
}
|
|
1139
|
+
});
|
|
1079
1140
|
const container = document.getElementById(containerId);
|
|
1080
1141
|
const styles = this.getThemeStyles();
|
|
1081
1142
|
if (container) {
|
|
1082
1143
|
container.innerHTML = `
|
|
1083
|
-
<img src="${
|
|
1084
|
-
alt="QR Code for Reclaim verification"
|
|
1085
|
-
style="width: 200px; height: 200px; border-radius: 4px;"
|
|
1086
|
-
onerror="this.style.display='none'; this.nextElementSibling.style.display='block';">
|
|
1144
|
+
<img src="${dataUrl}"
|
|
1145
|
+
alt="QR Code for Reclaim verification"
|
|
1146
|
+
style="width: 200px; height: 200px; border-radius: 4px;">
|
|
1087
1147
|
<div style="display: none; padding: 20px; color: ${styles.textColor}; font-size: 14px;">
|
|
1088
|
-
QR code could not be loaded.<br>
|
|
1089
1148
|
<a href="${text}" target="_blank" style="color: ${styles.linkColor}; text-decoration: underline;">
|
|
1090
1149
|
Click here to open verification link
|
|
1091
1150
|
</a>
|
|
@@ -1313,10 +1372,123 @@ function clearDeviceCache() {
|
|
|
1313
1372
|
cachedMobileType = null;
|
|
1314
1373
|
}
|
|
1315
1374
|
|
|
1316
|
-
// src/utils/
|
|
1375
|
+
// src/utils/providerUtils.ts
|
|
1317
1376
|
var logger7 = logger_default.logger;
|
|
1377
|
+
function fetchProviderHashRequirementsBy(providerId, exactProviderVersionString, allowedTags, proofs) {
|
|
1378
|
+
return __async(this, null, function* () {
|
|
1379
|
+
var _a, _b;
|
|
1380
|
+
const providerResponse = yield fetchProviderConfigs(providerId, exactProviderVersionString, allowedTags);
|
|
1381
|
+
try {
|
|
1382
|
+
const providerConfigs = providerResponse.providers;
|
|
1383
|
+
if (!providerConfigs || !providerConfigs.length) {
|
|
1384
|
+
throw new ProviderConfigFetchError(`No provider configs found for providerId: ${providerId}, exactProviderVersionString: ${exactProviderVersionString}`);
|
|
1385
|
+
}
|
|
1386
|
+
const hashRequirements = [];
|
|
1387
|
+
for (const providerConfig of providerConfigs) {
|
|
1388
|
+
hashRequirements.push(getProviderHashRequirementsFromSpec({
|
|
1389
|
+
requests: [...(_a = providerConfig == null ? void 0 : providerConfig.requestData) != null ? _a : [], ...generateSpecsFromRequestSpecTemplate((_b = providerConfig == null ? void 0 : providerConfig.allowedInjectedRequestData) != null ? _b : [], takeTemplateParametersFromProofs(proofs))]
|
|
1390
|
+
}));
|
|
1391
|
+
}
|
|
1392
|
+
return hashRequirements;
|
|
1393
|
+
} catch (e) {
|
|
1394
|
+
const errorMessage = `Failed to fetch provider hash requirements for providerId: ${providerId}, exactProviderVersionString: ${exactProviderVersionString}`;
|
|
1395
|
+
logger7.info(errorMessage, e);
|
|
1396
|
+
throw new ProviderConfigFetchError(`Error fetching provider hash requirements for providerId: ${providerId}, exactProviderVersionString: ${exactProviderVersionString}`);
|
|
1397
|
+
}
|
|
1398
|
+
});
|
|
1399
|
+
}
|
|
1400
|
+
function generateSpecsFromRequestSpecTemplate(requestSpecTemplates, templateParameters) {
|
|
1401
|
+
var _a;
|
|
1402
|
+
if (!requestSpecTemplates) return [];
|
|
1403
|
+
const generatedRequestTemplate = [];
|
|
1404
|
+
for (const template of requestSpecTemplates) {
|
|
1405
|
+
const templateVariables = (_a = template.templateParams) != null ? _a : [];
|
|
1406
|
+
if (!templateVariables.length) {
|
|
1407
|
+
generatedRequestTemplate.push(template);
|
|
1408
|
+
continue;
|
|
1409
|
+
}
|
|
1410
|
+
const templateParamsPairMatch = Object.entries(templateParameters).filter(([key, value]) => templateVariables.includes(key) && value.length);
|
|
1411
|
+
const hasAllTemplateVariableMatch = templateParamsPairMatch.length === templateVariables.length;
|
|
1412
|
+
if (!hasAllTemplateVariableMatch) {
|
|
1413
|
+
throw new InvalidRequestSpecError(`Not all template variables are present for template`);
|
|
1414
|
+
}
|
|
1415
|
+
const templateParamsPairMatchLength = templateParamsPairMatch[0][1].length;
|
|
1416
|
+
const allTemplateVariablesHaveSameLength = templateParamsPairMatch.every(([key, value]) => value.length === templateParamsPairMatchLength);
|
|
1417
|
+
if (!allTemplateVariablesHaveSameLength) {
|
|
1418
|
+
throw new InvalidRequestSpecError(`Not all template variables have same length for template`);
|
|
1419
|
+
}
|
|
1420
|
+
const getRequestSpecVariableTemplate = (key) => {
|
|
1421
|
+
return `\${${key}}`;
|
|
1422
|
+
};
|
|
1423
|
+
for (let i = 0; i < templateParamsPairMatchLength; i++) {
|
|
1424
|
+
const currentTemplateParams = {};
|
|
1425
|
+
for (const [key, values] of templateParamsPairMatch) {
|
|
1426
|
+
currentTemplateParams[key] = values[i];
|
|
1427
|
+
}
|
|
1428
|
+
const spec = __spreadProps(__spreadValues({}, template), {
|
|
1429
|
+
responseMatches: template.responseMatches ? template.responseMatches.map((m) => __spreadValues({}, m)) : [],
|
|
1430
|
+
responseRedactions: template.responseRedactions ? template.responseRedactions.map((r) => __spreadValues({}, r)) : []
|
|
1431
|
+
});
|
|
1432
|
+
for (const match of spec.responseMatches) {
|
|
1433
|
+
for (const [key, value] of Object.entries(currentTemplateParams)) {
|
|
1434
|
+
match.value = match.value.split(getRequestSpecVariableTemplate(key)).join(value);
|
|
1435
|
+
}
|
|
1436
|
+
}
|
|
1437
|
+
for (const redaction of spec.responseRedactions) {
|
|
1438
|
+
for (const [key, value] of Object.entries(currentTemplateParams)) {
|
|
1439
|
+
redaction.jsonPath = redaction.jsonPath.split(getRequestSpecVariableTemplate(key)).join(value);
|
|
1440
|
+
redaction.xPath = redaction.xPath.split(getRequestSpecVariableTemplate(key)).join(value);
|
|
1441
|
+
redaction.regex = redaction.regex.split(getRequestSpecVariableTemplate(key)).join(value);
|
|
1442
|
+
}
|
|
1443
|
+
}
|
|
1444
|
+
generatedRequestTemplate.push(spec);
|
|
1445
|
+
}
|
|
1446
|
+
}
|
|
1447
|
+
return generatedRequestTemplate;
|
|
1448
|
+
}
|
|
1449
|
+
function takeTemplateParametersFromProofs(proofs) {
|
|
1450
|
+
return takePairsWhereValueIsArray(proofs == null ? void 0 : proofs.map((it) => JSON.parse(it.claimData.context).extractedParameters).reduce((acc, it) => __spreadValues(__spreadValues({}, acc), it), {}));
|
|
1451
|
+
}
|
|
1452
|
+
function takePairsWhereValueIsArray(o) {
|
|
1453
|
+
if (!o) return {};
|
|
1454
|
+
const pairs = {};
|
|
1455
|
+
for (const [key, value] of Object.entries(o)) {
|
|
1456
|
+
if (Array.isArray(value) && value.length) {
|
|
1457
|
+
pairs[key] = value;
|
|
1458
|
+
} else {
|
|
1459
|
+
try {
|
|
1460
|
+
const parsedValue = JSON.parse(value);
|
|
1461
|
+
if (Array.isArray(parsedValue) && parsedValue.length) {
|
|
1462
|
+
pairs[key] = parsedValue;
|
|
1463
|
+
}
|
|
1464
|
+
} catch (_) {
|
|
1465
|
+
}
|
|
1466
|
+
}
|
|
1467
|
+
}
|
|
1468
|
+
return pairs;
|
|
1469
|
+
}
|
|
1470
|
+
function getProviderHashRequirementsFromSpec(spec) {
|
|
1471
|
+
var _a;
|
|
1472
|
+
return {
|
|
1473
|
+
hashes: ((_a = spec == null ? void 0 : spec.requests) == null ? void 0 : _a.map(hashRequestSpec)) || []
|
|
1474
|
+
};
|
|
1475
|
+
}
|
|
1476
|
+
function hashRequestSpec(request) {
|
|
1477
|
+
const hash = hashProofClaimParams(__spreadProps(__spreadValues({}, request), {
|
|
1478
|
+
// Body is strictly empty unless body sniff is explicitly enabled
|
|
1479
|
+
body: request.bodySniff.enabled ? request.bodySniff.template : ""
|
|
1480
|
+
}));
|
|
1481
|
+
return {
|
|
1482
|
+
value: hash,
|
|
1483
|
+
required: request.required,
|
|
1484
|
+
multiple: request.multiple
|
|
1485
|
+
};
|
|
1486
|
+
}
|
|
1487
|
+
|
|
1488
|
+
// src/utils/proofValidationUtils.ts
|
|
1489
|
+
var logger8 = logger_default.logger;
|
|
1318
1490
|
var HASH_REQUIRED_DEFAULT = true;
|
|
1319
|
-
var HASH_MATCH_MULTIPLE_DEFAULT =
|
|
1491
|
+
var HASH_MATCH_MULTIPLE_DEFAULT = true;
|
|
1320
1492
|
function assertValidProofsByHash(proofs, config) {
|
|
1321
1493
|
var _a, _b;
|
|
1322
1494
|
if (!config.hashes) {
|
|
@@ -1326,31 +1498,36 @@ function assertValidProofsByHash(proofs, config) {
|
|
|
1326
1498
|
for (let i = 0; i < proofs.length; i++) {
|
|
1327
1499
|
const proof = proofs[i];
|
|
1328
1500
|
const claimParams = getHttpProviderClaimParamsFromProof(proof);
|
|
1329
|
-
const
|
|
1330
|
-
|
|
1501
|
+
const computedHashesOfProof = hashProofClaimParams(claimParams);
|
|
1502
|
+
const proofHashes = Array.isArray(computedHashesOfProof) ? computedHashesOfProof.map((h) => h.toLowerCase().trim()) : [computedHashesOfProof.toLowerCase().trim()];
|
|
1503
|
+
unvalidatedProofHashByIndex.set(i, proofHashes);
|
|
1331
1504
|
}
|
|
1332
1505
|
for (const hashRequirement of config.hashes) {
|
|
1333
1506
|
let found = false;
|
|
1334
|
-
const
|
|
1507
|
+
const expectedHashes = Array.isArray(hashRequirement.value) ? hashRequirement.value.map((h) => h.toLowerCase().trim()) : [hashRequirement.value.toLowerCase().trim()];
|
|
1335
1508
|
const isRequired = (_a = hashRequirement.required) != null ? _a : HASH_REQUIRED_DEFAULT;
|
|
1336
1509
|
const canMatchMultiple = (_b = hashRequirement.multiple) != null ? _b : HASH_MATCH_MULTIPLE_DEFAULT;
|
|
1337
|
-
for (const [i,
|
|
1338
|
-
|
|
1510
|
+
for (const [i, proofHashes] of unvalidatedProofHashByIndex.entries()) {
|
|
1511
|
+
const intersection = expectedHashes.filter((eh) => proofHashes.includes(eh));
|
|
1512
|
+
if (intersection.length > 0) {
|
|
1339
1513
|
unvalidatedProofHashByIndex.delete(i);
|
|
1340
1514
|
if (!found) {
|
|
1341
1515
|
found = true;
|
|
1342
1516
|
} else if (!canMatchMultiple) {
|
|
1343
|
-
|
|
1517
|
+
const expectedHashStr = expectedHashes.length === 1 ? expectedHashes[0] : `[${expectedHashes.join(", ")}]`;
|
|
1518
|
+
throw new ProofNotValidatedError(`Proof by hash '${expectedHashStr}' is not allowed to appear more than once`);
|
|
1344
1519
|
}
|
|
1345
1520
|
}
|
|
1346
1521
|
}
|
|
1347
1522
|
if (!found && isRequired) {
|
|
1348
|
-
|
|
1523
|
+
const expectedHashStr = expectedHashes.length === 1 ? expectedHashes[0] : `[${expectedHashes.join(", ")}]`;
|
|
1524
|
+
throw new ProofNotValidatedError(`Proof by required hash '${expectedHashStr}' was not found`);
|
|
1349
1525
|
}
|
|
1350
1526
|
}
|
|
1351
1527
|
if (unvalidatedProofHashByIndex.size > 0) {
|
|
1352
1528
|
const contactSupport = "Please contact Reclaim Protocol Support team or mail us at support@reclaimprotocol.org.";
|
|
1353
|
-
|
|
1529
|
+
const unvalidatedHashesStrArr = [...unvalidatedProofHashByIndex.values()].map((h) => h.length === 1 ? h[0] : `[${h.join(", ")}]`);
|
|
1530
|
+
throw new UnknownProofsNotValidatedError(`Extra ${unvalidatedProofHashByIndex.size} proof(s) by hashes ${unvalidatedHashesStrArr.join(", ")} was found but could not be validated and indicates a security risk. ${contactSupport}`);
|
|
1354
1531
|
}
|
|
1355
1532
|
}
|
|
1356
1533
|
var allowedHttpMethods = /* @__PURE__ */ new Set(["GET", "POST", "PUT", "PATCH", "DELETE"]);
|
|
@@ -1359,7 +1536,7 @@ function isHttpProviderClaimParams(claimParams) {
|
|
|
1359
1536
|
return false;
|
|
1360
1537
|
}
|
|
1361
1538
|
const params = claimParams;
|
|
1362
|
-
return typeof params.url === "string" && typeof params.method === "string" && allowedHttpMethods.has(params.method) && typeof params.body === "string" && Array.isArray(params.responseMatches) && params.responseMatches.length > 0 && Array.isArray(params.responseRedactions);
|
|
1539
|
+
return typeof params.url === "string" && typeof params.method === "string" && allowedHttpMethods.has(params.method) && (params.body == null || typeof params.body === "string") && Array.isArray(params.responseMatches) && params.responseMatches.length > 0 && Array.isArray(params.responseRedactions);
|
|
1363
1540
|
}
|
|
1364
1541
|
function getHttpProviderClaimParamsFromProof(proof) {
|
|
1365
1542
|
try {
|
|
@@ -1372,31 +1549,781 @@ function getHttpProviderClaimParamsFromProof(proof) {
|
|
|
1372
1549
|
throw new ProofNotValidatedError("Proof has no HTTP provider params to hash");
|
|
1373
1550
|
}
|
|
1374
1551
|
function assertValidateProof(proofs, config) {
|
|
1375
|
-
|
|
1376
|
-
|
|
1377
|
-
|
|
1552
|
+
return __async(this, null, function* () {
|
|
1553
|
+
if ("dangerouslyDisableContentValidation" in config && config.dangerouslyDisableContentValidation) {
|
|
1554
|
+
logger8.warn("Validation skipped because it was disabled during proof verification");
|
|
1555
|
+
return;
|
|
1556
|
+
}
|
|
1557
|
+
if ("providerId" in config) {
|
|
1558
|
+
if (!config.providerId || typeof config.providerId !== "string") {
|
|
1559
|
+
throw new ProofNotValidatedError("Provider id is required for proof validation");
|
|
1560
|
+
}
|
|
1561
|
+
if (config.providerVersion && typeof config.providerVersion !== "string") {
|
|
1562
|
+
throw new ProofNotValidatedError("Provider version must be a string");
|
|
1563
|
+
}
|
|
1564
|
+
const hashRequirementsFromProvider = yield fetchProviderHashRequirementsBy(config.providerId, config.providerVersion, config.allowedTags, proofs);
|
|
1565
|
+
if (!hashRequirementsFromProvider.length) {
|
|
1566
|
+
throw new ProofNotValidatedError("Could not find any provider information for the given provider id and version");
|
|
1567
|
+
}
|
|
1568
|
+
if (hashRequirementsFromProvider.length != 1) {
|
|
1569
|
+
let lastError = null;
|
|
1570
|
+
for (const hashRequirement of hashRequirementsFromProvider) {
|
|
1571
|
+
try {
|
|
1572
|
+
return yield assertValidateProof(proofs, hashRequirement);
|
|
1573
|
+
} catch (e) {
|
|
1574
|
+
lastError = e;
|
|
1575
|
+
}
|
|
1576
|
+
}
|
|
1577
|
+
throw new ProofNotValidatedError("Could not validate proof", lastError);
|
|
1578
|
+
} else {
|
|
1579
|
+
return assertValidateProof(proofs, hashRequirementsFromProvider[0]);
|
|
1580
|
+
}
|
|
1581
|
+
}
|
|
1582
|
+
const effectiveHashRequirement = ("hashes" in config && Array.isArray(config == null ? void 0 : config.hashes) ? config.hashes : []).map((it) => {
|
|
1583
|
+
if (typeof it == "string") {
|
|
1584
|
+
return {
|
|
1585
|
+
value: it
|
|
1586
|
+
};
|
|
1587
|
+
} else {
|
|
1588
|
+
return it;
|
|
1589
|
+
}
|
|
1590
|
+
});
|
|
1591
|
+
return assertValidProofsByHash(proofs, {
|
|
1592
|
+
hashes: effectiveHashRequirement
|
|
1593
|
+
});
|
|
1594
|
+
});
|
|
1595
|
+
}
|
|
1596
|
+
|
|
1597
|
+
// src/utils/verifyTee.ts
|
|
1598
|
+
var import_node_forge = __toESM(require("node-forge"));
|
|
1599
|
+
var import_ethers4 = require("ethers");
|
|
1600
|
+
|
|
1601
|
+
// src/utils/amdCerts.ts
|
|
1602
|
+
var AMD_CERTS = {
|
|
1603
|
+
"Milan": `-----BEGIN CERTIFICATE-----
|
|
1604
|
+
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
|
|
1639
|
+
0YPk
|
|
1640
|
+
-----END CERTIFICATE-----
|
|
1641
|
+
-----BEGIN CERTIFICATE-----
|
|
1642
|
+
MIIGYzCCBBKgAwIBAgIDAQAAMEYGCSqGSIb3DQEBCjA5oA8wDQYJYIZIAWUDBAIC
|
|
1643
|
+
BQChHDAaBgkqhkiG9w0BAQgwDQYJYIZIAWUDBAICBQCiAwIBMKMDAgEBMHsxFDAS
|
|
1644
|
+
BgNVBAsMC0VuZ2luZWVyaW5nMQswCQYDVQQGEwJVUzEUMBIGA1UEBwwLU2FudGEg
|
|
1645
|
+
Q2xhcmExCzAJBgNVBAgMAkNBMR8wHQYDVQQKDBZBZHZhbmNlZCBNaWNybyBEZXZp
|
|
1646
|
+
Y2VzMRIwEAYDVQQDDAlBUkstTWlsYW4wHhcNMjAxMDIyMTcyMzA1WhcNNDUxMDIy
|
|
1647
|
+
MTcyMzA1WjB7MRQwEgYDVQQLDAtFbmdpbmVlcmluZzELMAkGA1UEBhMCVVMxFDAS
|
|
1648
|
+
BgNVBAcMC1NhbnRhIENsYXJhMQswCQYDVQQIDAJDQTEfMB0GA1UECgwWQWR2YW5j
|
|
1649
|
+
ZWQgTWljcm8gRGV2aWNlczESMBAGA1UEAwwJQVJLLU1pbGFuMIICIjANBgkqhkiG
|
|
1650
|
+
9w0BAQEFAAOCAg8AMIICCgKCAgEA0Ld52RJOdeiJlqK2JdsVmD7FktuotWwX1fNg
|
|
1651
|
+
W41XY9Xz1HEhSUmhLz9Cu9DHRlvgJSNxbeYYsnJfvyjx1MfU0V5tkKiU1EesNFta
|
|
1652
|
+
1kTA0szNisdYc9isqk7mXT5+KfGRbfc4V/9zRIcE8jlHN61S1ju8X93+6dxDUrG2
|
|
1653
|
+
SzxqJ4BhqyYmUDruPXJSX4vUc01P7j98MpqOS95rORdGHeI52Naz5m2B+O+vjsC0
|
|
1654
|
+
60d37jY9LFeuOP4Meri8qgfi2S5kKqg/aF6aPtuAZQVR7u3KFYXP59XmJgtcog05
|
|
1655
|
+
gmI0T/OitLhuzVvpZcLph0odh/1IPXqx3+MnjD97A7fXpqGd/y8KxX7jksTEzAOg
|
|
1656
|
+
bKAeam3lm+3yKIcTYMlsRMXPcjNbIvmsBykD//xSniusuHBkgnlENEWx1UcbQQrs
|
|
1657
|
+
+gVDkuVPhsnzIRNgYvM48Y+7LGiJYnrmE8xcrexekBxrva2V9TJQqnN3Q53kt5vi
|
|
1658
|
+
Qi3+gCfmkwC0F0tirIZbLkXPrPwzZ0M9eNxhIySb2npJfgnqz55I0u33wh4r0ZNQ
|
|
1659
|
+
eTGfw03MBUtyuzGesGkcw+loqMaq1qR4tjGbPYxCvpCq7+OgpCCoMNit2uLo9M18
|
|
1660
|
+
fHz10lOMT8nWAUvRZFzteXCm+7PHdYPlmQwUw3LvenJ/ILXoQPHfbkH0CyPfhl1j
|
|
1661
|
+
WhJFZasCAwEAAaN+MHwwDgYDVR0PAQH/BAQDAgEGMB0GA1UdDgQWBBSFrBrRQ/fI
|
|
1662
|
+
rFXUxR1BSKvVeErUUzAPBgNVHRMBAf8EBTADAQH/MDoGA1UdHwQzMDEwL6AtoCuG
|
|
1663
|
+
KWh0dHBzOi8va2RzaW50Zi5hbWQuY29tL3ZjZWsvdjEvTWlsYW4vY3JsMEYGCSqG
|
|
1664
|
+
SIb3DQEBCjA5oA8wDQYJYIZIAWUDBAICBQChHDAaBgkqhkiG9w0BAQgwDQYJYIZI
|
|
1665
|
+
AWUDBAICBQCiAwIBMKMDAgEBA4ICAQC6m0kDp6zv4Ojfgy+zleehsx6ol0ocgVel
|
|
1666
|
+
ETobpx+EuCsqVFRPK1jZ1sp/lyd9+0fQ0r66n7kagRk4Ca39g66WGTJMeJdqYriw
|
|
1667
|
+
STjjDCKVPSesWXYPVAyDhmP5n2v+BYipZWhpvqpaiO+EGK5IBP+578QeW/sSokrK
|
|
1668
|
+
dHaLAxG2LhZxj9aF73fqC7OAJZ5aPonw4RE299FVarh1Tx2eT3wSgkDgutCTB1Yq
|
|
1669
|
+
zT5DuwvAe+co2CIVIzMDamYuSFjPN0BCgojl7V+bTou7dMsqIu/TW/rPCX9/EUcp
|
|
1670
|
+
KGKqPQ3P+N9r1hjEFY1plBg93t53OOo49GNI+V1zvXPLI6xIFVsh+mto2RtgEX/e
|
|
1671
|
+
pmMKTNN6psW88qg7c1hTWtN6MbRuQ0vm+O+/2tKBF2h8THb94OvvHHoFDpbCELlq
|
|
1672
|
+
HnIYhxy0YKXGyaW1NjfULxrrmxVW4wcn5E8GddmvNa6yYm8scJagEi13mhGu4Jqh
|
|
1673
|
+
3QU3sf8iUSUr09xQDwHtOQUVIqx4maBZPBtSMf+qUDtjXSSq8lfWcd8bLr9mdsUn
|
|
1674
|
+
JZJ0+tuPMKmBnSH860llKk+VpVQsgqbzDIvOLvD6W1Umq25boxCYJ+TuBoa4s+HH
|
|
1675
|
+
CViAvgT9kf/rBq1d+ivj6skkHxuzcxbk1xv6ZGxrteJxVH7KlX7YRdZ6eARKwLe4
|
|
1676
|
+
AFZEAwoKCQ==
|
|
1677
|
+
-----END CERTIFICATE-----`,
|
|
1678
|
+
"Genoa": `-----BEGIN CERTIFICATE-----
|
|
1679
|
+
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
|
|
1714
|
+
2cko
|
|
1715
|
+
-----END CERTIFICATE-----
|
|
1716
|
+
-----BEGIN CERTIFICATE-----
|
|
1717
|
+
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
|
|
1751
|
+
/wMz1R1BHg==
|
|
1752
|
+
-----END CERTIFICATE-----`
|
|
1753
|
+
};
|
|
1754
|
+
|
|
1755
|
+
// src/utils/verifyTee.ts
|
|
1756
|
+
var crlCache = {};
|
|
1757
|
+
var logger9 = logger_default.logger;
|
|
1758
|
+
function toUint8Array(input) {
|
|
1759
|
+
if (typeof Buffer !== "undefined" && typeof Buffer.isBuffer === "function" && Buffer.isBuffer(input)) {
|
|
1760
|
+
return new Uint8Array(input);
|
|
1378
1761
|
}
|
|
1379
|
-
|
|
1380
|
-
|
|
1381
|
-
|
|
1382
|
-
|
|
1383
|
-
|
|
1762
|
+
if (input instanceof Uint8Array) {
|
|
1763
|
+
return new Uint8Array(input);
|
|
1764
|
+
}
|
|
1765
|
+
if (typeof ArrayBuffer !== "undefined" && input instanceof ArrayBuffer) {
|
|
1766
|
+
return new Uint8Array(input);
|
|
1767
|
+
}
|
|
1768
|
+
throw new Error("Unsupported binary data type");
|
|
1769
|
+
}
|
|
1770
|
+
function uint8ArrayToBinaryString(bytes) {
|
|
1771
|
+
let result = "";
|
|
1772
|
+
const chunkSize = 32768;
|
|
1773
|
+
for (let i = 0; i < bytes.length; i += chunkSize) {
|
|
1774
|
+
const chunk = bytes.subarray(i, i + chunkSize);
|
|
1775
|
+
result += String.fromCharCode(...chunk);
|
|
1776
|
+
}
|
|
1777
|
+
return result;
|
|
1778
|
+
}
|
|
1779
|
+
function binaryStringToUint8Array(binary) {
|
|
1780
|
+
const result = new Uint8Array(binary.length);
|
|
1781
|
+
for (let i = 0; i < binary.length; i++) {
|
|
1782
|
+
result[i] = binary.charCodeAt(i);
|
|
1783
|
+
}
|
|
1784
|
+
return result;
|
|
1785
|
+
}
|
|
1786
|
+
function base64ToUint8Array(base64) {
|
|
1787
|
+
if (typeof atob === "function") {
|
|
1788
|
+
const binary = atob(base64);
|
|
1789
|
+
return binaryStringToUint8Array(binary);
|
|
1790
|
+
}
|
|
1791
|
+
if (typeof Buffer !== "undefined") {
|
|
1792
|
+
return new Uint8Array(Buffer.from(base64, "base64"));
|
|
1793
|
+
}
|
|
1794
|
+
throw new Error("Base64 decoding is not supported in this environment");
|
|
1795
|
+
}
|
|
1796
|
+
function arrayBufferToHex(buffer) {
|
|
1797
|
+
const view = buffer instanceof Uint8Array ? buffer : new Uint8Array(buffer);
|
|
1798
|
+
let hex = "";
|
|
1799
|
+
for (let i = 0; i < view.length; i++) {
|
|
1800
|
+
hex += view[i].toString(16).padStart(2, "0");
|
|
1801
|
+
}
|
|
1802
|
+
return hex;
|
|
1803
|
+
}
|
|
1804
|
+
function concatUint8Arrays(parts) {
|
|
1805
|
+
const totalLength = parts.reduce((sum, arr) => sum + arr.length, 0);
|
|
1806
|
+
const result = new Uint8Array(totalLength);
|
|
1807
|
+
let offset = 0;
|
|
1808
|
+
for (const arr of parts) {
|
|
1809
|
+
result.set(arr, offset);
|
|
1810
|
+
offset += arr.length;
|
|
1811
|
+
}
|
|
1812
|
+
return result;
|
|
1813
|
+
}
|
|
1814
|
+
function reverseBytes(bytes) {
|
|
1815
|
+
const copy = Uint8Array.from(bytes);
|
|
1816
|
+
copy.reverse();
|
|
1817
|
+
return copy;
|
|
1818
|
+
}
|
|
1819
|
+
function normalizeSerial(s) {
|
|
1820
|
+
let cleaned = s.toLowerCase().replace(/[^a-f0-9]/g, "");
|
|
1821
|
+
while (cleaned.startsWith("0") && cleaned.length > 1) cleaned = cleaned.substring(1);
|
|
1822
|
+
return cleaned;
|
|
1823
|
+
}
|
|
1824
|
+
var isNode = typeof process !== "undefined" && process.versions && process.versions.node;
|
|
1825
|
+
var getSubtleCrypto = () => {
|
|
1826
|
+
var _a;
|
|
1827
|
+
if (typeof window !== "undefined" && ((_a = window.crypto) == null ? void 0 : _a.subtle)) return window.crypto.subtle;
|
|
1828
|
+
if (isNode) return require("crypto").webcrypto.subtle;
|
|
1829
|
+
throw new Error("No WebCrypto subtle implementation found in this environment");
|
|
1830
|
+
};
|
|
1831
|
+
function parseCert(buffer) {
|
|
1832
|
+
const bytes = toUint8Array(buffer);
|
|
1833
|
+
const asn1 = import_node_forge.default.asn1.fromDer(uint8ArrayToBinaryString(bytes));
|
|
1834
|
+
const certSeq = asn1.value;
|
|
1835
|
+
const tbsAsn1 = certSeq[0];
|
|
1836
|
+
const sigAlgAsn1 = certSeq[1];
|
|
1837
|
+
const sigValueAsn1 = certSeq[2];
|
|
1838
|
+
const tbsFields = tbsAsn1.value;
|
|
1839
|
+
let idx = 0;
|
|
1840
|
+
if (tbsFields[idx].tagClass === 128) idx++;
|
|
1841
|
+
const serialAsn1 = tbsFields[idx++];
|
|
1842
|
+
const serialNumber = import_node_forge.default.util.bytesToHex(serialAsn1.value);
|
|
1843
|
+
idx++;
|
|
1844
|
+
idx++;
|
|
1845
|
+
const validityAsn1 = tbsFields[idx++];
|
|
1846
|
+
idx++;
|
|
1847
|
+
const spkiAsn1 = tbsFields[idx];
|
|
1848
|
+
if (!validityAsn1 || !Array.isArray(validityAsn1.value) || validityAsn1.value.length < 2) {
|
|
1849
|
+
throw new Error("Certificate validity window is malformed");
|
|
1850
|
+
}
|
|
1851
|
+
const notBeforeNode = validityAsn1.value[0];
|
|
1852
|
+
const notAfterNode = validityAsn1.value[1];
|
|
1853
|
+
const notBefore = notBeforeNode ? parseAsn1Time(notBeforeNode) : void 0;
|
|
1854
|
+
const notAfter = notAfterNode ? parseAsn1Time(notAfterNode) : void 0;
|
|
1855
|
+
const sigRaw = typeof sigValueAsn1.value === "string" ? sigValueAsn1.value : "";
|
|
1856
|
+
const signature = binaryStringToUint8Array(sigRaw.substring(1));
|
|
1857
|
+
const sigAlgOid = import_node_forge.default.asn1.derToOid(sigAlgAsn1.value[0].value);
|
|
1858
|
+
return {
|
|
1859
|
+
serialNumber: normalizeSerial(serialNumber),
|
|
1860
|
+
tbsDer: binaryStringToUint8Array(import_node_forge.default.asn1.toDer(tbsAsn1).getBytes()),
|
|
1861
|
+
signature,
|
|
1862
|
+
sigAlgOid,
|
|
1863
|
+
spkiDer: binaryStringToUint8Array(import_node_forge.default.asn1.toDer(spkiAsn1).getBytes()),
|
|
1864
|
+
notBefore,
|
|
1865
|
+
notAfter
|
|
1866
|
+
};
|
|
1867
|
+
}
|
|
1868
|
+
function verifySignature(publicKeyPem, data, signature, sigAlgOid) {
|
|
1869
|
+
return __async(this, null, function* () {
|
|
1870
|
+
const cryptoSubtle = getSubtleCrypto();
|
|
1871
|
+
const forgeCert = import_node_forge.default.pki.certificateFromPem(publicKeyPem);
|
|
1872
|
+
const spkiBuf = binaryStringToUint8Array(import_node_forge.default.asn1.toDer(import_node_forge.default.pki.publicKeyToAsn1(forgeCert.publicKey)).getBytes());
|
|
1873
|
+
let importParams;
|
|
1874
|
+
let verifyParams;
|
|
1875
|
+
if (sigAlgOid === "1.2.840.113549.1.1.10") {
|
|
1876
|
+
importParams = { name: "RSA-PSS", hash: "SHA-384" };
|
|
1877
|
+
verifyParams = { name: "RSA-PSS", saltLength: 48 };
|
|
1878
|
+
} else if (sigAlgOid === "1.2.840.113549.1.1.11" || sigAlgOid === "1.2.840.113549.1.1.12" || sigAlgOid === "1.2.840.113549.1.1.5") {
|
|
1879
|
+
importParams = { name: "RSASSA-PKCS1-v1_5", hash: sigAlgOid === "1.2.840.113549.1.1.12" ? "SHA-384" : "SHA-256" };
|
|
1880
|
+
verifyParams = { name: "RSASSA-PKCS1-v1_5" };
|
|
1881
|
+
} else if (sigAlgOid === "1.2.840.10045.4.3.3") {
|
|
1882
|
+
importParams = { name: "ECDSA", namedCurve: "P-384" };
|
|
1883
|
+
verifyParams = { name: "ECDSA", hash: "SHA-384" };
|
|
1384
1884
|
} else {
|
|
1385
|
-
|
|
1885
|
+
importParams = { name: "RSASSA-PKCS1-v1_5", hash: "SHA-256" };
|
|
1886
|
+
verifyParams = { name: "RSASSA-PKCS1-v1_5" };
|
|
1887
|
+
}
|
|
1888
|
+
const key = yield cryptoSubtle.importKey("spki", spkiBuf, importParams, false, ["verify"]);
|
|
1889
|
+
const isValid = yield cryptoSubtle.verify(verifyParams, key, signature, data);
|
|
1890
|
+
if (!isValid) throw new Error(`Signature verification failed (OID: ${sigAlgOid}, ImportParams: ${JSON.stringify(importParams)})`);
|
|
1891
|
+
});
|
|
1892
|
+
}
|
|
1893
|
+
var COSIGN_PUBLIC_KEY = `-----BEGIN PUBLIC KEY-----
|
|
1894
|
+
MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEjiL30OjPuxa+GC1I7SAcBv2u2pMt
|
|
1895
|
+
h9WbP33IvB3eFww+C1hoW0fwdZPiq4FxBtKNiZuFpmYuFngW/nJteBu9kQ==
|
|
1896
|
+
-----END PUBLIC KEY-----
|
|
1897
|
+
`;
|
|
1898
|
+
function verifyTeeAttestation(proof, expectedApplicationId) {
|
|
1899
|
+
return __async(this, null, function* () {
|
|
1900
|
+
try {
|
|
1901
|
+
let teeAttestation = proof.teeAttestation;
|
|
1902
|
+
if (!teeAttestation) {
|
|
1903
|
+
throw new Error("Missing teeAttestation in proof");
|
|
1904
|
+
}
|
|
1905
|
+
if (typeof teeAttestation === "string") {
|
|
1906
|
+
teeAttestation = JSON.parse(teeAttestation);
|
|
1907
|
+
}
|
|
1908
|
+
let expectedNonceSignature;
|
|
1909
|
+
let nonceDataObj;
|
|
1910
|
+
try {
|
|
1911
|
+
const context = JSON.parse(proof.claimData.context);
|
|
1912
|
+
expectedNonceSignature = context.attestationNonce;
|
|
1913
|
+
nonceDataObj = context.attestationNonceData;
|
|
1914
|
+
} catch (e) {
|
|
1915
|
+
throw new Error("Failed to parse proof context to extract attestationNonce");
|
|
1916
|
+
}
|
|
1917
|
+
if (!expectedNonceSignature || !nonceDataObj) {
|
|
1918
|
+
throw new Error("Proof context is missing attestationNonce or attestationNonceData");
|
|
1919
|
+
}
|
|
1920
|
+
if (teeAttestation.nonce !== expectedNonceSignature) {
|
|
1921
|
+
throw new Error(`Nonce Mismatch! Expected signature ${expectedNonceSignature}, got ${teeAttestation.nonce}`);
|
|
1922
|
+
}
|
|
1923
|
+
const { applicationId, sessionId, timestamp } = nonceDataObj;
|
|
1924
|
+
if (expectedApplicationId && applicationId.toLowerCase() !== expectedApplicationId.toLowerCase()) {
|
|
1925
|
+
throw new Error(`Application ID Mismatch! Expected ${expectedApplicationId}, but proof context contains ${applicationId}`);
|
|
1926
|
+
}
|
|
1927
|
+
const expectedNonceData = `${applicationId}:${sessionId}:${timestamp}`;
|
|
1928
|
+
const nonceMsg = import_ethers4.ethers.getBytes(import_ethers4.ethers.keccak256(new TextEncoder().encode(expectedNonceData)));
|
|
1929
|
+
const recoveredAddress = import_ethers4.ethers.verifyMessage(nonceMsg, expectedNonceSignature);
|
|
1930
|
+
if (recoveredAddress.toLowerCase() !== applicationId.toLowerCase()) {
|
|
1931
|
+
throw new Error(`Nonce signature verification failed: recovered ${recoveredAddress}, expected ${applicationId}`);
|
|
1932
|
+
}
|
|
1933
|
+
try {
|
|
1934
|
+
const context = JSON.parse(proof.claimData.context);
|
|
1935
|
+
const paramSessionId = context.attestationNonceData.sessionId;
|
|
1936
|
+
if (!paramSessionId) {
|
|
1937
|
+
throw new Error(`Proof parameters are missing proxySessionId or sessionId`);
|
|
1938
|
+
}
|
|
1939
|
+
if (paramSessionId.toString() !== sessionId.toString()) {
|
|
1940
|
+
throw new Error(`Session ID Mismatch! Expected ${sessionId}, but proof parameters contain ${paramSessionId}`);
|
|
1941
|
+
}
|
|
1942
|
+
const claimTimestampMs = proof.claimData.timestampS * 1e3;
|
|
1943
|
+
const nonceTimestampMs = parseInt(timestamp, 10);
|
|
1944
|
+
const diffMs = Math.abs(claimTimestampMs - nonceTimestampMs);
|
|
1945
|
+
const TEN_MINUTES_MS = 10 * 60 * 1e3;
|
|
1946
|
+
if (diffMs > TEN_MINUTES_MS) {
|
|
1947
|
+
throw new Error(`Timestamp Skew Too Large! claimData.timestampS and attestationNonce timestamp differ by ${Math.round(diffMs / 1e3)}s (limit: 600s)`);
|
|
1948
|
+
}
|
|
1949
|
+
} catch (e) {
|
|
1950
|
+
if (e instanceof Error && (e.message.includes("Session ID Mismatch!") || e.message.includes("Timestamp Skew"))) {
|
|
1951
|
+
throw e;
|
|
1952
|
+
}
|
|
1953
|
+
throw new Error(`Failed to cross-verify session ID: ${e.message}`);
|
|
1954
|
+
}
|
|
1955
|
+
const reportBuffer = base64ToUint8Array(teeAttestation.snp_report);
|
|
1956
|
+
const report = parseAttestationReport(reportBuffer);
|
|
1957
|
+
if (report.isDebugEnabled) {
|
|
1958
|
+
throw new Error("POLICY CHECK FAILED: Debug mode is ALLOWED. Environment is compromised.");
|
|
1959
|
+
}
|
|
1960
|
+
const certBuffer = base64ToUint8Array(teeAttestation.vlek_cert);
|
|
1961
|
+
yield verifyAMDChain(certBuffer);
|
|
1962
|
+
verifyTCB(certBuffer, report);
|
|
1963
|
+
yield verifyHardwareSignature(reportBuffer, certBuffer);
|
|
1964
|
+
yield verifyReportData(teeAttestation, proof.claimData.context, report);
|
|
1965
|
+
return true;
|
|
1966
|
+
} catch (error) {
|
|
1967
|
+
logger9.error("TEE attestation verification failed:", error);
|
|
1968
|
+
return false;
|
|
1969
|
+
}
|
|
1970
|
+
});
|
|
1971
|
+
}
|
|
1972
|
+
function parseAttestationReport(buffer) {
|
|
1973
|
+
if (buffer.length < 1e3) {
|
|
1974
|
+
throw new Error(`Report buffer is too small: ${buffer.length} bytes`);
|
|
1975
|
+
}
|
|
1976
|
+
const view = new DataView(buffer.buffer, buffer.byteOffset, buffer.byteLength);
|
|
1977
|
+
const policy = view.getBigUint64(8, true);
|
|
1978
|
+
const isDebugEnabled = (policy & BigInt(1) << BigInt(19)) !== BigInt(0);
|
|
1979
|
+
const reported_tcb = {
|
|
1980
|
+
bootloader: buffer[56],
|
|
1981
|
+
tee: buffer[57],
|
|
1982
|
+
snp: buffer[62],
|
|
1983
|
+
microcode: buffer[63]
|
|
1984
|
+
};
|
|
1985
|
+
const reportData = arrayBufferToHex(buffer.subarray(80, 144));
|
|
1986
|
+
return { policy, isDebugEnabled, reported_tcb, reportData };
|
|
1987
|
+
}
|
|
1988
|
+
function getExtValue(certAsn1, oidString) {
|
|
1989
|
+
const tbsCert = certAsn1.value[0];
|
|
1990
|
+
if (!tbsCert || !tbsCert.value) return null;
|
|
1991
|
+
const extBlockWrapper = tbsCert.value.find((node) => node.tagClass === import_node_forge.default.asn1.Class.CONTEXT_SPECIFIC && node.type === 3);
|
|
1992
|
+
if (!extBlockWrapper || !extBlockWrapper.value || !extBlockWrapper.value.length) return null;
|
|
1993
|
+
const extSequence = extBlockWrapper.value[0];
|
|
1994
|
+
for (const ext of extSequence.value) {
|
|
1995
|
+
const extIdAsn1 = ext.value[0];
|
|
1996
|
+
const extIdStr = import_node_forge.default.asn1.derToOid(extIdAsn1.value);
|
|
1997
|
+
if (extIdStr === oidString) {
|
|
1998
|
+
const extValueAsn1 = ext.value[ext.value.length - 1];
|
|
1999
|
+
const rawOctetStringBytes = extValueAsn1.value;
|
|
2000
|
+
try {
|
|
2001
|
+
const innerAsn1 = import_node_forge.default.asn1.fromDer(import_node_forge.default.util.createBuffer(rawOctetStringBytes));
|
|
2002
|
+
if (innerAsn1.type === 2) {
|
|
2003
|
+
const bytes = innerAsn1.value;
|
|
2004
|
+
if (typeof bytes === "string" && bytes.length > 0) {
|
|
2005
|
+
return bytes.charCodeAt(bytes.length - 1);
|
|
2006
|
+
} else {
|
|
2007
|
+
throw new Error(`Extension ${oidString} INTEGER value is empty or invalid`);
|
|
2008
|
+
}
|
|
2009
|
+
} else {
|
|
2010
|
+
throw new Error(`Extension ${oidString} does not contain an INTEGER, found type ${innerAsn1.type}`);
|
|
2011
|
+
}
|
|
2012
|
+
} catch (e) {
|
|
2013
|
+
throw new Error(`Failed to strictly parse AMD TCB extension ${oidString}: ${e.message}`);
|
|
2014
|
+
}
|
|
2015
|
+
}
|
|
2016
|
+
}
|
|
2017
|
+
return null;
|
|
2018
|
+
}
|
|
2019
|
+
function verifyTCB(vlekCertBuffer, report) {
|
|
2020
|
+
const certAsn1 = import_node_forge.default.asn1.fromDer(import_node_forge.default.util.createBuffer(uint8ArrayToBinaryString(vlekCertBuffer)));
|
|
2021
|
+
const OID_BOOTLOADER = "1.3.6.1.4.1.3704.1.3.1";
|
|
2022
|
+
const OID_TEE = "1.3.6.1.4.1.3704.1.3.2";
|
|
2023
|
+
const OID_SNP = "1.3.6.1.4.1.3704.1.3.3";
|
|
2024
|
+
const OID_MICROCODE = "1.3.6.1.4.1.3704.1.3.8";
|
|
2025
|
+
const certTcb = {
|
|
2026
|
+
bootloader: getExtValue(certAsn1, OID_BOOTLOADER),
|
|
2027
|
+
tee: getExtValue(certAsn1, OID_TEE),
|
|
2028
|
+
snp: getExtValue(certAsn1, OID_SNP),
|
|
2029
|
+
microcode: getExtValue(certAsn1, OID_MICROCODE)
|
|
2030
|
+
};
|
|
2031
|
+
if (certTcb.bootloader !== null && report.reported_tcb.bootloader < certTcb.bootloader) {
|
|
2032
|
+
throw new Error(`TCB Downgrade! Bootloader reported ${report.reported_tcb.bootloader}, but certificate requires ${certTcb.bootloader}`);
|
|
2033
|
+
}
|
|
2034
|
+
if (certTcb.tee !== null && report.reported_tcb.tee < certTcb.tee) {
|
|
2035
|
+
throw new Error(`TCB Downgrade! TEE reported ${report.reported_tcb.tee}, but certificate requires ${certTcb.tee}`);
|
|
2036
|
+
}
|
|
2037
|
+
if (certTcb.snp !== null && report.reported_tcb.snp < certTcb.snp) {
|
|
2038
|
+
throw new Error(`TCB Downgrade! SNP reported ${report.reported_tcb.snp}, but certificate requires ${certTcb.snp}`);
|
|
2039
|
+
}
|
|
2040
|
+
if (certTcb.microcode !== null && report.reported_tcb.microcode < certTcb.microcode) {
|
|
2041
|
+
throw new Error(`TCB Downgrade! Microcode reported ${report.reported_tcb.microcode}, but certificate requires ${certTcb.microcode}`);
|
|
2042
|
+
}
|
|
2043
|
+
}
|
|
2044
|
+
function parseAsn1Time(node) {
|
|
2045
|
+
const s = node.value;
|
|
2046
|
+
if (node.type === import_node_forge.default.asn1.Type.UTCTIME) {
|
|
2047
|
+
const yr = parseInt(s.substring(0, 2), 10);
|
|
2048
|
+
return new Date(Date.UTC(
|
|
2049
|
+
yr >= 50 ? 1900 + yr : 2e3 + yr,
|
|
2050
|
+
parseInt(s.substring(2, 4), 10) - 1,
|
|
2051
|
+
parseInt(s.substring(4, 6), 10),
|
|
2052
|
+
parseInt(s.substring(6, 8), 10),
|
|
2053
|
+
parseInt(s.substring(8, 10), 10),
|
|
2054
|
+
parseInt(s.substring(10, 12), 10)
|
|
2055
|
+
));
|
|
2056
|
+
} else {
|
|
2057
|
+
return new Date(Date.UTC(
|
|
2058
|
+
parseInt(s.substring(0, 4), 10),
|
|
2059
|
+
parseInt(s.substring(4, 6), 10) - 1,
|
|
2060
|
+
parseInt(s.substring(6, 8), 10),
|
|
2061
|
+
parseInt(s.substring(8, 10), 10),
|
|
2062
|
+
parseInt(s.substring(10, 12), 10),
|
|
2063
|
+
parseInt(s.substring(12, 14), 10)
|
|
2064
|
+
));
|
|
2065
|
+
}
|
|
2066
|
+
}
|
|
2067
|
+
function verifyCRL(crlBuf, arkPem, vlekSerial) {
|
|
2068
|
+
return __async(this, null, function* () {
|
|
2069
|
+
const crlAsn1 = import_node_forge.default.asn1.fromDer(import_node_forge.default.util.createBuffer(uint8ArrayToBinaryString(crlBuf)));
|
|
2070
|
+
if (!Array.isArray(crlAsn1.value) || crlAsn1.value.length < 3) {
|
|
2071
|
+
throw new Error("CRL ASN.1 structure is invalid: expected SEQUENCE with TBSCertList, AlgorithmIdentifier, BIT STRING");
|
|
2072
|
+
}
|
|
2073
|
+
const tbsAsn1 = crlAsn1.value[0];
|
|
2074
|
+
const sigBitsAsn1 = crlAsn1.value[2];
|
|
2075
|
+
if (!Array.isArray(tbsAsn1.value)) {
|
|
2076
|
+
throw new Error("CRL TBSCertList is not a valid SEQUENCE");
|
|
2077
|
+
}
|
|
2078
|
+
const tbsFields = tbsAsn1.value;
|
|
2079
|
+
let fi = 0;
|
|
2080
|
+
if (fi < tbsFields.length && tbsFields[fi].tagClass === import_node_forge.default.asn1.Class.UNIVERSAL && tbsFields[fi].type === import_node_forge.default.asn1.Type.INTEGER) {
|
|
2081
|
+
fi++;
|
|
2082
|
+
}
|
|
2083
|
+
if (fi < tbsFields.length) fi++;
|
|
2084
|
+
if (fi >= tbsFields.length) throw new Error("CRL TBSCertList missing issuer");
|
|
2085
|
+
const issuerAsn1 = tbsFields[fi++];
|
|
2086
|
+
if (fi >= tbsFields.length) throw new Error("CRL TBSCertList missing thisUpdate");
|
|
2087
|
+
const thisUpdateAsn1 = tbsFields[fi++];
|
|
2088
|
+
let nextUpdateAsn1 = null;
|
|
2089
|
+
if (fi < tbsFields.length && tbsFields[fi].tagClass === import_node_forge.default.asn1.Class.UNIVERSAL && (tbsFields[fi].type === import_node_forge.default.asn1.Type.UTCTIME || tbsFields[fi].type === import_node_forge.default.asn1.Type.GENERALIZEDTIME)) {
|
|
2090
|
+
nextUpdateAsn1 = tbsFields[fi++];
|
|
2091
|
+
}
|
|
2092
|
+
let revokedSeq = null;
|
|
2093
|
+
if (fi < tbsFields.length && tbsFields[fi].tagClass === import_node_forge.default.asn1.Class.UNIVERSAL && tbsFields[fi].type === import_node_forge.default.asn1.Type.SEQUENCE) {
|
|
2094
|
+
revokedSeq = tbsFields[fi];
|
|
2095
|
+
}
|
|
2096
|
+
const now = /* @__PURE__ */ new Date();
|
|
2097
|
+
const thisUpdate = parseAsn1Time(thisUpdateAsn1);
|
|
2098
|
+
if (thisUpdate > now) {
|
|
2099
|
+
throw new Error(`CRL is not yet valid: thisUpdate is ${thisUpdate.toISOString()}`);
|
|
2100
|
+
}
|
|
2101
|
+
if (nextUpdateAsn1) {
|
|
2102
|
+
const nextUpdate = parseAsn1Time(nextUpdateAsn1);
|
|
2103
|
+
if (nextUpdate < now) {
|
|
2104
|
+
throw new Error(`CRL has expired: nextUpdate was ${nextUpdate.toISOString()}`);
|
|
2105
|
+
}
|
|
2106
|
+
}
|
|
2107
|
+
const crlIssuerDer = import_node_forge.default.asn1.toDer(issuerAsn1).getBytes();
|
|
2108
|
+
const arkForgeCert = import_node_forge.default.pki.certificateFromPem(arkPem);
|
|
2109
|
+
const arkCertAsn1 = import_node_forge.default.pki.certificateToAsn1(arkForgeCert);
|
|
2110
|
+
const arkSubjectAsn1 = arkCertAsn1.value[0].value[5];
|
|
2111
|
+
const arkSubjectDer = import_node_forge.default.asn1.toDer(arkSubjectAsn1).getBytes();
|
|
2112
|
+
if (crlIssuerDer !== arkSubjectDer) {
|
|
2113
|
+
throw new Error("CRL issuer does not match AMD ARK certificate subject \u2014 chain mismatch");
|
|
2114
|
+
}
|
|
2115
|
+
const tbsDerBuf = binaryStringToUint8Array(import_node_forge.default.asn1.toDer(tbsAsn1).getBytes());
|
|
2116
|
+
const sigRaw = typeof sigBitsAsn1.value === "string" ? sigBitsAsn1.value : "";
|
|
2117
|
+
const sigBuf = binaryStringToUint8Array(sigRaw.substring(1));
|
|
2118
|
+
const cryptoSubtle = getSubtleCrypto();
|
|
2119
|
+
const spkiBuf = binaryStringToUint8Array(
|
|
2120
|
+
import_node_forge.default.asn1.toDer(import_node_forge.default.pki.publicKeyToAsn1(arkForgeCert.publicKey)).getBytes()
|
|
2121
|
+
);
|
|
2122
|
+
const arkCryptoKey = yield cryptoSubtle.importKey(
|
|
2123
|
+
"spki",
|
|
2124
|
+
spkiBuf,
|
|
2125
|
+
{ name: "RSA-PSS", hash: "SHA-384" },
|
|
2126
|
+
false,
|
|
2127
|
+
["verify"]
|
|
2128
|
+
);
|
|
2129
|
+
const isValid = yield cryptoSubtle.verify(
|
|
2130
|
+
{ name: "RSA-PSS", saltLength: 48 },
|
|
2131
|
+
// SHA-384 salt length is 48
|
|
2132
|
+
arkCryptoKey,
|
|
2133
|
+
sigBuf,
|
|
2134
|
+
tbsDerBuf
|
|
2135
|
+
);
|
|
2136
|
+
if (!isValid) {
|
|
2137
|
+
throw new Error("CRL signature is INVALID \u2014 the CRL may be tampered or forged");
|
|
2138
|
+
}
|
|
2139
|
+
const targetSerial = normalizeSerial(vlekSerial);
|
|
2140
|
+
if (revokedSeq && Array.isArray(revokedSeq.value)) {
|
|
2141
|
+
for (const entry of revokedSeq.value) {
|
|
2142
|
+
if (!Array.isArray(entry.value) || entry.value.length < 2) continue;
|
|
2143
|
+
const serialAsn1 = entry.value[0];
|
|
2144
|
+
if (serialAsn1.type !== import_node_forge.default.asn1.Type.INTEGER || typeof serialAsn1.value !== "string") continue;
|
|
2145
|
+
const serialHex = import_node_forge.default.util.bytesToHex(serialAsn1.value);
|
|
2146
|
+
if (normalizeSerial(serialHex) === targetSerial) {
|
|
2147
|
+
throw new Error("\u{1F6A8} VLEK Certificate is REVOKED per AMD CRL! This hardware may be compromised.");
|
|
2148
|
+
}
|
|
2149
|
+
}
|
|
2150
|
+
}
|
|
2151
|
+
});
|
|
2152
|
+
}
|
|
2153
|
+
function assertCertValidity(label, cert) {
|
|
2154
|
+
const now = Date.now();
|
|
2155
|
+
if (cert.notBefore && now < cert.notBefore.getTime()) {
|
|
2156
|
+
throw new Error(`${label} certificate is not yet valid (notBefore: ${cert.notBefore.toISOString()})`);
|
|
2157
|
+
}
|
|
2158
|
+
if (cert.notAfter && now > cert.notAfter.getTime()) {
|
|
2159
|
+
throw new Error(`${label} certificate expired on ${cert.notAfter.toISOString()}`);
|
|
2160
|
+
}
|
|
2161
|
+
}
|
|
2162
|
+
function verifyAMDChain(vlekCertBuffer) {
|
|
2163
|
+
return __async(this, null, function* () {
|
|
2164
|
+
const processors = ["Milan", "Genoa"];
|
|
2165
|
+
let chainVerified = false;
|
|
2166
|
+
const vlek = parseCert(vlekCertBuffer);
|
|
2167
|
+
assertCertValidity("VLEK", vlek);
|
|
2168
|
+
for (const processor of processors) {
|
|
2169
|
+
let matchedChain = false;
|
|
2170
|
+
try {
|
|
2171
|
+
const chainPem = AMD_CERTS[processor];
|
|
2172
|
+
if (!chainPem) continue;
|
|
2173
|
+
const certs = chainPem.split("-----END CERTIFICATE-----").map((c) => c.trim()).filter((c) => c.length > 0).map((c) => c + "\n-----END CERTIFICATE-----\n");
|
|
2174
|
+
const askCert = import_node_forge.default.pki.certificateFromPem(certs[0]);
|
|
2175
|
+
const arkCert = import_node_forge.default.pki.certificateFromPem(certs[1]);
|
|
2176
|
+
const askDer = import_node_forge.default.asn1.toDer(import_node_forge.default.pki.certificateToAsn1(askCert)).getBytes();
|
|
2177
|
+
const arkDer = import_node_forge.default.asn1.toDer(import_node_forge.default.pki.certificateToAsn1(arkCert)).getBytes();
|
|
2178
|
+
const ask = parseCert(binaryStringToUint8Array(askDer));
|
|
2179
|
+
const ark = parseCert(binaryStringToUint8Array(arkDer));
|
|
2180
|
+
assertCertValidity("ASK", ask);
|
|
2181
|
+
assertCertValidity("ARK", ark);
|
|
2182
|
+
try {
|
|
2183
|
+
yield verifySignature(certs[1], ark.tbsDer, ark.signature, ark.sigAlgOid);
|
|
2184
|
+
} catch (e) {
|
|
2185
|
+
throw new Error(`AMD ARK self-signature verification failed: ${e.message}`);
|
|
2186
|
+
}
|
|
2187
|
+
try {
|
|
2188
|
+
yield verifySignature(certs[1], ask.tbsDer, ask.signature, ask.sigAlgOid);
|
|
2189
|
+
} catch (e) {
|
|
2190
|
+
throw new Error(`AMD ASK-by-ARK signature verification failed: ${e.message}`);
|
|
2191
|
+
}
|
|
2192
|
+
try {
|
|
2193
|
+
yield verifySignature(certs[0], vlek.tbsDer, vlek.signature, vlek.sigAlgOid);
|
|
2194
|
+
} catch (e) {
|
|
2195
|
+
throw new Error(`VLEK-by-ASK signature verification failed: ${e.message}`);
|
|
2196
|
+
}
|
|
2197
|
+
matchedChain = true;
|
|
2198
|
+
let crlBuf;
|
|
2199
|
+
const now = Date.now();
|
|
2200
|
+
if (crlCache[processor] && now - crlCache[processor].fetchedAt < 36e5) {
|
|
2201
|
+
crlBuf = crlCache[processor].buffer;
|
|
2202
|
+
} else {
|
|
2203
|
+
const crlUrl = `https://kdsintf.amd.com/vlek/v1/${processor}/crl`;
|
|
2204
|
+
const controller = new AbortController();
|
|
2205
|
+
const timeoutId = setTimeout(() => controller.abort(), 5e3);
|
|
2206
|
+
const crlResp = yield fetch(crlUrl, { signal: controller.signal });
|
|
2207
|
+
clearTimeout(timeoutId);
|
|
2208
|
+
if (!crlResp.ok) continue;
|
|
2209
|
+
crlBuf = new Uint8Array(yield crlResp.arrayBuffer());
|
|
2210
|
+
crlCache[processor] = { buffer: crlBuf, fetchedAt: now };
|
|
2211
|
+
}
|
|
2212
|
+
if (vlek.serialNumber && crlBuf) {
|
|
2213
|
+
yield verifyCRL(crlBuf, certs[1], vlek.serialNumber);
|
|
2214
|
+
}
|
|
2215
|
+
chainVerified = true;
|
|
2216
|
+
break;
|
|
2217
|
+
} catch (e) {
|
|
2218
|
+
if (matchedChain) {
|
|
2219
|
+
throw e;
|
|
2220
|
+
}
|
|
2221
|
+
continue;
|
|
2222
|
+
}
|
|
2223
|
+
}
|
|
2224
|
+
if (!chainVerified) {
|
|
2225
|
+
throw new Error("VLEK Certificate failed verification against all known AMD Root of Trust chains!");
|
|
2226
|
+
}
|
|
2227
|
+
});
|
|
2228
|
+
}
|
|
2229
|
+
function verifyHardwareSignature(reportBytes, certBytes) {
|
|
2230
|
+
return __async(this, null, function* () {
|
|
2231
|
+
const vlek = parseCert(certBytes);
|
|
2232
|
+
const sigOffset = 672;
|
|
2233
|
+
const rLE = reportBytes.subarray(sigOffset, sigOffset + 72);
|
|
2234
|
+
const sLE = reportBytes.subarray(sigOffset + 72, sigOffset + 144);
|
|
2235
|
+
const rBE = reverseBytes(rLE);
|
|
2236
|
+
const sBE = reverseBytes(sLE);
|
|
2237
|
+
const signedData = reportBytes.subarray(0, 672);
|
|
2238
|
+
const cryptoSubtle = getSubtleCrypto();
|
|
2239
|
+
const importedKey = yield cryptoSubtle.importKey(
|
|
2240
|
+
"spki",
|
|
2241
|
+
vlek.spkiDer,
|
|
2242
|
+
{ name: "ECDSA", namedCurve: "P-384" },
|
|
2243
|
+
false,
|
|
2244
|
+
["verify"]
|
|
2245
|
+
);
|
|
2246
|
+
const rPadding = rBE.subarray(0, rBE.length - 48);
|
|
2247
|
+
const sPadding = sBE.subarray(0, sBE.length - 48);
|
|
2248
|
+
if (!rPadding.every((b) => b === 0) || !sPadding.every((b) => b === 0)) {
|
|
2249
|
+
throw new Error("Hardware ECDSA signature is malformed: non-zero padding bytes detected in the structural signature coordinates.");
|
|
2250
|
+
}
|
|
2251
|
+
const r48 = rBE.subarray(rBE.length - 48);
|
|
2252
|
+
const s48 = sBE.subarray(sBE.length - 48);
|
|
2253
|
+
const rawSignature = concatUint8Arrays([r48, s48]);
|
|
2254
|
+
const isValid = yield cryptoSubtle.verify(
|
|
2255
|
+
{ name: "ECDSA", hash: { name: "SHA-384" } },
|
|
2256
|
+
importedKey,
|
|
2257
|
+
rawSignature,
|
|
2258
|
+
signedData
|
|
2259
|
+
);
|
|
2260
|
+
if (!isValid) {
|
|
2261
|
+
throw new Error("Hardware ECDSA signature is completely invalid!");
|
|
1386
2262
|
}
|
|
1387
2263
|
});
|
|
1388
|
-
|
|
1389
|
-
|
|
2264
|
+
}
|
|
2265
|
+
function verifyReportData(teeAttestation, proofContext, report) {
|
|
2266
|
+
return __async(this, null, function* () {
|
|
2267
|
+
if (!teeAttestation.workload_digest || !teeAttestation.verifier_digest) {
|
|
2268
|
+
throw new Error("POLICY CHECK FAILED: Missing workload_digest or verifier_digest in TEE attestation.");
|
|
2269
|
+
}
|
|
2270
|
+
const { attestationNonce: nonce } = JSON.parse(proofContext);
|
|
2271
|
+
const cryptoSubtle = getSubtleCrypto();
|
|
2272
|
+
const extractDigestBytes = (imageRef) => {
|
|
2273
|
+
const marker = "@sha256:";
|
|
2274
|
+
const idx = imageRef.lastIndexOf(marker);
|
|
2275
|
+
if (idx < 0) throw new Error(`Image ref missing @sha256: digest: ${imageRef}`);
|
|
2276
|
+
const hexDigest = imageRef.substring(idx + marker.length);
|
|
2277
|
+
if (hexDigest.length !== 64) throw new Error(`SHA256 digest must be 64 hex chars, got ${hexDigest.length} in: ${imageRef}`);
|
|
2278
|
+
const bytes = new Uint8Array(32);
|
|
2279
|
+
for (let i = 0; i < 32; i++) bytes[i] = parseInt(hexDigest.substring(i * 2, i * 2 + 2), 16);
|
|
2280
|
+
return bytes;
|
|
2281
|
+
};
|
|
2282
|
+
const importedCosignKey = yield cryptoSubtle.importKey(
|
|
2283
|
+
"spki",
|
|
2284
|
+
base64ToUint8Array(
|
|
2285
|
+
COSIGN_PUBLIC_KEY.replace("-----BEGIN PUBLIC KEY-----", "").replace("-----END PUBLIC KEY-----", "").replace(/\s+/g, "")
|
|
2286
|
+
),
|
|
2287
|
+
{ name: "ECDSA", namedCurve: "P-256" },
|
|
2288
|
+
true,
|
|
2289
|
+
["verify"]
|
|
2290
|
+
);
|
|
2291
|
+
const pubKeySpkiDer = yield cryptoSubtle.exportKey("spki", importedCosignKey);
|
|
2292
|
+
const pubKeyHashBuffer = yield cryptoSubtle.digest("SHA-256", pubKeySpkiDer);
|
|
2293
|
+
const pubKeyHashBytes = new Uint8Array(pubKeyHashBuffer);
|
|
2294
|
+
const nonceHex = (teeAttestation.nonce || nonce).replace(/^0x/i, "");
|
|
2295
|
+
const nonceBytes = new Uint8Array(nonceHex.length / 2);
|
|
2296
|
+
for (let i = 0; i < nonceBytes.length; i++) nonceBytes[i] = parseInt(nonceHex.substring(i * 2, i * 2 + 2), 16);
|
|
2297
|
+
const workloadBytes = extractDigestBytes(teeAttestation.workload_digest);
|
|
2298
|
+
const verifierBytes = extractDigestBytes(teeAttestation.verifier_digest);
|
|
2299
|
+
const domainSep = new TextEncoder().encode("POPCORN_TEE_REPORT_DATA_V1");
|
|
2300
|
+
const version = new Uint8Array([1]);
|
|
2301
|
+
const payload = new Uint8Array(
|
|
2302
|
+
domainSep.length + version.length + workloadBytes.length + verifierBytes.length + pubKeyHashBytes.length + nonceBytes.length
|
|
2303
|
+
);
|
|
2304
|
+
let offset = 0;
|
|
2305
|
+
for (const chunk of [domainSep, version, workloadBytes, verifierBytes, pubKeyHashBytes, nonceBytes]) {
|
|
2306
|
+
payload.set(chunk, offset);
|
|
2307
|
+
offset += chunk.length;
|
|
2308
|
+
}
|
|
2309
|
+
const hashBuffer = yield cryptoSubtle.digest("SHA-256", payload);
|
|
2310
|
+
const hashHex = arrayBufferToHex(hashBuffer);
|
|
2311
|
+
const expected64ByteHex = hashHex + hashHex;
|
|
2312
|
+
if (report.reportData !== expected64ByteHex) {
|
|
2313
|
+
throw new Error(`REPORT_DATA Mismatch! Hardware report is not bound to these image digests or nonce.
|
|
2314
|
+
Expected: ${expected64ByteHex}
|
|
2315
|
+
Got: ${report.reportData}`);
|
|
2316
|
+
}
|
|
1390
2317
|
});
|
|
1391
2318
|
}
|
|
1392
2319
|
|
|
1393
2320
|
// src/Reclaim.ts
|
|
1394
|
-
var
|
|
2321
|
+
var logger10 = logger_default.logger;
|
|
1395
2322
|
var sdkVersion = require_package().version;
|
|
1396
|
-
function verifyProof(proofOrProofs, config) {
|
|
2323
|
+
function verifyProof(proofOrProofs, config, verifyTEE) {
|
|
1397
2324
|
return __async(this, null, function* () {
|
|
2325
|
+
const proofs = Array.isArray(proofOrProofs) ? proofOrProofs : [proofOrProofs];
|
|
1398
2326
|
try {
|
|
1399
|
-
const proofs = Array.isArray(proofOrProofs) ? proofOrProofs : [proofOrProofs];
|
|
1400
2327
|
if (proofs.length === 0) {
|
|
1401
2328
|
throw new ProofNotValidatedError("No proofs provided");
|
|
1402
2329
|
}
|
|
@@ -1407,14 +2334,57 @@ function verifyProof(proofOrProofs, config) {
|
|
|
1407
2334
|
for (const proof of proofs) {
|
|
1408
2335
|
yield assertVerifiedProof(proof, attestors);
|
|
1409
2336
|
}
|
|
1410
|
-
assertValidateProof(proofs, config);
|
|
1411
|
-
|
|
2337
|
+
yield assertValidateProof(proofs, config);
|
|
2338
|
+
const result = {
|
|
2339
|
+
isVerified: true,
|
|
2340
|
+
data: proofs.map(extractProofData)
|
|
2341
|
+
};
|
|
2342
|
+
if (verifyTEE) {
|
|
2343
|
+
const hasTeeData = proofs.every((proof) => proof.teeAttestation || JSON.parse(proof.claimData.context).attestationNonce);
|
|
2344
|
+
if (!hasTeeData) {
|
|
2345
|
+
logger10.error("TEE verification requested but one or more proofs are missing TEE attestation data");
|
|
2346
|
+
result.isTeeVerified = false;
|
|
2347
|
+
result.isVerified = false;
|
|
2348
|
+
return result;
|
|
2349
|
+
}
|
|
2350
|
+
try {
|
|
2351
|
+
const teeResults = yield Promise.all(proofs.map((proof) => verifyTeeAttestation(proof)));
|
|
2352
|
+
result.isTeeVerified = teeResults.every((r) => r === true);
|
|
2353
|
+
if (!result.isTeeVerified) {
|
|
2354
|
+
logger10.error("TEE attestation verification failed for one or more proofs");
|
|
2355
|
+
}
|
|
2356
|
+
result.isVerified = result.isVerified && result.isTeeVerified;
|
|
2357
|
+
} catch (error) {
|
|
2358
|
+
logger10.error("Error verifying TEE attestation:", error);
|
|
2359
|
+
result.isTeeVerified = false;
|
|
2360
|
+
result.isVerified = false;
|
|
2361
|
+
}
|
|
2362
|
+
}
|
|
2363
|
+
return result;
|
|
1412
2364
|
} catch (error) {
|
|
1413
|
-
|
|
1414
|
-
return
|
|
2365
|
+
logger10.error("Error in validating proof:", error);
|
|
2366
|
+
return {
|
|
2367
|
+
isVerified: false,
|
|
2368
|
+
data: []
|
|
2369
|
+
};
|
|
1415
2370
|
}
|
|
1416
2371
|
});
|
|
1417
2372
|
}
|
|
2373
|
+
function extractProofData(proof) {
|
|
2374
|
+
try {
|
|
2375
|
+
const context = JSON.parse(proof.claimData.context);
|
|
2376
|
+
const _a = context, { extractedParameters } = _a, rest = __objRest(_a, ["extractedParameters"]);
|
|
2377
|
+
return {
|
|
2378
|
+
context: rest,
|
|
2379
|
+
extractedParameters: extractedParameters != null ? extractedParameters : {}
|
|
2380
|
+
};
|
|
2381
|
+
} catch (e) {
|
|
2382
|
+
return {
|
|
2383
|
+
context: {},
|
|
2384
|
+
extractedParameters: {}
|
|
2385
|
+
};
|
|
2386
|
+
}
|
|
2387
|
+
}
|
|
1418
2388
|
function transformForOnchain(proof) {
|
|
1419
2389
|
const claimInfoBuilder = /* @__PURE__ */ new Map([
|
|
1420
2390
|
["context", proof.claimData.context],
|
|
@@ -1513,7 +2483,7 @@ var ReclaimProofRequest = class _ReclaimProofRequest {
|
|
|
1513
2483
|
};
|
|
1514
2484
|
return templateData;
|
|
1515
2485
|
};
|
|
1516
|
-
var _a, _b;
|
|
2486
|
+
var _a, _b, _c;
|
|
1517
2487
|
this.providerId = providerId;
|
|
1518
2488
|
this.timeStamp = Date.now().toString();
|
|
1519
2489
|
this.applicationId = applicationId;
|
|
@@ -1530,34 +2500,38 @@ var ReclaimProofRequest = class _ReclaimProofRequest {
|
|
|
1530
2500
|
logger_default.setLogLevel("silent");
|
|
1531
2501
|
}
|
|
1532
2502
|
if (options.useAppClip === void 0) {
|
|
1533
|
-
options.useAppClip =
|
|
2503
|
+
options.useAppClip = false;
|
|
1534
2504
|
}
|
|
2505
|
+
this.customSharePageUrl = (_c = (_b = options.portalUrl) != null ? _b : options.customSharePageUrl) != null ? _c : "https://portal.reclaimprotocol.org";
|
|
2506
|
+
options.customSharePageUrl = this.customSharePageUrl;
|
|
1535
2507
|
if (options == null ? void 0 : options.envUrl) {
|
|
1536
2508
|
setBackendBaseUrl(options.envUrl);
|
|
1537
|
-
} else if (
|
|
1538
|
-
|
|
2509
|
+
} else if (this.customSharePageUrl) {
|
|
2510
|
+
try {
|
|
2511
|
+
if (new URL(this.customSharePageUrl).hostname === "eu.portal.reclaimprotocol.org") {
|
|
2512
|
+
setBackendBaseUrl("https://eu.api.reclaimprotocol.org");
|
|
2513
|
+
}
|
|
2514
|
+
} catch (e) {
|
|
2515
|
+
}
|
|
1539
2516
|
}
|
|
1540
2517
|
if (options.extensionID) {
|
|
1541
2518
|
this.extensionID = options.extensionID;
|
|
1542
2519
|
}
|
|
1543
|
-
if (options == null ? void 0 : options.customSharePageUrl) {
|
|
1544
|
-
this.customSharePageUrl = options.customSharePageUrl;
|
|
1545
|
-
}
|
|
1546
2520
|
if (options == null ? void 0 : options.customAppClipUrl) {
|
|
1547
2521
|
this.customAppClipUrl = options.customAppClipUrl;
|
|
1548
2522
|
}
|
|
1549
2523
|
this.options = options;
|
|
1550
2524
|
this.sdkVersion = "js-" + sdkVersion;
|
|
1551
|
-
|
|
2525
|
+
logger10.info(`Initializing client with applicationId: ${this.applicationId}`);
|
|
1552
2526
|
}
|
|
1553
2527
|
/**
|
|
1554
|
-
* Initializes a new Reclaim proof request instance with automatic signature generation and session creation
|
|
2528
|
+
* Initializes a new Reclaim proof request instance with automatic signature generation and session creation.
|
|
1555
2529
|
*
|
|
1556
2530
|
* @param applicationId - Your Reclaim application ID
|
|
1557
2531
|
* @param appSecret - Your application secret key for signing requests
|
|
1558
2532
|
* @param providerId - The ID of the provider to use for proof generation
|
|
1559
2533
|
* @param options - Optional configuration options for the proof request
|
|
1560
|
-
* @returns
|
|
2534
|
+
* @returns A fully initialized proof request instance
|
|
1561
2535
|
* @throws {InitError} When initialization fails due to invalid parameters or session creation errors
|
|
1562
2536
|
*
|
|
1563
2537
|
* @example
|
|
@@ -1566,7 +2540,7 @@ var ReclaimProofRequest = class _ReclaimProofRequest {
|
|
|
1566
2540
|
* 'your-app-id',
|
|
1567
2541
|
* 'your-app-secret',
|
|
1568
2542
|
* 'provider-id',
|
|
1569
|
-
* {
|
|
2543
|
+
* { portalUrl: 'https://portal.reclaimprotocol.org', log: true }
|
|
1570
2544
|
* );
|
|
1571
2545
|
* ```
|
|
1572
2546
|
*/
|
|
@@ -1619,6 +2593,11 @@ var ReclaimProofRequest = class _ReclaimProofRequest {
|
|
|
1619
2593
|
{ paramName: "envUrl", input: options.envUrl, isString: true }
|
|
1620
2594
|
], "the constructor");
|
|
1621
2595
|
}
|
|
2596
|
+
if (options.portalUrl) {
|
|
2597
|
+
validateFunctionParams([
|
|
2598
|
+
{ paramName: "portalUrl", input: options.portalUrl, isString: true }
|
|
2599
|
+
], "the constructor");
|
|
2600
|
+
}
|
|
1622
2601
|
if (options.customSharePageUrl) {
|
|
1623
2602
|
validateFunctionParams([
|
|
1624
2603
|
{ paramName: "customSharePageUrl", input: options.customSharePageUrl, isString: true }
|
|
@@ -1641,7 +2620,7 @@ var ReclaimProofRequest = class _ReclaimProofRequest {
|
|
|
1641
2620
|
Intl.getCanonicalLocales(options.preferredLocale);
|
|
1642
2621
|
return true;
|
|
1643
2622
|
} catch (error) {
|
|
1644
|
-
|
|
2623
|
+
logger10.info("Failed to canonicalize locale", error);
|
|
1645
2624
|
return false;
|
|
1646
2625
|
}
|
|
1647
2626
|
}
|
|
@@ -1655,10 +2634,21 @@ var ReclaimProofRequest = class _ReclaimProofRequest {
|
|
|
1655
2634
|
proofRequestInstance.sessionId = data.sessionId;
|
|
1656
2635
|
proofRequestInstance.resolvedProviderVersion = data.resolvedProviderVersion;
|
|
1657
2636
|
proofRequestInstance.context.reclaimSessionId = data.sessionId;
|
|
2637
|
+
if (options == null ? void 0 : options.acceptTeeAttestation) {
|
|
2638
|
+
const wallet = new import_ethers5.ethers.Wallet(appSecret);
|
|
2639
|
+
const nonceData = `${applicationId}:${data.sessionId}:${proofRequestInstance.timeStamp}`;
|
|
2640
|
+
const nonceMsg = import_ethers5.ethers.getBytes(import_ethers5.ethers.keccak256(new TextEncoder().encode(nonceData)));
|
|
2641
|
+
const nonceSignature = yield wallet.signMessage(nonceMsg);
|
|
2642
|
+
proofRequestInstance.setAttestationContext(nonceSignature, {
|
|
2643
|
+
applicationId,
|
|
2644
|
+
sessionId: data.sessionId,
|
|
2645
|
+
timestamp: proofRequestInstance.timeStamp
|
|
2646
|
+
});
|
|
2647
|
+
}
|
|
1658
2648
|
return proofRequestInstance;
|
|
1659
2649
|
} catch (error) {
|
|
1660
2650
|
console.error(error);
|
|
1661
|
-
|
|
2651
|
+
logger10.info("Failed to initialize ReclaimProofRequest", error);
|
|
1662
2652
|
throw new InitError("Failed to initialize ReclaimProofRequest", error);
|
|
1663
2653
|
}
|
|
1664
2654
|
});
|
|
@@ -1775,7 +2765,7 @@ var ReclaimProofRequest = class _ReclaimProofRequest {
|
|
|
1775
2765
|
Intl.getCanonicalLocales(options.preferredLocale);
|
|
1776
2766
|
return true;
|
|
1777
2767
|
} catch (error) {
|
|
1778
|
-
|
|
2768
|
+
logger10.info("Failed to canonicalize locale", error);
|
|
1779
2769
|
return false;
|
|
1780
2770
|
}
|
|
1781
2771
|
}
|
|
@@ -1784,6 +2774,7 @@ var ReclaimProofRequest = class _ReclaimProofRequest {
|
|
|
1784
2774
|
const proofRequestInstance = new _ReclaimProofRequest(applicationId, providerId, options);
|
|
1785
2775
|
proofRequestInstance.sessionId = sessionId;
|
|
1786
2776
|
proofRequestInstance.context = context;
|
|
2777
|
+
proofRequestInstance.setAttestationContext(context == null ? void 0 : context.attestationNonce, context == null ? void 0 : context.attestationNonceData);
|
|
1787
2778
|
proofRequestInstance.parameters = parameters;
|
|
1788
2779
|
proofRequestInstance.appCallbackUrl = appCallbackUrl;
|
|
1789
2780
|
proofRequestInstance.redirectUrl = redirectUrl;
|
|
@@ -1799,7 +2790,7 @@ var ReclaimProofRequest = class _ReclaimProofRequest {
|
|
|
1799
2790
|
proofRequestInstance.cancelRedirectUrlOptions = cancelRedirectUrlOptions;
|
|
1800
2791
|
return proofRequestInstance;
|
|
1801
2792
|
} catch (error) {
|
|
1802
|
-
|
|
2793
|
+
logger10.info("Failed to parse JSON string in fromJsonString:", error);
|
|
1803
2794
|
throw new InvalidParamError("Invalid JSON string provided to fromJsonString");
|
|
1804
2795
|
}
|
|
1805
2796
|
});
|
|
@@ -1960,9 +2951,9 @@ var ReclaimProofRequest = class _ReclaimProofRequest {
|
|
|
1960
2951
|
try {
|
|
1961
2952
|
validateModalOptions(options, "setModalOptions");
|
|
1962
2953
|
this.modalOptions = __spreadValues(__spreadValues({}, this.modalOptions), options);
|
|
1963
|
-
|
|
2954
|
+
logger10.info("Modal options set successfully");
|
|
1964
2955
|
} catch (error) {
|
|
1965
|
-
|
|
2956
|
+
logger10.info("Error setting modal options:", error);
|
|
1966
2957
|
throw new SetParamsError("Error setting modal options", error);
|
|
1967
2958
|
}
|
|
1968
2959
|
}
|
|
@@ -1990,8 +2981,9 @@ var ReclaimProofRequest = class _ReclaimProofRequest {
|
|
|
1990
2981
|
{ input: context, paramName: "context", isString: false }
|
|
1991
2982
|
], "setJsonContext");
|
|
1992
2983
|
this.context = JSON.parse(canonicalStringify(__spreadProps(__spreadValues({}, context), { reclaimSessionId: this.sessionId })));
|
|
2984
|
+
this.applyAttestationContext();
|
|
1993
2985
|
} catch (error) {
|
|
1994
|
-
|
|
2986
|
+
logger10.info("Error setting context", error);
|
|
1995
2987
|
throw new SetContextError("Error setting context", error);
|
|
1996
2988
|
}
|
|
1997
2989
|
}
|
|
@@ -2021,8 +3013,9 @@ var ReclaimProofRequest = class _ReclaimProofRequest {
|
|
|
2021
3013
|
{ input: message, paramName: "message", isString: true }
|
|
2022
3014
|
], "setContext");
|
|
2023
3015
|
this.context = { contextAddress: address, contextMessage: message, reclaimSessionId: this.sessionId };
|
|
3016
|
+
this.applyAttestationContext();
|
|
2024
3017
|
} catch (error) {
|
|
2025
|
-
|
|
3018
|
+
logger10.info("Error setting context", error);
|
|
2026
3019
|
throw new SetContextError("Error setting context", error);
|
|
2027
3020
|
}
|
|
2028
3021
|
}
|
|
@@ -2057,7 +3050,7 @@ var ReclaimProofRequest = class _ReclaimProofRequest {
|
|
|
2057
3050
|
validateParameters(params);
|
|
2058
3051
|
this.parameters = __spreadValues(__spreadValues({}, this.parameters), params);
|
|
2059
3052
|
} catch (error) {
|
|
2060
|
-
|
|
3053
|
+
logger10.info("Error Setting Params:", error);
|
|
2061
3054
|
throw new SetParamsError("Error setting params", error);
|
|
2062
3055
|
}
|
|
2063
3056
|
}
|
|
@@ -2081,7 +3074,7 @@ var ReclaimProofRequest = class _ReclaimProofRequest {
|
|
|
2081
3074
|
validateFunctionParams([{ input: this.sessionId, paramName: "sessionId", isString: true }], "getAppCallbackUrl");
|
|
2082
3075
|
return this.appCallbackUrl || `${constants.DEFAULT_RECLAIM_CALLBACK_URL}${this.sessionId}`;
|
|
2083
3076
|
} catch (error) {
|
|
2084
|
-
|
|
3077
|
+
logger10.info("Error getting app callback url", error);
|
|
2085
3078
|
throw new GetAppCallbackUrlError("Error getting app callback url", error);
|
|
2086
3079
|
}
|
|
2087
3080
|
}
|
|
@@ -2105,7 +3098,7 @@ var ReclaimProofRequest = class _ReclaimProofRequest {
|
|
|
2105
3098
|
validateFunctionParams([{ input: this.sessionId, paramName: "sessionId", isString: true }], "getCancelCallbackUrl");
|
|
2106
3099
|
return this.cancelCallbackUrl || `${constants.DEFAULT_RECLAIM_CANCEL_CALLBACK_URL}${this.sessionId}`;
|
|
2107
3100
|
} catch (error) {
|
|
2108
|
-
|
|
3101
|
+
logger10.info("Error getting cancel callback url", error);
|
|
2109
3102
|
throw new GetAppCallbackUrlError("Error getting cancel callback url", error);
|
|
2110
3103
|
}
|
|
2111
3104
|
}
|
|
@@ -2128,7 +3121,7 @@ var ReclaimProofRequest = class _ReclaimProofRequest {
|
|
|
2128
3121
|
validateFunctionParams([{ input: this.sessionId, paramName: "sessionId", isString: true }], "getStatusUrl");
|
|
2129
3122
|
return `${constants.DEFAULT_RECLAIM_STATUS_URL}${this.sessionId}`;
|
|
2130
3123
|
} catch (error) {
|
|
2131
|
-
|
|
3124
|
+
logger10.info("Error fetching Status Url", error);
|
|
2132
3125
|
throw new GetStatusUrlError("Error fetching status url", error);
|
|
2133
3126
|
}
|
|
2134
3127
|
}
|
|
@@ -2158,25 +3151,25 @@ var ReclaimProofRequest = class _ReclaimProofRequest {
|
|
|
2158
3151
|
try {
|
|
2159
3152
|
validateFunctionParams([{ input: signature, paramName: "signature", isString: true }], "setSignature");
|
|
2160
3153
|
this.signature = signature;
|
|
2161
|
-
|
|
3154
|
+
logger10.info(`Signature set successfully for applicationId: ${this.applicationId}`);
|
|
2162
3155
|
} catch (error) {
|
|
2163
|
-
|
|
3156
|
+
logger10.info("Error setting signature", error);
|
|
2164
3157
|
throw new SetSignatureError("Error setting signature", error);
|
|
2165
3158
|
}
|
|
2166
3159
|
}
|
|
2167
3160
|
generateSignature(applicationSecret) {
|
|
2168
3161
|
return __async(this, null, function* () {
|
|
2169
3162
|
try {
|
|
2170
|
-
const wallet = new
|
|
3163
|
+
const wallet = new import_ethers5.ethers.Wallet(applicationSecret);
|
|
2171
3164
|
const canonicalData = (0, import_canonicalize3.default)({ providerId: this.providerId, timestamp: this.timeStamp });
|
|
2172
3165
|
if (!canonicalData) {
|
|
2173
3166
|
throw new SignatureGeneratingError("Failed to canonicalize data for signing.");
|
|
2174
3167
|
}
|
|
2175
|
-
const messageHash =
|
|
2176
|
-
return yield wallet.signMessage(
|
|
3168
|
+
const messageHash = import_ethers5.ethers.keccak256(new TextEncoder().encode(canonicalData));
|
|
3169
|
+
return yield wallet.signMessage(import_ethers5.ethers.getBytes(messageHash));
|
|
2177
3170
|
} catch (err) {
|
|
2178
|
-
|
|
2179
|
-
throw new SignatureGeneratingError(`Error generating signature for
|
|
3171
|
+
logger10.info(`Error generating proof request for applicationId: ${this.applicationId}, providerId: ${this.providerId}, timeStamp: ${this.timeStamp}`);
|
|
3172
|
+
throw new SignatureGeneratingError(`Error generating signature for applicationId: ${this.applicationId}`);
|
|
2180
3173
|
}
|
|
2181
3174
|
});
|
|
2182
3175
|
}
|
|
@@ -2186,12 +3179,25 @@ var ReclaimProofRequest = class _ReclaimProofRequest {
|
|
|
2186
3179
|
this.intervals.delete(this.sessionId);
|
|
2187
3180
|
}
|
|
2188
3181
|
}
|
|
2189
|
-
|
|
2190
|
-
|
|
2191
|
-
|
|
2192
|
-
return `${this.customSharePageUrl}/?template=${template}`;
|
|
3182
|
+
setAttestationContext(nonce, data) {
|
|
3183
|
+
if (!nonce || !data) {
|
|
3184
|
+
return;
|
|
2193
3185
|
}
|
|
2194
|
-
|
|
3186
|
+
this.attestationNonce = nonce;
|
|
3187
|
+
this.attestationNonceData = data;
|
|
3188
|
+
this.applyAttestationContext();
|
|
3189
|
+
}
|
|
3190
|
+
applyAttestationContext() {
|
|
3191
|
+
if (!this.attestationNonce || !this.attestationNonceData) {
|
|
3192
|
+
return;
|
|
3193
|
+
}
|
|
3194
|
+
this.context = __spreadProps(__spreadValues({}, this.context), {
|
|
3195
|
+
attestationNonce: this.attestationNonce,
|
|
3196
|
+
attestationNonceData: this.attestationNonceData
|
|
3197
|
+
});
|
|
3198
|
+
}
|
|
3199
|
+
buildSharePageUrl(template) {
|
|
3200
|
+
return `https://share.reclaimprotocol.org/verify/?template=${template}`;
|
|
2195
3201
|
}
|
|
2196
3202
|
/**
|
|
2197
3203
|
* Exports the Reclaim proof verification request as a JSON string
|
|
@@ -2245,13 +3251,15 @@ var ReclaimProofRequest = class _ReclaimProofRequest {
|
|
|
2245
3251
|
});
|
|
2246
3252
|
}
|
|
2247
3253
|
/**
|
|
2248
|
-
* Generates and returns the request URL for proof verification
|
|
3254
|
+
* Generates and returns the request URL for proof verification.
|
|
2249
3255
|
*
|
|
2250
|
-
*
|
|
2251
|
-
*
|
|
2252
|
-
* -
|
|
2253
|
-
* -
|
|
2254
|
-
* -
|
|
3256
|
+
* Defaults to portal mode. Pass `{ verificationMode: 'app' }` for native app flow URLs.
|
|
3257
|
+
*
|
|
3258
|
+
* - Portal mode (default): returns portal URL on all platforms
|
|
3259
|
+
* - App mode: returns share page URL on all platforms
|
|
3260
|
+
* - App mode + `useAppClip: true` on iOS: returns App Clip URL instead
|
|
3261
|
+
*
|
|
3262
|
+
* Falls back to `launchOptions` set at init time if not passed at call time.
|
|
2255
3263
|
*
|
|
2256
3264
|
* @param launchOptions - Optional launch configuration to override default behavior
|
|
2257
3265
|
* @returns Promise<string> - The generated request URL
|
|
@@ -2259,59 +3267,58 @@ var ReclaimProofRequest = class _ReclaimProofRequest {
|
|
|
2259
3267
|
*
|
|
2260
3268
|
* @example
|
|
2261
3269
|
* ```typescript
|
|
2262
|
-
*
|
|
2263
|
-
*
|
|
3270
|
+
* // Portal URL (default)
|
|
3271
|
+
* const url = await proofRequest.getRequestUrl();
|
|
3272
|
+
*
|
|
3273
|
+
* // Native app flow URL
|
|
3274
|
+
* const url = await proofRequest.getRequestUrl({ verificationMode: 'app' });
|
|
2264
3275
|
* ```
|
|
2265
3276
|
*/
|
|
2266
3277
|
getRequestUrl(launchOptions) {
|
|
2267
3278
|
return __async(this, null, function* () {
|
|
2268
3279
|
var _a, _b, _c;
|
|
2269
3280
|
const options = launchOptions || ((_a = this.options) == null ? void 0 : _a.launchOptions) || {};
|
|
2270
|
-
|
|
3281
|
+
const mode = (_b = options.verificationMode) != null ? _b : "portal";
|
|
3282
|
+
logger10.info("Creating Request Url");
|
|
2271
3283
|
if (!this.signature) {
|
|
2272
3284
|
throw new SignatureNotFoundError("Signature is not set.");
|
|
2273
3285
|
}
|
|
2274
3286
|
try {
|
|
2275
3287
|
const templateData = this.getTemplateData();
|
|
2276
3288
|
yield updateSession(this.sessionId, "SESSION_STARTED" /* SESSION_STARTED */);
|
|
2277
|
-
|
|
2278
|
-
if (((_b = this.options) == null ? void 0 : _b.useAppClip) && deviceType === "mobile" /* MOBILE */) {
|
|
3289
|
+
if (mode === "app") {
|
|
2279
3290
|
let template = encodeURIComponent(JSON.stringify(templateData));
|
|
2280
3291
|
template = replaceAll(template, "(", "%28");
|
|
2281
3292
|
template = replaceAll(template, ")", "%29");
|
|
2282
|
-
|
|
2283
|
-
if (!isIos) {
|
|
2284
|
-
let instantAppUrl = this.buildSharePageUrl(template);
|
|
2285
|
-
const isDeferredDeeplinksFlowEnabled = (_c = options.canUseDeferredDeepLinksFlow) != null ? _c : false;
|
|
2286
|
-
if (isDeferredDeeplinksFlowEnabled) {
|
|
2287
|
-
instantAppUrl = instantAppUrl.replace("/verifier", "/link");
|
|
2288
|
-
}
|
|
2289
|
-
logger8.info("Instant App Url created successfully: " + instantAppUrl);
|
|
2290
|
-
return instantAppUrl;
|
|
2291
|
-
} else {
|
|
3293
|
+
if (((_c = this.options) == null ? void 0 : _c.useAppClip) && getDeviceType() === "mobile" /* MOBILE */ && getMobileDeviceType() === "ios" /* IOS */) {
|
|
2292
3294
|
const appClipUrl = this.customAppClipUrl ? `${this.customAppClipUrl}&template=${template}` : `https://appclip.apple.com/id?p=org.reclaimprotocol.app.clip&template=${template}`;
|
|
2293
|
-
|
|
3295
|
+
logger10.info("App Clip Url created successfully: " + appClipUrl);
|
|
2294
3296
|
return appClipUrl;
|
|
2295
3297
|
}
|
|
2296
|
-
|
|
2297
|
-
|
|
2298
|
-
|
|
2299
|
-
return link;
|
|
3298
|
+
const sharePageUrl = yield createLinkWithTemplateData(templateData, "https://share.reclaimprotocol.org/verify");
|
|
3299
|
+
logger10.info("Share page Url created successfully: " + sharePageUrl);
|
|
3300
|
+
return sharePageUrl;
|
|
2300
3301
|
}
|
|
3302
|
+
const link = yield createLinkWithTemplateData(templateData, this.customSharePageUrl);
|
|
3303
|
+
logger10.info("Request Url created successfully: " + link);
|
|
3304
|
+
return link;
|
|
2301
3305
|
} catch (error) {
|
|
2302
|
-
|
|
3306
|
+
logger10.info("Error creating Request Url:", error);
|
|
2303
3307
|
throw error;
|
|
2304
3308
|
}
|
|
2305
3309
|
});
|
|
2306
3310
|
}
|
|
2307
3311
|
/**
|
|
2308
|
-
* Triggers the appropriate Reclaim verification flow based on device type and configuration
|
|
3312
|
+
* Triggers the appropriate Reclaim verification flow based on device type and configuration.
|
|
3313
|
+
*
|
|
3314
|
+
* Defaults to portal mode (remote browser verification). Pass `{ verificationMode: 'app' }`
|
|
3315
|
+
* for native app flow via the share page.
|
|
2309
3316
|
*
|
|
2310
|
-
*
|
|
2311
|
-
* - Desktop
|
|
2312
|
-
* - Desktop
|
|
2313
|
-
* - Mobile
|
|
2314
|
-
* - Mobile
|
|
3317
|
+
* - Desktop: browser extension takes priority in both modes
|
|
3318
|
+
* - Desktop portal mode (no extension): opens portal in new tab
|
|
3319
|
+
* - Desktop app mode (no extension): shows QR code modal with share page URL
|
|
3320
|
+
* - Mobile portal mode: opens portal in new tab
|
|
3321
|
+
* - Mobile app mode: opens share page (or App Clip on iOS if `useAppClip` is `true`)
|
|
2315
3322
|
*
|
|
2316
3323
|
* @param launchOptions - Optional launch configuration to override default behavior
|
|
2317
3324
|
* @returns Promise<void>
|
|
@@ -2319,45 +3326,95 @@ var ReclaimProofRequest = class _ReclaimProofRequest {
|
|
|
2319
3326
|
*
|
|
2320
3327
|
* @example
|
|
2321
3328
|
* ```typescript
|
|
3329
|
+
* // Portal flow (default)
|
|
2322
3330
|
* await proofRequest.triggerReclaimFlow();
|
|
2323
|
-
*
|
|
3331
|
+
*
|
|
3332
|
+
* // Native app flow
|
|
3333
|
+
* await proofRequest.triggerReclaimFlow({ verificationMode: 'app' });
|
|
3334
|
+
*
|
|
3335
|
+
* // App Clip on iOS (requires useAppClip: true at init)
|
|
3336
|
+
* const request = await ReclaimProofRequest.init(APP_ID, SECRET, PROVIDER, { useAppClip: true });
|
|
3337
|
+
* await request.triggerReclaimFlow({ verificationMode: 'app' });
|
|
3338
|
+
*
|
|
3339
|
+
* // Can also set verificationMode at init time via launchOptions
|
|
3340
|
+
* const request = await ReclaimProofRequest.init(APP_ID, SECRET, PROVIDER, {
|
|
3341
|
+
* launchOptions: { verificationMode: 'app' }
|
|
3342
|
+
* });
|
|
3343
|
+
* await request.triggerReclaimFlow(); // uses 'app' mode from init
|
|
2324
3344
|
* ```
|
|
2325
3345
|
*/
|
|
2326
3346
|
triggerReclaimFlow(launchOptions) {
|
|
2327
3347
|
return __async(this, null, function* () {
|
|
2328
|
-
var _a, _b;
|
|
3348
|
+
var _a, _b, _c, _d, _e, _f;
|
|
2329
3349
|
const options = launchOptions || ((_a = this.options) == null ? void 0 : _a.launchOptions) || {};
|
|
3350
|
+
const mode = (_b = options.verificationMode) != null ? _b : "portal";
|
|
2330
3351
|
if (!this.signature) {
|
|
2331
3352
|
throw new SignatureNotFoundError("Signature is not set.");
|
|
2332
3353
|
}
|
|
2333
3354
|
try {
|
|
2334
3355
|
const templateData = this.getTemplateData();
|
|
2335
3356
|
this.templateData = templateData;
|
|
2336
|
-
|
|
3357
|
+
logger10.info(`Triggering Reclaim flow (mode: ${mode})`);
|
|
2337
3358
|
const deviceType = getDeviceType();
|
|
2338
3359
|
updateSession(this.sessionId, "SESSION_STARTED" /* SESSION_STARTED */);
|
|
2339
3360
|
if (deviceType === "desktop" /* DESKTOP */) {
|
|
2340
3361
|
const extensionAvailable = yield this.isBrowserExtensionAvailable();
|
|
2341
|
-
if (((
|
|
2342
|
-
|
|
3362
|
+
if (((_c = this.options) == null ? void 0 : _c.useBrowserExtension) && extensionAvailable) {
|
|
3363
|
+
logger10.info("Triggering browser extension flow");
|
|
2343
3364
|
this.triggerBrowserExtensionFlow();
|
|
2344
3365
|
return;
|
|
3366
|
+
}
|
|
3367
|
+
if (mode === "portal") {
|
|
3368
|
+
const portalUrl = (_d = this.customSharePageUrl) != null ? _d : "https://portal.reclaimprotocol.org";
|
|
3369
|
+
const newTab = window.open("about:blank", "_blank");
|
|
3370
|
+
const link = yield createLinkWithTemplateData(templateData, portalUrl);
|
|
3371
|
+
logger10.info("Opening portal in new tab: " + link);
|
|
3372
|
+
if (newTab) {
|
|
3373
|
+
newTab.location = link;
|
|
3374
|
+
setTimeout(() => {
|
|
3375
|
+
try {
|
|
3376
|
+
if (newTab.location.href === "about:blank") {
|
|
3377
|
+
newTab.close();
|
|
3378
|
+
window.open(link, "_blank");
|
|
3379
|
+
}
|
|
3380
|
+
} catch (_) {
|
|
3381
|
+
}
|
|
3382
|
+
}, 500);
|
|
3383
|
+
}
|
|
2345
3384
|
} else {
|
|
2346
|
-
|
|
2347
|
-
yield this.showQRCodeModal();
|
|
3385
|
+
logger10.info("Showing QR code modal with share page URL");
|
|
3386
|
+
yield this.showQRCodeModal("app");
|
|
2348
3387
|
}
|
|
2349
3388
|
} else if (deviceType === "mobile" /* MOBILE */) {
|
|
2350
|
-
|
|
2351
|
-
|
|
2352
|
-
|
|
2353
|
-
|
|
2354
|
-
|
|
2355
|
-
|
|
2356
|
-
|
|
3389
|
+
if (mode === "app") {
|
|
3390
|
+
if (((_e = this.options) == null ? void 0 : _e.useAppClip) && getMobileDeviceType() === "ios" /* IOS */) {
|
|
3391
|
+
logger10.info("Redirecting to iOS app clip");
|
|
3392
|
+
this.redirectToAppClip();
|
|
3393
|
+
} else {
|
|
3394
|
+
logger10.info("Redirecting to share page");
|
|
3395
|
+
yield this.redirectToInstantApp(options);
|
|
3396
|
+
}
|
|
3397
|
+
} else {
|
|
3398
|
+
const portalUrl = (_f = this.customSharePageUrl) != null ? _f : "https://portal.reclaimprotocol.org";
|
|
3399
|
+
const newTab = window.open("about:blank", "_blank");
|
|
3400
|
+
const link = yield createLinkWithTemplateData(templateData, portalUrl);
|
|
3401
|
+
logger10.info("Opening portal on mobile: " + link);
|
|
3402
|
+
if (newTab) {
|
|
3403
|
+
newTab.location = link;
|
|
3404
|
+
setTimeout(() => {
|
|
3405
|
+
try {
|
|
3406
|
+
if (newTab.location.href === "about:blank") {
|
|
3407
|
+
newTab.close();
|
|
3408
|
+
window.open(link, "_blank");
|
|
3409
|
+
}
|
|
3410
|
+
} catch (_) {
|
|
3411
|
+
}
|
|
3412
|
+
}, 500);
|
|
3413
|
+
}
|
|
2357
3414
|
}
|
|
2358
3415
|
}
|
|
2359
3416
|
} catch (error) {
|
|
2360
|
-
|
|
3417
|
+
logger10.info("Error triggering Reclaim flow:", error);
|
|
2361
3418
|
throw error;
|
|
2362
3419
|
}
|
|
2363
3420
|
});
|
|
@@ -2405,7 +3462,7 @@ var ReclaimProofRequest = class _ReclaimProofRequest {
|
|
|
2405
3462
|
window.postMessage(message, "*");
|
|
2406
3463
|
});
|
|
2407
3464
|
} catch (error) {
|
|
2408
|
-
|
|
3465
|
+
logger10.info("Error checking Reclaim extension installed:", error);
|
|
2409
3466
|
return false;
|
|
2410
3467
|
}
|
|
2411
3468
|
});
|
|
@@ -2418,16 +3475,17 @@ var ReclaimProofRequest = class _ReclaimProofRequest {
|
|
|
2418
3475
|
extensionID: this.extensionID
|
|
2419
3476
|
};
|
|
2420
3477
|
window.postMessage(message, "*");
|
|
2421
|
-
|
|
3478
|
+
logger10.info("Browser extension flow triggered");
|
|
2422
3479
|
}
|
|
2423
|
-
showQRCodeModal() {
|
|
3480
|
+
showQRCodeModal(mode = "portal") {
|
|
2424
3481
|
return __async(this, null, function* () {
|
|
2425
3482
|
try {
|
|
2426
|
-
const
|
|
3483
|
+
const url = mode === "app" ? "https://share.reclaimprotocol.org/verify" : this.customSharePageUrl;
|
|
3484
|
+
const requestUrl = yield createLinkWithTemplateData(this.templateData, url);
|
|
2427
3485
|
this.modal = new QRCodeModal(this.modalOptions);
|
|
2428
3486
|
yield this.modal.show(requestUrl);
|
|
2429
3487
|
} catch (error) {
|
|
2430
|
-
|
|
3488
|
+
logger10.info("Error showing QR code modal:", error);
|
|
2431
3489
|
throw error;
|
|
2432
3490
|
}
|
|
2433
3491
|
});
|
|
@@ -2440,7 +3498,7 @@ var ReclaimProofRequest = class _ReclaimProofRequest {
|
|
|
2440
3498
|
template = replaceAll(template, "(", "%28");
|
|
2441
3499
|
template = replaceAll(template, ")", "%29");
|
|
2442
3500
|
let instantAppUrl = this.buildSharePageUrl(template);
|
|
2443
|
-
|
|
3501
|
+
logger10.info("Redirecting to Android instant app: " + instantAppUrl);
|
|
2444
3502
|
const isDeferredDeeplinksFlowEnabled = (_a = options.canUseDeferredDeepLinksFlow) != null ? _a : false;
|
|
2445
3503
|
if (isDeferredDeeplinksFlowEnabled) {
|
|
2446
3504
|
instantAppUrl = instantAppUrl.replace("/verifier", "/link");
|
|
@@ -2490,7 +3548,7 @@ var ReclaimProofRequest = class _ReclaimProofRequest {
|
|
|
2490
3548
|
}
|
|
2491
3549
|
window.location.href = instantAppUrl;
|
|
2492
3550
|
} catch (error) {
|
|
2493
|
-
|
|
3551
|
+
logger10.info("Error redirecting to instant app:", error);
|
|
2494
3552
|
throw error;
|
|
2495
3553
|
}
|
|
2496
3554
|
});
|
|
@@ -2501,29 +3559,49 @@ var ReclaimProofRequest = class _ReclaimProofRequest {
|
|
|
2501
3559
|
template = replaceAll(template, "(", "%28");
|
|
2502
3560
|
template = replaceAll(template, ")", "%29");
|
|
2503
3561
|
const appClipUrl = this.customAppClipUrl ? `${this.customAppClipUrl}&template=${template}` : `https://appclip.apple.com/id?p=org.reclaimprotocol.app.clip&template=${template}`;
|
|
2504
|
-
|
|
3562
|
+
logger10.info("Redirecting to iOS app clip: " + appClipUrl);
|
|
2505
3563
|
const verifierUrl = `https://share.reclaimprotocol.org/verifier/?template=${template}`;
|
|
2506
3564
|
window.location.href = appClipUrl;
|
|
2507
3565
|
setTimeout(() => {
|
|
2508
3566
|
window.location.href = verifierUrl;
|
|
2509
3567
|
}, 5 * 1e3);
|
|
2510
3568
|
} catch (error) {
|
|
2511
|
-
|
|
3569
|
+
logger10.info("Error redirecting to app clip:", error);
|
|
2512
3570
|
throw error;
|
|
2513
3571
|
}
|
|
2514
3572
|
}
|
|
3573
|
+
/**
|
|
3574
|
+
* Returns the provider id and exact version of the provider that was used in the verification session of this request.
|
|
3575
|
+
*
|
|
3576
|
+
* This can be provided as a config parameter to the `verifyProof` function to verify the proof.
|
|
3577
|
+
*
|
|
3578
|
+
* See also:
|
|
3579
|
+
* * `verifyProof()` - Verifies a proof against the expected provider configuration.
|
|
3580
|
+
* * `getProviderHashRequirements()` - An alternative of this function to get the expected hashes for a provider version by providing providerId and exactProviderVersionString. The result can be provided in verifyProof function's `config` parameter for proof validation.
|
|
3581
|
+
* * `getProviderHashRequirementsFromSpec()` - An alternative of this function to get the expected hashes from a provider spec. The result can be provided in verifyProof function's `config` parameter for proof validation.
|
|
3582
|
+
*/
|
|
3583
|
+
getProviderVersion() {
|
|
3584
|
+
var _a, _b;
|
|
3585
|
+
const exactProviderVersionString = (_a = this.resolvedProviderVersion) != null ? _a : "";
|
|
3586
|
+
return {
|
|
3587
|
+
providerId: this.providerId,
|
|
3588
|
+
providerVersion: exactProviderVersionString,
|
|
3589
|
+
allowedTags: ((_b = this.options) == null ? void 0 : _b.acceptAiProviders) ? ["ai"] : []
|
|
3590
|
+
};
|
|
3591
|
+
}
|
|
2515
3592
|
/**
|
|
2516
3593
|
* Fetches the provider config that was used for this session and returns the hash requirements
|
|
2517
3594
|
*
|
|
2518
3595
|
* See also:
|
|
3596
|
+
* * `verifyProof()` - Verifies a proof against the expected provider configuration.
|
|
2519
3597
|
* * `fetchProviderHashRequirementsBy()` - An alternative of this function to get the expected hashes for a provider version by providing providerId and exactProviderVersionString. The result can be provided in verifyProof function's `config` parameter for proof validation.
|
|
2520
3598
|
* * `getProviderHashRequirementsFromSpec()` - An alternative of this function to get the expected hashes from a provider spec. The result can be provided in verifyProof function's `config` parameter for proof validation.
|
|
2521
3599
|
*
|
|
2522
|
-
* @returns A promise that resolves to a ProviderHashRequirementsConfig
|
|
3600
|
+
* @returns A promise that resolves to a `ProviderHashRequirementsConfig` or `ProviderHashRequirementsConfig[]`
|
|
2523
3601
|
*/
|
|
2524
|
-
getProviderHashRequirements() {
|
|
3602
|
+
getProviderHashRequirements(proofs, allowedTags) {
|
|
2525
3603
|
var _a;
|
|
2526
|
-
return fetchProviderHashRequirementsBy(this.providerId, (_a = this.resolvedProviderVersion) != null ? _a : "");
|
|
3604
|
+
return fetchProviderHashRequirementsBy(this.providerId, (_a = this.resolvedProviderVersion) != null ? _a : "", allowedTags, proofs);
|
|
2527
3605
|
}
|
|
2528
3606
|
/**
|
|
2529
3607
|
* Starts the proof request session and monitors for proof submission
|
|
@@ -2565,16 +3643,16 @@ var ReclaimProofRequest = class _ReclaimProofRequest {
|
|
|
2565
3643
|
* ```
|
|
2566
3644
|
*/
|
|
2567
3645
|
startSession(_0) {
|
|
2568
|
-
return __async(this, arguments, function* ({ onSuccess, onError }) {
|
|
3646
|
+
return __async(this, arguments, function* ({ onSuccess, onError, verificationConfig }) {
|
|
2569
3647
|
if (!this.sessionId) {
|
|
2570
3648
|
const message = "Session can't be started due to undefined value of sessionId";
|
|
2571
|
-
|
|
3649
|
+
logger10.info(message);
|
|
2572
3650
|
throw new SessionNotStartedError(message);
|
|
2573
3651
|
}
|
|
2574
|
-
|
|
3652
|
+
logger10.info("Starting session");
|
|
2575
3653
|
const sessionUpdatePollingInterval = 3 * 1e3;
|
|
2576
3654
|
const interval = setInterval(() => __async(this, null, function* () {
|
|
2577
|
-
var _a, _b, _c;
|
|
3655
|
+
var _a, _b, _c, _d, _e;
|
|
2578
3656
|
try {
|
|
2579
3657
|
const statusUrlResponse = yield fetchStatusUrl(this.sessionId);
|
|
2580
3658
|
if (!statusUrlResponse.session) return;
|
|
@@ -2586,7 +3664,8 @@ var ReclaimProofRequest = class _ReclaimProofRequest {
|
|
|
2586
3664
|
if (!this.lastFailureTime) {
|
|
2587
3665
|
this.lastFailureTime = currentTime;
|
|
2588
3666
|
} else if (currentTime - this.lastFailureTime >= this.FAILURE_TIMEOUT) {
|
|
2589
|
-
|
|
3667
|
+
const errorMessage = ((_a = statusUrlResponse.session.error) == null ? void 0 : _a.message) || "Proof generation failed - timeout reached";
|
|
3668
|
+
throw new ProviderFailedError(errorMessage);
|
|
2590
3669
|
}
|
|
2591
3670
|
return;
|
|
2592
3671
|
}
|
|
@@ -2598,9 +3677,9 @@ var ReclaimProofRequest = class _ReclaimProofRequest {
|
|
|
2598
3677
|
if (statusUrlResponse.session.proofs && statusUrlResponse.session.proofs.length > 0) {
|
|
2599
3678
|
const proofs = statusUrlResponse.session.proofs;
|
|
2600
3679
|
if (this.claimCreationType === "createClaim" /* STANDALONE */) {
|
|
2601
|
-
const verified = yield verifyProof(proofs,
|
|
3680
|
+
const { isVerified: verified } = yield verifyProof(proofs, this.getProviderVersion());
|
|
2602
3681
|
if (!verified) {
|
|
2603
|
-
|
|
3682
|
+
logger10.info(`Proofs not verified: count=${proofs == null ? void 0 : proofs.length}`);
|
|
2604
3683
|
throw new ProofNotVerifiedError();
|
|
2605
3684
|
}
|
|
2606
3685
|
}
|
|
@@ -2610,18 +3689,19 @@ var ReclaimProofRequest = class _ReclaimProofRequest {
|
|
|
2610
3689
|
onSuccess(proofs);
|
|
2611
3690
|
}
|
|
2612
3691
|
this.clearInterval();
|
|
2613
|
-
(
|
|
3692
|
+
(_b = this.modal) == null ? void 0 : _b.close();
|
|
2614
3693
|
}
|
|
2615
3694
|
} else {
|
|
2616
3695
|
if (statusUrlResponse.session.statusV2 === "PROOF_SUBMISSION_FAILED" /* PROOF_SUBMISSION_FAILED */) {
|
|
2617
|
-
|
|
3696
|
+
const errorMessage = ((_c = statusUrlResponse.session.error) == null ? void 0 : _c.message) || "Proof submission failed";
|
|
3697
|
+
throw new ProofSubmissionFailedError(errorMessage);
|
|
2618
3698
|
}
|
|
2619
3699
|
if (statusUrlResponse.session.statusV2 === "PROOF_SUBMITTED" /* PROOF_SUBMITTED */ || statusUrlResponse.session.statusV2 === "AI_PROOF_SUBMITTED" /* AI_PROOF_SUBMITTED */) {
|
|
2620
3700
|
if (onSuccess) {
|
|
2621
3701
|
onSuccess([]);
|
|
2622
3702
|
}
|
|
2623
3703
|
this.clearInterval();
|
|
2624
|
-
(
|
|
3704
|
+
(_d = this.modal) == null ? void 0 : _d.close();
|
|
2625
3705
|
}
|
|
2626
3706
|
}
|
|
2627
3707
|
} catch (e) {
|
|
@@ -2629,7 +3709,7 @@ var ReclaimProofRequest = class _ReclaimProofRequest {
|
|
|
2629
3709
|
onError(e);
|
|
2630
3710
|
}
|
|
2631
3711
|
this.clearInterval();
|
|
2632
|
-
(
|
|
3712
|
+
(_e = this.modal) == null ? void 0 : _e.close();
|
|
2633
3713
|
}
|
|
2634
3714
|
}), sessionUpdatePollingInterval);
|
|
2635
3715
|
this.intervals.set(this.sessionId, interval);
|
|
@@ -2651,7 +3731,7 @@ var ReclaimProofRequest = class _ReclaimProofRequest {
|
|
|
2651
3731
|
closeModal() {
|
|
2652
3732
|
if (this.modal) {
|
|
2653
3733
|
this.modal.close();
|
|
2654
|
-
|
|
3734
|
+
logger10.info("Modal closed by user");
|
|
2655
3735
|
}
|
|
2656
3736
|
}
|
|
2657
3737
|
/**
|
|
@@ -2672,12 +3752,32 @@ var ReclaimProofRequest = class _ReclaimProofRequest {
|
|
|
2672
3752
|
// Annotate the CommonJS export names for ESM import in node:
|
|
2673
3753
|
0 && (module.exports = {
|
|
2674
3754
|
ReclaimProofRequest,
|
|
3755
|
+
assertValidProofsByHash,
|
|
3756
|
+
assertValidateProof,
|
|
3757
|
+
assertVerifiedProof,
|
|
2675
3758
|
clearDeviceCache,
|
|
3759
|
+
createLinkWithTemplateData,
|
|
3760
|
+
fetchProviderConfigs,
|
|
3761
|
+
fetchProviderHashRequirementsBy,
|
|
3762
|
+
fetchStatusUrl,
|
|
3763
|
+
generateSpecsFromRequestSpecTemplate,
|
|
3764
|
+
getAttestors,
|
|
2676
3765
|
getDeviceType,
|
|
3766
|
+
getHttpProviderClaimParamsFromProof,
|
|
2677
3767
|
getMobileDeviceType,
|
|
3768
|
+
getProviderHashRequirementsFromSpec,
|
|
3769
|
+
getShortenedUrl,
|
|
3770
|
+
hashRequestSpec,
|
|
3771
|
+
initSession,
|
|
2678
3772
|
isDesktopDevice,
|
|
3773
|
+
isHttpProviderClaimParams,
|
|
2679
3774
|
isMobileDevice,
|
|
3775
|
+
recoverSignersOfSignedClaim,
|
|
3776
|
+
takePairsWhereValueIsArray,
|
|
3777
|
+
takeTemplateParametersFromProofs,
|
|
2680
3778
|
transformForOnchain,
|
|
2681
|
-
|
|
3779
|
+
updateSession,
|
|
3780
|
+
verifyProof,
|
|
3781
|
+
verifyTeeAttestation
|
|
2682
3782
|
});
|
|
2683
3783
|
//# sourceMappingURL=index.js.map
|