@cboxdk/id-js 0.19.0 → 0.21.0

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 (42) hide show
  1. package/CHANGELOG.md +213 -0
  2. package/README.md +51 -3
  3. package/RELEASE-CANDIDATE.md +11 -0
  4. package/dist/agent.cjs +613 -0
  5. package/dist/agent.cjs.map +1 -0
  6. package/dist/agent.d.cts +400 -0
  7. package/dist/agent.d.ts +400 -0
  8. package/dist/agent.js +527 -0
  9. package/dist/agent.js.map +1 -0
  10. package/dist/api-keys-BE3R3q_A.d.ts +105 -0
  11. package/dist/api-keys-C8-Q4eFA.d.cts +105 -0
  12. package/dist/chunk-EVZ6RB3K.js +98 -0
  13. package/dist/chunk-EVZ6RB3K.js.map +1 -0
  14. package/dist/{chunk-YGLMLIKL.js → chunk-T5LCQOLS.js} +4 -22
  15. package/dist/chunk-T5LCQOLS.js.map +1 -0
  16. package/dist/chunk-VGQASHTI.js +22 -0
  17. package/dist/chunk-VGQASHTI.js.map +1 -0
  18. package/dist/decisions-C84Fzah4.d.ts +23 -0
  19. package/dist/decisions-DNd9UXwi.d.cts +23 -0
  20. package/dist/index.cjs +127 -14
  21. package/dist/index.cjs.map +1 -1
  22. package/dist/index.d.cts +1 -0
  23. package/dist/index.d.ts +1 -0
  24. package/dist/index.js +27 -6
  25. package/dist/index.js.map +1 -1
  26. package/dist/management.cjs +352 -19
  27. package/dist/management.cjs.map +1 -1
  28. package/dist/management.d.cts +994 -42
  29. package/dist/management.d.ts +994 -42
  30. package/dist/management.js +352 -19
  31. package/dist/management.js.map +1 -1
  32. package/dist/nextjs.d.cts +1 -1
  33. package/dist/nextjs.d.ts +1 -1
  34. package/dist/nextjs.js +2 -1
  35. package/dist/nextjs.js.map +1 -1
  36. package/dist/server.cjs +103 -9
  37. package/dist/server.cjs.map +1 -1
  38. package/dist/server.d.cts +3 -105
  39. package/dist/server.d.ts +3 -105
  40. package/dist/server.js +1 -0
  41. package/package.json +16 -3
  42. package/dist/chunk-YGLMLIKL.js.map +0 -1
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/errors.ts","../src/legacy.ts","../src/issuer.ts","../src/frontend.ts","../src/discovery.ts","../src/pkce.ts","../src/claims.ts","../src/vault.ts","../src/webhook.ts","../src/client.ts","../src/authz.ts"],"names":["header","key","organization","timingSafeEqual","json","createRemoteJWKSet","jwtVerify","permissions","roles"],"mappings":"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","file":"index.cjs","sourcesContent":["/**\n * Base class for every error this SDK throws, so callers can `catch (e) { if (e\n * instanceof CboxIdError) ... }` in one branch.\n */\nexport class CboxIdError extends Error {\n constructor(message: string) {\n super(message);\n this.name = new.target.name;\n }\n}\n\n/** The client is misconfigured (a required option is missing or empty). */\nexport class ConfigurationError extends CboxIdError {}\n\n/**\n * The login `state` did not match what was stored — the callback is forged or\n * stale. Treat as a fresh start, not an error to surface to the user.\n */\nexport class InvalidStateError extends CboxIdError {}\n\n/**\n * Login could not be completed: the provider returned an error, the callback was\n * missing a code, or a token / id_token failed verification.\n *\n * `error` carries the RFC 6749 §5.2 code the authorization server sent, when it sent one.\n * It used to be discarded at every back-channel boundary, leaving a single message string\n * for outcomes that need opposite responses: `invalid_grant` on a refresh means the\n * session is over and the person has to sign in again, while `temporarily_unavailable`\n * means try the same token in a moment. A caller reduced to matching on prose either\n * retries what can never succeed, or signs out somebody who did not need to be.\n */\nexport class AuthenticationError extends CboxIdError {\n constructor(\n message: string,\n /** RFC 6749 §5.2 error code, when the server sent a parseable one. */\n readonly error?: string,\n /** The server's `error_description`, verbatim. Not end-user copy. */\n readonly errorDescription?: string,\n /** HTTP status, for the cases where the body says nothing useful. */\n readonly status?: number,\n /**\n * Seconds to wait, off the `Retry-After` header — set only on a 429.\n *\n * The distinction it carries is the one a caller most needs and could least infer:\n * a 429 is the ONLY back-channel failure where the same request will succeed\n * unchanged if you simply wait. Every other one needs a different request, or a new\n * sign-in. Without this the SDK reported \"token refresh failed\" and a caller with a\n * retry loop hammered a limiter that was already telling it exactly how long to stop.\n */\n readonly retryAfter?: number,\n ) {\n super(message);\n }\n\n /** Whether waiting `retryAfter` seconds and repeating the same request is worth it. */\n get isRateLimited(): boolean {\n return this.status === 429;\n }\n}\n\n/**\n * Read an OAuth error out of a failed token-endpoint response.\n *\n * Best-effort by design: a 502 from a proxy is HTML, a captive portal is worse, and the\n * caller still needs an error rather than a parse exception. What it must never do is\n * invent a code — an absent or unparseable `error` stays undefined, so\n * `e.error === 'invalid_grant'` is true only because the server said so.\n */\nexport async function oauthError(response: Response, fallback: string): Promise<AuthenticationError> {\n const body = await response.text().catch(() => '');\n\n let code: string | undefined;\n let description: string | undefined;\n\n try {\n const parsed: unknown = JSON.parse(body);\n\n if (typeof parsed === 'object' && parsed !== null) {\n const { error, error_description: errorDescription } = parsed as Record<string, unknown>;\n code = typeof error === 'string' ? error : undefined;\n description = typeof errorDescription === 'string' ? errorDescription : undefined;\n }\n } catch {\n // Not JSON. The status and the truncated body below are all there is to report.\n }\n\n // THE BODY IS NEVER ECHOED. These calls carry `client_secret`, `code_verifier` and\n // refresh tokens in their REQUEST, and a debug proxy, a captive portal or an upstream\n // error page that reflects what it received puts those straight into a thrown message\n // — which production apps log. Only the server's own OAuth error code travels, and\n // failing that, the status alone.\n const detail = code ?? `HTTP ${response.status}`;\n\n // `Retry-After` is seconds here — Laravel's throttler writes the integer form. The\n // HTTP-date form is legal too and is deliberately NOT parsed: guessing at a clock\n // skew is worse than saying nothing, and `status === 429` still tells the caller to\n // back off.\n const retryAfterHeader = response.headers.get('retry-after');\n const retryAfter = retryAfterHeader !== null && /^\\d+$/.test(retryAfterHeader.trim())\n ? Number(retryAfterHeader.trim())\n : undefined;\n\n return new AuthenticationError(`${fallback}: ${detail}`, code, description, response.status, retryAfter);\n}\n\n/**\n * The Frontend API refused, or could not be reached.\n *\n * Carries a `code` because the four ways this goes wrong need four different responses\n * from the caller, and telling them apart from a message string is the kind of thing\n * that works until somebody rewords the message:\n *\n * - `origin_not_allowed` — the overwhelmingly likely cause of a refusal, and a\n * configuration problem the developer fixes once in the console.\n * - `rate_limited` — back off; `retryAfter` says for how long, when the server said.\n * - `unavailable` — the network, or a 5xx. Transient by assumption; already retried.\n * - `malformed` — a 200 whose body is not the document we expect, which means something\n * between the page and us is rewriting responses (a proxy, an extension, a captive\n * portal). Worth distinguishing, because retrying it never helps.\n */\nexport class FrontendApiError extends CboxIdError {\n constructor(\n message: string,\n readonly code: 'origin_not_allowed' | 'rate_limited' | 'unavailable' | 'malformed',\n readonly status?: number,\n readonly retryAfter?: number,\n ) {\n super(message);\n }\n}\n","import { ConfigurationError } from './errors.js';\n\n/**\n * The handler on YOUR side of a legacy migration.\n *\n * Cbox ID offers it an email and a password it has never seen, and your code answers with\n * the person or with nothing. On a yes they are created in Cbox ID as a result of the\n * login that just succeeded, and from their next sign-in the old system is never asked\n * again.\n *\n * WHY THIS IS A FACTORY AND NOT A DOCUMENT. The wire format is simple enough to describe\n * in a paragraph — a signed POST, JSON in, JSON out — and describing it would mean every\n * customer writes the signature check themselves. That check is exactly the part people\n * get wrong: `===` instead of a constant-time compare, no freshness window, no thought\n * about replay. So the factory owns all of it and you write the one function that knows\n * your own database.\n *\n * It is deliberately framework-agnostic: it takes a `Request` and returns a `Response`,\n * which is what Next.js route handlers, Remix, Hono, Bun and Deno all speak natively.\n */\n\n/** What your handler answers with. Returning `null` means \"no\", and is not an error. */\nexport interface LegacyUser {\n email: string;\n name?: string | null;\n emailVerified?: boolean;\n /**\n * Your stored hash, when you can expose it.\n *\n * Passing it lets the person keep their password in Cbox ID verbatim — it is stored as\n * is and upgraded to the platform hasher on their next login, exactly like a\n * bulk-imported user. Omit it and Cbox ID hashes the password they just proved they\n * know, which is the honest option when your store cannot hand a hash over.\n */\n passwordHash?: string;\n}\n\nexport interface LegacyVerifierOptions {\n /** The same secret you declared in your manifest, or configured in the console. */\n secret: string;\n /**\n * Decide whether these credentials are good, and say who they belong to.\n *\n * Return `null` for no. THROWING IS NOT THE SAME as returning null: a throw means your\n * store could not decide, and is answered with a 503 so Cbox ID refuses the sign-in\n * rather than treating an outage as a wrong password.\n */\n verify: (email: string, password: string) => Promise<LegacyUser | null>;\n /**\n * How far out of date a request may be, in seconds. Defaults to 300.\n *\n * A window is what makes a captured request stop working. Too wide and a recording is\n * useful for hours; too narrow and ordinary clock skew starts refusing real traffic.\n */\n toleranceSeconds?: number;\n}\n\n/**\n * Build the request handler.\n *\n * ```ts\n * // app/api/cbox-legacy/route.ts\n * export const POST = createLegacyVerifier({\n * secret: process.env.CBOX_LEGACY_SECRET!,\n * async verify(email, password) {\n * const row = await db.users.findByEmail(email)\n * if (!row || !(await argon2.verify(row.password, password))) return null\n * return { email: row.email, name: row.name, emailVerified: !!row.confirmedAt }\n * },\n * })\n * ```\n */\nexport function createLegacyVerifier(options: LegacyVerifierOptions): (request: Request) => Promise<Response> {\n if (!options.secret || options.secret.length < 32) {\n throw new ConfigurationError(\n 'A legacy verifier secret must be at least 32 characters; it is the only thing proving a request came from Cbox ID.',\n );\n }\n\n const tolerance = options.toleranceSeconds ?? 300;\n\n return async function handle(request: Request): Promise<Response> {\n // Read once. The signature covers the RAW body, so re-serializing parsed JSON would\n // produce different bytes and every valid request would be refused.\n const raw = await request.text();\n\n if (!(await isSignedByCboxId(raw, request.headers.get('X-Cbox-Signature'), options.secret, tolerance))) {\n // No detail. A caller who cannot sign is not owed help distinguishing \"bad\n // signature\" from \"stale timestamp\" — both mean the same thing to anyone\n // legitimate, and the difference is a hint to anyone else.\n return json({ error: 'unauthorized' }, 401);\n }\n\n let payload: { email?: unknown; password?: unknown };\n\n try {\n payload = JSON.parse(raw) as typeof payload;\n } catch {\n return json({ error: 'invalid_request' }, 400);\n }\n\n const { email, password } = payload;\n\n if (typeof email !== 'string' || email === '') {\n return json({ error: 'invalid_request' }, 400);\n }\n\n // No password means Cbox ID is asking \"do you know this address\" — the tooling path,\n // used for a dry run before cutover. It never reaches here from a sign-in.\n if (typeof password !== 'string') {\n return json({ user: null }, 200);\n }\n\n let user: LegacyUser | null;\n\n try {\n user = await options.verify(email, password);\n } catch {\n // 503, not 401. Your store could not decide, and Cbox ID must refuse the sign-in\n // rather than read an outage as a wrong password — but it should also be able to\n // tell the two apart in its own logs, which a 401 would hide.\n return json({ error: 'unavailable' }, 503);\n }\n\n if (!user) {\n return json({ user: null }, 200);\n }\n\n return json(\n {\n email: user.email,\n name: user.name ?? null,\n email_verified: user.emailVerified === true,\n ...(user.passwordHash ? { password_hash: user.passwordHash } : {}),\n },\n 200,\n );\n };\n}\n\n/**\n * Whether this body was signed by Cbox ID, recently.\n *\n * Both halves matter. The HMAC proves it came from something holding the secret; the\n * freshness window is what stops a captured request working forever. Compared in constant\n * time, because a comparison that returns early leaks how much of a guess was right.\n */\nasync function isSignedByCboxId(\n body: string,\n header: string | null,\n secret: string,\n toleranceSeconds: number,\n): Promise<boolean> {\n if (!header) {\n return false;\n }\n\n const parts: Record<string, string> = {};\n\n for (const piece of header.split(',')) {\n const [key, value] = piece.split('=', 2);\n if (key && value) {\n parts[key.trim()] = value.trim();\n }\n }\n\n const timestamp = parts['t'] ?? '';\n const signature = parts['v1'] ?? '';\n\n if (!/^\\d+$/.test(timestamp) || signature === '') {\n return false;\n }\n\n if (Math.abs(Math.floor(Date.now() / 1000) - Number(timestamp)) > toleranceSeconds) {\n return false;\n }\n\n const key = await crypto.subtle.importKey(\n 'raw',\n new TextEncoder().encode(secret),\n { name: 'HMAC', hash: 'SHA-256' },\n false,\n ['sign'],\n );\n\n const mac = await crypto.subtle.sign('HMAC', key, new TextEncoder().encode(`${timestamp}.${body}`));\n const expected = [...new Uint8Array(mac)].map((b) => b.toString(16).padStart(2, '0')).join('');\n\n return timingSafeEqual(expected, signature);\n}\n\n/** Constant-time string compare. Length is not secret; content is. */\nfunction timingSafeEqual(a: string, b: string): boolean {\n if (a.length !== b.length) {\n return false;\n }\n\n let diff = 0;\n\n for (let i = 0; i < a.length; i++) {\n diff |= a.charCodeAt(i) ^ b.charCodeAt(i);\n }\n\n return diff === 0;\n}\n\nfunction json(body: unknown, status: number): Response {\n return new Response(JSON.stringify(body), {\n status,\n headers: { 'Content-Type': 'application/json' },\n });\n}\n","import { ConfigurationError } from './errors.js';\n\n/**\n * An issuer must be HTTPS.\n *\n * Everything this SDK does with it carries a credential: the authorization code, the PKCE\n * verifier, the client secret, the refresh token. Over `http://` a network attacker reads\n * all of them — and, worse, replaces the discovery document and JWKS, at which point a\n * forged id_token verifies cleanly and the whole verification chain proves nothing.\n *\n * Loopback is allowed because a native app's own callback listener is loopback by\n * definition (RFC 8252) and a dev instance runs there.\n */\nexport function assertSecureIssuer(issuer: string): void {\n let url: URL;\n\n try {\n url = new URL(issuer);\n } catch {\n throw new ConfigurationError('Cbox ID config `issuer` is not a valid URL.');\n }\n\n if (url.protocol === 'https:') {\n return;\n }\n\n const loopback = url.hostname === 'localhost' || url.hostname === '127.0.0.1' || url.hostname === '[::1]' || url.hostname === '::1';\n\n if (url.protocol === 'http:' && loopback) {\n return;\n }\n\n throw new ConfigurationError(\n `Cbox ID config \\`issuer\\` must be https (got ${url.protocol}//${url.hostname}).`,\n );\n}\n","import { assertSecureIssuer } from './issuer.js';\nimport { ConfigurationError, FrontendApiError } from './errors.js';\n\n/**\n * The browser-safe half of the SDK.\n *\n * Everything else in this package assumes a server: it holds a client secret, it exchanges\n * codes, it verifies webhooks. None of that may run in a page, which is why the UI\n * components have always been redirect shells — a page that cannot authenticate itself to\n * the identity provider cannot ask it anything, so it sends the person away and waits.\n *\n * A publishable key changes that. It is public on purpose: it ships in your bundle, it is\n * visible in devtools, and it is safe there because it only works from the origins you\n * registered. What it buys is that a page can read its OWN sign-in configuration — the\n * endpoints, the social buttons, your theme — and render a form itself.\n *\n * This client deliberately has no secret, no token storage and no crypto. It reads two\n * documents. Anything that mints or holds a credential still belongs on your server.\n */\n\n/** How a page identifies itself. Public — put it in your bundle. */\nexport interface FrontendClientOptions {\n /** Your identity provider's origin, e.g. `https://id.acme.com`. */\n issuer: string;\n /** `pk_live_…` or `pk_test_…`. Safe to publish. */\n publishableKey: string;\n /** Abort after this long. Defaults to 10s. */\n timeoutMs?: number;\n /**\n * How many times to retry a transient failure. Defaults to 2 (so three attempts).\n *\n * Only the network and 5xx are retried. A refusal is a configuration problem and\n * retrying it just delays the developer finding out; a 429 is honoured rather than\n * hammered.\n */\n retries?: number;\n /** Injectable for tests and for runtimes with a non-global fetch. */\n fetch?: typeof globalThis.fetch;\n}\n\n/** A social button to draw. Name and provider only — never an internal id. */\nexport interface SocialProvider {\n provider: string;\n name: string;\n}\n\n/** The customer's theme, when they have set one. Absent means \"use your own defaults\". */\nexport interface Appearance {\n preset: string;\n radius: string;\n font: string;\n light: Record<string, string>;\n dark: Record<string, string>;\n}\n\n/** Everything needed to draw a sign-in box, and nothing that identifies anybody. */\nexport interface FrontendConfig {\n mode: 'test' | 'live' | null;\n issuer: string;\n endpoints: {\n authorization: string;\n token: string;\n userinfo: string;\n end_session: string;\n jwks: string;\n };\n /**\n * The social buttons to draw, exactly as the hosted sign-in page would: the environment's\n * own providers, or — with `config({ organization })` — that organization's.\n */\n social: SocialProvider[];\n appearance?: Appearance;\n /**\n * Which other sign-in methods are switched on, so a box does not draw a button whose\n * endpoint answers 403. Absent from instances that predate it.\n */\n methods?: { passkeys: boolean; magic_link: boolean };\n}\n\n/** Options for {@link CboxIdFrontend.config}. */\nexport interface FrontendConfigOptions {\n /**\n * The organization the box is for, by id or slug — the way a hosted page is addressed.\n * `social` is then exactly what that organization's sign-in page offers. An organization\n * the environment does not have is answered as no hint at all.\n */\n organization?: string;\n}\n\n/**\n * A second factor the person can answer an `mfa_required` with. Kinds only — the server\n * never says which number a text would go to before one is sent.\n */\nexport type SecondFactorKind = 'totp' | 'sms' | 'recovery_code';\n\n/** What a sign-in attempt produced. */\nexport type SignInResult =\n | { status: 'ok'; loginTicket: string; expiresIn: number }\n | {\n status: 'mfa_required';\n mfaToken: string;\n /**\n * The factors this person can answer with (laravel-id 1.24+). Absent when the\n * instance predates the list — then only an authenticator or a recovery code works.\n */\n factors?: SecondFactorKind[];\n }\n | { status: 'otp_required'; mfaToken: string }\n | { status: 'sso_required' }\n | { status: 'invalid' }\n | { status: 'rate_limited'; retryAfter: number | undefined };\n\n/** What asking for a texted sign-in code produced. */\nexport type SmsCodeResult =\n /** Sent. `to` is the number masked (`+45 ******78`); the code lasts `expiresIn` seconds. */\n | { status: 'sent'; to: string; expiresIn: number }\n /** Too soon, or a sending limit was hit. Waiting `retryAfter` seconds may help. */\n | { status: 'rate_limited'; retryAfter: number | undefined }\n /** The text provider failed. Try again shortly, or offer another factor. */\n | { status: 'unavailable' }\n /**\n * Refused: an unknown or spent token, no number on file, a country texts are not sent\n * to, or no attempts left. One answer for every reason, like a wrong password.\n */\n | { status: 'invalid' };\n\nconst SECOND_FACTOR_KINDS: ReadonlySet<string> = new Set<SecondFactorKind>(['totp', 'sms', 'recovery_code']);\n\n/** What a browser needs to ask an authenticator for a passkey assertion. */\nexport interface PasskeyOptions {\n challenge: string;\n /** Carries the challenge to the second request, in place of a session cookie. */\n challenge_token: string;\n rpId: string;\n userVerification: string;\n allowCredentials: unknown[];\n timeout: number;\n}\n\n/** Who the browser is signed in as, or nobody. */\nexport interface FrontendSession {\n user: { id: string; email: string; name: string | null } | null;\n}\n\n/**\n * Reads the public configuration and the current session from a browser.\n *\n * ```ts\n * const frontend = new CboxIdFrontend({\n * issuer: 'https://id.acme.com',\n * publishableKey: 'pk_live_…',\n * })\n *\n * const config = await frontend.config() // cached for you; safe to call per component\n * const { user } = await frontend.session(accessToken)\n * ```\n */\nexport class CboxIdFrontend {\n private readonly issuer: string;\n private readonly publishableKey: string;\n private readonly timeoutMs: number;\n private readonly retries: number;\n private readonly fetchImpl: typeof globalThis.fetch;\n\n /**\n * The config document, and the in-flight promise for it.\n *\n * Deduplicated rather than merely cached: a page with a sign-in form, a user button and\n * an organization switcher mounts three components in the same tick, and three parallel\n * fetches of the same immutable document is a waste the SDK should absorb rather than\n * ask every consumer to.\n */\n private readonly configPromises = new Map<string, Promise<FrontendConfig>>();\n\n constructor(options: FrontendClientOptions) {\n if (!options.issuer) {\n throw new ConfigurationError('issuer is required.');\n }\n\n // The browser channel carries login tickets, one-time codes and the session the user\n // is in the middle of establishing. Over `http` a network attacker on the same café\n // Wi-Fi reads the ticket and redeems it — and the sign-in box the user is looking at\n // is served by the attacker, so nothing about the page tells them.\n assertSecureIssuer(options.issuer);\n\n // Caught here rather than at the first request, because the failure otherwise arrives\n // as an opaque 401 from the network tab and the cause — a secret key pasted into a\n // browser bundle — is exactly the mistake worth naming out loud.\n if (!options.publishableKey?.startsWith('pk_')) {\n throw new ConfigurationError(\n 'publishableKey must be a pk_test_… or pk_live_… key. Client secrets and API keys must never be put in a browser.',\n );\n }\n\n this.issuer = options.issuer.replace(/\\/$/, '');\n this.publishableKey = options.publishableKey;\n this.timeoutMs = options.timeoutMs ?? 10_000;\n this.retries = Math.max(0, options.retries ?? 2);\n this.fetchImpl = options.fetch ?? globalThis.fetch.bind(globalThis);\n }\n\n /** Whether this key drives real sign-ins. Handy for a \"test mode\" badge in your own UI. */\n get isLive(): boolean {\n return this.publishableKey.startsWith('pk_live_');\n }\n\n /**\n * The public sign-in configuration.\n *\n * Fetched once per client instance. The document is small and changes when somebody\n * edits it in the console, so a long-lived page picks changes up on its next full load\n * rather than mid-session — which is the right trade for something that decides layout.\n * Each `organization` is fetched and cached on its own.\n */\n async config(options: FrontendConfigOptions = {}): Promise<FrontendConfig> {\n const organization = options.organization ?? '';\n let pending = this.configPromises.get(organization);\n\n if (pending === undefined) {\n const path = organization === ''\n ? '/frontend/v1/config'\n : `/frontend/v1/config?${new URLSearchParams({ organization }).toString()}`;\n\n pending = this.get<FrontendConfig>(path, {}, isFrontendConfig).catch((error: unknown) => {\n // Cleared so a transient network failure does not poison the instance for the\n // lifetime of the page.\n this.configPromises.delete(organization);\n throw error;\n });\n this.configPromises.set(organization, pending);\n }\n\n return pending;\n }\n\n /**\n * Who is signed in, given an access token your app already holds.\n *\n * Returns `{ user: null }` rather than throwing when nobody is signed in. That is a\n * state, not an error: a user button renders on pages nobody has signed in on, and\n * making callers treat a rejection as a state is how flash-of-signed-out bugs happen.\n *\n * The publishable key grants nothing here — the token is the entire authority.\n */\n async session(accessToken?: string): Promise<FrontendSession> {\n if (!accessToken) {\n return { user: null };\n }\n\n return this.get<FrontendSession>(\n '/frontend/v1/session',\n { Authorization: `Bearer ${accessToken}` },\n isFrontendSession,\n );\n }\n\n /**\n * Sign in with a password, from a form your page drew.\n *\n * WHAT COMES BACK IS A TICKET, NEVER A TOKEN. Handing tokens to a page that proved a\n * password is the implicit grant, which OAuth 2.1 removes: tokens in a URL, in history,\n * in `Referer`, with no client authentication and no PKCE binding. Spend the ticket by\n * sending the browser to `/oauth/authorize` with your own PKCE challenge and\n * `login_ticket` in the query — the ordinary flow, which then issues an ordinary code.\n *\n * It expires in sixty seconds. It is for one redirect, not for storing.\n *\n * ```ts\n * const result = await frontend.signIn(email, password)\n *\n * if (result.status === 'ok') {\n * window.location.href = `${config.endpoints.authorization}?${new URLSearchParams({\n * client_id, redirect_uri, response_type: 'code', code_challenge, code_challenge_method: 'S256',\n * login_ticket: result.loginTicket,\n * })}`\n * }\n * ```\n *\n * EVERY REFUSAL IS THE SAME REFUSAL. `invalid` covers a wrong password, an unknown\n * address and a locked account, because distinguishing them is the enumeration oracle\n * the server refuses to build — do not present them differently in your UI either.\n */\n async signIn(email: string, password: string): Promise<SignInResult> {\n const response = await this.post('/frontend/v1/sign-in', { email, password });\n\n if (response.status === 429) {\n const retryAfter = Number(response.headers.get('Retry-After') ?? '');\n\n return { status: 'rate_limited', retryAfter: Number.isFinite(retryAfter) ? retryAfter : undefined };\n }\n\n let body: { status?: string; login_ticket?: string; mfa_token?: string; expires_in?: number; factors?: unknown };\n\n try {\n body = (await response.json()) as typeof body;\n } catch {\n throw new FrontendApiError('Cbox ID returned a body that is not JSON.', 'malformed', response.status);\n }\n\n if (body.status === 'ok' && typeof body.login_ticket === 'string') {\n return { status: 'ok', loginTicket: body.login_ticket, expiresIn: body.expires_in ?? 60 };\n }\n\n if (body.status === 'mfa_required' && typeof body.mfa_token === 'string') {\n // Unknown kinds are dropped rather than passed on: a page that draws a button for a\n // factor this SDK cannot complete strands the person on it.\n const factors = Array.isArray(body.factors)\n ? body.factors.filter((f): f is SecondFactorKind => typeof f === 'string' && SECOND_FACTOR_KINDS.has(f))\n : undefined;\n\n return { status: 'mfa_required', mfaToken: body.mfa_token, ...(factors ? { factors } : {}) };\n }\n\n if (body.status === 'otp_required' && typeof body.mfa_token === 'string') {\n return { status: 'otp_required', mfaToken: body.mfa_token };\n }\n\n if (body.status === 'sso_required') {\n return { status: 'sso_required' };\n }\n\n return { status: 'invalid' };\n }\n\n /**\n * Finish a sign-in that owed a second factor.\n *\n * The token from `signIn()` carries the pending state, because a cross-origin page has\n * no session cookie to carry it in. A TOTP code or a recovery code both work — an\n * embedded form that could not accept a recovery code would strand exactly the people\n * that escape hatch exists for.\n *\n * A wrong code costs an attempt, not the sign-in: five are allowed before the token\n * dies and the person starts from the password again.\n *\n * `method` says which challenge the code answers: `'mfa'` for an authenticator or\n * recovery code, `'otp'` for an emailed code (`otp_required`), `'sms'` for a code sent\n * with {@link sendSmsCode}. A texted code is six digits like an authenticator's, so the\n * server cannot tell them apart by shape — answering one as the other is refused.\n */\n async submitSecondFactor(mfaToken: string, code: string, method: 'mfa' | 'otp' | 'sms' = 'mfa'): Promise<SignInResult> {\n const response = await this.post('/frontend/v1/sign-in/factor', { mfa_token: mfaToken, code, method });\n\n let body: { status?: string; login_ticket?: string; expires_in?: number };\n\n try {\n body = (await response.json()) as typeof body;\n } catch {\n throw new FrontendApiError('Cbox ID returned a body that is not JSON.', 'malformed', response.status);\n }\n\n return body.status === 'ok' && typeof body.login_ticket === 'string'\n ? { status: 'ok', loginTicket: body.login_ticket, expiresIn: body.expires_in ?? 60 }\n : { status: 'invalid' };\n }\n\n /**\n * Text the person a sign-in code, when `mfa_required` listed `'sms'` in `factors`.\n * Then finish with `submitSecondFactor(mfaToken, code, 'sms')`.\n *\n * Only call it when the person asks (\"Text me a code\"), never on page load: each send\n * spends one of the token's five attempts — that is what bounds how many texts one\n * proved password can cause — and every text costs the customer money.\n *\n * ```ts\n * if (result.status === 'mfa_required' && result.factors?.includes('sms')) {\n * const sent = await frontend.sendSmsCode(result.mfaToken)\n * if (sent.status === 'sent') showCodeField(`We texted ${sent.to}`)\n * }\n * ```\n */\n async sendSmsCode(mfaToken: string): Promise<SmsCodeResult> {\n const response = await this.post('/frontend/v1/sign-in/factor/sms', { mfa_token: mfaToken });\n\n let body: { status?: string; to?: unknown; expires_in?: unknown; retry_after?: unknown };\n\n try {\n body = (await response.json()) as typeof body;\n } catch {\n throw new FrontendApiError('Cbox ID returned a body that is not JSON.', 'malformed', response.status);\n }\n\n if (body.status === 'sent' && typeof body.to === 'string') {\n return { status: 'sent', to: body.to, expiresIn: typeof body.expires_in === 'number' ? body.expires_in : 300 };\n }\n\n if (body.status === 'rate_limited' || response.status === 429) {\n const retryAfter = typeof body.retry_after === 'number' ? body.retry_after : Number(response.headers.get('Retry-After') ?? '');\n\n return { status: 'rate_limited', retryAfter: Number.isFinite(retryAfter) && retryAfter > 0 ? retryAfter : undefined };\n }\n\n if (body.status === 'unavailable') {\n return { status: 'unavailable' };\n }\n\n return { status: 'invalid' };\n }\n\n /**\n * The WebAuthn options for a passkey sign-in, and the handle that carries the challenge.\n *\n * The handle exists because a cross-origin page has no session cookie to keep the\n * challenge in between the two requests WebAuthn needs. Pass it back to\n * {@link signInWithPasskey} with whatever `navigator.credentials.get()` returns.\n *\n * `allowCredentials` comes back empty on purpose: this is a discoverable-credential\n * flow, so the authenticator offers whichever passkey it holds and the page never has to\n * say who is signing in — asking for an email first, to look up which credentials exist,\n * would be an enumeration oracle.\n */\n async passkeyOptions(): Promise<PasskeyOptions> {\n const response = await this.post('/frontend/v1/sign-in/passkey/options', {});\n\n if (!response.ok) {\n throw new FrontendApiError(\n `Cbox ID refused the request (${response.status}). Check that this page's origin is on the key's allow-list.`,\n 'origin_not_allowed',\n response.status,\n );\n }\n\n return (await response.json()) as PasskeyOptions;\n }\n\n /**\n * Complete a passkey sign-in with the assertion the authenticator produced.\n *\n * `assertion` is the credential from `navigator.credentials.get()`, serialised — the\n * server verifies the raw body, so pass it through unchanged rather than rebuilding it.\n */\n async signInWithPasskey(challengeToken: string, assertion: Record<string, unknown>): Promise<SignInResult> {\n const response = await this.post('/frontend/v1/sign-in/passkey', { ...assertion, challenge_token: challengeToken });\n\n let body: { status?: string; login_ticket?: string; expires_in?: number };\n\n try {\n body = (await response.json()) as typeof body;\n } catch {\n throw new FrontendApiError('Cbox ID returned a body that is not JSON.', 'malformed', response.status);\n }\n\n return body.status === 'ok' && typeof body.login_ticket === 'string'\n ? { status: 'ok', loginTicket: body.login_ticket, expiresIn: body.expires_in ?? 60 }\n : { status: 'invalid' };\n }\n\n private async post(path: string, payload: Record<string, unknown>): Promise<Response> {\n const controller = new AbortController();\n const timer = setTimeout(() => controller.abort(), this.timeoutMs);\n\n try {\n return await this.fetchImpl(`${this.issuer}${path}`, {\n method: 'POST',\n headers: {\n 'X-Cbox-Publishable-Key': this.publishableKey,\n 'Content-Type': 'application/json',\n Accept: 'application/json',\n },\n body: JSON.stringify(payload),\n signal: controller.signal,\n });\n } catch {\n throw new FrontendApiError(\n `Could not reach Cbox ID at ${this.issuer}. If this is a browser, check that this page's origin is on the key's allow-list — a refused request fails as a network error by design.`,\n 'unavailable',\n );\n } finally {\n clearTimeout(timer);\n }\n }\n\n private async get<T>(\n path: string,\n extraHeaders: Record<string, string> = {},\n validate?: (body: unknown) => body is T,\n ): Promise<T> {\n let lastError: unknown;\n\n for (let attempt = 0; attempt <= this.retries; attempt++) {\n // Linear, not exponential, and only between attempts. This sits inside a page\n // render: a caller waiting on their sign-in box would rather fail in a second than\n // succeed in eight.\n if (attempt > 0) {\n await new Promise((resolve) => setTimeout(resolve, 150 * attempt));\n }\n\n try {\n return await this.attempt<T>(path, extraHeaders, validate);\n } catch (error) {\n lastError = error;\n\n // Retry only what a retry can fix. A refusal is a configuration problem and\n // retrying it delays the developer finding out; a rate limit is honoured rather\n // than hammered; a malformed body will be malformed again.\n if (!(error instanceof FrontendApiError) || error.code !== 'unavailable') {\n throw error;\n }\n }\n }\n\n throw lastError;\n }\n\n private async attempt<T>(\n path: string,\n extraHeaders: Record<string, string>,\n validate?: (body: unknown) => body is T,\n ): Promise<T> {\n const controller = new AbortController();\n const timer = setTimeout(() => controller.abort(), this.timeoutMs);\n\n let response: Response;\n\n try {\n response = await this.fetchImpl(`${this.issuer}${path}`, {\n headers: {\n // A header, never a query string: a query string puts the key in server logs,\n // in `Referer` on every outbound link, and in browser history.\n 'X-Cbox-Publishable-Key': this.publishableKey,\n Accept: 'application/json',\n ...extraHeaders,\n },\n signal: controller.signal,\n });\n } catch (cause) {\n // Includes the abort on timeout, and — in a browser — a refusal, because a refused\n // request deliberately carries no CORS headers and so never becomes a Response.\n throw new FrontendApiError(\n `Could not reach Cbox ID at ${this.issuer}. If this is a browser, check that this page's origin is on the key's allow-list — a refused request fails as a network error by design.`,\n 'unavailable',\n );\n } finally {\n clearTimeout(timer);\n }\n\n if (response.status === 429) {\n const retryAfter = Number(response.headers.get('Retry-After') ?? '');\n\n throw new FrontendApiError(\n (await described(response)) ?? 'Cbox ID is rate limiting this key.',\n 'rate_limited',\n 429,\n Number.isFinite(retryAfter) ? retryAfter : undefined,\n );\n }\n\n if (response.status === 401 || response.status === 403) {\n throw new FrontendApiError(\n // THE SERVER'S OWN REASON FIRST. It answers precisely — \"No publishable key was\n // presented\" is a different problem from \"That publishable key cannot be used\n // from this origin\" — and substituting a guess for it made this client less\n // precise than the API it wraps. The fallback still stands for the browser case,\n // where a refusal never becomes a readable Response at all.\n (await described(response)) ??\n `Cbox ID refused the request (${response.status}). Check that this page's origin is on the key's allow-list, and that the key is not revoked.`,\n 'origin_not_allowed',\n response.status,\n );\n }\n\n if (!response.ok) {\n throw new FrontendApiError(\n (await described(response)) ?? `Cbox ID returned ${response.status}.`,\n 'unavailable',\n response.status,\n );\n }\n\n let body: unknown;\n\n try {\n body = await response.json();\n } catch {\n throw new FrontendApiError('Cbox ID returned a body that is not JSON.', 'malformed', response.status);\n }\n\n // A 200 whose body is not the document we expect means something between the page and\n // us is rewriting responses — a proxy, an extension, a captive portal. Caught here so\n // it surfaces as that, rather than as `undefined` deep inside somebody's component.\n if (validate && !validate(body)) {\n throw new FrontendApiError(\n 'Cbox ID returned a body that is not the expected document.',\n 'malformed',\n response.status,\n );\n }\n\n return body as T;\n }\n}\n\n/**\n * The server's own `error_description`, when it sent one.\n *\n * Read from a CLONE: the caller may still want the body, and a Response body can only be\n * consumed once — a helper that quietly drained it would turn a precise error into a\n * different, stranger one.\n */\nasync function described(response: Response): Promise<string | undefined> {\n try {\n const body: unknown = await response.clone().json();\n\n if (typeof body === 'object' && body !== null && 'error_description' in body) {\n const description = (body as { error_description: unknown }).error_description;\n\n return typeof description === 'string' && description !== '' ? description : undefined;\n }\n } catch {\n // A refusal without a readable body is the normal case in a browser.\n }\n\n return undefined;\n}\n\n/** The shape check for the config document. Structural, not exhaustive. */\nfunction isFrontendConfig(body: unknown): body is FrontendConfig {\n if (typeof body !== 'object' || body === null) {\n return false;\n }\n\n const doc = body as Partial<FrontendConfig>;\n\n return typeof doc.issuer === 'string' && typeof doc.endpoints === 'object' && doc.endpoints !== null;\n}\n\n/** The shape check for the session document. `user: null` is valid and expected. */\nfunction isFrontendSession(body: unknown): body is FrontendSession {\n return typeof body === 'object' && body !== null && 'user' in body;\n}\n","import { AuthenticationError, ConfigurationError } from './errors.js';\nimport type { DiscoveryDocument } from './types.js';\n\n/**\n * Fetches and caches an instance's OIDC discovery document. One instance of this\n * lives per {@link CboxIdClient}; the document is refetched only after the TTL.\n */\nexport class Discovery {\n private cached: { doc: DiscoveryDocument; expiresAt: number } | null = null;\n\n constructor(\n private readonly issuer: string,\n private readonly timeoutMs: number,\n private readonly cacheTtlMs: number,\n private readonly now: () => number = Date.now,\n ) {}\n\n async document(): Promise<DiscoveryDocument> {\n if (this.cached && this.cached.expiresAt > this.now()) {\n return this.cached.doc;\n }\n\n const url = `${trimSlash(this.issuer)}/.well-known/openid-configuration`;\n const controller = new AbortController();\n const timer = setTimeout(() => controller.abort(), this.timeoutMs);\n\n let doc: DiscoveryDocument;\n try {\n const response = await fetch(url, { signal: controller.signal });\n if (!response.ok) {\n throw new AuthenticationError(`Discovery request failed with status ${response.status}.`);\n }\n doc = (await response.json()) as DiscoveryDocument;\n } catch (error) {\n if (error instanceof AuthenticationError) {\n throw error;\n }\n throw new AuthenticationError(`Discovery request failed: ${String(error)}`);\n } finally {\n clearTimeout(timer);\n }\n\n if (typeof doc.issuer !== 'string' || doc.issuer === '') {\n throw new AuthenticationError('The discovery document was missing an issuer.');\n }\n\n // RFC 8414 §3.3: the `issuer` in the document MUST match the one it was fetched for.\n // Without this the SDK sends credentials to whatever endpoints the document names and\n // verifies tokens against whatever JWKS it points at, while the caller still believes\n // it is talking to the issuer it configured — so one tenant's host answering with\n // another tenant's document silently redirects the whole flow.\n if (trimSlash(doc.issuer) !== trimSlash(this.issuer)) {\n throw new AuthenticationError(\n `The discovery document is for a different issuer (${doc.issuer}).`,\n );\n }\n\n this.cached = { doc, expiresAt: this.now() + this.cacheTtlMs };\n return doc;\n }\n\n /** A required endpoint from the discovery document. */\n async endpoint(name: keyof DiscoveryDocument): Promise<string> {\n const value = (await this.document())[name];\n if (typeof value !== 'string' || value === '') {\n throw new ConfigurationError(`The instance does not advertise a ${name}.`);\n }\n return value;\n }\n\n /** An optional endpoint, or null when the instance advertises none. */\n async optionalEndpoint(name: keyof DiscoveryDocument): Promise<string | null> {\n const value = (await this.document())[name];\n return typeof value === 'string' && value !== '' ? value : null;\n }\n}\n\n/** Compare issuers without letting a trailing slash decide identity. */\nfunction trimSlash(value: string): string {\n return value.replace(/\\/+$/, '');\n}\n","/**\n * PKCE (RFC 7636) and the random values the login flow needs, built on Web Crypto\n * (`globalThis.crypto`) so the same code runs on Node, edge runtimes and browsers.\n */\n\nfunction base64url(bytes: Uint8Array): string {\n let binary = '';\n for (const byte of bytes) {\n binary += String.fromCharCode(byte);\n }\n return btoa(binary).replace(/\\+/g, '-').replace(/\\//g, '_').replace(/=+$/, '');\n}\n\n/** A URL-safe random token of `bytes` bytes (default 32), for state and nonce. */\nexport function randomToken(bytes = 32): string {\n return base64url(crypto.getRandomValues(new Uint8Array(bytes)));\n}\n\n/** A high-entropy PKCE code verifier. */\nexport function createVerifier(): string {\n return randomToken(32);\n}\n\n/** The S256 code challenge for a verifier. */\nexport async function challenge(verifier: string): Promise<string> {\n const digest = await crypto.subtle.digest('SHA-256', new TextEncoder().encode(verifier));\n return base64url(new Uint8Array(digest));\n}\n","import type { CboxUser } from './types.js';\n\n/**\n * The membership tier a person holds in the organization a token is bound to — the\n * `org_role` claim. Coarse on purpose: it says who may administer the organization\n * itself (invite, bill, delete). What they may do inside YOUR app is `roles` /\n * `permissions`, which your app declares and Cbox ID assigns.\n */\nexport type OrganizationRole = 'owner' | 'admin' | 'developer' | 'member' | 'viewer';\n\nconst ORGANIZATION_ROLES: ReadonlySet<string> = new Set<OrganizationRole>([\n 'owner',\n 'admin',\n 'developer',\n 'member',\n 'viewer',\n]);\n\n/** The organization a token is bound to: the `org`, `org_name` and `org_role` claims. */\nexport interface CboxActiveOrganization {\n /** The stable organization id (`org`). */\n id: string;\n /** Its display name (`org_name`), when the instance sent one. */\n name: string | null;\n /**\n * The person's membership tier in it (`org_role`). Null when the claim is absent, or\n * carries a tier this SDK version does not know — an unrecognised tier is never\n * guessed upward into one that grants something.\n */\n role: OrganizationRole | null;\n}\n\n/**\n * Who is actually driving a delegated session — the RFC 8693 §4.1 `act` claim. Cbox ID\n * sets it on the tokens of a SUPPORT SESSION: a staff member acting as one of your users,\n * with a stated reason, for at most an hour, with no refresh token.\n *\n * `sub` is the actor's subject id. It is null when an `act` claim is present but not in\n * the shape RFC 8693 describes — the token is still acted, and saying so matters more\n * than knowing by whom (see {@link isSupportSession}).\n */\nexport interface CboxActor {\n sub: string | null;\n /** The prior actor, when delegation was chained (RFC 8693 §4.1 nested `act`). */\n actor: CboxActor | null;\n}\n\n/**\n * Anything the helpers below can read claims from: a {@link CboxUser} from sign-in, or a\n * claim set you verified yourself — an access token's payload on a resource server, say.\n */\nexport type ClaimSource = CboxUser | Readonly<Record<string, unknown>>;\n\n/**\n * The organization this session is bound to, or null when it is bound to none.\n *\n * ```ts\n * const org = organization(user);\n * if (org?.role === 'owner') showBilling();\n * ```\n */\nexport function organization(source: ClaimSource): CboxActiveOrganization | null {\n const claims = claimsOf(source);\n const id = claims['org'];\n\n if (typeof id !== 'string' || id === '') {\n return null;\n }\n\n const name = claims['org_name'];\n const role = claims['org_role'];\n\n return {\n id,\n name: typeof name === 'string' && name !== '' ? name : null,\n role: typeof role === 'string' && ORGANIZATION_ROLES.has(role) ? (role as OrganizationRole) : null,\n };\n}\n\n/**\n * The actor behind a support session (`act`), or null for an ordinary session in which\n * the person is acting as themselves.\n */\nexport function actor(source: ClaimSource): CboxActor | null {\n return parseActor(claimsOf(source)['act'], 0);\n}\n\n/**\n * Whether somebody other than the signed-in person is driving this session — a staff\n * member in a support session (the token carries `act`).\n *\n * FAIL-CLOSED. Any `act` claim at all counts, including one whose shape this SDK cannot\n * read: the check exists so an app can show a banner and refuse the things a helper\n * should never do on somebody's behalf (change their password, move their money), and a\n * malformed claim is not evidence that nobody else is at the keyboard.\n */\nexport function isSupportSession(source: ClaimSource): boolean {\n return actor(source) !== null;\n}\n\n/**\n * The Cbox ID sign-in session this token came from — the ID Token's `sid` claim — or null\n * when the instance sent none.\n *\n * Store it with your own session: an OIDC Back-Channel Logout token names the session it\n * ends by this value, and matching on it is how you end the right one (rather than every\n * session the person has) when they sign out of Cbox ID elsewhere.\n */\nexport function sessionId(source: ClaimSource): string | null {\n const sid = claimsOf(source)['sid'];\n\n return typeof sid === 'string' && sid !== '' ? sid : null;\n}\n\n/** The app roles this session holds — the `roles` claim; empty when there are none. */\nexport function roles(source: ClaimSource): string[] {\n return stringList(claimsOf(source)['roles']);\n}\n\n/**\n * The permissions this session holds — the `permissions` claim, already expanded from\n * `roles` by Cbox ID; empty when there are none.\n */\nexport function permissions(source: ClaimSource): string[] {\n return stringList(claimsOf(source)['permissions']);\n}\n\n/** Whether the session holds `role`. Exact match; no wildcards. */\nexport function hasRole(source: ClaimSource, role: string): boolean {\n return roles(source).includes(role);\n}\n\n/**\n * Whether the session holds `permission` (`feature:action`). Exact match; no wildcards\n * — a claim of `invoices:*` does not grant `invoices:delete`, because nothing on the\n * issuing side ever mints one.\n */\nexport function hasPermission(source: ClaimSource, permission: string): boolean {\n return permissions(source).includes(permission);\n}\n\n/**\n * The scope that puts the `feature_flags` claim on the ID token, the access token and\n * UserInfo. Request it at sign-in (`scopes: ['openid', 'profile', FEATURE_FLAGS_SCOPE]`)\n * and give the app the scope on its Scopes tab.\n */\nexport const FEATURE_FLAGS_SCOPE = 'feature_flags';\n\n/**\n * The keys of the feature flags that are on for this person, in the organization the\n * session is bound to — the `feature_flags` claim, sorted as the server sent it.\n *\n * NULL IS NOT EMPTY. `null` means the claim is absent: the `feature_flags` scope was not\n * requested, or the instance predates it. `[]` means it was asked and nothing is on. A\n * token carries the flags as they were when it was issued; the next refresh, or UserInfo,\n * picks up a change.\n */\nexport function featureFlags(source: ClaimSource): string[] | null {\n const claim = claimsOf(source)['feature_flags'];\n\n return Array.isArray(claim) ? stringList(claim) : null;\n}\n\n/**\n * Whether the feature flag `key` is on for this session. Exact match on the key.\n *\n * False when the claim is absent — an app that forgot to request the scope sees every\n * feature off, never every feature on. Use {@link featureFlags} to tell the two apart.\n */\nexport function hasFeature(source: ClaimSource, key: string): boolean {\n return featureFlags(source)?.includes(key) ?? false;\n}\n\n/**\n * Nesting is bounded: RFC 8693 chains are a handful deep in practice, and a claim nested\n * thousands deep is either a bug or an attempt to exhaust the stack. Past the bound the\n * chain is cut, not dropped — the session is still acted.\n */\nconst MAX_ACTOR_DEPTH = 8;\n\nfunction parseActor(claim: unknown, depth: number): CboxActor | null {\n if (claim === undefined || claim === null) {\n return null;\n }\n\n if (typeof claim !== 'object' || Array.isArray(claim)) {\n return { sub: null, actor: null };\n }\n\n const record = claim as Record<string, unknown>;\n const sub = record['sub'];\n\n return {\n sub: typeof sub === 'string' && sub !== '' ? sub : null,\n actor: depth + 1 < MAX_ACTOR_DEPTH ? parseActor(record['act'], depth + 1) : null,\n };\n}\n\nfunction stringList(claim: unknown): string[] {\n return Array.isArray(claim)\n ? claim.filter((value): value is string => typeof value === 'string' && value !== '')\n : [];\n}\n\nfunction claimsOf(source: ClaimSource): Readonly<Record<string, unknown>> {\n return isUser(source) ? source.claims : source;\n}\n\n/**\n * A `CboxUser` is told apart by the credential it carries alongside its claims. A raw\n * claim set never has an `accessToken` key — JWT claims are snake_case — so a verified\n * payload is never mistaken for a user and read from the wrong place.\n */\nfunction isUser(source: ClaimSource): source is CboxUser {\n return (\n typeof source['claims'] === 'object' &&\n source['claims'] !== null &&\n typeof source['accessToken'] === 'string'\n );\n}\n","import { AuthenticationError, CboxIdError } from './errors.js';\n\n/** A stored vault secret's metadata (never its plaintext). */\nexport interface VaultSecretRef {\n id: string;\n name: string;\n provider: string;\n ownerType: string | null;\n ownerId: string | null;\n expiresAt: string | null;\n revoked: boolean;\n}\n\n/** A brokered credential — the plaintext, for immediate use. */\nexport interface VaultLease {\n secretId: string;\n provider: string;\n secret: string;\n expiresAt: string;\n}\n\n/** A provider a pipe can connect to. */\nexport type PipeProvider = 'github' | 'google' | 'microsoft' | 'slack' | 'salesforce' | 'hubspot' | 'linear' | 'notion';\n\n/**\n * A fresh access token for one person's connected account at a provider — what\n * {@link VaultClient.leasePipeToken} returns. Use it, drop it, lease again next time.\n */\nexport interface PipeToken {\n /** The provider's access token. Send it as a bearer token to the provider's API. */\n accessToken: string;\n tokenType: 'Bearer';\n provider: string;\n userId: string;\n connectionId: string;\n /** What the person consented to. */\n scopes: string[];\n /** When the PROVIDER stops accepting it; null for tokens that do not expire. */\n expiresAt: string | null;\n /** When to drop it and lease again. */\n leaseExpiresAt: string;\n /** What some providers need to be called at all — Salesforce's `instance_url`, Slack's `team.id`. */\n metadata: Record<string, string>;\n}\n\n/** Where a person connects a provider, and where they come back to afterwards. */\nexport interface PipeConnectOptions {\n /** Your app's client id — the connect page shows its name and allows its origins. */\n clientId?: string;\n /**\n * Where to land afterwards, with `?provider=…&status=connected|cancelled|failed`. Must be\n * on one of the app's registered redirect origins, or it is ignored.\n */\n returnTo?: string;\n}\n\n/**\n * Add `client_id` and `return_to` to a connect URL — the one a lease error carries, or\n * one built with {@link pipeConnectUrl}.\n */\nexport function withConnectReturn(connectUrl: string, options: PipeConnectOptions = {}): string {\n const url = new URL(connectUrl);\n if (options.clientId) url.searchParams.set('client_id', options.clientId);\n if (options.returnTo) url.searchParams.set('return_to', options.returnTo);\n return url.toString();\n}\n\n/**\n * The hosted page where the signed-in person connects their account at `provider`:\n * `{issuer}/account/connected-services/{provider}/connect?client_id=…&return_to=…`.\n */\nexport function pipeConnectUrl(issuer: string, provider: PipeProvider | string, options: PipeConnectOptions = {}): string {\n return withConnectReturn(\n `${issuer.replace(/\\/$/, '')}/account/connected-services/${encodeURIComponent(provider)}/connect`,\n options,\n );\n}\n\n/**\n * A pipe token lease was refused. Catch the subclasses for the cases you can act on:\n *\n * - {@link PipeNotConnectedError} (404) and {@link PipeReauthorizationRequiredError}\n * (409) — send the person to `connectUrl`.\n * - {@link PipeTemporarilyUnavailableError} (503) — retry after `retryAfter` seconds.\n * - {@link PipeLeaseDeniedError} (403) — a configuration problem: the app is not granted\n * the pipe, it is disabled, or the person is outside the app's organization.\n *\n * Anything else (401, 422, 429) arrives as this base class with `status` and `error`.\n */\nexport class PipeLeaseError extends CboxIdError {\n constructor(\n message: string,\n /** The server's error code, e.g. `not_connected`. */\n readonly error: string | null,\n readonly status: number,\n /** Where to send the person to (re)connect — set on 404 and 409. */\n readonly connectUrl: string | null = null,\n /** Seconds to wait off `Retry-After`, when the server sent one. */\n readonly retryAfter: number | null = null,\n ) {\n super(message);\n }\n\n /** `connectUrl` with your `client_id` and `return_to` on it, or null when there is none. */\n connectUrlWith(options: PipeConnectOptions): string | null {\n return this.connectUrl === null ? null : withConnectReturn(this.connectUrl, options);\n }\n}\n\n/** The person has not connected this provider (404 `not_connected`). Send them to `connectUrl`. */\nexport class PipeNotConnectedError extends PipeLeaseError {\n declare readonly connectUrl: string;\n}\n\n/**\n * The provider stopped accepting the connection — revoked, or the refresh token expired\n * (409 `reauthorization_required`). Send the person to `connectUrl` to connect again.\n */\nexport class PipeReauthorizationRequiredError extends PipeLeaseError {\n declare readonly connectUrl: string;\n}\n\n/** The provider could not refresh the token just now (503). Retry after `retryAfter`. */\nexport class PipeTemporarilyUnavailableError extends PipeLeaseError {}\n\n/**\n * The lease was denied (403 `lease_denied`): the app is not granted the pipe, the pipe is\n * disabled or missing, the person is not in the app's organization, or `userId` names\n * someone other than the token's person. One answer for every reason, by design.\n */\nexport class PipeLeaseDeniedError extends PipeLeaseError {}\n\nexport interface StoreSecretInput {\n name: string;\n provider: string;\n secret: string;\n ownerType?: 'organization' | 'user';\n ownerId?: string;\n expiresAt?: string;\n}\n\n/**\n * Client for a Cbox ID instance's Token Vault API. Bind it to an access token\n * (obtain one with {@link CboxIdClient.machineToken}, scoped `vault.manage` for\n * provisioning or `vault.lease` for redeeming). All calls are server-to-server.\n */\nexport class VaultClient {\n private readonly base: string;\n\n constructor(\n issuer: string,\n private readonly token: string,\n private readonly timeoutMs = 10_000,\n ) {\n this.base = `${issuer.replace(/\\/$/, '')}/api/v1/vault`;\n }\n\n /** Ingest a downstream credential, sealed at rest (scope `vault.manage`). */\n store(input: StoreSecretInput): Promise<VaultSecretRef> {\n return this.json<VaultSecretRef>('POST', '/secrets', {\n name: input.name,\n provider: input.provider,\n secret: input.secret,\n owner_type: input.ownerType,\n owner_id: input.ownerId,\n expires_at: input.expiresAt,\n });\n }\n\n /** Rotate a secret's value, keeping its id and grants (scope `vault.manage`). */\n rotate(secretId: string, secret: string): Promise<VaultSecretRef> {\n return this.json<VaultSecretRef>('POST', `/secrets/${encodeURIComponent(secretId)}/rotate`, { secret });\n }\n\n /** Revoke a secret permanently (scope `vault.manage`). */\n async revoke(secretId: string): Promise<void> {\n await this.request('DELETE', `/secrets/${encodeURIComponent(secretId)}`);\n }\n\n /** Authorize an agent client to lease a secret (scope `vault.manage`). */\n grant(\n secretId: string,\n clientId: string,\n maxTtlSeconds?: number,\n ): Promise<{ secretId: string; clientId: string; maxTtlSeconds: number | null }> {\n return this.json('POST', `/secrets/${encodeURIComponent(secretId)}/grants`, {\n client_id: clientId,\n max_ttl_seconds: maxTtlSeconds,\n }).then((raw) => {\n const r = raw as { secret_id: string; client_id: string; max_ttl_seconds: number | null };\n return { secretId: r.secret_id, clientId: r.client_id, maxTtlSeconds: r.max_ttl_seconds };\n });\n }\n\n /** Revoke an agent's authorization (scope `vault.manage`). */\n async revokeGrant(secretId: string, clientId: string): Promise<void> {\n await this.request(\n 'DELETE',\n `/secrets/${encodeURIComponent(secretId)}/grants/${encodeURIComponent(clientId)}`,\n );\n }\n\n /**\n * Redeem a leased credential for immediate use (scope `vault.lease`). The caller\n * is identified by the token's client; a lease with no live grant is refused.\n */\n lease(secretId: string, purpose: string): Promise<VaultLease> {\n return this.json('POST', `/secrets/${encodeURIComponent(secretId)}/lease`, { purpose }).then((raw) => {\n const r = raw as { secret_id: string; provider: string; secret: string; expires_at: string };\n return { secretId: r.secret_id, provider: r.provider, secret: r.secret, expiresAt: r.expires_at };\n });\n }\n\n /**\n * Lease a fresh access token for a person's connected account at `provider` (Pipes,\n * scope `vault.lease`). The token is refreshed first when it is about to expire, so\n * you never handle a refresh token.\n *\n * With a client-credentials token, name the person in `userId`. With a token issued to\n * your app FOR a person, leave it out — the lease is theirs.\n *\n * ```ts\n * try {\n * const { accessToken } = await vault.leasePipeToken('github', { userId, purpose: 'list-repos' })\n * } catch (e) {\n * if (e instanceof PipeNotConnectedError || e instanceof PipeReauthorizationRequiredError) {\n * return redirect(e.connectUrlWith({ clientId, returnTo }))\n * }\n * throw e\n * }\n * ```\n */\n async leasePipeToken(\n provider: PipeProvider | string,\n options: { purpose: string; userId?: string },\n ): Promise<PipeToken> {\n const path = `/pipes/${encodeURIComponent(provider)}/token`;\n const response = await this.send('POST', path, {\n purpose: options.purpose,\n ...(options.userId !== undefined ? { user_id: options.userId } : {}),\n });\n\n let body: Record<string, unknown> = {};\n try {\n const parsed: unknown = await response.json();\n if (typeof parsed === 'object' && parsed !== null && !Array.isArray(parsed)) {\n body = parsed as Record<string, unknown>;\n }\n } catch {\n // Not JSON — a proxy's error page. The status below is all there is.\n }\n\n if (!response.ok) {\n throw pipeLeaseError(response, body);\n }\n\n if (typeof body.access_token !== 'string') {\n throw new PipeLeaseError('The pipe lease answered without an access token.', null, response.status);\n }\n\n return {\n accessToken: body.access_token,\n tokenType: 'Bearer',\n provider: String(body.provider ?? provider),\n userId: String(body.user_id ?? ''),\n connectionId: String(body.connection_id ?? ''),\n scopes: Array.isArray(body.scopes) ? body.scopes.filter((s): s is string => typeof s === 'string') : [],\n expiresAt: typeof body.expires_at === 'string' ? body.expires_at : null,\n leaseExpiresAt: String(body.lease_expires_at ?? ''),\n metadata: isStringRecord(body.metadata) ? body.metadata : {},\n };\n }\n\n private async json<T>(method: string, path: string, body: Record<string, unknown>): Promise<T> {\n const response = await this.request(method, path, body);\n return (await response.json()) as T;\n }\n\n private async request(method: string, path: string, body?: Record<string, unknown>): Promise<Response> {\n const response = await this.send(method, path, body);\n if (!response.ok) {\n throw new AuthenticationError(`Vault ${method} ${path} failed with status ${response.status}.`);\n }\n return response;\n }\n\n private async send(method: string, path: string, body?: Record<string, unknown>): Promise<Response> {\n const controller = new AbortController();\n const timer = setTimeout(() => controller.abort(), this.timeoutMs);\n try {\n const init: RequestInit = {\n method,\n headers: {\n authorization: `Bearer ${this.token}`,\n ...(body ? { 'content-type': 'application/json' } : {}),\n },\n signal: controller.signal,\n };\n if (body) {\n init.body = JSON.stringify(body);\n }\n return await fetch(`${this.base}${path}`, init);\n } finally {\n clearTimeout(timer);\n }\n }\n}\n\nfunction pipeLeaseError(response: Response, body: Record<string, unknown>): PipeLeaseError {\n const error = typeof body.error === 'string' ? body.error : null;\n const message = typeof body.message === 'string' && body.message !== ''\n ? body.message\n : `The pipe lease failed with status ${response.status}.`;\n const connectUrl = typeof body.connect_url === 'string' && body.connect_url !== '' ? body.connect_url : null;\n const header = response.headers.get('retry-after')?.trim() ?? '';\n const retryAfter = /^\\d+$/.test(header) ? Number(header) : null;\n\n if (response.status === 404 && connectUrl !== null) {\n return new PipeNotConnectedError(message, error, 404, connectUrl, retryAfter);\n }\n if (response.status === 409 && connectUrl !== null) {\n return new PipeReauthorizationRequiredError(message, error, 409, connectUrl, retryAfter);\n }\n if (response.status === 503) {\n return new PipeTemporarilyUnavailableError(message, error, 503, connectUrl, retryAfter);\n }\n if (response.status === 403 && error !== 'insufficient_scope') {\n return new PipeLeaseDeniedError(message, error, 403, connectUrl, retryAfter);\n }\n\n return new PipeLeaseError(message, error, response.status, connectUrl, retryAfter);\n}\n\nfunction isStringRecord(value: unknown): value is Record<string, string> {\n return (\n typeof value === 'object' &&\n value !== null &&\n !Array.isArray(value) &&\n Object.values(value).every((v) => typeof v === 'string')\n );\n}\n","/**\n * Verify a Cbox ID webhook / inline-action signature. The header is\n * `X-Cbox-Signature: t={unix},v1={hex hmac}` — an HMAC-SHA256 over\n * `\"{timestamp}.{raw body}\"`, valid within a freshness window. Built on Web Crypto\n * so it runs on Node, edge and the browser.\n */\n\n/** Constant-time compare of two hex strings. */\nfunction timingSafeEqual(a: string, b: string): boolean {\n if (a.length !== b.length) {\n return false;\n }\n let mismatch = 0;\n for (let i = 0; i < a.length; i++) {\n mismatch |= a.charCodeAt(i) ^ b.charCodeAt(i);\n }\n return mismatch === 0;\n}\n\nfunction toHex(bytes: ArrayBuffer): string {\n return Array.from(new Uint8Array(bytes))\n .map((b) => b.toString(16).padStart(2, '0'))\n .join('');\n}\n\nexport interface VerifyWebhookOptions {\n /** The RAW request body — the exact bytes received, not a re-encoded copy. */\n payload: string;\n /** The value of the `X-Cbox-Signature` header. */\n signatureHeader: string | null | undefined;\n /** The signing secret issued when the webhook/action endpoint was registered. */\n secret: string;\n /** Freshness window in seconds. Defaults to 300 (5 minutes). */\n toleranceSeconds?: number;\n /** Injectable clock (unix seconds), for tests. Defaults to `Date.now()`. */\n now?: number;\n}\n\n/** Returns `true` only when the signature is present, fresh and valid. Never throws. */\nexport async function verifyWebhook(options: VerifyWebhookOptions): Promise<boolean> {\n const { payload, signatureHeader, secret } = options;\n const toleranceSeconds = options.toleranceSeconds ?? 300;\n const now = options.now ?? Math.floor(Date.now() / 1000);\n\n if (!signatureHeader) {\n return false;\n }\n\n const parts: Record<string, string> = {};\n for (const segment of signatureHeader.split(',')) {\n const [key, value] = segment.trim().split('=', 2);\n if (key) {\n parts[key] = value ?? '';\n }\n }\n\n const timestamp = parts['t'] ?? '';\n const signature = parts['v1'] ?? '';\n\n if (timestamp === '' || signature === '' || !/^\\d+$/.test(timestamp)) {\n return false;\n }\n\n if (Math.abs(now - Number(timestamp)) > toleranceSeconds) {\n return false;\n }\n\n const key = await crypto.subtle.importKey(\n 'raw',\n new TextEncoder().encode(secret),\n { name: 'HMAC', hash: 'SHA-256' },\n false,\n ['sign'],\n );\n const expected = toHex(\n await crypto.subtle.sign('HMAC', key, new TextEncoder().encode(`${timestamp}.${payload}`)),\n );\n\n return timingSafeEqual(expected, signature);\n}\n\n/** Headers as a `Headers` object or a plain record (Node's `IncomingHttpHeaders`, a framework's map). */\nexport type WebhookHeaders = Headers | Record<string, string | readonly string[] | undefined>;\n\nexport interface VerifyStandardWebhookOptions {\n /** The RAW request body — the exact bytes received, not a re-encoded copy. */\n payload: string;\n /** The request headers; `webhook-id`, `webhook-timestamp` and `webhook-signature` are read. */\n headers: WebhookHeaders;\n /**\n * The endpoint's secret: a `whsec_…` secret, or the 64-hex secret of an endpoint that\n * moved from the `cbox` scheme (Cbox ID uses it as `whsec_` + base64 of the hex string,\n * which keys the HMAC with the same bytes).\n */\n secret: string;\n /** Freshness window in seconds. Defaults to 300 (5 minutes). */\n toleranceSeconds?: number;\n /** Injectable clock (unix seconds), for tests. Defaults to `Date.now()`. */\n now?: number;\n}\n\nfunction header(headers: WebhookHeaders, name: string): string | undefined {\n if (typeof Headers !== 'undefined' && headers instanceof Headers) {\n return headers.get(name) ?? undefined;\n }\n\n const record = headers as Record<string, string | readonly string[] | undefined>;\n const key = Object.keys(record).find((k) => k.toLowerCase() === name);\n const value = key === undefined ? undefined : record[key];\n\n return Array.isArray(value) ? value.join(' ') : (value as string | undefined);\n}\n\nfunction base64ToBytes(value: string): Uint8Array<ArrayBuffer> | null {\n try {\n const binary = atob(value);\n return Uint8Array.from(binary, (c) => c.charCodeAt(0));\n } catch {\n return null;\n }\n}\n\nfunction toBase64(bytes: ArrayBuffer): string {\n let binary = '';\n for (const byte of new Uint8Array(bytes)) {\n binary += String.fromCharCode(byte);\n }\n return btoa(binary);\n}\n\n/**\n * Verify a delivery from an endpoint on the `standard_webhooks` signature scheme\n * ([Standard Webhooks](https://www.standardwebhooks.com/)): `webhook-signature` carries one or\n * more space-separated `v1,<base64 HMAC-SHA256 of \"{webhook-id}.{webhook-timestamp}.{body}\">`,\n * and the timestamp must be within the freshness window. Use {@link verifyWebhook} for the\n * default `cbox` scheme (`X-Cbox-Signature`).\n *\n * Returns `true` only when a signature is present, fresh and valid. Never throws.\n */\nexport async function verifyStandardWebhook(options: VerifyStandardWebhookOptions): Promise<boolean> {\n const { payload, headers, secret } = options;\n const toleranceSeconds = options.toleranceSeconds ?? 300;\n const now = options.now ?? Math.floor(Date.now() / 1000);\n\n const id = header(headers, 'webhook-id');\n const timestamp = header(headers, 'webhook-timestamp');\n const signatures = header(headers, 'webhook-signature');\n\n if (!id || !timestamp || !signatures || !/^\\d+$/.test(timestamp)) {\n return false;\n }\n\n if (Math.abs(now - Number(timestamp)) > toleranceSeconds) {\n return false;\n }\n\n const keyBytes: Uint8Array<ArrayBuffer> | null = secret.startsWith('whsec_') ? base64ToBytes(secret.slice('whsec_'.length)) : new TextEncoder().encode(secret);\n\n if (keyBytes === null || keyBytes.length === 0) {\n return false;\n }\n\n const key = await crypto.subtle.importKey('raw', keyBytes, { name: 'HMAC', hash: 'SHA-256' }, false, ['sign']);\n const expected = toBase64(await crypto.subtle.sign('HMAC', key, new TextEncoder().encode(`${id}.${timestamp}.${payload}`)));\n\n // Several signatures may be sent while a secret rotates; any valid `v1` one is enough.\n let valid = false;\n for (const candidate of signatures.split(' ')) {\n const [version, signature] = candidate.split(',', 2);\n if (version === 'v1' && signature !== undefined && timingSafeEqual(expected, signature)) {\n valid = true;\n }\n }\n\n return valid;\n}\n","import { createRemoteJWKSet, jwtVerify, type JWTPayload } from 'jose';\nimport { Discovery } from './discovery.js';\nimport { assertSecureIssuer } from './issuer.js';\nimport { AuthenticationError, ConfigurationError, InvalidStateError, oauthError } from './errors.js';\nimport { challenge, createVerifier, randomToken } from './pkce.js';\nimport { actor, featureFlags, organization, permissions, roles, sessionId } from './claims.js';\nimport { pipeConnectUrl, type PipeProvider } from './vault.js';\nimport type {\n AuthorizationPrompt,\n AuthorizationRequest,\n AuthorizationRequestOptions,\n CboxIdConfig,\n DeviceAuthorization,\n CboxOrganization,\n CboxUser,\n RefreshedTokens,\n TokenResponse,\n TokenTypeHint,\n} from './types.js';\nimport { VaultClient } from './vault.js';\nimport { verifyWebhook, type VerifyWebhookOptions } from './webhook.js';\n\ntype JwksResolver = ReturnType<typeof createRemoteJWKSet>;\n\n/** Query parameters as they arrive on your callback route. */\nexport interface CallbackParams {\n code?: string | null;\n state?: string | null;\n error?: string | null;\n error_description?: string | null;\n}\n\n/** The values you persisted from {@link CboxIdClient.createAuthorizationRequest}. */\nexport interface StoredAuthState {\n state: string;\n codeVerifier: string;\n nonce: string;\n /** The `maxAge` this login demanded, if any. See {@link AuthorizationRequest.maxAge}. */\n maxAge?: number;\n /**\n * The organization this sign-in was bound to, if any. See\n * {@link AuthorizationRequest.organization}.\n *\n * Checked, not trusted: a binding nobody verifies is a binding in name only. An\n * instance that predates the `organization` parameter ignores it and returns tokens for\n * whichever organization the session already had — and an app that switched to \"Globex\"\n * would then show Globex's name over Acme's data.\n */\n organization?: string;\n /**\n * The scopes THIS authorization asked for, when you overrode the configured set.\n *\n * Read so `authenticate()` can judge the response against what was requested rather\n * than against the config: a login that asked for `openid` and came back without an\n * id_token is a protocol violation, and one that never asked cannot be held to it.\n * Omitted, the configured scopes are assumed — which is what a caller who did not\n * override them actually sent.\n */\n scopes?: string[];\n}\n\n/**\n * Turnkey Cbox ID client for JavaScript/TypeScript. It speaks standard OpenID\n * Connect against a Cbox ID instance — so integrating is a redirect and a callback,\n * not a rewrite — and adds the conveniences a hosted-identity product needs: a\n * redirect to the instance's hosted profile page, and back-channel helpers (machine\n * tokens, userinfo, introspection, webhook verification).\n *\n * Login is hardened by default: PKCE (S256), a CSRF state check, a nonce, and full\n * id_token signature + issuer + audience verification against the instance's JWKS\n * (via `jose`).\n *\n * The class is framework-agnostic: {@link createAuthorizationRequest} hands you the\n * `state`, `codeVerifier` and `nonce` to persist however you like, and\n * {@link authenticate} takes them back. For Next.js, the `@cboxdk/id-js/nextjs`\n * entry wires this to cookies for you.\n */\nexport class CboxIdClient {\n private readonly discovery: Discovery;\n private readonly jwksByUri = new Map<string, JwksResolver>();\n\n constructor(private readonly config: CboxIdConfig) {\n if (!config.issuer) {\n throw new ConfigurationError('Cbox ID config `issuer` is required.');\n }\n if (!config.clientId) {\n throw new ConfigurationError('Cbox ID config `clientId` is required.');\n }\n assertSecureIssuer(config.issuer);\n this.discovery = new Discovery(\n config.issuer,\n config.timeoutMs ?? 10_000,\n config.cacheTtlMs ?? 3_600_000,\n );\n }\n\n /**\n * Begin login. Returns the authorize URL plus the `state`, `codeVerifier` and\n * `nonce` — persist those (signed, httpOnly cookies are ideal) and hand them back\n * to {@link authenticate} on the callback.\n */\n async createAuthorizationRequest(options: AuthorizationRequestOptions = {}): Promise<AuthorizationRequest> {\n const prompt = promptValue(options.prompt);\n assertOrganizationOptions(options, prompt);\n\n const codeVerifier = createVerifier();\n const state = options.state ?? randomToken(16);\n const nonce = randomToken(16);\n\n const redirectUri = options.redirectUri ?? this.config.redirectUri;\n\n if (redirectUri === undefined || redirectUri === '') {\n // Checked where it is needed rather than at construction, so a CLI can build a\n // client at all. An authorize URL without `redirect_uri` would fail at the\n // authorization server instead, describing a request the caller never knowingly\n // made — see the device grant, which has no callback to name.\n throw new ConfigurationError(\n 'A `redirectUri` is required to start the browser sign-in flow. Set it in the config, or pass it to createAuthorizationRequest.',\n );\n }\n\n const params = new URLSearchParams({\n response_type: 'code',\n client_id: this.config.clientId,\n redirect_uri: redirectUri,\n scope: (options.scopes ?? this.scopes()).join(' '),\n state,\n nonce,\n code_challenge: await challenge(codeVerifier),\n code_challenge_method: 'S256',\n });\n if (prompt.length > 0) {\n params.set('prompt', prompt.join(' '));\n }\n if (options.loginHint) {\n params.set('login_hint', options.loginHint);\n }\n if (typeof options.maxAge === 'number') {\n params.set('max_age', String(options.maxAge));\n }\n if (options.organization !== undefined) {\n params.set('organization', options.organization);\n }\n if (options.organizationHint !== undefined) {\n params.set('organization_hint', options.organizationHint);\n }\n\n const endpoint = await this.discovery.endpoint('authorization_endpoint');\n return {\n url: `${endpoint}?${params.toString()}`,\n state,\n codeVerifier,\n nonce,\n // Carried through so authenticate() can hold the instance to it. Only present\n // when requested (exactOptionalPropertyTypes).\n ...(typeof options.maxAge === 'number' ? { maxAge: options.maxAge } : {}),\n ...(options.organization !== undefined ? { organization: options.organization } : {}),\n };\n }\n\n /**\n * Switch the signed-in person to another organization: a new authorization bound to\n * `organizationId`. Persist and redirect exactly as for\n * {@link createAuthorizationRequest} — it is one, with `organization` set.\n *\n * Cbox ID already holds the person's session, so this is normally a redirect there and\n * straight back with no sign-in form. The tokens that come back carry the new `org`,\n * `org_role`, `roles` and `permissions`; replace your session with them rather than\n * patching the old one, because every one of those can differ between organizations.\n *\n * A person who is not (or is no longer) an active member of that organization comes\n * back with `error=access_denied`, which {@link authenticate} throws as an\n * `AuthenticationError` with `error === 'access_denied'`.\n */\n switchOrganization(\n organizationId: string,\n options: Omit<AuthorizationRequestOptions, 'organization' | 'organizationHint'> = {},\n ): Promise<AuthorizationRequest> {\n return this.createAuthorizationRequest({ ...options, organization: organizationId });\n }\n\n /**\n * Complete login on your callback route: verify state, exchange the code with the\n * PKCE verifier, verify the id_token, and return the authenticated user.\n *\n * @throws InvalidStateError when state does not match (forged/stale request)\n * @throws AuthenticationError on any other failure\n */\n async authenticate(input: {\n params: CallbackParams;\n stored: StoredAuthState;\n redirectUri?: string;\n }): Promise<CboxUser> {\n const { params, stored } = input;\n\n if (!params.state || !stored.state || !timingSafeEqualString(params.state, stored.state)) {\n throw new InvalidStateError('The login state did not match — the request may be forged or stale.');\n }\n\n if (params.error) {\n // The code travels as `error`, not only in the message: `access_denied` after a\n // switchOrganization() means \"not a member of that organization\", which an app\n // answers by switching back — not by signing the person out.\n throw new AuthenticationError(\n `Cbox ID returned an error: ${params.error}${params.error_description ? ` (${params.error_description})` : ''}`,\n params.error,\n params.error_description ?? undefined,\n );\n }\n\n if (!params.code) {\n throw new AuthenticationError('The callback was missing an authorization code.');\n }\n\n const tokens = await this.exchange(params.code, stored.codeVerifier, input.redirectUri);\n\n if (!tokens.access_token) {\n throw new AuthenticationError('No access token was returned.');\n }\n\n let verified: Record<string, unknown> = {};\n\n if (tokens.id_token) {\n verified = await this.verifyIdToken(tokens.id_token, stored.nonce, stored.maxAge);\n } else if ((stored.scopes ?? this.scopes()).includes('openid')) {\n // AN `openid` REQUEST WITHOUT AN ID_TOKEN IS A PROTOCOL VIOLATION, and refusing it\n // is the difference between an authenticated login and a bearer token. Without this\n // the identity below came from UserInfo alone — a bearer-authenticated endpoint\n // whose response nothing signed — and the `nonce` pulled from storage was never used.\n //\n // Asked of the SCOPES REQUESTED, not of the response: a caller who never asked for\n // `openid` is running an OAuth flow and is not held to an OIDC rule.\n throw new AuthenticationError(\n 'An openid login returned no id_token, so the identity could not be verified.',\n );\n } else if (typeof stored.maxAge === 'number') {\n // No id_token means no auth_time, and therefore no evidence the demanded\n // re-authentication happened. Accepting that silently is the whole defect.\n throw new AuthenticationError(\n 'A max_age was requested but no id_token was returned, so the authentication age could not be verified.',\n );\n }\n\n const user = await this.identityFrom(tokens, verified);\n\n if (stored.organization !== undefined && user.organizationId !== stored.organization) {\n throw new AuthenticationError(\n `The sign-in was bound to organization ${stored.organization}, but the tokens are for ${user.organizationId ?? 'no organization'}. The instance may not support organization selection.`,\n );\n }\n\n return user;\n }\n\n /**\n * Turn a token response into the verified {@link CboxUser} every flow returns.\n *\n * Shared by the browser flow and the device flow rather than written twice: the checks\n * in here — the UserInfo subject matching the id_token's, the merge that lets UserInfo\n * enrich but never overwrite signed claims — are the ones that decide whether an\n * identity is trustworthy. A second copy is a second place for one of them to be\n * quietly missing, and the flow it was missing from would look exactly as correct.\n */\n private async identityFrom(\n tokens: TokenResponse,\n verified: Record<string, unknown>,\n ): Promise<CboxUser> {\n const profile = await this.userinfo(tokens.access_token);\n\n // OIDC Core §5.3.2: the UserInfo `sub` MUST match the id_token's, and when it does\n // not the response MUST NOT be used. UserInfo is fetched with a bearer token and its\n // body carries no signature, so without this an IdP — or anything able to answer as\n // one — hands back `{\"sub\":\"somebody-else\"}` and the SDK returns it as the identity.\n const verifiedSub = verified['sub'];\n const profileSub = profile['sub'];\n\n if (typeof verifiedSub === 'string' && typeof profileSub === 'string' && !timingSafeEqualString(verifiedSub, profileSub)) {\n throw new AuthenticationError('The UserInfo subject does not match the verified id_token.');\n }\n\n // ENRICHES, NEVER REPLACES. UserInfo fills in what a minimal id_token omits (email,\n // name, org) and the verified claims go back on top, so the merge cannot move `sub`,\n // `iss`, `aud`, `nonce` or anything else the signature covered. The spread used to run\n // the other way round.\n const claims: Record<string, unknown> = { ...profile, ...verified };\n\n const sub = claims['sub'];\n if (typeof sub !== 'string' || sub === '') {\n throw new AuthenticationError('The verified token carried no subject.');\n }\n\n const organizations = parseOrganizations(claims['organizations']);\n\n return {\n id: sub,\n email: typeof claims['email'] === 'string' ? claims['email'] : null,\n name: typeof claims['name'] === 'string' ? claims['name'] : null,\n organizationId: typeof claims['org'] === 'string' ? claims['org'] : null,\n organization: organization(claims),\n roles: roles(claims),\n permissions: permissions(claims),\n featureFlags: featureFlags(claims),\n actor: actor(claims),\n sessionId: sessionId(claims),\n // Only present when the instance emitted the claim (exactOptionalPropertyTypes).\n ...(organizations ? { organizations } : {}),\n claims,\n accessToken: tokens.access_token,\n refreshToken: tokens.refresh_token ?? null,\n idToken: tokens.id_token ?? null,\n expiresIn: typeof tokens.expires_in === 'number' ? tokens.expires_in : 0,\n };\n }\n\n /**\n * Start the device authorization grant (RFC 8628) — the flow for a program with no\n * browser of its own: a CLI, a CI job, a container, a TV.\n *\n * Print `userCode` and `verificationUri`, then call\n * {@link CboxIdClient.pollDeviceToken}. If the machine has a desktop you may also open\n * `verificationUriComplete`, which fills the code in — but print the code anyway: the\n * machine running your program is often not the one the person is looking at.\n *\n * The scopes are bounded by what the app is REGISTERED for. A device request naming one\n * outside that ceiling is refused with `invalid_scope` rather than quietly reduced,\n * because no browser is in front of it to notice a smaller grant.\n *\n * @throws ConfigurationError when the instance advertises no device endpoint.\n */\n async requestDeviceAuthorization(scopes?: string[]): Promise<DeviceAuthorization> {\n const endpoint = await this.discovery.optionalEndpoint('device_authorization_endpoint');\n\n if (endpoint === null) {\n throw new ConfigurationError(\n 'This instance does not advertise a device_authorization_endpoint, so it does not support CLI sign-in.',\n );\n }\n\n const body = new URLSearchParams({\n client_id: this.config.clientId,\n scope: (scopes ?? this.scopes()).join(' '),\n });\n if (this.config.clientSecret) {\n body.set('client_secret', this.config.clientSecret);\n }\n\n const response = await this.post(endpoint, body);\n if (!response.ok) {\n throw await oauthError(response, 'Device authorization request failed');\n }\n\n const payload = (await response.json()) as Record<string, unknown>;\n\n const deviceCode = payload['device_code'];\n const userCode = payload['user_code'];\n const verificationUri = payload['verification_uri'];\n\n if (typeof deviceCode !== 'string' || typeof userCode !== 'string' || typeof verificationUri !== 'string') {\n throw new AuthenticationError('The device authorization response was incomplete.');\n }\n\n return {\n deviceCode,\n userCode,\n verificationUri,\n verificationUriComplete:\n typeof payload['verification_uri_complete'] === 'string'\n ? payload['verification_uri_complete']\n : null,\n expiresIn: typeof payload['expires_in'] === 'number' ? payload['expires_in'] : 600,\n // RFC 8628 §3.2: absent means 5 seconds. Polling faster than the server allows is\n // answered with `slow_down`, so the default is the one the server assumes too.\n interval: typeof payload['interval'] === 'number' ? payload['interval'] : 5,\n };\n }\n\n /**\n * Poll until the person approves, and return them.\n *\n * Blocks. It honours the server's `interval`, backs off permanently by five seconds on\n * `slow_down` (RFC 8628 §3.5), and stops on the three answers that are final: they\n * declined, the code expired, or tokens arrived. Pass an `AbortSignal` to give up\n * early — a CLI should let Ctrl-C work.\n *\n * @throws AuthenticationError when the person declines or the code expires.\n */\n async pollDeviceToken(\n authorization: DeviceAuthorization,\n options: { signal?: AbortSignal } = {},\n ): Promise<CboxUser> {\n const endpoint = await this.discovery.endpoint('token_endpoint');\n const deadline = Date.now() + authorization.expiresIn * 1000;\n let intervalMs = authorization.interval * 1000;\n\n for (;;) {\n if (options.signal?.aborted === true) {\n throw new AuthenticationError('Device sign-in was cancelled.');\n }\n if (Date.now() > deadline) {\n throw new AuthenticationError(\n 'The device code expired before it was approved. Start the sign-in again.',\n );\n }\n\n await sleep(intervalMs, options.signal);\n\n const body = new URLSearchParams({\n grant_type: 'urn:ietf:params:oauth:grant-type:device_code',\n device_code: authorization.deviceCode,\n client_id: this.config.clientId,\n });\n if (this.config.clientSecret) {\n body.set('client_secret', this.config.clientSecret);\n }\n\n const response = await this.post(endpoint, body);\n\n if (response.ok) {\n const tokens = (await response.json()) as TokenResponse;\n\n if (!tokens.access_token) {\n throw new AuthenticationError('The device token response carried no access token.');\n }\n\n // No nonce: RFC 8628 has no browser leg to carry one, so there is nothing to\n // bind. Everything else about the id_token — signature, issuer, audience,\n // expiry — is verified exactly as it is on the browser flow.\n const verified = tokens.id_token ? await this.verifyIdToken(tokens.id_token, '') : {};\n\n return await this.identityFrom(tokens, verified);\n }\n\n const payload = (await response.json().catch(() => ({}))) as Record<string, unknown>;\n const error = typeof payload['error'] === 'string' ? payload['error'] : 'invalid_request';\n\n if (error === 'authorization_pending') {\n continue;\n }\n\n if (error === 'slow_down') {\n // Permanently, not for one round: the server is telling us our rate is wrong,\n // and returning to it next tick earns the same answer forever.\n intervalMs += 5000;\n continue;\n }\n\n if (error === 'access_denied') {\n throw new AuthenticationError('Sign-in was declined.');\n }\n\n if (error === 'expired_token') {\n throw new AuthenticationError(\n 'The device code expired before it was approved. Start the sign-in again.',\n );\n }\n\n throw await oauthError(response, 'Device sign-in failed');\n }\n }\n\n /**\n * Exchange a refresh token for a fresh access token (OAuth 2.0 `refresh_token`\n * grant). Cbox ID rotates refresh tokens and detects reuse, so ALWAYS persist the\n * returned `refreshToken` and discard the one you passed — presenting a rotated\n * token again revokes the entire token family.\n *\n * @throws AuthenticationError when the refresh token is invalid, expired, or already rotated.\n */\n async refresh(refreshToken: string): Promise<RefreshedTokens> {\n const body = new URLSearchParams({\n grant_type: 'refresh_token',\n client_id: this.config.clientId,\n refresh_token: refreshToken,\n });\n if (this.config.clientSecret) {\n body.set('client_secret', this.config.clientSecret);\n }\n\n const response = await this.post(await this.discovery.endpoint('token_endpoint'), body);\n if (!response.ok) {\n // The most consequential of these: `invalid_grant` means the refresh token is\n // spent, revoked or replayed and the person must sign in again, while a 5xx or\n // `temporarily_unavailable` means the same token is still good in a moment. One\n // message string for both is what makes callers guess.\n throw await oauthError(response, 'Token refresh failed');\n }\n\n const tokens = (await response.json()) as TokenResponse;\n if (!tokens.access_token) {\n throw new AuthenticationError('The refresh response carried no access token.');\n }\n\n // VERIFIED BEFORE IT IS HANDED BACK. A refresh response carries a fresh id_token, and\n // this returned it unchecked — so an application that refreshes its session claims\n // from `refresh().idToken` accepted a forged, expired, wrong-audience or wrong-issuer\n // token, having verified only the one it got at login. The nonce is not re-checked:\n // RFC 6749 has no nonce on this leg, and OIDC Core §12.2 says an id_token from a\n // refresh need not carry one.\n if (tokens.id_token) {\n await this.verifyIdToken(tokens.id_token, '');\n }\n\n return {\n accessToken: tokens.access_token,\n // Keep the presented token when the server does not rotate (OAuth 2.0 §6);\n // callers persist this value, so it must never come back null.\n refreshToken: tokens.refresh_token ?? refreshToken,\n idToken: tokens.id_token ?? null,\n expiresIn: typeof tokens.expires_in === 'number' ? tokens.expires_in : 0,\n scope: typeof tokens.scope === 'string' ? tokens.scope : null,\n };\n }\n\n /**\n * The URL of the instance's hosted account/profile page (self-service password,\n * MFA, passkeys, sessions). A signed-in user is authenticated there by their Cbox\n * ID session; `returnTo` is passed so the page can link back to your app.\n */\n profileUrl(returnTo?: string): string {\n const base = `${this.config.issuer.replace(/\\/$/, '')}${this.accountPath()}`;\n return returnTo ? `${base}?${new URLSearchParams({ return_to: returnTo }).toString()}` : base;\n }\n\n /**\n * The hosted page where a person creates and revokes API keys for your API — Cbox ID's\n * `/account/api-keys`, preselected to this app (or `clientId`). Keys made there are\n * checked with `ApiKeyVerifier` from `@cboxdk/id-js/server`.\n *\n * `returnTo` becomes a link back to your app, honoured only for an origin the app\n * registered. `organization` picks which of the person's organizations the keys act in;\n * omitted, the page uses the one they are in.\n */\n /**\n * The hosted page where the signed-in person connects their account at `provider`\n * (Pipes) — `/account/connected-services/{provider}/connect`, preselected to this app.\n * They come back to `returnTo` with `?provider=…&status=connected|cancelled|failed`,\n * honoured only on an origin the app registered.\n */\n pipeConnectUrl(provider: PipeProvider | string, returnTo?: string): string {\n return pipeConnectUrl(this.config.issuer, provider, {\n clientId: this.config.clientId,\n ...(returnTo !== undefined ? { returnTo } : {}),\n });\n }\n\n apiKeysUrl(options: { clientId?: string; returnTo?: string; organization?: string } = {}): string {\n const params = new URLSearchParams({ client_id: options.clientId ?? this.config.clientId });\n if (options.returnTo) {\n params.set('return_to', options.returnTo);\n }\n if (options.organization) {\n params.set('organization', options.organization);\n }\n\n return `${this.config.issuer.replace(/\\/$/, '')}/account/api-keys?${params.toString()}`;\n }\n\n /**\n * The RP-initiated logout URL, or null when the instance advertises none.\n *\n * `client_id` is always sent, even without a `returnTo`: the OP validates\n * `post_logout_redirect_uri` against the registered allow-list of THAT client\n * (OIDC RP-Initiated Logout 1.0 §2). With no way to name the RP the OP cannot\n * check the list, so it silently drops the return URL and strands the user on a\n * bare \"you are signed out\" page. `idTokenHint` — the user's `id_token`, if you\n * still hold it — is the spec's other way to identify the RP, and additionally\n * tells the OP which subject is logging out.\n *\n * PASS THE HINT IF YOU WANT \"SIGN OUT EVERYWHERE\". Cbox ID revokes every session\n * the person holds only when a hint it can VERIFY names the subject holding the\n * browser; with no hint it signs this browser out and leaves their other devices\n * alone. That is deliberate: the endpoint is unauthenticated and reached by a\n * redirect, so a request carrying no proof of who it concerns could otherwise be\n * forged into ending anyone's sessions everywhere. See laravel-id UPGRADING.md\n * for 1.8.0.\n */\n async logoutUrl(returnTo?: string, idTokenHint?: string): Promise<string | null> {\n const endpoint = await this.discovery.optionalEndpoint('end_session_endpoint');\n if (!endpoint) {\n return null;\n }\n const params = new URLSearchParams({ client_id: this.config.clientId });\n if (returnTo) {\n params.set('post_logout_redirect_uri', returnTo);\n }\n if (idTokenHint) {\n params.set('id_token_hint', idTokenHint);\n }\n return `${endpoint}?${params.toString()}`;\n }\n\n /**\n * A machine (client-credentials) access token for calling Cbox ID APIs as your\n * app, not on a user's behalf. Requires a client secret.\n */\n async machineToken(options: { scopes?: string[]; resource?: string } = {}): Promise<string> {\n const body = new URLSearchParams({\n grant_type: 'client_credentials',\n client_id: this.config.clientId,\n client_secret: this.requireSecret(),\n });\n if (options.scopes && options.scopes.length > 0) {\n body.set('scope', options.scopes.join(' '));\n }\n if (options.resource) {\n body.set('resource', options.resource);\n }\n\n const response = await this.post(await this.discovery.endpoint('token_endpoint'), body);\n if (!response.ok) {\n throw await oauthError(response, 'Machine token request failed');\n }\n const json = (await response.json()) as { access_token?: unknown };\n if (typeof json.access_token !== 'string') {\n throw new AuthenticationError('The token response had no access_token.');\n }\n return json.access_token;\n }\n\n /** The OIDC userinfo claims for an access token. */\n async userinfo(accessToken: string): Promise<Record<string, unknown>> {\n const endpoint = await this.discovery.optionalEndpoint('userinfo_endpoint');\n if (!endpoint) {\n return {};\n }\n const response = await this.fetchWithTimeout(endpoint, {\n headers: { authorization: `Bearer ${accessToken}` },\n });\n if (!response.ok) {\n throw await oauthError(response, 'Userinfo request failed');\n }\n return (await response.json()) as Record<string, unknown>;\n }\n\n /**\n * RFC 7662 token introspection (confidential-client auth). Returns the raw\n * response; `active` tells you if the token is currently valid. Requires a secret.\n */\n async introspect(token: string): Promise<Record<string, unknown>> {\n const endpoint = await this.discovery.endpoint('introspection_endpoint');\n const basic = btoa(`${this.config.clientId}:${this.requireSecret()}`);\n const response = await this.post(\n endpoint,\n new URLSearchParams({ token }),\n { authorization: `Basic ${basic}` },\n );\n if (!response.ok) {\n throw await oauthError(response, 'Introspection request failed');\n }\n return (await response.json()) as Record<string, unknown>;\n }\n\n /**\n * RFC 7009 token revocation. Revokes an access or refresh token; revoking a refresh\n * token drops the whole token family, so this is what a real \"sign out everywhere\" does.\n *\n * **PUBLIC CLIENTS TOO.** This demanded a secret and threw `ConfigurationError` without\n * one — so the clients that most need it were the ones that could not call it. A PKCE\n * browser or native app authenticates with `none`, holds no secret, and is exactly the\n * case where a refresh token sits in storage on a device somebody has just signed out\n * of. Cbox ID's revocation endpoint accepts a public client, and its discovery document\n * advertises `none` among the revocation auth methods; RFC 7009 §2.1 scopes every\n * revocation to the calling client, so the only capability here is \"destroy a token you\n * are already holding\". The SDK was the half saying no.\n *\n * A confidential client still authenticates with Basic; a public one names itself in the\n * body, the same shape {@link exchange} already uses for the token endpoint.\n *\n * Per RFC 7009 the server answers 200 for an unknown or already-revoked token, so\n * success means \"this token is not valid any more\", not \"it existed\".\n *\n * @param tokenTypeHint which store to search first — only a hint, never required.\n */\n async revoke(token: string, tokenTypeHint?: TokenTypeHint): Promise<void> {\n const endpoint = await this.discovery.endpoint('revocation_endpoint');\n const body = new URLSearchParams({ token, client_id: this.config.clientId });\n if (tokenTypeHint) {\n body.set('token_type_hint', tokenTypeHint);\n }\n\n const headers: Record<string, string> = {};\n if (this.config.clientSecret) {\n headers.authorization = `Basic ${btoa(`${this.config.clientId}:${this.config.clientSecret}`)}`;\n }\n\n const response = await this.post(endpoint, body, headers);\n if (!response.ok) {\n throw await oauthError(response, 'Revocation request failed');\n }\n }\n\n /** Verify a Cbox ID webhook / inline-action signature. See {@link verifyWebhook}. */\n verifyWebhook(options: VerifyWebhookOptions): Promise<boolean> {\n return verifyWebhook(options);\n }\n\n /**\n * A Token Vault client bound to an access token. Obtain the token with\n * {@link machineToken} (scope `vault.manage` to provision/grant, `vault.lease` to\n * redeem), then call `store` / `grant` / `lease` etc.\n */\n vault(accessToken: string): VaultClient {\n return new VaultClient(this.config.issuer, accessToken, this.config.timeoutMs ?? 10_000);\n }\n\n private async exchange(code: string, verifier: string, redirectUri?: string): Promise<TokenResponse> {\n const callback = redirectUri ?? this.config.redirectUri;\n\n if (callback === undefined || callback === '') {\n throw new ConfigurationError(\n 'A `redirectUri` is required to exchange an authorization code. It must be the same one the authorization request used.',\n );\n }\n\n const body = new URLSearchParams({\n grant_type: 'authorization_code',\n code,\n redirect_uri: callback,\n client_id: this.config.clientId,\n code_verifier: verifier,\n });\n if (this.config.clientSecret) {\n body.set('client_secret', this.config.clientSecret);\n }\n\n const response = await this.post(await this.discovery.endpoint('token_endpoint'), body);\n if (!response.ok) {\n throw await oauthError(response, 'Token exchange failed');\n }\n return (await response.json()) as TokenResponse;\n }\n\n private async verifyIdToken(\n idToken: string,\n // Empty skips the nonce comparison below, which is what a refresh leg needs: RFC 6749\n // has no nonce there and OIDC Core §12.2 says the id_token from a refresh need not\n // carry one. Signature, issuer, audience and expiry are checked either way.\n nonce: string,\n maxAge?: number,\n ): Promise<Record<string, unknown>> {\n const jwksUri = await this.discovery.endpoint('jwks_uri');\n let resolver = this.jwksByUri.get(jwksUri);\n if (!resolver) {\n resolver = createRemoteJWKSet(new URL(jwksUri));\n this.jwksByUri.set(jwksUri, resolver);\n }\n\n let payload: JWTPayload;\n try {\n ({ payload } = await jwtVerify(idToken, resolver, {\n issuer: this.config.issuer,\n audience: this.config.clientId,\n // Pin the accepted signature algorithms explicitly. `jose` already refuses\n // `alg: none` and key-type confusion, so this is belt-and-braces — but it\n // states the contract in code rather than relying on a library default.\n algorithms: ['RS256', 'ES256'],\n }));\n } catch (error) {\n throw new AuthenticationError(`The id_token could not be verified: ${String(error)}`);\n }\n\n if (nonce && payload['nonce'] !== nonce) {\n throw new AuthenticationError('The id_token nonce did not match — possible replay.');\n }\n\n // OIDC Core §3.1.3.7 step 12: when max_age was requested, `auth_time` is REQUIRED\n // and the relying party MUST check it. `max_age` is the control you reach for\n // before a payment or an admin grant, and the whole point is that the person\n // authenticated JUST NOW — so a login({maxAge}) whose result is never checked is a\n // step-up in name only: a day-old session comes back carrying its original\n // auth_time and nothing anywhere says so.\n if (typeof maxAge === 'number') {\n const authTime = payload['auth_time'];\n\n if (typeof authTime !== 'number') {\n throw new AuthenticationError(\n 'A max_age was requested but the id_token carried no auth_time, so the authentication age could not be verified.',\n );\n }\n\n const tolerance = this.config.authTimeToleranceSeconds ?? 60;\n const age = Math.floor(Date.now() / 1000) - authTime;\n\n if (age > maxAge + tolerance) {\n throw new AuthenticationError(\n `The authentication is ${age}s old but max_age required ${maxAge}s — the user did not re-authenticate.`,\n );\n }\n }\n\n return payload as Record<string, unknown>;\n }\n\n private scopes(): string[] {\n const scopes = this.config.scopes;\n return scopes && scopes.length > 0 ? scopes : ['openid', 'profile', 'email'];\n }\n\n private accountPath(): string {\n const path = this.config.accountPath;\n // `/account`, not `/settings`. The latter is the organization-admin page: it\n // redirects a non-admin to `/account` and drops `return_to` on the way, so a member\n // following this link arrives at the right screen having lost where they came from.\n return path && path !== '' ? `/${path.replace(/^\\//, '')}` : '/account';\n }\n\n private requireSecret(): string {\n if (!this.config.clientSecret) {\n throw new ConfigurationError('This call requires a `clientSecret`, but none is configured.');\n }\n return this.config.clientSecret;\n }\n\n private post(url: string, body: URLSearchParams, headers: Record<string, string> = {}): Promise<Response> {\n return this.fetchWithTimeout(url, {\n method: 'POST',\n headers: { 'content-type': 'application/x-www-form-urlencoded', ...headers },\n body,\n });\n }\n\n private async fetchWithTimeout(url: string, init: RequestInit): Promise<Response> {\n const controller = new AbortController();\n const timer = setTimeout(() => controller.abort(), this.config.timeoutMs ?? 10_000);\n try {\n return await fetch(url, { ...init, signal: controller.signal });\n } finally {\n clearTimeout(timer);\n }\n }\n}\n\n/** Normalise `prompt` to a de-duplicated list, refusing what the server would refuse. */\nfunction promptValue(prompt: AuthorizationRequestOptions['prompt']): AuthorizationPrompt[] {\n if (prompt === undefined) {\n return [];\n }\n\n const values = [...new Set(typeof prompt === 'string' ? [prompt] : prompt)];\n\n // OIDC Core §3.1.2.1: `none` with any other value is an error. Failing here names the\n // call that built it; failing at the server names nothing the caller can find.\n if (values.includes('none') && values.length > 1) {\n throw new ConfigurationError(\"`prompt: 'none'` cannot be combined with another prompt value.\");\n }\n\n return values;\n}\n\n/**\n * Refuse organization options that contradict each other. Each of these would reach the\n * server as a request with two incompatible meanings and come back as a generic error\n * after a full redirect — far from the line that built it.\n */\nfunction assertOrganizationOptions(options: AuthorizationRequestOptions, prompt: AuthorizationPrompt[]): void {\n // An empty id is not \"no organization\" at the server — it is a parameter that is\n // present and names nothing. Omit the option instead.\n if (options.organization === '') {\n throw new ConfigurationError('`organization` is empty. Omit it to sign in without binding to an organization.');\n }\n if (options.organizationHint === '') {\n throw new ConfigurationError('`organizationHint` is empty. Omit it when you have no organization to suggest.');\n }\n\n if (options.organization === undefined) {\n return;\n }\n\n // `organization` binds to an existing organization; both prompts below ask the person\n // to choose or create one. Sending both leaves the server to guess which you meant.\n if (prompt.includes('select_organization')) {\n throw new ConfigurationError(\n \"`organization` binds the sign-in to one organization, so `prompt: 'select_organization'` has nothing to choose. Use `organizationHint` to preselect an organization in the picker instead.\",\n );\n }\n if (prompt.includes('create_organization')) {\n throw new ConfigurationError(\n \"`organization` binds the sign-in to an existing organization and `prompt: 'create_organization'` creates a new one. Send one or the other.\",\n );\n }\n}\n\n/** Constant-time string compare, so state validation doesn't leak via timing. */\nfunction timingSafeEqualString(a: string, b: string): boolean {\n if (a.length !== b.length) {\n return false;\n }\n let mismatch = 0;\n for (let i = 0; i < a.length; i++) {\n mismatch |= a.charCodeAt(i) ^ b.charCodeAt(i);\n }\n return mismatch === 0;\n}\n\n/**\n * Parse an `organizations` claim into typed orgs, ignoring anything malformed. The\n * claim is optional and instance-specific; absent or non-array → undefined, so\n * callers can tell \"no claim\" from \"empty\".\n */\nfunction parseOrganizations(claim: unknown): CboxOrganization[] | undefined {\n if (!Array.isArray(claim)) {\n return undefined;\n }\n const orgs: CboxOrganization[] = [];\n for (const entry of claim) {\n if (typeof entry !== 'object' || entry === null) {\n continue;\n }\n const record = entry as Record<string, unknown>;\n const id = record['id'];\n const name = record['name'];\n if (typeof id === 'string' && id !== '' && typeof name === 'string' && name !== '') {\n orgs.push({ id, name, role: typeof record['role'] === 'string' ? record['role'] : null });\n }\n }\n return orgs;\n}\n\n/**\n * Wait, but stay interruptible.\n *\n * A CLI that ignores Ctrl-C for five seconds at a time feels broken, and a bare\n * `setTimeout` promise cannot be cancelled — so the abort is wired to the same timer\n * rather than checked after it.\n */\nfunction sleep(ms: number, signal?: AbortSignal): Promise<void> {\n return new Promise((resolve, reject) => {\n if (signal?.aborted === true) {\n reject(new AuthenticationError('Device sign-in was cancelled.'));\n return;\n }\n\n const timer = setTimeout(() => {\n signal?.removeEventListener('abort', onAbort);\n resolve();\n }, ms);\n\n const onAbort = (): void => {\n clearTimeout(timer);\n reject(new AuthenticationError('Device sign-in was cancelled.'));\n };\n\n signal?.addEventListener('abort', onAbort, { once: true });\n });\n}\n","import { Discovery } from './discovery.js';\nimport { AuthenticationError, ConfigurationError } from './errors.js';\n\n/**\n * A permission your app declares. `key` is a `feature:action` slug (e.g.\n * `invoices:create`); `description` is human-facing copy for the Cbox ID console.\n */\nexport interface PermissionDefinition {\n key: string;\n description?: string;\n /**\n * Whether an organization's own administrators may hand this permission out in a custom\n * role they build themselves (self-serve). Defaults to `false`: a permission is internal\n * unless you opt it in, so a key added in a hurry never becomes something every customer\n * can grant. Sent as `tenant_assignable: true`.\n */\n tenantAssignable?: boolean;\n}\n\n/**\n * A role your app declares. `permissions` lists the permission keys the role\n * grants — each must reference a declared {@link PermissionDefinition}.\n */\nexport interface RoleDefinition {\n key: string;\n name: string;\n description?: string;\n permissions: string[];\n /**\n * Whether an organization's administrators may assign this role to their members.\n * Defaults to `true`.\n *\n * Set `false` for a STAFF role — your own support or operations people, held\n * environment-wide across every customer (typically the role that grants\n * `support:impersonate`). Cbox ID never lists or accepts a staff role on the\n * organization plane; only an environment administrator can grant it. Sent as\n * `tenant_assignable: false`.\n */\n tenantAssignable?: boolean;\n}\n\n/** A permission as it is sent to Cbox ID (snake_case, the manifest's wire format). */\nexport interface ManifestPermission {\n key: string;\n description?: string;\n /** Present only for a self-serve permission. See {@link PermissionDefinition.tenantAssignable}. */\n tenant_assignable?: true;\n}\n\n/** A role as it is sent to Cbox ID (snake_case, the manifest's wire format). */\nexport interface ManifestRole {\n key: string;\n name: string;\n description?: string;\n permissions: string[];\n /** Present only for a staff role. See {@link RoleDefinition.tenantAssignable}. */\n tenant_assignable?: false;\n}\n\n/**\n * The roles + permissions an app declares in code. Either list may be omitted.\n * Pass this to {@link defineAuthz} (to validate up front) or straight to\n * {@link buildManifest} / {@link publishManifest}.\n */\nexport interface AuthzDeclaration {\n permissions?: PermissionDefinition[];\n roles?: RoleDefinition[];\n /**\n * Where this app's OLD login lives, while you are migrating off it.\n *\n * Declared here for the same reason roles are: it is a fact about the app, it belongs\n * with the deploy, and the alternative is a URL pasted into a console and a secret\n * pasted into an env file that quietly disagree six weeks later.\n *\n * IT DOES NOT TAKE EFFECT ON ITS OWN. Unlike a role — which affects only the app that\n * declared it — this names a URL that every unknown email and the password typed with\n * it will be offered to, on the environment's whole sign-in path. So it arrives as a\n * proposal and an operator has to approve it in the console. Changing the url later\n * drops that approval, on purpose.\n */\n legacyLogin?: LegacyLoginDeclaration;\n}\n\n/** Where an app's old login lives. See {@link AuthzDeclaration.legacyLogin}. */\nexport interface LegacyLoginDeclaration {\n /** Must be https — a password in the clear is readable by everything on the path. */\n url: string;\n /** At least 32 characters. It is the only thing proving a request came from Cbox ID. */\n secret: string;\n}\n\n/**\n * The manifest as it is sent to Cbox ID: the declared permissions + roles plus a\n * content-derived `version`, so republishing an unchanged catalog is a no-op.\n */\nexport interface AuthzManifest {\n version: string;\n permissions: ManifestPermission[];\n roles: ManifestRole[];\n legacy_login?: LegacyLoginDeclaration;\n}\n\n/** What {@link publishManifest} needs to authenticate the push. */\nexport interface ManifestPublisherConfig {\n /** Base URL (issuer) of the Cbox ID instance — the `token_endpoint` is discovered from it. */\n issuer: string;\n /** Your OAuth client id. The client must hold the `apps.manifest` scope. */\n clientId: string;\n /** Your OAuth client secret. The push uses the client-credentials grant. */\n clientSecret: string;\n /** Timeout (ms) for back-channel HTTP calls. Defaults to `10000`. */\n timeoutMs?: number;\n}\n\n/**\n * The server's sync summary. The named fields are the ones the SDK/CLI reads;\n * the index signature keeps any extra fields the server returns.\n */\nexport interface ManifestSyncSummary {\n unchanged?: boolean;\n roles_declared?: number;\n permissions_declared?: number;\n version?: string;\n [key: string]: unknown;\n}\n\n/**\n * Validate a roles/permissions declaration and return it normalized (both lists\n * always present). Call this where you declare your catalog so mistakes — a role\n * that grants an undeclared permission, a duplicate key — surface immediately\n * rather than on deploy.\n *\n * @throws ConfigurationError on a missing key/name, a duplicate, or a role that\n * references a permission that was never declared.\n */\nexport function defineAuthz(\n declaration: AuthzDeclaration,\n): AuthzDeclaration & { permissions: PermissionDefinition[]; roles: RoleDefinition[] } {\n const permissions = declaration.permissions ?? [];\n const roles = declaration.roles ?? [];\n assertDeclaration(permissions, roles);\n\n // The legacy login is validated here too, so a bad one fails in the deploy that\n // introduced it rather than as a 4xx from a manifest push somebody has to go and read.\n if (declaration.legacyLogin) {\n assertLegacyLogin(declaration.legacyLogin);\n }\n\n // `Required<>` no longer fits: the catalog is always present after this, and the legacy\n // login legitimately is not. Returning the declaration's own optionality keeps a caller\n // from having to invent an empty one.\n return { ...declaration, permissions, roles };\n}\n\n/**\n * Build the manifest — the declared catalog plus a stable content hash `version`\n * (first 16 hex chars of the sha256 of the canonicalized catalog). The catalog is\n * sorted by key first, so declaration order never changes the version.\n */\nexport async function buildManifest(declaration: AuthzDeclaration): Promise<AuthzManifest> {\n const permissions = declaration.permissions ?? [];\n const roles = declaration.roles ?? [];\n assertDeclaration(permissions, roles);\n\n // The version hashes the CATALOG only, and the legacy login is deliberately outside it:\n // this canonicalization is a cross-SDK contract — id-js, id-python, id-go and the PHP\n // reference all produce the same bytes, and a shared fixture exists to keep them from\n // drifting. The server compares a declared url separately for the same reason.\n const version = (await sha256Hex(canonicalManifestJson(permissions, roles))).slice(0, 16);\n\n const manifest: AuthzManifest = {\n version,\n permissions: [...permissions].sort((a, b) => byteCompare(a.key, b.key)).map(wirePermission),\n roles: [...roles].sort((a, b) => byteCompare(a.key, b.key)).map(wireRole),\n };\n\n if (declaration.legacyLogin) {\n assertLegacyLogin(declaration.legacyLogin);\n manifest.legacy_login = declaration.legacyLogin;\n }\n\n return manifest;\n}\n\n/**\n * Publish this app's authorization manifest (its declared roles + permissions) to\n * Cbox ID. The app owns what a role means; Cbox ID owns identity and who holds it.\n *\n * It mints a client-credentials token with the `apps.manifest` scope (token\n * endpoint discovered from the issuer's OIDC configuration), then POSTs the\n * manifest to `{issuer}/api/v1/apps/manifest`. Run it on deploy or from a script;\n * an unchanged catalog is a server-side no-op.\n *\n * @returns the server's sync summary (`unchanged`, `roles_declared`, …).\n * @throws ConfigurationError when config or the declaration is invalid.\n * @throws AuthenticationError when the token cannot be minted or the push fails.\n */\nexport async function publishManifest(\n config: ManifestPublisherConfig,\n declaration: AuthzDeclaration,\n): Promise<ManifestSyncSummary> {\n if (!config.issuer || !config.clientId || !config.clientSecret) {\n throw new ConfigurationError('Publishing a manifest needs issuer, clientId and clientSecret.');\n }\n\n const timeoutMs = config.timeoutMs ?? 10_000;\n const manifest = await buildManifest(declaration);\n const discovery = new Discovery(config.issuer, timeoutMs, 3_600_000);\n\n const token = await mintToken(config, discovery, timeoutMs);\n\n const response = await fetchWithTimeout(\n `${config.issuer.replace(/\\/$/, '')}/api/v1/apps/manifest`,\n {\n method: 'POST',\n headers: {\n authorization: `Bearer ${token}`,\n accept: 'application/json',\n 'content-type': 'application/json',\n },\n body: JSON.stringify(manifest),\n },\n timeoutMs,\n );\n\n if (!response.ok) {\n throw new AuthenticationError(`Manifest push failed: HTTP ${response.status} ${await response.text()}`);\n }\n\n const json = (await response.json()) as unknown;\n return json !== null && typeof json === 'object' ? (json as ManifestSyncSummary) : {};\n}\n\nasync function mintToken(\n config: ManifestPublisherConfig,\n discovery: Discovery,\n timeoutMs: number,\n): Promise<string> {\n const response = await fetchWithTimeout(\n await discovery.endpoint('token_endpoint'),\n {\n method: 'POST',\n headers: { 'content-type': 'application/x-www-form-urlencoded' },\n body: new URLSearchParams({\n grant_type: 'client_credentials',\n client_id: config.clientId,\n client_secret: config.clientSecret,\n scope: 'apps.manifest',\n }),\n },\n timeoutMs,\n );\n\n const json = (await response.json().catch(() => ({}))) as { access_token?: unknown };\n if (typeof json.access_token !== 'string' || json.access_token === '') {\n throw new AuthenticationError(\n 'Could not obtain an apps.manifest access token — check the client credentials and that the client holds the apps.manifest scope.',\n );\n }\n return json.access_token;\n}\n\n/**\n * A `feature:action` (or bare `feature`) key: lowercase, with dot/colon-separated segments.\n * The server's own pattern, restated so a bad key fails where it was written rather than\n * as a 4xx from a manifest push on deploy.\n */\nconst KEY_PATTERN = /^[a-z][a-z0-9_-]*(?:[.:][a-z0-9_-]+)*$/;\n\nfunction assertDeclaration(permissions: PermissionDefinition[], roles: RoleDefinition[]): void {\n const permissionKeys = new Set<string>();\n for (const permission of permissions) {\n if (!permission.key) {\n throw new ConfigurationError('Every permission needs a non-empty `key`.');\n }\n assertKey(permission.key, 'Permission');\n if (permissionKeys.has(permission.key)) {\n throw new ConfigurationError(`Permission \"${permission.key}\" is declared more than once.`);\n }\n assertFlag(permission.tenantAssignable, `Permission \"${permission.key}\"`);\n permissionKeys.add(permission.key);\n }\n\n const roleKeys = new Set<string>();\n for (const role of roles) {\n if (!role.key) {\n throw new ConfigurationError('Every role needs a non-empty `key`.');\n }\n assertKey(role.key, 'Role');\n if (!role.name) {\n throw new ConfigurationError(`Role \"${role.key}\" needs a non-empty \\`name\\`.`);\n }\n if (roleKeys.has(role.key)) {\n throw new ConfigurationError(`Role \"${role.key}\" is declared more than once.`);\n }\n assertFlag(role.tenantAssignable, `Role \"${role.key}\"`);\n roleKeys.add(role.key);\n for (const reference of role.permissions) {\n if (!permissionKeys.has(reference)) {\n throw new ConfigurationError(\n `Role \"${role.key}\" references permission \"${reference}\", which is not declared.`,\n );\n }\n }\n }\n}\n\nfunction assertKey(key: string, what: 'Permission' | 'Role'): void {\n if (!KEY_PATTERN.test(key)) {\n throw new ConfigurationError(\n `${what} key \"${key}\" is not a lowercase \\`feature:action\\` slug (e.g. \\`invoices:create\\`).`,\n );\n }\n}\n\n/**\n * `tenantAssignable`, when given, must be a real boolean.\n *\n * The type says so, but a catalog loaded from YAML or JSON arrives untyped, and the\n * string `\"false\"` is truthy: the one value that has to mean \"staff only\" would read as\n * \"every customer may grant this\". The server refuses a non-boolean role flag for the\n * same reason; refusing it here puts the failure in the deploy that introduced it.\n */\nfunction assertFlag(value: unknown, owner: string): void {\n if (value !== undefined && typeof value !== 'boolean') {\n throw new ConfigurationError(`${owner} \\`tenantAssignable\\` must be true or false.`);\n }\n}\n\n/**\n * A permission in the manifest's wire format: fixed key order, no `undefined` fields.\n *\n * `tenant_assignable` is written only when it is `true`, the non-default. The server reads\n * the snake_case key and nothing else, so this mapping is the whole difference between a\n * self-serve permission and an internal one — `tenantAssignable` sent as-is would be\n * ignored.\n */\nfunction wirePermission(permission: PermissionDefinition): ManifestPermission {\n return {\n key: permission.key,\n ...(permission.description === undefined ? {} : { description: permission.description }),\n ...(permission.tenantAssignable === true ? { tenant_assignable: true as const } : {}),\n };\n}\n\n/**\n * A role in the manifest's wire format: fixed key order, de-duplicated and sorted\n * permission refs, no `undefined` fields.\n *\n * `tenant_assignable: false` is written only for a staff role. THIS IS THE LINE THAT\n * KEEPS A STAFF ROLE STAFF-ONLY: the server defaults an absent key to assignable, so a\n * camelCase `tenantAssignable: false` passed straight through would publish your support\n * role as one every customer's administrator can hand out.\n */\nfunction wireRole(role: RoleDefinition): ManifestRole {\n return {\n key: role.key,\n name: role.name,\n ...(role.description === undefined ? {} : { description: role.description }),\n permissions: uniqueSorted(role.permissions),\n ...(role.tenantAssignable === false ? { tenant_assignable: false as const } : {}),\n };\n}\n\n/**\n * Serialize {permissions, roles} to the exact canonical JSON the PHP reference hashes,\n * so the `version` is byte-for-byte identical across every Cbox ID SDK. Matches PHP\n * `json_encode` defaults: object keys in insertion order, permissions and roles sorted\n * by key, each role's permission refs de-duplicated and sorted, an absent-or-empty\n * description emitted as `null`, forward slashes escaped as `\\/`, and every non-ASCII\n * code unit as `\\uXXXX`.\n *\n * Each `tenant_assignable` flag appears ONLY in its non-default state — `true` on a\n * permission, `false` on a role — exactly as the reference writes it. That keeps every\n * catalog that never mentions the flag hashing to the bytes it always has, while a\n * change to it still changes the version (an unchanged version is a skipped sync).\n */\nexport function canonicalManifestJson(\n permissions: PermissionDefinition[],\n roles: RoleDefinition[],\n): string {\n const canonical = {\n permissions: [...permissions]\n .sort((a, b) => byteCompare(a.key, b.key))\n .map((p) => ({\n key: p.key,\n description: emptyToNull(p.description),\n ...(p.tenantAssignable === true ? { tenant_assignable: true } : {}),\n })),\n roles: [...roles]\n .sort((a, b) => byteCompare(a.key, b.key))\n .map((r) => ({\n key: r.key,\n name: r.name,\n description: emptyToNull(r.description),\n permissions: uniqueSorted(r.permissions),\n ...(r.tenantAssignable === false ? { tenant_assignable: false } : {}),\n })),\n };\n return escapeLikePhp(JSON.stringify(canonical));\n}\n\n/**\n * Permission refs as the server stores them: each once, sorted. The server drops a\n * repeated ref before it hashes, so hashing the repeat here would give a `version` that\n * no server ever computes.\n */\nfunction uniqueSorted(values: readonly string[]): string[] {\n return [...new Set(values)].sort(byteCompare);\n}\n\n/** PHP treats an absent or empty description as `null` in the hashed catalog. */\nfunction emptyToNull(value: string | undefined): string | null {\n return value === undefined || value === '' ? null : value;\n}\n\n/** Byte-wise (code-unit) comparison — matches PHP `strcmp` on the ASCII-only keys. */\nfunction byteCompare(a: string, b: string): number {\n return a < b ? -1 : a > b ? 1 : 0;\n}\n\n/** Apply PHP `json_encode`'s default `\\/` slash and `\\uXXXX` non-ASCII escaping. */\nfunction escapeLikePhp(json: string): string {\n let out = '';\n for (let i = 0; i < json.length; i++) {\n const char = json.charAt(i);\n const code = json.charCodeAt(i);\n if (char === '/') {\n out += '\\\\/';\n } else if (code > 0x7f) {\n out += '\\\\u' + code.toString(16).padStart(4, '0');\n } else {\n out += char;\n }\n }\n return out;\n}\n\nasync function sha256Hex(input: string): Promise<string> {\n const digest = await crypto.subtle.digest('SHA-256', new TextEncoder().encode(input));\n return Array.from(new Uint8Array(digest))\n .map((byte) => byte.toString(16).padStart(2, '0'))\n .join('');\n}\n\nasync function fetchWithTimeout(url: string, init: RequestInit, timeoutMs: number): Promise<Response> {\n const controller = new AbortController();\n const timer = setTimeout(() => controller.abort(), timeoutMs);\n try {\n return await fetch(url, { ...init, signal: controller.signal });\n } finally {\n clearTimeout(timer);\n }\n}\n\n/**\n * Refuse a legacy login declaration the server would refuse anyway.\n *\n * Checked in the SDK so it fails at build time, in the deploy that introduced it, rather\n * than as a 4xx from a manifest push somebody has to go and read. Both rules are the\n * server's and are restated here rather than inferred: https because a password in the\n * clear is readable by everything on the path, and a real secret because it is the only\n * thing proving a request came from Cbox ID.\n */\nfunction assertLegacyLogin(legacy: LegacyLoginDeclaration): void {\n if (!legacy.url.startsWith('https://')) {\n throw new ConfigurationError('legacyLogin.url must be https — a password must never cross the network in the clear.');\n }\n\n if (!legacy.secret || legacy.secret.length < 32) {\n throw new ConfigurationError('legacyLogin.secret must be at least 32 characters; it is what proves a request came from Cbox ID.');\n }\n}\n"]}
1
+ {"version":3,"sources":["../src/errors.ts","../src/legacy.ts","../src/issuer.ts","../src/frontend.ts","../src/discovery.ts","../src/pkce.ts","../src/claims.ts","../src/vault.ts","../src/webhook.ts","../src/client.ts","../src/authz.ts","../src/decisions.ts"],"names":["header","key","organization","record","timingSafeEqual","json","createRemoteJWKSet","jwtVerify","permissions","roles"],"mappings":"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","file":"index.cjs","sourcesContent":["/**\n * Base class for every error this SDK throws, so callers can `catch (e) { if (e\n * instanceof CboxIdError) ... }` in one branch.\n */\nexport class CboxIdError extends Error {\n constructor(message: string) {\n super(message);\n this.name = new.target.name;\n }\n}\n\n/** The client is misconfigured (a required option is missing or empty). */\nexport class ConfigurationError extends CboxIdError {}\n\n/**\n * The login `state` did not match what was stored — the callback is forged or\n * stale. Treat as a fresh start, not an error to surface to the user.\n */\nexport class InvalidStateError extends CboxIdError {}\n\n/**\n * Login could not be completed: the provider returned an error, the callback was\n * missing a code, or a token / id_token failed verification.\n *\n * `error` carries the RFC 6749 §5.2 code the authorization server sent, when it sent one.\n * It used to be discarded at every back-channel boundary, leaving a single message string\n * for outcomes that need opposite responses: `invalid_grant` on a refresh means the\n * session is over and the person has to sign in again, while `temporarily_unavailable`\n * means try the same token in a moment. A caller reduced to matching on prose either\n * retries what can never succeed, or signs out somebody who did not need to be.\n */\nexport class AuthenticationError extends CboxIdError {\n constructor(\n message: string,\n /** RFC 6749 §5.2 error code, when the server sent a parseable one. */\n readonly error?: string,\n /** The server's `error_description`, verbatim. Not end-user copy. */\n readonly errorDescription?: string,\n /** HTTP status, for the cases where the body says nothing useful. */\n readonly status?: number,\n /**\n * Seconds to wait, off the `Retry-After` header — set only on a 429.\n *\n * The distinction it carries is the one a caller most needs and could least infer:\n * a 429 is the ONLY back-channel failure where the same request will succeed\n * unchanged if you simply wait. Every other one needs a different request, or a new\n * sign-in. Without this the SDK reported \"token refresh failed\" and a caller with a\n * retry loop hammered a limiter that was already telling it exactly how long to stop.\n */\n readonly retryAfter?: number,\n ) {\n super(message);\n }\n\n /** Whether waiting `retryAfter` seconds and repeating the same request is worth it. */\n get isRateLimited(): boolean {\n return this.status === 429;\n }\n}\n\n/**\n * Read an OAuth error out of a failed token-endpoint response.\n *\n * Best-effort by design: a 502 from a proxy is HTML, a captive portal is worse, and the\n * caller still needs an error rather than a parse exception. What it must never do is\n * invent a code — an absent or unparseable `error` stays undefined, so\n * `e.error === 'invalid_grant'` is true only because the server said so.\n */\nexport async function oauthError(response: Response, fallback: string): Promise<AuthenticationError> {\n const body = await response.text().catch(() => '');\n\n let code: string | undefined;\n let description: string | undefined;\n\n try {\n const parsed: unknown = JSON.parse(body);\n\n if (typeof parsed === 'object' && parsed !== null) {\n const { error, error_description: errorDescription } = parsed as Record<string, unknown>;\n code = typeof error === 'string' ? error : undefined;\n description = typeof errorDescription === 'string' ? errorDescription : undefined;\n }\n } catch {\n // Not JSON. The status and the truncated body below are all there is to report.\n }\n\n // THE BODY IS NEVER ECHOED. These calls carry `client_secret`, `code_verifier` and\n // refresh tokens in their REQUEST, and a debug proxy, a captive portal or an upstream\n // error page that reflects what it received puts those straight into a thrown message\n // — which production apps log. Only the server's own OAuth error code travels, and\n // failing that, the status alone.\n const detail = code ?? `HTTP ${response.status}`;\n\n // `Retry-After` is seconds here — Laravel's throttler writes the integer form. The\n // HTTP-date form is legal too and is deliberately NOT parsed: guessing at a clock\n // skew is worse than saying nothing, and `status === 429` still tells the caller to\n // back off.\n const retryAfterHeader = response.headers.get('retry-after');\n const retryAfter = retryAfterHeader !== null && /^\\d+$/.test(retryAfterHeader.trim())\n ? Number(retryAfterHeader.trim())\n : undefined;\n\n return new AuthenticationError(`${fallback}: ${detail}`, code, description, response.status, retryAfter);\n}\n\n/**\n * The Frontend API refused, or could not be reached.\n *\n * Carries a `code` because the four ways this goes wrong need four different responses\n * from the caller, and telling them apart from a message string is the kind of thing\n * that works until somebody rewords the message:\n *\n * - `origin_not_allowed` — the overwhelmingly likely cause of a refusal, and a\n * configuration problem the developer fixes once in the console.\n * - `rate_limited` — back off; `retryAfter` says for how long, when the server said.\n * - `unavailable` — the network, or a 5xx. Transient by assumption; already retried.\n * - `malformed` — a 200 whose body is not the document we expect, which means something\n * between the page and us is rewriting responses (a proxy, an extension, a captive\n * portal). Worth distinguishing, because retrying it never helps.\n */\nexport class FrontendApiError extends CboxIdError {\n constructor(\n message: string,\n readonly code: 'origin_not_allowed' | 'rate_limited' | 'unavailable' | 'malformed',\n readonly status?: number,\n readonly retryAfter?: number,\n ) {\n super(message);\n }\n}\n","import { ConfigurationError } from './errors.js';\n\n/**\n * The handler on YOUR side of a legacy migration.\n *\n * Cbox ID offers it an email and a password it has never seen, and your code answers with\n * the person or with nothing. On a yes they are created in Cbox ID as a result of the\n * login that just succeeded, and from their next sign-in the old system is never asked\n * again.\n *\n * WHY THIS IS A FACTORY AND NOT A DOCUMENT. The wire format is simple enough to describe\n * in a paragraph — a signed POST, JSON in, JSON out — and describing it would mean every\n * customer writes the signature check themselves. That check is exactly the part people\n * get wrong: `===` instead of a constant-time compare, no freshness window, no thought\n * about replay. So the factory owns all of it and you write the one function that knows\n * your own database.\n *\n * It is deliberately framework-agnostic: it takes a `Request` and returns a `Response`,\n * which is what Next.js route handlers, Remix, Hono, Bun and Deno all speak natively.\n */\n\n/** What your handler answers with. Returning `null` means \"no\", and is not an error. */\nexport interface LegacyUser {\n email: string;\n name?: string | null;\n emailVerified?: boolean;\n /**\n * Your stored hash, when you can expose it.\n *\n * Passing it lets the person keep their password in Cbox ID verbatim — it is stored as\n * is and upgraded to the platform hasher on their next login, exactly like a\n * bulk-imported user. Omit it and Cbox ID hashes the password they just proved they\n * know, which is the honest option when your store cannot hand a hash over.\n */\n passwordHash?: string;\n}\n\nexport interface LegacyVerifierOptions {\n /** The same secret you declared in your manifest, or configured in the console. */\n secret: string;\n /**\n * Decide whether these credentials are good, and say who they belong to.\n *\n * Return `null` for no. THROWING IS NOT THE SAME as returning null: a throw means your\n * store could not decide, and is answered with a 503 so Cbox ID refuses the sign-in\n * rather than treating an outage as a wrong password.\n */\n verify: (email: string, password: string) => Promise<LegacyUser | null>;\n /**\n * How far out of date a request may be, in seconds. Defaults to 300.\n *\n * A window is what makes a captured request stop working. Too wide and a recording is\n * useful for hours; too narrow and ordinary clock skew starts refusing real traffic.\n */\n toleranceSeconds?: number;\n}\n\n/**\n * Build the request handler.\n *\n * ```ts\n * // app/api/cbox-legacy/route.ts\n * export const POST = createLegacyVerifier({\n * secret: process.env.CBOX_LEGACY_SECRET!,\n * async verify(email, password) {\n * const row = await db.users.findByEmail(email)\n * if (!row || !(await argon2.verify(row.password, password))) return null\n * return { email: row.email, name: row.name, emailVerified: !!row.confirmedAt }\n * },\n * })\n * ```\n */\nexport function createLegacyVerifier(options: LegacyVerifierOptions): (request: Request) => Promise<Response> {\n if (!options.secret || options.secret.length < 32) {\n throw new ConfigurationError(\n 'A legacy verifier secret must be at least 32 characters; it is the only thing proving a request came from Cbox ID.',\n );\n }\n\n const tolerance = options.toleranceSeconds ?? 300;\n\n return async function handle(request: Request): Promise<Response> {\n // Read once. The signature covers the RAW body, so re-serializing parsed JSON would\n // produce different bytes and every valid request would be refused.\n const raw = await request.text();\n\n if (!(await isSignedByCboxId(raw, request.headers.get('X-Cbox-Signature'), options.secret, tolerance))) {\n // No detail. A caller who cannot sign is not owed help distinguishing \"bad\n // signature\" from \"stale timestamp\" — both mean the same thing to anyone\n // legitimate, and the difference is a hint to anyone else.\n return json({ error: 'unauthorized' }, 401);\n }\n\n let payload: { email?: unknown; password?: unknown };\n\n try {\n payload = JSON.parse(raw) as typeof payload;\n } catch {\n return json({ error: 'invalid_request' }, 400);\n }\n\n const { email, password } = payload;\n\n if (typeof email !== 'string' || email === '') {\n return json({ error: 'invalid_request' }, 400);\n }\n\n // No password means Cbox ID is asking \"do you know this address\" — the tooling path,\n // used for a dry run before cutover. It never reaches here from a sign-in.\n if (typeof password !== 'string') {\n return json({ user: null }, 200);\n }\n\n let user: LegacyUser | null;\n\n try {\n user = await options.verify(email, password);\n } catch {\n // 503, not 401. Your store could not decide, and Cbox ID must refuse the sign-in\n // rather than read an outage as a wrong password — but it should also be able to\n // tell the two apart in its own logs, which a 401 would hide.\n return json({ error: 'unavailable' }, 503);\n }\n\n if (!user) {\n return json({ user: null }, 200);\n }\n\n return json(\n {\n email: user.email,\n name: user.name ?? null,\n email_verified: user.emailVerified === true,\n ...(user.passwordHash ? { password_hash: user.passwordHash } : {}),\n },\n 200,\n );\n };\n}\n\n/**\n * Whether this body was signed by Cbox ID, recently.\n *\n * Both halves matter. The HMAC proves it came from something holding the secret; the\n * freshness window is what stops a captured request working forever. Compared in constant\n * time, because a comparison that returns early leaks how much of a guess was right.\n */\nasync function isSignedByCboxId(\n body: string,\n header: string | null,\n secret: string,\n toleranceSeconds: number,\n): Promise<boolean> {\n if (!header) {\n return false;\n }\n\n const parts: Record<string, string> = {};\n\n for (const piece of header.split(',')) {\n const [key, value] = piece.split('=', 2);\n if (key && value) {\n parts[key.trim()] = value.trim();\n }\n }\n\n const timestamp = parts['t'] ?? '';\n const signature = parts['v1'] ?? '';\n\n if (!/^\\d+$/.test(timestamp) || signature === '') {\n return false;\n }\n\n if (Math.abs(Math.floor(Date.now() / 1000) - Number(timestamp)) > toleranceSeconds) {\n return false;\n }\n\n const key = await crypto.subtle.importKey(\n 'raw',\n new TextEncoder().encode(secret),\n { name: 'HMAC', hash: 'SHA-256' },\n false,\n ['sign'],\n );\n\n const mac = await crypto.subtle.sign('HMAC', key, new TextEncoder().encode(`${timestamp}.${body}`));\n const expected = [...new Uint8Array(mac)].map((b) => b.toString(16).padStart(2, '0')).join('');\n\n return timingSafeEqual(expected, signature);\n}\n\n/** Constant-time string compare. Length is not secret; content is. */\nfunction timingSafeEqual(a: string, b: string): boolean {\n if (a.length !== b.length) {\n return false;\n }\n\n let diff = 0;\n\n for (let i = 0; i < a.length; i++) {\n diff |= a.charCodeAt(i) ^ b.charCodeAt(i);\n }\n\n return diff === 0;\n}\n\nfunction json(body: unknown, status: number): Response {\n return new Response(JSON.stringify(body), {\n status,\n headers: { 'Content-Type': 'application/json' },\n });\n}\n","import { ConfigurationError } from './errors.js';\n\n/**\n * An issuer must be HTTPS.\n *\n * Everything this SDK does with it carries a credential: the authorization code, the PKCE\n * verifier, the client secret, the refresh token. Over `http://` a network attacker reads\n * all of them — and, worse, replaces the discovery document and JWKS, at which point a\n * forged id_token verifies cleanly and the whole verification chain proves nothing.\n *\n * Loopback is allowed because a native app's own callback listener is loopback by\n * definition (RFC 8252) and a dev instance runs there.\n */\nexport function assertSecureIssuer(issuer: string): void {\n let url: URL;\n\n try {\n url = new URL(issuer);\n } catch {\n throw new ConfigurationError('Cbox ID config `issuer` is not a valid URL.');\n }\n\n if (url.protocol === 'https:') {\n return;\n }\n\n const loopback = url.hostname === 'localhost' || url.hostname === '127.0.0.1' || url.hostname === '[::1]' || url.hostname === '::1';\n\n if (url.protocol === 'http:' && loopback) {\n return;\n }\n\n throw new ConfigurationError(\n `Cbox ID config \\`issuer\\` must be https (got ${url.protocol}//${url.hostname}).`,\n );\n}\n","import { assertSecureIssuer } from './issuer.js';\nimport { ConfigurationError, FrontendApiError } from './errors.js';\n\n/**\n * The browser-safe half of the SDK.\n *\n * Everything else in this package assumes a server: it holds a client secret, it exchanges\n * codes, it verifies webhooks. None of that may run in a page, which is why the UI\n * components have always been redirect shells — a page that cannot authenticate itself to\n * the identity provider cannot ask it anything, so it sends the person away and waits.\n *\n * A publishable key changes that. It is public on purpose: it ships in your bundle, it is\n * visible in devtools, and it is safe there because it only works from the origins you\n * registered. What it buys is that a page can read its OWN sign-in configuration — the\n * endpoints, the social buttons, your theme — and render a form itself.\n *\n * This client deliberately has no secret, no token storage and no crypto. It reads two\n * documents. Anything that mints or holds a credential still belongs on your server.\n */\n\n/** How a page identifies itself. Public — put it in your bundle. */\nexport interface FrontendClientOptions {\n /** Your identity provider's origin, e.g. `https://id.acme.com`. */\n issuer: string;\n /** `pk_live_…` or `pk_test_…`. Safe to publish. */\n publishableKey: string;\n /** Abort after this long. Defaults to 10s. */\n timeoutMs?: number;\n /**\n * How many times to retry a transient failure. Defaults to 2 (so three attempts).\n *\n * Only the network and 5xx are retried. A refusal is a configuration problem and\n * retrying it just delays the developer finding out; a 429 is honoured rather than\n * hammered.\n */\n retries?: number;\n /** Injectable for tests and for runtimes with a non-global fetch. */\n fetch?: typeof globalThis.fetch;\n}\n\n/** A social button to draw. Name and provider only — never an internal id. */\nexport interface SocialProvider {\n provider: string;\n name: string;\n}\n\n/** The customer's theme, when they have set one. Absent means \"use your own defaults\". */\nexport interface Appearance {\n preset: string;\n radius: string;\n font: string;\n light: Record<string, string>;\n dark: Record<string, string>;\n}\n\n/** Everything needed to draw a sign-in box, and nothing that identifies anybody. */\nexport interface FrontendConfig {\n mode: 'test' | 'live' | null;\n issuer: string;\n endpoints: {\n authorization: string;\n token: string;\n userinfo: string;\n end_session: string;\n jwks: string;\n };\n /**\n * The social buttons to draw, exactly as the hosted sign-in page would: the environment's\n * own providers, or — with `config({ organization })` — that organization's.\n */\n social: SocialProvider[];\n appearance?: Appearance;\n /**\n * Which other sign-in methods are switched on, so a box does not draw a button whose\n * endpoint answers 403. Absent from instances that predate it.\n */\n methods?: { passkeys: boolean; magic_link: boolean };\n}\n\n/** Options for {@link CboxIdFrontend.config}. */\nexport interface FrontendConfigOptions {\n /**\n * The organization the box is for, by id or slug — the way a hosted page is addressed.\n * `social` is then exactly what that organization's sign-in page offers. An organization\n * the environment does not have is answered as no hint at all.\n */\n organization?: string;\n}\n\n/**\n * A second factor the person can answer an `mfa_required` with. Kinds only — the server\n * never says which number a text would go to before one is sent.\n */\nexport type SecondFactorKind = 'totp' | 'sms' | 'recovery_code';\n\n/** What a sign-in attempt produced. */\nexport type SignInResult =\n | { status: 'ok'; loginTicket: string; expiresIn: number }\n | {\n status: 'mfa_required';\n mfaToken: string;\n /**\n * The factors this person can answer with (laravel-id 1.24+). Absent when the\n * instance predates the list — then only an authenticator or a recovery code works.\n */\n factors?: SecondFactorKind[];\n }\n | { status: 'otp_required'; mfaToken: string }\n | { status: 'sso_required' }\n | { status: 'invalid' }\n | { status: 'rate_limited'; retryAfter: number | undefined };\n\n/** What asking for a texted sign-in code produced. */\nexport type SmsCodeResult =\n /** Sent. `to` is the number masked (`+45 ******78`); the code lasts `expiresIn` seconds. */\n | { status: 'sent'; to: string; expiresIn: number }\n /** Too soon, or a sending limit was hit. Waiting `retryAfter` seconds may help. */\n | { status: 'rate_limited'; retryAfter: number | undefined }\n /** The text provider failed. Try again shortly, or offer another factor. */\n | { status: 'unavailable' }\n /**\n * Refused: an unknown or spent token, no number on file, a country texts are not sent\n * to, or no attempts left. One answer for every reason, like a wrong password.\n */\n | { status: 'invalid' };\n\nconst SECOND_FACTOR_KINDS: ReadonlySet<string> = new Set<SecondFactorKind>(['totp', 'sms', 'recovery_code']);\n\n/** What a browser needs to ask an authenticator for a passkey assertion. */\nexport interface PasskeyOptions {\n challenge: string;\n /** Carries the challenge to the second request, in place of a session cookie. */\n challenge_token: string;\n rpId: string;\n userVerification: string;\n allowCredentials: unknown[];\n timeout: number;\n}\n\n/** Who the browser is signed in as, or nobody. */\nexport interface FrontendSession {\n user: { id: string; email: string; name: string | null } | null;\n}\n\n/**\n * Reads the public configuration and the current session from a browser.\n *\n * ```ts\n * const frontend = new CboxIdFrontend({\n * issuer: 'https://id.acme.com',\n * publishableKey: 'pk_live_…',\n * })\n *\n * const config = await frontend.config() // cached for you; safe to call per component\n * const { user } = await frontend.session(accessToken)\n * ```\n */\nexport class CboxIdFrontend {\n private readonly issuer: string;\n private readonly publishableKey: string;\n private readonly timeoutMs: number;\n private readonly retries: number;\n private readonly fetchImpl: typeof globalThis.fetch;\n\n /**\n * The config document, and the in-flight promise for it.\n *\n * Deduplicated rather than merely cached: a page with a sign-in form, a user button and\n * an organization switcher mounts three components in the same tick, and three parallel\n * fetches of the same immutable document is a waste the SDK should absorb rather than\n * ask every consumer to.\n */\n private readonly configPromises = new Map<string, Promise<FrontendConfig>>();\n\n constructor(options: FrontendClientOptions) {\n if (!options.issuer) {\n throw new ConfigurationError('issuer is required.');\n }\n\n // The browser channel carries login tickets, one-time codes and the session the user\n // is in the middle of establishing. Over `http` a network attacker on the same café\n // Wi-Fi reads the ticket and redeems it — and the sign-in box the user is looking at\n // is served by the attacker, so nothing about the page tells them.\n assertSecureIssuer(options.issuer);\n\n // Caught here rather than at the first request, because the failure otherwise arrives\n // as an opaque 401 from the network tab and the cause — a secret key pasted into a\n // browser bundle — is exactly the mistake worth naming out loud.\n if (!options.publishableKey?.startsWith('pk_')) {\n throw new ConfigurationError(\n 'publishableKey must be a pk_test_… or pk_live_… key. Client secrets and API keys must never be put in a browser.',\n );\n }\n\n this.issuer = options.issuer.replace(/\\/$/, '');\n this.publishableKey = options.publishableKey;\n this.timeoutMs = options.timeoutMs ?? 10_000;\n this.retries = Math.max(0, options.retries ?? 2);\n this.fetchImpl = options.fetch ?? globalThis.fetch.bind(globalThis);\n }\n\n /** Whether this key drives real sign-ins. Handy for a \"test mode\" badge in your own UI. */\n get isLive(): boolean {\n return this.publishableKey.startsWith('pk_live_');\n }\n\n /**\n * The public sign-in configuration.\n *\n * Fetched once per client instance. The document is small and changes when somebody\n * edits it in the console, so a long-lived page picks changes up on its next full load\n * rather than mid-session — which is the right trade for something that decides layout.\n * Each `organization` is fetched and cached on its own.\n */\n async config(options: FrontendConfigOptions = {}): Promise<FrontendConfig> {\n const organization = options.organization ?? '';\n let pending = this.configPromises.get(organization);\n\n if (pending === undefined) {\n const path = organization === ''\n ? '/frontend/v1/config'\n : `/frontend/v1/config?${new URLSearchParams({ organization }).toString()}`;\n\n pending = this.get<FrontendConfig>(path, {}, isFrontendConfig).catch((error: unknown) => {\n // Cleared so a transient network failure does not poison the instance for the\n // lifetime of the page.\n this.configPromises.delete(organization);\n throw error;\n });\n this.configPromises.set(organization, pending);\n }\n\n return pending;\n }\n\n /**\n * Who is signed in, given an access token your app already holds.\n *\n * Returns `{ user: null }` rather than throwing when nobody is signed in. That is a\n * state, not an error: a user button renders on pages nobody has signed in on, and\n * making callers treat a rejection as a state is how flash-of-signed-out bugs happen.\n *\n * The publishable key grants nothing here — the token is the entire authority.\n */\n async session(accessToken?: string): Promise<FrontendSession> {\n if (!accessToken) {\n return { user: null };\n }\n\n return this.get<FrontendSession>(\n '/frontend/v1/session',\n { Authorization: `Bearer ${accessToken}` },\n isFrontendSession,\n );\n }\n\n /**\n * Sign in with a password, from a form your page drew.\n *\n * WHAT COMES BACK IS A TICKET, NEVER A TOKEN. Handing tokens to a page that proved a\n * password is the implicit grant, which OAuth 2.1 removes: tokens in a URL, in history,\n * in `Referer`, with no client authentication and no PKCE binding. Spend the ticket by\n * sending the browser to `/oauth/authorize` with your own PKCE challenge and\n * `login_ticket` in the query — the ordinary flow, which then issues an ordinary code.\n *\n * It expires in sixty seconds. It is for one redirect, not for storing.\n *\n * ```ts\n * const result = await frontend.signIn(email, password)\n *\n * if (result.status === 'ok') {\n * window.location.href = `${config.endpoints.authorization}?${new URLSearchParams({\n * client_id, redirect_uri, response_type: 'code', code_challenge, code_challenge_method: 'S256',\n * login_ticket: result.loginTicket,\n * })}`\n * }\n * ```\n *\n * EVERY REFUSAL IS THE SAME REFUSAL. `invalid` covers a wrong password, an unknown\n * address and a locked account, because distinguishing them is the enumeration oracle\n * the server refuses to build — do not present them differently in your UI either.\n */\n async signIn(email: string, password: string): Promise<SignInResult> {\n const response = await this.post('/frontend/v1/sign-in', { email, password });\n\n if (response.status === 429) {\n const retryAfter = Number(response.headers.get('Retry-After') ?? '');\n\n return { status: 'rate_limited', retryAfter: Number.isFinite(retryAfter) ? retryAfter : undefined };\n }\n\n let body: { status?: string; login_ticket?: string; mfa_token?: string; expires_in?: number; factors?: unknown };\n\n try {\n body = (await response.json()) as typeof body;\n } catch {\n throw new FrontendApiError('Cbox ID returned a body that is not JSON.', 'malformed', response.status);\n }\n\n if (body.status === 'ok' && typeof body.login_ticket === 'string') {\n return { status: 'ok', loginTicket: body.login_ticket, expiresIn: body.expires_in ?? 60 };\n }\n\n if (body.status === 'mfa_required' && typeof body.mfa_token === 'string') {\n // Unknown kinds are dropped rather than passed on: a page that draws a button for a\n // factor this SDK cannot complete strands the person on it.\n const factors = Array.isArray(body.factors)\n ? body.factors.filter((f): f is SecondFactorKind => typeof f === 'string' && SECOND_FACTOR_KINDS.has(f))\n : undefined;\n\n return { status: 'mfa_required', mfaToken: body.mfa_token, ...(factors ? { factors } : {}) };\n }\n\n if (body.status === 'otp_required' && typeof body.mfa_token === 'string') {\n return { status: 'otp_required', mfaToken: body.mfa_token };\n }\n\n if (body.status === 'sso_required') {\n return { status: 'sso_required' };\n }\n\n return { status: 'invalid' };\n }\n\n /**\n * Finish a sign-in that owed a second factor.\n *\n * The token from `signIn()` carries the pending state, because a cross-origin page has\n * no session cookie to carry it in. A TOTP code or a recovery code both work — an\n * embedded form that could not accept a recovery code would strand exactly the people\n * that escape hatch exists for.\n *\n * A wrong code costs an attempt, not the sign-in: five are allowed before the token\n * dies and the person starts from the password again.\n *\n * `method` says which challenge the code answers: `'mfa'` for an authenticator or\n * recovery code, `'otp'` for an emailed code (`otp_required`), `'sms'` for a code sent\n * with {@link sendSmsCode}. A texted code is six digits like an authenticator's, so the\n * server cannot tell them apart by shape — answering one as the other is refused.\n */\n async submitSecondFactor(mfaToken: string, code: string, method: 'mfa' | 'otp' | 'sms' = 'mfa'): Promise<SignInResult> {\n const response = await this.post('/frontend/v1/sign-in/factor', { mfa_token: mfaToken, code, method });\n\n let body: { status?: string; login_ticket?: string; expires_in?: number };\n\n try {\n body = (await response.json()) as typeof body;\n } catch {\n throw new FrontendApiError('Cbox ID returned a body that is not JSON.', 'malformed', response.status);\n }\n\n return body.status === 'ok' && typeof body.login_ticket === 'string'\n ? { status: 'ok', loginTicket: body.login_ticket, expiresIn: body.expires_in ?? 60 }\n : { status: 'invalid' };\n }\n\n /**\n * Text the person a sign-in code, when `mfa_required` listed `'sms'` in `factors`.\n * Then finish with `submitSecondFactor(mfaToken, code, 'sms')`.\n *\n * Only call it when the person asks (\"Text me a code\"), never on page load: each send\n * spends one of the token's five attempts — that is what bounds how many texts one\n * proved password can cause — and every text costs the customer money.\n *\n * ```ts\n * if (result.status === 'mfa_required' && result.factors?.includes('sms')) {\n * const sent = await frontend.sendSmsCode(result.mfaToken)\n * if (sent.status === 'sent') showCodeField(`We texted ${sent.to}`)\n * }\n * ```\n */\n async sendSmsCode(mfaToken: string): Promise<SmsCodeResult> {\n const response = await this.post('/frontend/v1/sign-in/factor/sms', { mfa_token: mfaToken });\n\n let body: { status?: string; to?: unknown; expires_in?: unknown; retry_after?: unknown };\n\n try {\n body = (await response.json()) as typeof body;\n } catch {\n throw new FrontendApiError('Cbox ID returned a body that is not JSON.', 'malformed', response.status);\n }\n\n if (body.status === 'sent' && typeof body.to === 'string') {\n return { status: 'sent', to: body.to, expiresIn: typeof body.expires_in === 'number' ? body.expires_in : 300 };\n }\n\n if (body.status === 'rate_limited' || response.status === 429) {\n const retryAfter = typeof body.retry_after === 'number' ? body.retry_after : Number(response.headers.get('Retry-After') ?? '');\n\n return { status: 'rate_limited', retryAfter: Number.isFinite(retryAfter) && retryAfter > 0 ? retryAfter : undefined };\n }\n\n if (body.status === 'unavailable') {\n return { status: 'unavailable' };\n }\n\n return { status: 'invalid' };\n }\n\n /**\n * The WebAuthn options for a passkey sign-in, and the handle that carries the challenge.\n *\n * The handle exists because a cross-origin page has no session cookie to keep the\n * challenge in between the two requests WebAuthn needs. Pass it back to\n * {@link signInWithPasskey} with whatever `navigator.credentials.get()` returns.\n *\n * `allowCredentials` comes back empty on purpose: this is a discoverable-credential\n * flow, so the authenticator offers whichever passkey it holds and the page never has to\n * say who is signing in — asking for an email first, to look up which credentials exist,\n * would be an enumeration oracle.\n */\n async passkeyOptions(): Promise<PasskeyOptions> {\n const response = await this.post('/frontend/v1/sign-in/passkey/options', {});\n\n if (!response.ok) {\n throw new FrontendApiError(\n `Cbox ID refused the request (${response.status}). Check that this page's origin is on the key's allow-list.`,\n 'origin_not_allowed',\n response.status,\n );\n }\n\n return (await response.json()) as PasskeyOptions;\n }\n\n /**\n * Complete a passkey sign-in with the assertion the authenticator produced.\n *\n * `assertion` is the credential from `navigator.credentials.get()`, serialised — the\n * server verifies the raw body, so pass it through unchanged rather than rebuilding it.\n */\n async signInWithPasskey(challengeToken: string, assertion: Record<string, unknown>): Promise<SignInResult> {\n const response = await this.post('/frontend/v1/sign-in/passkey', { ...assertion, challenge_token: challengeToken });\n\n let body: { status?: string; login_ticket?: string; expires_in?: number };\n\n try {\n body = (await response.json()) as typeof body;\n } catch {\n throw new FrontendApiError('Cbox ID returned a body that is not JSON.', 'malformed', response.status);\n }\n\n return body.status === 'ok' && typeof body.login_ticket === 'string'\n ? { status: 'ok', loginTicket: body.login_ticket, expiresIn: body.expires_in ?? 60 }\n : { status: 'invalid' };\n }\n\n private async post(path: string, payload: Record<string, unknown>): Promise<Response> {\n const controller = new AbortController();\n const timer = setTimeout(() => controller.abort(), this.timeoutMs);\n\n try {\n return await this.fetchImpl(`${this.issuer}${path}`, {\n method: 'POST',\n headers: {\n 'X-Cbox-Publishable-Key': this.publishableKey,\n 'Content-Type': 'application/json',\n Accept: 'application/json',\n },\n body: JSON.stringify(payload),\n signal: controller.signal,\n });\n } catch {\n throw new FrontendApiError(\n `Could not reach Cbox ID at ${this.issuer}. If this is a browser, check that this page's origin is on the key's allow-list — a refused request fails as a network error by design.`,\n 'unavailable',\n );\n } finally {\n clearTimeout(timer);\n }\n }\n\n private async get<T>(\n path: string,\n extraHeaders: Record<string, string> = {},\n validate?: (body: unknown) => body is T,\n ): Promise<T> {\n let lastError: unknown;\n\n for (let attempt = 0; attempt <= this.retries; attempt++) {\n // Linear, not exponential, and only between attempts. This sits inside a page\n // render: a caller waiting on their sign-in box would rather fail in a second than\n // succeed in eight.\n if (attempt > 0) {\n await new Promise((resolve) => setTimeout(resolve, 150 * attempt));\n }\n\n try {\n return await this.attempt<T>(path, extraHeaders, validate);\n } catch (error) {\n lastError = error;\n\n // Retry only what a retry can fix. A refusal is a configuration problem and\n // retrying it delays the developer finding out; a rate limit is honoured rather\n // than hammered; a malformed body will be malformed again.\n if (!(error instanceof FrontendApiError) || error.code !== 'unavailable') {\n throw error;\n }\n }\n }\n\n throw lastError;\n }\n\n private async attempt<T>(\n path: string,\n extraHeaders: Record<string, string>,\n validate?: (body: unknown) => body is T,\n ): Promise<T> {\n const controller = new AbortController();\n const timer = setTimeout(() => controller.abort(), this.timeoutMs);\n\n let response: Response;\n\n try {\n response = await this.fetchImpl(`${this.issuer}${path}`, {\n headers: {\n // A header, never a query string: a query string puts the key in server logs,\n // in `Referer` on every outbound link, and in browser history.\n 'X-Cbox-Publishable-Key': this.publishableKey,\n Accept: 'application/json',\n ...extraHeaders,\n },\n signal: controller.signal,\n });\n } catch (cause) {\n // Includes the abort on timeout, and — in a browser — a refusal, because a refused\n // request deliberately carries no CORS headers and so never becomes a Response.\n throw new FrontendApiError(\n `Could not reach Cbox ID at ${this.issuer}. If this is a browser, check that this page's origin is on the key's allow-list — a refused request fails as a network error by design.`,\n 'unavailable',\n );\n } finally {\n clearTimeout(timer);\n }\n\n if (response.status === 429) {\n const retryAfter = Number(response.headers.get('Retry-After') ?? '');\n\n throw new FrontendApiError(\n (await described(response)) ?? 'Cbox ID is rate limiting this key.',\n 'rate_limited',\n 429,\n Number.isFinite(retryAfter) ? retryAfter : undefined,\n );\n }\n\n if (response.status === 401 || response.status === 403) {\n throw new FrontendApiError(\n // THE SERVER'S OWN REASON FIRST. It answers precisely — \"No publishable key was\n // presented\" is a different problem from \"That publishable key cannot be used\n // from this origin\" — and substituting a guess for it made this client less\n // precise than the API it wraps. The fallback still stands for the browser case,\n // where a refusal never becomes a readable Response at all.\n (await described(response)) ??\n `Cbox ID refused the request (${response.status}). Check that this page's origin is on the key's allow-list, and that the key is not revoked.`,\n 'origin_not_allowed',\n response.status,\n );\n }\n\n if (!response.ok) {\n throw new FrontendApiError(\n (await described(response)) ?? `Cbox ID returned ${response.status}.`,\n 'unavailable',\n response.status,\n );\n }\n\n let body: unknown;\n\n try {\n body = await response.json();\n } catch {\n throw new FrontendApiError('Cbox ID returned a body that is not JSON.', 'malformed', response.status);\n }\n\n // A 200 whose body is not the document we expect means something between the page and\n // us is rewriting responses — a proxy, an extension, a captive portal. Caught here so\n // it surfaces as that, rather than as `undefined` deep inside somebody's component.\n if (validate && !validate(body)) {\n throw new FrontendApiError(\n 'Cbox ID returned a body that is not the expected document.',\n 'malformed',\n response.status,\n );\n }\n\n return body as T;\n }\n}\n\n/**\n * The server's own `error_description`, when it sent one.\n *\n * Read from a CLONE: the caller may still want the body, and a Response body can only be\n * consumed once — a helper that quietly drained it would turn a precise error into a\n * different, stranger one.\n */\nasync function described(response: Response): Promise<string | undefined> {\n try {\n const body: unknown = await response.clone().json();\n\n if (typeof body === 'object' && body !== null && 'error_description' in body) {\n const description = (body as { error_description: unknown }).error_description;\n\n return typeof description === 'string' && description !== '' ? description : undefined;\n }\n } catch {\n // A refusal without a readable body is the normal case in a browser.\n }\n\n return undefined;\n}\n\n/** The shape check for the config document. Structural, not exhaustive. */\nfunction isFrontendConfig(body: unknown): body is FrontendConfig {\n if (typeof body !== 'object' || body === null) {\n return false;\n }\n\n const doc = body as Partial<FrontendConfig>;\n\n return typeof doc.issuer === 'string' && typeof doc.endpoints === 'object' && doc.endpoints !== null;\n}\n\n/** The shape check for the session document. `user: null` is valid and expected. */\nfunction isFrontendSession(body: unknown): body is FrontendSession {\n return typeof body === 'object' && body !== null && 'user' in body;\n}\n","import { AuthenticationError, ConfigurationError } from './errors.js';\nimport type { DiscoveryDocument } from './types.js';\n\n/**\n * Fetches and caches an instance's OIDC discovery document. One instance of this\n * lives per {@link CboxIdClient}; the document is refetched only after the TTL.\n */\nexport class Discovery {\n private cached: { doc: DiscoveryDocument; expiresAt: number } | null = null;\n\n constructor(\n private readonly issuer: string,\n private readonly timeoutMs: number,\n private readonly cacheTtlMs: number,\n private readonly now: () => number = Date.now,\n ) {}\n\n async document(): Promise<DiscoveryDocument> {\n if (this.cached && this.cached.expiresAt > this.now()) {\n return this.cached.doc;\n }\n\n const url = `${trimSlash(this.issuer)}/.well-known/openid-configuration`;\n const controller = new AbortController();\n const timer = setTimeout(() => controller.abort(), this.timeoutMs);\n\n let doc: DiscoveryDocument;\n try {\n const response = await fetch(url, { signal: controller.signal });\n if (!response.ok) {\n throw new AuthenticationError(`Discovery request failed with status ${response.status}.`);\n }\n doc = (await response.json()) as DiscoveryDocument;\n } catch (error) {\n if (error instanceof AuthenticationError) {\n throw error;\n }\n throw new AuthenticationError(`Discovery request failed: ${String(error)}`);\n } finally {\n clearTimeout(timer);\n }\n\n if (typeof doc.issuer !== 'string' || doc.issuer === '') {\n throw new AuthenticationError('The discovery document was missing an issuer.');\n }\n\n // RFC 8414 §3.3: the `issuer` in the document MUST match the one it was fetched for.\n // Without this the SDK sends credentials to whatever endpoints the document names and\n // verifies tokens against whatever JWKS it points at, while the caller still believes\n // it is talking to the issuer it configured — so one tenant's host answering with\n // another tenant's document silently redirects the whole flow.\n if (trimSlash(doc.issuer) !== trimSlash(this.issuer)) {\n throw new AuthenticationError(\n `The discovery document is for a different issuer (${doc.issuer}).`,\n );\n }\n\n this.cached = { doc, expiresAt: this.now() + this.cacheTtlMs };\n return doc;\n }\n\n /** A required endpoint from the discovery document. */\n async endpoint(name: keyof DiscoveryDocument): Promise<string> {\n const value = (await this.document())[name];\n if (typeof value !== 'string' || value === '') {\n throw new ConfigurationError(`The instance does not advertise a ${name}.`);\n }\n return value;\n }\n\n /** An optional endpoint, or null when the instance advertises none. */\n async optionalEndpoint(name: keyof DiscoveryDocument): Promise<string | null> {\n const value = (await this.document())[name];\n return typeof value === 'string' && value !== '' ? value : null;\n }\n}\n\n/** Compare issuers without letting a trailing slash decide identity. */\nfunction trimSlash(value: string): string {\n return value.replace(/\\/+$/, '');\n}\n","/**\n * PKCE (RFC 7636) and the random values the login flow needs, built on Web Crypto\n * (`globalThis.crypto`) so the same code runs on Node, edge runtimes and browsers.\n */\n\nfunction base64url(bytes: Uint8Array): string {\n let binary = '';\n for (const byte of bytes) {\n binary += String.fromCharCode(byte);\n }\n return btoa(binary).replace(/\\+/g, '-').replace(/\\//g, '_').replace(/=+$/, '');\n}\n\n/** A URL-safe random token of `bytes` bytes (default 32), for state and nonce. */\nexport function randomToken(bytes = 32): string {\n return base64url(crypto.getRandomValues(new Uint8Array(bytes)));\n}\n\n/** A high-entropy PKCE code verifier. */\nexport function createVerifier(): string {\n return randomToken(32);\n}\n\n/** The S256 code challenge for a verifier. */\nexport async function challenge(verifier: string): Promise<string> {\n const digest = await crypto.subtle.digest('SHA-256', new TextEncoder().encode(verifier));\n return base64url(new Uint8Array(digest));\n}\n","import type { CboxUser } from './types.js';\n\n/**\n * The membership tier a person holds in the organization a token is bound to — the\n * `org_role` claim. Coarse on purpose: it says who may administer the organization\n * itself (invite, bill, delete). What they may do inside YOUR app is `roles` /\n * `permissions`, which your app declares and Cbox ID assigns.\n */\nexport type OrganizationRole = 'owner' | 'admin' | 'developer' | 'member' | 'viewer';\n\nconst ORGANIZATION_ROLES: ReadonlySet<string> = new Set<OrganizationRole>([\n 'owner',\n 'admin',\n 'developer',\n 'member',\n 'viewer',\n]);\n\n/** The organization a token is bound to: the `org`, `org_name` and `org_role` claims. */\nexport interface CboxActiveOrganization {\n /** The stable organization id (`org`). */\n id: string;\n /** Its display name (`org_name`), when the instance sent one. */\n name: string | null;\n /**\n * The person's membership tier in it (`org_role`). Null when the claim is absent, or\n * carries a tier this SDK version does not know — an unrecognised tier is never\n * guessed upward into one that grants something.\n */\n role: OrganizationRole | null;\n}\n\n/**\n * Who is actually driving a delegated session — the RFC 8693 §4.1 `act` claim. Cbox ID\n * sets it on the tokens of a SUPPORT SESSION: a staff member acting as one of your users,\n * with a stated reason, for at most an hour, with no refresh token.\n *\n * `sub` is the actor's subject id. It is null when an `act` claim is present but not in\n * the shape RFC 8693 describes — the token is still acted, and saying so matters more\n * than knowing by whom (see {@link isSupportSession}).\n */\nexport interface CboxActor {\n sub: string | null;\n /** The prior actor, when delegation was chained (RFC 8693 §4.1 nested `act`). */\n actor: CboxActor | null;\n}\n\n/**\n * Anything the helpers below can read claims from: a {@link CboxUser} from sign-in, or a\n * claim set you verified yourself — an access token's payload on a resource server, say.\n */\nexport type ClaimSource = CboxUser | Readonly<Record<string, unknown>>;\n\n/**\n * The organization this session is bound to, or null when it is bound to none.\n *\n * ```ts\n * const org = organization(user);\n * if (org?.role === 'owner') showBilling();\n * ```\n */\nexport function organization(source: ClaimSource): CboxActiveOrganization | null {\n const claims = claimsOf(source);\n const id = claims['org'];\n\n if (typeof id !== 'string' || id === '') {\n return null;\n }\n\n const name = claims['org_name'];\n const role = claims['org_role'];\n\n return {\n id,\n name: typeof name === 'string' && name !== '' ? name : null,\n role: typeof role === 'string' && ORGANIZATION_ROLES.has(role) ? (role as OrganizationRole) : null,\n };\n}\n\n/**\n * The actor behind a support session (`act`), or null for an ordinary session in which\n * the person is acting as themselves.\n */\nexport function actor(source: ClaimSource): CboxActor | null {\n return parseActor(claimsOf(source)['act'], 0);\n}\n\n/**\n * Whether somebody other than the signed-in person is driving this session — a staff\n * member in a support session (the token carries `act`).\n *\n * FAIL-CLOSED. Any `act` claim at all counts, including one whose shape this SDK cannot\n * read: the check exists so an app can show a banner and refuse the things a helper\n * should never do on somebody's behalf (change their password, move their money), and a\n * malformed claim is not evidence that nobody else is at the keyboard.\n */\nexport function isSupportSession(source: ClaimSource): boolean {\n return actor(source) !== null;\n}\n\n/**\n * The Cbox ID sign-in session this token came from — the ID Token's `sid` claim — or null\n * when the instance sent none.\n *\n * Store it with your own session: an OIDC Back-Channel Logout token names the session it\n * ends by this value, and matching on it is how you end the right one (rather than every\n * session the person has) when they sign out of Cbox ID elsewhere.\n */\nexport function sessionId(source: ClaimSource): string | null {\n const sid = claimsOf(source)['sid'];\n\n return typeof sid === 'string' && sid !== '' ? sid : null;\n}\n\n/** The app roles this session holds — the `roles` claim; empty when there are none. */\nexport function roles(source: ClaimSource): string[] {\n return stringList(claimsOf(source)['roles']);\n}\n\n/**\n * The permissions this session holds — the `permissions` claim, already expanded from\n * `roles` by Cbox ID; empty when there are none.\n */\nexport function permissions(source: ClaimSource): string[] {\n return stringList(claimsOf(source)['permissions']);\n}\n\n/** Whether the session holds `role`. Exact match; no wildcards. */\nexport function hasRole(source: ClaimSource, role: string): boolean {\n return roles(source).includes(role);\n}\n\n/**\n * Whether the session holds `permission` (`feature:action`). Exact match; no wildcards\n * — a claim of `invoices:*` does not grant `invoices:delete`, because nothing on the\n * issuing side ever mints one.\n */\nexport function hasPermission(source: ClaimSource, permission: string): boolean {\n return permissions(source).includes(permission);\n}\n\n/**\n * The scope that puts the `feature_flags` claim on the ID token, the access token and\n * UserInfo. Request it at sign-in (`scopes: ['openid', 'profile', FEATURE_FLAGS_SCOPE]`)\n * and give the app the scope on its Scopes tab.\n */\nexport const FEATURE_FLAGS_SCOPE = 'feature_flags';\n\n/**\n * The keys of the feature flags that are on for this person, in the organization the\n * session is bound to — the `feature_flags` claim, sorted as the server sent it.\n *\n * NULL IS NOT EMPTY. `null` means the claim is absent: the `feature_flags` scope was not\n * requested, or the instance predates it. `[]` means it was asked and nothing is on. A\n * token carries the flags as they were when it was issued; the next refresh, or UserInfo,\n * picks up a change.\n */\nexport function featureFlags(source: ClaimSource): string[] | null {\n const claim = claimsOf(source)['feature_flags'];\n\n return Array.isArray(claim) ? stringList(claim) : null;\n}\n\n/**\n * Whether the feature flag `key` is on for this session. Exact match on the key.\n *\n * False when the claim is absent — an app that forgot to request the scope sees every\n * feature off, never every feature on. Use {@link featureFlags} to tell the two apart.\n */\nexport function hasFeature(source: ClaimSource, key: string): boolean {\n return featureFlags(source)?.includes(key) ?? false;\n}\n\n/**\n * Nesting is bounded: RFC 8693 chains are a handful deep in practice, and a claim nested\n * thousands deep is either a bug or an attempt to exhaust the stack. Past the bound the\n * chain is cut, not dropped — the session is still acted.\n */\nconst MAX_ACTOR_DEPTH = 8;\n\nfunction parseActor(claim: unknown, depth: number): CboxActor | null {\n if (claim === undefined || claim === null) {\n return null;\n }\n\n if (typeof claim !== 'object' || Array.isArray(claim)) {\n return { sub: null, actor: null };\n }\n\n const record = claim as Record<string, unknown>;\n const sub = record['sub'];\n\n return {\n sub: typeof sub === 'string' && sub !== '' ? sub : null,\n actor: depth + 1 < MAX_ACTOR_DEPTH ? parseActor(record['act'], depth + 1) : null,\n };\n}\n\nfunction stringList(claim: unknown): string[] {\n return Array.isArray(claim)\n ? claim.filter((value): value is string => typeof value === 'string' && value !== '')\n : [];\n}\n\nfunction claimsOf(source: ClaimSource): Readonly<Record<string, unknown>> {\n return isUser(source) ? source.claims : source;\n}\n\n/**\n * A `CboxUser` is told apart by the credential it carries alongside its claims. A raw\n * claim set never has an `accessToken` key — JWT claims are snake_case — so a verified\n * payload is never mistaken for a user and read from the wrong place.\n */\nfunction isUser(source: ClaimSource): source is CboxUser {\n return (\n typeof source['claims'] === 'object' &&\n source['claims'] !== null &&\n typeof source['accessToken'] === 'string'\n );\n}\n","import { AuthenticationError, CboxIdError } from './errors.js';\n\n/** A stored vault secret's metadata (never its plaintext). */\nexport interface VaultSecretRef {\n id: string;\n name: string;\n provider: string;\n ownerType: string | null;\n ownerId: string | null;\n expiresAt: string | null;\n revoked: boolean;\n}\n\n/** A brokered credential — the plaintext, for immediate use. */\nexport interface VaultLease {\n secretId: string;\n provider: string;\n secret: string;\n expiresAt: string;\n}\n\n/** A provider a pipe can connect to. */\nexport type PipeProvider = 'github' | 'google' | 'microsoft' | 'slack' | 'salesforce' | 'hubspot' | 'linear' | 'notion';\n\n/**\n * A fresh access token for one person's connected account at a provider — what\n * {@link VaultClient.leasePipeToken} returns. Use it, drop it, lease again next time.\n */\nexport interface PipeToken {\n /** The provider's access token. Send it as a bearer token to the provider's API. */\n accessToken: string;\n tokenType: 'Bearer';\n provider: string;\n userId: string;\n connectionId: string;\n /** What the person consented to. */\n scopes: string[];\n /** When the PROVIDER stops accepting it; null for tokens that do not expire. */\n expiresAt: string | null;\n /** When to drop it and lease again. */\n leaseExpiresAt: string;\n /** What some providers need to be called at all — Salesforce's `instance_url`, Slack's `team.id`. */\n metadata: Record<string, string>;\n}\n\n/** Where a person connects a provider, and where they come back to afterwards. */\nexport interface PipeConnectOptions {\n /** Your app's client id — the connect page shows its name and allows its origins. */\n clientId?: string;\n /**\n * Where to land afterwards, with `?provider=…&status=connected|cancelled|failed`. Must be\n * on one of the app's registered redirect origins, or it is ignored.\n */\n returnTo?: string;\n}\n\n/**\n * Add `client_id` and `return_to` to a connect URL — the one a lease error carries, or\n * one built with {@link pipeConnectUrl}.\n */\nexport function withConnectReturn(connectUrl: string, options: PipeConnectOptions = {}): string {\n const url = new URL(connectUrl);\n if (options.clientId) url.searchParams.set('client_id', options.clientId);\n if (options.returnTo) url.searchParams.set('return_to', options.returnTo);\n return url.toString();\n}\n\n/**\n * The hosted page where the signed-in person connects their account at `provider`:\n * `{issuer}/account/connected-services/{provider}/connect?client_id=…&return_to=…`.\n */\nexport function pipeConnectUrl(issuer: string, provider: PipeProvider | string, options: PipeConnectOptions = {}): string {\n return withConnectReturn(\n `${issuer.replace(/\\/$/, '')}/account/connected-services/${encodeURIComponent(provider)}/connect`,\n options,\n );\n}\n\n/**\n * A pipe token lease was refused. Catch the subclasses for the cases you can act on:\n *\n * - {@link PipeNotConnectedError} (404) and {@link PipeReauthorizationRequiredError}\n * (409) — send the person to `connectUrl`.\n * - {@link PipeTemporarilyUnavailableError} (503) — retry after `retryAfter` seconds.\n * - {@link PipeLeaseDeniedError} (403) — a configuration problem: the app is not granted\n * the pipe, it is disabled, or the person is outside the app's organization.\n *\n * Anything else (401, 422, 429) arrives as this base class with `status` and `error`.\n */\nexport class PipeLeaseError extends CboxIdError {\n constructor(\n message: string,\n /** The server's error code, e.g. `not_connected`. */\n readonly error: string | null,\n readonly status: number,\n /** Where to send the person to (re)connect — set on 404 and 409. */\n readonly connectUrl: string | null = null,\n /** Seconds to wait off `Retry-After`, when the server sent one. */\n readonly retryAfter: number | null = null,\n ) {\n super(message);\n }\n\n /** `connectUrl` with your `client_id` and `return_to` on it, or null when there is none. */\n connectUrlWith(options: PipeConnectOptions): string | null {\n return this.connectUrl === null ? null : withConnectReturn(this.connectUrl, options);\n }\n}\n\n/** The person has not connected this provider (404 `not_connected`). Send them to `connectUrl`. */\nexport class PipeNotConnectedError extends PipeLeaseError {\n declare readonly connectUrl: string;\n}\n\n/**\n * The provider stopped accepting the connection — revoked, or the refresh token expired\n * (409 `reauthorization_required`). Send the person to `connectUrl` to connect again.\n */\nexport class PipeReauthorizationRequiredError extends PipeLeaseError {\n declare readonly connectUrl: string;\n}\n\n/** The provider could not refresh the token just now (503). Retry after `retryAfter`. */\nexport class PipeTemporarilyUnavailableError extends PipeLeaseError {}\n\n/**\n * The lease was denied (403 `lease_denied`): the app is not granted the pipe, the pipe is\n * disabled or missing, the person is not in the app's organization, or `userId` names\n * someone other than the token's person. One answer for every reason, by design.\n */\nexport class PipeLeaseDeniedError extends PipeLeaseError {}\n\nexport interface StoreSecretInput {\n name: string;\n provider: string;\n secret: string;\n ownerType?: 'organization' | 'user';\n ownerId?: string;\n expiresAt?: string;\n}\n\n/**\n * Client for a Cbox ID instance's Token Vault API. Bind it to an access token\n * (obtain one with {@link CboxIdClient.machineToken}, scoped `vault.manage` for\n * provisioning or `vault.lease` for redeeming). All calls are server-to-server.\n */\nexport class VaultClient {\n private readonly base: string;\n\n constructor(\n issuer: string,\n private readonly token: string,\n private readonly timeoutMs = 10_000,\n ) {\n this.base = `${issuer.replace(/\\/$/, '')}/api/v1/vault`;\n }\n\n /** Ingest a downstream credential, sealed at rest (scope `vault.manage`). */\n store(input: StoreSecretInput): Promise<VaultSecretRef> {\n return this.json<VaultSecretRef>('POST', '/secrets', {\n name: input.name,\n provider: input.provider,\n secret: input.secret,\n owner_type: input.ownerType,\n owner_id: input.ownerId,\n expires_at: input.expiresAt,\n });\n }\n\n /** Rotate a secret's value, keeping its id and grants (scope `vault.manage`). */\n rotate(secretId: string, secret: string): Promise<VaultSecretRef> {\n return this.json<VaultSecretRef>('POST', `/secrets/${encodeURIComponent(secretId)}/rotate`, { secret });\n }\n\n /** Revoke a secret permanently (scope `vault.manage`). */\n async revoke(secretId: string): Promise<void> {\n await this.request('DELETE', `/secrets/${encodeURIComponent(secretId)}`);\n }\n\n /** Authorize an agent client to lease a secret (scope `vault.manage`). */\n grant(\n secretId: string,\n clientId: string,\n maxTtlSeconds?: number,\n ): Promise<{ secretId: string; clientId: string; maxTtlSeconds: number | null }> {\n return this.json('POST', `/secrets/${encodeURIComponent(secretId)}/grants`, {\n client_id: clientId,\n max_ttl_seconds: maxTtlSeconds,\n }).then((raw) => {\n const r = raw as { secret_id: string; client_id: string; max_ttl_seconds: number | null };\n return { secretId: r.secret_id, clientId: r.client_id, maxTtlSeconds: r.max_ttl_seconds };\n });\n }\n\n /** Revoke an agent's authorization (scope `vault.manage`). */\n async revokeGrant(secretId: string, clientId: string): Promise<void> {\n await this.request(\n 'DELETE',\n `/secrets/${encodeURIComponent(secretId)}/grants/${encodeURIComponent(clientId)}`,\n );\n }\n\n /**\n * Redeem a leased credential for immediate use (scope `vault.lease`). The caller\n * is identified by the token's client; a lease with no live grant is refused.\n */\n lease(secretId: string, purpose: string): Promise<VaultLease> {\n return this.json('POST', `/secrets/${encodeURIComponent(secretId)}/lease`, { purpose }).then((raw) => {\n const r = raw as { secret_id: string; provider: string; secret: string; expires_at: string };\n return { secretId: r.secret_id, provider: r.provider, secret: r.secret, expiresAt: r.expires_at };\n });\n }\n\n /**\n * Lease a fresh access token for a person's connected account at `provider` (Pipes,\n * scope `vault.lease`). The token is refreshed first when it is about to expire, so\n * you never handle a refresh token.\n *\n * With a client-credentials token, name the person in `userId`. With a token issued to\n * your app FOR a person, leave it out — the lease is theirs.\n *\n * ```ts\n * try {\n * const { accessToken } = await vault.leasePipeToken('github', { userId, purpose: 'list-repos' })\n * } catch (e) {\n * if (e instanceof PipeNotConnectedError || e instanceof PipeReauthorizationRequiredError) {\n * return redirect(e.connectUrlWith({ clientId, returnTo }))\n * }\n * throw e\n * }\n * ```\n */\n async leasePipeToken(\n provider: PipeProvider | string,\n options: { purpose: string; userId?: string },\n ): Promise<PipeToken> {\n const path = `/pipes/${encodeURIComponent(provider)}/token`;\n const response = await this.send('POST', path, {\n purpose: options.purpose,\n ...(options.userId !== undefined ? { user_id: options.userId } : {}),\n });\n\n let body: Record<string, unknown> = {};\n try {\n const parsed: unknown = await response.json();\n if (typeof parsed === 'object' && parsed !== null && !Array.isArray(parsed)) {\n body = parsed as Record<string, unknown>;\n }\n } catch {\n // Not JSON — a proxy's error page. The status below is all there is.\n }\n\n if (!response.ok) {\n throw pipeLeaseError(response, body);\n }\n\n if (typeof body.access_token !== 'string') {\n throw new PipeLeaseError('The pipe lease answered without an access token.', null, response.status);\n }\n\n return {\n accessToken: body.access_token,\n tokenType: 'Bearer',\n provider: String(body.provider ?? provider),\n userId: String(body.user_id ?? ''),\n connectionId: String(body.connection_id ?? ''),\n scopes: Array.isArray(body.scopes) ? body.scopes.filter((s): s is string => typeof s === 'string') : [],\n expiresAt: typeof body.expires_at === 'string' ? body.expires_at : null,\n leaseExpiresAt: String(body.lease_expires_at ?? ''),\n metadata: isStringRecord(body.metadata) ? body.metadata : {},\n };\n }\n\n private async json<T>(method: string, path: string, body: Record<string, unknown>): Promise<T> {\n const response = await this.request(method, path, body);\n return (await response.json()) as T;\n }\n\n private async request(method: string, path: string, body?: Record<string, unknown>): Promise<Response> {\n const response = await this.send(method, path, body);\n if (!response.ok) {\n throw new AuthenticationError(`Vault ${method} ${path} failed with status ${response.status}.`);\n }\n return response;\n }\n\n private async send(method: string, path: string, body?: Record<string, unknown>): Promise<Response> {\n const controller = new AbortController();\n const timer = setTimeout(() => controller.abort(), this.timeoutMs);\n try {\n const init: RequestInit = {\n method,\n headers: {\n authorization: `Bearer ${this.token}`,\n ...(body ? { 'content-type': 'application/json' } : {}),\n },\n signal: controller.signal,\n };\n if (body) {\n init.body = JSON.stringify(body);\n }\n return await fetch(`${this.base}${path}`, init);\n } finally {\n clearTimeout(timer);\n }\n }\n}\n\nfunction pipeLeaseError(response: Response, body: Record<string, unknown>): PipeLeaseError {\n const error = typeof body.error === 'string' ? body.error : null;\n const message = typeof body.message === 'string' && body.message !== ''\n ? body.message\n : `The pipe lease failed with status ${response.status}.`;\n const connectUrl = typeof body.connect_url === 'string' && body.connect_url !== '' ? body.connect_url : null;\n const header = response.headers.get('retry-after')?.trim() ?? '';\n const retryAfter = /^\\d+$/.test(header) ? Number(header) : null;\n\n if (response.status === 404 && connectUrl !== null) {\n return new PipeNotConnectedError(message, error, 404, connectUrl, retryAfter);\n }\n if (response.status === 409 && connectUrl !== null) {\n return new PipeReauthorizationRequiredError(message, error, 409, connectUrl, retryAfter);\n }\n if (response.status === 503) {\n return new PipeTemporarilyUnavailableError(message, error, 503, connectUrl, retryAfter);\n }\n if (response.status === 403 && error !== 'insufficient_scope') {\n return new PipeLeaseDeniedError(message, error, 403, connectUrl, retryAfter);\n }\n\n return new PipeLeaseError(message, error, response.status, connectUrl, retryAfter);\n}\n\nfunction isStringRecord(value: unknown): value is Record<string, string> {\n return (\n typeof value === 'object' &&\n value !== null &&\n !Array.isArray(value) &&\n Object.values(value).every((v) => typeof v === 'string')\n );\n}\n","/**\n * Verify a Cbox ID webhook / inline-action signature. The header is\n * `X-Cbox-Signature: t={unix},v1={hex hmac}` — an HMAC-SHA256 over\n * `\"{timestamp}.{raw body}\"`, valid within a freshness window. Built on Web Crypto\n * so it runs on Node, edge and the browser.\n */\n\n/** Constant-time compare of two hex strings. */\nfunction timingSafeEqual(a: string, b: string): boolean {\n if (a.length !== b.length) {\n return false;\n }\n let mismatch = 0;\n for (let i = 0; i < a.length; i++) {\n mismatch |= a.charCodeAt(i) ^ b.charCodeAt(i);\n }\n return mismatch === 0;\n}\n\nfunction toHex(bytes: ArrayBuffer): string {\n return Array.from(new Uint8Array(bytes))\n .map((b) => b.toString(16).padStart(2, '0'))\n .join('');\n}\n\nexport interface VerifyWebhookOptions {\n /** The RAW request body — the exact bytes received, not a re-encoded copy. */\n payload: string;\n /** The value of the `X-Cbox-Signature` header. */\n signatureHeader: string | null | undefined;\n /** The signing secret issued when the webhook/action endpoint was registered. */\n secret: string;\n /** Freshness window in seconds. Defaults to 300 (5 minutes). */\n toleranceSeconds?: number;\n /** Injectable clock (unix seconds), for tests. Defaults to `Date.now()`. */\n now?: number;\n}\n\n/** Returns `true` only when the signature is present, fresh and valid. Never throws. */\nexport async function verifyWebhook(options: VerifyWebhookOptions): Promise<boolean> {\n const { payload, signatureHeader, secret } = options;\n const toleranceSeconds = options.toleranceSeconds ?? 300;\n const now = options.now ?? Math.floor(Date.now() / 1000);\n\n if (!signatureHeader) {\n return false;\n }\n\n const parts: Record<string, string> = {};\n for (const segment of signatureHeader.split(',')) {\n const [key, value] = segment.trim().split('=', 2);\n if (key) {\n parts[key] = value ?? '';\n }\n }\n\n const timestamp = parts['t'] ?? '';\n const signature = parts['v1'] ?? '';\n\n if (timestamp === '' || signature === '' || !/^\\d+$/.test(timestamp)) {\n return false;\n }\n\n if (Math.abs(now - Number(timestamp)) > toleranceSeconds) {\n return false;\n }\n\n const key = await crypto.subtle.importKey(\n 'raw',\n new TextEncoder().encode(secret),\n { name: 'HMAC', hash: 'SHA-256' },\n false,\n ['sign'],\n );\n const expected = toHex(\n await crypto.subtle.sign('HMAC', key, new TextEncoder().encode(`${timestamp}.${payload}`)),\n );\n\n return timingSafeEqual(expected, signature);\n}\n\n/** Headers as a `Headers` object or a plain record (Node's `IncomingHttpHeaders`, a framework's map). */\nexport type WebhookHeaders = Headers | Record<string, string | readonly string[] | undefined>;\n\nexport interface VerifyStandardWebhookOptions {\n /** The RAW request body — the exact bytes received, not a re-encoded copy. */\n payload: string;\n /** The request headers; `webhook-id`, `webhook-timestamp` and `webhook-signature` are read. */\n headers: WebhookHeaders;\n /**\n * The endpoint's secret: a `whsec_…` secret, or the 64-hex secret of an endpoint that\n * moved from the `cbox` scheme (Cbox ID uses it as `whsec_` + base64 of the hex string,\n * which keys the HMAC with the same bytes).\n */\n secret: string;\n /** Freshness window in seconds. Defaults to 300 (5 minutes). */\n toleranceSeconds?: number;\n /** Injectable clock (unix seconds), for tests. Defaults to `Date.now()`. */\n now?: number;\n}\n\nfunction header(headers: WebhookHeaders, name: string): string | undefined {\n if (typeof Headers !== 'undefined' && headers instanceof Headers) {\n return headers.get(name) ?? undefined;\n }\n\n const record = headers as Record<string, string | readonly string[] | undefined>;\n const key = Object.keys(record).find((k) => k.toLowerCase() === name);\n const value = key === undefined ? undefined : record[key];\n\n return Array.isArray(value) ? value.join(' ') : (value as string | undefined);\n}\n\nfunction base64ToBytes(value: string): Uint8Array<ArrayBuffer> | null {\n try {\n const binary = atob(value);\n return Uint8Array.from(binary, (c) => c.charCodeAt(0));\n } catch {\n return null;\n }\n}\n\nfunction toBase64(bytes: ArrayBuffer): string {\n let binary = '';\n for (const byte of new Uint8Array(bytes)) {\n binary += String.fromCharCode(byte);\n }\n return btoa(binary);\n}\n\n/**\n * Verify a delivery from an endpoint on the `standard_webhooks` signature scheme\n * ([Standard Webhooks](https://www.standardwebhooks.com/)): `webhook-signature` carries one or\n * more space-separated `v1,<base64 HMAC-SHA256 of \"{webhook-id}.{webhook-timestamp}.{body}\">`,\n * and the timestamp must be within the freshness window. Use {@link verifyWebhook} for the\n * default `cbox` scheme (`X-Cbox-Signature`).\n *\n * Returns `true` only when a signature is present, fresh and valid. Never throws.\n */\nexport async function verifyStandardWebhook(options: VerifyStandardWebhookOptions): Promise<boolean> {\n const { payload, headers, secret } = options;\n const toleranceSeconds = options.toleranceSeconds ?? 300;\n const now = options.now ?? Math.floor(Date.now() / 1000);\n\n const id = header(headers, 'webhook-id');\n const timestamp = header(headers, 'webhook-timestamp');\n const signatures = header(headers, 'webhook-signature');\n\n if (!id || !timestamp || !signatures || !/^\\d+$/.test(timestamp)) {\n return false;\n }\n\n if (Math.abs(now - Number(timestamp)) > toleranceSeconds) {\n return false;\n }\n\n const keyBytes: Uint8Array<ArrayBuffer> | null = secret.startsWith('whsec_') ? base64ToBytes(secret.slice('whsec_'.length)) : new TextEncoder().encode(secret);\n\n if (keyBytes === null || keyBytes.length === 0) {\n return false;\n }\n\n const key = await crypto.subtle.importKey('raw', keyBytes, { name: 'HMAC', hash: 'SHA-256' }, false, ['sign']);\n const expected = toBase64(await crypto.subtle.sign('HMAC', key, new TextEncoder().encode(`${id}.${timestamp}.${payload}`)));\n\n // Several signatures may be sent while a secret rotates; any valid `v1` one is enough.\n let valid = false;\n for (const candidate of signatures.split(' ')) {\n const [version, signature] = candidate.split(',', 2);\n if (version === 'v1' && signature !== undefined && timingSafeEqual(expected, signature)) {\n valid = true;\n }\n }\n\n return valid;\n}\n","import { createRemoteJWKSet, jwtVerify, type JWTPayload } from 'jose';\nimport { Discovery } from './discovery.js';\nimport { assertSecureIssuer } from './issuer.js';\nimport { AuthenticationError, ConfigurationError, InvalidStateError, oauthError } from './errors.js';\nimport { challenge, createVerifier, randomToken } from './pkce.js';\nimport { actor, featureFlags, organization, permissions, roles, sessionId } from './claims.js';\nimport { pipeConnectUrl, type PipeProvider } from './vault.js';\nimport type {\n AuthorizationPrompt,\n AuthorizationRequest,\n AuthorizationRequestOptions,\n CboxIdConfig,\n DeviceAuthorization,\n CboxOrganization,\n CboxUser,\n RefreshedTokens,\n TokenResponse,\n TokenTypeHint,\n} from './types.js';\nimport { VaultClient } from './vault.js';\nimport { verifyWebhook, type VerifyWebhookOptions } from './webhook.js';\n\ntype JwksResolver = ReturnType<typeof createRemoteJWKSet>;\n\n/** Query parameters as they arrive on your callback route. */\nexport interface CallbackParams {\n code?: string | null;\n state?: string | null;\n error?: string | null;\n error_description?: string | null;\n}\n\n/** The values you persisted from {@link CboxIdClient.createAuthorizationRequest}. */\nexport interface StoredAuthState {\n state: string;\n codeVerifier: string;\n nonce: string;\n /** The `maxAge` this login demanded, if any. See {@link AuthorizationRequest.maxAge}. */\n maxAge?: number;\n /**\n * The organization this sign-in was bound to, if any. See\n * {@link AuthorizationRequest.organization}.\n *\n * Checked, not trusted: a binding nobody verifies is a binding in name only. An\n * instance that predates the `organization` parameter ignores it and returns tokens for\n * whichever organization the session already had — and an app that switched to \"Globex\"\n * would then show Globex's name over Acme's data.\n */\n organization?: string;\n /**\n * The scopes THIS authorization asked for, when you overrode the configured set.\n *\n * Read so `authenticate()` can judge the response against what was requested rather\n * than against the config: a login that asked for `openid` and came back without an\n * id_token is a protocol violation, and one that never asked cannot be held to it.\n * Omitted, the configured scopes are assumed — which is what a caller who did not\n * override them actually sent.\n */\n scopes?: string[];\n}\n\n/**\n * Turnkey Cbox ID client for JavaScript/TypeScript. It speaks standard OpenID\n * Connect against a Cbox ID instance — so integrating is a redirect and a callback,\n * not a rewrite — and adds the conveniences a hosted-identity product needs: a\n * redirect to the instance's hosted profile page, and back-channel helpers (machine\n * tokens, userinfo, introspection, webhook verification).\n *\n * Login is hardened by default: PKCE (S256), a CSRF state check, a nonce, and full\n * id_token signature + issuer + audience verification against the instance's JWKS\n * (via `jose`).\n *\n * The class is framework-agnostic: {@link createAuthorizationRequest} hands you the\n * `state`, `codeVerifier` and `nonce` to persist however you like, and\n * {@link authenticate} takes them back. For Next.js, the `@cboxdk/id-js/nextjs`\n * entry wires this to cookies for you.\n */\nexport class CboxIdClient {\n private readonly discovery: Discovery;\n private readonly jwksByUri = new Map<string, JwksResolver>();\n\n constructor(private readonly config: CboxIdConfig) {\n if (!config.issuer) {\n throw new ConfigurationError('Cbox ID config `issuer` is required.');\n }\n if (!config.clientId) {\n throw new ConfigurationError('Cbox ID config `clientId` is required.');\n }\n assertSecureIssuer(config.issuer);\n this.discovery = new Discovery(\n config.issuer,\n config.timeoutMs ?? 10_000,\n config.cacheTtlMs ?? 3_600_000,\n );\n }\n\n /**\n * Begin login. Returns the authorize URL plus the `state`, `codeVerifier` and\n * `nonce` — persist those (signed, httpOnly cookies are ideal) and hand them back\n * to {@link authenticate} on the callback.\n */\n async createAuthorizationRequest(options: AuthorizationRequestOptions = {}): Promise<AuthorizationRequest> {\n const prompt = promptValue(options.prompt);\n assertOrganizationOptions(options, prompt);\n\n const codeVerifier = createVerifier();\n const state = options.state ?? randomToken(16);\n const nonce = randomToken(16);\n\n const redirectUri = options.redirectUri ?? this.config.redirectUri;\n\n if (redirectUri === undefined || redirectUri === '') {\n // Checked where it is needed rather than at construction, so a CLI can build a\n // client at all. An authorize URL without `redirect_uri` would fail at the\n // authorization server instead, describing a request the caller never knowingly\n // made — see the device grant, which has no callback to name.\n throw new ConfigurationError(\n 'A `redirectUri` is required to start the browser sign-in flow. Set it in the config, or pass it to createAuthorizationRequest.',\n );\n }\n\n const params = new URLSearchParams({\n response_type: 'code',\n client_id: this.config.clientId,\n redirect_uri: redirectUri,\n scope: (options.scopes ?? this.scopes()).join(' '),\n state,\n nonce,\n code_challenge: await challenge(codeVerifier),\n code_challenge_method: 'S256',\n });\n if (prompt.length > 0) {\n params.set('prompt', prompt.join(' '));\n }\n if (options.loginHint) {\n params.set('login_hint', options.loginHint);\n }\n if (typeof options.maxAge === 'number') {\n params.set('max_age', String(options.maxAge));\n }\n if (options.organization !== undefined) {\n params.set('organization', options.organization);\n }\n if (options.organizationHint !== undefined) {\n params.set('organization_hint', options.organizationHint);\n }\n\n const endpoint = await this.discovery.endpoint('authorization_endpoint');\n return {\n url: `${endpoint}?${params.toString()}`,\n state,\n codeVerifier,\n nonce,\n // Carried through so authenticate() can hold the instance to it. Only present\n // when requested (exactOptionalPropertyTypes).\n ...(typeof options.maxAge === 'number' ? { maxAge: options.maxAge } : {}),\n ...(options.organization !== undefined ? { organization: options.organization } : {}),\n };\n }\n\n /**\n * Switch the signed-in person to another organization: a new authorization bound to\n * `organizationId`. Persist and redirect exactly as for\n * {@link createAuthorizationRequest} — it is one, with `organization` set.\n *\n * Cbox ID already holds the person's session, so this is normally a redirect there and\n * straight back with no sign-in form. The tokens that come back carry the new `org`,\n * `org_role`, `roles` and `permissions`; replace your session with them rather than\n * patching the old one, because every one of those can differ between organizations.\n *\n * A person who is not (or is no longer) an active member of that organization comes\n * back with `error=access_denied`, which {@link authenticate} throws as an\n * `AuthenticationError` with `error === 'access_denied'`.\n */\n switchOrganization(\n organizationId: string,\n options: Omit<AuthorizationRequestOptions, 'organization' | 'organizationHint'> = {},\n ): Promise<AuthorizationRequest> {\n return this.createAuthorizationRequest({ ...options, organization: organizationId });\n }\n\n /**\n * Complete login on your callback route: verify state, exchange the code with the\n * PKCE verifier, verify the id_token, and return the authenticated user.\n *\n * @throws InvalidStateError when state does not match (forged/stale request)\n * @throws AuthenticationError on any other failure\n */\n async authenticate(input: {\n params: CallbackParams;\n stored: StoredAuthState;\n redirectUri?: string;\n }): Promise<CboxUser> {\n const { params, stored } = input;\n\n if (!params.state || !stored.state || !timingSafeEqualString(params.state, stored.state)) {\n throw new InvalidStateError('The login state did not match — the request may be forged or stale.');\n }\n\n if (params.error) {\n // The code travels as `error`, not only in the message: `access_denied` after a\n // switchOrganization() means \"not a member of that organization\", which an app\n // answers by switching back — not by signing the person out.\n throw new AuthenticationError(\n `Cbox ID returned an error: ${params.error}${params.error_description ? ` (${params.error_description})` : ''}`,\n params.error,\n params.error_description ?? undefined,\n );\n }\n\n if (!params.code) {\n throw new AuthenticationError('The callback was missing an authorization code.');\n }\n\n const tokens = await this.exchange(params.code, stored.codeVerifier, input.redirectUri);\n\n if (!tokens.access_token) {\n throw new AuthenticationError('No access token was returned.');\n }\n\n let verified: Record<string, unknown> = {};\n\n if (tokens.id_token) {\n verified = await this.verifyIdToken(tokens.id_token, stored.nonce, stored.maxAge);\n } else if ((stored.scopes ?? this.scopes()).includes('openid')) {\n // AN `openid` REQUEST WITHOUT AN ID_TOKEN IS A PROTOCOL VIOLATION, and refusing it\n // is the difference between an authenticated login and a bearer token. Without this\n // the identity below came from UserInfo alone — a bearer-authenticated endpoint\n // whose response nothing signed — and the `nonce` pulled from storage was never used.\n //\n // Asked of the SCOPES REQUESTED, not of the response: a caller who never asked for\n // `openid` is running an OAuth flow and is not held to an OIDC rule.\n throw new AuthenticationError(\n 'An openid login returned no id_token, so the identity could not be verified.',\n );\n } else if (typeof stored.maxAge === 'number') {\n // No id_token means no auth_time, and therefore no evidence the demanded\n // re-authentication happened. Accepting that silently is the whole defect.\n throw new AuthenticationError(\n 'A max_age was requested but no id_token was returned, so the authentication age could not be verified.',\n );\n }\n\n const user = await this.identityFrom(tokens, verified);\n\n if (stored.organization !== undefined && user.organizationId !== stored.organization) {\n throw new AuthenticationError(\n `The sign-in was bound to organization ${stored.organization}, but the tokens are for ${user.organizationId ?? 'no organization'}. The instance may not support organization selection.`,\n );\n }\n\n return user;\n }\n\n /**\n * Turn a token response into the verified {@link CboxUser} every flow returns.\n *\n * Shared by the browser flow and the device flow rather than written twice: the checks\n * in here — the UserInfo subject matching the id_token's, the merge that lets UserInfo\n * enrich but never overwrite signed claims — are the ones that decide whether an\n * identity is trustworthy. A second copy is a second place for one of them to be\n * quietly missing, and the flow it was missing from would look exactly as correct.\n */\n private async identityFrom(\n tokens: TokenResponse,\n verified: Record<string, unknown>,\n ): Promise<CboxUser> {\n const profile = await this.userinfo(tokens.access_token);\n\n // OIDC Core §5.3.2: the UserInfo `sub` MUST match the id_token's, and when it does\n // not the response MUST NOT be used. UserInfo is fetched with a bearer token and its\n // body carries no signature, so without this an IdP — or anything able to answer as\n // one — hands back `{\"sub\":\"somebody-else\"}` and the SDK returns it as the identity.\n const verifiedSub = verified['sub'];\n const profileSub = profile['sub'];\n\n if (typeof verifiedSub === 'string' && typeof profileSub === 'string' && !timingSafeEqualString(verifiedSub, profileSub)) {\n throw new AuthenticationError('The UserInfo subject does not match the verified id_token.');\n }\n\n // ENRICHES, NEVER REPLACES. UserInfo fills in what a minimal id_token omits (email,\n // name, org) and the verified claims go back on top, so the merge cannot move `sub`,\n // `iss`, `aud`, `nonce` or anything else the signature covered. The spread used to run\n // the other way round.\n const claims: Record<string, unknown> = { ...profile, ...verified };\n\n const sub = claims['sub'];\n if (typeof sub !== 'string' || sub === '') {\n throw new AuthenticationError('The verified token carried no subject.');\n }\n\n const organizations = parseOrganizations(claims['organizations']);\n\n return {\n id: sub,\n email: typeof claims['email'] === 'string' ? claims['email'] : null,\n name: typeof claims['name'] === 'string' ? claims['name'] : null,\n organizationId: typeof claims['org'] === 'string' ? claims['org'] : null,\n organization: organization(claims),\n roles: roles(claims),\n permissions: permissions(claims),\n featureFlags: featureFlags(claims),\n actor: actor(claims),\n sessionId: sessionId(claims),\n // Only present when the instance emitted the claim (exactOptionalPropertyTypes).\n ...(organizations ? { organizations } : {}),\n claims,\n accessToken: tokens.access_token,\n refreshToken: tokens.refresh_token ?? null,\n idToken: tokens.id_token ?? null,\n expiresIn: typeof tokens.expires_in === 'number' ? tokens.expires_in : 0,\n };\n }\n\n /**\n * Start the device authorization grant (RFC 8628) — the flow for a program with no\n * browser of its own: a CLI, a CI job, a container, a TV.\n *\n * Print `userCode` and `verificationUri`, then call\n * {@link CboxIdClient.pollDeviceToken}. If the machine has a desktop you may also open\n * `verificationUriComplete`, which fills the code in — but print the code anyway: the\n * machine running your program is often not the one the person is looking at.\n *\n * The scopes are bounded by what the app is REGISTERED for. A device request naming one\n * outside that ceiling is refused with `invalid_scope` rather than quietly reduced,\n * because no browser is in front of it to notice a smaller grant.\n *\n * @throws ConfigurationError when the instance advertises no device endpoint.\n */\n async requestDeviceAuthorization(scopes?: string[]): Promise<DeviceAuthorization> {\n const endpoint = await this.discovery.optionalEndpoint('device_authorization_endpoint');\n\n if (endpoint === null) {\n throw new ConfigurationError(\n 'This instance does not advertise a device_authorization_endpoint, so it does not support CLI sign-in.',\n );\n }\n\n const body = new URLSearchParams({\n client_id: this.config.clientId,\n scope: (scopes ?? this.scopes()).join(' '),\n });\n if (this.config.clientSecret) {\n body.set('client_secret', this.config.clientSecret);\n }\n\n const response = await this.post(endpoint, body);\n if (!response.ok) {\n throw await oauthError(response, 'Device authorization request failed');\n }\n\n const payload = (await response.json()) as Record<string, unknown>;\n\n const deviceCode = payload['device_code'];\n const userCode = payload['user_code'];\n const verificationUri = payload['verification_uri'];\n\n if (typeof deviceCode !== 'string' || typeof userCode !== 'string' || typeof verificationUri !== 'string') {\n throw new AuthenticationError('The device authorization response was incomplete.');\n }\n\n return {\n deviceCode,\n userCode,\n verificationUri,\n verificationUriComplete:\n typeof payload['verification_uri_complete'] === 'string'\n ? payload['verification_uri_complete']\n : null,\n expiresIn: typeof payload['expires_in'] === 'number' ? payload['expires_in'] : 600,\n // RFC 8628 §3.2: absent means 5 seconds. Polling faster than the server allows is\n // answered with `slow_down`, so the default is the one the server assumes too.\n interval: typeof payload['interval'] === 'number' ? payload['interval'] : 5,\n };\n }\n\n /**\n * Poll until the person approves, and return them.\n *\n * Blocks. It honours the server's `interval`, backs off permanently by five seconds on\n * `slow_down` (RFC 8628 §3.5), and stops on the three answers that are final: they\n * declined, the code expired, or tokens arrived. Pass an `AbortSignal` to give up\n * early — a CLI should let Ctrl-C work.\n *\n * @throws AuthenticationError when the person declines or the code expires.\n */\n async pollDeviceToken(\n authorization: DeviceAuthorization,\n options: { signal?: AbortSignal } = {},\n ): Promise<CboxUser> {\n const endpoint = await this.discovery.endpoint('token_endpoint');\n const deadline = Date.now() + authorization.expiresIn * 1000;\n let intervalMs = authorization.interval * 1000;\n\n for (;;) {\n if (options.signal?.aborted === true) {\n throw new AuthenticationError('Device sign-in was cancelled.');\n }\n if (Date.now() > deadline) {\n throw new AuthenticationError(\n 'The device code expired before it was approved. Start the sign-in again.',\n );\n }\n\n await sleep(intervalMs, options.signal);\n\n const body = new URLSearchParams({\n grant_type: 'urn:ietf:params:oauth:grant-type:device_code',\n device_code: authorization.deviceCode,\n client_id: this.config.clientId,\n });\n if (this.config.clientSecret) {\n body.set('client_secret', this.config.clientSecret);\n }\n\n const response = await this.post(endpoint, body);\n\n if (response.ok) {\n const tokens = (await response.json()) as TokenResponse;\n\n if (!tokens.access_token) {\n throw new AuthenticationError('The device token response carried no access token.');\n }\n\n // No nonce: RFC 8628 has no browser leg to carry one, so there is nothing to\n // bind. Everything else about the id_token — signature, issuer, audience,\n // expiry — is verified exactly as it is on the browser flow.\n const verified = tokens.id_token ? await this.verifyIdToken(tokens.id_token, '') : {};\n\n return await this.identityFrom(tokens, verified);\n }\n\n const payload = (await response.json().catch(() => ({}))) as Record<string, unknown>;\n const error = typeof payload['error'] === 'string' ? payload['error'] : 'invalid_request';\n\n if (error === 'authorization_pending') {\n continue;\n }\n\n if (error === 'slow_down') {\n // Permanently, not for one round: the server is telling us our rate is wrong,\n // and returning to it next tick earns the same answer forever.\n intervalMs += 5000;\n continue;\n }\n\n if (error === 'access_denied') {\n throw new AuthenticationError('Sign-in was declined.');\n }\n\n if (error === 'expired_token') {\n throw new AuthenticationError(\n 'The device code expired before it was approved. Start the sign-in again.',\n );\n }\n\n throw await oauthError(response, 'Device sign-in failed');\n }\n }\n\n /**\n * Exchange a refresh token for a fresh access token (OAuth 2.0 `refresh_token`\n * grant). Cbox ID rotates refresh tokens and detects reuse, so ALWAYS persist the\n * returned `refreshToken` and discard the one you passed — presenting a rotated\n * token again revokes the entire token family.\n *\n * @throws AuthenticationError when the refresh token is invalid, expired, or already rotated.\n */\n async refresh(refreshToken: string): Promise<RefreshedTokens> {\n const body = new URLSearchParams({\n grant_type: 'refresh_token',\n client_id: this.config.clientId,\n refresh_token: refreshToken,\n });\n if (this.config.clientSecret) {\n body.set('client_secret', this.config.clientSecret);\n }\n\n const response = await this.post(await this.discovery.endpoint('token_endpoint'), body);\n if (!response.ok) {\n // The most consequential of these: `invalid_grant` means the refresh token is\n // spent, revoked or replayed and the person must sign in again, while a 5xx or\n // `temporarily_unavailable` means the same token is still good in a moment. One\n // message string for both is what makes callers guess.\n throw await oauthError(response, 'Token refresh failed');\n }\n\n const tokens = (await response.json()) as TokenResponse;\n if (!tokens.access_token) {\n throw new AuthenticationError('The refresh response carried no access token.');\n }\n\n // VERIFIED BEFORE IT IS HANDED BACK. A refresh response carries a fresh id_token, and\n // this returned it unchecked — so an application that refreshes its session claims\n // from `refresh().idToken` accepted a forged, expired, wrong-audience or wrong-issuer\n // token, having verified only the one it got at login. The nonce is not re-checked:\n // RFC 6749 has no nonce on this leg, and OIDC Core §12.2 says an id_token from a\n // refresh need not carry one.\n if (tokens.id_token) {\n await this.verifyIdToken(tokens.id_token, '');\n }\n\n return {\n accessToken: tokens.access_token,\n // Keep the presented token when the server does not rotate (OAuth 2.0 §6);\n // callers persist this value, so it must never come back null.\n refreshToken: tokens.refresh_token ?? refreshToken,\n idToken: tokens.id_token ?? null,\n expiresIn: typeof tokens.expires_in === 'number' ? tokens.expires_in : 0,\n scope: typeof tokens.scope === 'string' ? tokens.scope : null,\n };\n }\n\n /**\n * The URL of the instance's hosted account/profile page (self-service password,\n * MFA, passkeys, sessions). A signed-in user is authenticated there by their Cbox\n * ID session; `returnTo` is passed so the page can link back to your app.\n */\n profileUrl(returnTo?: string): string {\n const base = `${this.config.issuer.replace(/\\/$/, '')}${this.accountPath()}`;\n return returnTo ? `${base}?${new URLSearchParams({ return_to: returnTo }).toString()}` : base;\n }\n\n /**\n * The hosted page where a person creates and revokes API keys for your API — Cbox ID's\n * `/account/api-keys`, preselected to this app (or `clientId`). Keys made there are\n * checked with `ApiKeyVerifier` from `@cboxdk/id-js/server`.\n *\n * `returnTo` becomes a link back to your app, honoured only for an origin the app\n * registered. `organization` picks which of the person's organizations the keys act in;\n * omitted, the page uses the one they are in.\n */\n /**\n * The hosted page where the signed-in person connects their account at `provider`\n * (Pipes) — `/account/connected-services/{provider}/connect`, preselected to this app.\n * They come back to `returnTo` with `?provider=…&status=connected|cancelled|failed`,\n * honoured only on an origin the app registered.\n */\n pipeConnectUrl(provider: PipeProvider | string, returnTo?: string): string {\n return pipeConnectUrl(this.config.issuer, provider, {\n clientId: this.config.clientId,\n ...(returnTo !== undefined ? { returnTo } : {}),\n });\n }\n\n apiKeysUrl(options: { clientId?: string; returnTo?: string; organization?: string } = {}): string {\n const params = new URLSearchParams({ client_id: options.clientId ?? this.config.clientId });\n if (options.returnTo) {\n params.set('return_to', options.returnTo);\n }\n if (options.organization) {\n params.set('organization', options.organization);\n }\n\n return `${this.config.issuer.replace(/\\/$/, '')}/account/api-keys?${params.toString()}`;\n }\n\n /**\n * The RP-initiated logout URL, or null when the instance advertises none.\n *\n * `client_id` is always sent, even without a `returnTo`: the OP validates\n * `post_logout_redirect_uri` against the registered allow-list of THAT client\n * (OIDC RP-Initiated Logout 1.0 §2). With no way to name the RP the OP cannot\n * check the list, so it silently drops the return URL and strands the user on a\n * bare \"you are signed out\" page. `idTokenHint` — the user's `id_token`, if you\n * still hold it — is the spec's other way to identify the RP, and additionally\n * tells the OP which subject is logging out.\n *\n * PASS THE HINT IF YOU WANT \"SIGN OUT EVERYWHERE\". Cbox ID revokes every session\n * the person holds only when a hint it can VERIFY names the subject holding the\n * browser; with no hint it signs this browser out and leaves their other devices\n * alone. That is deliberate: the endpoint is unauthenticated and reached by a\n * redirect, so a request carrying no proof of who it concerns could otherwise be\n * forged into ending anyone's sessions everywhere. See laravel-id UPGRADING.md\n * for 1.8.0.\n */\n async logoutUrl(returnTo?: string, idTokenHint?: string): Promise<string | null> {\n const endpoint = await this.discovery.optionalEndpoint('end_session_endpoint');\n if (!endpoint) {\n return null;\n }\n const params = new URLSearchParams({ client_id: this.config.clientId });\n if (returnTo) {\n params.set('post_logout_redirect_uri', returnTo);\n }\n if (idTokenHint) {\n params.set('id_token_hint', idTokenHint);\n }\n return `${endpoint}?${params.toString()}`;\n }\n\n /**\n * A machine (client-credentials) access token for calling Cbox ID APIs as your\n * app, not on a user's behalf. Requires a client secret.\n */\n async machineToken(options: { scopes?: string[]; resource?: string } = {}): Promise<string> {\n const body = new URLSearchParams({\n grant_type: 'client_credentials',\n client_id: this.config.clientId,\n client_secret: this.requireSecret(),\n });\n if (options.scopes && options.scopes.length > 0) {\n body.set('scope', options.scopes.join(' '));\n }\n if (options.resource) {\n body.set('resource', options.resource);\n }\n\n const response = await this.post(await this.discovery.endpoint('token_endpoint'), body);\n if (!response.ok) {\n throw await oauthError(response, 'Machine token request failed');\n }\n const json = (await response.json()) as { access_token?: unknown };\n if (typeof json.access_token !== 'string') {\n throw new AuthenticationError('The token response had no access_token.');\n }\n return json.access_token;\n }\n\n /** The OIDC userinfo claims for an access token. */\n async userinfo(accessToken: string): Promise<Record<string, unknown>> {\n const endpoint = await this.discovery.optionalEndpoint('userinfo_endpoint');\n if (!endpoint) {\n return {};\n }\n const response = await this.fetchWithTimeout(endpoint, {\n headers: { authorization: `Bearer ${accessToken}` },\n });\n if (!response.ok) {\n throw await oauthError(response, 'Userinfo request failed');\n }\n return (await response.json()) as Record<string, unknown>;\n }\n\n /**\n * RFC 7662 token introspection (confidential-client auth). Returns the raw\n * response; `active` tells you if the token is currently valid. Requires a secret.\n */\n async introspect(token: string): Promise<Record<string, unknown>> {\n const endpoint = await this.discovery.endpoint('introspection_endpoint');\n const basic = btoa(`${this.config.clientId}:${this.requireSecret()}`);\n const response = await this.post(\n endpoint,\n new URLSearchParams({ token }),\n { authorization: `Basic ${basic}` },\n );\n if (!response.ok) {\n throw await oauthError(response, 'Introspection request failed');\n }\n return (await response.json()) as Record<string, unknown>;\n }\n\n /**\n * RFC 7009 token revocation. Revokes an access or refresh token; revoking a refresh\n * token drops the whole token family, so this is what a real \"sign out everywhere\" does.\n *\n * **PUBLIC CLIENTS TOO.** This demanded a secret and threw `ConfigurationError` without\n * one — so the clients that most need it were the ones that could not call it. A PKCE\n * browser or native app authenticates with `none`, holds no secret, and is exactly the\n * case where a refresh token sits in storage on a device somebody has just signed out\n * of. Cbox ID's revocation endpoint accepts a public client, and its discovery document\n * advertises `none` among the revocation auth methods; RFC 7009 §2.1 scopes every\n * revocation to the calling client, so the only capability here is \"destroy a token you\n * are already holding\". The SDK was the half saying no.\n *\n * A confidential client still authenticates with Basic; a public one names itself in the\n * body, the same shape {@link exchange} already uses for the token endpoint.\n *\n * Per RFC 7009 the server answers 200 for an unknown or already-revoked token, so\n * success means \"this token is not valid any more\", not \"it existed\".\n *\n * @param tokenTypeHint which store to search first — only a hint, never required.\n */\n async revoke(token: string, tokenTypeHint?: TokenTypeHint): Promise<void> {\n const endpoint = await this.discovery.endpoint('revocation_endpoint');\n const body = new URLSearchParams({ token, client_id: this.config.clientId });\n if (tokenTypeHint) {\n body.set('token_type_hint', tokenTypeHint);\n }\n\n const headers: Record<string, string> = {};\n if (this.config.clientSecret) {\n headers.authorization = `Basic ${btoa(`${this.config.clientId}:${this.config.clientSecret}`)}`;\n }\n\n const response = await this.post(endpoint, body, headers);\n if (!response.ok) {\n throw await oauthError(response, 'Revocation request failed');\n }\n }\n\n /** Verify a Cbox ID webhook / inline-action signature. See {@link verifyWebhook}. */\n verifyWebhook(options: VerifyWebhookOptions): Promise<boolean> {\n return verifyWebhook(options);\n }\n\n /**\n * A Token Vault client bound to an access token. Obtain the token with\n * {@link machineToken} (scope `vault.manage` to provision/grant, `vault.lease` to\n * redeem), then call `store` / `grant` / `lease` etc.\n */\n vault(accessToken: string): VaultClient {\n return new VaultClient(this.config.issuer, accessToken, this.config.timeoutMs ?? 10_000);\n }\n\n private async exchange(code: string, verifier: string, redirectUri?: string): Promise<TokenResponse> {\n const callback = redirectUri ?? this.config.redirectUri;\n\n if (callback === undefined || callback === '') {\n throw new ConfigurationError(\n 'A `redirectUri` is required to exchange an authorization code. It must be the same one the authorization request used.',\n );\n }\n\n const body = new URLSearchParams({\n grant_type: 'authorization_code',\n code,\n redirect_uri: callback,\n client_id: this.config.clientId,\n code_verifier: verifier,\n });\n if (this.config.clientSecret) {\n body.set('client_secret', this.config.clientSecret);\n }\n\n const response = await this.post(await this.discovery.endpoint('token_endpoint'), body);\n if (!response.ok) {\n throw await oauthError(response, 'Token exchange failed');\n }\n return (await response.json()) as TokenResponse;\n }\n\n private async verifyIdToken(\n idToken: string,\n // Empty skips the nonce comparison below, which is what a refresh leg needs: RFC 6749\n // has no nonce there and OIDC Core §12.2 says the id_token from a refresh need not\n // carry one. Signature, issuer, audience and expiry are checked either way.\n nonce: string,\n maxAge?: number,\n ): Promise<Record<string, unknown>> {\n const jwksUri = await this.discovery.endpoint('jwks_uri');\n let resolver = this.jwksByUri.get(jwksUri);\n if (!resolver) {\n resolver = createRemoteJWKSet(new URL(jwksUri));\n this.jwksByUri.set(jwksUri, resolver);\n }\n\n let payload: JWTPayload;\n try {\n ({ payload } = await jwtVerify(idToken, resolver, {\n issuer: this.config.issuer,\n audience: this.config.clientId,\n // Pin the accepted signature algorithms explicitly. `jose` already refuses\n // `alg: none` and key-type confusion, so this is belt-and-braces — but it\n // states the contract in code rather than relying on a library default.\n algorithms: ['RS256', 'ES256'],\n }));\n } catch (error) {\n throw new AuthenticationError(`The id_token could not be verified: ${String(error)}`);\n }\n\n if (nonce && payload['nonce'] !== nonce) {\n throw new AuthenticationError('The id_token nonce did not match — possible replay.');\n }\n\n // OIDC Core §3.1.3.7 step 12: when max_age was requested, `auth_time` is REQUIRED\n // and the relying party MUST check it. `max_age` is the control you reach for\n // before a payment or an admin grant, and the whole point is that the person\n // authenticated JUST NOW — so a login({maxAge}) whose result is never checked is a\n // step-up in name only: a day-old session comes back carrying its original\n // auth_time and nothing anywhere says so.\n if (typeof maxAge === 'number') {\n const authTime = payload['auth_time'];\n\n if (typeof authTime !== 'number') {\n throw new AuthenticationError(\n 'A max_age was requested but the id_token carried no auth_time, so the authentication age could not be verified.',\n );\n }\n\n const tolerance = this.config.authTimeToleranceSeconds ?? 60;\n const age = Math.floor(Date.now() / 1000) - authTime;\n\n if (age > maxAge + tolerance) {\n throw new AuthenticationError(\n `The authentication is ${age}s old but max_age required ${maxAge}s — the user did not re-authenticate.`,\n );\n }\n }\n\n return payload as Record<string, unknown>;\n }\n\n private scopes(): string[] {\n const scopes = this.config.scopes;\n return scopes && scopes.length > 0 ? scopes : ['openid', 'profile', 'email'];\n }\n\n private accountPath(): string {\n const path = this.config.accountPath;\n // `/account`, not `/settings`. The latter is the organization-admin page: it\n // redirects a non-admin to `/account` and drops `return_to` on the way, so a member\n // following this link arrives at the right screen having lost where they came from.\n return path && path !== '' ? `/${path.replace(/^\\//, '')}` : '/account';\n }\n\n private requireSecret(): string {\n if (!this.config.clientSecret) {\n throw new ConfigurationError('This call requires a `clientSecret`, but none is configured.');\n }\n return this.config.clientSecret;\n }\n\n private post(url: string, body: URLSearchParams, headers: Record<string, string> = {}): Promise<Response> {\n return this.fetchWithTimeout(url, {\n method: 'POST',\n headers: { 'content-type': 'application/x-www-form-urlencoded', ...headers },\n body,\n });\n }\n\n private async fetchWithTimeout(url: string, init: RequestInit): Promise<Response> {\n const controller = new AbortController();\n const timer = setTimeout(() => controller.abort(), this.config.timeoutMs ?? 10_000);\n try {\n return await fetch(url, { ...init, signal: controller.signal });\n } finally {\n clearTimeout(timer);\n }\n }\n}\n\n/** Normalise `prompt` to a de-duplicated list, refusing what the server would refuse. */\nfunction promptValue(prompt: AuthorizationRequestOptions['prompt']): AuthorizationPrompt[] {\n if (prompt === undefined) {\n return [];\n }\n\n const values = [...new Set(typeof prompt === 'string' ? [prompt] : prompt)];\n\n // OIDC Core §3.1.2.1: `none` with any other value is an error. Failing here names the\n // call that built it; failing at the server names nothing the caller can find.\n if (values.includes('none') && values.length > 1) {\n throw new ConfigurationError(\"`prompt: 'none'` cannot be combined with another prompt value.\");\n }\n\n return values;\n}\n\n/**\n * Refuse organization options that contradict each other. Each of these would reach the\n * server as a request with two incompatible meanings and come back as a generic error\n * after a full redirect — far from the line that built it.\n */\nfunction assertOrganizationOptions(options: AuthorizationRequestOptions, prompt: AuthorizationPrompt[]): void {\n // An empty id is not \"no organization\" at the server — it is a parameter that is\n // present and names nothing. Omit the option instead.\n if (options.organization === '') {\n throw new ConfigurationError('`organization` is empty. Omit it to sign in without binding to an organization.');\n }\n if (options.organizationHint === '') {\n throw new ConfigurationError('`organizationHint` is empty. Omit it when you have no organization to suggest.');\n }\n\n if (options.organization === undefined) {\n return;\n }\n\n // `organization` binds to an existing organization; both prompts below ask the person\n // to choose or create one. Sending both leaves the server to guess which you meant.\n if (prompt.includes('select_organization')) {\n throw new ConfigurationError(\n \"`organization` binds the sign-in to one organization, so `prompt: 'select_organization'` has nothing to choose. Use `organizationHint` to preselect an organization in the picker instead.\",\n );\n }\n if (prompt.includes('create_organization')) {\n throw new ConfigurationError(\n \"`organization` binds the sign-in to an existing organization and `prompt: 'create_organization'` creates a new one. Send one or the other.\",\n );\n }\n}\n\n/** Constant-time string compare, so state validation doesn't leak via timing. */\nfunction timingSafeEqualString(a: string, b: string): boolean {\n if (a.length !== b.length) {\n return false;\n }\n let mismatch = 0;\n for (let i = 0; i < a.length; i++) {\n mismatch |= a.charCodeAt(i) ^ b.charCodeAt(i);\n }\n return mismatch === 0;\n}\n\n/**\n * Parse an `organizations` claim into typed orgs, ignoring anything malformed. The\n * claim is optional and instance-specific; absent or non-array → undefined, so\n * callers can tell \"no claim\" from \"empty\".\n */\nfunction parseOrganizations(claim: unknown): CboxOrganization[] | undefined {\n if (!Array.isArray(claim)) {\n return undefined;\n }\n const orgs: CboxOrganization[] = [];\n for (const entry of claim) {\n if (typeof entry !== 'object' || entry === null) {\n continue;\n }\n const record = entry as Record<string, unknown>;\n const id = record['id'];\n const name = record['name'];\n if (typeof id === 'string' && id !== '' && typeof name === 'string' && name !== '') {\n orgs.push({ id, name, role: typeof record['role'] === 'string' ? record['role'] : null });\n }\n }\n return orgs;\n}\n\n/**\n * Wait, but stay interruptible.\n *\n * A CLI that ignores Ctrl-C for five seconds at a time feels broken, and a bare\n * `setTimeout` promise cannot be cancelled — so the abort is wired to the same timer\n * rather than checked after it.\n */\nfunction sleep(ms: number, signal?: AbortSignal): Promise<void> {\n return new Promise((resolve, reject) => {\n if (signal?.aborted === true) {\n reject(new AuthenticationError('Device sign-in was cancelled.'));\n return;\n }\n\n const timer = setTimeout(() => {\n signal?.removeEventListener('abort', onAbort);\n resolve();\n }, ms);\n\n const onAbort = (): void => {\n clearTimeout(timer);\n reject(new AuthenticationError('Device sign-in was cancelled.'));\n };\n\n signal?.addEventListener('abort', onAbort, { once: true });\n });\n}\n","import { Discovery } from './discovery.js';\nimport { AuthenticationError, ConfigurationError } from './errors.js';\nimport { assertSecureIssuer } from './issuer.js';\n\n/**\n * A permission your app declares. `key` is a `feature:action` slug (e.g.\n * `invoices:create`); `description` is human-facing copy for the Cbox ID console.\n */\nexport interface PermissionDefinition {\n key: string;\n description?: string;\n /**\n * Whether an organization's own administrators may hand this permission out in a custom\n * role they build themselves (self-serve). Defaults to `false`: a permission is internal\n * unless you opt it in, so a key added in a hurry never becomes something every customer\n * can grant. Sent as `tenant_assignable: true`.\n */\n tenantAssignable?: boolean;\n}\n\n/**\n * A role your app declares. `permissions` lists the permission keys the role\n * grants — each must reference a declared {@link PermissionDefinition}.\n */\nexport interface RoleDefinition {\n key: string;\n name: string;\n description?: string;\n permissions: string[];\n /**\n * Whether an organization's administrators may assign this role to their members.\n * Defaults to `true`.\n *\n * Set `false` for a STAFF role — your own support or operations people, held\n * environment-wide across every customer (typically the role that grants\n * `support:impersonate`). Cbox ID never lists or accepts a staff role on the\n * organization plane; only an environment administrator can grant it. Sent as\n * `tenant_assignable: false`.\n */\n tenantAssignable?: boolean;\n}\n\n/** A permission as it is sent to Cbox ID (snake_case, the manifest's wire format). */\nexport interface ManifestPermission {\n key: string;\n description?: string;\n /** Present only for a self-serve permission. See {@link PermissionDefinition.tenantAssignable}. */\n tenant_assignable?: true;\n}\n\n/** A role as it is sent to Cbox ID (snake_case, the manifest's wire format). */\nexport interface ManifestRole {\n key: string;\n name: string;\n description?: string;\n permissions: string[];\n /** Present only for a staff role. See {@link RoleDefinition.tenantAssignable}. */\n tenant_assignable?: false;\n}\n\n/**\n * The roles + permissions an app declares in code. Either list may be omitted.\n * Pass this to {@link defineAuthz} (to validate up front) or straight to\n * {@link buildManifest} / {@link publishManifest}.\n */\nexport interface AuthzDeclaration {\n permissions?: PermissionDefinition[];\n roles?: RoleDefinition[];\n /**\n * Where this app's OLD login lives, while you are migrating off it.\n *\n * Declared here for the same reason roles are: it is a fact about the app, it belongs\n * with the deploy, and the alternative is a URL pasted into a console and a secret\n * pasted into an env file that quietly disagree six weeks later.\n *\n * IT DOES NOT TAKE EFFECT ON ITS OWN. Unlike a role — which affects only the app that\n * declared it — this names a URL that every unknown email and the password typed with\n * it will be offered to, on the environment's whole sign-in path. So it arrives as a\n * proposal and an operator has to approve it in the console. Changing the url later\n * drops that approval, on purpose.\n */\n legacyLogin?: LegacyLoginDeclaration;\n}\n\n/** Where an app's old login lives. See {@link AuthzDeclaration.legacyLogin}. */\nexport interface LegacyLoginDeclaration {\n /** Must be https — a password in the clear is readable by everything on the path. */\n url: string;\n /** At least 32 characters. It is the only thing proving a request came from Cbox ID. */\n secret: string;\n}\n\n/**\n * The manifest as it is sent to Cbox ID: the declared permissions + roles plus a\n * content-derived `version`, so republishing an unchanged catalog is a no-op.\n */\nexport interface AuthzManifest {\n version: string;\n permissions: ManifestPermission[];\n roles: ManifestRole[];\n legacy_login?: LegacyLoginDeclaration;\n}\n\n/** What {@link publishManifest} needs to authenticate the push. */\nexport interface ManifestPublisherConfig {\n /** Base URL (issuer) of the Cbox ID instance — the `token_endpoint` is discovered from it. */\n issuer: string;\n /** Your OAuth client id. The client must hold the `apps.manifest` scope. */\n clientId: string;\n /** Your OAuth client secret. The push uses the client-credentials grant. */\n clientSecret: string;\n /** Timeout (ms) for back-channel HTTP calls. Defaults to `10000`. */\n timeoutMs?: number;\n}\n\n/**\n * The server's sync summary. The named fields are the ones the SDK/CLI reads;\n * the index signature keeps any extra fields the server returns.\n */\nexport interface ManifestSyncSummary {\n unchanged?: boolean;\n roles_declared?: number;\n permissions_declared?: number;\n version?: string;\n [key: string]: unknown;\n}\n\n/**\n * Validate a roles/permissions declaration and return it normalized (both lists\n * always present). Call this where you declare your catalog so mistakes — a role\n * that grants an undeclared permission, a duplicate key — surface immediately\n * rather than on deploy.\n *\n * @throws ConfigurationError on a missing key/name, a duplicate, or a role that\n * references a permission that was never declared.\n */\nexport function defineAuthz(\n declaration: AuthzDeclaration,\n): AuthzDeclaration & { permissions: PermissionDefinition[]; roles: RoleDefinition[] } {\n const permissions = declaration.permissions ?? [];\n const roles = declaration.roles ?? [];\n assertDeclaration(permissions, roles);\n\n // The legacy login is validated here too, so a bad one fails in the deploy that\n // introduced it rather than as a 4xx from a manifest push somebody has to go and read.\n if (declaration.legacyLogin) {\n assertLegacyLogin(declaration.legacyLogin);\n }\n\n // `Required<>` no longer fits: the catalog is always present after this, and the legacy\n // login legitimately is not. Returning the declaration's own optionality keeps a caller\n // from having to invent an empty one.\n return { ...declaration, permissions, roles };\n}\n\n/**\n * Build the manifest — the declared catalog plus a stable content hash `version`\n * (first 16 hex chars of the sha256 of the canonicalized catalog). The catalog is\n * sorted by key first, so declaration order never changes the version.\n */\nexport async function buildManifest(declaration: AuthzDeclaration): Promise<AuthzManifest> {\n const permissions = declaration.permissions ?? [];\n const roles = declaration.roles ?? [];\n assertDeclaration(permissions, roles);\n\n // The version hashes the CATALOG only, and the legacy login is deliberately outside it:\n // this canonicalization is a cross-SDK contract — id-js, id-python, id-go and the PHP\n // reference all produce the same bytes, and a shared fixture exists to keep them from\n // drifting. The server compares a declared url separately for the same reason.\n const version = (await sha256Hex(canonicalManifestJson(permissions, roles))).slice(0, 16);\n\n const manifest: AuthzManifest = {\n version,\n permissions: [...permissions].sort((a, b) => byteCompare(a.key, b.key)).map(wirePermission),\n roles: [...roles].sort((a, b) => byteCompare(a.key, b.key)).map(wireRole),\n };\n\n if (declaration.legacyLogin) {\n assertLegacyLogin(declaration.legacyLogin);\n manifest.legacy_login = declaration.legacyLogin;\n }\n\n return manifest;\n}\n\n/**\n * Publish this app's authorization manifest (its declared roles + permissions) to\n * Cbox ID. The app owns what a role means; Cbox ID owns identity and who holds it.\n *\n * It mints a client-credentials token with the `apps.manifest` scope (token\n * endpoint discovered from the issuer's OIDC configuration), then POSTs the\n * manifest to `{issuer}/api/v1/apps/manifest`. Run it on deploy or from a script;\n * an unchanged catalog is a server-side no-op.\n *\n * @returns the server's sync summary (`unchanged`, `roles_declared`, …).\n * @throws ConfigurationError when config or the declaration is invalid.\n * @throws AuthenticationError when the token cannot be minted or the push fails.\n */\nexport async function publishManifest(\n config: ManifestPublisherConfig,\n declaration: AuthzDeclaration,\n): Promise<ManifestSyncSummary> {\n if (!config.issuer || !config.clientId || !config.clientSecret) {\n throw new ConfigurationError('Publishing a manifest needs issuer, clientId and clientSecret.');\n }\n\n const timeoutMs = config.timeoutMs ?? 10_000;\n assertSecureIssuer(config.issuer);\n const issuer = new URL(config.issuer);\n if (issuer.username || issuer.password || issuer.search || issuer.hash) {\n throw new ConfigurationError('The manifest issuer must not contain credentials, a query or a fragment.');\n }\n const manifest = await buildManifest(declaration);\n const discovery = new Discovery(config.issuer, timeoutMs, 3_600_000);\n\n const token = await mintToken(config, discovery, timeoutMs);\n\n const response = await fetchWithTimeout(\n `${config.issuer.replace(/\\/$/, '')}/api/v1/apps/manifest`,\n {\n method: 'POST',\n redirect: 'error',\n headers: {\n authorization: `Bearer ${token}`,\n accept: 'application/json',\n 'content-type': 'application/json',\n },\n body: JSON.stringify(manifest),\n },\n timeoutMs,\n );\n\n if (!response.ok) {\n throw new AuthenticationError(`Manifest push failed: HTTP ${response.status}`);\n }\n\n const json: unknown = await response.json().catch(() => {\n throw new AuthenticationError('Cbox ID returned an invalid manifest acknowledgement.');\n });\n const checksum = await sha256Hex(canonicalManifestJson(declaration.permissions ?? [], declaration.roles ?? []));\n if (json === null || typeof json !== 'object' || Array.isArray(json)) {\n throw new AuthenticationError('Cbox ID did not acknowledge the authorization manifest.');\n }\n const summary = json as ManifestSyncSummary;\n if (summary.client_id !== config.clientId || summary.version !== manifest.version || summary.checksum !== checksum\n || typeof summary.unchanged !== 'boolean' || !Number.isInteger(summary.roles_declared)\n || !Number.isInteger(summary.permissions_declared)\n || (summary.roles_declared ?? -1) < 0 || (summary.permissions_declared ?? -1) < 0\n || (!summary.unchanged && (summary.roles_declared !== manifest.roles.length\n || summary.permissions_declared !== manifest.permissions.length))) {\n throw new AuthenticationError('Cbox ID did not acknowledge this app and its complete authorization manifest.');\n }\n return summary;\n}\n\nasync function mintToken(\n config: ManifestPublisherConfig,\n discovery: Discovery,\n timeoutMs: number,\n): Promise<string> {\n const response = await fetchWithTimeout(\n await discovery.endpoint('token_endpoint'),\n {\n method: 'POST',\n headers: { 'content-type': 'application/x-www-form-urlencoded' },\n redirect: 'error',\n body: new URLSearchParams({\n grant_type: 'client_credentials',\n client_id: config.clientId,\n client_secret: config.clientSecret,\n scope: 'apps.manifest',\n }),\n },\n timeoutMs,\n );\n\n const json = (await response.json().catch(() => ({}))) as { access_token?: unknown };\n if (!response.ok || typeof json.access_token !== 'string' || json.access_token === '') {\n throw new AuthenticationError(\n 'Could not obtain an apps.manifest access token — check the client credentials and that the client holds the apps.manifest scope.',\n );\n }\n return json.access_token;\n}\n\n/**\n * A `feature:action` (or bare `feature`) key: lowercase, with dot/colon-separated segments.\n * The server's own pattern, restated so a bad key fails where it was written rather than\n * as a 4xx from a manifest push on deploy.\n */\nconst KEY_PATTERN = /^[a-z][a-z0-9_-]*(?:[.:][a-z0-9_-]+)*$/;\n\nfunction assertDeclaration(permissions: PermissionDefinition[], roles: RoleDefinition[]): void {\n const permissionKeys = new Set<string>();\n for (const permission of permissions) {\n if (!permission.key) {\n throw new ConfigurationError('Every permission needs a non-empty `key`.');\n }\n assertKey(permission.key, 'Permission');\n if (permissionKeys.has(permission.key)) {\n throw new ConfigurationError(`Permission \"${permission.key}\" is declared more than once.`);\n }\n assertFlag(permission.tenantAssignable, `Permission \"${permission.key}\"`);\n permissionKeys.add(permission.key);\n }\n\n const roleKeys = new Set<string>();\n for (const role of roles) {\n if (!role.key) {\n throw new ConfigurationError('Every role needs a non-empty `key`.');\n }\n assertKey(role.key, 'Role');\n if (!role.name) {\n throw new ConfigurationError(`Role \"${role.key}\" needs a non-empty \\`name\\`.`);\n }\n if (roleKeys.has(role.key)) {\n throw new ConfigurationError(`Role \"${role.key}\" is declared more than once.`);\n }\n assertFlag(role.tenantAssignable, `Role \"${role.key}\"`);\n roleKeys.add(role.key);\n for (const reference of role.permissions) {\n if (!permissionKeys.has(reference)) {\n throw new ConfigurationError(\n `Role \"${role.key}\" references permission \"${reference}\", which is not declared.`,\n );\n }\n }\n }\n}\n\nfunction assertKey(key: string, what: 'Permission' | 'Role'): void {\n if (!KEY_PATTERN.test(key)) {\n throw new ConfigurationError(\n `${what} key \"${key}\" is not a lowercase \\`feature:action\\` slug (e.g. \\`invoices:create\\`).`,\n );\n }\n}\n\n/**\n * `tenantAssignable`, when given, must be a real boolean.\n *\n * The type says so, but a catalog loaded from YAML or JSON arrives untyped, and the\n * string `\"false\"` is truthy: the one value that has to mean \"staff only\" would read as\n * \"every customer may grant this\". The server refuses a non-boolean role flag for the\n * same reason; refusing it here puts the failure in the deploy that introduced it.\n */\nfunction assertFlag(value: unknown, owner: string): void {\n if (value !== undefined && typeof value !== 'boolean') {\n throw new ConfigurationError(`${owner} \\`tenantAssignable\\` must be true or false.`);\n }\n}\n\n/**\n * A permission in the manifest's wire format: fixed key order, no `undefined` fields.\n *\n * `tenant_assignable` is written only when it is `true`, the non-default. The server reads\n * the snake_case key and nothing else, so this mapping is the whole difference between a\n * self-serve permission and an internal one — `tenantAssignable` sent as-is would be\n * ignored.\n */\nfunction wirePermission(permission: PermissionDefinition): ManifestPermission {\n return {\n key: permission.key,\n ...(permission.description === undefined ? {} : { description: permission.description }),\n ...(permission.tenantAssignable === true ? { tenant_assignable: true as const } : {}),\n };\n}\n\n/**\n * A role in the manifest's wire format: fixed key order, de-duplicated and sorted\n * permission refs, no `undefined` fields.\n *\n * `tenant_assignable: false` is written only for a staff role. THIS IS THE LINE THAT\n * KEEPS A STAFF ROLE STAFF-ONLY: the server defaults an absent key to assignable, so a\n * camelCase `tenantAssignable: false` passed straight through would publish your support\n * role as one every customer's administrator can hand out.\n */\nfunction wireRole(role: RoleDefinition): ManifestRole {\n return {\n key: role.key,\n name: role.name,\n ...(role.description === undefined ? {} : { description: role.description }),\n permissions: uniqueSorted(role.permissions),\n ...(role.tenantAssignable === false ? { tenant_assignable: false as const } : {}),\n };\n}\n\n/**\n * Serialize {permissions, roles} to the exact canonical JSON the PHP reference hashes,\n * so the `version` is byte-for-byte identical across every Cbox ID SDK. Matches PHP\n * `json_encode` defaults: object keys in insertion order, permissions and roles sorted\n * by key, each role's permission refs de-duplicated and sorted, an absent-or-empty\n * description emitted as `null`, forward slashes escaped as `\\/`, and every non-ASCII\n * code unit as `\\uXXXX`.\n *\n * Each `tenant_assignable` flag appears ONLY in its non-default state — `true` on a\n * permission, `false` on a role — exactly as the reference writes it. That keeps every\n * catalog that never mentions the flag hashing to the bytes it always has, while a\n * change to it still changes the version (an unchanged version is a skipped sync).\n */\nexport function canonicalManifestJson(\n permissions: PermissionDefinition[],\n roles: RoleDefinition[],\n): string {\n const canonical = {\n permissions: [...permissions]\n .sort((a, b) => byteCompare(a.key, b.key))\n .map((p) => ({\n key: p.key,\n description: emptyToNull(p.description),\n ...(p.tenantAssignable === true ? { tenant_assignable: true } : {}),\n })),\n roles: [...roles]\n .sort((a, b) => byteCompare(a.key, b.key))\n .map((r) => ({\n key: r.key,\n name: r.name,\n description: emptyToNull(r.description),\n permissions: uniqueSorted(r.permissions),\n ...(r.tenantAssignable === false ? { tenant_assignable: false } : {}),\n })),\n };\n return escapeLikePhp(JSON.stringify(canonical));\n}\n\n/**\n * Permission refs as the server stores them: each once, sorted. The server drops a\n * repeated ref before it hashes, so hashing the repeat here would give a `version` that\n * no server ever computes.\n */\nfunction uniqueSorted(values: readonly string[]): string[] {\n return [...new Set(values)].sort(byteCompare);\n}\n\n/** PHP treats an absent or empty description as `null` in the hashed catalog. */\nfunction emptyToNull(value: string | undefined): string | null {\n return value === undefined || value === '' ? null : value;\n}\n\n/** Byte-wise (code-unit) comparison — matches PHP `strcmp` on the ASCII-only keys. */\nfunction byteCompare(a: string, b: string): number {\n return a < b ? -1 : a > b ? 1 : 0;\n}\n\n/** Apply PHP `json_encode`'s default `\\/` slash and `\\uXXXX` non-ASCII escaping. */\nfunction escapeLikePhp(json: string): string {\n let out = '';\n for (let i = 0; i < json.length; i++) {\n const char = json.charAt(i);\n const code = json.charCodeAt(i);\n if (char === '/') {\n out += '\\\\/';\n } else if (code > 0x7f) {\n out += '\\\\u' + code.toString(16).padStart(4, '0');\n } else {\n out += char;\n }\n }\n return out;\n}\n\nasync function sha256Hex(input: string): Promise<string> {\n const digest = await crypto.subtle.digest('SHA-256', new TextEncoder().encode(input));\n return Array.from(new Uint8Array(digest))\n .map((byte) => byte.toString(16).padStart(2, '0'))\n .join('');\n}\n\nasync function fetchWithTimeout(url: string, init: RequestInit, timeoutMs: number): Promise<Response> {\n const controller = new AbortController();\n const timer = setTimeout(() => controller.abort(), timeoutMs);\n try {\n return await fetch(url, { ...init, signal: controller.signal });\n } catch {\n throw new AuthenticationError('Cbox ID manifest publication could not be verified.');\n } finally {\n clearTimeout(timer);\n }\n}\n\n/**\n * Refuse a legacy login declaration the server would refuse anyway.\n *\n * Checked in the SDK so it fails at build time, in the deploy that introduced it, rather\n * than as a 4xx from a manifest push somebody has to go and read. Both rules are the\n * server's and are restated here rather than inferred: https because a password in the\n * clear is readable by everything on the path, and a real secret because it is the only\n * thing proving a request came from Cbox ID.\n */\nfunction assertLegacyLogin(legacy: LegacyLoginDeclaration): void {\n if (!legacy.url.startsWith('https://')) {\n throw new ConfigurationError('legacyLogin.url must be https — a password must never cross the network in the clear.');\n }\n\n if (!legacy.secret || legacy.secret.length < 32) {\n throw new ConfigurationError('legacyLogin.secret must be at least 32 characters; it is what proves a request came from Cbox ID.');\n }\n}\n","import { AuthenticationError, ConfigurationError } from './errors.js';\nimport { assertSecureIssuer } from './issuer.js';\nimport type { OrganizationRole } from './claims.js';\n\nexport interface PermissionDecisionConfig {\n issuer: string;\n clientId: string;\n timeoutMs?: number;\n}\n\n/** A current server decision; shared membership tiers are not app grants. */\nexport class PermissionDecision {\n constructor(\n readonly subject: string,\n readonly organization: string | null,\n readonly clientId: string,\n readonly organizationRole: OrganizationRole | null,\n readonly organizationActive: boolean,\n readonly permissions: Readonly<Record<string, boolean>>,\n ) {}\n\n allows(permission: string): boolean {\n return this.organizationActive && this.permissions[permission] === true;\n }\n\n allowed(): boolean {\n const values = Object.values(this.permissions);\n return this.organizationActive && values.length > 0 && values.every(value => value === true);\n }\n}\n\n/** No positive cache: check each request and again when queued work starts. */\nexport async function checkPermissions(\n config: PermissionDecisionConfig,\n accessToken: string,\n subject: string,\n organization: string | null,\n permissions: readonly string[],\n): Promise<PermissionDecision> {\n assertSecureIssuer(config.issuer);\n const issuer = new URL(config.issuer);\n if (issuer.username || issuer.password || issuer.search || issuer.hash || !config.clientId\n || !subject || organization === '' || !accessToken || accessToken.length > 32768\n || /[\\x00-\\x20\\x7f]/.test(accessToken) || !permissions.length || permissions.length > 50\n || permissions.some(permission => !permission.trim() || new TextEncoder().encode(permission).length > 255)) {\n throw new ConfigurationError('Permission decision request is not configured or valid.');\n }\n const requested = [...new Set(permissions)];\n try {\n const response = await fetch(`${config.issuer.replace(/\\/$/, '')}/oauth/decisions`, {\n method: 'POST', redirect: 'error', cache: 'no-store',\n signal: AbortSignal.timeout(Math.max(1, config.timeoutMs ?? 10_000)),\n headers: { authorization: `Bearer ${accessToken}`, accept: 'application/json', 'content-type': 'application/json' },\n body: JSON.stringify({ subject, org: organization, permission: requested }),\n });\n if (response.status !== 200) {\n await response.body?.cancel();\n throw new AuthenticationError('Permission decision could not be verified.', undefined, undefined, response.status);\n }\n const reader = response.body?.getReader();\n if (!reader) throw new AuthenticationError('Permission decision response is invalid.');\n let size = 0;\n let raw = '';\n const decoder = new TextDecoder();\n try {\n for (;;) {\n const { value, done } = await reader.read();\n if (done) break;\n size += value.byteLength;\n if (size > 65536) throw new AuthenticationError('Permission decision response exceeded its limit.');\n raw += decoder.decode(value, { stream: true });\n }\n raw += decoder.decode();\n } finally {\n await reader.cancel();\n reader.releaseLock();\n }\n const data: unknown = JSON.parse(raw);\n if (!record(data) || !record(data.subject) || data.mode !== 'rbac'\n || data.subject.type !== 'user' || data.subject.id !== subject\n || data.organization !== organization || data.client_id !== config.clientId\n || typeof data.organization_active !== 'boolean' || typeof data.allowed !== 'boolean'\n || !(data.org_role === null || (typeof data.org_role === 'string'\n && ['owner', 'admin', 'developer', 'member', 'viewer'].includes(data.org_role)))\n || !Array.isArray(data.results) || data.results.length !== requested.length) {\n throw new AuthenticationError('Permission decision response binding is invalid.');\n }\n const checks: Record<string, boolean> = Object.create(null) as Record<string, boolean>;\n for (const result of data.results as unknown[]) {\n if (!record(result) || typeof result.permission !== 'string' || typeof result.allowed !== 'boolean'\n || !requested.includes(result.permission) || Object.hasOwn(checks, result.permission)) {\n throw new AuthenticationError('Permission decision result is invalid.');\n }\n checks[result.permission] = result.allowed;\n }\n const decision = new PermissionDecision(subject, organization, config.clientId,\n data.org_role as OrganizationRole | null, data.organization_active, Object.freeze(checks));\n if (data.allowed !== decision.allowed()) throw new AuthenticationError('Permission decision result is inconsistent.');\n return decision;\n } catch (error) {\n if (error instanceof AuthenticationError) throw error;\n throw new AuthenticationError('Permission decision could not be verified.');\n }\n}\n\nfunction record(value: unknown): value is Record<string, unknown> {\n return value !== null && typeof value === 'object' && !Array.isArray(value);\n}\n"]}