@tinycloud/node-sdk 3.6.0-beta.3 → 3.6.0-beta.5
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 +6 -0
- package/dist/{TinyCloudNode-N4mfZI_k.d.cts → TinyCloudNode-B5WCe_ps.d.ts} +3 -250
- package/dist/{TinyCloudNode-N4mfZI_k.d.ts → TinyCloudNode-CIGurdHw.d.cts} +3 -250
- package/dist/{authority-BgZpUFss.d.cts → authority-Beg1WM2U.d.cts} +1 -1
- package/dist/{authority-C670-9su.d.ts → authority-Vh7ike0I.d.ts} +1 -1
- package/dist/core.d.cts +3 -2
- package/dist/core.d.ts +3 -2
- package/dist/credential-pending-store.cjs +401 -0
- package/dist/credential-pending-store.cjs.map +1 -0
- package/dist/credential-pending-store.d.cts +42 -0
- package/dist/credential-pending-store.d.ts +42 -0
- package/dist/credential-pending-store.js +389 -0
- package/dist/credential-pending-store.js.map +1 -0
- package/dist/credentials-core.cjs +309 -0
- package/dist/credentials-core.cjs.map +1 -0
- package/dist/credentials-core.d.cts +337 -0
- package/dist/credentials-core.d.ts +337 -0
- package/dist/credentials-core.js +294 -0
- package/dist/credentials-core.js.map +1 -0
- package/dist/credentials.cjs +746 -0
- package/dist/credentials.cjs.map +1 -0
- package/dist/credentials.d.cts +4 -0
- package/dist/credentials.d.ts +4 -0
- package/dist/credentials.js +732 -0
- package/dist/credentials.js.map +1 -0
- package/dist/delegation-0LKZkmP2.d.cts +251 -0
- package/dist/delegation-0LKZkmP2.d.ts +251 -0
- package/dist/email-proof-Blhdm4ox.d.cts +155 -0
- package/dist/email-proof-Blhdm4ox.d.ts +155 -0
- package/dist/index.d.cts +2 -1
- package/dist/index.d.ts +2 -1
- package/dist/replication/authority.d.cts +3 -2
- package/dist/replication/authority.d.ts +3 -2
- package/package.json +18 -2
|
@@ -0,0 +1,294 @@
|
|
|
1
|
+
// src/credentials/interpreter.ts
|
|
2
|
+
import {
|
|
3
|
+
CredentialError,
|
|
4
|
+
encodeBase64Url,
|
|
5
|
+
holderBindingSigningBytes,
|
|
6
|
+
validateCredentialHolderBinding
|
|
7
|
+
} from "@tinycloud/sdk-core";
|
|
8
|
+
var delay = (ms, signal) => new Promise((resolve, reject) => {
|
|
9
|
+
const timer = setTimeout(resolve, ms);
|
|
10
|
+
signal?.addEventListener("abort", () => {
|
|
11
|
+
clearTimeout(timer);
|
|
12
|
+
reject(new DOMException("Aborted", "AbortError"));
|
|
13
|
+
}, { once: true });
|
|
14
|
+
});
|
|
15
|
+
function mailboxSubject(requirement) {
|
|
16
|
+
const email = requirement.claims.email;
|
|
17
|
+
return typeof email === "string" && email.length > 0 ? Object.freeze({ kind: "email", value: email }) : void 0;
|
|
18
|
+
}
|
|
19
|
+
async function interpretCredentialFlow(input) {
|
|
20
|
+
const steps = new Map(input.descriptor.steps.map((step) => [step.type, step]));
|
|
21
|
+
const completed = /* @__PURE__ */ new Set();
|
|
22
|
+
let lastTransition = "";
|
|
23
|
+
for (; ; ) {
|
|
24
|
+
input.signal?.throwIfAborted();
|
|
25
|
+
const state = await input.transport.state(input.requestId, input.verifier, input.signal);
|
|
26
|
+
if (state.requestId !== input.requestId) throw new CredentialError("REQUEST_SUBSTITUTED", "Credential request identity changed");
|
|
27
|
+
if (state.state === "expired") throw new CredentialError("REQUEST_EXPIRED", "Credential request expired", { state: state.state, correlationId: state.correlationId });
|
|
28
|
+
if (state.state === "canceled") throw new CredentialError("CANCELED", "Credential request was canceled", { state: state.state, correlationId: state.correlationId });
|
|
29
|
+
if (state.state === "issuer_unready") throw new CredentialError("ISSUER_UNREADY", "Credential issuer is not ready", { retryAfterMs: state.retryAfterMs, state: state.state, correlationId: state.correlationId });
|
|
30
|
+
if (state.state === "complete") return;
|
|
31
|
+
if (state.state === "ready_to_issue" || state.state === "issued") {
|
|
32
|
+
if (state.state === "ready_to_issue" && !completed.has("issue")) {
|
|
33
|
+
await input.transport.issue(input.requestId, input.verifier, input.signal);
|
|
34
|
+
completed.add("issue");
|
|
35
|
+
} else await (input.onWait?.() ?? delay(state.retryAfterMs ?? 50, input.signal));
|
|
36
|
+
continue;
|
|
37
|
+
}
|
|
38
|
+
const next = state.nextStep;
|
|
39
|
+
if (!next) {
|
|
40
|
+
await (input.onWait?.() ?? delay(state.retryAfterMs ?? 50, input.signal));
|
|
41
|
+
continue;
|
|
42
|
+
}
|
|
43
|
+
const declared = steps.get(next.type);
|
|
44
|
+
if (next.id !== next.type || !declared || declared.type !== next.type || declared.version !== next.version) throw new CredentialError("REQUEST_SUBSTITUTED", "Server selected an undeclared credential step");
|
|
45
|
+
if (completed.has(next.id) || state.transitionId === lastTransition) {
|
|
46
|
+
await (input.onWait?.() ?? delay(state.retryAfterMs ?? 50, input.signal));
|
|
47
|
+
continue;
|
|
48
|
+
}
|
|
49
|
+
lastTransition = state.transitionId;
|
|
50
|
+
if (next.type === "holder_signature") {
|
|
51
|
+
input.onProgress?.({ state: "signing", stepId: next.id, correlationId: state.correlationId });
|
|
52
|
+
const binding = validateCredentialHolderBinding(await input.transport.holderBinding(input.requestId, input.verifier, input.signal));
|
|
53
|
+
if (binding.requestId !== input.requestId || binding.descriptorDigest !== input.descriptorDigest || binding.requirementDigest !== input.requirementDigest || binding.holderDid !== input.holderDid || binding.issuer !== input.descriptor.issuer.did || binding.issuerKid !== input.descriptor.issuer.kid || binding.profile !== input.descriptor.profile || binding.openerOrigin !== input.openerOrigin || binding.completionOrigin !== input.openerOrigin || binding.audience !== "tinycloud://credentials") throw new CredentialError("REQUEST_SUBSTITUTED", "Holder binding was substituted");
|
|
54
|
+
const bytes = holderBindingSigningBytes(binding);
|
|
55
|
+
let signature = await input.signing.autoSign?.(binding, bytes, input.signal);
|
|
56
|
+
if (signature === void 0) {
|
|
57
|
+
if (!input.signing.requestApproval) throw new CredentialError("SIGNATURE_REJECTED", "OpenKey approval is required");
|
|
58
|
+
try {
|
|
59
|
+
signature = await input.signing.requestApproval(binding, bytes, input.signal);
|
|
60
|
+
} catch (cause) {
|
|
61
|
+
if (cause instanceof CredentialError) throw cause;
|
|
62
|
+
throw new CredentialError("SIGNATURE_REJECTED", "OpenKey approval was rejected", { cause });
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
if (!(signature instanceof Uint8Array) || signature.length === 0) throw new CredentialError("SIGNATURE_REJECTED", "OpenKey signature is invalid");
|
|
66
|
+
await input.transport.submitHolderSignature(input.requestId, input.verifier, encodeBase64Url(signature), input.signal, input.signing.holderKey);
|
|
67
|
+
} else {
|
|
68
|
+
input.onProgress?.({ state: next.type === "collect_input" ? "collecting" : "proving", stepId: next.id, correlationId: state.correlationId });
|
|
69
|
+
const handler = input.handlers?.[next.type];
|
|
70
|
+
const inlineHandler = input.proofHandler;
|
|
71
|
+
if (!handler && !inlineHandler) {
|
|
72
|
+
await (input.onWait?.() ?? delay(state.retryAfterMs ?? 50, input.signal));
|
|
73
|
+
continue;
|
|
74
|
+
}
|
|
75
|
+
if (next.constraints.challengeRequired === true) await input.transport.beginStep(input.requestId, input.verifier, next.type, input.signal);
|
|
76
|
+
if (handler) {
|
|
77
|
+
const proof = await handler({ descriptor: input.descriptor, requirement: input.requirement, stepId: next.id, constraints: next.constraints, signal: input.signal });
|
|
78
|
+
await input.transport.submitStep(input.requestId, input.verifier, next.id, proof, input.signal);
|
|
79
|
+
} else {
|
|
80
|
+
let feedback;
|
|
81
|
+
for (let attempt = 1; ; attempt += 1) {
|
|
82
|
+
const proof = await inlineHandler({
|
|
83
|
+
stepId: next.id,
|
|
84
|
+
constraints: next.constraints,
|
|
85
|
+
display: {
|
|
86
|
+
title: input.descriptor.display.title,
|
|
87
|
+
description: input.descriptor.display.description,
|
|
88
|
+
consent: input.descriptor.display.consent,
|
|
89
|
+
progressLabel: input.descriptor.accessibility.progressLabel,
|
|
90
|
+
errorLiveRegion: input.descriptor.accessibility.errorLiveRegion
|
|
91
|
+
},
|
|
92
|
+
inputs: input.descriptor.inputs.map(({ id, label, schema }) => ({ id, label, schema })),
|
|
93
|
+
...feedback === void 0 ? {} : { feedback },
|
|
94
|
+
signal: input.signal
|
|
95
|
+
});
|
|
96
|
+
try {
|
|
97
|
+
await input.transport.submitStep(input.requestId, input.verifier, next.id, proof, input.signal);
|
|
98
|
+
break;
|
|
99
|
+
} catch (cause) {
|
|
100
|
+
if (!(cause instanceof CredentialError) || cause.code !== "PROOF_REJECTED") throw cause;
|
|
101
|
+
const attemptsRemaining = input.descriptor.lifecycle.maxProofAttempts - attempt;
|
|
102
|
+
if (next.type !== "mailbox_otp" || attemptsRemaining <= 0) throw new CredentialError("VERIFICATION_FAILED", "The proof was not accepted", { state: attemptsRemaining <= 0 ? "proof_attempts_exhausted" : "proof_rejected", cause });
|
|
103
|
+
feedback = { kind: "rejected", attemptsRemaining };
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
completed.add(next.id);
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
// src/credentials/transport.ts
|
|
113
|
+
import {
|
|
114
|
+
CredentialError as CredentialError2,
|
|
115
|
+
canonicalDigest,
|
|
116
|
+
credentialEndpointPath,
|
|
117
|
+
decodeBase64Url,
|
|
118
|
+
encodeBase64Url as encodeBase64Url2,
|
|
119
|
+
holderBindingCanonicalBytes,
|
|
120
|
+
sha256Base64Url,
|
|
121
|
+
validateCredentialHolderBinding as validateCredentialHolderBinding2
|
|
122
|
+
} from "@tinycloud/sdk-core";
|
|
123
|
+
function object(value, label) {
|
|
124
|
+
if (typeof value !== "object" || value === null || Array.isArray(value)) throw new CredentialError2("VERIFICATION_FAILED", `${label} is invalid`);
|
|
125
|
+
return value;
|
|
126
|
+
}
|
|
127
|
+
function opaque(value, label) {
|
|
128
|
+
if (typeof value !== "string" || !/^[A-Za-z0-9_-]{16,128}$/.test(value)) throw new CredentialError2("REQUEST_SUBSTITUTED", `${label} is invalid`);
|
|
129
|
+
return value;
|
|
130
|
+
}
|
|
131
|
+
function timestamp(value, label) {
|
|
132
|
+
if (typeof value !== "string" || !Number.isFinite(Date.parse(value))) throw new CredentialError2("VERIFICATION_FAILED", `${label} is invalid`);
|
|
133
|
+
return new Date(value).toISOString();
|
|
134
|
+
}
|
|
135
|
+
function jwtPayload(credential) {
|
|
136
|
+
const part = credential.split("~", 1)[0]?.split(".")[1];
|
|
137
|
+
if (!part) throw new CredentialError2("VERIFICATION_FAILED", "Issued SD-JWT is invalid");
|
|
138
|
+
try {
|
|
139
|
+
return object(JSON.parse(new TextDecoder().decode(decodeBase64Url(part))), "SD-JWT payload");
|
|
140
|
+
} catch (cause) {
|
|
141
|
+
if (cause instanceof CredentialError2) throw cause;
|
|
142
|
+
throw new CredentialError2("VERIFICATION_FAILED", "Issued SD-JWT is invalid", { cause });
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
var SERVER_CODES = /* @__PURE__ */ new Set(["REQUEST_EXPIRED", "ISSUER_UNREADY", "UNSUPPORTED_PROFILE", "UNSUPPORTED_VERSION", "SIGNATURE_REJECTED"]);
|
|
146
|
+
function serverError(value, response, honorServerRecoverable) {
|
|
147
|
+
if (typeof value !== "object" || value === null || Array.isArray(value)) return void 0;
|
|
148
|
+
const body = value;
|
|
149
|
+
const keys = Object.keys(body).sort();
|
|
150
|
+
if (keys.join(",") !== "code,correlationId,recoverable,state,type" || body.type !== "tinycloud.credentials/error/v1" || typeof body.code !== "string" || typeof body.recoverable !== "boolean" || typeof body.state !== "string" || typeof body.correlationId !== "string") return void 0;
|
|
151
|
+
if (body.code === "PROOF_REJECTED") return body.recoverable ? new CredentialError2("PROOF_REJECTED", "The proof was not accepted", { state: body.state, correlationId: body.correlationId }) : new CredentialError2("VERIFICATION_FAILED", "The proof attempt limit was reached", { state: "proof_attempts_exhausted", correlationId: body.correlationId });
|
|
152
|
+
if (body.code === "RATE_LIMITED") return new CredentialError2("ISSUER_UNREADY", "Too many verification codes were requested", { state: "rate_limited", correlationId: body.correlationId, retryAfterMs: Number(response.headers.get("retry-after")) * 1e3 || void 0, recoverable: honorServerRecoverable ? body.recoverable : void 0 });
|
|
153
|
+
if (body.code === "CHALLENGE_EXPIRED") return new CredentialError2("REQUEST_EXPIRED", "The credential challenge expired", { state: body.state, correlationId: body.correlationId, recoverable: honorServerRecoverable ? body.recoverable : void 0 });
|
|
154
|
+
if (!SERVER_CODES.has(body.code)) return void 0;
|
|
155
|
+
const code = body.code;
|
|
156
|
+
return new CredentialError2(code, `OpenCredentials rejected the request: ${code}`, {
|
|
157
|
+
state: body.state,
|
|
158
|
+
correlationId: body.correlationId,
|
|
159
|
+
retryAfterMs: Number(response.headers.get("retry-after")) * 1e3 || void 0,
|
|
160
|
+
recoverable: honorServerRecoverable ? body.recoverable : void 0
|
|
161
|
+
});
|
|
162
|
+
}
|
|
163
|
+
var OpenCredentialsHttpTransport = class {
|
|
164
|
+
constructor(descriptor, fetchFn = globalThis.fetch.bind(globalThis), options = {}) {
|
|
165
|
+
this.descriptor = descriptor;
|
|
166
|
+
this.fetchFn = fetchFn;
|
|
167
|
+
this.options = options;
|
|
168
|
+
this.nonces = /* @__PURE__ */ new Map();
|
|
169
|
+
this.bindings = /* @__PURE__ */ new Map();
|
|
170
|
+
}
|
|
171
|
+
url(endpoint, id) {
|
|
172
|
+
return new URL(credentialEndpointPath(endpoint, id), this.descriptor.issuer.origin).href;
|
|
173
|
+
}
|
|
174
|
+
async request(endpoint, input) {
|
|
175
|
+
let response;
|
|
176
|
+
try {
|
|
177
|
+
const init = { method: input.method ?? "GET", credentials: "omit", cache: "no-store", redirect: "error", referrerPolicy: "no-referrer", signal: input.signal, headers: { accept: "application/json", ...input.body === void 0 ? {} : { "content-type": "application/json" }, ...input.verifier === void 0 ? {} : { authorization: `Bearer ${input.verifier}` } }, ...input.body === void 0 ? {} : { body: JSON.stringify(input.body) } };
|
|
178
|
+
response = await this.fetchFn(this.url(endpoint, input.id), init);
|
|
179
|
+
} catch (cause) {
|
|
180
|
+
if (cause instanceof DOMException && cause.name === "AbortError") throw new CredentialError2("CANCELED", "Credential acquisition was canceled", { cause });
|
|
181
|
+
throw new CredentialError2("OFFLINE", "OpenCredentials is unavailable", { cause });
|
|
182
|
+
}
|
|
183
|
+
if (!response.ok) {
|
|
184
|
+
let parsed;
|
|
185
|
+
try {
|
|
186
|
+
parsed = await response.json();
|
|
187
|
+
} catch {
|
|
188
|
+
parsed = void 0;
|
|
189
|
+
}
|
|
190
|
+
const typed = serverError(parsed, response, this.options.honorServerRecoverable === true);
|
|
191
|
+
if (typed) throw typed;
|
|
192
|
+
if (response.status === 410) throw new CredentialError2("REQUEST_EXPIRED", "Credential request expired");
|
|
193
|
+
if (response.status === 409) throw new CredentialError2("REQUEST_SUBSTITUTED", "Credential request was replayed or substituted");
|
|
194
|
+
if (response.status === 503) throw new CredentialError2("ISSUER_UNREADY", "Credential issuer is not ready", { retryAfterMs: Number(response.headers.get("retry-after")) * 1e3 || void 0 });
|
|
195
|
+
throw new CredentialError2("VERIFICATION_FAILED", "OpenCredentials rejected the request");
|
|
196
|
+
}
|
|
197
|
+
if (response.status === 204) return void 0;
|
|
198
|
+
try {
|
|
199
|
+
return await response.json();
|
|
200
|
+
} catch (cause) {
|
|
201
|
+
throw new CredentialError2("VERIFICATION_FAILED", "OpenCredentials response is invalid", { cause });
|
|
202
|
+
}
|
|
203
|
+
}
|
|
204
|
+
async create(input) {
|
|
205
|
+
const body = object(await this.request("request", { method: "POST", body: { protocol: input.descriptor.protocol, profile: input.descriptor.profile, profileVersion: input.descriptor.profileVersion, descriptorDigest: input.descriptorDigest, requirementDigest: input.requirementDigest, holderDid: input.holderDid, inputs: input.inputs ?? input.requirement.claims, audience: "tinycloud://credentials", openerOrigin: input.openerOrigin, completionOrigin: input.openerOrigin, completionContext: "sdk-acquisition", completionVerifierChallenge: input.completionVerifierChallenge }, signal: input.signal }), "create response");
|
|
206
|
+
if (body.type !== "tinycloud.credentials/acquisition-request/v1" || body.protocol !== input.descriptor.protocol || body.next !== "challenge" || body.endpoint !== "challenge") throw new CredentialError2("VERIFICATION_FAILED", "create response is invalid");
|
|
207
|
+
const requestId = opaque(body.requestId, "requestId");
|
|
208
|
+
return { requestId, locator: requestId, expiresAt: timestamp(body.expiresAt, "expiresAt"), correlationId: requestId };
|
|
209
|
+
}
|
|
210
|
+
proofStep() {
|
|
211
|
+
return this.descriptor.steps.some((step) => step.type === "mailbox_otp") ? "mailbox_otp" : "collect_input";
|
|
212
|
+
}
|
|
213
|
+
async state(id, verifier, signal) {
|
|
214
|
+
const raw = object(await this.request("state", { id, verifier, signal }), "state response");
|
|
215
|
+
if (raw.type !== "tinycloud.credentials/acquisition-state/v1" || raw.requestId !== id || raw.profile !== this.descriptor.profile || raw.profileVersion !== 1) throw new CredentialError2("REQUEST_SUBSTITUTED", "Credential state response is substituted");
|
|
216
|
+
const base = { type: "OpenCredentialsAcquisitionState", version: 1, requestId: id, transitionId: `${String(raw.state)}:${String(raw.resultPreviouslyRead ?? false)}`, correlationId: id };
|
|
217
|
+
if (raw.state === "challenge_required") {
|
|
218
|
+
const type = this.proofStep();
|
|
219
|
+
return { ...base, state: "pending", nextStep: { id: type, type, version: 1, constraints: { challengeRequired: true } } };
|
|
220
|
+
}
|
|
221
|
+
if (raw.state === "proof_required") {
|
|
222
|
+
const type = this.proofStep();
|
|
223
|
+
this.nonces.set(id, opaque(raw.challengeNonce, "challengeNonce"));
|
|
224
|
+
return { ...base, state: "pending", nextStep: { id: type, type, version: 1, constraints: {} } };
|
|
225
|
+
}
|
|
226
|
+
if (raw.state === "holder_binding_required" || raw.state === "holder_signature_required") return { ...base, state: "pending", nextStep: { id: "holder_signature", type: "holder_signature", version: 1, constraints: {} } };
|
|
227
|
+
if (raw.state === "ready_to_issue") return { ...base, state: "ready_to_issue" };
|
|
228
|
+
if (raw.state === "issued") return { ...base, state: "complete" };
|
|
229
|
+
throw new CredentialError2("REQUEST_SUBSTITUTED", "Credential state is unsupported");
|
|
230
|
+
}
|
|
231
|
+
async beginStep(id, verifier, stepId, signal) {
|
|
232
|
+
const step = this.proofStep();
|
|
233
|
+
if (stepId !== step) throw new CredentialError2("REQUEST_SUBSTITUTED", "Credential challenge step is substituted");
|
|
234
|
+
const challenge = object(await this.request("challenge", { id, verifier, method: "POST", body: { step, stepVersion: 1 }, signal }), "challenge response");
|
|
235
|
+
if (challenge.type !== "tinycloud.credentials/challenge/v1" || challenge.step !== step || challenge.stepVersion !== 1) throw new CredentialError2("REQUEST_SUBSTITUTED", "Credential challenge is substituted");
|
|
236
|
+
this.nonces.set(id, opaque(challenge.challengeNonce, "challengeNonce"));
|
|
237
|
+
}
|
|
238
|
+
async submitStep(id, verifier, stepId, proof, signal) {
|
|
239
|
+
const step = this.proofStep();
|
|
240
|
+
if (stepId !== step) throw new CredentialError2("REQUEST_SUBSTITUTED", "Credential proof step is substituted");
|
|
241
|
+
const nonce = this.nonces.get(id);
|
|
242
|
+
if (!nonce) throw new CredentialError2("REQUEST_SUBSTITUTED", "Credential challenge is missing");
|
|
243
|
+
await this.request("proof", { id, verifier, method: "POST", body: { step, stepVersion: 1, challengeNonce: nonce, proof }, signal });
|
|
244
|
+
}
|
|
245
|
+
async holderBinding(id, verifier, signal) {
|
|
246
|
+
const raw = object(await this.request("holder_binding", { id, verifier, signal }), "holder binding response");
|
|
247
|
+
if (raw.type !== "tinycloud.credentials/holder-binding-request/v1" || raw.signingDomain !== "tinycloud.credentials/holder-binding/v1" || raw.alg !== "EdDSA" || typeof raw.canonical !== "string") throw new CredentialError2("REQUEST_SUBSTITUTED", "Holder binding response is invalid");
|
|
248
|
+
const binding = validateCredentialHolderBinding2(raw.binding);
|
|
249
|
+
if (encodeBase64Url2(holderBindingCanonicalBytes(binding)) !== raw.canonical) throw new CredentialError2("REQUEST_SUBSTITUTED", "Holder binding canonical bytes were substituted");
|
|
250
|
+
this.bindings.set(id, binding);
|
|
251
|
+
return binding;
|
|
252
|
+
}
|
|
253
|
+
async submitHolderSignature(id, verifier, signature, signal, key) {
|
|
254
|
+
const binding = this.bindings.get(id);
|
|
255
|
+
if (!binding) throw new CredentialError2("REQUEST_SUBSTITUTED", "Holder binding was not retrieved");
|
|
256
|
+
const kid = key?.kid ?? `${binding.holderDid}#${binding.holderDid.replace("did:key:", "")}`;
|
|
257
|
+
await this.request("holder_signature", { id, verifier, method: "POST", body: { alg: key?.alg ?? "EdDSA", kid, signature }, signal });
|
|
258
|
+
}
|
|
259
|
+
async issue(id, verifier, signal) {
|
|
260
|
+
await this.request("issue", { id, verifier, method: "POST", signal });
|
|
261
|
+
}
|
|
262
|
+
async result(id, verifier, signal) {
|
|
263
|
+
const raw = object(await this.request("result", { id, verifier, signal }), "result response");
|
|
264
|
+
if (raw.type !== "tinycloud.credentials/result/v1" || raw.protocol !== this.descriptor.protocol || raw.profile !== this.descriptor.profile || raw.profileVersion !== 1 || raw.format !== "vc+sd-jwt" || raw.descriptorDigest !== await canonicalDigest(this.descriptor) || raw.issuer !== this.descriptor.issuer.did || raw.issuerKid !== this.descriptor.issuer.kid || typeof raw.credential !== "string" || await sha256Base64Url(raw.credential) !== raw.credentialDigest) throw new CredentialError2("VERIFICATION_FAILED", "Issued result metadata is invalid");
|
|
265
|
+
const holder = object(raw.holderBinding, "result holder binding");
|
|
266
|
+
if (raw.subject !== holder.did || holder.signingDomain !== "tinycloud.credentials/holder-binding/v1") throw new CredentialError2("HOLDER_MISMATCH", "Issued holder binding is invalid");
|
|
267
|
+
const claimsRaw = object(raw.claims, "result claims");
|
|
268
|
+
const claims = {};
|
|
269
|
+
for (const [name, value] of Object.entries(claimsRaw)) {
|
|
270
|
+
if (typeof value !== "string") throw new CredentialError2("VERIFICATION_FAILED", "Issued claims are invalid");
|
|
271
|
+
claims[name] = value;
|
|
272
|
+
}
|
|
273
|
+
const validity = object(raw.validity, "result validity");
|
|
274
|
+
const payload = jwtPayload(raw.credential);
|
|
275
|
+
if (typeof payload.jti !== "string") throw new CredentialError2("VERIFICATION_FAILED", "Credential id is invalid");
|
|
276
|
+
const issuedAt = timestamp(validity.issuedAt, "issuedAt");
|
|
277
|
+
const expiresAt = timestamp(validity.expiresAt, "expiresAt");
|
|
278
|
+
const status = object(raw.status, "result status");
|
|
279
|
+
if (status.type !== "none" || status.freshnessSeconds !== this.descriptor.status.freshnessSeconds) throw new CredentialError2("VERIFICATION_FAILED", "Credential status is invalid");
|
|
280
|
+
return { type: "OpenCredentialsIssuedCredential", version: 1, protocol: this.descriptor.protocol, profile: { id: this.descriptor.profile, version: 1 }, credentialType: { id: this.descriptor.format.vct, version: 1 }, schema: this.descriptor.format.vct, format: "vc+sd-jwt", issuerDid: raw.issuer, issuerKid: raw.issuerKid, subjectDid: raw.subject, holderDid: raw.subject, claims, claimsDigest: await canonicalDigest(claims), descriptorDigest: raw.descriptorDigest, credentialId: payload.jti, issuedAt, notBefore: issuedAt, expiresAt, status: { method: "none", freshnessSeconds: status.freshnessSeconds }, credential: raw.credential };
|
|
281
|
+
}
|
|
282
|
+
async issuerMetadata(signal) {
|
|
283
|
+
return await this.request("issuer_metadata", { signal });
|
|
284
|
+
}
|
|
285
|
+
async checkStatus(status, _signal) {
|
|
286
|
+
return status.method === "none" && status.freshnessSeconds === this.descriptor.status.freshnessSeconds;
|
|
287
|
+
}
|
|
288
|
+
};
|
|
289
|
+
export {
|
|
290
|
+
OpenCredentialsHttpTransport,
|
|
291
|
+
interpretCredentialFlow,
|
|
292
|
+
mailboxSubject
|
|
293
|
+
};
|
|
294
|
+
//# sourceMappingURL=credentials-core.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/credentials/interpreter.ts","../src/credentials/transport.ts"],"sourcesContent":["import {\n CredentialError,\n encodeBase64Url,\n holderBindingSigningBytes,\n validateCredentialHolderBinding,\n type CredentialFlowDescriptor,\n type CredentialProgressEvent,\n type CredentialRequirement,\n} from \"@tinycloud/sdk-core\";\nimport type { CredentialAcquisitionTransport, CredentialProofSubject, CredentialSigningAdapter, InlineCredentialProofHandler, InlineCredentialProofRequest, PrimitiveStepHandler } from \"./types\";\n\nconst delay = (ms: number, signal?: AbortSignal) => new Promise<void>((resolve, reject) => {\n const timer = setTimeout(resolve, ms);\n signal?.addEventListener(\"abort\", () => { clearTimeout(timer); reject(new DOMException(\"Aborted\", \"AbortError\")); }, { once: true });\n});\n\n/** The mailbox named by an email requirement, which the issuer delivers the code to. */\nexport function mailboxSubject(requirement: CredentialRequirement): CredentialProofSubject | undefined {\n const email = requirement.claims.email;\n return typeof email === \"string\" && email.length > 0 ? Object.freeze({ kind: \"email\" as const, value: email }) : undefined;\n}\n\n/** Finite step interpreter. Dispatch is exclusively by registered primitive and version. */\nexport async function interpretCredentialFlow(input: {\n readonly descriptor: CredentialFlowDescriptor;\n readonly requirement: CredentialRequirement;\n readonly requestId: string;\n readonly verifier: string;\n readonly holderDid: string;\n readonly descriptorDigest: string;\n readonly requirementDigest: string;\n readonly openerOrigin: string;\n readonly transport: CredentialAcquisitionTransport;\n readonly signing: CredentialSigningAdapter;\n /**\n * Fallback for a host-owned surface. It receives every declared proof step,\n * including primitives added by a later protocol version.\n */\n readonly proofHandler?: InlineCredentialProofHandler;\n readonly handlers?: Partial<Record<\"collect_input\" | \"mailbox_otp\", PrimitiveStepHandler>>;\n readonly signal?: AbortSignal;\n readonly onProgress?: (event: CredentialProgressEvent) => void;\n readonly onWait?: () => Promise<void>;\n}): Promise<void> {\n const steps = new Map(input.descriptor.steps.map((step) => [step.type, step]));\n const completed = new Set<string>(); let lastTransition = \"\";\n for (;;) {\n input.signal?.throwIfAborted();\n const state = await input.transport.state(input.requestId, input.verifier, input.signal);\n if (state.requestId !== input.requestId) throw new CredentialError(\"REQUEST_SUBSTITUTED\", \"Credential request identity changed\");\n if (state.state === \"expired\") throw new CredentialError(\"REQUEST_EXPIRED\", \"Credential request expired\", { state: state.state, correlationId: state.correlationId });\n if (state.state === \"canceled\") throw new CredentialError(\"CANCELED\", \"Credential request was canceled\", { state: state.state, correlationId: state.correlationId });\n if (state.state === \"issuer_unready\") throw new CredentialError(\"ISSUER_UNREADY\", \"Credential issuer is not ready\", { retryAfterMs: state.retryAfterMs, state: state.state, correlationId: state.correlationId });\n if (state.state === \"complete\") return;\n if (state.state === \"ready_to_issue\" || state.state === \"issued\") {\n if (state.state === \"ready_to_issue\" && !completed.has(\"issue\")) { await input.transport.issue(input.requestId, input.verifier, input.signal); completed.add(\"issue\"); }\n else await (input.onWait?.() ?? delay(state.retryAfterMs ?? 50, input.signal));\n continue;\n }\n const next = state.nextStep;\n if (!next) { await (input.onWait?.() ?? delay(state.retryAfterMs ?? 50, input.signal)); continue; }\n const declared = steps.get(next.type);\n if (next.id !== next.type || !declared || declared.type !== next.type || declared.version !== next.version) throw new CredentialError(\"REQUEST_SUBSTITUTED\", \"Server selected an undeclared credential step\");\n if (completed.has(next.id) || state.transitionId === lastTransition) { await (input.onWait?.() ?? delay(state.retryAfterMs ?? 50, input.signal)); continue; }\n lastTransition = state.transitionId;\n if (next.type === \"holder_signature\") {\n input.onProgress?.({ state: \"signing\", stepId: next.id, correlationId: state.correlationId });\n const binding = validateCredentialHolderBinding(await input.transport.holderBinding(input.requestId, input.verifier, input.signal));\n if (binding.requestId !== input.requestId || binding.descriptorDigest !== input.descriptorDigest || binding.requirementDigest !== input.requirementDigest || binding.holderDid !== input.holderDid || binding.issuer !== input.descriptor.issuer.did || binding.issuerKid !== input.descriptor.issuer.kid || binding.profile !== input.descriptor.profile || binding.openerOrigin !== input.openerOrigin || binding.completionOrigin !== input.openerOrigin || binding.audience !== \"tinycloud://credentials\") throw new CredentialError(\"REQUEST_SUBSTITUTED\", \"Holder binding was substituted\");\n const bytes = holderBindingSigningBytes(binding);\n let signature = await input.signing.autoSign?.(binding, bytes, input.signal);\n if (signature === undefined) {\n if (!input.signing.requestApproval) throw new CredentialError(\"SIGNATURE_REJECTED\", \"OpenKey approval is required\");\n try { signature = await input.signing.requestApproval(binding, bytes, input.signal); } catch (cause) { if (cause instanceof CredentialError) throw cause; throw new CredentialError(\"SIGNATURE_REJECTED\", \"OpenKey approval was rejected\", { cause }); }\n }\n if (!(signature instanceof Uint8Array) || signature.length === 0) throw new CredentialError(\"SIGNATURE_REJECTED\", \"OpenKey signature is invalid\");\n await input.transport.submitHolderSignature(input.requestId, input.verifier, encodeBase64Url(signature), input.signal, input.signing.holderKey);\n } else {\n input.onProgress?.({ state: next.type === \"collect_input\" ? \"collecting\" : \"proving\", stepId: next.id, correlationId: state.correlationId });\n const handler = input.handlers?.[next.type];\n const inlineHandler = input.proofHandler;\n if (!handler && !inlineHandler) { await (input.onWait?.() ?? delay(state.retryAfterMs ?? 50, input.signal)); continue; }\n if (next.constraints.challengeRequired === true) await input.transport.beginStep(input.requestId, input.verifier, next.type, input.signal);\n if (handler) {\n const proof = await handler({ descriptor: input.descriptor, requirement: input.requirement, stepId: next.id, constraints: next.constraints, signal: input.signal });\n await input.transport.submitStep(input.requestId, input.verifier, next.id, proof, input.signal);\n } else {\n let feedback: InlineCredentialProofRequest[\"feedback\"];\n // A mistyped code is re-entered against the same challenge; the issuer\n // counts every attempt and reports when the bounded budget is spent.\n for (let attempt = 1; ; attempt += 1) {\n const proof = await inlineHandler!({\n stepId: next.id,\n constraints: next.constraints,\n display: {\n title: input.descriptor.display.title,\n description: input.descriptor.display.description,\n consent: input.descriptor.display.consent,\n progressLabel: input.descriptor.accessibility.progressLabel,\n errorLiveRegion: input.descriptor.accessibility.errorLiveRegion,\n },\n inputs: input.descriptor.inputs.map(({ id, label, schema }) => ({ id, label, schema })),\n ...(feedback === undefined ? {} : { feedback }),\n signal: input.signal,\n });\n try {\n await input.transport.submitStep(input.requestId, input.verifier, next.id, proof, input.signal);\n break;\n } catch (cause) {\n if (!(cause instanceof CredentialError) || cause.code !== \"PROOF_REJECTED\") throw cause;\n const attemptsRemaining = input.descriptor.lifecycle.maxProofAttempts - attempt;\n // Once this view stops re-prompting, the rejection is final: a\n // host must not silently start a new acquisition on its behalf.\n if (next.type !== \"mailbox_otp\" || attemptsRemaining <= 0) throw new CredentialError(\"VERIFICATION_FAILED\", \"The proof was not accepted\", { state: attemptsRemaining <= 0 ? \"proof_attempts_exhausted\" : \"proof_rejected\", cause });\n feedback = { kind: \"rejected\", attemptsRemaining };\n }\n }\n }\n }\n completed.add(next.id);\n }\n}\n","import {\n CredentialError, canonicalDigest, credentialEndpointPath, decodeBase64Url, encodeBase64Url,\n holderBindingCanonicalBytes, sha256Base64Url, validateCredentialHolderBinding,\n type CredentialFlowDescriptor, type CredentialHolderBinding, type CredentialIssuerMetadata,\n type CredentialRequirement, type IssuedCredentialEnvelope,\n} from \"@tinycloud/sdk-core\";\nimport type { CredentialAcquisitionTransport, CredentialRequestState, HolderSignatureKey, PrimitiveStepResult } from \"./types\";\n\nfunction object(value: unknown, label: string): Record<string, unknown> { if (typeof value !== \"object\" || value === null || Array.isArray(value)) throw new CredentialError(\"VERIFICATION_FAILED\", `${label} is invalid`); return value as Record<string, unknown>; }\nfunction opaque(value: unknown, label: string): string { if (typeof value !== \"string\" || !/^[A-Za-z0-9_-]{16,128}$/.test(value)) throw new CredentialError(\"REQUEST_SUBSTITUTED\", `${label} is invalid`); return value; }\nfunction timestamp(value: unknown, label: string): string { if (typeof value !== \"string\" || !Number.isFinite(Date.parse(value))) throw new CredentialError(\"VERIFICATION_FAILED\", `${label} is invalid`); return new Date(value).toISOString(); }\nfunction jwtPayload(credential: string): Record<string, unknown> { const part = credential.split(\"~\", 1)[0]?.split(\".\")[1]; if (!part) throw new CredentialError(\"VERIFICATION_FAILED\", \"Issued SD-JWT is invalid\"); try { return object(JSON.parse(new TextDecoder().decode(decodeBase64Url(part))), \"SD-JWT payload\"); } catch (cause) { if (cause instanceof CredentialError) throw cause; throw new CredentialError(\"VERIFICATION_FAILED\", \"Issued SD-JWT is invalid\", { cause }); } }\nconst SERVER_CODES = new Set([\"REQUEST_EXPIRED\", \"ISSUER_UNREADY\", \"UNSUPPORTED_PROFILE\", \"UNSUPPORTED_VERSION\", \"SIGNATURE_REJECTED\"] as const);\nfunction serverError(value: unknown, response: Response, honorServerRecoverable: boolean): CredentialError | undefined {\n if (typeof value !== \"object\" || value === null || Array.isArray(value)) return undefined;\n const body = value as Record<string, unknown>;\n const keys = Object.keys(body).sort();\n if (keys.join(\",\") !== \"code,correlationId,recoverable,state,type\" || body.type !== \"tinycloud.credentials/error/v1\" || typeof body.code !== \"string\" || typeof body.recoverable !== \"boolean\" || typeof body.state !== \"string\" || typeof body.correlationId !== \"string\") return undefined;\n // A rejected proof is retryable only while the issuer still has attempts\n // left for this challenge; once exhausted the acquisition cannot finish.\n if (body.code === \"PROOF_REJECTED\") return body.recoverable\n ? new CredentialError(\"PROOF_REJECTED\", \"The proof was not accepted\", { state: body.state, correlationId: body.correlationId })\n : new CredentialError(\"VERIFICATION_FAILED\", \"The proof attempt limit was reached\", { state: \"proof_attempts_exhausted\", correlationId: body.correlationId });\n if (body.code === \"RATE_LIMITED\") return new CredentialError(\"ISSUER_UNREADY\", \"Too many verification codes were requested\", { state: \"rate_limited\", correlationId: body.correlationId, retryAfterMs: Number(response.headers.get(\"retry-after\")) * 1000 || undefined, recoverable: honorServerRecoverable ? body.recoverable : undefined });\n if (body.code === \"CHALLENGE_EXPIRED\") return new CredentialError(\"REQUEST_EXPIRED\", \"The credential challenge expired\", { state: body.state, correlationId: body.correlationId, recoverable: honorServerRecoverable ? body.recoverable : undefined });\n if (!SERVER_CODES.has(body.code as any)) return undefined;\n const code = body.code as \"REQUEST_EXPIRED\" | \"ISSUER_UNREADY\" | \"UNSUPPORTED_PROFILE\" | \"UNSUPPORTED_VERSION\" | \"SIGNATURE_REJECTED\";\n return new CredentialError(code, `OpenCredentials rejected the request: ${code}`, {\n state: body.state,\n correlationId: body.correlationId,\n retryAfterMs: Number(response.headers.get(\"retry-after\")) * 1000 || undefined,\n recoverable: honorServerRecoverable ? body.recoverable : undefined,\n });\n}\n\nexport class OpenCredentialsHttpTransport implements CredentialAcquisitionTransport {\n private readonly nonces = new Map<string, string>();\n private readonly bindings = new Map<string, CredentialHolderBinding>();\n constructor(private readonly descriptor: CredentialFlowDescriptor, private readonly fetchFn: typeof fetch = globalThis.fetch.bind(globalThis), private readonly options: { readonly honorServerRecoverable?: boolean } = {}) {}\n private url(endpoint: Parameters<typeof credentialEndpointPath>[0], id?: string): string { return new URL(credentialEndpointPath(endpoint, id), this.descriptor.issuer.origin).href; }\n private async request(endpoint: Parameters<typeof credentialEndpointPath>[0], input: { readonly id?: string; readonly method?: \"GET\" | \"POST\"; readonly verifier?: string; readonly body?: unknown; readonly signal?: AbortSignal }): Promise<unknown> {\n let response: Response;\n try { const init: RequestInit & { readonly cache: \"no-store\" } = { method: input.method ?? \"GET\", credentials: \"omit\", cache: \"no-store\", redirect: \"error\", referrerPolicy: \"no-referrer\", signal: input.signal, headers: { accept: \"application/json\", ...(input.body === undefined ? {} : { \"content-type\": \"application/json\" }), ...(input.verifier === undefined ? {} : { authorization: `Bearer ${input.verifier}` }) }, ...(input.body === undefined ? {} : { body: JSON.stringify(input.body) }) }; response = await this.fetchFn(this.url(endpoint, input.id), init); }\n catch (cause) { if (cause instanceof DOMException && cause.name === \"AbortError\") throw new CredentialError(\"CANCELED\", \"Credential acquisition was canceled\", { cause }); throw new CredentialError(\"OFFLINE\", \"OpenCredentials is unavailable\", { cause }); }\n if (!response.ok) {\n let parsed: unknown;\n try { parsed = await response.json(); } catch { parsed = undefined; }\n const typed = serverError(parsed, response, this.options.honorServerRecoverable === true);\n if (typed) throw typed;\n if (response.status === 410) throw new CredentialError(\"REQUEST_EXPIRED\", \"Credential request expired\");\n if (response.status === 409) throw new CredentialError(\"REQUEST_SUBSTITUTED\", \"Credential request was replayed or substituted\");\n if (response.status === 503) throw new CredentialError(\"ISSUER_UNREADY\", \"Credential issuer is not ready\", { retryAfterMs: Number(response.headers.get(\"retry-after\")) * 1000 || undefined });\n throw new CredentialError(\"VERIFICATION_FAILED\", \"OpenCredentials rejected the request\");\n }\n if (response.status === 204) return undefined; try { return await response.json(); } catch (cause) { throw new CredentialError(\"VERIFICATION_FAILED\", \"OpenCredentials response is invalid\", { cause }); }\n }\n async create(input: { descriptor: CredentialFlowDescriptor; descriptorDigest: string; requirement: CredentialRequirement; requirementDigest: string; holderDid: string; openerOrigin: string; completionVerifierChallenge: string; inputs?: Readonly<Record<string, string>>; signal?: AbortSignal }) {\n const body = object(await this.request(\"request\", { method: \"POST\", body: { protocol: input.descriptor.protocol, profile: input.descriptor.profile, profileVersion: input.descriptor.profileVersion, descriptorDigest: input.descriptorDigest, requirementDigest: input.requirementDigest, holderDid: input.holderDid, inputs: input.inputs ?? input.requirement.claims, audience: \"tinycloud://credentials\", openerOrigin: input.openerOrigin, completionOrigin: input.openerOrigin, completionContext: \"sdk-acquisition\", completionVerifierChallenge: input.completionVerifierChallenge }, signal: input.signal }), \"create response\");\n if (body.type !== \"tinycloud.credentials/acquisition-request/v1\" || body.protocol !== input.descriptor.protocol || body.next !== \"challenge\" || body.endpoint !== \"challenge\") throw new CredentialError(\"VERIFICATION_FAILED\", \"create response is invalid\");\n const requestId = opaque(body.requestId, \"requestId\"); return { requestId, locator: requestId, expiresAt: timestamp(body.expiresAt, \"expiresAt\"), correlationId: requestId };\n }\n private proofStep(): \"mailbox_otp\" | \"collect_input\" { return this.descriptor.steps.some((step) => step.type === \"mailbox_otp\") ? \"mailbox_otp\" : \"collect_input\"; }\n async state(id: string, verifier: string, signal?: AbortSignal): Promise<CredentialRequestState> {\n const raw = object(await this.request(\"state\", { id, verifier, signal }), \"state response\");\n if (raw.type !== \"tinycloud.credentials/acquisition-state/v1\" || raw.requestId !== id || raw.profile !== this.descriptor.profile || raw.profileVersion !== 1) throw new CredentialError(\"REQUEST_SUBSTITUTED\", \"Credential state response is substituted\");\n const base = { type: \"OpenCredentialsAcquisitionState\" as const, version: 1 as const, requestId: id, transitionId: `${String(raw.state)}:${String(raw.resultPreviouslyRead ?? false)}`, correlationId: id };\n if (raw.state === \"challenge_required\") { const type = this.proofStep(); return { ...base, state: \"pending\", nextStep: { id: type, type, version: 1, constraints: { challengeRequired: true } } }; }\n if (raw.state === \"proof_required\") { const type = this.proofStep(); this.nonces.set(id, opaque(raw.challengeNonce, \"challengeNonce\")); return { ...base, state: \"pending\", nextStep: { id: type, type, version: 1, constraints: {} } }; }\n if (raw.state === \"holder_binding_required\" || raw.state === \"holder_signature_required\") return { ...base, state: \"pending\", nextStep: { id: \"holder_signature\", type: \"holder_signature\", version: 1, constraints: {} } };\n if (raw.state === \"ready_to_issue\") return { ...base, state: \"ready_to_issue\" };\n if (raw.state === \"issued\") return { ...base, state: \"complete\" };\n throw new CredentialError(\"REQUEST_SUBSTITUTED\", \"Credential state is unsupported\");\n }\n async beginStep(id: string, verifier: string, stepId: \"collect_input\" | \"mailbox_otp\", signal?: AbortSignal): Promise<void> { const step = this.proofStep(); if (stepId !== step) throw new CredentialError(\"REQUEST_SUBSTITUTED\", \"Credential challenge step is substituted\"); const challenge = object(await this.request(\"challenge\", { id, verifier, method: \"POST\", body: { step, stepVersion: 1 }, signal }), \"challenge response\"); if (challenge.type !== \"tinycloud.credentials/challenge/v1\" || challenge.step !== step || challenge.stepVersion !== 1) throw new CredentialError(\"REQUEST_SUBSTITUTED\", \"Credential challenge is substituted\"); this.nonces.set(id, opaque(challenge.challengeNonce, \"challengeNonce\")); }\n async submitStep(id: string, verifier: string, stepId: string, proof: PrimitiveStepResult, signal?: AbortSignal): Promise<void> { const step = this.proofStep(); if (stepId !== step) throw new CredentialError(\"REQUEST_SUBSTITUTED\", \"Credential proof step is substituted\"); const nonce = this.nonces.get(id); if (!nonce) throw new CredentialError(\"REQUEST_SUBSTITUTED\", \"Credential challenge is missing\"); await this.request(\"proof\", { id, verifier, method: \"POST\", body: { step, stepVersion: 1, challengeNonce: nonce, proof }, signal }); }\n async holderBinding(id: string, verifier: string, signal?: AbortSignal): Promise<CredentialHolderBinding> { const raw = object(await this.request(\"holder_binding\", { id, verifier, signal }), \"holder binding response\"); if (raw.type !== \"tinycloud.credentials/holder-binding-request/v1\" || raw.signingDomain !== \"tinycloud.credentials/holder-binding/v1\" || raw.alg !== \"EdDSA\" || typeof raw.canonical !== \"string\") throw new CredentialError(\"REQUEST_SUBSTITUTED\", \"Holder binding response is invalid\"); const binding = validateCredentialHolderBinding(raw.binding); if (encodeBase64Url(holderBindingCanonicalBytes(binding)) !== raw.canonical) throw new CredentialError(\"REQUEST_SUBSTITUTED\", \"Holder binding canonical bytes were substituted\"); this.bindings.set(id, binding); return binding; }\n async submitHolderSignature(id: string, verifier: string, signature: string, signal?: AbortSignal, key?: HolderSignatureKey): Promise<void> { const binding = this.bindings.get(id); if (!binding) throw new CredentialError(\"REQUEST_SUBSTITUTED\", \"Holder binding was not retrieved\"); const kid = key?.kid ?? `${binding.holderDid}#${binding.holderDid.replace(\"did:key:\", \"\")}`; await this.request(\"holder_signature\", { id, verifier, method: \"POST\", body: { alg: key?.alg ?? \"EdDSA\", kid, signature }, signal }); }\n async issue(id: string, verifier: string, signal?: AbortSignal): Promise<void> { await this.request(\"issue\", { id, verifier, method: \"POST\", signal }); }\n async result(id: string, verifier: string, signal?: AbortSignal): Promise<IssuedCredentialEnvelope> {\n const raw = object(await this.request(\"result\", { id, verifier, signal }), \"result response\"); if (raw.type !== \"tinycloud.credentials/result/v1\" || raw.protocol !== this.descriptor.protocol || raw.profile !== this.descriptor.profile || raw.profileVersion !== 1 || raw.format !== \"vc+sd-jwt\" || raw.descriptorDigest !== await canonicalDigest(this.descriptor) || raw.issuer !== this.descriptor.issuer.did || raw.issuerKid !== this.descriptor.issuer.kid || typeof raw.credential !== \"string\" || await sha256Base64Url(raw.credential) !== raw.credentialDigest) throw new CredentialError(\"VERIFICATION_FAILED\", \"Issued result metadata is invalid\");\n const holder = object(raw.holderBinding, \"result holder binding\"); if (raw.subject !== holder.did || holder.signingDomain !== \"tinycloud.credentials/holder-binding/v1\") throw new CredentialError(\"HOLDER_MISMATCH\", \"Issued holder binding is invalid\");\n const claimsRaw = object(raw.claims, \"result claims\"); const claims: Record<string, string> = {}; for (const [name, value] of Object.entries(claimsRaw)) { if (typeof value !== \"string\") throw new CredentialError(\"VERIFICATION_FAILED\", \"Issued claims are invalid\"); claims[name] = value; }\n const validity = object(raw.validity, \"result validity\"); const payload = jwtPayload(raw.credential); if (typeof payload.jti !== \"string\") throw new CredentialError(\"VERIFICATION_FAILED\", \"Credential id is invalid\"); const issuedAt = timestamp(validity.issuedAt, \"issuedAt\"); const expiresAt = timestamp(validity.expiresAt, \"expiresAt\");\n const status = object(raw.status, \"result status\"); if (status.type !== \"none\" || status.freshnessSeconds !== this.descriptor.status.freshnessSeconds) throw new CredentialError(\"VERIFICATION_FAILED\", \"Credential status is invalid\");\n return { type: \"OpenCredentialsIssuedCredential\", version: 1, protocol: this.descriptor.protocol, profile: { id: this.descriptor.profile, version: 1 }, credentialType: { id: this.descriptor.format.vct, version: 1 }, schema: this.descriptor.format.vct, format: \"vc+sd-jwt\", issuerDid: raw.issuer as string, issuerKid: raw.issuerKid as string, subjectDid: raw.subject as string, holderDid: raw.subject as string, claims, claimsDigest: await canonicalDigest(claims), descriptorDigest: raw.descriptorDigest as string, credentialId: payload.jti, issuedAt, notBefore: issuedAt, expiresAt, status: { method: \"none\", freshnessSeconds: status.freshnessSeconds as number }, credential: raw.credential };\n }\n async issuerMetadata(signal?: AbortSignal): Promise<CredentialIssuerMetadata> { return await this.request(\"issuer_metadata\", { signal }) as CredentialIssuerMetadata; }\n async checkStatus(status: IssuedCredentialEnvelope[\"status\"], _signal?: AbortSignal): Promise<boolean> { return status.method === \"none\" && status.freshnessSeconds === this.descriptor.status.freshnessSeconds; }\n}\n"],"mappings":"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","names":["CredentialError","encodeBase64Url","validateCredentialHolderBinding"]}
|