@agentlogin/issuer 0.0.0-stage → 0.2.0-beta.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.
Files changed (58) hide show
  1. package/LICENSE +202 -0
  2. package/README.md +237 -2
  3. package/dist/agents.d.ts +40 -0
  4. package/dist/agents.js +257 -0
  5. package/dist/agents.js.map +1 -0
  6. package/dist/app.d.ts +3 -0
  7. package/dist/app.js +652 -0
  8. package/dist/app.js.map +1 -0
  9. package/dist/clients.d.ts +20 -0
  10. package/dist/clients.js +272 -0
  11. package/dist/clients.js.map +1 -0
  12. package/dist/constants.d.ts +30 -0
  13. package/dist/constants.js +32 -0
  14. package/dist/constants.js.map +1 -0
  15. package/dist/context.d.ts +37 -0
  16. package/dist/context.js +2 -0
  17. package/dist/context.js.map +1 -0
  18. package/dist/errors.d.ts +10 -0
  19. package/dist/errors.js +17 -0
  20. package/dist/errors.js.map +1 -0
  21. package/dist/index.d.ts +45 -0
  22. package/dist/index.js +107 -0
  23. package/dist/index.js.map +1 -0
  24. package/dist/owner-address.d.ts +2 -0
  25. package/dist/owner-address.js +24 -0
  26. package/dist/owner-address.js.map +1 -0
  27. package/dist/safefetch.d.ts +38 -0
  28. package/dist/safefetch.js +164 -0
  29. package/dist/safefetch.js.map +1 -0
  30. package/dist/server.d.ts +1 -0
  31. package/dist/server.js +89 -0
  32. package/dist/server.js.map +1 -0
  33. package/dist/signing-configuration.d.ts +14 -0
  34. package/dist/signing-configuration.js +35 -0
  35. package/dist/signing-configuration.js.map +1 -0
  36. package/dist/signing-state.d.ts +22 -0
  37. package/dist/signing-state.js +14 -0
  38. package/dist/signing-state.js.map +1 -0
  39. package/dist/sqlite-store.d.ts +24 -0
  40. package/dist/sqlite-store.js +81 -0
  41. package/dist/sqlite-store.js.map +1 -0
  42. package/dist/state.d.ts +30 -0
  43. package/dist/state.js +77 -0
  44. package/dist/state.js.map +1 -0
  45. package/dist/store.d.ts +693 -0
  46. package/dist/store.js +883 -0
  47. package/dist/store.js.map +1 -0
  48. package/dist/tokens.d.ts +37 -0
  49. package/dist/tokens.js +167 -0
  50. package/dist/tokens.js.map +1 -0
  51. package/dist/transactions.d.ts +90 -0
  52. package/dist/transactions.js +449 -0
  53. package/dist/transactions.js.map +1 -0
  54. package/dist/util.d.ts +29 -0
  55. package/dist/util.js +113 -0
  56. package/dist/util.js.map +1 -0
  57. package/package.json +37 -4
  58. package/static/wait.js +42 -0
@@ -0,0 +1,449 @@
1
+ // Section 5.3 and Section 6: the Sign-in Transaction.
2
+ import { compactVerify, decodeProtectedHeader, importJWK } from 'jose';
3
+ import { AGENT_KEY_ALGS, ASSERTION_TYP, DISCLOSURE, OWNER_SCOPES, SCOPES } from './constants.js';
4
+ import { OAuthError } from './errors.js';
5
+ import { getLiveKey } from './agents.js';
6
+ import { ownerClaimsAvailable } from './tokens.js';
7
+ import { commit, ended } from './state.js';
8
+ import { TERMINAL, consentRecordReason } from './store.js';
9
+ import { domainServed, handlesEqual, isPlainObject, parseHandle, randomId, randomSecret, sha256, typMatches } from './util.js';
10
+ export const txUrl = (ctx, id) => `${ctx.issuer}/transactions/${id}`;
11
+ /** Section 5.3: create the transaction. */
12
+ export async function createTransaction(ctx, p) {
13
+ const now = await ctx.store.currentTime(ctx.now());
14
+ const tx = {
15
+ id: randomId(),
16
+ version: 0,
17
+ continueSecret: randomSecret(),
18
+ clientId: p.client.clientId,
19
+ clientPresentation: { type: p.client.type, clientName: p.client.clientName, logoUri: p.client.logoUri,
20
+ tosUri: p.client.tosUri, policyUri: p.client.policyUri, relayIssuer: p.client.relayIssuer, relayPolicyUri: p.client.relayPolicyUri },
21
+ redirectUri: p.redirectUri,
22
+ scopes: p.scopes,
23
+ state: p.state,
24
+ nonce: p.nonce,
25
+ codeChallenge: p.codeChallenge,
26
+ prompt: p.prompt,
27
+ maxAge: p.maxAge,
28
+ loginHint: p.loginHint,
29
+ disclosure: p.scopes.map((s) => ({ scope: s, ...DISCLOSURE[s] })),
30
+ requester: p.requester,
31
+ status: 'awaiting_agent',
32
+ challenge: randomSecret(),
33
+ createdAt: now,
34
+ expiresAt: now + ctx.constants.T_TXN,
35
+ acceptDisclosure: false,
36
+ deliverToSession: false,
37
+ ownerApprovalOutstanding: false,
38
+ reviewOutstanding: false,
39
+ passedCap: false,
40
+ sessionSecretHash: sha256(p.sessionSecret),
41
+ codeIssued: false,
42
+ };
43
+ await ctx.store.insertTransaction(tx);
44
+ return tx;
45
+ }
46
+ /**
47
+ * Loads a transaction as it stands now, or throws 404 `invalid_transaction` (Section 6.7); terminal ones are retained
48
+ * for T_RETAIN. Effective expiry and lifecycle state are computed by a read-only store operation. Polling never
49
+ * persists a denial or releases a reservation; mutation paths enforce the same state independently.
50
+ */
51
+ export async function loadTransaction(ctx, id) {
52
+ const tx = await ctx.store.readTransaction(id, { now: ctx.now(), retainFor: ctx.constants.T_RETAIN });
53
+ if (!tx)
54
+ throw new OAuthError(404, 'invalid_transaction');
55
+ return tx;
56
+ }
57
+ /** Keep displayed terms fixed while authentication, review policy and quota continue to use the current Client. */
58
+ export function presentedClient(tx, client) {
59
+ const shown = tx.clientPresentation;
60
+ return { ...client, type: shown?.type ?? client.type, clientName: shown?.clientName, logoUri: shown?.logoUri,
61
+ tosUri: shown?.tosUri, policyUri: shown?.policyUri, relayIssuer: shown?.relayIssuer, relayPolicyUri: shown?.relayPolicyUri };
62
+ }
63
+ /** Section 6.1: the Transaction Resource as seen by `viewer`. */
64
+ export function resource(ctx, tx, client, viewer) {
65
+ client = presentedClient(tx, client);
66
+ const base = txUrl(ctx, tx.id);
67
+ const r = {
68
+ transaction_id: tx.id,
69
+ iss: ctx.issuer,
70
+ url: base,
71
+ status: tx.status,
72
+ next: next(ctx, tx, viewer),
73
+ expires_at: tx.expiresAt,
74
+ client: {
75
+ client_id: client.clientId,
76
+ client_type: client.type,
77
+ redirect_host: new URL(tx.redirectUri).host,
78
+ client_name: client.clientName,
79
+ logo_uri: client.logoUri,
80
+ tos_uri: client.tosUri,
81
+ policy_uri: client.policyUri,
82
+ },
83
+ requested_scopes: tx.scopes,
84
+ disclosure: tx.disclosure,
85
+ };
86
+ if (tx.requester)
87
+ r.requester = tx.requester;
88
+ if (tx.status === 'awaiting_agent')
89
+ r.challenge = tx.challenge;
90
+ if (tx.status === 'awaiting_consent')
91
+ r.consent_reason = tx.consentReason;
92
+ if (tx.loginHint)
93
+ r.login_hint = tx.loginHint;
94
+ if (tx.status === 'denied')
95
+ r.reason = tx.reason;
96
+ return r;
97
+ }
98
+ function next(ctx, tx, viewer) {
99
+ const base = txUrl(ctx, tx.id);
100
+ switch (tx.status) {
101
+ case 'awaiting_agent':
102
+ return { action: 'assert', method: 'POST', url: `${base}/assertion` };
103
+ case 'awaiting_owner':
104
+ return { action: 'await_owner', method: 'GET', url: base, retry_after: 5 };
105
+ case 'awaiting_consent':
106
+ return { action: 'review', method: 'POST', url: `${base}/review` };
107
+ case 'completed':
108
+ return { action: 'none' };
109
+ case 'ready':
110
+ case 'denied':
111
+ case 'expired': {
112
+ // Section 6.5: the continue URL goes to the transaction_token holder, and to the Session Holder only
113
+ // when the accepted assertion carried deliver_to_session.
114
+ const release = viewer.kind === 'transaction_token' || (viewer.kind === 'session' && tx.deliverToSession);
115
+ const n = { action: 'continue', method: 'GET' };
116
+ if (release)
117
+ n.url = `${base}/continue/${tx.continueSecret}`;
118
+ return n;
119
+ }
120
+ }
121
+ }
122
+ /** Identifies the requester of a transaction resource from its credentials (Section 6.5). */
123
+ export function identifyViewer(tx, bearer, cookieSecret) {
124
+ if (bearer) {
125
+ const h = sha256(bearer);
126
+ if (tx.transactionTokenHash && h === tx.transactionTokenHash)
127
+ return { kind: 'transaction_token', tokenHash: h };
128
+ if (tx.sessionSecretHash && h === tx.sessionSecretHash)
129
+ return { kind: 'session' };
130
+ throw new OAuthError(401, 'invalid_token', undefined, { 'WWW-Authenticate': 'Bearer error="invalid_token"' });
131
+ }
132
+ if (cookieSecret && tx.sessionSecretHash && sha256(cookieSecret) === tx.sessionSecretHash)
133
+ return { kind: 'session' };
134
+ return { kind: 'none' };
135
+ }
136
+ /** Section 6.4: whether a review is required, and why. */
137
+ /**
138
+ * Section 6.4: why a review is required. `record` is a reason that the Agent's acceptance of the disclosure
139
+ * satisfies (the Consent Record is missing, outdated or expired); `forced` is one that it does not (the request or
140
+ * the client demands a review).
141
+ */
142
+ export function reviewReasons(ctx, tx, client, consent, now = ctx.now()) {
143
+ client = presentedClient(tx, client);
144
+ const record = consentRecordReason(consent, { scopes: tx.scopes, redirectHost: new URL(tx.redirectUri).host,
145
+ clientName: client.clientName, tosUri: client.tosUri, policyUri: client.policyUri }, now - ctx.constants.T_CONSENT) ?? null;
146
+ const forced = tx.prompt === 'consent' ? 'prompt_consent' : client.requireReview ? 'policy' : null;
147
+ return { record, forced };
148
+ }
149
+ /** Effects committed atomically with the transition; a delayed request cannot grant consent to a replacement Agent. */
150
+ function transitionEffects(ctx, tx, client, grantConsent = false) {
151
+ client = presentedClient(tx, client);
152
+ const consentContext = tx.handle ? { handle: tx.handle, clientId: tx.clientId, scopes: tx.scopes, redirectHost: new URL(tx.redirectUri).host,
153
+ clientName: client.clientName, tosUri: client.tosUri, policyUri: client.policyUri } : undefined;
154
+ return {
155
+ maxSignups: client.maxSignupsPerOwner,
156
+ expireConsentBefore: ctx.now() - ctx.constants.T_CONSENT,
157
+ consent: grantConsent ? consentContext : undefined,
158
+ consentContext,
159
+ touchConsent: tx.status === 'ready' && tx.consentRelied,
160
+ };
161
+ }
162
+ /**
163
+ * Section 6.7 precedence: `invalid_transaction` (loading), then `invalid_token`, then `transaction_expired`, then any
164
+ * other error. The two guards below are applied in that order before a request body or the status is looked at.
165
+ */
166
+ export function requireTransactionToken(viewer) {
167
+ if (viewer.kind !== 'transaction_token')
168
+ throw new OAuthError(401, 'invalid_token', undefined, { 'WWW-Authenticate': 'Bearer error="invalid_token"' });
169
+ }
170
+ export function requireOpen(tx) {
171
+ if (TERMINAL.has(tx.status))
172
+ throw new OAuthError(410, 'transaction_expired');
173
+ }
174
+ /**
175
+ * Section 6.3: verify an assertion and advance the transaction. Returns the transaction as accepted and its
176
+ * transaction_token. Steps 6 and 7 are one conditional write: of several assertions for one transaction, at whatever
177
+ * issuer process they arrive, one is accepted and the others are answered `assertion_replayed`.
178
+ */
179
+ export async function assert(ctx, loaded, client, body) {
180
+ const tx = loaded;
181
+ requireOpen(tx);
182
+ if (!isPlainObject(body) || typeof body.assertion !== 'string')
183
+ throw new OAuthError(400, 'invalid_request', 'assertion required');
184
+ const jws = body.assertion;
185
+ const c = ctx.constants;
186
+ const bad = (d) => new OAuthError(400, 'invalid_assertion', d);
187
+ // Step 1: size, header, parse.
188
+ if (Buffer.byteLength(jws) > c.N_ASSERTION)
189
+ throw bad('assertion too large');
190
+ let header;
191
+ try {
192
+ header = decodeProtectedHeader(jws);
193
+ }
194
+ catch {
195
+ throw bad('malformed JWS');
196
+ }
197
+ if (!AGENT_KEY_ALGS.includes(header.alg))
198
+ throw bad('alg not permitted');
199
+ if (!typMatches(header.typ, ASSERTION_TYP))
200
+ throw bad('typ');
201
+ if (typeof header.kid !== 'string')
202
+ throw bad('kid required');
203
+ for (const f of ['jwk', 'jku', 'x5u', 'x5c', 'crit'])
204
+ if (header[f] !== undefined)
205
+ throw bad(`header ${f} not permitted`);
206
+ let payload;
207
+ try {
208
+ const parts = jws.split('.');
209
+ payload = JSON.parse(Buffer.from(parts[1], 'base64url').toString('utf8'));
210
+ if (!isPlainObject(payload))
211
+ throw new Error();
212
+ }
213
+ catch {
214
+ throw bad('malformed payload');
215
+ }
216
+ if (typeof payload.iss !== 'string' || payload.sub !== payload.iss)
217
+ throw bad('iss and sub must both be the handle');
218
+ const parsed = parseHandle(payload.iss);
219
+ if (!parsed)
220
+ throw bad('handle syntax');
221
+ // Step 2: resolve the key.
222
+ const key = await getLiveKey(ctx, header.kid, parsed.handle);
223
+ if (!key || !handlesEqual(key.handle, parsed.handle) || !domainServed(parsed.domain, ctx.handleDomains))
224
+ throw new OAuthError(401, 'unknown_key');
225
+ if (key.status !== 'active' || (await ctx.store.currentTime(ctx.now())) >= key.expiresAt)
226
+ throw new OAuthError(401, 'key_revoked');
227
+ if (header.alg !== 'ES256')
228
+ throw bad('alg does not match the key'); // only P-256 keys are enrolled
229
+ // Step 3: signature.
230
+ try {
231
+ await compactVerify(jws, await importJWK(key.jwk, 'ES256'), { algorithms: ['ES256'] });
232
+ }
233
+ catch {
234
+ throw new OAuthError(401, 'invalid_signature');
235
+ }
236
+ // Step 4: claims.
237
+ const now = await ctx.store.currentTime(ctx.now());
238
+ if (payload.aud !== ctx.issuer)
239
+ throw bad('aud');
240
+ if (payload.txn !== tx.id)
241
+ throw bad('txn');
242
+ if (tx.status !== 'awaiting_agent' || payload.nonce !== tx.challenge) {
243
+ if (tx.status !== 'awaiting_agent')
244
+ throw new OAuthError(409, 'assertion_replayed');
245
+ throw bad('nonce');
246
+ }
247
+ const iat = payload.iat;
248
+ const exp = payload.exp;
249
+ if (typeof iat !== 'number' || typeof exp !== 'number')
250
+ throw bad('iat and exp required');
251
+ if (exp > iat + c.T_ASSERT)
252
+ throw bad('exp too far from iat');
253
+ if (now >= exp)
254
+ throw bad('expired');
255
+ if (iat < now - c.T_ASSERT || iat > now + c.T_SKEW)
256
+ throw bad('iat outside window');
257
+ if (typeof payload.jti !== 'string')
258
+ throw bad('jti required');
259
+ if (payload.accept_disclosure !== undefined && typeof payload.accept_disclosure !== 'boolean')
260
+ throw bad('accept_disclosure');
261
+ if (payload.deliver_to_session !== undefined && typeof payload.deliver_to_session !== 'boolean')
262
+ throw bad('deliver_to_session');
263
+ // Step 5: login_hint.
264
+ if (tx.loginHint && !handlesEqual(tx.loginHint, parsed.handle))
265
+ throw bad('login_hint mismatch');
266
+ const agent = await ctx.store.getAgent(key.handle);
267
+ if (!agent || !agent.enabled || agent.sub !== key.agentSub)
268
+ throw new OAuthError(401, 'unknown_key');
269
+ const token = randomSecret();
270
+ const account = await ctx.store.getAccount(agent.handle, tx.clientId);
271
+ const subject = { handle: agent.handle, kid: key.kid, keyEnrollment: key.enrollment, clientId: tx.clientId, agentSub: agent.sub, agentVersion: agent.authorizationVersion, accountVersion: account?.authorizationVersion ?? 0 };
272
+ for (let current = tx;;) {
273
+ // Step 6: one assertion per transaction. Decided again on every attempt, against the transaction as it is now.
274
+ if (TERMINAL.has(current.status))
275
+ throw new OAuthError(410, 'transaction_expired');
276
+ if (current.status !== 'awaiting_agent')
277
+ throw new OAuthError(409, 'assertion_replayed');
278
+ if (payload.nonce !== current.challenge)
279
+ throw bad('nonce');
280
+ // Permissions can change while gates are being planned. Each attempt stays bound to the verified enrollment.
281
+ const currentKey = await ctx.store.getKey(key.kid, key.handle);
282
+ if (!currentKey || currentKey.enrollment !== key.enrollment || currentKey.agentSub !== key.agentSub)
283
+ throw new OAuthError(401, 'unknown_key');
284
+ // Step 7: the challenge is consumed and the authentication event recorded.
285
+ let next = {
286
+ ...current,
287
+ challenge: undefined,
288
+ ...subject,
289
+ ownerId: agent.ownerId,
290
+ assertedAt: now,
291
+ acceptDisclosure: payload.accept_disclosure === true,
292
+ deliverToSession: payload.deliver_to_session === true,
293
+ transactionTokenHash: sha256(token),
294
+ };
295
+ let grantConsent = false;
296
+ // Cap admission and assertion acceptance are a single conditional store operation. A losing assertion owns no cleanup.
297
+ if (account?.status === 'disabled')
298
+ next = ended(ctx, next, 'denied', 'access_denied');
299
+ else
300
+ ({ next, grantConsent } = await gates(ctx, next, client, currentKey.permissions.share_owner, agent.ownerId));
301
+ if (await commit(ctx, next, current.version, { ...transitionEffects(ctx, next, client, grantConsent), expectedShareOwner: currentKey.permissions.share_owner, assertionWindow: { notBefore: iat - c.T_SKEW, expiresAt: exp } })) {
302
+ return { tx: next, token };
303
+ }
304
+ current = await loadTransaction(ctx, tx.id);
305
+ }
306
+ }
307
+ /** Step 10 of Section 6.3: the outstanding gates and the status they lead to. */
308
+ async function gates(ctx, tx, client, shareOwner, ownerId) {
309
+ const next = { ...tx };
310
+ const wantsOwner = next.scopes.some((s) => OWNER_SCOPES.includes(s));
311
+ if (wantsOwner) {
312
+ // Section 6.6: a requested Owner Claim that cannot be issued for this Owner ends the sign-in; it is never omitted.
313
+ const owner = await ctx.store.getOwner(ownerId);
314
+ if (!owner || !ownerClaimsAvailable(owner, next.scopes))
315
+ return { next: ended(ctx, next, 'denied', 'access_denied'), grantConsent: false };
316
+ }
317
+ next.ownerApprovalOutstanding = wantsOwner && !shareOwner;
318
+ const consent = await ctx.store.getConsent(next.handle, next.clientId);
319
+ const { record, forced } = reviewReasons(ctx, next, client, consent, await ctx.store.currentTime(ctx.now()));
320
+ // accept_disclosure answers for the Consent Record only; a review that the request or the client demands stays due.
321
+ const recordOutstanding = record !== null && !next.acceptDisclosure;
322
+ next.reviewOutstanding = recordOutstanding || forced !== null;
323
+ next.consentReason = (recordOutstanding ? record : forced) ?? undefined;
324
+ next.consentRelied = consent !== undefined && record === null;
325
+ if (next.prompt === 'none' && next.reviewOutstanding)
326
+ return { next: ended(ctx, next, 'denied', 'consent_required'), grantConsent: false };
327
+ if (next.prompt === 'none' && next.ownerApprovalOutstanding)
328
+ return { next: ended(ctx, next, 'denied', 'interaction_required'), grantConsent: false };
329
+ if (next.ownerApprovalOutstanding) {
330
+ next.status = 'awaiting_owner';
331
+ next.expiresAt = Math.max(next.expiresAt, next.createdAt + ctx.constants.T_OWNER); // Section 6.6
332
+ }
333
+ else if (next.reviewOutstanding)
334
+ next.status = 'awaiting_consent';
335
+ else
336
+ next.status = 'ready';
337
+ return { next, grantConsent: next.acceptDisclosure && !next.reviewOutstanding };
338
+ }
339
+ /** Section 6.4: the review decision, authorised by the transaction_token only. Returns the transaction as changed. */
340
+ export async function review(ctx, loaded, client, viewer, body) {
341
+ requireTransactionToken(viewer); // the session binding does not authorise this step
342
+ for (let current = loaded;;) {
343
+ if (viewer.tokenHash !== current.transactionTokenHash)
344
+ throw new OAuthError(401, 'invalid_token', undefined, { 'WWW-Authenticate': 'Bearer error="invalid_token"' });
345
+ requireOpen(current);
346
+ if (current.status !== 'awaiting_consent')
347
+ throw new OAuthError(400, 'invalid_request', 'no review is outstanding');
348
+ if (!isPlainObject(body) || (body.decision !== 'allow' && body.decision !== 'deny'))
349
+ throw new OAuthError(400, 'invalid_request', 'decision must be allow or deny');
350
+ const allow = body.decision === 'allow';
351
+ const next = allow
352
+ ? { ...current, reviewOutstanding: false, status: current.ownerApprovalOutstanding ? 'awaiting_owner' : 'ready' }
353
+ : ended(ctx, current, 'denied', 'cancelled');
354
+ if (await commit(ctx, next, current.version, { ...transitionEffects(ctx, next, client, allow), transactionTokenHash: viewer.tokenHash })) {
355
+ return next;
356
+ }
357
+ current = await reload(ctx, loaded.id);
358
+ }
359
+ }
360
+ /** Section 6.6: the Owner's decision, given with an Owner Credential of the asserting Agent's Owner. */
361
+ export async function ownerDecision(ctx, loaded, client, ownerId, decision) {
362
+ for (let current = loaded;;) {
363
+ requireOpen(current);
364
+ if (current.status !== 'awaiting_owner')
365
+ throw new OAuthError(400, 'invalid_request', 'no approval is outstanding');
366
+ if (current.ownerId !== ownerId)
367
+ throw new OAuthError(404, 'invalid_transaction');
368
+ if (decision !== 'approve' && decision !== 'refuse')
369
+ throw new OAuthError(400, 'invalid_request', 'decision must be approve or refuse');
370
+ const next = decision === 'refuse'
371
+ ? ended(ctx, current, 'denied', 'owner_declined')
372
+ : { ...current, ownerApprovalOutstanding: false, status: current.reviewOutstanding ? 'awaiting_consent' : 'ready' };
373
+ if (await commit(ctx, next, current.version, transitionEffects(ctx, next, client))) {
374
+ return next;
375
+ }
376
+ current = await reload(ctx, loaded.id);
377
+ }
378
+ }
379
+ async function reload(ctx, id) {
380
+ return loadTransaction(ctx, id);
381
+ }
382
+ /**
383
+ * Section 6.5: follow the continue URL. Completion, code insertion and Account counting are one conditional store
384
+ * transaction. Only the request that commits receives the code: of several requests, at whatever issuer process, one receives a
385
+ * code and the others `transaction_expired`.
386
+ */
387
+ export async function cont(ctx, loaded, secret, viewer) {
388
+ for (let tx = await loadTransaction(ctx, loaded.id);;) {
389
+ if (viewer.kind === 'transaction_token' && viewer.tokenHash !== tx.transactionTokenHash)
390
+ throw new OAuthError(401, 'invalid_token', undefined, { 'WWW-Authenticate': 'Bearer error="invalid_token"' });
391
+ const release = viewer.kind === 'transaction_token' || (viewer.kind === 'session' && tx.deliverToSession);
392
+ if (!release)
393
+ throw new OAuthError(401, 'invalid_token', undefined, { 'WWW-Authenticate': 'Bearer error="invalid_token"' });
394
+ if (secret !== tx.continueSecret)
395
+ throw new OAuthError(404, 'invalid_transaction');
396
+ const u = new URL(tx.redirectUri);
397
+ u.searchParams.set('state', tx.state);
398
+ u.searchParams.set('iss', ctx.issuer);
399
+ if (tx.status === 'completed')
400
+ throw new OAuthError(410, 'transaction_expired');
401
+ if (tx.status === 'denied' || tx.status === 'expired') {
402
+ const { error, description } = redirectError(tx);
403
+ u.searchParams.set('error', error);
404
+ if (description)
405
+ u.searchParams.set('error_description', description);
406
+ return { redirect: u.href };
407
+ }
408
+ if (tx.status !== 'ready')
409
+ throw new OAuthError(400, 'invalid_request', 'transaction is not ready');
410
+ const next = { ...ended(ctx, tx, 'completed'), codeIssued: true };
411
+ const code = randomSecret();
412
+ const now = await ctx.store.currentTime(ctx.now());
413
+ const completed = await ctx.store.completeTransaction(next, tx.version, {
414
+ hash: sha256(code), txnId: next.id, clientId: next.clientId, redirectUri: next.redirectUri,
415
+ codeChallenge: next.codeChallenge, nonce: next.nonce, scopes: next.scopes,
416
+ handle: next.handle, kid: next.kid, keyEnrollment: next.keyEnrollment,
417
+ agentSub: next.agentSub, agentVersion: next.agentVersion, accountVersion: next.accountVersion,
418
+ authTime: next.assertedAt, maxAge: next.maxAge, expiresAt: now + ctx.constants.T_CODE, used: false, voided: false,
419
+ }, now, viewer.kind === 'transaction_token' ? viewer.tokenHash : undefined);
420
+ if (!completed || completed.status !== 'completed') {
421
+ tx = completed ?? await loadTransaction(ctx, tx.id);
422
+ continue;
423
+ }
424
+ u.searchParams.set('code', code);
425
+ return { redirect: u.href };
426
+ }
427
+ }
428
+ /** Section 5.5 table. */
429
+ export function redirectError(tx) {
430
+ if (tx.status === 'expired')
431
+ return { error: 'access_denied', description: 'transaction_expired' };
432
+ switch (tx.reason) {
433
+ case 'owner_declined':
434
+ return { error: 'access_denied', description: 'owner_declined' };
435
+ case 'consent_required':
436
+ return { error: 'consent_required' };
437
+ case 'interaction_required':
438
+ return { error: 'interaction_required' };
439
+ case 'login_required':
440
+ return { error: 'login_required' };
441
+ case 'signup_limit_reached':
442
+ return { error: 'signup_limit_reached' };
443
+ default:
444
+ return { error: 'access_denied' };
445
+ }
446
+ }
447
+ export const isTerminal = (s) => TERMINAL.has(s);
448
+ export const scopeList = (raw) => [...new Set(raw.split(' ').filter((s) => SCOPES.includes(s)))];
449
+ //# sourceMappingURL=transactions.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"transactions.js","sourceRoot":"","sources":["../src/transactions.ts"],"names":[],"mappings":"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"}
package/dist/util.d.ts ADDED
@@ -0,0 +1,29 @@
1
+ export declare const b64u: (buf: Uint8Array) => string;
2
+ /** Random bearer secret: 256 bits, base64url (N_ENTROPY is 128 bits). */
3
+ export declare const randomSecret: () => string;
4
+ /** Random identifier: 128 bits, base64url, 22 characters. */
5
+ export declare const randomId: () => string;
6
+ export declare const sha256: (s: string) => string;
7
+ export declare const nowSeconds: () => number;
8
+ export declare function safeEqual(a: string, b: string): boolean;
9
+ /** Section 2.1: local "@" domain; local is RFC 5322 dot-atom-text, ASCII; domain as lower-case A-labels. */
10
+ export interface Handle {
11
+ handle: string;
12
+ local: string;
13
+ domain: string;
14
+ }
15
+ export declare function parseHandle(input: string): Handle | null;
16
+ /** Section 2.1 and RFC 7565 Section 7: the `acct:` URI of a handle, with octets of `local` outside `userpart` percent-encoded. */
17
+ export declare function acctUri(handle: string): string;
18
+ /** The handle named by an `acct:` URI, or null. The userpart is percent-decoded once; the host is not. */
19
+ export declare function parseAcctUri(uri: string): Handle | null;
20
+ /** Equality per Section 2.1: local octet-equal, domains equal after lower-casing. */
21
+ export declare function handlesEqual(a: string, b: string): boolean;
22
+ /** Section 2.4 `handle_domains`: exact match, or `*.example.com` matching one or more labels below example.com. */
23
+ export declare function domainServed(domain: string, handleDomains: string[]): boolean;
24
+ /** Section 5.3: JSON is chosen when application/json is the highest-weighted acceptable type and outranks text/html. */
25
+ export declare function prefersJson(accept: string | undefined): boolean;
26
+ export declare function parseBearer(authorization: string | undefined): string | null;
27
+ /** Section 4.1.9 of RFC 7515: `typ` compared case-insensitively, with an implied `application/` prefix. */
28
+ export declare function typMatches(typ: unknown, expected: string): boolean;
29
+ export declare function isPlainObject(v: unknown): v is Record<string, unknown>;
package/dist/util.js ADDED
@@ -0,0 +1,113 @@
1
+ // Small helpers shared by the issuer: randomness, hashing, time, handles, Accept negotiation.
2
+ import { createHash, randomBytes, timingSafeEqual } from 'node:crypto';
3
+ export const b64u = (buf) => Buffer.from(buf).toString('base64url');
4
+ /** Random bearer secret: 256 bits, base64url (N_ENTROPY is 128 bits). */
5
+ export const randomSecret = () => b64u(randomBytes(32));
6
+ /** Random identifier: 128 bits, base64url, 22 characters. */
7
+ export const randomId = () => b64u(randomBytes(16));
8
+ export const sha256 = (s) => createHash('sha256').update(s).digest('base64url');
9
+ export const nowSeconds = () => Math.floor(Date.now() / 1000);
10
+ export function safeEqual(a, b) {
11
+ const ab = Buffer.from(a);
12
+ const bb = Buffer.from(b);
13
+ return ab.length === bb.length && timingSafeEqual(ab, bb);
14
+ }
15
+ const ATEXT = /^[A-Za-z0-9!#$%&'*+\-/=?^_`{|}~]+(\.[A-Za-z0-9!#$%&'*+\-/=?^_`{|}~]+)*$/;
16
+ const LABEL = /^[a-z0-9]([a-z0-9-]{0,61}[a-z0-9])?$/;
17
+ export function parseHandle(input) {
18
+ if (typeof input !== 'string' || input.length > 254)
19
+ return null;
20
+ const at = input.lastIndexOf('@');
21
+ if (at <= 0 || at === input.length - 1)
22
+ return null;
23
+ const local = input.slice(0, at);
24
+ const domain = input.slice(at + 1).toLowerCase();
25
+ if (Buffer.byteLength(local) > 64 || !ATEXT.test(local))
26
+ return null;
27
+ if (domain.length > 253)
28
+ return null;
29
+ const labels = domain.split('.');
30
+ if (labels.length < 2 || !labels.every((l) => LABEL.test(l)))
31
+ return null;
32
+ return { handle: `${local}@${domain}`, local, domain };
33
+ }
34
+ /** Section 2.1 and RFC 7565 Section 7: the `acct:` URI of a handle, with octets of `local` outside `userpart` percent-encoded. */
35
+ export function acctUri(handle) {
36
+ const at = handle.lastIndexOf('@');
37
+ const userpart = [...Buffer.from(handle.slice(0, at), 'utf8')].map((b) => (/[A-Za-z0-9\-._~!$&'()*+,;=]/.test(String.fromCharCode(b)) ? String.fromCharCode(b) : `%${b.toString(16).toUpperCase().padStart(2, '0')}`)).join('');
38
+ return `acct:${userpart}@${handle.slice(at + 1)}`;
39
+ }
40
+ /** The handle named by an `acct:` URI, or null. The userpart is percent-decoded once; the host is not. */
41
+ export function parseAcctUri(uri) {
42
+ if (!uri.startsWith('acct:'))
43
+ return null;
44
+ const rest = uri.slice(5);
45
+ const at = rest.lastIndexOf('@');
46
+ if (at <= 0)
47
+ return null;
48
+ let local;
49
+ try {
50
+ local = decodeURIComponent(rest.slice(0, at));
51
+ }
52
+ catch {
53
+ return null;
54
+ }
55
+ return parseHandle(`${local}@${rest.slice(at + 1)}`);
56
+ }
57
+ /** Equality per Section 2.1: local octet-equal, domains equal after lower-casing. */
58
+ export function handlesEqual(a, b) {
59
+ const pa = parseHandle(a);
60
+ const pb = parseHandle(b);
61
+ return !!pa && !!pb && pa.local === pb.local && pa.domain === pb.domain;
62
+ }
63
+ /** Section 2.4 `handle_domains`: exact match, or `*.example.com` matching one or more labels below example.com. */
64
+ export function domainServed(domain, handleDomains) {
65
+ return handleDomains.some((d) => (d.startsWith('*.') ? domain.endsWith(d.slice(1)) && domain.length > d.length - 1 : d === domain));
66
+ }
67
+ /** Section 5.3: JSON is chosen when application/json is the highest-weighted acceptable type and outranks text/html. */
68
+ export function prefersJson(accept) {
69
+ if (!accept)
70
+ return false;
71
+ let json = 0;
72
+ let html = 0;
73
+ for (const part of accept.split(',')) {
74
+ const [typeRaw, ...params] = part.trim().split(';');
75
+ const type = (typeRaw ?? '').trim().toLowerCase();
76
+ let q = 1;
77
+ for (const p of params) {
78
+ const [k, v] = p.trim().split('=');
79
+ if (k?.trim() === 'q' && v !== undefined)
80
+ q = Number.parseFloat(v) || 0;
81
+ }
82
+ if (type === 'application/json')
83
+ json = Math.max(json, q);
84
+ else if (type === 'text/html')
85
+ html = Math.max(html, q);
86
+ else if (type === 'application/*')
87
+ json = Math.max(json, q * 0.999);
88
+ else if (type === 'text/*')
89
+ html = Math.max(html, q * 0.999);
90
+ else if (type === '*/*') {
91
+ json = Math.max(json, q * 0.998);
92
+ html = Math.max(html, q * 0.998);
93
+ }
94
+ }
95
+ return json > 0 && json > html;
96
+ }
97
+ export function parseBearer(authorization) {
98
+ if (!authorization)
99
+ return null;
100
+ const m = /^Bearer\s+([A-Za-z0-9\-._~+/]+=*)$/i.exec(authorization.trim());
101
+ return m ? m[1] : null;
102
+ }
103
+ /** Section 4.1.9 of RFC 7515: `typ` compared case-insensitively, with an implied `application/` prefix. */
104
+ export function typMatches(typ, expected) {
105
+ if (typeof typ !== 'string')
106
+ return false;
107
+ const t = typ.toLowerCase();
108
+ return t === expected || t === `application/${expected}`;
109
+ }
110
+ export function isPlainObject(v) {
111
+ return typeof v === 'object' && v !== null && !Array.isArray(v);
112
+ }
113
+ //# sourceMappingURL=util.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"util.js","sourceRoot":"","sources":["../src/util.ts"],"names":[],"mappings":"AAAA,8FAA8F;AAC9F,OAAO,EAAE,UAAU,EAAE,WAAW,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAEvE,MAAM,CAAC,MAAM,IAAI,GAAG,CAAC,GAAe,EAAU,EAAE,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,QAAQ,CAAC,WAAW,CAAC,CAAC;AAExF,yEAAyE;AACzE,MAAM,CAAC,MAAM,YAAY,GAAG,GAAW,EAAE,CAAC,IAAI,CAAC,WAAW,CAAC,EAAE,CAAC,CAAC,CAAC;AAChE,6DAA6D;AAC7D,MAAM,CAAC,MAAM,QAAQ,GAAG,GAAW,EAAE,CAAC,IAAI,CAAC,WAAW,CAAC,EAAE,CAAC,CAAC,CAAC;AAC5D,MAAM,CAAC,MAAM,MAAM,GAAG,CAAC,CAAS,EAAU,EAAE,CAAC,UAAU,CAAC,QAAQ,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,WAAW,CAAC,CAAC;AAChG,MAAM,CAAC,MAAM,UAAU,GAAG,GAAW,EAAE,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,EAAE,GAAG,IAAI,CAAC,CAAC;AAEtE,MAAM,UAAU,SAAS,CAAC,CAAS,EAAE,CAAS;IAC5C,MAAM,EAAE,GAAG,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAC1B,MAAM,EAAE,GAAG,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAC1B,OAAO,EAAE,CAAC,MAAM,KAAK,EAAE,CAAC,MAAM,IAAI,eAAe,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC;AAC5D,CAAC;AAID,MAAM,KAAK,GAAG,yEAAyE,CAAC;AACxF,MAAM,KAAK,GAAG,sCAAsC,CAAC;AACrD,MAAM,UAAU,WAAW,CAAC,KAAa;IACvC,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,CAAC,MAAM,GAAG,GAAG;QAAE,OAAO,IAAI,CAAC;IACjE,MAAM,EAAE,GAAG,KAAK,CAAC,WAAW,CAAC,GAAG,CAAC,CAAC;IAClC,IAAI,EAAE,IAAI,CAAC,IAAI,EAAE,KAAK,KAAK,CAAC,MAAM,GAAG,CAAC;QAAE,OAAO,IAAI,CAAC;IACpD,MAAM,KAAK,GAAG,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;IACjC,MAAM,MAAM,GAAG,KAAK,CAAC,KAAK,CAAC,EAAE,GAAG,CAAC,CAAC,CAAC,WAAW,EAAE,CAAC;IACjD,IAAI,MAAM,CAAC,UAAU,CAAC,KAAK,CAAC,GAAG,EAAE,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC;QAAE,OAAO,IAAI,CAAC;IACrE,IAAI,MAAM,CAAC,MAAM,GAAG,GAAG;QAAE,OAAO,IAAI,CAAC;IACrC,MAAM,MAAM,GAAG,MAAM,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;IACjC,IAAI,MAAM,CAAC,MAAM,GAAG,CAAC,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAAE,OAAO,IAAI,CAAC;IAC1E,OAAO,EAAE,MAAM,EAAE,GAAG,KAAK,IAAI,MAAM,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,CAAC;AACzD,CAAC;AACD,kIAAkI;AAClI,MAAM,UAAU,OAAO,CAAC,MAAc;IACpC,MAAM,EAAE,GAAG,MAAM,CAAC,WAAW,CAAC,GAAG,CAAC,CAAC;IACnC,MAAM,QAAQ,GAAG,CAAC,GAAG,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,EAAE,MAAM,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,6BAA6B,CAAC,IAAI,CAAC,MAAM,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC,WAAW,EAAE,CAAC,QAAQ,CAAC,CAAC,EAAE,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IAChO,OAAO,QAAQ,QAAQ,IAAI,MAAM,CAAC,KAAK,CAAC,EAAE,GAAG,CAAC,CAAC,EAAE,CAAC;AACpD,CAAC;AACD,0GAA0G;AAC1G,MAAM,UAAU,YAAY,CAAC,GAAW;IACtC,IAAI,CAAC,GAAG,CAAC,UAAU,CAAC,OAAO,CAAC;QAAE,OAAO,IAAI,CAAC;IAC1C,MAAM,IAAI,GAAG,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;IAC1B,MAAM,EAAE,GAAG,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,CAAC;IACjC,IAAI,EAAE,IAAI,CAAC;QAAE,OAAO,IAAI,CAAC;IACzB,IAAI,KAAa,CAAC;IAClB,IAAI,CAAC;QACH,KAAK,GAAG,kBAAkB,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC;IAChD,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,IAAI,CAAC;IACd,CAAC;IACD,OAAO,WAAW,CAAC,GAAG,KAAK,IAAI,IAAI,CAAC,KAAK,CAAC,EAAE,GAAG,CAAC,CAAC,EAAE,CAAC,CAAC;AACvD,CAAC;AACD,qFAAqF;AACrF,MAAM,UAAU,YAAY,CAAC,CAAS,EAAE,CAAS;IAC/C,MAAM,EAAE,GAAG,WAAW,CAAC,CAAC,CAAC,CAAC;IAC1B,MAAM,EAAE,GAAG,WAAW,CAAC,CAAC,CAAC,CAAC;IAC1B,OAAO,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC,EAAE,IAAI,EAAE,CAAC,KAAK,KAAK,EAAE,CAAC,KAAK,IAAI,EAAE,CAAC,MAAM,KAAK,EAAE,CAAC,MAAM,CAAC;AAC1E,CAAC;AACD,mHAAmH;AACnH,MAAM,UAAU,YAAY,CAAC,MAAc,EAAE,aAAuB;IAClE,OAAO,aAAa,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,MAAM,CAAC,MAAM,GAAG,CAAC,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,MAAM,CAAC,CAAC,CAAC;AACtI,CAAC;AAED,wHAAwH;AACxH,MAAM,UAAU,WAAW,CAAC,MAA0B;IACpD,IAAI,CAAC,MAAM;QAAE,OAAO,KAAK,CAAC;IAC1B,IAAI,IAAI,GAAG,CAAC,CAAC;IACb,IAAI,IAAI,GAAG,CAAC,CAAC;IACb,KAAK,MAAM,IAAI,IAAI,MAAM,CAAC,KAAK,CAAC,GAAG,CAAC,EAAE,CAAC;QACrC,MAAM,CAAC,OAAO,EAAE,GAAG,MAAM,CAAC,GAAG,IAAI,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;QACpD,MAAM,IAAI,GAAG,CAAC,OAAO,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;QAClD,IAAI,CAAC,GAAG,CAAC,CAAC;QACV,KAAK,MAAM,CAAC,IAAI,MAAM,EAAE,CAAC;YACvB,MAAM,CAAC,CAAC,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;YACnC,IAAI,CAAC,EAAE,IAAI,EAAE,KAAK,GAAG,IAAI,CAAC,KAAK,SAAS;gBAAE,CAAC,GAAG,MAAM,CAAC,UAAU,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;QAC1E,CAAC;QACD,IAAI,IAAI,KAAK,kBAAkB;YAAE,IAAI,GAAG,IAAI,CAAC,GAAG,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC;aACrD,IAAI,IAAI,KAAK,WAAW;YAAE,IAAI,GAAG,IAAI,CAAC,GAAG,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC;aACnD,IAAI,IAAI,KAAK,eAAe;YAAE,IAAI,GAAG,IAAI,CAAC,GAAG,CAAC,IAAI,EAAE,CAAC,GAAG,KAAK,CAAC,CAAC;aAC/D,IAAI,IAAI,KAAK,QAAQ;YAAE,IAAI,GAAG,IAAI,CAAC,GAAG,CAAC,IAAI,EAAE,CAAC,GAAG,KAAK,CAAC,CAAC;aACxD,IAAI,IAAI,KAAK,KAAK,EAAE,CAAC;YACxB,IAAI,GAAG,IAAI,CAAC,GAAG,CAAC,IAAI,EAAE,CAAC,GAAG,KAAK,CAAC,CAAC;YACjC,IAAI,GAAG,IAAI,CAAC,GAAG,CAAC,IAAI,EAAE,CAAC,GAAG,KAAK,CAAC,CAAC;QACnC,CAAC;IACH,CAAC;IACD,OAAO,IAAI,GAAG,CAAC,IAAI,IAAI,GAAG,IAAI,CAAC;AACjC,CAAC;AAED,MAAM,UAAU,WAAW,CAAC,aAAiC;IAC3D,IAAI,CAAC,aAAa;QAAE,OAAO,IAAI,CAAC;IAChC,MAAM,CAAC,GAAG,qCAAqC,CAAC,IAAI,CAAC,aAAa,CAAC,IAAI,EAAE,CAAC,CAAC;IAC3E,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAE,CAAC,CAAC,CAAC,IAAI,CAAC;AAC1B,CAAC;AAED,2GAA2G;AAC3G,MAAM,UAAU,UAAU,CAAC,GAAY,EAAE,QAAgB;IACvD,IAAI,OAAO,GAAG,KAAK,QAAQ;QAAE,OAAO,KAAK,CAAC;IAC1C,MAAM,CAAC,GAAG,GAAG,CAAC,WAAW,EAAE,CAAC;IAC5B,OAAO,CAAC,KAAK,QAAQ,IAAI,CAAC,KAAK,eAAe,QAAQ,EAAE,CAAC;AAC3D,CAAC;AAED,MAAM,UAAU,aAAa,CAAC,CAAU;IACtC,OAAO,OAAO,CAAC,KAAK,QAAQ,IAAI,CAAC,KAAK,IAAI,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC;AAClE,CAAC"}