@substrat-run/vertical-auth 0.21.1 → 0.22.1

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.
@@ -17,6 +17,14 @@
17
17
  * and the directory then resolves them as that member. Revoking takes the principal's scope
18
18
  * roles back and then removes the invite row.
19
19
  *
20
+ * Since #1686 the token is the secret of a `become` capability in the scope's own Durable
21
+ * Object, minted by the inviter under a bound (they must hold everything the invited
22
+ * principal holds): single use, revocable, and on the spine — its mint as
23
+ * `capability.become-minted` with the inviter as actor, its accept as `capability.exercised`.
24
+ * It has no expiry, as an invite never had, and the inviter is not re-checked at accept:
25
+ * the role was bounded when it was granted, and withdrawing the invite is the lever. An
26
+ * invite minted before #1686 is redeemed the old way, by hash (`claimInvite`).
27
+ *
20
28
  * Who may invite, and at which role, are two questions (#1931). The vertical's admin gate
21
29
  * answers the first — may this caller manage members at all. The second is the kernel's
22
30
  * assignment bound (`ctx.canAssign`): a caller may confer a role only if they already hold
@@ -32,10 +40,13 @@
32
40
  * than this one with more fields.
33
41
  */
34
42
  import { HTTPException } from 'hono/http-exception';
35
- import { coverage, coverageRefusal, principalId, z } from '@substrat-run/contracts';
36
- import { ulid } from '@substrat-run/kernel';
37
- import { claimToken, invitePath, sha256Hex } from './owner-claim-link.js';
43
+ import { BECOME_LINK_STATES_MAX_IDS, boundedBecomeMint, boundedBecomeRevoke, becomeLinkState, capabilityId, coverage, coverageRefusal, principalId, z, } from '@substrat-run/contracts';
44
+ import { capabilityTokenHash, plausibleCapabilitySecret, ulid } from '@substrat-run/kernel';
45
+ import { redeemBecomeLink } from './become-link.js';
46
+ import { invitePath, sha256Hex } from './owner-claim-link.js';
38
47
  import { bodyOf } from './request-body.js';
48
+ /** The label every member invite's capability carries — what an operator's capability read shows. */
49
+ export const MEMBER_INVITE_LABEL = 'member invite';
39
50
  const inviteCaller = z.object({ principal: principalId });
40
51
  /** The body `POST /api/invites` takes. */
41
52
  export const inviteBody = z.object({
@@ -52,34 +63,117 @@ export const uncovered = (missing, roleKey, act) => new HTTPException(403, { mes
52
63
  * own `POST /api/invites` and the platform's `/internal/members/invite` (vertical-host), so the
53
64
  * two doors cannot drift on the token, the hash, or the order.
54
65
  *
55
- * Pre-mint a principal; grant it the role through `grant`, which MUST be the bounded grant
56
- * (check and write in one scope task) — a refusal returns its coverage and nothing else is
57
- * written; then record the invite under the token's SHA-256. The grant comes first: a row whose
58
- * principal holds nothing is a link to no access, while a grant with no row is inert — nobody
59
- * can bind to it. The two writes are two Durable Objects with no transaction between them, so a
60
- * failed record takes the grant back (`rollback`) before the failure is rethrown: inert is not
61
- * harmless when every retry would mint another orphan. If the rollback fails too, the ORIGINAL
62
- * failure is what the caller hears.
66
+ * Pre-mint a principal, then three writes, each failing closed:
67
+ * 1. grant it the role through `grant`, which MUST be the bounded grant (check and write in one
68
+ * scope task) — a refusal returns its coverage and nothing else is written;
69
+ * 2. mint its link (#1686): a `become` capability for that principal, single use and with no
70
+ * expiry (an invite has never had one), bounded by what the inviter holds — the scope's own
71
+ * record, on the spine as `capability.become-minted`. A refusal takes the grant back;
72
+ * 3. record the invite under the secret's hash, naming the capability.
73
+ * The grant comes first: a row whose principal holds nothing is a link to no access, while a
74
+ * grant with no row is inert — nobody can bind to it, and a capability with no row is refused
75
+ * before its exchange. The writes are two Durable Objects with no transaction between them, so a
76
+ * failed record revokes the capability and takes the grant back (`rollback`) before the failure
77
+ * is rethrown: inert is not harmless when every retry would mint another orphan. If a rollback
78
+ * step fails too, the ORIGINAL failure is what the caller hears.
63
79
  */
64
80
  export async function mintMemberInvite(steps, input) {
65
81
  const principal = principalId.parse(ulid());
66
- // A long, URL-safe token; only its hash is stored. Two UUIDs = 256 bits of entropy.
67
- const token = claimToken();
68
82
  const bound = coverage.safeParse(await steps.grant(principal));
69
83
  if (!bound.success) {
70
84
  throw new HTTPException(500, { message: 'the canAssign bound did not answer with a coverage — refusing' });
71
85
  }
72
86
  if (!bound.data.covered)
73
87
  return { ok: false, coverage: bound.data };
88
+ const ungrant = () => steps.rollback(principal).catch(() => undefined);
89
+ let minted;
74
90
  try {
75
- await steps.record(principal, await sha256Hex(token));
91
+ minted = boundedBecomeMint.parse(await steps.mint({ principal, maxUses: 1, label: MEMBER_INVITE_LABEL }));
76
92
  }
77
93
  catch (err) {
78
- await steps.rollback(principal).catch(() => undefined);
94
+ await ungrant();
95
+ throw err;
96
+ }
97
+ if (!minted.ok) {
98
+ await ungrant();
99
+ // The grant just made is what the principal holds; it holds nothing only when the role
100
+ // carries no permission at all — nothing to invite anyone into. The principal was minted
101
+ // just now, so no link to it can have been exchanged; that refusal is answered all the same.
102
+ if (!('coverage' in minted)) {
103
+ throw new HTTPException(409, {
104
+ message: minted.refused === 'target-holds-nothing'
105
+ ? `'${input.roleKey}' confers nothing here — there is nothing to invite anyone into`
106
+ : 'this invite\'s principal is already claimed — refusing a second link to it',
107
+ });
108
+ }
109
+ return { ok: false, coverage: minted.coverage };
110
+ }
111
+ const link = minted.minted;
112
+ try {
113
+ await steps.record(principal, await capabilityTokenHash(link.secret), link.id);
114
+ }
115
+ catch (err) {
116
+ await steps.revokeCapability(link.id).catch(() => undefined);
117
+ await ungrant();
79
118
  throw err;
80
119
  }
81
120
  const origin = input.origin.replace(/\/$/, '');
82
- return { ok: true, invite: { principal, roleKey: input.roleKey, email: input.email, acceptUrl: `${origin}${invitePath(token)}` } };
121
+ return { ok: true, invite: { principal, roleKey: input.roleKey, email: input.email, acceptUrl: `${origin}${invitePath(link.secret)}` } };
122
+ }
123
+ /**
124
+ * Join each invite to where its link stands (#1686), in ONE read of the scope — the list every
125
+ * pending-invite door shows, so a link the scope revoked (its principal's holdings changed) or that
126
+ * expired is never listed as open. A legacy hash-only invite has no link to read: `link: null`.
127
+ */
128
+ export async function withLinkStates(rows, states) {
129
+ const ids = rows.flatMap((r) => (r.capabilityId ? [capabilityId.parse(r.capabilityId)] : []));
130
+ // In pages of the read's cap (`BECOME_LINK_STATES_MAX_IDS`), which refuses rather than truncates.
131
+ const read = [];
132
+ for (let at = 0; at < ids.length; at += BECOME_LINK_STATES_MAX_IDS) {
133
+ const page = ids.slice(at, at + BECOME_LINK_STATES_MAX_IDS);
134
+ const answer = (await states(page)).map((s) => becomeLinkState.parse(s));
135
+ if (answer.length !== page.length)
136
+ break;
137
+ read.push(...answer);
138
+ }
139
+ if (read.length !== ids.length)
140
+ throw new HTTPException(500, { message: 'the scope answered a link state per id it was not asked for — refusing' });
141
+ const byId = new Map(ids.map((id, i) => [id, read[i]]));
142
+ return rows.map(({ capabilityId: id, ...row }) => ({ ...row, link: id ? byId.get(id) : null }));
143
+ }
144
+ /**
145
+ * Accept an invite (#1150, #1686) — the one copy every accept door runs. A capability secret is
146
+ * redeemed as every `become` link is (`redeemBecomeLink`): checked against the directory before
147
+ * the scope spends its use, exchanged, then bound only while the row still names that capability
148
+ * and principal. A token that is not a capability secret is a LEGACY hash-only invite, redeemed by
149
+ * hash (`claimInvite`). Null for every refusal, one answer.
150
+ */
151
+ export async function acceptMemberInvite(deps, scopeId, sub, token) {
152
+ if (!plausibleCapabilitySecret(token)) {
153
+ // LEGACY — a hash-only invite (see `claimInvite`).
154
+ return deps.directory.claimInvite(scopeId, sub, await sha256Hex(token));
155
+ }
156
+ return redeemBecomeLink({
157
+ matches: (hash) => deps.directory.inviteMatches(scopeId, hash),
158
+ exchange: deps.exchange,
159
+ bind: (capabilityId, principal) => deps.directory.claimInviteByCapability(scopeId, sub, capabilityId, principal),
160
+ }, token);
161
+ }
162
+ /**
163
+ * Withdraw an invite's link and then its row (#1686), once the caller's bound has taken the
164
+ * roles. The link goes first, named by the row: a revoke that fails leaves the row in place, so
165
+ * the withdrawal fails as a whole and its retry finds the link again — the scope's own record
166
+ * and the directory never part company. Revoking is idempotent, so a retry after a revoke that
167
+ * landed and a delete that did not is the same call. Then the row goes, which stops an accept.
168
+ */
169
+ export async function withdrawMemberInvite(steps, scopeId, principal) {
170
+ const link = await steps.directory.inviteLink(scopeId, principal);
171
+ if (link) {
172
+ const revoke = boundedBecomeRevoke.parse(await steps.revokeCapability(capabilityId.parse(link)));
173
+ if (!revoke.ok)
174
+ throw uncovered(revoke.coverage.missing, principal, 'withdraw the link of');
175
+ }
176
+ await steps.directory.revokeInvite(scopeId, principal);
83
177
  }
84
178
  /**
85
179
  * Mount the four invite routes on a vertical's Hono app:
@@ -106,6 +200,9 @@ export function mountInviteRoutes(app, deps) {
106
200
  if (typeof deps.assignScopeRoleBounded !== 'function') {
107
201
  throw new HTTPException(500, { message: 'invites are mounted without the bounded grant — refusing to confer an unbounded role' });
108
202
  }
203
+ if (typeof deps.mintBecomeCapabilityBounded !== 'function' || typeof deps.revokeBecomeCapability !== 'function') {
204
+ throw new HTTPException(500, { message: 'invites are mounted without the capability verbs — refusing to mint a link nothing can revoke' });
205
+ }
109
206
  const parsed = inviteCaller.safeParse(caller);
110
207
  if (!parsed.success) {
111
208
  throw new HTTPException(500, { message: 'the admin gate named no caller — refusing to confer a role the bound cannot be asked about' });
@@ -124,7 +221,9 @@ export function mountInviteRoutes(app, deps) {
124
221
  app.get('/api/invites', async (c) => {
125
222
  const node = await deps.nodeFor(c.req.raw, c.env);
126
223
  await deps.requireAdmin(c);
127
- return c.json({ roles: [...deps.roles], invites: await deps.directory(c.env, node).listInvites(node.scopeId) });
224
+ const rows = await deps.directory(c.env, node).listInvites(node.scopeId);
225
+ const invites = await withLinkStates(rows, (ids) => deps.becomeLinkStates(c.env, node, ids));
226
+ return c.json({ roles: [...deps.roles], invites });
128
227
  });
129
228
  app.post('/api/invites', async (c) => {
130
229
  const node = await deps.nodeFor(c.req.raw, c.env);
@@ -135,7 +234,9 @@ export function mountInviteRoutes(app, deps) {
135
234
  throw new HTTPException(400, { message: `unknown role '${roleKey}'` });
136
235
  const minted = await mintMemberInvite({
137
236
  grant: (assignee) => deps.assignScopeRoleBounded(c.env, node, caller.principal, assignee, roleKey),
138
- record: (principal, tokenHash) => deps.directory(c.env, node).createInvite(node.scopeId, principal, roleKey, email ?? null, tokenHash),
237
+ mint: (link) => deps.mintBecomeCapabilityBounded(c.env, node, caller.principal, link),
238
+ record: (principal, tokenHash, link) => deps.directory(c.env, node).createInvite(node.scopeId, principal, roleKey, email ?? null, tokenHash, link),
239
+ revokeCapability: (link) => deps.revokeBecomeCapability(c.env, node, link, caller.principal),
139
240
  rollback: (principal) => deps.revokeScopeRole(c.env, node.scopeId, principal, roleKey),
140
241
  }, { roleKey, email: email ?? null, origin: originOf(c.req.raw) });
141
242
  if (!minted.ok)
@@ -160,7 +261,7 @@ export function mountInviteRoutes(app, deps) {
160
261
  // principal holding nothing.
161
262
  const taken = await deps.revokeScopeRolesBounded(c.env, node, caller.principal, principal.data);
162
263
  assertCoverage(taken.coverage, principal.data, 'withdraw the invite of');
163
- await directory.revokeInvite(node.scopeId, principal.data);
264
+ await withdrawMemberInvite({ directory, revokeCapability: (link) => deps.revokeBecomeCapability(c.env, node, link, caller.principal) }, node.scopeId, principal.data);
164
265
  }
165
266
  return c.body(null, 204);
166
267
  });
@@ -176,7 +277,7 @@ export function mountInviteRoutes(app, deps) {
176
277
  if (!subject)
177
278
  throw new HTTPException(401, { message: 'sign in before accepting an invite' });
178
279
  const { token } = await bodyOf(c, acceptInviteBody);
179
- const principal = await deps.directory(c.env, node).claimInvite(node.scopeId, subject.sub, await sha256Hex(token));
280
+ const principal = await acceptMemberInvite({ directory: deps.directory(c.env, node), exchange: (secret) => deps.exchangeCapability(c.env, node, secret) }, node.scopeId, subject.sub, token);
180
281
  if (!principal)
181
282
  throw new HTTPException(400, { message: 'this invite is invalid or already used' });
182
283
  return c.json({ ok: true, principal });
@@ -1 +1 @@
1
- {"version":3,"file":"invite-routes.js","sourceRoot":"","sources":["../src/invite-routes.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"invite-routes.js","sourceRoot":"","sources":["../src/invite-routes.ts"],"names":[],"mappings":"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"}
@@ -7,6 +7,13 @@
7
7
  * An invite is a pre-minted principal + a role the inviter already granted at scope level,
8
8
  * waiting for a login to claim it by token. Only the token's HASH is stored — the token itself
9
9
  * lives in the accept link, never here, so a read of this table cannot mint access.
10
+ *
11
+ * Since #1686 the token is the secret of a `become` capability in the scope's own Durable
12
+ * Object (single use, revocable, on the spine), and `capability_id` names it: the scope judges
13
+ * the secret, this row says which capability IS the invite and which principal it seats. A row
14
+ * with no `capability_id` is LEGACY — hash alone, as every invite was before #1686 and as
15
+ * ticket0's own desk-invite flow still writes them — and is still redeemed the old way, by hash;
16
+ * an invite has no expiry, so nothing ages those out (see `claimInvite`).
10
17
  */
11
18
  import type { RegistrySql } from './site-registry.js';
12
19
  export { migrateOwnerSeat, unbindPrincipal } from './owner-seat.js';
@@ -14,12 +21,23 @@ export type { RegistrySql } from './site-registry.js';
14
21
  export declare const INVITE_DDL: string[];
15
22
  /** The whole directory an invite touches: the identity (and owner-seat) tables, then the invites. */
16
23
  export declare const MEMBER_DIRECTORY_DDL: readonly string[];
17
- /** An outstanding invite as the directory returns it — never its token. */
24
+ /**
25
+ * Bring an `invite` table from before #1686 up to date: `CREATE TABLE IF NOT EXISTS` leaves an
26
+ * existing table alone, so a directory whose storage predates `capability_id` needs the one
27
+ * `ALTER`, and every row it had reads as legacy (NULL). Idempotent — run it after the DDL.
28
+ */
29
+ export declare function migrateInvites(sql: RegistrySql): void;
30
+ /**
31
+ * An outstanding invite as the directory returns it — never its token. `capabilityId` names the
32
+ * `become` capability its link is (#1686), so a list can ask the scope where that link stands;
33
+ * null for a legacy hash-only invite.
34
+ */
18
35
  export type InviteRow = {
19
36
  principal: string;
20
37
  roleKey: string;
21
38
  email: string | null;
22
39
  createdAt: number;
40
+ capabilityId: string | null;
23
41
  };
24
42
  /** One principal as the identity directory knows it at a scope (#1150). */
25
43
  export type MemberBinding = {
@@ -27,20 +45,56 @@ export type MemberBinding = {
27
45
  logins: number;
28
46
  email: string | null;
29
47
  };
30
- export declare function createInvite(sql: RegistrySql, scopeId: string, principal: string, roleKey: string, email: string | null, tokenHash: string): void;
48
+ /**
49
+ * Record an invite under its token's hash. `capabilityId` names the `become` capability whose
50
+ * secret the token is (#1686); null writes a legacy hash-only row, which this package's own
51
+ * invite routes no longer mint.
52
+ */
53
+ export declare function createInvite(sql: RegistrySql, scopeId: string, principal: string, roleKey: string, email: string | null, tokenHash: string, capabilityId?: string | null): void;
31
54
  /** The scope's outstanding (unclaimed) invites, newest first. No token. */
32
55
  export declare function listInvites(sql: RegistrySql, scopeId: string): InviteRow[];
33
56
  /** One outstanding invite by its pre-minted principal, or null (#1931). */
34
57
  export declare function getInvite(sql: RegistrySql, scopeId: string, principal: string): InviteRow | null;
35
58
  export declare function inviteExists(sql: RegistrySql, scopeId: string, tokenHash: string): boolean;
36
- /** Withdraw an unclaimed invite by its pre-minted principal. */
37
- export declare function revokeInvite(sql: RegistrySql, scopeId: string, principal: string): void;
38
- /**
39
- * Claim an invite: bind the verified subject to the invite's pre-minted principal and consume
40
- * the invite, with no await between the read and the writes — so in the Durable Object a
41
- * withdrawal (`revokeInvite`) and a claim are serialized, and a claim after a withdrawal finds
42
- * nothing. Returns the principal, or null when no unclaimed invite matches. It writes nothing
43
- * to the scope: the role was granted when the invite was minted.
59
+ /**
60
+ * Withdraw an unclaimed invite by its pre-minted principal. Returns the `become` capability its
61
+ * link was (#1686), or null for a legacy invite, or none. Deleting the row is what stops an
62
+ * accept here; a withdrawal revokes the link in the scope BEFORE this (`inviteLink`).
63
+ */
64
+ export declare function revokeInvite(sql: RegistrySql, scopeId: string, principal: string): string | null;
65
+ /**
66
+ * The `become` capability an open invite's link is (#1686), or null — a legacy invite, or none.
67
+ * What a withdrawal revokes FIRST, while the row is still there to name it: a revoke that fails
68
+ * leaves the row, and the retry finds the link again.
69
+ */
70
+ export declare function inviteLink(sql: RegistrySql, scopeId: string, principal: string): string | null;
71
+ /**
72
+ * Is `tokenHash` an open capability-era invite here (#1686)? Asked BEFORE the secret is
73
+ * exchanged, so a secret that is no open invite — withdrawn, already accepted, or a `become`
74
+ * capability minted for something else — is refused without spending its use. The exchange is
75
+ * still the authority: this only decides whether to ask it.
76
+ */
77
+ export declare function inviteMatches(sql: RegistrySql, scopeId: string, tokenHash: string): boolean;
78
+ /**
79
+ * Accept an invite with an exchanged `become` capability (#1686): the scope has taken the
80
+ * capability's one use and answered the principal it becomes. Binds the subject when an open
81
+ * invite here names that capability AND that principal, and consumes it — so a withdrawal
82
+ * landing between the exchange and this finds nothing to bind. Null otherwise, one answer.
83
+ */
84
+ export declare function claimInviteByCapability(sql: RegistrySql, scopeId: string, sub: string, capabilityId: string, principal: string): string | null;
85
+ /**
86
+ * LEGACY (#1686) — claim an invite minted before invites became `become` capabilities, by its
87
+ * token's hash: bind the verified subject to the invite's pre-minted principal and consume the
88
+ * invite, with no await between the read and the writes — so in the Durable Object a withdrawal
89
+ * (`revokeInvite`) and a claim are serialized, and a claim after a withdrawal finds nothing.
90
+ * Returns the principal, or null when no unclaimed legacy invite matches. It writes nothing to
91
+ * the scope: the role was granted when the invite was minted.
92
+ *
93
+ * A capability-era row is NEVER claimed here, whatever hash is presented: its secret goes
94
+ * through the scope's exchange (`claimInviteByCapability`), which is what spends its one use
95
+ * and puts it on the spine. Unlike an owner claim link, a legacy invite never expires, so this
96
+ * path cannot age out on a timer: it stays until every legacy row is accepted or withdrawn, or
97
+ * a cut-off is decided.
44
98
  */
45
99
  export declare function claimInvite(sql: RegistrySql, scopeId: string, sub: string, tokenHash: string): string | null;
46
100
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"member-directory.d.ts","sourceRoot":"","sources":["../src/member-directory.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AACH,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AAItD,OAAO,EAAE,gBAAgB,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAC;AACpE,YAAY,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AAEtD,eAAO,MAAM,UAAU,EAAE,MAAM,EAM9B,CAAC;AAEF,qGAAqG;AACrG,eAAO,MAAM,oBAAoB,EAAE,SAAS,MAAM,EAAuC,CAAC;AAE1F,2EAA2E;AAC3E,MAAM,MAAM,SAAS,GAAG;IAAE,SAAS,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IAAC,SAAS,EAAE,MAAM,CAAA;CAAE,CAAC;AAExG,2EAA2E;AAC3E,MAAM,MAAM,aAAa,GAAG;IAAE,SAAS,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,GAAG,IAAI,CAAA;CAAE,CAAC;AASxF,wBAAgB,YAAY,CAC1B,GAAG,EAAE,WAAW,EAAE,OAAO,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,IAAI,EAAE,SAAS,EAAE,MAAM,GAC7G,IAAI,CAKN;AAED,2EAA2E;AAC3E,wBAAgB,WAAW,CAAC,GAAG,EAAE,WAAW,EAAE,OAAO,EAAE,MAAM,GAAG,SAAS,EAAE,CAK1E;AAED,2EAA2E;AAC3E,wBAAgB,SAAS,CAAC,GAAG,EAAE,WAAW,EAAE,OAAO,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,SAAS,GAAG,IAAI,CAMhG;AAED,wBAAgB,YAAY,CAAC,GAAG,EAAE,WAAW,EAAE,OAAO,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,OAAO,CAE1F;AAED,gEAAgE;AAChE,wBAAgB,YAAY,CAAC,GAAG,EAAE,WAAW,EAAE,OAAO,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,IAAI,CAEvF;AAED;;;;;;GAMG;AACH,wBAAgB,WAAW,CAAC,GAAG,EAAE,WAAW,EAAE,OAAO,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAM5G;AAED;;;;GAIG;AACH,wBAAgB,kBAAkB,CAAC,GAAG,EAAE,WAAW,EAAE,OAAO,EAAE,MAAM,GAAG,aAAa,EAAE,CAarF"}
1
+ {"version":3,"file":"member-directory.d.ts","sourceRoot":"","sources":["../src/member-directory.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AACH,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AAItD,OAAO,EAAE,gBAAgB,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAC;AACpE,YAAY,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AAEtD,eAAO,MAAM,UAAU,EAAE,MAAM,EAO9B,CAAC;AAEF,qGAAqG;AACrG,eAAO,MAAM,oBAAoB,EAAE,SAAS,MAAM,EAAuC,CAAC;AAE1F;;;;GAIG;AACH,wBAAgB,cAAc,CAAC,GAAG,EAAE,WAAW,GAAG,IAAI,CAGrD;AAED;;;;GAIG;AACH,MAAM,MAAM,SAAS,GAAG;IAAE,SAAS,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IAAC,SAAS,EAAE,MAAM,CAAC;IAAC,YAAY,EAAE,MAAM,GAAG,IAAI,CAAA;CAAE,CAAC;AAErI,2EAA2E;AAC3E,MAAM,MAAM,aAAa,GAAG;IAAE,SAAS,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,GAAG,IAAI,CAAA;CAAE,CAAC;AAUxF;;;;GAIG;AACH,wBAAgB,YAAY,CAC1B,GAAG,EAAE,WAAW,EAAE,OAAO,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,IAAI,EAAE,SAAS,EAAE,MAAM,EAC9G,YAAY,GAAE,MAAM,GAAG,IAAW,GACjC,IAAI,CAKN;AAED,2EAA2E;AAC3E,wBAAgB,WAAW,CAAC,GAAG,EAAE,WAAW,EAAE,OAAO,EAAE,MAAM,GAAG,SAAS,EAAE,CAK1E;AAED,2EAA2E;AAC3E,wBAAgB,SAAS,CAAC,GAAG,EAAE,WAAW,EAAE,OAAO,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,SAAS,GAAG,IAAI,CAMhG;AAED,wBAAgB,YAAY,CAAC,GAAG,EAAE,WAAW,EAAE,OAAO,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,OAAO,CAE1F;AAED;;;;GAIG;AACH,wBAAgB,YAAY,CAAC,GAAG,EAAE,WAAW,EAAE,OAAO,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAMhG;AAED;;;;GAIG;AACH,wBAAgB,UAAU,CAAC,GAAG,EAAE,WAAW,EAAE,OAAO,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAM9F;AAED;;;;;GAKG;AACH,wBAAgB,aAAa,CAAC,GAAG,EAAE,WAAW,EAAE,OAAO,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,OAAO,CAK3F;AAED;;;;;GAKG;AACH,wBAAgB,uBAAuB,CACrC,GAAG,EAAE,WAAW,EAAE,OAAO,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GACtF,MAAM,GAAG,IAAI,CAMf;AASD;;;;;;;;;;;;;GAaG;AACH,wBAAgB,WAAW,CAAC,GAAG,EAAE,WAAW,EAAE,OAAO,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAM5G;AAED;;;;GAIG;AACH,wBAAgB,kBAAkB,CAAC,GAAG,EAAE,WAAW,EAAE,OAAO,EAAE,MAAM,GAAG,aAAa,EAAE,CAarF"}
@@ -5,50 +5,109 @@ export const INVITE_DDL = [
5
5
  `CREATE TABLE IF NOT EXISTS invite (
6
6
  token_hash TEXT PRIMARY KEY, scope_id TEXT NOT NULL, principal TEXT NOT NULL,
7
7
  role_key TEXT NOT NULL, email TEXT, claimed INTEGER NOT NULL DEFAULT 0,
8
- created_at INTEGER NOT NULL DEFAULT (cast(unixepoch('subsecond') * 1000 as integer)))`,
8
+ created_at INTEGER NOT NULL DEFAULT (cast(unixepoch('subsecond') * 1000 as integer)),
9
+ capability_id TEXT)`,
9
10
  `CREATE INDEX IF NOT EXISTS invite_by_scope ON invite (scope_id)`,
10
11
  ];
11
12
  /** The whole directory an invite touches: the identity (and owner-seat) tables, then the invites. */
12
13
  export const MEMBER_DIRECTORY_DDL = [...OWNER_SEAT_DDL, ...INVITE_DDL];
14
+ /**
15
+ * Bring an `invite` table from before #1686 up to date: `CREATE TABLE IF NOT EXISTS` leaves an
16
+ * existing table alone, so a directory whose storage predates `capability_id` needs the one
17
+ * `ALTER`, and every row it had reads as legacy (NULL). Idempotent — run it after the DDL.
18
+ */
19
+ export function migrateInvites(sql) {
20
+ const columns = [...sql.exec('PRAGMA table_info(invite)')].map((r) => r.name);
21
+ if (!columns.includes('capability_id'))
22
+ sql.exec('ALTER TABLE invite ADD COLUMN capability_id TEXT');
23
+ }
13
24
  const inviteRowOf = (r) => ({
14
25
  principal: r.principal,
15
26
  roleKey: r.role_key,
16
27
  email: r.email ?? null,
17
28
  createdAt: Number(r.created_at),
29
+ capabilityId: r.capability_id ?? null,
18
30
  });
19
- export function createInvite(sql, scopeId, principal, roleKey, email, tokenHash) {
20
- sql.exec('INSERT INTO invite (token_hash, scope_id, principal, role_key, email) VALUES (?, ?, ?, ?, ?)', tokenHash, scopeId, principal, roleKey, email);
31
+ /**
32
+ * Record an invite under its token's hash. `capabilityId` names the `become` capability whose
33
+ * secret the token is (#1686); null writes a legacy hash-only row, which this package's own
34
+ * invite routes no longer mint.
35
+ */
36
+ export function createInvite(sql, scopeId, principal, roleKey, email, tokenHash, capabilityId = null) {
37
+ sql.exec('INSERT INTO invite (token_hash, scope_id, principal, role_key, email, capability_id) VALUES (?, ?, ?, ?, ?, ?)', tokenHash, scopeId, principal, roleKey, email, capabilityId);
21
38
  }
22
39
  /** The scope's outstanding (unclaimed) invites, newest first. No token. */
23
40
  export function listInvites(sql, scopeId) {
24
- return [...sql.exec('SELECT principal, role_key, email, created_at FROM invite WHERE scope_id = ? AND claimed = 0 ORDER BY created_at DESC', scopeId)].map(inviteRowOf);
41
+ return [...sql.exec('SELECT principal, role_key, email, created_at, capability_id FROM invite WHERE scope_id = ? AND claimed = 0 ORDER BY created_at DESC', scopeId)].map(inviteRowOf);
25
42
  }
26
43
  /** One outstanding invite by its pre-minted principal, or null (#1931). */
27
44
  export function getInvite(sql, scopeId, principal) {
28
- const r = [...sql.exec('SELECT principal, role_key, email, created_at FROM invite WHERE scope_id = ? AND principal = ? AND claimed = 0', scopeId, principal)][0];
45
+ const r = [...sql.exec('SELECT principal, role_key, email, created_at, capability_id FROM invite WHERE scope_id = ? AND principal = ? AND claimed = 0', scopeId, principal)][0];
29
46
  return r ? inviteRowOf(r) : null;
30
47
  }
31
48
  export function inviteExists(sql, scopeId, tokenHash) {
32
49
  return [...sql.exec('SELECT 1 FROM invite WHERE scope_id = ? AND token_hash = ? AND claimed = 0', scopeId, tokenHash)].length > 0;
33
50
  }
34
- /** Withdraw an unclaimed invite by its pre-minted principal. */
51
+ /**
52
+ * Withdraw an unclaimed invite by its pre-minted principal. Returns the `become` capability its
53
+ * link was (#1686), or null for a legacy invite, or none. Deleting the row is what stops an
54
+ * accept here; a withdrawal revokes the link in the scope BEFORE this (`inviteLink`).
55
+ */
35
56
  export function revokeInvite(sql, scopeId, principal) {
36
- sql.exec('DELETE FROM invite WHERE scope_id = ? AND principal = ? AND claimed = 0', scopeId, principal);
57
+ const gone = [...sql.exec('DELETE FROM invite WHERE scope_id = ? AND principal = ? AND claimed = 0 RETURNING capability_id', scopeId, principal)][0];
58
+ return gone?.capability_id ?? null;
37
59
  }
38
60
  /**
39
- * Claim an invite: bind the verified subject to the invite's pre-minted principal and consume
40
- * the invite, with no await between the read and the writes — so in the Durable Object a
41
- * withdrawal (`revokeInvite`) and a claim are serialized, and a claim after a withdrawal finds
42
- * nothing. Returns the principal, or null when no unclaimed invite matches. It writes nothing
43
- * to the scope: the role was granted when the invite was minted.
61
+ * The `become` capability an open invite's link is (#1686), or null — a legacy invite, or none.
62
+ * What a withdrawal revokes FIRST, while the row is still there to name it: a revoke that fails
63
+ * leaves the row, and the retry finds the link again.
44
64
  */
45
- export function claimInvite(sql, scopeId, sub, tokenHash) {
46
- const inv = [...sql.exec('SELECT principal FROM invite WHERE scope_id = ? AND token_hash = ? AND claimed = 0', scopeId, tokenHash)][0];
47
- if (!inv)
48
- return null;
49
- sql.exec('INSERT OR REPLACE INTO identity (scope_id, sub, principal) VALUES (?, ?, ?)', scopeId, sub, inv.principal);
65
+ export function inviteLink(sql, scopeId, principal) {
66
+ const open = [...sql.exec('SELECT capability_id FROM invite WHERE scope_id = ? AND principal = ? AND claimed = 0', scopeId, principal)][0];
67
+ return open?.capability_id ?? null;
68
+ }
69
+ /**
70
+ * Is `tokenHash` an open capability-era invite here (#1686)? Asked BEFORE the secret is
71
+ * exchanged, so a secret that is no open invite — withdrawn, already accepted, or a `become`
72
+ * capability minted for something else — is refused without spending its use. The exchange is
73
+ * still the authority: this only decides whether to ask it.
74
+ */
75
+ export function inviteMatches(sql, scopeId, tokenHash) {
76
+ return [...sql.exec('SELECT 1 FROM invite WHERE scope_id = ? AND token_hash = ? AND claimed = 0 AND capability_id IS NOT NULL', scopeId, tokenHash)].length > 0;
77
+ }
78
+ /**
79
+ * Accept an invite with an exchanged `become` capability (#1686): the scope has taken the
80
+ * capability's one use and answered the principal it becomes. Binds the subject when an open
81
+ * invite here names that capability AND that principal, and consumes it — so a withdrawal
82
+ * landing between the exchange and this finds nothing to bind. Null otherwise, one answer.
83
+ */
84
+ export function claimInviteByCapability(sql, scopeId, sub, capabilityId, principal) {
85
+ const inv = [...sql.exec('SELECT token_hash FROM invite WHERE scope_id = ? AND capability_id = ? AND principal = ? AND claimed = 0', scopeId, capabilityId, principal)][0];
86
+ return inv ? bindInvite(sql, scopeId, sub, principal, inv.token_hash) : null;
87
+ }
88
+ /** Bind the subject to the invite's principal and consume the invite — the write both claims share. */
89
+ function bindInvite(sql, scopeId, sub, principal, tokenHash) {
90
+ sql.exec('INSERT OR REPLACE INTO identity (scope_id, sub, principal) VALUES (?, ?, ?)', scopeId, sub, principal);
50
91
  sql.exec('UPDATE invite SET claimed = 1 WHERE scope_id = ? AND token_hash = ?', scopeId, tokenHash);
51
- return inv.principal;
92
+ return principal;
93
+ }
94
+ /**
95
+ * LEGACY (#1686) — claim an invite minted before invites became `become` capabilities, by its
96
+ * token's hash: bind the verified subject to the invite's pre-minted principal and consume the
97
+ * invite, with no await between the read and the writes — so in the Durable Object a withdrawal
98
+ * (`revokeInvite`) and a claim are serialized, and a claim after a withdrawal finds nothing.
99
+ * Returns the principal, or null when no unclaimed legacy invite matches. It writes nothing to
100
+ * the scope: the role was granted when the invite was minted.
101
+ *
102
+ * A capability-era row is NEVER claimed here, whatever hash is presented: its secret goes
103
+ * through the scope's exchange (`claimInviteByCapability`), which is what spends its one use
104
+ * and puts it on the spine. Unlike an owner claim link, a legacy invite never expires, so this
105
+ * path cannot age out on a timer: it stays until every legacy row is accepted or withdrawn, or
106
+ * a cut-off is decided.
107
+ */
108
+ export function claimInvite(sql, scopeId, sub, tokenHash) {
109
+ const inv = [...sql.exec('SELECT principal FROM invite WHERE scope_id = ? AND token_hash = ? AND claimed = 0 AND capability_id IS NULL', scopeId, tokenHash)][0];
110
+ return inv ? bindInvite(sql, scopeId, sub, inv.principal, tokenHash) : null;
52
111
  }
53
112
  /**
54
113
  * Who this directory knows at the scope, by principal (#1150): how many subjects are bound to
@@ -1 +1 @@
1
- {"version":3,"file":"member-directory.js","sourceRoot":"","sources":["../src/member-directory.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"member-directory.js","sourceRoot":"","sources":["../src/member-directory.ts"],"names":[],"mappings":"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"}
@@ -30,7 +30,7 @@ export declare const UNATTRIBUTED_PLATFORM_ACTOR: PlatformActorId;
30
30
  */
31
31
  export interface OwnerClaimMintHost {
32
32
  mintCapabilityLocal(tenantId: TenantId, scopeId: ScopeId, input: BecomeCapabilityInput, actor: PlatformActorId): Promise<MintedCapability>;
33
- revokeCapabilityLocal(scopeId: ScopeId, capabilityId: CapabilityId, actor: PlatformActorId): Promise<boolean>;
33
+ revokeCapabilityLocal(scopeId: ScopeId, capabilityId: CapabilityId, actor: PlatformActorId): Promise<unknown>;
34
34
  }
35
35
  /** The slice of the identity directory a mint touches. */
36
36
  export type OwnerClaimMintDirectory = Pick<IdentityStub, 'ownerClaimTarget' | 'recordOwnerClaim'>;
@@ -21,18 +21,16 @@
21
21
  * only if that capability is still the recorded link and names the pending owner.
22
22
  *
23
23
  * Every refusal after step 1 is the same 400, so a probe learns nothing about which step said no.
24
- *
25
- * LEGACY: a token that is not a capability secret is a link minted before #1686, and is redeemed
26
- * the old way (`claimOwner`, by hash) until it expires — at most `OWNER_CLAIM_TTL_MS` after the
27
- * deploy that ships this. REMOVE that branch in the release after the one that ships #1686
28
- * (written 2026-10-04), with `claimOwner` in owner-seat.ts.
24
+ * A token that is not a capability secret at all gets it too: the hash-only links #925 minted
25
+ * before #1686 are no longer redeemed — every one of them expired `OWNER_CLAIM_TTL_MS` after it
26
+ * was minted, and the release after #1686 has long shipped.
29
27
  */
30
28
  import type { Context, Hono } from 'hono';
31
29
  import { z, type CapabilityExchange, type ScopeId, type TenantId } from '@substrat-run/contracts';
32
30
  import type { IdentityStub } from './identity-do.js';
33
31
  import type { AuthProvider, AuthSubject } from './provider.js';
34
32
  /** The slice of the identity directory the redemption touches. */
35
- export type OwnerClaimDirectory = Pick<IdentityStub, 'ownerClaimMatches' | 'claimOwnerByCapability' | 'claimOwner'>;
33
+ export type OwnerClaimDirectory = Pick<IdentityStub, 'ownerClaimMatches' | 'claimOwnerByCapability'>;
36
34
  /** What the redemption needs of the scope host: the exchange, asked for a `become` capability only. */
37
35
  export interface OwnerClaimExchangeHost {
38
36
  exchangeCapability(tenantId: TenantId, scopeId: ScopeId, secret: string, options?: {
@@ -1 +1 @@
1
- {"version":3,"file":"owner-claim-routes.d.ts","sourceRoot":"","sources":["../src/owner-claim-routes.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AAEH,OAAO,KAAK,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;AAE1C,OAAO,EAAE,CAAC,EAAE,KAAK,kBAAkB,EAAE,KAAK,OAAO,EAAE,KAAK,QAAQ,EAAE,MAAM,yBAAyB,CAAC;AAElG,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAC;AAErD,OAAO,KAAK,EAAE,YAAY,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAG/D,kEAAkE;AAClE,MAAM,MAAM,mBAAmB,GAAG,IAAI,CAAC,YAAY,EAAE,mBAAmB,GAAG,wBAAwB,GAAG,YAAY,CAAC,CAAC;AAEpH,uGAAuG;AACvG,MAAM,WAAW,sBAAsB;IACrC,kBAAkB,CAChB,QAAQ,EAAE,QAAQ,EAClB,OAAO,EAAE,OAAO,EAChB,MAAM,EAAE,MAAM,EACd,OAAO,CAAC,EAAE;QAAE,IAAI,CAAC,EAAE,KAAK,GAAG,QAAQ,CAAA;KAAE,GACpC,OAAO,CAAC,kBAAkB,GAAG,IAAI,CAAC,CAAC;CACvC;AAED,8CAA8C;AAC9C,eAAO,MAAM,cAAc;;iBAAyC,CAAC;AAErE,uDAAuD;AACvD,MAAM,WAAW,YAAY,CAAC,CAAC;IAC7B,IAAI,EAAE,CAAC,CAAC;IACR,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,WAAW,CAAC;CACtB;AAED,gGAAgG;AAChG,MAAM,WAAW,mBAAmB,CAAC,CAAC,SAAS,MAAM,EAAE,CAAC,SAAS;IAAE,QAAQ,EAAE,QAAQ,CAAC;IAAC,OAAO,EAAE,OAAO,CAAA;CAAE;IACvG,0FAA0F;IAC1F,OAAO,EAAE,CAAC,GAAG,EAAE,OAAO,EAAE,GAAG,EAAE,CAAC,KAAK,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,CAAC;IAClD,mGAAmG;IACnG,YAAY,EAAE,CAAC,GAAG,EAAE,CAAC,EAAE,GAAG,EAAE,OAAO,KAAK,OAAO,CAAC,YAAY,CAAC,CAAC;IAC9D,wFAAwF;IACxF,SAAS,EAAE,CAAC,GAAG,EAAE,CAAC,EAAE,IAAI,EAAE,CAAC,KAAK,mBAAmB,CAAC;IACpD,gEAAgE;IAChE,IAAI,EAAE,CAAC,GAAG,EAAE,CAAC,KAAK,sBAAsB,CAAC;IACzC;;;OAGG;IACH,IAAI,CAAC,EAAE,MAAM,CAAC;IACd;;;OAGG;IACH,SAAS,CAAC,EAAE,CAAC,CAAC,EAAE,OAAO,CAAC;QAAE,QAAQ,EAAE,CAAC,CAAA;KAAE,CAAC,EAAE,OAAO,EAAE,YAAY,CAAC,CAAC,CAAC,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;CACtF;AAKD;;;;;GAKG;AACH,wBAAgB,eAAe,CAAC,CAAC,SAAS,MAAM,EAAE,CAAC,SAAS;IAAE,QAAQ,EAAE,QAAQ,CAAC;IAAC,OAAO,EAAE,OAAO,CAAA;CAAE,EAClG,GAAG,EAAE,IAAI,CAAC;IAAE,QAAQ,EAAE,CAAC,CAAA;CAAE,CAAC,EAC1B,IAAI,EAAE,mBAAmB,CAAC,CAAC,EAAE,CAAC,CAAC,GAC9B,IAAI,CA4BN"}
1
+ {"version":3,"file":"owner-claim-routes.d.ts","sourceRoot":"","sources":["../src/owner-claim-routes.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AAEH,OAAO,KAAK,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;AAE1C,OAAO,EAAE,CAAC,EAAE,KAAK,kBAAkB,EAAE,KAAK,OAAO,EAAE,KAAK,QAAQ,EAAE,MAAM,yBAAyB,CAAC;AAElG,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAC;AACrD,OAAO,KAAK,EAAE,YAAY,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAG/D,kEAAkE;AAClE,MAAM,MAAM,mBAAmB,GAAG,IAAI,CAAC,YAAY,EAAE,mBAAmB,GAAG,wBAAwB,CAAC,CAAC;AAErG,uGAAuG;AACvG,MAAM,WAAW,sBAAsB;IACrC,kBAAkB,CAChB,QAAQ,EAAE,QAAQ,EAClB,OAAO,EAAE,OAAO,EAChB,MAAM,EAAE,MAAM,EACd,OAAO,CAAC,EAAE;QAAE,IAAI,CAAC,EAAE,KAAK,GAAG,QAAQ,CAAA;KAAE,GACpC,OAAO,CAAC,kBAAkB,GAAG,IAAI,CAAC,CAAC;CACvC;AAED,8CAA8C;AAC9C,eAAO,MAAM,cAAc;;iBAAyC,CAAC;AAErE,uDAAuD;AACvD,MAAM,WAAW,YAAY,CAAC,CAAC;IAC7B,IAAI,EAAE,CAAC,CAAC;IACR,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,WAAW,CAAC;CACtB;AAED,gGAAgG;AAChG,MAAM,WAAW,mBAAmB,CAAC,CAAC,SAAS,MAAM,EAAE,CAAC,SAAS;IAAE,QAAQ,EAAE,QAAQ,CAAC;IAAC,OAAO,EAAE,OAAO,CAAA;CAAE;IACvG,0FAA0F;IAC1F,OAAO,EAAE,CAAC,GAAG,EAAE,OAAO,EAAE,GAAG,EAAE,CAAC,KAAK,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,CAAC;IAClD,mGAAmG;IACnG,YAAY,EAAE,CAAC,GAAG,EAAE,CAAC,EAAE,GAAG,EAAE,OAAO,KAAK,OAAO,CAAC,YAAY,CAAC,CAAC;IAC9D,wFAAwF;IACxF,SAAS,EAAE,CAAC,GAAG,EAAE,CAAC,EAAE,IAAI,EAAE,CAAC,KAAK,mBAAmB,CAAC;IACpD,gEAAgE;IAChE,IAAI,EAAE,CAAC,GAAG,EAAE,CAAC,KAAK,sBAAsB,CAAC;IACzC;;;OAGG;IACH,IAAI,CAAC,EAAE,MAAM,CAAC;IACd;;;OAGG;IACH,SAAS,CAAC,EAAE,CAAC,CAAC,EAAE,OAAO,CAAC;QAAE,QAAQ,EAAE,CAAC,CAAA;KAAE,CAAC,EAAE,OAAO,EAAE,YAAY,CAAC,CAAC,CAAC,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;CACtF;AAKD;;;;;GAKG;AACH,wBAAgB,eAAe,CAAC,CAAC,SAAS,MAAM,EAAE,CAAC,SAAS;IAAE,QAAQ,EAAE,QAAQ,CAAC;IAAC,OAAO,EAAE,OAAO,CAAA;CAAE,EAClG,GAAG,EAAE,IAAI,CAAC;IAAE,QAAQ,EAAE,CAAC,CAAA;CAAE,CAAC,EAC1B,IAAI,EAAE,mBAAmB,CAAC,CAAC,EAAE,CAAC,CAAC,GAC9B,IAAI,CAqBN"}