@suveren/gateway 0.7.3 → 0.7.6
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/content/integrations/gmail.json +3 -6
- package/dist/control-plane/index.mjs +294 -62
- package/dist/mcp-server/http.mjs +467 -73
- package/dist/ui/assets/{index-CkWaRck1.css → index-BYVb_0oG.css} +1 -1
- package/dist/ui/assets/index-CsrM6RQr.js +110 -0
- package/dist/ui/index.html +2 -2
- package/node_modules/@hap/core/dist/index.d.mts +258 -9
- package/node_modules/@hap/core/dist/index.d.ts +258 -9
- package/node_modules/@hap/core/dist/index.js +227 -5
- package/node_modules/@hap/core/dist/index.mjs +213 -4
- package/node_modules/@hap/core/package.json +3 -2
- package/node_modules/@hap/core/src/did-key.ts +126 -0
- package/node_modules/@hap/core/src/identity.ts +21 -5
- package/node_modules/@hap/core/src/index.ts +3 -0
- package/node_modules/@hap/core/src/mandate.ts +207 -0
- package/node_modules/@hap/core/src/receipt.ts +74 -0
- package/node_modules/@hap/core/src/types.ts +81 -5
- package/node_modules/@hono/node-server/dist/index.cjs +151 -9
- package/node_modules/@hono/node-server/dist/index.mjs +151 -9
- package/node_modules/@hono/node-server/package.json +1 -1
- package/node_modules/@modelcontextprotocol/sdk/node_modules/body-parser/node_modules/content-type/README.md +2 -0
- package/node_modules/@modelcontextprotocol/sdk/node_modules/body-parser/node_modules/content-type/dist/index.d.ts +20 -0
- package/node_modules/@modelcontextprotocol/sdk/node_modules/body-parser/node_modules/content-type/dist/index.js +20 -14
- package/node_modules/@modelcontextprotocol/sdk/node_modules/body-parser/node_modules/content-type/dist/index.js.map +1 -1
- package/node_modules/@modelcontextprotocol/sdk/node_modules/body-parser/node_modules/content-type/package.json +1 -1
- package/node_modules/@modelcontextprotocol/sdk/node_modules/negotiator/lib/accept.js +54 -0
- package/node_modules/@modelcontextprotocol/sdk/node_modules/negotiator/lib/charset.js +10 -34
- package/node_modules/@modelcontextprotocol/sdk/node_modules/negotiator/lib/encoding.js +9 -30
- package/node_modules/@modelcontextprotocol/sdk/node_modules/negotiator/lib/language.js +15 -36
- package/node_modules/@modelcontextprotocol/sdk/node_modules/negotiator/lib/mediaType.js +16 -134
- package/node_modules/@modelcontextprotocol/sdk/node_modules/negotiator/node_modules/content-type/LICENSE +22 -0
- package/node_modules/@modelcontextprotocol/sdk/node_modules/negotiator/node_modules/content-type/README.md +71 -0
- package/node_modules/@modelcontextprotocol/sdk/node_modules/negotiator/node_modules/content-type/dist/index.d.ts +46 -0
- package/node_modules/@modelcontextprotocol/sdk/node_modules/negotiator/node_modules/content-type/dist/index.js +176 -0
- package/node_modules/@modelcontextprotocol/sdk/node_modules/negotiator/node_modules/content-type/dist/index.js.map +1 -0
- package/node_modules/@modelcontextprotocol/sdk/node_modules/negotiator/node_modules/content-type/package.json +52 -0
- package/node_modules/@modelcontextprotocol/sdk/node_modules/negotiator/package.json +16 -10
- package/node_modules/@modelcontextprotocol/sdk/node_modules/type-is/node_modules/content-type/README.md +2 -0
- package/node_modules/@modelcontextprotocol/sdk/node_modules/type-is/node_modules/content-type/dist/index.d.ts +20 -0
- package/node_modules/@modelcontextprotocol/sdk/node_modules/type-is/node_modules/content-type/dist/index.js +20 -14
- package/node_modules/@modelcontextprotocol/sdk/node_modules/type-is/node_modules/content-type/dist/index.js.map +1 -1
- package/node_modules/@modelcontextprotocol/sdk/node_modules/type-is/node_modules/content-type/package.json +1 -1
- package/node_modules/@types/node/README.md +1 -1
- package/node_modules/@types/node/buffer.buffer.d.ts +5 -5
- package/node_modules/@types/node/crypto.d.ts +2 -2
- package/node_modules/@types/node/http.d.ts +16 -0
- package/node_modules/@types/node/http2.d.ts +10 -2
- package/node_modules/@types/node/package.json +2 -2
- package/node_modules/@types/node/process.d.ts +52 -0
- package/node_modules/@types/node/quic.d.ts +210 -28
- package/node_modules/@types/node/sqlite.d.ts +6 -2
- package/node_modules/@types/node/test.d.ts +36 -0
- package/node_modules/eventsource-parser/dist/index.cjs +2 -2
- package/node_modules/eventsource-parser/dist/index.cjs.map +1 -1
- package/node_modules/eventsource-parser/dist/index.js +2 -2
- package/node_modules/eventsource-parser/dist/index.js.map +1 -1
- package/node_modules/eventsource-parser/package.json +1 -1
- package/node_modules/eventsource-parser/src/parse.ts +4 -2
- package/node_modules/fast-uri/index.js +201 -48
- package/node_modules/fast-uri/lib/schemes.js +9 -4
- package/node_modules/fast-uri/lib/utils.js +388 -91
- package/node_modules/fast-uri/package.json +1 -1
- package/node_modules/fast-uri/test/component-safe-serialization.test.js +105 -0
- package/node_modules/fast-uri/test/equal.test.js +31 -3
- package/node_modules/fast-uri/test/fixtures/uri-js-parse.json +2 -0
- package/node_modules/fast-uri/test/ipv6-canonical.test.js +34 -0
- package/node_modules/fast-uri/test/ipv6-validation.test.js +90 -0
- package/node_modules/fast-uri/test/malformed-percent.test.js +77 -0
- package/node_modules/fast-uri/test/malformed-urn.test.js +61 -0
- package/node_modules/fast-uri/test/parse.test.js +7 -3
- package/node_modules/fast-uri/test/query-fragment-normalization.test.js +33 -0
- package/node_modules/fast-uri/test/reserved-path-normalization.test.js +109 -0
- package/node_modules/fast-uri/test/scheme-validation.test.js +124 -0
- package/node_modules/fast-uri/test/security-normalization.test.js +101 -0
- package/node_modules/fast-uri/test/security.test.js +75 -3
- package/node_modules/fast-uri/test/urn-full-input.test.js +29 -0
- package/node_modules/fast-uri/test/websocket-query-preservation.test.js +24 -0
- package/node_modules/hono/dist/cjs/client/client.js +27 -13
- package/node_modules/hono/dist/cjs/client/utils.js +4 -1
- package/node_modules/hono/dist/cjs/context.js +4 -0
- package/node_modules/hono/dist/cjs/helper/accepts/accepts.js +36 -2
- package/node_modules/hono/dist/cjs/helper/ssg/ssg.js +1 -1
- package/node_modules/hono/dist/cjs/helper/ssg/utils.js +30 -10
- package/node_modules/hono/dist/cjs/jsx/dom/render.js +2 -0
- package/node_modules/hono/dist/cjs/jsx/intrinsic-element/components.js +1 -1
- package/node_modules/hono/dist/cjs/middleware/cache/index.js +1 -1
- package/node_modules/hono/dist/cjs/middleware/cors/index.js +16 -13
- package/node_modules/hono/dist/cjs/middleware/csrf/index.js +1 -1
- package/node_modules/hono/dist/cjs/middleware/etag/digest.js +47 -1
- package/node_modules/hono/dist/cjs/middleware/etag/index.js +3 -3
- package/node_modules/hono/dist/cjs/middleware/pretty-json/index.js +3 -1
- package/node_modules/hono/dist/cjs/middleware/secure-headers/secure-headers.js +6 -3
- package/node_modules/hono/dist/cjs/request.js +8 -4
- package/node_modules/hono/dist/cjs/router/linear-router/router.js +7 -2
- package/node_modules/hono/dist/cjs/router/pattern-router/router.js +3 -9
- package/node_modules/hono/dist/cjs/router/reg-exp-router/node.js +10 -3
- package/node_modules/hono/dist/cjs/router/reg-exp-router/router.js +47 -83
- package/node_modules/hono/dist/cjs/router/reg-exp-router/trie.js +2 -1
- package/node_modules/hono/dist/cjs/router/trie-router/node.js +46 -69
- package/node_modules/hono/dist/cjs/router/trie-router/router.js +3 -11
- package/node_modules/hono/dist/cjs/router/utils.js +27 -0
- package/node_modules/hono/dist/cjs/utils/body.js +15 -3
- package/node_modules/hono/dist/cjs/utils/cookie.js +1 -1
- package/node_modules/hono/dist/cjs/utils/ipaddr.js +5 -3
- package/node_modules/hono/dist/cjs/utils/stream.js +7 -1
- package/node_modules/hono/dist/cjs/utils/url.js +11 -3
- package/node_modules/hono/dist/client/client.js +27 -13
- package/node_modules/hono/dist/client/utils.js +4 -1
- package/node_modules/hono/dist/context.js +4 -0
- package/node_modules/hono/dist/helper/accepts/accepts.js +36 -2
- package/node_modules/hono/dist/helper/ssg/ssg.js +1 -1
- package/node_modules/hono/dist/helper/ssg/utils.js +30 -10
- package/node_modules/hono/dist/jsx/dom/render.js +2 -0
- package/node_modules/hono/dist/jsx/intrinsic-element/components.js +1 -1
- package/node_modules/hono/dist/middleware/cache/index.js +1 -1
- package/node_modules/hono/dist/middleware/cors/index.js +16 -13
- package/node_modules/hono/dist/middleware/csrf/index.js +1 -1
- package/node_modules/hono/dist/middleware/etag/digest.js +47 -1
- package/node_modules/hono/dist/middleware/etag/index.js +3 -3
- package/node_modules/hono/dist/middleware/pretty-json/index.js +3 -1
- package/node_modules/hono/dist/middleware/secure-headers/secure-headers.js +6 -3
- package/node_modules/hono/dist/request.js +8 -4
- package/node_modules/hono/dist/router/linear-router/router.js +7 -2
- package/node_modules/hono/dist/router/pattern-router/router.js +3 -9
- package/node_modules/hono/dist/router/reg-exp-router/node.js +6 -2
- package/node_modules/hono/dist/router/reg-exp-router/router.js +53 -84
- package/node_modules/hono/dist/router/reg-exp-router/trie.js +2 -1
- package/node_modules/hono/dist/router/trie-router/node.js +46 -69
- package/node_modules/hono/dist/router/trie-router/router.js +3 -11
- package/node_modules/hono/dist/router/utils.js +5 -0
- package/node_modules/hono/dist/types/context.d.ts +4 -0
- package/node_modules/hono/dist/types/middleware/secure-headers/permissions-policy.d.ts +3 -3
- package/node_modules/hono/dist/types/router/reg-exp-router/node.d.ts +3 -0
- package/node_modules/hono/dist/types/router/trie-router/node.d.ts +1 -2
- package/node_modules/hono/dist/types/router/trie-router/router.d.ts +0 -1
- package/node_modules/hono/dist/types/router/utils.d.ts +1 -0
- package/node_modules/hono/dist/types/utils/url.d.ts +4 -0
- package/node_modules/hono/dist/utils/body.js +15 -3
- package/node_modules/hono/dist/utils/cookie.js +1 -1
- package/node_modules/hono/dist/utils/ipaddr.js +5 -3
- package/node_modules/hono/dist/utils/stream.js +7 -1
- package/node_modules/hono/dist/utils/url.js +11 -3
- package/node_modules/hono/package.json +1 -1
- package/node_modules/ip-address/README.md +134 -134
- package/node_modules/ip-address/dist/address-error.d.ts +11 -0
- package/node_modules/ip-address/dist/address-error.js.map +1 -1
- package/node_modules/ip-address/dist/ipv4.d.ts +22 -6
- package/node_modules/ip-address/dist/ipv4.js +22 -6
- package/node_modules/ip-address/dist/ipv4.js.map +1 -1
- package/node_modules/ip-address/dist/ipv6.d.ts +10 -3
- package/node_modules/ip-address/dist/ipv6.js +26 -17
- package/node_modules/ip-address/dist/ipv6.js.map +1 -1
- package/node_modules/ip-address/package.json +1 -1
- package/node_modules/is-plain-object/README.md +39 -95
- package/node_modules/is-plain-object/dist/is-plain-object.js +0 -2
- package/node_modules/is-plain-object/is-plain-object.d.ts +6 -1
- package/node_modules/is-plain-object/package.json +8 -34
- package/node_modules/jose/dist/types/jwe/compact/encrypt.d.ts +4 -3
- package/node_modules/jose/dist/types/jwe/flattened/encrypt.d.ts +4 -3
- package/node_modules/jose/dist/types/jwe/general/encrypt.d.ts +4 -3
- package/node_modules/jose/dist/types/jwks/remote.d.ts +4 -4
- package/node_modules/jose/dist/types/jws/general/verify.d.ts +3 -3
- package/node_modules/jose/dist/types/jwt/encrypt.d.ts +12 -17
- package/node_modules/jose/dist/types/jwt/sign.d.ts +8 -14
- package/node_modules/jose/dist/types/jwt/unsecured.d.ts +9 -15
- package/node_modules/jose/dist/types/types.d.ts +4 -2
- package/node_modules/jose/dist/webapi/jwe/compact/encrypt.js +30 -8
- package/node_modules/jose/dist/webapi/jwe/flattened/decrypt.js +8 -4
- package/node_modules/jose/dist/webapi/jwe/flattened/encrypt.js +6 -13
- package/node_modules/jose/dist/webapi/jwe/general/decrypt.js +19 -19
- package/node_modules/jose/dist/webapi/jwe/general/encrypt.js +32 -21
- package/node_modules/jose/dist/webapi/jwk/embedded.js +15 -1
- package/node_modules/jose/dist/webapi/jwk/thumbprint.js +11 -5
- package/node_modules/jose/dist/webapi/jwks/local.js +45 -53
- package/node_modules/jose/dist/webapi/jwks/remote.js +82 -103
- package/node_modules/jose/dist/webapi/jws/compact/sign.js +10 -9
- package/node_modules/jose/dist/webapi/jws/flattened/sign.js +2 -1
- package/node_modules/jose/dist/webapi/jws/flattened/verify.js +8 -7
- package/node_modules/jose/dist/webapi/jws/general/sign.js +5 -3
- package/node_modules/jose/dist/webapi/jws/general/verify.js +51 -21
- package/node_modules/jose/dist/webapi/jwt/decrypt.js +7 -9
- package/node_modules/jose/dist/webapi/jwt/encrypt.js +21 -50
- package/node_modules/jose/dist/webapi/jwt/sign.js +8 -41
- package/node_modules/jose/dist/webapi/jwt/unsecured.js +21 -42
- package/node_modules/jose/dist/webapi/key/generate_key_pair.js +6 -2
- package/node_modules/jose/dist/webapi/key/generate_secret.js +7 -6
- package/node_modules/jose/dist/webapi/key/import.js +16 -12
- package/node_modules/jose/dist/webapi/lib/asn1.js +7 -2
- package/node_modules/jose/dist/webapi/lib/content_encryption.js +7 -15
- package/node_modules/jose/dist/webapi/lib/deflate.js +8 -0
- package/node_modules/jose/dist/webapi/lib/helpers.js +1 -1
- package/node_modules/jose/dist/webapi/lib/jwe_decrypt.js +85 -28
- package/node_modules/jose/dist/webapi/lib/jwe_encrypt.js +45 -13
- package/node_modules/jose/dist/webapi/lib/jwk_metadata.js +20 -0
- package/node_modules/jose/dist/webapi/lib/jws_sign.js +47 -36
- package/node_modules/jose/dist/webapi/lib/jws_verify.js +77 -45
- package/node_modules/jose/dist/webapi/lib/jwt_claims_set.js +82 -47
- package/node_modules/jose/dist/webapi/lib/key.js +24 -9
- package/node_modules/jose/dist/webapi/lib/key_management.js +10 -4
- package/node_modules/jose/dist/webapi/lib/key_options.js +6 -0
- package/node_modules/jose/dist/webapi/lib/options.js +26 -0
- package/node_modules/jose/dist/webapi/lib/type_checks.js +11 -13
- package/node_modules/jose/package.json +1 -1
- package/package.json +2 -2
- package/dist/ui/assets/index-DdJeSfV9.js +0 -110
- package/node_modules/@modelcontextprotocol/sdk/node_modules/negotiator/HISTORY.md +0 -114
|
@@ -31,8 +31,11 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
|
|
|
31
31
|
var index_exports = {};
|
|
32
32
|
__export(index_exports, {
|
|
33
33
|
ContentBindingError: () => ContentBindingError,
|
|
34
|
+
MandateError: () => MandateError,
|
|
35
|
+
approvalSigningBytes: () => approvalSigningBytes,
|
|
34
36
|
attestationId: () => attestationId,
|
|
35
37
|
bindingAppliesTo: () => bindingAppliesTo,
|
|
38
|
+
buildMandateProjection: () => buildMandateProjection,
|
|
36
39
|
canonicalBounds: () => canonicalBounds,
|
|
37
40
|
canonicalContext: () => canonicalContext,
|
|
38
41
|
canonicalFrame: () => canonicalFrame,
|
|
@@ -49,28 +52,38 @@ __export(index_exports, {
|
|
|
49
52
|
computeIntentHash: () => computeIntentHash,
|
|
50
53
|
contentCanonicalBytes: () => contentCanonicalBytes,
|
|
51
54
|
decodeAttestationBlob: () => decodeAttestationBlob,
|
|
55
|
+
decodeDidKey: () => decodeDidKey,
|
|
52
56
|
deriveIdentityLine: () => deriveIdentityLine,
|
|
53
57
|
encodeAttestationBlob: () => encodeAttestationBlob,
|
|
58
|
+
encodeDidKey: () => encodeDidKey,
|
|
54
59
|
frameHash: () => frameHash,
|
|
55
60
|
getAllProfiles: () => getAllProfiles,
|
|
56
61
|
getProfile: () => getProfile,
|
|
57
62
|
intentDisclosureCanonicalBytes: () => intentDisclosureCanonicalBytes,
|
|
58
63
|
isFieldBinding: () => isFieldBinding,
|
|
64
|
+
isKeyBearingDid: () => isKeyBearingDid,
|
|
59
65
|
isV4Attestation: () => isV4Attestation,
|
|
60
66
|
listProfiles: () => listProfiles,
|
|
67
|
+
mandateSigningBytes: () => mandateSigningBytes,
|
|
61
68
|
registerProfile: () => registerProfile,
|
|
62
69
|
selectBoundFields: () => selectBoundFields,
|
|
70
|
+
signApproval: () => signApproval,
|
|
71
|
+
signMandateProjection: () => signMandateProjection,
|
|
63
72
|
validateBoundsParams: () => validateBoundsParams,
|
|
64
73
|
validateContextParams: () => validateContextParams,
|
|
65
74
|
validateFrameParams: () => validateFrameParams,
|
|
66
75
|
validateSubject: () => validateSubject,
|
|
67
76
|
verify: () => verify,
|
|
77
|
+
verifyApproval: () => verifyApproval,
|
|
68
78
|
verifyAttestation: () => verifyAttestation,
|
|
69
79
|
verifyAttestationSignature: () => verifyAttestationSignature,
|
|
70
80
|
verifyAttestationV4: () => verifyAttestationV4,
|
|
71
81
|
verifyBoundsHash: () => verifyBoundsHash,
|
|
72
82
|
verifyContextHash: () => verifyContextHash,
|
|
73
|
-
verifyFrameHash: () => verifyFrameHash
|
|
83
|
+
verifyFrameHash: () => verifyFrameHash,
|
|
84
|
+
verifyOwnerMandate: () => verifyOwnerMandate,
|
|
85
|
+
verifyOwnerMandates: () => verifyOwnerMandates,
|
|
86
|
+
verifyReceiptSignature: () => verifyReceiptSignature
|
|
74
87
|
});
|
|
75
88
|
module.exports = __toCommonJS(index_exports);
|
|
76
89
|
|
|
@@ -227,9 +240,9 @@ function computeIntentDisclosureHash(intentCiphertext, approversFrozen) {
|
|
|
227
240
|
}
|
|
228
241
|
|
|
229
242
|
// src/identity.ts
|
|
230
|
-
function validateSubject(subject) {
|
|
243
|
+
function validateSubject(subject, opts) {
|
|
231
244
|
const errors = [];
|
|
232
|
-
const { did, assurance, method, trust_root, verifier, disclose
|
|
245
|
+
const { did, assurance, method, trust_root, verifier, disclose } = subject;
|
|
233
246
|
if (!did) errors.push("subject.did is required");
|
|
234
247
|
if (assurance === "low") {
|
|
235
248
|
if (method !== "self_declared") errors.push(`low assurance requires method "self_declared", got "${method}"`);
|
|
@@ -242,7 +255,10 @@ function validateSubject(subject) {
|
|
|
242
255
|
} else if (method === "eudi") {
|
|
243
256
|
if (trust_root !== "external") errors.push('eudi requires trust_root "external"');
|
|
244
257
|
if (!verifier) errors.push("eudi requires a verifier");
|
|
245
|
-
if (
|
|
258
|
+
if (opts?.ownerMandates !== void 0) {
|
|
259
|
+
const entry = opts.ownerMandates.find((m) => m.did === did && m.binding === "eudi");
|
|
260
|
+
if (!entry) errors.push('eudi requires an owner_mandates entry with binding "eudi" for this DID');
|
|
261
|
+
}
|
|
246
262
|
} else {
|
|
247
263
|
errors.push(`high assurance requires method "as_vouched" or "eudi", got "${method}"`);
|
|
248
264
|
}
|
|
@@ -945,11 +961,207 @@ function resolveCumulativeFields(request, profile, executionLog, now) {
|
|
|
945
961
|
}
|
|
946
962
|
return errors;
|
|
947
963
|
}
|
|
964
|
+
|
|
965
|
+
// src/did-key.ts
|
|
966
|
+
var B58_ALPHABET = "123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz";
|
|
967
|
+
var B58_MAP = {};
|
|
968
|
+
for (let i = 0; i < B58_ALPHABET.length; i++) B58_MAP[B58_ALPHABET[i]] = i;
|
|
969
|
+
var ED25519_MULTICODEC = Uint8Array.from([237, 1]);
|
|
970
|
+
var ED25519_KEY_BYTES = 32;
|
|
971
|
+
function base58btcEncode(bytes) {
|
|
972
|
+
let zeros = 0;
|
|
973
|
+
while (zeros < bytes.length && bytes[zeros] === 0) zeros++;
|
|
974
|
+
const digits = [];
|
|
975
|
+
for (let i = zeros; i < bytes.length; i++) {
|
|
976
|
+
let carry = bytes[i];
|
|
977
|
+
for (let j = 0; j < digits.length; j++) {
|
|
978
|
+
carry += digits[j] * 256;
|
|
979
|
+
digits[j] = carry % 58;
|
|
980
|
+
carry = carry / 58 | 0;
|
|
981
|
+
}
|
|
982
|
+
while (carry > 0) {
|
|
983
|
+
digits.push(carry % 58);
|
|
984
|
+
carry = carry / 58 | 0;
|
|
985
|
+
}
|
|
986
|
+
}
|
|
987
|
+
let out = "1".repeat(zeros);
|
|
988
|
+
for (let i = digits.length - 1; i >= 0; i--) out += B58_ALPHABET[digits[i]];
|
|
989
|
+
return out;
|
|
990
|
+
}
|
|
991
|
+
function base58btcDecode(s) {
|
|
992
|
+
let zeros = 0;
|
|
993
|
+
while (zeros < s.length && s[zeros] === "1") zeros++;
|
|
994
|
+
const bytes = [];
|
|
995
|
+
for (let i = zeros; i < s.length; i++) {
|
|
996
|
+
const val = B58_MAP[s[i]];
|
|
997
|
+
if (val === void 0) throw new Error(`invalid base58 character "${s[i]}"`);
|
|
998
|
+
let carry = val;
|
|
999
|
+
for (let j = 0; j < bytes.length; j++) {
|
|
1000
|
+
carry += bytes[j] * 58;
|
|
1001
|
+
bytes[j] = carry & 255;
|
|
1002
|
+
carry >>= 8;
|
|
1003
|
+
}
|
|
1004
|
+
while (carry > 0) {
|
|
1005
|
+
bytes.push(carry & 255);
|
|
1006
|
+
carry >>= 8;
|
|
1007
|
+
}
|
|
1008
|
+
}
|
|
1009
|
+
const out = new Uint8Array(zeros + bytes.length);
|
|
1010
|
+
for (let i = 0; i < bytes.length; i++) out[zeros + i] = bytes[bytes.length - 1 - i];
|
|
1011
|
+
return out;
|
|
1012
|
+
}
|
|
1013
|
+
function encodeDidKey(publicKey) {
|
|
1014
|
+
if (publicKey.length !== ED25519_KEY_BYTES) {
|
|
1015
|
+
throw new Error(`INVALID_KEY: expected ${ED25519_KEY_BYTES} bytes, got ${publicKey.length}`);
|
|
1016
|
+
}
|
|
1017
|
+
const prefixed = new Uint8Array(ED25519_MULTICODEC.length + publicKey.length);
|
|
1018
|
+
prefixed.set(ED25519_MULTICODEC, 0);
|
|
1019
|
+
prefixed.set(publicKey, ED25519_MULTICODEC.length);
|
|
1020
|
+
return `did:key:z${base58btcEncode(prefixed)}`;
|
|
1021
|
+
}
|
|
1022
|
+
function decodeDidKey(did) {
|
|
1023
|
+
if (!did.startsWith("did:key:z")) {
|
|
1024
|
+
throw new Error(`NOT_KEY_BEARING: ${JSON.stringify(did)} is not a base58btc did:key`);
|
|
1025
|
+
}
|
|
1026
|
+
let decoded;
|
|
1027
|
+
try {
|
|
1028
|
+
decoded = base58btcDecode(did.slice("did:key:z".length));
|
|
1029
|
+
} catch (err) {
|
|
1030
|
+
throw new Error(`NOT_KEY_BEARING: ${err.message}`);
|
|
1031
|
+
}
|
|
1032
|
+
if (decoded.length !== ED25519_MULTICODEC.length + ED25519_KEY_BYTES || decoded[0] !== ED25519_MULTICODEC[0] || decoded[1] !== ED25519_MULTICODEC[1]) {
|
|
1033
|
+
throw new Error("NOT_KEY_BEARING: not an ed25519-pub multicodec payload");
|
|
1034
|
+
}
|
|
1035
|
+
return decoded.slice(ED25519_MULTICODEC.length);
|
|
1036
|
+
}
|
|
1037
|
+
function isKeyBearingDid(did) {
|
|
1038
|
+
try {
|
|
1039
|
+
decodeDidKey(did);
|
|
1040
|
+
return true;
|
|
1041
|
+
} catch {
|
|
1042
|
+
return false;
|
|
1043
|
+
}
|
|
1044
|
+
}
|
|
1045
|
+
|
|
1046
|
+
// src/mandate.ts
|
|
1047
|
+
var ed2 = __toESM(require("@noble/ed25519"));
|
|
1048
|
+
var MandateError = class extends Error {
|
|
1049
|
+
constructor(code, message) {
|
|
1050
|
+
super(`${code}: ${message}`);
|
|
1051
|
+
this.code = code;
|
|
1052
|
+
this.name = "MandateError";
|
|
1053
|
+
}
|
|
1054
|
+
};
|
|
1055
|
+
function buildMandateProjection(payload, entry) {
|
|
1056
|
+
const { profile_id, bounds_hash, context_hash, execution_context_hash, gate_content_hashes, commitment_mode, expires_at } = payload;
|
|
1057
|
+
if (!bounds_hash || !context_hash || !commitment_mode) {
|
|
1058
|
+
throw new MandateError("MALFORMED_ATTESTATION", "mandate projection requires bounds_hash, context_hash and commitment_mode");
|
|
1059
|
+
}
|
|
1060
|
+
const projection = {
|
|
1061
|
+
typ: "HAP-mandate",
|
|
1062
|
+
version: "0.6",
|
|
1063
|
+
profile_id,
|
|
1064
|
+
owner_did: entry.did,
|
|
1065
|
+
bounds_hash,
|
|
1066
|
+
context_hash,
|
|
1067
|
+
execution_context_hash,
|
|
1068
|
+
gate_content_hashes,
|
|
1069
|
+
commitment_mode,
|
|
1070
|
+
expires_at,
|
|
1071
|
+
nonce: entry.nonce
|
|
1072
|
+
};
|
|
1073
|
+
if (payload.intent_disclosure_hash !== void 0) {
|
|
1074
|
+
projection.intent_disclosure_hash = payload.intent_disclosure_hash;
|
|
1075
|
+
}
|
|
1076
|
+
return projection;
|
|
1077
|
+
}
|
|
1078
|
+
function mandateSigningBytes(projection) {
|
|
1079
|
+
return new TextEncoder().encode(canonicalize(projection));
|
|
1080
|
+
}
|
|
1081
|
+
function approvalSigningBytes(approval) {
|
|
1082
|
+
return new TextEncoder().encode(canonicalize(approval));
|
|
1083
|
+
}
|
|
1084
|
+
function base64urlToBytes(s) {
|
|
1085
|
+
const base64 = s.replace(/-/g, "+").replace(/_/g, "/");
|
|
1086
|
+
const padding = base64.length % 4 === 0 ? "" : "=".repeat(4 - base64.length % 4);
|
|
1087
|
+
return new Uint8Array(Buffer.from(base64 + padding, "base64"));
|
|
1088
|
+
}
|
|
1089
|
+
function bytesToBase64url(bytes) {
|
|
1090
|
+
return Buffer.from(bytes).toString("base64").replace(/\+/g, "-").replace(/\//g, "_").replace(/=+$/, "");
|
|
1091
|
+
}
|
|
1092
|
+
async function signMandateProjection(projection, privateKey) {
|
|
1093
|
+
const sig = await ed2.signAsync(mandateSigningBytes(projection), privateKey);
|
|
1094
|
+
return bytesToBase64url(sig);
|
|
1095
|
+
}
|
|
1096
|
+
async function signApproval(approval, privateKey) {
|
|
1097
|
+
const sig = await ed2.signAsync(approvalSigningBytes(approval), privateKey);
|
|
1098
|
+
return bytesToBase64url(sig);
|
|
1099
|
+
}
|
|
1100
|
+
async function verifyOwnerMandate(attestation, entry) {
|
|
1101
|
+
const owners = attestation.payload.resolved_owners ?? [];
|
|
1102
|
+
if (!owners.includes(entry.did)) {
|
|
1103
|
+
throw new MandateError("OWNER_NOT_RESOLVED", `signing DID ${entry.did} is not in resolved_owners`);
|
|
1104
|
+
}
|
|
1105
|
+
if (entry.alg !== "EdDSA") {
|
|
1106
|
+
throw new MandateError("MANDATE_SIGNATURE_INVALID", `alg ${entry.alg} disagrees with the DID's key type (DID is authoritative)`);
|
|
1107
|
+
}
|
|
1108
|
+
let publicKey;
|
|
1109
|
+
try {
|
|
1110
|
+
publicKey = decodeDidKey(entry.did);
|
|
1111
|
+
} catch (err) {
|
|
1112
|
+
throw new MandateError("NOT_KEY_BEARING", err.message);
|
|
1113
|
+
}
|
|
1114
|
+
const projection = buildMandateProjection(attestation.payload, entry);
|
|
1115
|
+
const ok = await ed2.verifyAsync(base64urlToBytes(entry.signature), mandateSigningBytes(projection), publicKey);
|
|
1116
|
+
if (!ok) {
|
|
1117
|
+
throw new MandateError("MANDATE_SIGNATURE_INVALID", `owner mandate signature by ${entry.did} does not verify`);
|
|
1118
|
+
}
|
|
1119
|
+
}
|
|
1120
|
+
async function verifyOwnerMandates(attestation) {
|
|
1121
|
+
const entries = attestation.payload.owner_mandates ?? [];
|
|
1122
|
+
for (const entry of entries) {
|
|
1123
|
+
await verifyOwnerMandate(attestation, entry);
|
|
1124
|
+
}
|
|
1125
|
+
return entries;
|
|
1126
|
+
}
|
|
1127
|
+
async function verifyApproval(approval, signature, signerDid) {
|
|
1128
|
+
let publicKey;
|
|
1129
|
+
try {
|
|
1130
|
+
publicKey = decodeDidKey(signerDid);
|
|
1131
|
+
} catch (err) {
|
|
1132
|
+
throw new MandateError("NOT_KEY_BEARING", err.message);
|
|
1133
|
+
}
|
|
1134
|
+
const ok = await ed2.verifyAsync(base64urlToBytes(signature), approvalSigningBytes(approval), publicKey);
|
|
1135
|
+
if (!ok) {
|
|
1136
|
+
throw new MandateError("APPROVAL_SIGNATURE_INVALID", `approval signature by ${signerDid} does not verify`);
|
|
1137
|
+
}
|
|
1138
|
+
}
|
|
1139
|
+
|
|
1140
|
+
// src/receipt.ts
|
|
1141
|
+
var ed3 = __toESM(require("@noble/ed25519"));
|
|
1142
|
+
async function verifyReceiptSignature(receipt, publicKeyHex) {
|
|
1143
|
+
const { signature, ...unsigned } = receipt;
|
|
1144
|
+
if (!signature) {
|
|
1145
|
+
throw new Error("INVALID_SIGNATURE: receipt carries no signature");
|
|
1146
|
+
}
|
|
1147
|
+
const bytes = new TextEncoder().encode(canonicalize(unsigned));
|
|
1148
|
+
const base64 = signature.replace(/-/g, "+").replace(/_/g, "/");
|
|
1149
|
+
const padding = base64.length % 4 === 0 ? "" : "=".repeat(4 - base64.length % 4);
|
|
1150
|
+
const sigBytes = new Uint8Array(Buffer.from(base64 + padding, "base64"));
|
|
1151
|
+
const publicKeyBytes = new Uint8Array(Buffer.from(publicKeyHex, "hex"));
|
|
1152
|
+
const ok = await ed3.verifyAsync(sigBytes, bytes, publicKeyBytes).catch(() => false);
|
|
1153
|
+
if (!ok) {
|
|
1154
|
+
throw new Error("INVALID_SIGNATURE: receipt signature verification failed");
|
|
1155
|
+
}
|
|
1156
|
+
}
|
|
948
1157
|
// Annotate the CommonJS export names for ESM import in node:
|
|
949
1158
|
0 && (module.exports = {
|
|
950
1159
|
ContentBindingError,
|
|
1160
|
+
MandateError,
|
|
1161
|
+
approvalSigningBytes,
|
|
951
1162
|
attestationId,
|
|
952
1163
|
bindingAppliesTo,
|
|
1164
|
+
buildMandateProjection,
|
|
953
1165
|
canonicalBounds,
|
|
954
1166
|
canonicalContext,
|
|
955
1167
|
canonicalFrame,
|
|
@@ -966,26 +1178,36 @@ function resolveCumulativeFields(request, profile, executionLog, now) {
|
|
|
966
1178
|
computeIntentHash,
|
|
967
1179
|
contentCanonicalBytes,
|
|
968
1180
|
decodeAttestationBlob,
|
|
1181
|
+
decodeDidKey,
|
|
969
1182
|
deriveIdentityLine,
|
|
970
1183
|
encodeAttestationBlob,
|
|
1184
|
+
encodeDidKey,
|
|
971
1185
|
frameHash,
|
|
972
1186
|
getAllProfiles,
|
|
973
1187
|
getProfile,
|
|
974
1188
|
intentDisclosureCanonicalBytes,
|
|
975
1189
|
isFieldBinding,
|
|
1190
|
+
isKeyBearingDid,
|
|
976
1191
|
isV4Attestation,
|
|
977
1192
|
listProfiles,
|
|
1193
|
+
mandateSigningBytes,
|
|
978
1194
|
registerProfile,
|
|
979
1195
|
selectBoundFields,
|
|
1196
|
+
signApproval,
|
|
1197
|
+
signMandateProjection,
|
|
980
1198
|
validateBoundsParams,
|
|
981
1199
|
validateContextParams,
|
|
982
1200
|
validateFrameParams,
|
|
983
1201
|
validateSubject,
|
|
984
1202
|
verify,
|
|
1203
|
+
verifyApproval,
|
|
985
1204
|
verifyAttestation,
|
|
986
1205
|
verifyAttestationSignature,
|
|
987
1206
|
verifyAttestationV4,
|
|
988
1207
|
verifyBoundsHash,
|
|
989
1208
|
verifyContextHash,
|
|
990
|
-
verifyFrameHash
|
|
1209
|
+
verifyFrameHash,
|
|
1210
|
+
verifyOwnerMandate,
|
|
1211
|
+
verifyOwnerMandates,
|
|
1212
|
+
verifyReceiptSignature
|
|
991
1213
|
});
|
|
@@ -151,9 +151,9 @@ function computeIntentDisclosureHash(intentCiphertext, approversFrozen) {
|
|
|
151
151
|
}
|
|
152
152
|
|
|
153
153
|
// src/identity.ts
|
|
154
|
-
function validateSubject(subject) {
|
|
154
|
+
function validateSubject(subject, opts) {
|
|
155
155
|
const errors = [];
|
|
156
|
-
const { did, assurance, method, trust_root, verifier, disclose
|
|
156
|
+
const { did, assurance, method, trust_root, verifier, disclose } = subject;
|
|
157
157
|
if (!did) errors.push("subject.did is required");
|
|
158
158
|
if (assurance === "low") {
|
|
159
159
|
if (method !== "self_declared") errors.push(`low assurance requires method "self_declared", got "${method}"`);
|
|
@@ -166,7 +166,10 @@ function validateSubject(subject) {
|
|
|
166
166
|
} else if (method === "eudi") {
|
|
167
167
|
if (trust_root !== "external") errors.push('eudi requires trust_root "external"');
|
|
168
168
|
if (!verifier) errors.push("eudi requires a verifier");
|
|
169
|
-
if (
|
|
169
|
+
if (opts?.ownerMandates !== void 0) {
|
|
170
|
+
const entry = opts.ownerMandates.find((m) => m.did === did && m.binding === "eudi");
|
|
171
|
+
if (!entry) errors.push('eudi requires an owner_mandates entry with binding "eudi" for this DID');
|
|
172
|
+
}
|
|
170
173
|
} else {
|
|
171
174
|
errors.push(`high assurance requires method "as_vouched" or "eudi", got "${method}"`);
|
|
172
175
|
}
|
|
@@ -869,10 +872,206 @@ function resolveCumulativeFields(request, profile, executionLog, now) {
|
|
|
869
872
|
}
|
|
870
873
|
return errors;
|
|
871
874
|
}
|
|
875
|
+
|
|
876
|
+
// src/did-key.ts
|
|
877
|
+
var B58_ALPHABET = "123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz";
|
|
878
|
+
var B58_MAP = {};
|
|
879
|
+
for (let i = 0; i < B58_ALPHABET.length; i++) B58_MAP[B58_ALPHABET[i]] = i;
|
|
880
|
+
var ED25519_MULTICODEC = Uint8Array.from([237, 1]);
|
|
881
|
+
var ED25519_KEY_BYTES = 32;
|
|
882
|
+
function base58btcEncode(bytes) {
|
|
883
|
+
let zeros = 0;
|
|
884
|
+
while (zeros < bytes.length && bytes[zeros] === 0) zeros++;
|
|
885
|
+
const digits = [];
|
|
886
|
+
for (let i = zeros; i < bytes.length; i++) {
|
|
887
|
+
let carry = bytes[i];
|
|
888
|
+
for (let j = 0; j < digits.length; j++) {
|
|
889
|
+
carry += digits[j] * 256;
|
|
890
|
+
digits[j] = carry % 58;
|
|
891
|
+
carry = carry / 58 | 0;
|
|
892
|
+
}
|
|
893
|
+
while (carry > 0) {
|
|
894
|
+
digits.push(carry % 58);
|
|
895
|
+
carry = carry / 58 | 0;
|
|
896
|
+
}
|
|
897
|
+
}
|
|
898
|
+
let out = "1".repeat(zeros);
|
|
899
|
+
for (let i = digits.length - 1; i >= 0; i--) out += B58_ALPHABET[digits[i]];
|
|
900
|
+
return out;
|
|
901
|
+
}
|
|
902
|
+
function base58btcDecode(s) {
|
|
903
|
+
let zeros = 0;
|
|
904
|
+
while (zeros < s.length && s[zeros] === "1") zeros++;
|
|
905
|
+
const bytes = [];
|
|
906
|
+
for (let i = zeros; i < s.length; i++) {
|
|
907
|
+
const val = B58_MAP[s[i]];
|
|
908
|
+
if (val === void 0) throw new Error(`invalid base58 character "${s[i]}"`);
|
|
909
|
+
let carry = val;
|
|
910
|
+
for (let j = 0; j < bytes.length; j++) {
|
|
911
|
+
carry += bytes[j] * 58;
|
|
912
|
+
bytes[j] = carry & 255;
|
|
913
|
+
carry >>= 8;
|
|
914
|
+
}
|
|
915
|
+
while (carry > 0) {
|
|
916
|
+
bytes.push(carry & 255);
|
|
917
|
+
carry >>= 8;
|
|
918
|
+
}
|
|
919
|
+
}
|
|
920
|
+
const out = new Uint8Array(zeros + bytes.length);
|
|
921
|
+
for (let i = 0; i < bytes.length; i++) out[zeros + i] = bytes[bytes.length - 1 - i];
|
|
922
|
+
return out;
|
|
923
|
+
}
|
|
924
|
+
function encodeDidKey(publicKey) {
|
|
925
|
+
if (publicKey.length !== ED25519_KEY_BYTES) {
|
|
926
|
+
throw new Error(`INVALID_KEY: expected ${ED25519_KEY_BYTES} bytes, got ${publicKey.length}`);
|
|
927
|
+
}
|
|
928
|
+
const prefixed = new Uint8Array(ED25519_MULTICODEC.length + publicKey.length);
|
|
929
|
+
prefixed.set(ED25519_MULTICODEC, 0);
|
|
930
|
+
prefixed.set(publicKey, ED25519_MULTICODEC.length);
|
|
931
|
+
return `did:key:z${base58btcEncode(prefixed)}`;
|
|
932
|
+
}
|
|
933
|
+
function decodeDidKey(did) {
|
|
934
|
+
if (!did.startsWith("did:key:z")) {
|
|
935
|
+
throw new Error(`NOT_KEY_BEARING: ${JSON.stringify(did)} is not a base58btc did:key`);
|
|
936
|
+
}
|
|
937
|
+
let decoded;
|
|
938
|
+
try {
|
|
939
|
+
decoded = base58btcDecode(did.slice("did:key:z".length));
|
|
940
|
+
} catch (err) {
|
|
941
|
+
throw new Error(`NOT_KEY_BEARING: ${err.message}`);
|
|
942
|
+
}
|
|
943
|
+
if (decoded.length !== ED25519_MULTICODEC.length + ED25519_KEY_BYTES || decoded[0] !== ED25519_MULTICODEC[0] || decoded[1] !== ED25519_MULTICODEC[1]) {
|
|
944
|
+
throw new Error("NOT_KEY_BEARING: not an ed25519-pub multicodec payload");
|
|
945
|
+
}
|
|
946
|
+
return decoded.slice(ED25519_MULTICODEC.length);
|
|
947
|
+
}
|
|
948
|
+
function isKeyBearingDid(did) {
|
|
949
|
+
try {
|
|
950
|
+
decodeDidKey(did);
|
|
951
|
+
return true;
|
|
952
|
+
} catch {
|
|
953
|
+
return false;
|
|
954
|
+
}
|
|
955
|
+
}
|
|
956
|
+
|
|
957
|
+
// src/mandate.ts
|
|
958
|
+
import * as ed2 from "@noble/ed25519";
|
|
959
|
+
var MandateError = class extends Error {
|
|
960
|
+
constructor(code, message) {
|
|
961
|
+
super(`${code}: ${message}`);
|
|
962
|
+
this.code = code;
|
|
963
|
+
this.name = "MandateError";
|
|
964
|
+
}
|
|
965
|
+
};
|
|
966
|
+
function buildMandateProjection(payload, entry) {
|
|
967
|
+
const { profile_id, bounds_hash, context_hash, execution_context_hash, gate_content_hashes, commitment_mode, expires_at } = payload;
|
|
968
|
+
if (!bounds_hash || !context_hash || !commitment_mode) {
|
|
969
|
+
throw new MandateError("MALFORMED_ATTESTATION", "mandate projection requires bounds_hash, context_hash and commitment_mode");
|
|
970
|
+
}
|
|
971
|
+
const projection = {
|
|
972
|
+
typ: "HAP-mandate",
|
|
973
|
+
version: "0.6",
|
|
974
|
+
profile_id,
|
|
975
|
+
owner_did: entry.did,
|
|
976
|
+
bounds_hash,
|
|
977
|
+
context_hash,
|
|
978
|
+
execution_context_hash,
|
|
979
|
+
gate_content_hashes,
|
|
980
|
+
commitment_mode,
|
|
981
|
+
expires_at,
|
|
982
|
+
nonce: entry.nonce
|
|
983
|
+
};
|
|
984
|
+
if (payload.intent_disclosure_hash !== void 0) {
|
|
985
|
+
projection.intent_disclosure_hash = payload.intent_disclosure_hash;
|
|
986
|
+
}
|
|
987
|
+
return projection;
|
|
988
|
+
}
|
|
989
|
+
function mandateSigningBytes(projection) {
|
|
990
|
+
return new TextEncoder().encode(canonicalize(projection));
|
|
991
|
+
}
|
|
992
|
+
function approvalSigningBytes(approval) {
|
|
993
|
+
return new TextEncoder().encode(canonicalize(approval));
|
|
994
|
+
}
|
|
995
|
+
function base64urlToBytes(s) {
|
|
996
|
+
const base64 = s.replace(/-/g, "+").replace(/_/g, "/");
|
|
997
|
+
const padding = base64.length % 4 === 0 ? "" : "=".repeat(4 - base64.length % 4);
|
|
998
|
+
return new Uint8Array(Buffer.from(base64 + padding, "base64"));
|
|
999
|
+
}
|
|
1000
|
+
function bytesToBase64url(bytes) {
|
|
1001
|
+
return Buffer.from(bytes).toString("base64").replace(/\+/g, "-").replace(/\//g, "_").replace(/=+$/, "");
|
|
1002
|
+
}
|
|
1003
|
+
async function signMandateProjection(projection, privateKey) {
|
|
1004
|
+
const sig = await ed2.signAsync(mandateSigningBytes(projection), privateKey);
|
|
1005
|
+
return bytesToBase64url(sig);
|
|
1006
|
+
}
|
|
1007
|
+
async function signApproval(approval, privateKey) {
|
|
1008
|
+
const sig = await ed2.signAsync(approvalSigningBytes(approval), privateKey);
|
|
1009
|
+
return bytesToBase64url(sig);
|
|
1010
|
+
}
|
|
1011
|
+
async function verifyOwnerMandate(attestation, entry) {
|
|
1012
|
+
const owners = attestation.payload.resolved_owners ?? [];
|
|
1013
|
+
if (!owners.includes(entry.did)) {
|
|
1014
|
+
throw new MandateError("OWNER_NOT_RESOLVED", `signing DID ${entry.did} is not in resolved_owners`);
|
|
1015
|
+
}
|
|
1016
|
+
if (entry.alg !== "EdDSA") {
|
|
1017
|
+
throw new MandateError("MANDATE_SIGNATURE_INVALID", `alg ${entry.alg} disagrees with the DID's key type (DID is authoritative)`);
|
|
1018
|
+
}
|
|
1019
|
+
let publicKey;
|
|
1020
|
+
try {
|
|
1021
|
+
publicKey = decodeDidKey(entry.did);
|
|
1022
|
+
} catch (err) {
|
|
1023
|
+
throw new MandateError("NOT_KEY_BEARING", err.message);
|
|
1024
|
+
}
|
|
1025
|
+
const projection = buildMandateProjection(attestation.payload, entry);
|
|
1026
|
+
const ok = await ed2.verifyAsync(base64urlToBytes(entry.signature), mandateSigningBytes(projection), publicKey);
|
|
1027
|
+
if (!ok) {
|
|
1028
|
+
throw new MandateError("MANDATE_SIGNATURE_INVALID", `owner mandate signature by ${entry.did} does not verify`);
|
|
1029
|
+
}
|
|
1030
|
+
}
|
|
1031
|
+
async function verifyOwnerMandates(attestation) {
|
|
1032
|
+
const entries = attestation.payload.owner_mandates ?? [];
|
|
1033
|
+
for (const entry of entries) {
|
|
1034
|
+
await verifyOwnerMandate(attestation, entry);
|
|
1035
|
+
}
|
|
1036
|
+
return entries;
|
|
1037
|
+
}
|
|
1038
|
+
async function verifyApproval(approval, signature, signerDid) {
|
|
1039
|
+
let publicKey;
|
|
1040
|
+
try {
|
|
1041
|
+
publicKey = decodeDidKey(signerDid);
|
|
1042
|
+
} catch (err) {
|
|
1043
|
+
throw new MandateError("NOT_KEY_BEARING", err.message);
|
|
1044
|
+
}
|
|
1045
|
+
const ok = await ed2.verifyAsync(base64urlToBytes(signature), approvalSigningBytes(approval), publicKey);
|
|
1046
|
+
if (!ok) {
|
|
1047
|
+
throw new MandateError("APPROVAL_SIGNATURE_INVALID", `approval signature by ${signerDid} does not verify`);
|
|
1048
|
+
}
|
|
1049
|
+
}
|
|
1050
|
+
|
|
1051
|
+
// src/receipt.ts
|
|
1052
|
+
import * as ed3 from "@noble/ed25519";
|
|
1053
|
+
async function verifyReceiptSignature(receipt, publicKeyHex) {
|
|
1054
|
+
const { signature, ...unsigned } = receipt;
|
|
1055
|
+
if (!signature) {
|
|
1056
|
+
throw new Error("INVALID_SIGNATURE: receipt carries no signature");
|
|
1057
|
+
}
|
|
1058
|
+
const bytes = new TextEncoder().encode(canonicalize(unsigned));
|
|
1059
|
+
const base64 = signature.replace(/-/g, "+").replace(/_/g, "/");
|
|
1060
|
+
const padding = base64.length % 4 === 0 ? "" : "=".repeat(4 - base64.length % 4);
|
|
1061
|
+
const sigBytes = new Uint8Array(Buffer.from(base64 + padding, "base64"));
|
|
1062
|
+
const publicKeyBytes = new Uint8Array(Buffer.from(publicKeyHex, "hex"));
|
|
1063
|
+
const ok = await ed3.verifyAsync(sigBytes, bytes, publicKeyBytes).catch(() => false);
|
|
1064
|
+
if (!ok) {
|
|
1065
|
+
throw new Error("INVALID_SIGNATURE: receipt signature verification failed");
|
|
1066
|
+
}
|
|
1067
|
+
}
|
|
872
1068
|
export {
|
|
873
1069
|
ContentBindingError,
|
|
1070
|
+
MandateError,
|
|
1071
|
+
approvalSigningBytes,
|
|
874
1072
|
attestationId,
|
|
875
1073
|
bindingAppliesTo,
|
|
1074
|
+
buildMandateProjection,
|
|
876
1075
|
canonicalBounds,
|
|
877
1076
|
canonicalContext,
|
|
878
1077
|
canonicalFrame,
|
|
@@ -889,26 +1088,36 @@ export {
|
|
|
889
1088
|
computeIntentHash,
|
|
890
1089
|
contentCanonicalBytes,
|
|
891
1090
|
decodeAttestationBlob,
|
|
1091
|
+
decodeDidKey,
|
|
892
1092
|
deriveIdentityLine,
|
|
893
1093
|
encodeAttestationBlob,
|
|
1094
|
+
encodeDidKey,
|
|
894
1095
|
frameHash,
|
|
895
1096
|
getAllProfiles,
|
|
896
1097
|
getProfile,
|
|
897
1098
|
intentDisclosureCanonicalBytes,
|
|
898
1099
|
isFieldBinding,
|
|
1100
|
+
isKeyBearingDid,
|
|
899
1101
|
isV4Attestation,
|
|
900
1102
|
listProfiles,
|
|
1103
|
+
mandateSigningBytes,
|
|
901
1104
|
registerProfile,
|
|
902
1105
|
selectBoundFields,
|
|
1106
|
+
signApproval,
|
|
1107
|
+
signMandateProjection,
|
|
903
1108
|
validateBoundsParams,
|
|
904
1109
|
validateContextParams,
|
|
905
1110
|
validateFrameParams,
|
|
906
1111
|
validateSubject,
|
|
907
1112
|
verify,
|
|
1113
|
+
verifyApproval,
|
|
908
1114
|
verifyAttestation,
|
|
909
1115
|
verifyAttestationSignature,
|
|
910
1116
|
verifyAttestationV4,
|
|
911
1117
|
verifyBoundsHash,
|
|
912
1118
|
verifyContextHash,
|
|
913
|
-
verifyFrameHash
|
|
1119
|
+
verifyFrameHash,
|
|
1120
|
+
verifyOwnerMandate,
|
|
1121
|
+
verifyOwnerMandates,
|
|
1122
|
+
verifyReceiptSignature
|
|
914
1123
|
};
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@humanagencyp/hap-core",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.9.0",
|
|
4
4
|
"description": "Core types, cryptographic primitives, and verification logic for the Human Agency Protocol",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"repository": {
|
|
@@ -39,5 +39,6 @@
|
|
|
39
39
|
"tsup": "^8.0.0",
|
|
40
40
|
"typescript": "^5.3.0",
|
|
41
41
|
"vitest": "^1.0.0"
|
|
42
|
-
}
|
|
42
|
+
},
|
|
43
|
+
"homepage": "https://humanagencyprotocol.org"
|
|
43
44
|
}
|