@c9up/visa 0.1.2 → 0.1.4

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 (56) hide show
  1. package/README.md +82 -11
  2. package/dist/VisaManager.d.ts +49 -0
  3. package/dist/VisaManager.d.ts.map +1 -1
  4. package/dist/VisaManager.js +181 -9
  5. package/dist/VisaManager.js.map +1 -1
  6. package/dist/VisaProvider.d.ts +4 -0
  7. package/dist/VisaProvider.d.ts.map +1 -1
  8. package/dist/VisaProvider.js +87 -5
  9. package/dist/VisaProvider.js.map +1 -1
  10. package/dist/clients.d.ts +1 -1
  11. package/dist/clients.d.ts.map +1 -1
  12. package/dist/clients.js +9 -1
  13. package/dist/clients.js.map +1 -1
  14. package/dist/configure.d.ts.map +1 -1
  15. package/dist/configure.js +16 -1
  16. package/dist/configure.js.map +1 -1
  17. package/dist/guard.d.ts +2 -1
  18. package/dist/guard.d.ts.map +1 -1
  19. package/dist/guard.js +18 -14
  20. package/dist/guard.js.map +1 -1
  21. package/dist/index.d.ts +1 -1
  22. package/dist/index.d.ts.map +1 -1
  23. package/dist/index.js.map +1 -1
  24. package/dist/register.d.ts +12 -1
  25. package/dist/register.d.ts.map +1 -1
  26. package/dist/register.js +44 -9
  27. package/dist/register.js.map +1 -1
  28. package/dist/store.d.ts +10 -0
  29. package/dist/store.d.ts.map +1 -1
  30. package/dist/stores/atlas.d.ts +1 -1
  31. package/dist/stores/atlas.d.ts.map +1 -1
  32. package/dist/stores/atlas.js +6 -1
  33. package/dist/stores/atlas.js.map +1 -1
  34. package/dist/stores/memory.d.ts +1 -2
  35. package/dist/stores/memory.d.ts.map +1 -1
  36. package/dist/stores/memory.js +1 -3
  37. package/dist/stores/memory.js.map +1 -1
  38. package/dist/token.js +17 -5
  39. package/dist/token.js.map +1 -1
  40. package/dist/types.d.ts +9 -0
  41. package/dist/types.d.ts.map +1 -1
  42. package/package.json +1 -1
  43. package/src/VisaManager.ts +226 -12
  44. package/src/VisaProvider.ts +108 -6
  45. package/src/clients.ts +10 -0
  46. package/src/configure.ts +17 -1
  47. package/src/guard.ts +23 -14
  48. package/src/index.ts +1 -0
  49. package/src/register.ts +55 -9
  50. package/src/store.ts +11 -0
  51. package/src/stores/atlas.ts +6 -1
  52. package/src/stores/memory.ts +1 -3
  53. package/src/token.ts +30 -11
  54. package/src/types.ts +9 -0
  55. package/stubs/database/migrations/9000_create_visa_tables.stub +2 -0
  56. package/stubs/database/migrations/9001_add_visa_client_secret_expiry.stub +29 -0
package/README.md CHANGED
@@ -41,13 +41,39 @@ consent screen, and both belong to your application. See below.
41
41
  - **Refresh rotation with replay detection.** Every use mints a new token; a
42
42
  spent one coming back proves a leak, and since there is no telling the thief
43
43
  from the victim, the whole family goes.
44
+ - **Parameters in the body only.** `/token`, `/introspect`, `/revoke` and
45
+ `/register` read the request body only, and answer `invalid_request` to a
46
+ request that puts an OAuth parameter (`client_secret`, `code`, `token`,
47
+ `refresh_token`, registration metadata on `/register`…) in the query
48
+ string: a secret, a code or a token in a URL ends up in access logs,
49
+ proxies and traces (RFC 6749 §2.3.1). Other query parameters are ignored.
50
+ - **A scope is not a permission.** `visaGuard()` puts the token's scopes on
51
+ `ctx.auth.user.currentAccessToken` (`allows`, `denies`, `authorize`) and
52
+ leaves `user.permissions` as your user provider returned it. A scope is
53
+ chosen by the client and granted by consent, which never checks the user's
54
+ own rights — so a route that needs both checks both.
44
55
  - **One sentence per failure.** "No such code", "expired", "already used" and
45
56
  "wrong client" are `invalid_grant: The code is not valid.` — telling them
46
57
  apart is how a code space gets probed.
47
58
 
48
59
  ## Wiring `/authorize`
49
60
 
50
- The decision is visa's; the page is yours.
61
+ The decision is visa's; the page is yours. The consent page is the one place a
62
+ user hands an application their data, so three things are not optional:
63
+
64
+ - **The consent POST is CSRF-protected.** Without it, a page on another site
65
+ auto-submits the form — its own client, its own PKCE challenge,
66
+ `approve=1` — and a signed-in user grants the attacker's application without
67
+ seeing anything (RFC 6819 §4.4.1.9). Turn on blackhole's CSRF
68
+ (`csrf: true` in `config/blackhole.ts`) and put `{{ csrfField() }}` in the
69
+ form.
70
+ - **The consent page cannot be framed.** A framed page lets another site lay
71
+ its own button over "Allow" (clickjacking, RFC 9700 §4.15). Send
72
+ `X-Frame-Options: DENY` from this page, and `frame-ancestors 'none'` if you
73
+ build its `Content-Security-Policy` yourself.
74
+ - **The POST grants what the page showed, not what the POST says.** The
75
+ validated request stays on the server, in a single-use ticket bound to the
76
+ session and the user. The form carries only the ticket's id.
51
77
 
52
78
  ```ts
53
79
  // start/routes.ts
@@ -63,22 +89,55 @@ router.get('/oauth/authorize', async (ctx) => {
63
89
  }
64
90
  if (!ctx.auth.user) return ctx.response.redirect('/login?next=' + encodeURIComponent(ctx.request.url(true)))
65
91
 
92
+ // Kept server-side: the POST below grants this, whatever it is sent.
93
+ const ticket = visa.consentTicket(outcome.request, ctx.auth.user.id)
94
+ ctx.session.put('visa.consent', ticket)
95
+
96
+ ctx.response.header('x-frame-options', 'DENY')
66
97
  return ctx.view.render('oauth/consent', {
67
98
  client: outcome.request.client,
68
99
  scopes: outcome.request.scopes,
100
+ ticket: ticket.id,
69
101
  })
70
102
  })
71
103
 
104
+ // CSRF-protected by blackhole, like every other form POST.
72
105
  router.post('/oauth/consent', async (ctx) => {
73
- const outcome = await visa.authorize(ctx.request.all(), ctx.auth.user.id)
74
- if (outcome.type !== 'consent') return ctx.response.redirect('/')
75
- const url = ctx.request.input('approve')
76
- ? await visa.grant(outcome.request, ctx.auth.user.id)
77
- : visa.deny(outcome.request)
106
+ const user = ctx.auth.getUserOrFail()
107
+ // Pulled, not read: a second POST of the same form finds nothing.
108
+ const validated = await visa.redeemConsentTicket(
109
+ ctx.session.pull('visa.consent'),
110
+ ctx.request.input('ticket'),
111
+ user.id,
112
+ )
113
+ if (validated === null) {
114
+ // No ticket, another page's ticket, another user, expired, or a client
115
+ // that changed since the page was shown: start again.
116
+ return ctx.view.render('oauth/error', { error: { error: 'invalid_request' } })
117
+ }
118
+
119
+ const url = ctx.request.input('approve') === '1'
120
+ ? await visa.grant(validated, user.id)
121
+ : visa.deny(validated)
78
122
  return ctx.response.redirect(url)
79
123
  })
80
124
  ```
81
125
 
126
+ ```html
127
+ <!-- resources/views/oauth/consent.inker -->
128
+ <form method="POST" action="/oauth/consent">
129
+ {{ csrfField() }}
130
+ <input type="hidden" name="ticket" value="{{ ticket }}">
131
+ <button name="approve" value="1">Allow</button>
132
+ <button name="approve" value="0">Deny</button>
133
+ </form>
134
+ ```
135
+
136
+ `redeemConsentTicket` validates the request again (a client may have lost a
137
+ scope or a redirect URI meanwhile) and mints nothing: the code exists only once
138
+ `grant` runs. A ticket lasts ten minutes; `consentTicketTtlSeconds` in the
139
+ config changes it.
140
+
82
141
  ## Registering a client
83
142
 
84
143
  ```ts
@@ -140,11 +199,23 @@ trailing slash is dropped — every endpoint is built by concatenation, so
140
199
 
141
200
  ## The store
142
201
 
143
- `MemoryStore` is for tests and a single development process. Everything else
144
- implements `VisaStore` — twelve methods. Two of them, `consumeAuthorizationCode`
145
- and `consumeRefreshToken`, **must be atomic**: two requests racing with the same
146
- code must not both succeed, and that single-use guarantee is what replay
147
- detection is built on.
202
+ `MemoryStore` is for tests and a single development process. `AtlasStore`
203
+ (`@c9up/visa/stores/atlas`) runs on the tables of the migration
204
+ `ream configure` writes. Anything else implements `VisaStore`. Two of its
205
+ methods, `consumeAuthorizationCode` and `consumeRefreshToken`, **must be
206
+ atomic**: two requests racing with the same code must not both succeed, and
207
+ that single-use guarantee is what replay detection is built on.
208
+
209
+ `saveClient` is optional, for clients that live in a table you do not own.
210
+ Without it `registerClient` throws, and a server with `registration.enabled`
211
+ refuses to boot rather than answering 500 to every registration.
212
+
213
+ A `visa_clients` table created by visa 0.1.3 or earlier has no
214
+ `secret_expires_at` column, and `AtlasStore` writes it on every client — a
215
+ secret's expiry is enforced from it. Run `ream configure @c9up/visa` again
216
+ before upgrading: your existing `9000_create_visa_tables` is left alone and
217
+ `9001_add_visa_client_secret_expiry` lands beside it; `migration:run` adds the
218
+ column.
148
219
 
149
220
  ## What is not here yet
150
221
 
@@ -19,6 +19,28 @@ export interface VisaConfig extends AuthorizeOptions, TokenOptions {
19
19
  store: VisaStore;
20
20
  /** Whether clients may register themselves, and on what terms (RFC 7591). */
21
21
  registration?: RegistrationOptions;
22
+ /**
23
+ * How long a consent page may stay open before its answer is refused, in
24
+ * seconds. Ten minutes by default — see {@link VisaManager.consentTicket}.
25
+ */
26
+ consentTicketTtlSeconds?: number;
27
+ }
28
+ /**
29
+ * What the application keeps server-side between the consent page and the
30
+ * POST that answers it — in the session, never in the form.
31
+ *
32
+ * Plain values only, so any session store can hold it: the request as it was
33
+ * validated, not the client record (which carries the secret's hash).
34
+ */
35
+ export interface ConsentTicket {
36
+ /** Random, 256 bits. The consent form posts it back; nothing else does. */
37
+ id: string;
38
+ /** Who was asked. Another user answering it is refused. */
39
+ userId: string;
40
+ /** Milliseconds since the epoch. */
41
+ expiresAt: number;
42
+ /** The authorization request, rebuilt from what was validated. */
43
+ request: AuthorizationRequest;
22
44
  }
23
45
  /** What `authorize()` decided. */
24
46
  export type AuthorizationOutcome =
@@ -60,6 +82,8 @@ export declare class VisaManager {
60
82
  scopes?: string[];
61
83
  tokenEndpointAuthMethod?: ClientAuthMethod;
62
84
  trusted?: boolean;
85
+ /** When the issued secret stops working. Omitted means it does not. */
86
+ secretExpiresAt?: Date;
63
87
  }): Promise<{
64
88
  client: Client;
65
89
  secret?: string;
@@ -85,6 +109,31 @@ export declare class VisaManager {
85
109
  * the answer to it is a POST the application owns.
86
110
  */
87
111
  grant(validated: ValidatedRequest, userId: string, now?: Date): Promise<string>;
112
+ /**
113
+ * Remember what the consent page asks, so its answer cannot change it.
114
+ *
115
+ * The application puts the ticket in the user's session, renders its `id`
116
+ * as a hidden field, and on the POST hands both to
117
+ * {@link redeemConsentTicket}. What gets granted is then the request the
118
+ * user was shown — not whatever parameters the POST carries — and the
119
+ * session makes it single use (`session.pull`) and bound to this browser.
120
+ */
121
+ consentTicket(validated: ValidatedRequest, userId: string, now?: Date): ConsentTicket;
122
+ /**
123
+ * The consent page's answer, checked against the ticket it was rendered with.
124
+ *
125
+ * `ticket` is what the session held — pulled, not read, so a second POST
126
+ * of the same form finds nothing. `presentedId` is the form's hidden field:
127
+ * it must name THIS ticket, which is what stops a form left open in one tab
128
+ * from approving the request another tab put in the session since. The
129
+ * request is validated again — the client may have lost a scope or a
130
+ * redirect URI meanwhile — and no code is minted: that is `grant`'s job,
131
+ * once the user said yes.
132
+ *
133
+ * `null` for anything wrong: no ticket, another ticket, another user,
134
+ * expired, or a request that no longer validates. The user starts again.
135
+ */
136
+ redeemConsentTicket(ticket: unknown, presentedId: unknown, userId: string, now?: Date): Promise<ValidatedRequest | null>;
88
137
  /** The user said no. */
89
138
  deny(validated: ValidatedRequest): string;
90
139
  token(body: Record<string, unknown>, credentials: ClientCredentials, now?: Date): Promise<TokenResponse>;
@@ -1 +1 @@
1
- {"version":3,"file":"VisaManager.d.ts","sourceRoot":"","sources":["../src/VisaManager.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"VisaManager.d.ts","sourceRoot":"","sources":["../src/VisaManager.ts"],"names":[],"mappings":"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"}
@@ -7,11 +7,12 @@
7
7
  */
8
8
  import { errorRedirect, issueAuthorizationCode, successRedirect, UnredirectableError, validateAuthorizationRequest, } from "./authorize.js";
9
9
  import { readCredentials, redirectUriMatches, } from "./clients.js";
10
- import { hashSecret, randomToken } from "./crypto.js";
10
+ import { hashMatches, hashSecret, randomToken, sha256 } from "./crypto.js";
11
11
  import { OAuthError, VisaError } from "./errors.js";
12
12
  import { introspect, revoke, verifyAccessToken } from "./introspect.js";
13
- import { registrationResponse, validateRegistration, } from "./register.js";
13
+ import { registrationResponse, secretExpiryFor, validateRegistration, } from "./register.js";
14
14
  import { token } from "./token.js";
15
+ const DEFAULT_CONSENT_TICKET_TTL_SECONDS = 600;
15
16
  export class VisaManager {
16
17
  #config;
17
18
  constructor(config) {
@@ -19,6 +20,7 @@ export class VisaManager {
19
20
  // with a broken issuer answers every metadata fetch with something no
20
21
  // client can use, and says so nowhere.
21
22
  this.#config = { ...config, issuer: normalizeIssuer(config.issuer) };
23
+ assertRegistration(config);
22
24
  }
23
25
  get issuer() {
24
26
  return this.#config.issuer;
@@ -50,14 +52,18 @@ export class VisaManager {
50
52
  tokenEndpointAuthMethod: method,
51
53
  ...(input.trusted === undefined ? {} : { trusted: input.trusted }),
52
54
  ...(secret === undefined ? {} : { secretHash: hashSecret(secret) }),
55
+ // Only alongside a secret: an expiry on a client that has none is a
56
+ // date nothing would ever read.
57
+ ...(secret === undefined || input.secretExpiresAt === undefined
58
+ ? {}
59
+ : { secretExpiresAt: input.secretExpiresAt }),
53
60
  };
54
61
  const store = this.#config.store;
55
- if (!("addClient" in store) || typeof store.addClient !== "function") {
56
- throw new VisaError("E_VISA_STORE_READ_ONLY", "This store cannot register clients; create them where they live.", {
57
- hint: "MemoryStore.addClient exists; a database store registers rows.",
58
- });
59
- }
60
- store.addClient(client);
62
+ if (store.saveClient === undefined)
63
+ throw readOnlyStore();
64
+ // Awaited: the secret below is handed out once, and handing it out for a
65
+ // client whose write failed is a credential nothing will ever accept.
66
+ await store.saveClient(client);
61
67
  return secret === undefined ? { client } : { client, secret };
62
68
  }
63
69
  /**
@@ -69,6 +75,10 @@ export class VisaManager {
69
75
  async register(request, presentedToken, now = new Date()) {
70
76
  const options = this.#config.registration ?? {};
71
77
  const metadata = validateRegistration(request, options, presentedToken);
78
+ // Computed once, here: the same value is stored on the client and
79
+ // answered in the 201 body, so the server cannot announce an expiry it
80
+ // does not enforce.
81
+ const secretExpiresAt = secretExpiryFor(now, options.secretTtlSeconds);
72
82
  const { client, secret } = await this.registerClient({
73
83
  // The id is ours to choose: a client naming itself could claim one
74
84
  // that already exists and read another application's tokens.
@@ -78,8 +88,9 @@ export class VisaManager {
78
88
  grantTypes: metadata.grantTypes,
79
89
  scopes: metadata.scopes,
80
90
  tokenEndpointAuthMethod: metadata.tokenEndpointAuthMethod,
91
+ ...(secretExpiresAt === undefined ? {} : { secretExpiresAt }),
81
92
  });
82
- return registrationResponse(client, now, secret, options);
93
+ return registrationResponse(client, now, secret);
83
94
  }
84
95
  /**
85
96
  * Step one: check the request, and decide what happens to the user.
@@ -136,6 +147,81 @@ export class VisaManager {
136
147
  const code = await issueAuthorizationCode(validated, userId, this.#config.store, this.#config, now);
137
148
  return successRedirect(validated, code);
138
149
  }
150
+ /**
151
+ * Remember what the consent page asks, so its answer cannot change it.
152
+ *
153
+ * The application puts the ticket in the user's session, renders its `id`
154
+ * as a hidden field, and on the POST hands both to
155
+ * {@link redeemConsentTicket}. What gets granted is then the request the
156
+ * user was shown — not whatever parameters the POST carries — and the
157
+ * session makes it single use (`session.pull`) and bound to this browser.
158
+ */
159
+ consentTicket(validated, userId, now = new Date()) {
160
+ const ttl = this.#config.consentTicketTtlSeconds ??
161
+ DEFAULT_CONSENT_TICKET_TTL_SECONDS;
162
+ return {
163
+ id: randomToken(),
164
+ userId,
165
+ expiresAt: now.getTime() + ttl * 1000,
166
+ request: {
167
+ response_type: "code",
168
+ client_id: validated.client.id,
169
+ redirect_uri: validated.redirectUri,
170
+ // Joined from what was resolved, so an omitted `scope` that
171
+ // defaulted to the client's list is the list the user saw, even
172
+ // if the client registers more by the time the user answers.
173
+ scope: validated.scopes.join(" "),
174
+ code_challenge: validated.codeChallenge,
175
+ code_challenge_method: validated.codeChallengeMethod,
176
+ ...(validated.state === undefined ? {} : { state: validated.state }),
177
+ ...(validated.nonce === undefined ? {} : { nonce: validated.nonce }),
178
+ ...(validated.resources.length === 0
179
+ ? {}
180
+ : { resource: [...validated.resources] }),
181
+ },
182
+ };
183
+ }
184
+ /**
185
+ * The consent page's answer, checked against the ticket it was rendered with.
186
+ *
187
+ * `ticket` is what the session held — pulled, not read, so a second POST
188
+ * of the same form finds nothing. `presentedId` is the form's hidden field:
189
+ * it must name THIS ticket, which is what stops a form left open in one tab
190
+ * from approving the request another tab put in the session since. The
191
+ * request is validated again — the client may have lost a scope or a
192
+ * redirect URI meanwhile — and no code is minted: that is `grant`'s job,
193
+ * once the user said yes.
194
+ *
195
+ * `null` for anything wrong: no ticket, another ticket, another user,
196
+ * expired, or a request that no longer validates. The user starts again.
197
+ */
198
+ async redeemConsentTicket(ticket, presentedId, userId, now = new Date()) {
199
+ const read = readConsentTicket(ticket);
200
+ if (read === null || typeof presentedId !== "string")
201
+ return null;
202
+ if (!hashMatches(sha256(presentedId), sha256(read.id)))
203
+ return null;
204
+ if (read.userId !== userId)
205
+ return null;
206
+ if (read.expiresAt <= now.getTime())
207
+ return null;
208
+ try {
209
+ const validated = await validateAuthorizationRequest(read.request, this.#config.store, this.#config);
210
+ // An empty `scope` resolves to the client's registered list, which
211
+ // may have grown since the page was shown: the user agreed to the
212
+ // list on the page, and to nothing it has become.
213
+ if (validated.scopes.join(" ") !== (read.request.scope ?? "")) {
214
+ return null;
215
+ }
216
+ return validated;
217
+ }
218
+ catch (error) {
219
+ if (error instanceof UnredirectableError || error instanceof OAuthError) {
220
+ return null;
221
+ }
222
+ throw error;
223
+ }
224
+ }
139
225
  /** The user said no. */
140
226
  deny(validated) {
141
227
  return errorRedirect(validated.redirectUri, new OAuthError("access_denied", "The user refused the request."), validated.state);
@@ -260,6 +346,92 @@ function normalizeIssuer(issuer) {
260
346
  }
261
347
  return issuer.replace(/\/+$/, "");
262
348
  }
349
+ /**
350
+ * A ticket as a session store hands it back: untyped, so read field by field.
351
+ *
352
+ * A session serialises to JSON and back, and a store an application wrote
353
+ * itself may hand back anything — a value that is not exactly a ticket is no
354
+ * ticket.
355
+ */
356
+ function readConsentTicket(value) {
357
+ if (typeof value !== "object" || value === null)
358
+ return null;
359
+ if (!("id" in value) || typeof value.id !== "string" || value.id === "")
360
+ return null;
361
+ if (!("userId" in value) || typeof value.userId !== "string")
362
+ return null;
363
+ if (!("expiresAt" in value) || typeof value.expiresAt !== "number")
364
+ return null;
365
+ if (!("request" in value))
366
+ return null;
367
+ const request = readTicketRequest(value.request);
368
+ if (request === null)
369
+ return null;
370
+ return {
371
+ id: value.id,
372
+ userId: value.userId,
373
+ expiresAt: value.expiresAt,
374
+ request,
375
+ };
376
+ }
377
+ /** `prompt` is left out on purpose: the ticket IS the consent being asked. */
378
+ const TICKET_STRING_FIELDS = [
379
+ "response_type",
380
+ "client_id",
381
+ "redirect_uri",
382
+ "scope",
383
+ "state",
384
+ "code_challenge",
385
+ "code_challenge_method",
386
+ "nonce",
387
+ ];
388
+ function readTicketRequest(value) {
389
+ if (typeof value !== "object" || value === null)
390
+ return null;
391
+ const request = {};
392
+ for (const key of TICKET_STRING_FIELDS) {
393
+ const field = Reflect.get(value, key);
394
+ if (field === undefined)
395
+ continue;
396
+ if (typeof field !== "string")
397
+ return null;
398
+ request[key] = field;
399
+ }
400
+ const resource = Reflect.get(value, "resource");
401
+ if (resource !== undefined) {
402
+ if (!Array.isArray(resource) ||
403
+ !resource.every((entry) => typeof entry === "string")) {
404
+ return null;
405
+ }
406
+ request.resource = resource;
407
+ }
408
+ return request;
409
+ }
410
+ /**
411
+ * Registration that can actually register, checked at boot.
412
+ *
413
+ * Both failures would otherwise surface on the first `POST /register`: a store
414
+ * with nowhere to write a client answers every MCP client a 500, and an empty
415
+ * initial access token is matched by `Authorization: Bearer ` — an endpoint
416
+ * the deployment meant to close, open to anyone who sends the header.
417
+ */
418
+ function assertRegistration(config) {
419
+ const registration = config.registration;
420
+ if (registration?.enabled !== true)
421
+ return;
422
+ if (config.store.saveClient === undefined)
423
+ throw readOnlyStore();
424
+ if (registration.initialAccessToken === "") {
425
+ throw new VisaError("E_VISA_INVALID_INITIAL_ACCESS_TOKEN", "registration.initialAccessToken is empty, which would accept an empty bearer token.", {
426
+ hint: "Set a long random value, or leave it out for open registration.",
427
+ });
428
+ }
429
+ }
430
+ function readOnlyStore() {
431
+ return new VisaError("E_VISA_STORE_READ_ONLY", "This store cannot register clients; create them where they live.", {
432
+ hint: "Implement saveClient(client) on the store — MemoryStore and AtlasStore both do.",
433
+ });
434
+ }
263
435
  /**
264
436
  * Every redirect URI a client registers, checked once.
265
437
  *
@@ -1 +1 @@
1
- {"version":3,"file":"VisaManager.js","sourceRoot":"","sources":["../src/VisaManager.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,EAGN,aAAa,EACb,sBAAsB,EACtB,eAAe,EACf,mBAAmB,EAEnB,4BAA4B,GAC5B,MAAM,gBAAgB,CAAC;AACxB,OAAO,EAEN,eAAe,EACf,kBAAkB,GAClB,MAAM,cAAc,CAAC;AACtB,OAAO,EAAE,UAAU,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AACtD,OAAO,EAAE,UAAU,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AACpD,OAAO,EAAE,UAAU,EAAE,MAAM,EAAE,iBAAiB,EAAE,MAAM,iBAAiB,CAAC;AACxE,OAAO,EAIN,oBAAoB,EACpB,oBAAoB,GACpB,MAAM,eAAe,CAAC;AAEvB,OAAO,EAAqB,KAAK,EAAE,MAAM,YAAY,CAAC;AA8BtD,MAAM,OAAO,WAAW;IACd,OAAO,CAAa;IAE7B,YAAY,MAAkB;QAC7B,uEAAuE;QACvE,sEAAsE;QACtE,uCAAuC;QACvC,IAAI,CAAC,OAAO,GAAG,EAAE,GAAG,MAAM,EAAE,MAAM,EAAE,eAAe,CAAC,MAAM,CAAC,MAAM,CAAC,EAAE,CAAC;IACtE,CAAC;IAED,IAAI,MAAM;QACT,OAAO,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC;IAC5B,CAAC;IAED,IAAI,KAAK;QACR,OAAO,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC;IAC3B,CAAC;IAED;;;;;;OAMG;IACH,KAAK,CAAC,cAAc,CAAC,KAQpB;QACA,qEAAqE;QACrE,yDAAyD;QACzD,qEAAqE;QACrE,yBAAyB;QACzB,kBAAkB,CAAC,KAAK,CAAC,YAAY,CAAC,CAAC;QACvC,MAAM,MAAM,GAAG,KAAK,CAAC,uBAAuB,IAAI,qBAAqB,CAAC;QACtE,MAAM,MAAM,GAAG,MAAM,KAAK,MAAM,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,WAAW,EAAE,CAAC;QAC7D,MAAM,MAAM,GAAW;YACtB,EAAE,EAAE,KAAK,CAAC,EAAE;YACZ,IAAI,EAAE,KAAK,CAAC,IAAI;YAChB,YAAY,EAAE,KAAK,CAAC,YAAY;YAChC,UAAU,EAAE,KAAK,CAAC,UAAU,IAAI,CAAC,oBAAoB,EAAE,eAAe,CAAC;YACvE,MAAM,EAAE,KAAK,CAAC,MAAM,IAAI,EAAE;YAC1B,uBAAuB,EAAE,MAAM;YAC/B,GAAG,CAAC,KAAK,CAAC,OAAO,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,OAAO,EAAE,KAAK,CAAC,OAAO,EAAE,CAAC;YAClE,GAAG,CAAC,MAAM,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,UAAU,EAAE,UAAU,CAAC,MAAM,CAAC,EAAE,CAAC;SACnE,CAAC;QACF,MAAM,KAAK,GAAG,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC;QACjC,IAAI,CAAC,CAAC,WAAW,IAAI,KAAK,CAAC,IAAI,OAAO,KAAK,CAAC,SAAS,KAAK,UAAU,EAAE,CAAC;YACtE,MAAM,IAAI,SAAS,CAClB,wBAAwB,EACxB,kEAAkE,EAClE;gBACC,IAAI,EAAE,gEAAgE;aACtE,CACD,CAAC;QACH,CAAC;QACD,KAAK,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC;QACxB,OAAO,MAAM,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,MAAM,EAAE,CAAC;IAC/D,CAAC;IAED;;;;;OAKG;IACH,KAAK,CAAC,QAAQ,CACb,OAAkC,EAClC,cAAuB,EACvB,MAAY,IAAI,IAAI,EAAE;QAEtB,MAAM,OAAO,GAAG,IAAI,CAAC,OAAO,CAAC,YAAY,IAAI,EAAE,CAAC;QAChD,MAAM,QAAQ,GAAG,oBAAoB,CAAC,OAAO,EAAE,OAAO,EAAE,cAAc,CAAC,CAAC;QACxE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,GAAG,MAAM,IAAI,CAAC,cAAc,CAAC;YACpD,mEAAmE;YACnE,6DAA6D;YAC7D,EAAE,EAAE,WAAW,EAAE;YACjB,IAAI,EAAE,QAAQ,CAAC,IAAI;YACnB,YAAY,EAAE,QAAQ,CAAC,YAAY;YACnC,UAAU,EAAE,QAAQ,CAAC,UAAU;YAC/B,MAAM,EAAE,QAAQ,CAAC,MAAM;YACvB,uBAAuB,EAAE,QAAQ,CAAC,uBAAuB;SACzD,CAAC,CAAC;QACH,OAAO,oBAAoB,CAAC,MAAM,EAAE,GAAG,EAAE,MAAM,EAAE,OAAO,CAAC,CAAC;IAC3D,CAAC;IAED;;;;;OAKG;IACH,KAAK,CAAC,SAAS,CACd,OAA6B,EAC7B,MAA0B;QAE1B,IAAI,SAA2B,CAAC;QAChC,IAAI,CAAC;YACJ,SAAS,GAAG,MAAM,4BAA4B,CAC7C,OAAO,EACP,IAAI,CAAC,OAAO,CAAC,KAAK,EAClB,IAAI,CAAC,OAAO,CACZ,CAAC;QACH,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YAChB,IAAI,KAAK,YAAY,mBAAmB,EAAE,CAAC;gBAC1C,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,KAAK,EAAE,KAAK,CAAC,KAAK,EAAE,CAAC;YAC9C,CAAC;YACD,IAAI,KAAK,YAAY,UAAU,EAAE,CAAC;gBACjC,4DAA4D;gBAC5D,MAAM,GAAG,GAAG,MAAM,IAAI,CAAC,eAAe,CAAC,OAAO,CAAC,CAAC;gBAChD,IAAI,GAAG,KAAK,IAAI;oBAAE,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,KAAK,EAAE,CAAC;gBAClD,OAAO;oBACN,IAAI,EAAE,UAAU;oBAChB,GAAG,EAAE,aAAa,CAAC,GAAG,EAAE,KAAK,EAAE,OAAO,CAAC,KAAK,CAAC;iBAC7C,CAAC;YACH,CAAC;YACD,MAAM,KAAK,CAAC;QACb,CAAC;QAED,IAAI,MAAM,KAAK,SAAS,EAAE,CAAC;YAC1B,OAAO,EAAE,IAAI,EAAE,SAAS,EAAE,OAAO,EAAE,SAAS,EAAE,CAAC;QAChD,CAAC;QAED,MAAM,OAAO,GAAG,MAAM,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,WAAW,CACnD,MAAM,EACN,SAAS,CAAC,MAAM,CAAC,EAAE,CACnB,CAAC;QACF,MAAM,OAAO,GACZ,OAAO,KAAK,IAAI;YAChB,SAAS,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAC;QACnE,MAAM,MAAM,GAAG,OAAO,CAAC,MAAM,KAAK,SAAS,CAAC;QAC5C,IAAI,SAAS,CAAC,MAAM,CAAC,OAAO,KAAK,IAAI,IAAI,CAAC,CAAC,OAAO,IAAI,MAAM,CAAC,EAAE,CAAC;YAC/D,OAAO,EAAE,IAAI,EAAE,SAAS,EAAE,OAAO,EAAE,SAAS,EAAE,CAAC;QAChD,CAAC;QAED,OAAO,EAAE,IAAI,EAAE,UAAU,EAAE,GAAG,EAAE,MAAM,IAAI,CAAC,KAAK,CAAC,SAAS,EAAE,MAAM,CAAC,EAAE,CAAC;IACvE,CAAC;IAED;;;;;OAKG;IACH,KAAK,CAAC,KAAK,CACV,SAA2B,EAC3B,MAAc,EACd,MAAY,IAAI,IAAI,EAAE;QAEtB,MAAM,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,WAAW,CAAC;YACpC,MAAM;YACN,QAAQ,EAAE,SAAS,CAAC,MAAM,CAAC,EAAE;YAC7B,MAAM,EAAE,SAAS,CAAC,MAAM;YACxB,SAAS,EAAE,GAAG;SACd,CAAC,CAAC;QACH,MAAM,IAAI,GAAG,MAAM,sBAAsB,CACxC,SAAS,EACT,MAAM,EACN,IAAI,CAAC,OAAO,CAAC,KAAK,EAClB,IAAI,CAAC,OAAO,EACZ,GAAG,CACH,CAAC;QACF,OAAO,eAAe,CAAC,SAAS,EAAE,IAAI,CAAC,CAAC;IACzC,CAAC;IAED,wBAAwB;IACxB,IAAI,CAAC,SAA2B;QAC/B,OAAO,aAAa,CACnB,SAAS,CAAC,WAAW,EACrB,IAAI,UAAU,CAAC,eAAe,EAAE,+BAA+B,CAAC,EAChE,SAAS,CAAC,KAAK,CACf,CAAC;IACH,CAAC;IAED,KAAK,CAAC,KAAK,CACV,IAA6B,EAC7B,WAA8B,EAC9B,MAAY,IAAI,IAAI,EAAE;QAEtB,OAAO,KAAK,CAAC,IAAI,EAAE,WAAW,EAAE,IAAI,CAAC,OAAO,CAAC,KAAK,EAAE,IAAI,CAAC,OAAO,EAAE,GAAG,CAAC,CAAC;IACxE,CAAC;IAED,KAAK,CAAC,UAAU,CACf,IAA6B,EAC7B,WAA8B,EAC9B,MAAY,IAAI,IAAI,EAAE;QAEtB,OAAO,UAAU,CAAC,IAAI,EAAE,WAAW,EAAE,IAAI,CAAC,OAAO,CAAC,KAAK,EAAE,GAAG,EAAE,IAAI,CAAC,MAAM,CAAC,CAAC;IAC5E,CAAC;IAED,KAAK,CAAC,MAAM,CACX,IAA6B,EAC7B,WAA8B,EAC9B,MAAY,IAAI,IAAI,EAAE;QAEtB,OAAO,MAAM,CAAC,IAAI,EAAE,WAAW,EAAE,IAAI,CAAC,OAAO,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC;IAC3D,CAAC;IAED;;;;;OAKG;IACH,KAAK,CAAC,MAAM,CACX,SAAiB,EACjB,MAAY,IAAI,IAAI,EAAE,EACtB,QAAiB;QAEjB,OAAO,iBAAiB,CAAC,SAAS,EAAE,IAAI,CAAC,OAAO,CAAC,KAAK,EAAE,GAAG,EAAE,QAAQ,CAAC,CAAC;IACxE,CAAC;IAED;;;;;;;OAOG;IACH,KAAK,CAAC,kBAAkB,CACvB,MAAc,EACd,MAAY,IAAI,IAAI,EAAE;QAEtB,MAAM,KAAK,GAAG,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC;QACjC,MAAM,QAAQ,GAAG,MAAM,KAAK,CAAC,YAAY,CAAC,MAAM,CAAC,CAAC;QAClD,MAAM,MAAM,GAAG,MAAM,KAAK,CAAC,gBAAgB,CAAC,MAAM,CAAC,CAAC;QAEpD,OAAO,OAAO,CAAC,GAAG,CACjB,QAAQ,CAAC,GAAG,CAAC,KAAK,EAAE,OAAO,EAAE,EAAE;YAC9B,MAAM,IAAI,GAAG,MAAM,CAAC,MAAM,CACzB,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,QAAQ,KAAK,OAAO,CAAC,QAAQ,CAC9C,CAAC;YACF,MAAM,MAAM,GAAG,MAAM,KAAK,CAAC,UAAU,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC;YACxD,MAAM,UAAU,GAAG,IAAI,CAAC,MAAM,CAAmB,CAAC,MAAM,EAAE,KAAK,EAAE,EAAE;gBAClE,IAAI,KAAK,CAAC,UAAU,KAAK,SAAS;oBAAE,OAAO,MAAM,CAAC;gBAClD,IAAI,MAAM,KAAK,SAAS;oBAAE,OAAO,KAAK,CAAC,UAAU,CAAC;gBAClD,OAAO,KAAK,CAAC,UAAU,GAAG,MAAM,CAAC,CAAC,CAAC,KAAK,CAAC,UAAU,CAAC,CAAC,CAAC,MAAM,CAAC;YAC9D,CAAC,EAAE,SAAS,CAAC,CAAC;YAEd,OAAO;gBACN,QAAQ,EAAE,OAAO,CAAC,QAAQ;gBAC1B,kEAAkE;gBAClE,2DAA2D;gBAC3D,IAAI,EAAE,MAAM,EAAE,IAAI,IAAI,OAAO,CAAC,QAAQ;gBACtC,MAAM,EAAE,OAAO,CAAC,MAAM;gBACtB,SAAS,EAAE,OAAO,CAAC,SAAS;gBAC5B,GAAG,CAAC,UAAU,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,UAAU,EAAE,CAAC;gBACnD,MAAM,EAAE,IAAI,CAAC,IAAI,CAChB,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,SAAS,KAAK,SAAS,IAAI,KAAK,CAAC,SAAS,GAAG,GAAG,CACjE;aACD,CAAC;QACH,CAAC,CAAC,CACF,CAAC;IACH,CAAC;IAED;;;;;;;;;;OAUG;IACH,KAAK,CAAC,mBAAmB,CACxB,MAAc,EACd,QAAgB,EAChB,MAAY,IAAI,IAAI,EAAE;QAEtB,MAAM,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,eAAe,CAAC,MAAM,EAAE,QAAQ,EAAE,GAAG,CAAC,CAAC;QAChE,MAAM,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,aAAa,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAC;IAC1D,CAAC;IAED,sEAAsE;IACtE,eAAe,CAAC,KAGf;QACA,OAAO,eAAe,CAAC,KAAK,CAAC,CAAC;IAC/B,CAAC;IAED;;;;OAIG;IACH,KAAK,CAAC,eAAe,CAAC,OAA6B;QAClD,IAAI,OAAO,CAAC,SAAS,KAAK,SAAS;YAAE,OAAO,IAAI,CAAC;QACjD,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,UAAU,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC;QACtE,IAAI,MAAM,KAAK,IAAI;YAAE,OAAO,IAAI,CAAC;QACjC,IAAI,OAAO,CAAC,YAAY,KAAK,SAAS,EAAE,CAAC;YACxC,OAAO,MAAM,CAAC,YAAY,CAAC,MAAM,KAAK,CAAC;gBACtC,CAAC,CAAC,CAAC,MAAM,CAAC,YAAY,CAAC,CAAC,CAAC,IAAI,IAAI,CAAC;gBAClC,CAAC,CAAC,IAAI,CAAC;QACT,CAAC;QACD,OAAO,kBAAkB,CAAC,OAAO,CAAC,YAAY,EAAE,MAAM,CAAC,YAAY,CAAC;YACnE,CAAC,CAAC,OAAO,CAAC,YAAY;YACtB,CAAC,CAAC,IAAI,CAAC;IACT,CAAC;CACD;AAED;;;;;;GAMG;AACH,SAAS,eAAe,CAAC,MAAc;IACtC,IAAI,MAAM,KAAK,SAAS,IAAI,MAAM,KAAK,EAAE,EAAE,CAAC;QAC3C,MAAM,IAAI,SAAS,CAClB,uBAAuB,EACvB,6EAA6E,EAC7E,EAAE,IAAI,EAAE,+DAA+D,EAAE,CACzE,CAAC;IACH,CAAC;IACD,IAAI,GAAQ,CAAC;IACb,IAAI,CAAC;QACJ,GAAG,GAAG,IAAI,GAAG,CAAC,MAAM,CAAC,CAAC;IACvB,CAAC;IAAC,MAAM,CAAC;QACR,MAAM,IAAI,SAAS,CAClB,uBAAuB,EACvB,+BAA+B,MAAM,EAAE,EACvC,EAAE,IAAI,EAAE,wDAAwD,EAAE,CAClE,CAAC;IACH,CAAC;IACD,IAAI,GAAG,CAAC,QAAQ,KAAK,QAAQ,IAAI,GAAG,CAAC,QAAQ,KAAK,WAAW,EAAE,CAAC;QAC/D,uEAAuE;QACvE,iEAAiE;QACjE,MAAM,IAAI,SAAS,CAClB,wBAAwB,EACxB,qDAAqD,MAAM,EAAE,CAC7D,CAAC;IACH,CAAC;IACD,IAAI,GAAG,CAAC,IAAI,KAAK,EAAE,IAAI,GAAG,CAAC,MAAM,KAAK,EAAE,EAAE,CAAC;QAC1C,MAAM,IAAI,SAAS,CAClB,uBAAuB,EACvB,2DAA2D,CAC3D,CAAC;IACH,CAAC;IACD,OAAO,MAAM,CAAC,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC;AACnC,CAAC;AAED;;;;;;GAMG;AACH,SAAS,kBAAkB,CAAC,IAAuB;IAClD,IAAI,IAAI,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACvB,MAAM,IAAI,SAAS,CAClB,wBAAwB,EACxB,2CAA2C,CAC3C,CAAC;IACH,CAAC;IACD,KAAK,MAAM,GAAG,IAAI,IAAI,EAAE,CAAC;QACxB,IAAI,GAAQ,CAAC;QACb,IAAI,CAAC;YACJ,GAAG,GAAG,IAAI,GAAG,CAAC,GAAG,CAAC,CAAC;QACpB,CAAC;QAAC,MAAM,CAAC;YACR,MAAM,IAAI,SAAS,CAAC,6BAA6B,EAAE,cAAc,GAAG,EAAE,EAAE;gBACvE,IAAI,EAAE,sDAAsD;aAC5D,CAAC,CAAC;QACJ,CAAC;QACD,IAAI,GAAG,CAAC,IAAI,KAAK,EAAE,EAAE,CAAC;YACrB,MAAM,IAAI,SAAS,CAClB,6BAA6B,EAC7B,0CAA0C,GAAG,EAAE,CAC/C,CAAC;QACH,CAAC;QACD,IAAI,GAAG,CAAC,QAAQ,CAAC,GAAG,CAAC,EAAE,CAAC;YACvB,MAAM,IAAI,SAAS,CAClB,6BAA6B,EAC7B,mEAAmE,GAAG,EAAE,CACxE,CAAC;QACH,CAAC;IACF,CAAC;AACF,CAAC"}
1
+ {"version":3,"file":"VisaManager.js","sourceRoot":"","sources":["../src/VisaManager.ts"],"names":[],"mappings":"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"}
@@ -14,6 +14,10 @@
14
14
  * decision; the page around it is yours. The README shows the ten lines.
15
15
  *
16
16
  * Duck-typed throughout: visa must not import its host's HTTP types.
17
+ *
18
+ * NAMED DEVIATION from the usual `request.all()`: these endpoints read the
19
+ * body only, and refuse a request that puts an OAuth parameter in the query
20
+ * string — see `readBody`.
17
21
  */
18
22
  import "./augmentations.js";
19
23
  interface VisaContainer {
@@ -1 +1 @@
1
- {"version":3,"file":"VisaProvider.d.ts","sourceRoot":"","sources":["../src/VisaProvider.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAEH,OAAO,oBAAoB,CAAC;AAW5B,UAAU,aAAa;IACtB,SAAS,CAAC,KAAK,EAAE,OAAO,EAAE,OAAO,EAAE,MAAM,OAAO,GAAG,IAAI,CAAC;IACxD,OAAO,CAAC,CAAC,GAAG,OAAO,EAAE,KAAK,EAAE,OAAO,GAAG,OAAO,CAAC,CAAC,CAAC,CAAC;IACjD,GAAG,CAAC,KAAK,EAAE,OAAO,GAAG,OAAO,CAAC;CAC7B;AACD,UAAU,eAAe;IACxB,GAAG,CAAC,CAAC,GAAG,OAAO,EAAE,GAAG,EAAE,MAAM,GAAG,CAAC,GAAG,SAAS,CAAC;CAC7C;AACD,MAAM,WAAW,cAAc;IAC9B,SAAS,EAAE,aAAa,CAAC;IACzB,MAAM,EAAE,eAAe,CAAC;CACxB;AAqBD,MAAM,CAAC,OAAO,OAAO,YAAY;;IAGpB,SAAS,CAAC,GAAG,EAAE,cAAc;gBAAnB,GAAG,EAAE,cAAc;IAEzC,QAAQ,IAAI,IAAI;IAiBV,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;IAMrB,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IA8HtB,QAAQ,IAAI,OAAO,CAAC,IAAI,CAAC;CA8B/B"}
1
+ {"version":3,"file":"VisaProvider.d.ts","sourceRoot":"","sources":["../src/VisaProvider.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;GAoBG;AAEH,OAAO,oBAAoB,CAAC;AAW5B,UAAU,aAAa;IACtB,SAAS,CAAC,KAAK,EAAE,OAAO,EAAE,OAAO,EAAE,MAAM,OAAO,GAAG,IAAI,CAAC;IACxD,OAAO,CAAC,CAAC,GAAG,OAAO,EAAE,KAAK,EAAE,OAAO,GAAG,OAAO,CAAC,CAAC,CAAC,CAAC;IACjD,GAAG,CAAC,KAAK,EAAE,OAAO,GAAG,OAAO,CAAC;CAC7B;AACD,UAAU,eAAe;IACxB,GAAG,CAAC,CAAC,GAAG,OAAO,EAAE,GAAG,EAAE,MAAM,GAAG,CAAC,GAAG,SAAS,CAAC;CAC7C;AACD,MAAM,WAAW,cAAc;IAC9B,SAAS,EAAE,aAAa,CAAC;IACzB,MAAM,EAAE,eAAe,CAAC;CACxB;AAwBD,MAAM,CAAC,OAAO,OAAO,YAAY;;IAGpB,SAAS,CAAC,GAAG,EAAE,cAAc;gBAAnB,GAAG,EAAE,cAAc;IAEzC,QAAQ,IAAI,IAAI;IAiBV,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;IAMrB,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IAiItB,QAAQ,IAAI,OAAO,CAAC,IAAI,CAAC;CA8B/B"}