kavachos 0.0.2 → 0.0.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/agent/index.d.ts +4 -5
- package/dist/agent/index.js +2 -2
- package/dist/audit/index.d.ts +3 -4
- package/dist/audit/index.js +2 -2
- package/dist/auth/index.d.ts +1719 -2
- package/dist/auth/index.js +2 -1
- package/dist/{chunk-I4J4KKKK.js → chunk-5DT4DN4Y.js} +9 -3
- package/dist/chunk-5DT4DN4Y.js.map +1 -0
- package/dist/chunk-KL6XW4S4.js +10774 -0
- package/dist/chunk-KL6XW4S4.js.map +1 -0
- package/dist/{chunk-DEVV32BE.js → chunk-OVGNZ5OX.js} +3 -3
- package/dist/{chunk-DEVV32BE.js.map → chunk-OVGNZ5OX.js.map} +1 -1
- package/dist/{chunk-N7VZO6SP.js → chunk-SJGSPIAD.js} +3 -3
- package/dist/{chunk-N7VZO6SP.js.map → chunk-SJGSPIAD.js.map} +1 -1
- package/dist/chunk-V66UUIA7.js +480 -0
- package/dist/chunk-V66UUIA7.js.map +1 -0
- package/dist/index.d.ts +1125 -14
- package/dist/index.js +2986 -111
- package/dist/index.js.map +1 -1
- package/dist/mcp/index.d.ts +2 -2
- package/dist/permission/index.d.ts +4 -5
- package/dist/permission/index.js +2 -2
- package/dist/types-Xk83hv4O.d.ts +7759 -0
- package/dist/{types-B4sQA44H.d.ts → types-mwupB57A.d.ts} +5 -5
- package/package.json +1 -1
- package/dist/chunk-7RKVTHFC.js +0 -96
- package/dist/chunk-7RKVTHFC.js.map +0 -1
- package/dist/chunk-I4J4KKKK.js.map +0 -1
- package/dist/chunk-UEE7OYLG.js +0 -161
- package/dist/chunk-UEE7OYLG.js.map +0 -1
- package/dist/types-WP-mKSdQ.d.ts +0 -2349
- package/dist/types-_7hIICee.d.ts +0 -52
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/auth/adapters/bearer.ts","../src/auth/adapters/custom.ts","../src/auth/adapters/header.ts","../src/auth/additional-fields.ts","../src/auth/admin.ts","../src/session/session.ts","../src/auth/admin-plugin.ts","../src/auth/anonymous.ts","../src/auth/anonymous-plugin.ts","../src/auth/api-key-manager.ts","../src/auth/api-key-plugin.ts","../src/auth/captcha.ts","../src/auth/custom-session.ts","../src/auth/device-auth.ts","../src/auth/email-otp.ts","../src/auth/email-otp-plugin.ts","../src/auth/gdpr.ts","../src/auth/gdpr-plugin.ts","../src/auth/hibp.ts","../src/auth/jwt-session.ts","../src/auth/last-login.ts","../src/auth/magic-link.ts","../src/auth/rate-limit-middleware.ts","../src/auth/rate-limiter.ts","../src/auth/magic-link-plugin.ts","../src/auth/oauth/pkce.ts","../src/auth/oauth-proxy.ts","../src/auth/oauth-proxy-plugin.ts","../src/auth/oidc-provider.ts","../src/auth/one-tap.ts","../src/auth/one-tap-plugin.ts","../src/auth/one-time-token.ts","../src/auth/openapi.ts","../src/auth/organization.ts","../src/auth/organization-plugin.ts","../src/auth/cbor.ts","../src/auth/passkey.ts","../src/auth/passkey-plugin.ts","../src/auth/phone.ts","../src/auth/polar.ts","../src/auth/polar-plugin.ts","../src/auth/scim.ts","../src/auth/scim-plugin.ts","../src/auth/siwe.ts","../src/auth/sso.ts","../src/auth/stripe.ts","../src/auth/stripe-plugin.ts","../src/auth/totp.ts","../src/auth/totp-plugin.ts","../src/auth/trusted-device.ts","../src/auth/username.ts","../src/auth/webhooks.ts"],"names":["errors","eq","json","createSecretKey","jwtVerify","jsonResponse","randomUUID","and","parseBody","apiKeys","randomBytes","DEFAULT_CODE_LENGTH","DEFAULT_CODE_EXPIRY_SECONDS","createHash","sql","z","SignJWT","gt","makeError","oldest","resetAt","getJwks","hashToken","lt","DEFAULT_MAX_ATTEMPTS","hashCode","timingSafeEqual","generateNumericCode","b","like","NodeTextEncoder","createRemoteJWKSet","verifyWebhookSignature","result","generateId","createHmac"],"mappings":"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","file":"chunk-KL6XW4S4.js","sourcesContent":["/**\n * JWT bearer-token auth adapter.\n *\n * Verifies a JWT from the `Authorization: Bearer <token>` header using a\n * symmetric secret (HS256/HS384/HS512). Extracts `sub`, `email`, `name`, and\n * `picture` from the payload and returns them as a `ResolvedUser`.\n *\n * @example\n * ```typescript\n * import { bearerAuth } from 'kavachos/auth';\n *\n * const adapter = bearerAuth({\n * secret: process.env.JWT_SECRET,\n * issuer: 'https://my-app.example.com',\n * audience: 'kavachos',\n * });\n * ```\n */\n\nimport { createSecretKey } from \"node:crypto\";\nimport { jwtVerify } from \"jose\";\nimport { z } from \"zod\";\nimport type { AuthAdapter, ResolvedUser } from \"../types.js\";\n\n// ---------------------------------------------------------------------------\n// Options schema\n// ---------------------------------------------------------------------------\n\nconst BearerAuthOptionsSchema = z.object({\n\t/**\n\t * Secret used to verify HS256/HS384/HS512 tokens.\n\t * Must be at least 32 characters.\n\t */\n\tsecret: z.string().min(1, \"secret is required\"),\n\t/** Expected `iss` claim. Omit to skip issuer validation. */\n\tissuer: z.string().optional(),\n\t/** Expected `aud` claim. Omit to skip audience validation. */\n\taudience: z.string().optional(),\n});\n\nexport type BearerAuthOptions = z.infer<typeof BearerAuthOptionsSchema>;\n\n// ---------------------------------------------------------------------------\n// Payload schema – only the fields KavachOS cares about\n// ---------------------------------------------------------------------------\n\nconst JwtPayloadSchema = z.object({\n\tsub: z.string(),\n\temail: z.string().optional(),\n\tname: z.string().optional(),\n\t// Both `picture` (OIDC) and `image` (custom) are accepted.\n\tpicture: z.string().optional(),\n\timage: z.string().optional(),\n});\n\n// ---------------------------------------------------------------------------\n// Factory\n// ---------------------------------------------------------------------------\n\n/**\n * Create an `AuthAdapter` that validates a JWT from the `Authorization: Bearer`\n * header and maps its claims to a `ResolvedUser`.\n *\n * Returns `null` when:\n * - No `Authorization` header is present\n * - The header does not use the `Bearer` scheme\n * - The JWT signature is invalid, the token is expired, or claims do not match\n * the configured `issuer` / `audience`\n */\nexport function bearerAuth(options: BearerAuthOptions): AuthAdapter {\n\tconst parsed = BearerAuthOptionsSchema.parse(options);\n\n\t// Pre-compute the KeyObject once so we don't recreate it per request.\n\tconst keyObject = createSecretKey(Buffer.from(parsed.secret, \"utf-8\"));\n\n\treturn {\n\t\tasync resolveUser(request: Request): Promise<ResolvedUser | null> {\n\t\t\tconst authHeader = request.headers.get(\"authorization\");\n\t\t\tif (!authHeader) return null;\n\n\t\t\tconst [scheme, token] = authHeader.split(\" \");\n\t\t\tif (scheme?.toLowerCase() !== \"bearer\" || !token) return null;\n\n\t\t\ttry {\n\t\t\t\tconst { payload } = await jwtVerify(token, keyObject, {\n\t\t\t\t\tissuer: parsed.issuer,\n\t\t\t\t\taudience: parsed.audience,\n\t\t\t\t});\n\n\t\t\t\tconst claims = JwtPayloadSchema.safeParse(payload);\n\t\t\t\tif (!claims.success) return null;\n\n\t\t\t\tconst { sub, email, name, picture, image } = claims.data;\n\n\t\t\t\t// Strip undefined fields from metadata so callers get a clean object.\n\t\t\t\tconst metadata: Record<string, unknown> = {};\n\t\t\t\tfor (const [k, v] of Object.entries(payload)) {\n\t\t\t\t\tif (\n\t\t\t\t\t\t![\n\t\t\t\t\t\t\t\"sub\",\n\t\t\t\t\t\t\t\"email\",\n\t\t\t\t\t\t\t\"name\",\n\t\t\t\t\t\t\t\"picture\",\n\t\t\t\t\t\t\t\"image\",\n\t\t\t\t\t\t\t\"iat\",\n\t\t\t\t\t\t\t\"exp\",\n\t\t\t\t\t\t\t\"iss\",\n\t\t\t\t\t\t\t\"aud\",\n\t\t\t\t\t\t\t\"nbf\",\n\t\t\t\t\t\t\t\"jti\",\n\t\t\t\t\t\t].includes(k)\n\t\t\t\t\t) {\n\t\t\t\t\t\tmetadata[k] = v;\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\treturn {\n\t\t\t\t\tid: sub,\n\t\t\t\t\t...(email !== undefined && { email }),\n\t\t\t\t\t...(name !== undefined && { name }),\n\t\t\t\t\t...(picture !== undefined || image !== undefined ? { image: picture ?? image } : {}),\n\t\t\t\t\t...(Object.keys(metadata).length > 0 && { metadata }),\n\t\t\t\t};\n\t\t\t} catch {\n\t\t\t\t// Token verification failed (expired, bad signature, wrong issuer, etc.)\n\t\t\t\treturn null;\n\t\t\t}\n\t\t},\n\t};\n}\n","/**\n * Custom resolver auth adapter.\n *\n * Wraps an arbitrary resolver function as an `AuthAdapter`. Use this when\n * you need to integrate with an auth provider that does not have a built-in\n * adapter (e.g. better-auth, Auth.js, Clerk, Supabase Auth, etc.).\n *\n * @example Clerk session cookie\n * ```typescript\n * import { customAuth } from 'kavachos/auth';\n * import { clerkClient } from '@clerk/clerk-sdk-node';\n *\n * const adapter = customAuth(async (request) => {\n * const sessionToken = request.headers.get('cookie')\n * ?.split('; ')\n * .find(c => c.startsWith('__session='))\n * ?.split('=')[1];\n *\n * if (!sessionToken) return null;\n *\n * const session = await clerkClient.sessions.verifySession('', sessionToken);\n * return { id: session.userId };\n * });\n * ```\n *\n * @example better-auth\n * ```typescript\n * import { customAuth } from 'kavachos/auth';\n * import { auth } from './lib/auth'; // your better-auth instance\n *\n * const adapter = customAuth(async (request) => {\n * const session = await auth.api.getSession({ headers: request.headers });\n * if (!session?.user) return null;\n * return {\n * id: session.user.id,\n * email: session.user.email ?? undefined,\n * name: session.user.name ?? undefined,\n * image: session.user.image ?? undefined,\n * };\n * });\n * ```\n */\n\nimport type { AuthAdapter, ResolvedUser } from \"../types.js\";\n\n/**\n * Create an `AuthAdapter` from a custom resolver function.\n *\n * The resolver receives the raw `Request` and must return either a\n * `ResolvedUser` or `null` (unauthenticated).\n */\nexport function customAuth(\n\tresolver: (request: Request) => Promise<ResolvedUser | null>,\n): AuthAdapter {\n\treturn {\n\t\tresolveUser: resolver,\n\t};\n}\n","/**\n * Header-based auth adapter.\n *\n * Extracts the user ID from a trusted request header. Designed for services\n * deployed behind an auth proxy (e.g. Nginx, Cloudflare Access, AWS ALB) that\n * injects a verified user-identity header before forwarding requests.\n *\n * @example Default header (`X-User-Id`)\n * ```typescript\n * import { headerAuth } from 'kavachos/auth';\n *\n * const adapter = headerAuth();\n * ```\n *\n * @example Custom header\n * ```typescript\n * const adapter = headerAuth({ header: 'X-Authenticated-User' });\n * ```\n *\n * IMPORTANT: Only use this adapter when the header cannot be forged by the\n * client (i.e. the upstream proxy strips or overrides it).\n */\n\nimport type { AuthAdapter, ResolvedUser } from \"../types.js\";\n\nexport interface HeaderAuthOptions {\n\t/**\n\t * Name of the HTTP header that carries the user ID.\n\t * Defaults to `X-User-Id`.\n\t */\n\theader?: string;\n}\n\n/**\n * Create an `AuthAdapter` that extracts the user identity from a request header.\n *\n * Returns `null` when the header is absent or its value is empty.\n */\nexport function headerAuth(options?: HeaderAuthOptions): AuthAdapter {\n\tconst headerName = options?.header ?? \"X-User-Id\";\n\t// Normalise to lower-case for case-insensitive lookup via the Headers API.\n\tconst normalised = headerName.toLowerCase();\n\n\treturn {\n\t\tasync resolveUser(request: Request): Promise<ResolvedUser | null> {\n\t\t\tconst value = request.headers.get(normalised);\n\t\t\tif (!value || value.trim() === \"\") return null;\n\n\t\t\treturn { id: value.trim() };\n\t\t},\n\t};\n}\n","/**\n * Additional user/session fields plugin for KavachOS.\n *\n * Lets callers extend the user and session schemas with typed custom fields\n * without writing any database migrations. Fields are stored in the existing\n * `user.metadata` or `session.metadata` JSON columns.\n *\n * Field types: `string`, `number`, `boolean`, `json`.\n * Required fields must be present when calling `setUserFields`.\n * Fields not in the schema are rejected during `validate()`.\n *\n * @example\n * ```typescript\n * import { createKavach } from 'kavachos';\n * import { additionalFields } from 'kavachos/auth';\n *\n * const kavach = await createKavach({\n * database: { provider: 'sqlite', url: 'kavach.db' },\n * plugins: [\n * additionalFields({\n * user: {\n * plan: { type: 'string', required: false, defaultValue: 'free' },\n * credits: { type: 'number', required: false, defaultValue: 0 },\n * },\n * }),\n * ],\n * });\n *\n * const mod = kavach.plugins.getContext().additionalFields as AdditionalFieldsModule;\n * await mod.setUserFields(userId, { plan: 'pro', credits: 100 });\n * const fields = await mod.getUserFields(userId);\n * // => { plan: 'pro', credits: 100 }\n * ```\n */\n\nimport { eq } from \"drizzle-orm\";\nimport type { Database } from \"../db/database.js\";\nimport { sessions, users } from \"../db/schema.js\";\nimport type { KavachPlugin } from \"../plugin/types.js\";\n\n// ---------------------------------------------------------------------------\n// Public types\n// ---------------------------------------------------------------------------\n\nexport interface FieldDefinition {\n\ttype: \"string\" | \"number\" | \"boolean\" | \"json\";\n\trequired?: boolean;\n\tdefaultValue?: unknown;\n}\n\nexport interface AdditionalFieldsConfig {\n\t/** Custom fields for users (stored in user.metadata). */\n\tuser?: Record<string, FieldDefinition>;\n\t/** Custom fields for sessions (stored in session.metadata). */\n\tsession?: Record<string, FieldDefinition>;\n}\n\nexport interface ValidationResult {\n\tvalid: boolean;\n\terrors?: string[];\n}\n\nexport interface AdditionalFieldsModule {\n\t/**\n\t * Return the additional fields stored in `user.metadata` for the given user.\n\t *\n\t * Fields missing from the stored metadata are filled with their `defaultValue`\n\t * (if one is defined in the schema).\n\t */\n\tgetUserFields(userId: string): Promise<Record<string, unknown>>;\n\t/**\n\t * Write `fields` into `user.metadata`, merging with any already-stored values.\n\t *\n\t * Validates against the `user` schema before writing.\n\t * Throws when the user does not exist or validation fails.\n\t */\n\tsetUserFields(userId: string, fields: Record<string, unknown>): Promise<void>;\n\t/**\n\t * Return the additional fields stored in `session.metadata` for the given session.\n\t */\n\tgetSessionFields(sessionId: string): Promise<Record<string, unknown>>;\n\t/**\n\t * Write `fields` into `session.metadata`, merging with any already-stored values.\n\t *\n\t * Validates against the `session` schema before writing.\n\t * Throws when the session does not exist or validation fails.\n\t */\n\tsetSessionFields(sessionId: string, fields: Record<string, unknown>): Promise<void>;\n\t/**\n\t * Validate a field map against the \"user\" or \"session\" schema.\n\t *\n\t * Returns `{ valid: true }` on success or `{ valid: false, errors: [...] }` on\n\t * failure. Does not throw.\n\t */\n\tvalidate(fields: Record<string, unknown>, schema: \"user\" | \"session\"): ValidationResult;\n}\n\n// ---------------------------------------------------------------------------\n// Validation\n// ---------------------------------------------------------------------------\n\nconst TYPE_CHECKS: Record<FieldDefinition[\"type\"], (v: unknown) => boolean> = {\n\tstring: (v) => typeof v === \"string\",\n\tnumber: (v) => typeof v === \"number\",\n\tboolean: (v) => typeof v === \"boolean\",\n\tjson: (v) => v !== null && v !== undefined,\n};\n\nfunction validateFields(\n\tfields: Record<string, unknown>,\n\tschema: Record<string, FieldDefinition> | undefined,\n): ValidationResult {\n\tif (!schema) return { valid: true };\n\n\tconst errors: string[] = [];\n\n\t// Check required fields are present\n\tfor (const [key, def] of Object.entries(schema)) {\n\t\tif (def.required && !(key in fields)) {\n\t\t\terrors.push(`Field \"${key}\" is required`);\n\t\t}\n\t}\n\n\t// Check provided fields are in schema and match the declared type\n\tfor (const [key, value] of Object.entries(fields)) {\n\t\tconst def = schema[key];\n\t\tif (!def) {\n\t\t\terrors.push(`Field \"${key}\" is not defined in the schema`);\n\t\t\tcontinue;\n\t\t}\n\t\tif (!TYPE_CHECKS[def.type](value)) {\n\t\t\terrors.push(`Field \"${key}\" must be of type ${def.type}`);\n\t\t}\n\t}\n\n\treturn errors.length === 0 ? { valid: true } : { valid: false, errors };\n}\n\n// ---------------------------------------------------------------------------\n// Default value hydration\n// ---------------------------------------------------------------------------\n\nfunction applyDefaults(\n\tstored: Record<string, unknown>,\n\tschema: Record<string, FieldDefinition> | undefined,\n): Record<string, unknown> {\n\tif (!schema) return stored;\n\n\tconst result: Record<string, unknown> = { ...stored };\n\tfor (const [key, def] of Object.entries(schema)) {\n\t\tif (!(key in result) && def.defaultValue !== undefined) {\n\t\t\tresult[key] = def.defaultValue;\n\t\t}\n\t}\n\treturn result;\n}\n\n// ---------------------------------------------------------------------------\n// Module factory\n// ---------------------------------------------------------------------------\n\nexport function createAdditionalFieldsModule(\n\tconfig: AdditionalFieldsConfig,\n\tdb: Database,\n): AdditionalFieldsModule {\n\tfunction validate(\n\t\tfields: Record<string, unknown>,\n\t\tschemaKey: \"user\" | \"session\",\n\t): ValidationResult {\n\t\treturn validateFields(fields, schemaKey === \"user\" ? config.user : config.session);\n\t}\n\n\t// ── User fields ────────────────────────────────────────────────────────\n\n\tasync function getUserFields(userId: string): Promise<Record<string, unknown>> {\n\t\tconst rows = await db\n\t\t\t.select({ metadata: users.metadata })\n\t\t\t.from(users)\n\t\t\t.where(eq(users.id, userId));\n\n\t\tconst row = rows[0];\n\t\tconst meta = row?.metadata ?? {};\n\t\tconst stored =\n\t\t\tmeta !== null &&\n\t\t\ttypeof meta === \"object\" &&\n\t\t\t!Array.isArray(meta) &&\n\t\t\t\"additionalFields\" in meta &&\n\t\t\tmeta.additionalFields !== null &&\n\t\t\ttypeof meta.additionalFields === \"object\" &&\n\t\t\t!Array.isArray(meta.additionalFields)\n\t\t\t\t? (meta.additionalFields as Record<string, unknown>)\n\t\t\t\t: {};\n\n\t\treturn applyDefaults(stored, config.user);\n\t}\n\n\tasync function setUserFields(userId: string, fields: Record<string, unknown>): Promise<void> {\n\t\tconst result = validate(fields, \"user\");\n\t\tif (!result.valid) {\n\t\t\tthrow new Error(\n\t\t\t\t`AdditionalFieldsModule: validation failed — ${(result.errors ?? []).join(\", \")}`,\n\t\t\t);\n\t\t}\n\n\t\tconst rows = await db\n\t\t\t.select({ metadata: users.metadata })\n\t\t\t.from(users)\n\t\t\t.where(eq(users.id, userId));\n\n\t\tif (!rows[0]) {\n\t\t\tthrow new Error(`AdditionalFieldsModule: user not found: ${userId}`);\n\t\t}\n\n\t\tconst existing = (rows[0].metadata ?? {}) as Record<string, unknown>;\n\t\tconst existingAdditional =\n\t\t\texisting.additionalFields !== null &&\n\t\t\texisting.additionalFields !== undefined &&\n\t\t\ttypeof existing.additionalFields === \"object\" &&\n\t\t\t!Array.isArray(existing.additionalFields)\n\t\t\t\t? (existing.additionalFields as Record<string, unknown>)\n\t\t\t\t: {};\n\n\t\tconst updatedMeta: Record<string, unknown> = {\n\t\t\t...existing,\n\t\t\tadditionalFields: { ...existingAdditional, ...fields },\n\t\t};\n\n\t\tawait db\n\t\t\t.update(users)\n\t\t\t.set({ metadata: updatedMeta, updatedAt: new Date() })\n\t\t\t.where(eq(users.id, userId));\n\t}\n\n\t// ── Session fields ─────────────────────────────────────────────────────\n\n\tasync function getSessionFields(sessionId: string): Promise<Record<string, unknown>> {\n\t\tconst rows = await db\n\t\t\t.select({ metadata: sessions.metadata })\n\t\t\t.from(sessions)\n\t\t\t.where(eq(sessions.id, sessionId));\n\n\t\tconst row = rows[0];\n\t\tconst meta = row?.metadata ?? {};\n\t\tconst stored =\n\t\t\tmeta !== null &&\n\t\t\ttypeof meta === \"object\" &&\n\t\t\t!Array.isArray(meta) &&\n\t\t\t\"additionalFields\" in meta &&\n\t\t\tmeta.additionalFields !== null &&\n\t\t\ttypeof meta.additionalFields === \"object\" &&\n\t\t\t!Array.isArray(meta.additionalFields)\n\t\t\t\t? (meta.additionalFields as Record<string, unknown>)\n\t\t\t\t: {};\n\n\t\treturn applyDefaults(stored, config.session);\n\t}\n\n\tasync function setSessionFields(\n\t\tsessionId: string,\n\t\tfields: Record<string, unknown>,\n\t): Promise<void> {\n\t\tconst result = validate(fields, \"session\");\n\t\tif (!result.valid) {\n\t\t\tthrow new Error(\n\t\t\t\t`AdditionalFieldsModule: validation failed — ${(result.errors ?? []).join(\", \")}`,\n\t\t\t);\n\t\t}\n\n\t\tconst rows = await db\n\t\t\t.select({ metadata: sessions.metadata })\n\t\t\t.from(sessions)\n\t\t\t.where(eq(sessions.id, sessionId));\n\n\t\tif (!rows[0]) {\n\t\t\tthrow new Error(`AdditionalFieldsModule: session not found: ${sessionId}`);\n\t\t}\n\n\t\tconst existing = (rows[0].metadata ?? {}) as Record<string, unknown>;\n\t\tconst existingAdditional =\n\t\t\texisting.additionalFields !== null &&\n\t\t\texisting.additionalFields !== undefined &&\n\t\t\ttypeof existing.additionalFields === \"object\" &&\n\t\t\t!Array.isArray(existing.additionalFields)\n\t\t\t\t? (existing.additionalFields as Record<string, unknown>)\n\t\t\t\t: {};\n\n\t\tconst updatedMeta: Record<string, unknown> = {\n\t\t\t...existing,\n\t\t\tadditionalFields: { ...existingAdditional, ...fields },\n\t\t};\n\n\t\tawait db.update(sessions).set({ metadata: updatedMeta }).where(eq(sessions.id, sessionId));\n\t}\n\n\treturn { getUserFields, setUserFields, getSessionFields, setSessionFields, validate };\n}\n\n// ---------------------------------------------------------------------------\n// Plugin factory\n// ---------------------------------------------------------------------------\n\nexport function additionalFields(config: AdditionalFieldsConfig = {}): KavachPlugin {\n\treturn {\n\t\tid: \"kavach-additional-fields\",\n\n\t\tasync init(ctx) {\n\t\t\tconst mod = createAdditionalFieldsModule(config, ctx.db);\n\n\t\t\t// GET /auth/users/fields?userId=<id>\n\t\t\tctx.addEndpoint({\n\t\t\t\tmethod: \"GET\",\n\t\t\t\tpath: \"/auth/users/fields\",\n\t\t\t\tmetadata: {\n\t\t\t\t\trequireAuth: true,\n\t\t\t\t\tdescription: \"Get additional fields for a user\",\n\t\t\t\t},\n\t\t\t\tasync handler(request, _endpointCtx) {\n\t\t\t\t\tconst url = new URL(request.url);\n\t\t\t\t\tconst userId = url.searchParams.get(\"userId\");\n\t\t\t\t\tif (!userId) {\n\t\t\t\t\t\treturn jsonResponse({ error: \"Missing required query parameter: userId\" }, 400);\n\t\t\t\t\t}\n\n\t\t\t\t\ttry {\n\t\t\t\t\t\tconst fields = await mod.getUserFields(userId);\n\t\t\t\t\t\treturn jsonResponse({ fields });\n\t\t\t\t\t} catch (err) {\n\t\t\t\t\t\treturn jsonResponse(\n\t\t\t\t\t\t\t{ error: err instanceof Error ? err.message : \"Failed to get user fields\" },\n\t\t\t\t\t\t\t500,\n\t\t\t\t\t\t);\n\t\t\t\t\t}\n\t\t\t\t},\n\t\t\t});\n\n\t\t\t// PUT /auth/users/fields\n\t\t\tctx.addEndpoint({\n\t\t\t\tmethod: \"PUT\",\n\t\t\t\tpath: \"/auth/users/fields\",\n\t\t\t\tmetadata: {\n\t\t\t\t\trequireAuth: true,\n\t\t\t\t\tdescription: \"Set additional fields on a user\",\n\t\t\t\t},\n\t\t\t\tasync handler(request, _endpointCtx) {\n\t\t\t\t\tlet body: Record<string, unknown>;\n\t\t\t\t\ttry {\n\t\t\t\t\t\tbody = (await request.json()) as Record<string, unknown>;\n\t\t\t\t\t} catch {\n\t\t\t\t\t\treturn jsonResponse({ error: \"Invalid JSON body\" }, 400);\n\t\t\t\t\t}\n\n\t\t\t\t\tconst userId = typeof body.userId === \"string\" ? body.userId : null;\n\t\t\t\t\tif (!userId) {\n\t\t\t\t\t\treturn jsonResponse({ error: \"Missing required field: userId\" }, 400);\n\t\t\t\t\t}\n\n\t\t\t\t\tconst fields =\n\t\t\t\t\t\tbody.fields !== null &&\n\t\t\t\t\t\tbody.fields !== undefined &&\n\t\t\t\t\t\ttypeof body.fields === \"object\" &&\n\t\t\t\t\t\t!Array.isArray(body.fields)\n\t\t\t\t\t\t\t? (body.fields as Record<string, unknown>)\n\t\t\t\t\t\t\t: null;\n\n\t\t\t\t\tif (!fields) {\n\t\t\t\t\t\treturn jsonResponse({ error: \"Missing or invalid field: fields\" }, 400);\n\t\t\t\t\t}\n\n\t\t\t\t\ttry {\n\t\t\t\t\t\tawait mod.setUserFields(userId, fields);\n\t\t\t\t\t\treturn jsonResponse({ updated: true });\n\t\t\t\t\t} catch (err) {\n\t\t\t\t\t\tconst message = err instanceof Error ? err.message : \"Update failed\";\n\t\t\t\t\t\tconst status = message.includes(\"not found\")\n\t\t\t\t\t\t\t? 404\n\t\t\t\t\t\t\t: message.includes(\"validation failed\")\n\t\t\t\t\t\t\t\t? 422\n\t\t\t\t\t\t\t\t: 500;\n\t\t\t\t\t\treturn jsonResponse({ error: message }, status);\n\t\t\t\t\t}\n\t\t\t\t},\n\t\t\t});\n\n\t\t\t// POST /auth/fields/validate\n\t\t\tctx.addEndpoint({\n\t\t\t\tmethod: \"POST\",\n\t\t\t\tpath: \"/auth/fields/validate\",\n\t\t\t\tmetadata: {\n\t\t\t\t\tdescription: \"Validate fields against the user or session schema\",\n\t\t\t\t},\n\t\t\t\tasync handler(request, _endpointCtx) {\n\t\t\t\t\tlet body: Record<string, unknown>;\n\t\t\t\t\ttry {\n\t\t\t\t\t\tbody = (await request.json()) as Record<string, unknown>;\n\t\t\t\t\t} catch {\n\t\t\t\t\t\treturn jsonResponse({ error: \"Invalid JSON body\" }, 400);\n\t\t\t\t\t}\n\n\t\t\t\t\tconst schema = body.schema === \"user\" || body.schema === \"session\" ? body.schema : null;\n\t\t\t\t\tif (!schema) {\n\t\t\t\t\t\treturn jsonResponse(\n\t\t\t\t\t\t\t{ error: 'Missing or invalid field: schema (must be \"user\" or \"session\")' },\n\t\t\t\t\t\t\t400,\n\t\t\t\t\t\t);\n\t\t\t\t\t}\n\n\t\t\t\t\tconst fields =\n\t\t\t\t\t\tbody.fields !== null &&\n\t\t\t\t\t\tbody.fields !== undefined &&\n\t\t\t\t\t\ttypeof body.fields === \"object\" &&\n\t\t\t\t\t\t!Array.isArray(body.fields)\n\t\t\t\t\t\t\t? (body.fields as Record<string, unknown>)\n\t\t\t\t\t\t\t: null;\n\n\t\t\t\t\tif (!fields) {\n\t\t\t\t\t\treturn jsonResponse({ error: \"Missing or invalid field: fields\" }, 400);\n\t\t\t\t\t}\n\n\t\t\t\t\tconst result = mod.validate(fields, schema);\n\t\t\t\t\treturn jsonResponse(result, result.valid ? 200 : 422);\n\t\t\t\t},\n\t\t\t});\n\n\t\t\treturn {\n\t\t\t\tcontext: { additionalFields: mod },\n\t\t\t};\n\t\t},\n\t};\n}\n\n// ---------------------------------------------------------------------------\n// Helpers\n// ---------------------------------------------------------------------------\n\nfunction jsonResponse(body: unknown, status = 200): Response {\n\treturn new Response(JSON.stringify(body), {\n\t\tstatus,\n\t\theaders: { \"Content-Type\": \"application/json\" },\n\t});\n}\n","/**\n * Admin module for KavachOS.\n *\n * Global admin operations: user listing, banning, impersonation, and deletion.\n * Admin access is determined by the `adminUserIds` config list.\n *\n * @example\n * ```typescript\n * const kavach = await createKavach({\n * database: { provider: 'sqlite', url: 'kavach.db' },\n * admin: { adminUserIds: ['user_abc123'], allowImpersonation: true },\n * });\n *\n * await kavach.admin.banUser('user_xyz', 'Violating terms');\n * const { session } = await kavach.admin.impersonate('user_abc123', 'user_xyz');\n * ```\n */\n\nimport { eq, like, sql } from \"drizzle-orm\";\nimport type { Database } from \"../db/database.js\";\nimport { agents, sessions, users } from \"../db/schema.js\";\nimport type { SessionManager } from \"../session/session.js\";\n\n// ---------------------------------------------------------------------------\n// Public types\n// ---------------------------------------------------------------------------\n\nexport interface AdminConfig {\n\t/** User IDs that are global admins */\n\tadminUserIds?: string[];\n\t/** Allow impersonation (default: true) */\n\tallowImpersonation?: boolean;\n\t/** Impersonation session TTL in seconds (default: 3600 = 1 hour) */\n\timpersonationTtlSeconds?: number;\n\t/** Callback for audit logging admin actions */\n\tonAdminAction?: (entry: AdminAuditEntry) => void | Promise<void>;\n}\n\nexport interface AdminAuditEntry {\n\tadminUserId: string;\n\taction: string;\n\ttargetUserId: string;\n\tdetails?: Record<string, unknown>;\n\ttimestamp: Date;\n}\n\nexport interface AdminUser {\n\tid: string;\n\temail: string;\n\tname: string | null;\n\tbanned: boolean;\n\tbanReason?: string;\n\tbanExpiresAt?: Date;\n\tagentCount: number;\n\tcreatedAt: Date;\n}\n\nexport interface AdminModule {\n\tisAdmin: (userId: string) => Promise<boolean>;\n\tlistUsers: (options?: {\n\t\tlimit?: number;\n\t\toffset?: number;\n\t\tsearch?: string;\n\t}) => Promise<{ users: AdminUser[]; total: number }>;\n\tgetUser: (userId: string) => Promise<AdminUser | null>;\n\tbanUser: (userId: string, reason?: string, expiresAt?: Date) => Promise<void>;\n\tunbanUser: (userId: string) => Promise<void>;\n\tdeleteUser: (userId: string) => Promise<void>;\n\timpersonate: (\n\t\tadminUserId: string,\n\t\ttargetUserId: string,\n\t) => Promise<{ session: { token: string; expiresAt: Date }; impersonating: boolean }>;\n\tstopImpersonation: (sessionToken: string) => Promise<void>;\n\tforcePasswordReset: (userId: string) => Promise<void>;\n\thandleRequest: (request: Request) => Promise<Response | null>;\n}\n\n// ---------------------------------------------------------------------------\n// Internal row type (matches schema with ban columns)\n// ---------------------------------------------------------------------------\n\ntype UserRow = typeof users.$inferSelect;\n\n// ---------------------------------------------------------------------------\n// Factory\n// ---------------------------------------------------------------------------\n\nconst DEFAULT_IMPERSONATION_TTL_SECONDS = 3600; // 1 hour\n\nexport function createAdminModule(\n\tconfig: AdminConfig,\n\tdb: Database,\n\tsessionManager: SessionManager | null,\n): AdminModule {\n\tconst adminUserIds = new Set(config.adminUserIds ?? []);\n\tconst allowImpersonation = config.allowImpersonation ?? true;\n\tconst impersonationTtlSeconds =\n\t\tconfig.impersonationTtlSeconds ?? DEFAULT_IMPERSONATION_TTL_SECONDS;\n\tconst onAdminAction = config.onAdminAction;\n\n\tasync function logAdminAction(\n\t\tadminUserId: string,\n\t\taction: string,\n\t\ttargetUserId: string,\n\t\tdetails?: Record<string, unknown>,\n\t): Promise<void> {\n\t\tif (onAdminAction) {\n\t\t\ttry {\n\t\t\t\tawait onAdminAction({\n\t\t\t\t\tadminUserId,\n\t\t\t\t\taction,\n\t\t\t\t\ttargetUserId,\n\t\t\t\t\tdetails,\n\t\t\t\t\ttimestamp: new Date(),\n\t\t\t\t});\n\t\t\t} catch {\n\t\t\t\t// Audit logging should never break the admin action\n\t\t\t}\n\t\t}\n\t}\n\n\tasync function isAdmin(userId: string): Promise<boolean> {\n\t\treturn adminUserIds.has(userId);\n\t}\n\n\tasync function getAgentCountForUser(userId: string): Promise<number> {\n\t\tconst rows = await db\n\t\t\t.select({ count: sql<number>`count(*)` })\n\t\t\t.from(agents)\n\t\t\t.where(eq(agents.ownerId, userId));\n\t\treturn Number(rows[0]?.count ?? 0);\n\t}\n\n\tfunction rowToAdminUser(row: UserRow, agentCount: number): AdminUser {\n\t\tconst banned = (row.banned ?? 0) === 1;\n\t\treturn {\n\t\t\tid: row.id,\n\t\t\temail: row.email,\n\t\t\tname: row.name,\n\t\t\tbanned,\n\t\t\tbanReason: banned && row.banReason ? row.banReason : undefined,\n\t\t\tbanExpiresAt: banned && row.banExpiresAt ? row.banExpiresAt : undefined,\n\t\t\tagentCount,\n\t\t\tcreatedAt: row.createdAt,\n\t\t};\n\t}\n\n\tasync function listUsers(options?: {\n\t\tlimit?: number;\n\t\toffset?: number;\n\t\tsearch?: string;\n\t}): Promise<{ users: AdminUser[]; total: number }> {\n\t\tconst limit = options?.limit ?? 50;\n\t\tconst offset = options?.offset ?? 0;\n\t\tconst search = options?.search;\n\n\t\tlet rows: UserRow[];\n\t\tlet countRows: { count: number }[];\n\n\t\tif (search) {\n\t\t\tconst pattern = `%${search}%`;\n\t\t\trows = await db\n\t\t\t\t.select()\n\t\t\t\t.from(users)\n\t\t\t\t.where(like(users.email, pattern))\n\t\t\t\t.limit(limit)\n\t\t\t\t.offset(offset);\n\t\t\tcountRows = await db\n\t\t\t\t.select({ count: sql<number>`count(*)` })\n\t\t\t\t.from(users)\n\t\t\t\t.where(like(users.email, pattern));\n\t\t} else {\n\t\t\trows = await db.select().from(users).limit(limit).offset(offset);\n\t\t\tcountRows = await db.select({ count: sql<number>`count(*)` }).from(users);\n\t\t}\n\n\t\tconst total = Number(countRows[0]?.count ?? 0);\n\n\t\tconst adminUsers = await Promise.all(\n\t\t\trows.map(async (row) => {\n\t\t\t\tconst agentCount = await getAgentCountForUser(row.id);\n\t\t\t\treturn rowToAdminUser(row, agentCount);\n\t\t\t}),\n\t\t);\n\n\t\treturn { users: adminUsers, total };\n\t}\n\n\tasync function getUser(userId: string): Promise<AdminUser | null> {\n\t\tconst rows = await db.select().from(users).where(eq(users.id, userId));\n\t\tconst row = rows[0];\n\t\tif (!row) return null;\n\t\tconst agentCount = await getAgentCountForUser(userId);\n\t\treturn rowToAdminUser(row, agentCount);\n\t}\n\n\tasync function banUser(userId: string, reason?: string, expiresAt?: Date): Promise<void> {\n\t\tawait db\n\t\t\t.update(users)\n\t\t\t.set({\n\t\t\t\tbanned: 1,\n\t\t\t\tbanReason: reason ?? null,\n\t\t\t\tbanExpiresAt: expiresAt ?? null,\n\t\t\t\tupdatedAt: new Date(),\n\t\t\t})\n\t\t\t.where(eq(users.id, userId));\n\n\t\t// Revoke all active sessions for the banned user\n\t\tawait db.delete(sessions).where(eq(sessions.userId, userId));\n\n\t\t// Revoke all active agent tokens for the banned user\n\t\tawait db.update(agents).set({ status: \"revoked\" }).where(eq(agents.ownerId, userId));\n\n\t\tawait logAdminAction(\"system\", \"ban_user\", userId, {\n\t\t\treason,\n\t\t\texpiresAt: expiresAt?.toISOString(),\n\t\t});\n\t}\n\n\tasync function unbanUser(userId: string): Promise<void> {\n\t\tawait db\n\t\t\t.update(users)\n\t\t\t.set({\n\t\t\t\tbanned: 0,\n\t\t\t\tbanReason: null,\n\t\t\t\tbanExpiresAt: null,\n\t\t\t\tupdatedAt: new Date(),\n\t\t\t})\n\t\t\t.where(eq(users.id, userId));\n\n\t\tawait logAdminAction(\"system\", \"unban_user\", userId);\n\t}\n\n\tasync function deleteUser(userId: string): Promise<void> {\n\t\t// Revoke sessions first\n\t\tawait db.delete(sessions).where(eq(sessions.userId, userId));\n\t\t// Mark agents as revoked to preserve audit trail\n\t\tawait db.update(agents).set({ status: \"revoked\" }).where(eq(agents.ownerId, userId));\n\t\tawait db.delete(users).where(eq(users.id, userId));\n\n\t\tawait logAdminAction(\"system\", \"delete_user\", userId);\n\t}\n\n\tasync function impersonate(\n\t\tadminUserId: string,\n\t\ttargetUserId: string,\n\t): Promise<{ session: { token: string; expiresAt: Date }; impersonating: boolean }> {\n\t\tif (!allowImpersonation) throw new Error(\"Impersonation is disabled\");\n\t\tif (!sessionManager) throw new Error(\"Session manager is required for impersonation\");\n\n\t\tconst isAdminUser = await isAdmin(adminUserId);\n\t\tif (!isAdminUser) throw new Error(`User \"${adminUserId}\" is not an admin`);\n\n\t\t// Impersonation sessions use a shorter TTL (default: 1 hour)\n\t\tconst impersonationExpiresAt = new Date(Date.now() + impersonationTtlSeconds * 1000);\n\n\t\tconst { token } = await sessionManager.create(targetUserId, {\n\t\t\timpersonating: true,\n\t\t\tadminUserId,\n\t\t\timpersonationExpiresAt: impersonationExpiresAt.toISOString(),\n\t\t\tsessionType: \"impersonation\",\n\t\t});\n\n\t\tawait logAdminAction(adminUserId, \"impersonate\", targetUserId);\n\n\t\treturn {\n\t\t\tsession: { token, expiresAt: impersonationExpiresAt },\n\t\t\timpersonating: true,\n\t\t};\n\t}\n\n\tasync function stopImpersonation(sessionToken: string): Promise<void> {\n\t\tif (!sessionManager) throw new Error(\"Session manager is required\");\n\t\tconst session = await sessionManager.validate(sessionToken);\n\t\tif (!session) throw new Error(\"Invalid or expired session token\");\n\t\tawait sessionManager.revoke(session.id);\n\t}\n\n\tasync function forcePasswordReset(userId: string): Promise<void> {\n\t\tawait db\n\t\t\t.update(users)\n\t\t\t.set({ forcePasswordReset: 1, updatedAt: new Date() })\n\t\t\t.where(eq(users.id, userId));\n\n\t\tawait logAdminAction(\"system\", \"force_password_reset\", userId);\n\t}\n\n\t// ── HTTP handler ──────────────────────────────────────────────────────────\n\n\tasync function handleRequest(request: Request): Promise<Response | null> {\n\t\tconst url = new URL(request.url);\n\t\tconst { pathname } = url;\n\t\tconst { method } = request;\n\n\t\tconst json = (data: unknown, status = 200) =>\n\t\t\tnew Response(JSON.stringify(data), {\n\t\t\t\tstatus,\n\t\t\t\theaders: { \"Content-Type\": \"application/json\" },\n\t\t\t});\n\n\t\t// GET /auth/admin/users\n\t\tif (method === \"GET\" && pathname === \"/auth/admin/users\") {\n\t\t\tconst limit = url.searchParams.get(\"limit\")\n\t\t\t\t? Number(url.searchParams.get(\"limit\"))\n\t\t\t\t: undefined;\n\t\t\tconst offset = url.searchParams.get(\"offset\")\n\t\t\t\t? Number(url.searchParams.get(\"offset\"))\n\t\t\t\t: undefined;\n\t\t\tconst search = url.searchParams.get(\"search\") ?? undefined;\n\t\t\tconst result = await listUsers({ limit, offset, search });\n\t\t\treturn json(result);\n\t\t}\n\n\t\t// GET /auth/admin/users/:id\n\t\tconst userMatch = /^\\/auth\\/admin\\/users\\/([^/]+)$/.exec(pathname);\n\t\tif (method === \"GET\" && userMatch) {\n\t\t\tconst userId = decodeURIComponent(userMatch[1] ?? \"\");\n\t\t\tconst user = await getUser(userId);\n\t\t\tif (!user) return json({ error: \"User not found\" }, 404);\n\t\t\treturn json(user);\n\t\t}\n\n\t\t// POST /auth/admin/users/:id/ban\n\t\tconst banMatch = /^\\/auth\\/admin\\/users\\/([^/]+)\\/ban$/.exec(pathname);\n\t\tif (method === \"POST\" && banMatch) {\n\t\t\tconst userId = decodeURIComponent(banMatch[1] ?? \"\");\n\t\t\tlet body: Record<string, unknown> = {};\n\t\t\ttry {\n\t\t\t\tbody = (await request.json()) as Record<string, unknown>;\n\t\t\t} catch {\n\t\t\t\t// body is optional\n\t\t\t}\n\t\t\tconst reason = typeof body.reason === \"string\" ? body.reason : undefined;\n\t\t\tconst expiresAt = body.expiresAt ? new Date(body.expiresAt as string) : undefined;\n\t\t\tawait banUser(userId, reason, expiresAt);\n\t\t\treturn json({ success: true });\n\t\t}\n\n\t\t// POST /auth/admin/users/:id/unban\n\t\tconst unbanMatch = /^\\/auth\\/admin\\/users\\/([^/]+)\\/unban$/.exec(pathname);\n\t\tif (method === \"POST\" && unbanMatch) {\n\t\t\tconst userId = decodeURIComponent(unbanMatch[1] ?? \"\");\n\t\t\tawait unbanUser(userId);\n\t\t\treturn json({ success: true });\n\t\t}\n\n\t\t// DELETE /auth/admin/users/:id\n\t\tconst deleteMatch = /^\\/auth\\/admin\\/users\\/([^/]+)$/.exec(pathname);\n\t\tif (method === \"DELETE\" && deleteMatch) {\n\t\t\tconst userId = decodeURIComponent(deleteMatch[1] ?? \"\");\n\t\t\tawait deleteUser(userId);\n\t\t\treturn json({ success: true });\n\t\t}\n\n\t\t// POST /auth/admin/impersonate/:userId\n\t\tconst impersonateMatch = /^\\/auth\\/admin\\/impersonate\\/([^/]+)$/.exec(pathname);\n\t\tif (method === \"POST\" && impersonateMatch) {\n\t\t\tconst targetUserId = decodeURIComponent(impersonateMatch[1] ?? \"\");\n\t\t\tlet body: Record<string, unknown> = {};\n\t\t\ttry {\n\t\t\t\tbody = (await request.json()) as Record<string, unknown>;\n\t\t\t} catch {\n\t\t\t\treturn json({ error: \"Invalid JSON body\" }, 400);\n\t\t\t}\n\t\t\tconst adminUserId = body.adminUserId;\n\t\t\tif (typeof adminUserId !== \"string\") {\n\t\t\t\treturn json({ error: \"Missing required field: adminUserId\" }, 400);\n\t\t\t}\n\t\t\ttry {\n\t\t\t\tconst result = await impersonate(adminUserId, targetUserId);\n\t\t\t\treturn json(result);\n\t\t\t} catch (err) {\n\t\t\t\treturn json({ error: err instanceof Error ? err.message : \"Unknown error\" }, 403);\n\t\t\t}\n\t\t}\n\n\t\t// POST /auth/admin/stop-impersonation\n\t\tif (method === \"POST\" && pathname === \"/auth/admin/stop-impersonation\") {\n\t\t\tconst auth = request.headers.get(\"Authorization\");\n\t\t\tconst token = auth?.startsWith(\"Bearer \") ? auth.slice(7) : null;\n\t\t\tif (!token) return json({ error: \"Missing Authorization header\" }, 401);\n\t\t\ttry {\n\t\t\t\tawait stopImpersonation(token);\n\t\t\t\treturn json({ success: true });\n\t\t\t} catch (err) {\n\t\t\t\treturn json({ error: err instanceof Error ? err.message : \"Unknown error\" }, 400);\n\t\t\t}\n\t\t}\n\n\t\treturn null;\n\t}\n\n\treturn {\n\t\tisAdmin,\n\t\tlistUsers,\n\t\tgetUser,\n\t\tbanUser,\n\t\tunbanUser,\n\t\tdeleteUser,\n\t\timpersonate,\n\t\tstopImpersonation,\n\t\tforcePasswordReset,\n\t\thandleRequest,\n\t};\n}\n","/**\n * Session management for KavachOS.\n *\n * Provides signed JWT session tokens backed by a `kavach_sessions` database\n * table. Each token carries the session ID as its `sub` claim; the full\n * session record (including metadata and expiry) lives in the database so\n * it can be revoked server-side at any time.\n *\n * Tokens are signed with HS256 via `jose` – the same library used for agent\n * JWT tokens elsewhere in KavachOS.\n *\n * @example\n * ```typescript\n * const kavach = await createKavach({ ... });\n * const sessions = kavach.auth.session;\n *\n * // On login\n * const { token } = await sessions.create(user.id, { role: 'admin' });\n * setCookie('kavach_session', token, { httpOnly: true, sameSite: 'lax' });\n *\n * // On each request\n * const session = await sessions.validate(token);\n * if (!session) return new Response('Unauthorized', { status: 401 });\n *\n * // On logout\n * await sessions.revoke(session.id);\n * ```\n */\n\nimport { createSecretKey, randomUUID } from \"node:crypto\";\nimport { and, eq } from \"drizzle-orm\";\nimport { jwtVerify, SignJWT } from \"jose\";\nimport type { Database } from \"../db/database.js\";\nimport { sessions } from \"../db/schema.js\";\n\n// ---------------------------------------------------------------------------\n// Public types\n// ---------------------------------------------------------------------------\n\nexport interface SessionConfig {\n\t/** Signing secret for session tokens. Must be at least 32 characters. */\n\tsecret: string;\n\t/**\n\t * Session lifetime in seconds.\n\t * Defaults to 604 800 (7 days).\n\t */\n\tmaxAge?: number;\n\t/**\n\t * Name of the cookie used to transport the session token.\n\t * Defaults to `kavach_session`.\n\t */\n\tcookieName?: string;\n}\n\nexport interface Session {\n\tid: string;\n\tuserId: string;\n\texpiresAt: Date;\n\tcreatedAt: Date;\n\tmetadata?: Record<string, unknown>;\n}\n\nexport interface SessionManager {\n\t/**\n\t * Create a new session for the given user.\n\t *\n\t * Persists the session to `kavach_sessions` and returns both the\n\t * session record and a signed JWT that the client should store (e.g. in a\n\t * `Set-Cookie` header).\n\t */\n\tcreate(\n\t\tuserId: string,\n\t\tmetadata?: Record<string, unknown>,\n\t): Promise<{ session: Session; token: string }>;\n\n\t/**\n\t * Validate a session token.\n\t *\n\t * Verifies the JWT signature, checks the database record exists, and\n\t * confirms the session has not expired. Returns `null` for any failure.\n\t */\n\tvalidate(token: string): Promise<Session | null>;\n\n\t/**\n\t * Revoke a single session by its ID.\n\t *\n\t * The session is deleted from the database; any token that encoded this\n\t * session ID will fail `validate()` immediately.\n\t */\n\trevoke(sessionId: string): Promise<void>;\n\n\t/**\n\t * Revoke all sessions for a user (e.g. on password change or account deletion).\n\t */\n\trevokeAll(userId: string): Promise<void>;\n\n\t/**\n\t * List all active sessions for a user, ordered by creation time descending.\n\t */\n\tlist(userId: string): Promise<Session[]>;\n}\n\n// ---------------------------------------------------------------------------\n// Default values\n// ---------------------------------------------------------------------------\n\nconst DEFAULT_MAX_AGE_SECONDS = 60 * 60 * 24 * 7; // 7 days\n\n// ---------------------------------------------------------------------------\n// Factory\n// ---------------------------------------------------------------------------\n\n/**\n * Create a `SessionManager` backed by the `kavach_sessions` database table.\n *\n * @param config Session configuration (secret, maxAge, cookieName).\n * @param db The Drizzle database instance from `createDatabase()`.\n */\nexport function createSessionManager(config: SessionConfig, db: Database): SessionManager {\n\tif (!config.secret || config.secret.length < 32) {\n\t\tthrow new Error(\"SessionManager: secret must be at least 32 characters.\");\n\t}\n\n\tconst maxAge = config.maxAge ?? DEFAULT_MAX_AGE_SECONDS;\n\tconst keyBytes = new TextEncoder().encode(config.secret);\n\tconst keyObject = createSecretKey(keyBytes);\n\n\t// ── helpers ────────────────────────────────────────────────────────────\n\n\tfunction rowToSession(row: {\n\t\tid: string;\n\t\tuserId: string;\n\t\texpiresAt: Date;\n\t\tcreatedAt: Date;\n\t\tmetadata: Record<string, unknown> | null;\n\t}): Session {\n\t\treturn {\n\t\t\tid: row.id,\n\t\t\tuserId: row.userId,\n\t\t\texpiresAt: row.expiresAt,\n\t\t\tcreatedAt: row.createdAt,\n\t\t\t...(row.metadata !== null && { metadata: row.metadata }),\n\t\t};\n\t}\n\n\t// ── public API ─────────────────────────────────────────────────────────\n\n\tasync function create(\n\t\tuserId: string,\n\t\tmetadata?: Record<string, unknown>,\n\t): Promise<{ session: Session; token: string }> {\n\t\tconst id = randomUUID();\n\t\tconst now = new Date();\n\t\tconst expiresAt = new Date(now.getTime() + maxAge * 1000);\n\n\t\tawait db.insert(sessions).values({\n\t\t\tid,\n\t\t\tuserId,\n\t\t\texpiresAt,\n\t\t\tmetadata: metadata ?? null,\n\t\t\tcreatedAt: now,\n\t\t});\n\n\t\tconst token = await new SignJWT({ sub: id })\n\t\t\t.setProtectedHeader({ alg: \"HS256\" })\n\t\t\t.setIssuedAt()\n\t\t\t.setExpirationTime(Math.floor(expiresAt.getTime() / 1000))\n\t\t\t.sign(keyObject);\n\n\t\tconst session: Session = {\n\t\t\tid,\n\t\t\tuserId,\n\t\t\texpiresAt,\n\t\t\tcreatedAt: now,\n\t\t\t...(metadata !== undefined && { metadata }),\n\t\t};\n\n\t\treturn { session, token };\n\t}\n\n\tasync function validate(token: string): Promise<Session | null> {\n\t\tlet sessionId: string;\n\n\t\ttry {\n\t\t\tconst { payload } = await jwtVerify(token, keyObject);\n\t\t\tif (typeof payload.sub !== \"string\" || !payload.sub) return null;\n\t\t\tsessionId = payload.sub;\n\t\t} catch {\n\t\t\treturn null;\n\t\t}\n\n\t\tconst now = new Date();\n\n\t\tconst rows = await db\n\t\t\t.select()\n\t\t\t.from(sessions)\n\t\t\t.where(and(eq(sessions.id, sessionId)));\n\n\t\tconst row = rows[0];\n\t\tif (!row) return null;\n\n\t\t// Belt-and-suspenders: also check DB expiry (token expiry is the same but\n\t\t// allows for clock skew during revokeAll / manual deletion flows).\n\t\tif (row.expiresAt <= now) {\n\t\t\t// Clean up expired row opportunistically.\n\t\t\tawait db.delete(sessions).where(eq(sessions.id, sessionId));\n\t\t\treturn null;\n\t\t}\n\n\t\treturn rowToSession(row);\n\t}\n\n\tasync function revoke(sessionId: string): Promise<void> {\n\t\tawait db.delete(sessions).where(eq(sessions.id, sessionId));\n\t}\n\n\tasync function revokeAll(userId: string): Promise<void> {\n\t\tawait db.delete(sessions).where(eq(sessions.userId, userId));\n\t}\n\n\tasync function list(userId: string): Promise<Session[]> {\n\t\tconst now = new Date();\n\n\t\tconst rows = await db\n\t\t\t.select()\n\t\t\t.from(sessions)\n\t\t\t.where(and(eq(sessions.userId, userId)));\n\n\t\t// Filter out expired sessions (they may not have been cleaned up yet)\n\t\t// and sort newest first.\n\t\treturn rows\n\t\t\t.filter((row) => row.expiresAt > now)\n\t\t\t.sort((a, b) => b.createdAt.getTime() - a.createdAt.getTime())\n\t\t\t.map(rowToSession);\n\t}\n\n\treturn { create, validate, revoke, revokeAll, list };\n}\n","import type { KavachPlugin } from \"../plugin/types.js\";\nimport { createSessionManager } from \"../session/session.js\";\nimport type { AdminConfig } from \"./admin.js\";\nimport { createAdminModule } from \"./admin.js\";\n\nexport type { AdminConfig };\n\n// ---------------------------------------------------------------------------\n// Helpers\n// ---------------------------------------------------------------------------\n\nfunction jsonResponse(body: unknown, status = 200): Response {\n\treturn new Response(JSON.stringify(body), {\n\t\tstatus,\n\t\theaders: { \"Content-Type\": \"application/json\" },\n\t});\n}\n\nasync function parseBody(request: Request): Promise<Record<string, unknown>> {\n\ttry {\n\t\treturn (await request.json()) as Record<string, unknown>;\n\t} catch {\n\t\treturn {};\n\t}\n}\n\n// ---------------------------------------------------------------------------\n// Plugin factory\n// ---------------------------------------------------------------------------\n\nexport function admin(config?: AdminConfig): KavachPlugin {\n\treturn {\n\t\tid: \"kavach-admin\",\n\n\t\tasync init(ctx): Promise<undefined> {\n\t\t\tconst sessionConfig = ctx.config.auth?.session;\n\t\t\tconst sessionManager = sessionConfig ? createSessionManager(sessionConfig, ctx.db) : null;\n\t\t\tconst module = createAdminModule(config ?? {}, ctx.db, sessionManager);\n\n\t\t\t// GET /auth/admin/users\n\t\t\t// Lists all users. Requires admin.\n\t\t\tctx.addEndpoint({\n\t\t\t\tmethod: \"GET\",\n\t\t\t\tpath: \"/auth/admin/users\",\n\t\t\t\tmetadata: {\n\t\t\t\t\trequireAuth: true,\n\t\t\t\t\tdescription: \"List all users (admin only)\",\n\t\t\t\t},\n\t\t\t\tasync handler(request, endpointCtx) {\n\t\t\t\t\tconst user = await endpointCtx.getUser(request);\n\t\t\t\t\tif (!user) {\n\t\t\t\t\t\treturn jsonResponse({ error: \"Authentication required\" }, 401);\n\t\t\t\t\t}\n\n\t\t\t\t\tconst isAdminUser = await module.isAdmin(user.id);\n\t\t\t\t\tif (!isAdminUser) {\n\t\t\t\t\t\treturn jsonResponse({ error: \"Admin access required\" }, 403);\n\t\t\t\t\t}\n\n\t\t\t\t\tconst url = new URL(request.url);\n\t\t\t\t\tconst limitParam = url.searchParams.get(\"limit\");\n\t\t\t\t\tconst offsetParam = url.searchParams.get(\"offset\");\n\t\t\t\t\tconst search = url.searchParams.get(\"search\") ?? undefined;\n\n\t\t\t\t\tconst result = await module.listUsers({\n\t\t\t\t\t\tlimit: limitParam ? Number(limitParam) : undefined,\n\t\t\t\t\t\toffset: offsetParam ? Number(offsetParam) : undefined,\n\t\t\t\t\t\tsearch,\n\t\t\t\t\t});\n\n\t\t\t\t\treturn jsonResponse(result);\n\t\t\t\t},\n\t\t\t});\n\n\t\t\t// GET /auth/admin/users/:id\n\t\t\t// Returns a single user by ID. Requires admin.\n\t\t\tctx.addEndpoint({\n\t\t\t\tmethod: \"GET\",\n\t\t\t\tpath: \"/auth/admin/users/:id\",\n\t\t\t\tmetadata: {\n\t\t\t\t\trequireAuth: true,\n\t\t\t\t\tdescription: \"Get a user by ID (admin only)\",\n\t\t\t\t},\n\t\t\t\tasync handler(request, endpointCtx) {\n\t\t\t\t\tconst user = await endpointCtx.getUser(request);\n\t\t\t\t\tif (!user) {\n\t\t\t\t\t\treturn jsonResponse({ error: \"Authentication required\" }, 401);\n\t\t\t\t\t}\n\n\t\t\t\t\tconst isAdminUser = await module.isAdmin(user.id);\n\t\t\t\t\tif (!isAdminUser) {\n\t\t\t\t\t\treturn jsonResponse({ error: \"Admin access required\" }, 403);\n\t\t\t\t\t}\n\n\t\t\t\t\tconst url = new URL(request.url);\n\t\t\t\t\tconst segments = url.pathname.split(\"/\").filter(Boolean);\n\t\t\t\t\t// Expected: [\"auth\", \"admin\", \"users\", \"<id>\"]\n\t\t\t\t\tconst targetId = segments[3];\n\n\t\t\t\t\tif (!targetId) {\n\t\t\t\t\t\treturn jsonResponse({ error: \"Missing user ID in path\" }, 400);\n\t\t\t\t\t}\n\n\t\t\t\t\tconst found = await module.getUser(decodeURIComponent(targetId));\n\t\t\t\t\tif (!found) {\n\t\t\t\t\t\treturn jsonResponse({ error: \"User not found\" }, 404);\n\t\t\t\t\t}\n\n\t\t\t\t\treturn jsonResponse(found);\n\t\t\t\t},\n\t\t\t});\n\n\t\t\t// POST /auth/admin/users/:id/ban\n\t\t\t// Bans a user. Optionally accepts { reason, expiresAt } in body. Requires admin.\n\t\t\tctx.addEndpoint({\n\t\t\t\tmethod: \"POST\",\n\t\t\t\tpath: \"/auth/admin/users/:id/ban\",\n\t\t\t\tmetadata: {\n\t\t\t\t\trequireAuth: true,\n\t\t\t\t\tdescription: \"Ban a user (admin only)\",\n\t\t\t\t},\n\t\t\t\tasync handler(request, endpointCtx) {\n\t\t\t\t\tconst user = await endpointCtx.getUser(request);\n\t\t\t\t\tif (!user) {\n\t\t\t\t\t\treturn jsonResponse({ error: \"Authentication required\" }, 401);\n\t\t\t\t\t}\n\n\t\t\t\t\tconst isAdminUser = await module.isAdmin(user.id);\n\t\t\t\t\tif (!isAdminUser) {\n\t\t\t\t\t\treturn jsonResponse({ error: \"Admin access required\" }, 403);\n\t\t\t\t\t}\n\n\t\t\t\t\tconst url = new URL(request.url);\n\t\t\t\t\tconst segments = url.pathname.split(\"/\").filter(Boolean);\n\t\t\t\t\t// Expected: [\"auth\", \"admin\", \"users\", \"<id>\", \"ban\"]\n\t\t\t\t\tconst targetId = segments[3];\n\n\t\t\t\t\tif (!targetId) {\n\t\t\t\t\t\treturn jsonResponse({ error: \"Missing user ID in path\" }, 400);\n\t\t\t\t\t}\n\n\t\t\t\t\tconst body = await parseBody(request);\n\t\t\t\t\tconst reason = typeof body.reason === \"string\" ? body.reason : undefined;\n\t\t\t\t\tconst expiresAt = body.expiresAt ? new Date(body.expiresAt as string) : undefined;\n\n\t\t\t\t\tawait module.banUser(decodeURIComponent(targetId), reason, expiresAt);\n\t\t\t\t\treturn jsonResponse({ success: true });\n\t\t\t\t},\n\t\t\t});\n\n\t\t\t// POST /auth/admin/users/:id/unban\n\t\t\t// Lifts a ban from a user. Requires admin.\n\t\t\tctx.addEndpoint({\n\t\t\t\tmethod: \"POST\",\n\t\t\t\tpath: \"/auth/admin/users/:id/unban\",\n\t\t\t\tmetadata: {\n\t\t\t\t\trequireAuth: true,\n\t\t\t\t\tdescription: \"Unban a user (admin only)\",\n\t\t\t\t},\n\t\t\t\tasync handler(request, endpointCtx) {\n\t\t\t\t\tconst user = await endpointCtx.getUser(request);\n\t\t\t\t\tif (!user) {\n\t\t\t\t\t\treturn jsonResponse({ error: \"Authentication required\" }, 401);\n\t\t\t\t\t}\n\n\t\t\t\t\tconst isAdminUser = await module.isAdmin(user.id);\n\t\t\t\t\tif (!isAdminUser) {\n\t\t\t\t\t\treturn jsonResponse({ error: \"Admin access required\" }, 403);\n\t\t\t\t\t}\n\n\t\t\t\t\tconst url = new URL(request.url);\n\t\t\t\t\tconst segments = url.pathname.split(\"/\").filter(Boolean);\n\t\t\t\t\t// Expected: [\"auth\", \"admin\", \"users\", \"<id>\", \"unban\"]\n\t\t\t\t\tconst targetId = segments[3];\n\n\t\t\t\t\tif (!targetId) {\n\t\t\t\t\t\treturn jsonResponse({ error: \"Missing user ID in path\" }, 400);\n\t\t\t\t\t}\n\n\t\t\t\t\tawait module.unbanUser(decodeURIComponent(targetId));\n\t\t\t\t\treturn jsonResponse({ success: true });\n\t\t\t\t},\n\t\t\t});\n\n\t\t\t// DELETE /auth/admin/users/:id\n\t\t\t// Permanently deletes a user. Requires admin.\n\t\t\tctx.addEndpoint({\n\t\t\t\tmethod: \"DELETE\",\n\t\t\t\tpath: \"/auth/admin/users/:id\",\n\t\t\t\tmetadata: {\n\t\t\t\t\trequireAuth: true,\n\t\t\t\t\tdescription: \"Delete a user (admin only)\",\n\t\t\t\t},\n\t\t\t\tasync handler(request, endpointCtx) {\n\t\t\t\t\tconst user = await endpointCtx.getUser(request);\n\t\t\t\t\tif (!user) {\n\t\t\t\t\t\treturn jsonResponse({ error: \"Authentication required\" }, 401);\n\t\t\t\t\t}\n\n\t\t\t\t\tconst isAdminUser = await module.isAdmin(user.id);\n\t\t\t\t\tif (!isAdminUser) {\n\t\t\t\t\t\treturn jsonResponse({ error: \"Admin access required\" }, 403);\n\t\t\t\t\t}\n\n\t\t\t\t\tconst url = new URL(request.url);\n\t\t\t\t\tconst segments = url.pathname.split(\"/\").filter(Boolean);\n\t\t\t\t\t// Expected: [\"auth\", \"admin\", \"users\", \"<id>\"]\n\t\t\t\t\tconst targetId = segments[3];\n\n\t\t\t\t\tif (!targetId) {\n\t\t\t\t\t\treturn jsonResponse({ error: \"Missing user ID in path\" }, 400);\n\t\t\t\t\t}\n\n\t\t\t\t\tawait module.deleteUser(decodeURIComponent(targetId));\n\t\t\t\t\treturn jsonResponse({ success: true });\n\t\t\t\t},\n\t\t\t});\n\n\t\t\t// POST /auth/admin/users/:id/impersonate\n\t\t\t// Starts an impersonation session as the target user. Requires admin.\n\t\t\tctx.addEndpoint({\n\t\t\t\tmethod: \"POST\",\n\t\t\t\tpath: \"/auth/admin/users/:id/impersonate\",\n\t\t\t\tmetadata: {\n\t\t\t\t\trequireAuth: true,\n\t\t\t\t\tdescription: \"Start an impersonation session as a target user (admin only)\",\n\t\t\t\t},\n\t\t\t\tasync handler(request, endpointCtx) {\n\t\t\t\t\tconst user = await endpointCtx.getUser(request);\n\t\t\t\t\tif (!user) {\n\t\t\t\t\t\treturn jsonResponse({ error: \"Authentication required\" }, 401);\n\t\t\t\t\t}\n\n\t\t\t\t\tconst isAdminUser = await module.isAdmin(user.id);\n\t\t\t\t\tif (!isAdminUser) {\n\t\t\t\t\t\treturn jsonResponse({ error: \"Admin access required\" }, 403);\n\t\t\t\t\t}\n\n\t\t\t\t\tconst url = new URL(request.url);\n\t\t\t\t\tconst segments = url.pathname.split(\"/\").filter(Boolean);\n\t\t\t\t\t// Expected: [\"auth\", \"admin\", \"users\", \"<id>\", \"impersonate\"]\n\t\t\t\t\tconst targetId = segments[3];\n\n\t\t\t\t\tif (!targetId) {\n\t\t\t\t\t\treturn jsonResponse({ error: \"Missing user ID in path\" }, 400);\n\t\t\t\t\t}\n\n\t\t\t\t\ttry {\n\t\t\t\t\t\tconst result = await module.impersonate(user.id, decodeURIComponent(targetId));\n\t\t\t\t\t\treturn jsonResponse(result);\n\t\t\t\t\t} catch (err) {\n\t\t\t\t\t\treturn jsonResponse(\n\t\t\t\t\t\t\t{ error: err instanceof Error ? err.message : \"Impersonation failed\" },\n\t\t\t\t\t\t\t403,\n\t\t\t\t\t\t);\n\t\t\t\t\t}\n\t\t\t\t},\n\t\t\t});\n\t\t},\n\t};\n}\n","/**\n * Anonymous authentication for KavachOS.\n *\n * Lets users start as guests without providing credentials. The anonymous\n * user can later be upgraded to a real account by supplying an email.\n *\n * Anonymous users are stored in `kavach_users` with a synthetic placeholder\n * email (`anon_<uuid>@kavachos.anonymous`) and a metadata flag\n * `{ anonymous: true }`. This satisfies the NOT NULL UNIQUE constraint on\n * the email column while keeping them easily identifiable.\n *\n * @example\n * ```typescript\n * const anon = createAnonymousAuthModule(config, db, sessionManager);\n *\n * // On first visit\n * const { userId, sessionToken } = await anon.createAnonymousUser();\n *\n * // Later, when user signs up\n * await anon.upgradeUser(userId, { email: 'alice@example.com', name: 'Alice' });\n * ```\n */\n\nimport { randomUUID } from \"node:crypto\";\nimport { and, eq, lt } from \"drizzle-orm\";\nimport type { Database } from \"../db/database.js\";\nimport { sessions, users } from \"../db/schema.js\";\nimport type { SessionManager } from \"../session/session.js\";\n\n// ---------------------------------------------------------------------------\n// Public types\n// ---------------------------------------------------------------------------\n\nexport interface AnonymousAuthConfig {\n\t/** How long anonymous sessions last in seconds (default: 86400 = 24 hours) */\n\tsessionTtlSeconds?: number;\n\t/** Whether to allow anonymous users to create agents (default: false) */\n\tallowAgentCreation?: boolean;\n}\n\nexport interface AnonymousAuthModule {\n\t/** Create an anonymous user and a session. */\n\tcreateAnonymousUser(): Promise<{ userId: string; sessionToken: string }>;\n\t/** Upgrade an anonymous user to a real account by setting their email. */\n\tupgradeUser(anonymousUserId: string, upgrade: { email: string; name?: string }): Promise<void>;\n\t/** Check if a user was created as anonymous and has not been upgraded. */\n\tisAnonymous(userId: string): Promise<boolean>;\n\t/**\n\t * Delete anonymous users older than `maxAgeMs` and their sessions.\n\t * Returns the number of users removed.\n\t */\n\tcleanup(maxAgeMs?: number): Promise<number>;\n}\n\n// ---------------------------------------------------------------------------\n// Constants\n// ---------------------------------------------------------------------------\n\nconst DEFAULT_SESSION_TTL_SECONDS = 60 * 60 * 24; // 24 hours\nconst DEFAULT_MAX_AGE_MS = 1000 * 60 * 60 * 24; // 24 hours\nconst ANONYMOUS_EMAIL_DOMAIN = \"kavachos.anonymous\";\n\n// ---------------------------------------------------------------------------\n// Factory\n// ---------------------------------------------------------------------------\n\nexport function createAnonymousAuthModule(\n\tconfig: AnonymousAuthConfig,\n\tdb: Database,\n\tsessionManager: SessionManager,\n): AnonymousAuthModule {\n\tconst sessionTtlSeconds = config.sessionTtlSeconds ?? DEFAULT_SESSION_TTL_SECONDS;\n\n\tasync function createAnonymousUser(): Promise<{ userId: string; sessionToken: string }> {\n\t\tconst userId = randomUUID();\n\t\tconst now = new Date();\n\n\t\tawait db.insert(users).values({\n\t\t\tid: userId,\n\t\t\temail: `anon_${userId}@${ANONYMOUS_EMAIL_DOMAIN}`,\n\t\t\tname: null,\n\t\t\tmetadata: { anonymous: true },\n\t\t\tcreatedAt: now,\n\t\t\tupdatedAt: now,\n\t\t});\n\n\t\tconst { token } = await sessionManager.create(userId, {\n\t\t\tanonymous: true,\n\t\t\tttl: sessionTtlSeconds,\n\t\t});\n\n\t\treturn { userId, sessionToken: token };\n\t}\n\n\tasync function upgradeUser(\n\t\tanonymousUserId: string,\n\t\tupgrade: { email: string; name?: string },\n\t): Promise<void> {\n\t\tconst rows = await db\n\t\t\t.select({ id: users.id, metadata: users.metadata })\n\t\t\t.from(users)\n\t\t\t.where(eq(users.id, anonymousUserId));\n\n\t\tconst row = rows[0];\n\t\tif (!row) {\n\t\t\tthrow new Error(`User not found: ${anonymousUserId}`);\n\t\t}\n\n\t\tconst isAnon =\n\t\t\trow.metadata !== null &&\n\t\t\ttypeof row.metadata === \"object\" &&\n\t\t\t(row.metadata as Record<string, unknown>).anonymous === true;\n\n\t\tif (!isAnon) {\n\t\t\tthrow new Error(`User ${anonymousUserId} is not an anonymous user`);\n\t\t}\n\n\t\t// Rebuild metadata without the anonymous flag (no delete operator).\n\t\tconst { anonymous: _anon, ...rest } = row.metadata as Record<string, unknown>;\n\t\tvoid _anon;\n\t\tconst updatedMetadata: Record<string, unknown> = rest;\n\n\t\tawait db\n\t\t\t.update(users)\n\t\t\t.set({\n\t\t\t\temail: upgrade.email,\n\t\t\t\tname: upgrade.name ?? null,\n\t\t\t\tmetadata: Object.keys(updatedMetadata).length > 0 ? updatedMetadata : null,\n\t\t\t\tupdatedAt: new Date(),\n\t\t\t})\n\t\t\t.where(eq(users.id, anonymousUserId));\n\t}\n\n\tasync function isAnonymous(userId: string): Promise<boolean> {\n\t\tconst rows = await db\n\t\t\t.select({ metadata: users.metadata })\n\t\t\t.from(users)\n\t\t\t.where(eq(users.id, userId));\n\n\t\tconst row = rows[0];\n\t\tif (!row) return false;\n\n\t\treturn (\n\t\t\trow.metadata !== null &&\n\t\t\ttypeof row.metadata === \"object\" &&\n\t\t\t(row.metadata as Record<string, unknown>).anonymous === true\n\t\t);\n\t}\n\n\tasync function cleanup(maxAgeMs?: number): Promise<number> {\n\t\tconst cutoff = new Date(Date.now() - (maxAgeMs ?? DEFAULT_MAX_AGE_MS));\n\n\t\t// Find anonymous users older than cutoff.\n\t\tconst allUsers = await db\n\t\t\t.select({\n\t\t\t\tid: users.id,\n\t\t\t\temail: users.email,\n\t\t\t\tmetadata: users.metadata,\n\t\t\t\tcreatedAt: users.createdAt,\n\t\t\t})\n\t\t\t.from(users)\n\t\t\t.where(lt(users.createdAt, cutoff));\n\n\t\tconst anonymousUserIds = allUsers\n\t\t\t.filter(\n\t\t\t\t(u) =>\n\t\t\t\t\tu.email.endsWith(`@${ANONYMOUS_EMAIL_DOMAIN}`) &&\n\t\t\t\t\tu.metadata !== null &&\n\t\t\t\t\ttypeof u.metadata === \"object\" &&\n\t\t\t\t\t(u.metadata as Record<string, unknown>).anonymous === true,\n\t\t\t)\n\t\t\t.map((u) => u.id);\n\n\t\tif (anonymousUserIds.length === 0) return 0;\n\n\t\t// Delete sessions first (FK constraint).\n\t\tfor (const userId of anonymousUserIds) {\n\t\t\tawait db.delete(sessions).where(eq(sessions.userId, userId));\n\t\t\tawait db.delete(users).where(and(eq(users.id, userId)));\n\t\t}\n\n\t\treturn anonymousUserIds.length;\n\t}\n\n\treturn { createAnonymousUser, upgradeUser, isAnonymous, cleanup };\n}\n","import type { KavachPlugin } from \"../plugin/types.js\";\nimport { createSessionManager } from \"../session/session.js\";\nimport type { AnonymousAuthConfig } from \"./anonymous.js\";\nimport { createAnonymousAuthModule } from \"./anonymous.js\";\n\n// ---------------------------------------------------------------------------\n// Helpers\n// ---------------------------------------------------------------------------\n\nfunction jsonResponse(body: unknown, status = 200): Response {\n\treturn new Response(JSON.stringify(body), {\n\t\tstatus,\n\t\theaders: { \"Content-Type\": \"application/json\" },\n\t});\n}\n\nasync function parseBody(request: Request): Promise<Record<string, unknown>> {\n\ttry {\n\t\treturn (await request.json()) as Record<string, unknown>;\n\t} catch {\n\t\treturn {};\n\t}\n}\n\n// ---------------------------------------------------------------------------\n// Plugin factory\n// ---------------------------------------------------------------------------\n\nexport function anonymousAuth(config?: AnonymousAuthConfig): KavachPlugin {\n\treturn {\n\t\tid: \"kavach-anonymous\",\n\n\t\tasync init(ctx): Promise<undefined> {\n\t\t\tconst sessionSecret = (\n\t\t\t\tctx.config as unknown as {\n\t\t\t\t\tauth?: { session?: { secret?: string } };\n\t\t\t\t}\n\t\t\t).auth?.session?.secret;\n\n\t\t\tif (!sessionSecret) {\n\t\t\t\tthrow new Error(\"anonymousAuth plugin requires auth.session.secret to be configured\");\n\t\t\t}\n\n\t\t\tconst sessionManager = createSessionManager({ secret: sessionSecret }, ctx.db);\n\t\t\tconst mod = createAnonymousAuthModule(config ?? {}, ctx.db, sessionManager);\n\n\t\t\t// POST /auth/anonymous\n\t\t\t// Creates a new anonymous user and returns a session token.\n\t\t\tctx.addEndpoint({\n\t\t\t\tmethod: \"POST\",\n\t\t\t\tpath: \"/auth/anonymous\",\n\t\t\t\tmetadata: {\n\t\t\t\t\tdescription: \"Create an anonymous guest user and return a session token\",\n\t\t\t\t\trateLimit: { window: 60_000, max: 20 },\n\t\t\t\t},\n\t\t\t\tasync handler(_request, _endpointCtx) {\n\t\t\t\t\ttry {\n\t\t\t\t\t\tconst result = await mod.createAnonymousUser();\n\t\t\t\t\t\treturn jsonResponse({ userId: result.userId, sessionToken: result.sessionToken });\n\t\t\t\t\t} catch (err) {\n\t\t\t\t\t\treturn jsonResponse(\n\t\t\t\t\t\t\t{ error: err instanceof Error ? err.message : \"Failed to create anonymous user\" },\n\t\t\t\t\t\t\t500,\n\t\t\t\t\t\t);\n\t\t\t\t\t}\n\t\t\t\t},\n\t\t\t});\n\n\t\t\t// POST /auth/anonymous/upgrade\n\t\t\t// Upgrades the current anonymous user to a real account.\n\t\t\tctx.addEndpoint({\n\t\t\t\tmethod: \"POST\",\n\t\t\t\tpath: \"/auth/anonymous/upgrade\",\n\t\t\t\tmetadata: {\n\t\t\t\t\trequireAuth: true,\n\t\t\t\t\tdescription: \"Upgrade an anonymous account to a real account by setting email\",\n\t\t\t\t},\n\t\t\t\tasync handler(request, endpointCtx) {\n\t\t\t\t\tconst user = await endpointCtx.getUser(request);\n\t\t\t\t\tif (!user) {\n\t\t\t\t\t\treturn jsonResponse({ error: \"Authentication required\" }, 401);\n\t\t\t\t\t}\n\n\t\t\t\t\tconst body = await parseBody(request);\n\t\t\t\t\tconst email = typeof body.email === \"string\" ? body.email.trim() : null;\n\t\t\t\t\tconst name = typeof body.name === \"string\" ? body.name.trim() : undefined;\n\n\t\t\t\t\tif (!email) {\n\t\t\t\t\t\treturn jsonResponse({ error: \"Missing required field: email\" }, 400);\n\t\t\t\t\t}\n\n\t\t\t\t\ttry {\n\t\t\t\t\t\tawait mod.upgradeUser(user.id, { email, name });\n\t\t\t\t\t\treturn jsonResponse({ upgraded: true });\n\t\t\t\t\t} catch (err) {\n\t\t\t\t\t\tconst message = err instanceof Error ? err.message : \"Upgrade failed\";\n\t\t\t\t\t\tconst status = message.includes(\"not an anonymous user\") ? 400 : 500;\n\t\t\t\t\t\treturn jsonResponse({ error: message }, status);\n\t\t\t\t\t}\n\t\t\t\t},\n\t\t\t});\n\n\t\t\t// GET /auth/anonymous/status\n\t\t\t// Returns whether the current user is anonymous.\n\t\t\tctx.addEndpoint({\n\t\t\t\tmethod: \"GET\",\n\t\t\t\tpath: \"/auth/anonymous/status\",\n\t\t\t\tmetadata: {\n\t\t\t\t\trequireAuth: true,\n\t\t\t\t\tdescription: \"Check if the authenticated user is an anonymous guest\",\n\t\t\t\t},\n\t\t\t\tasync handler(request, endpointCtx) {\n\t\t\t\t\tconst user = await endpointCtx.getUser(request);\n\t\t\t\t\tif (!user) {\n\t\t\t\t\t\treturn jsonResponse({ error: \"Authentication required\" }, 401);\n\t\t\t\t\t}\n\n\t\t\t\t\tconst anonymous = await mod.isAnonymous(user.id);\n\t\t\t\t\treturn jsonResponse({ anonymous });\n\t\t\t\t},\n\t\t\t});\n\t\t},\n\t};\n}\n","/**\n * API key management for KavachOS.\n *\n * Creates and validates static API keys with permission scopes. Keys are\n * stored as SHA-256 hashes — the full key is returned once at creation and\n * never stored. Validation tracks last-used time on every call.\n *\n * @example\n * ```typescript\n * const kavach = await createKavach({\n * database: { provider: 'sqlite', url: 'kavach.db' },\n * apiKeys: { prefix: 'kos_', defaultExpiryDays: 90 },\n * });\n *\n * const { key, apiKey } = await kavach.apiKeys.create({\n * userId: 'user_abc',\n * name: 'CI token',\n * permissions: ['agents:read'],\n * });\n * // key = 'kos_a3f8c2e1...' — show once, store nowhere\n * ```\n */\n\nimport { createHash, randomBytes, randomUUID } from \"node:crypto\";\nimport { eq } from \"drizzle-orm\";\nimport type { Database } from \"../db/database.js\";\nimport { apiKeys as apiKeysTable } from \"../db/schema.js\";\n\n// ---------------------------------------------------------------------------\n// Public types\n// ---------------------------------------------------------------------------\n\nexport interface ApiKeyManagerConfig {\n\t/** Prefix for API keys (default: \"kos_\") */\n\tprefix?: string;\n\t/** Default expiry in days (default: 365) */\n\tdefaultExpiryDays?: number;\n}\n\nexport interface ApiKey {\n\tid: string;\n\tuserId: string;\n\tname: string;\n\tprefix: string;\n\tpermissions: string[];\n\texpiresAt: Date | null;\n\tlastUsedAt: Date | null;\n\tcreatedAt: Date;\n}\n\nexport interface ApiKeyManagerModule {\n\tcreate: (input: {\n\t\tuserId: string;\n\t\tname: string;\n\t\tpermissions: string[];\n\t\texpiresAt?: Date;\n\t}) => Promise<{ apiKey: ApiKey; key: string }>;\n\tvalidate: (\n\t\tkey: string,\n\t) => Promise<{ userId: string; permissions: string[]; keyId: string } | null>;\n\t/** Validate a key and check that it has the required permission */\n\tvalidateWithScope: (\n\t\tkey: string,\n\t\trequiredPermission: string,\n\t) => Promise<{ userId: string; permissions: string[]; keyId: string } | null>;\n\tlist: (userId: string) => Promise<ApiKey[]>;\n\trevoke: (keyId: string) => Promise<void>;\n\trotate: (keyId: string) => Promise<{ apiKey: ApiKey; key: string }>;\n\thandleRequest: (request: Request) => Promise<Response | null>;\n}\n\n// ---------------------------------------------------------------------------\n// Helpers\n// ---------------------------------------------------------------------------\n\nfunction hashKey(key: string): string {\n\treturn createHash(\"sha256\").update(key).digest(\"hex\");\n}\n\n// ---------------------------------------------------------------------------\n// Row mapper\n// ---------------------------------------------------------------------------\n\ninterface ApiKeyRow {\n\tid: string;\n\tuserId: string;\n\tname: string;\n\tkeyHash: string;\n\tkeyPrefix: string;\n\tpermissions: string[];\n\texpiresAt: Date | null;\n\tlastUsedAt: Date | null;\n\tcreatedAt: Date;\n}\n\nfunction rowToApiKey(row: ApiKeyRow): ApiKey {\n\treturn {\n\t\tid: row.id,\n\t\tuserId: row.userId,\n\t\tname: row.name,\n\t\tprefix: row.keyPrefix,\n\t\tpermissions: row.permissions,\n\t\texpiresAt: row.expiresAt,\n\t\tlastUsedAt: row.lastUsedAt,\n\t\tcreatedAt: row.createdAt,\n\t};\n}\n\n// ---------------------------------------------------------------------------\n// Factory\n// ---------------------------------------------------------------------------\n\nexport function createApiKeyManagerModule(\n\tconfig: ApiKeyManagerConfig,\n\tdb: Database,\n): ApiKeyManagerModule {\n\tconst prefix = config.prefix ?? \"kos_\";\n\tconst defaultExpiryDays = config.defaultExpiryDays ?? 365;\n\n\tfunction generateKey(): string {\n\t\treturn `${prefix}${randomBytes(32).toString(\"hex\")}`;\n\t}\n\n\tfunction computeDefaultExpiry(): Date {\n\t\tconst d = new Date();\n\t\td.setDate(d.getDate() + defaultExpiryDays);\n\t\treturn d;\n\t}\n\n\tasync function create(input: {\n\t\tuserId: string;\n\t\tname: string;\n\t\tpermissions: string[];\n\t\texpiresAt?: Date;\n\t}): Promise<{ apiKey: ApiKey; key: string }> {\n\t\tconst key = generateKey();\n\t\tconst keyHash = hashKey(key);\n\t\tconst keyPrefix = key.slice(0, prefix.length + 8); // prefix + first 8 hex chars\n\t\tconst id = `key_${randomUUID().replace(/-/g, \"\")}`;\n\t\tconst now = new Date();\n\t\tconst expiresAt = input.expiresAt ?? computeDefaultExpiry();\n\n\t\tawait db.insert(apiKeysTable).values({\n\t\t\tid,\n\t\t\tuserId: input.userId,\n\t\t\tname: input.name,\n\t\t\tkeyHash,\n\t\t\tkeyPrefix,\n\t\t\tpermissions: input.permissions,\n\t\t\texpiresAt,\n\t\t\tlastUsedAt: null,\n\t\t\tcreatedAt: now,\n\t\t});\n\n\t\tconst apiKey: ApiKey = {\n\t\t\tid,\n\t\t\tuserId: input.userId,\n\t\t\tname: input.name,\n\t\t\tprefix: keyPrefix,\n\t\t\tpermissions: input.permissions,\n\t\t\texpiresAt,\n\t\t\tlastUsedAt: null,\n\t\t\tcreatedAt: now,\n\t\t};\n\n\t\treturn { apiKey, key };\n\t}\n\n\tasync function validate(\n\t\tkey: string,\n\t): Promise<{ userId: string; permissions: string[]; keyId: string } | null> {\n\t\tconst keyHash = hashKey(key);\n\t\tconst now = new Date();\n\n\t\tconst rows = await db.select().from(apiKeysTable).where(eq(apiKeysTable.keyHash, keyHash));\n\n\t\tconst row = rows[0] as ApiKeyRow | undefined;\n\t\tif (!row) return null;\n\n\t\t// Check expiry (null expiresAt = never expires)\n\t\tif (row.expiresAt !== null && row.expiresAt <= now) return null;\n\n\t\t// Update lastUsedAt (awaited to guarantee tracking)\n\t\tawait db.update(apiKeysTable).set({ lastUsedAt: now }).where(eq(apiKeysTable.id, row.id));\n\n\t\treturn {\n\t\t\tuserId: row.userId,\n\t\t\tpermissions: row.permissions,\n\t\t\tkeyId: row.id,\n\t\t};\n\t}\n\n\tasync function validateWithScope(\n\t\tkey: string,\n\t\trequiredPermission: string,\n\t): Promise<{ userId: string; permissions: string[]; keyId: string } | null> {\n\t\tconst result = await validate(key);\n\t\tif (!result) return null;\n\n\t\t// Wildcard permission grants access to everything\n\t\tif (result.permissions.includes(\"*\")) return result;\n\n\t\t// Check the specific permission\n\t\tif (!result.permissions.includes(requiredPermission)) return null;\n\n\t\treturn result;\n\t}\n\n\tasync function list(userId: string): Promise<ApiKey[]> {\n\t\tconst rows = (await db\n\t\t\t.select()\n\t\t\t.from(apiKeysTable)\n\t\t\t.where(eq(apiKeysTable.userId, userId))) as ApiKeyRow[];\n\t\treturn rows.map(rowToApiKey);\n\t}\n\n\tasync function revoke(keyId: string): Promise<void> {\n\t\tawait db.delete(apiKeysTable).where(eq(apiKeysTable.id, keyId));\n\t}\n\n\tasync function rotate(keyId: string): Promise<{ apiKey: ApiKey; key: string }> {\n\t\tconst rows = (await db\n\t\t\t.select()\n\t\t\t.from(apiKeysTable)\n\t\t\t.where(eq(apiKeysTable.id, keyId))) as ApiKeyRow[];\n\t\tconst existing = rows[0];\n\t\tif (!existing) throw new Error(`API key \"${keyId}\" not found`);\n\n\t\t// Revoke the old key\n\t\tawait revoke(keyId);\n\n\t\t// Create a new key with the same config\n\t\treturn create({\n\t\t\tuserId: existing.userId,\n\t\t\tname: existing.name,\n\t\t\tpermissions: existing.permissions,\n\t\t\texpiresAt: existing.expiresAt ?? undefined,\n\t\t});\n\t}\n\n\t// ── HTTP handler ──────────────────────────────────────────────────────────\n\n\tasync function handleRequest(request: Request): Promise<Response | null> {\n\t\tconst url = new URL(request.url);\n\t\tconst { pathname } = url;\n\t\tconst { method } = request;\n\n\t\tconst json = (data: unknown, status = 200) =>\n\t\t\tnew Response(JSON.stringify(data), {\n\t\t\t\tstatus,\n\t\t\t\theaders: { \"Content-Type\": \"application/json\" },\n\t\t\t});\n\n\t\t// POST /auth/api-keys\n\t\tif (method === \"POST\" && pathname === \"/auth/api-keys\") {\n\t\t\tlet body: unknown;\n\t\t\ttry {\n\t\t\t\tbody = await request.json();\n\t\t\t} catch {\n\t\t\t\treturn json({ error: \"Invalid JSON body\" }, 400);\n\t\t\t}\n\t\t\tconst b = body as Record<string, unknown>;\n\t\t\tif (\n\t\t\t\ttypeof b.userId !== \"string\" ||\n\t\t\t\ttypeof b.name !== \"string\" ||\n\t\t\t\t!Array.isArray(b.permissions)\n\t\t\t) {\n\t\t\t\treturn json({ error: \"Missing required fields: userId, name, permissions\" }, 400);\n\t\t\t}\n\t\t\tconst expiresAt = b.expiresAt ? new Date(b.expiresAt as string) : undefined;\n\t\t\tconst result = await create({\n\t\t\t\tuserId: b.userId,\n\t\t\t\tname: b.name,\n\t\t\t\tpermissions: b.permissions as string[],\n\t\t\t\texpiresAt,\n\t\t\t});\n\t\t\treturn json(result, 201);\n\t\t}\n\n\t\t// GET /auth/api-keys/:userId\n\t\tconst listMatch = /^\\/auth\\/api-keys\\/([^/]+)$/.exec(pathname);\n\t\tif (method === \"GET\" && listMatch) {\n\t\t\tconst userId = decodeURIComponent(listMatch[1] ?? \"\");\n\t\t\tconst keys = await list(userId);\n\t\t\treturn json(keys);\n\t\t}\n\n\t\t// DELETE /auth/api-keys/:keyId\n\t\tconst deleteMatch = /^\\/auth\\/api-keys\\/([^/]+)$/.exec(pathname);\n\t\tif (method === \"DELETE\" && deleteMatch) {\n\t\t\tconst keyId = decodeURIComponent(deleteMatch[1] ?? \"\");\n\t\t\tawait revoke(keyId);\n\t\t\treturn json({ success: true });\n\t\t}\n\n\t\t// POST /auth/api-keys/:keyId/rotate\n\t\tconst rotateMatch = /^\\/auth\\/api-keys\\/([^/]+)\\/rotate$/.exec(pathname);\n\t\tif (method === \"POST\" && rotateMatch) {\n\t\t\tconst keyId = decodeURIComponent(rotateMatch[1] ?? \"\");\n\t\t\ttry {\n\t\t\t\tconst result = await rotate(keyId);\n\t\t\t\treturn json(result);\n\t\t\t} catch (err) {\n\t\t\t\treturn json({ error: err instanceof Error ? err.message : \"Unknown error\" }, 404);\n\t\t\t}\n\t\t}\n\n\t\treturn null;\n\t}\n\n\treturn {\n\t\tcreate,\n\t\tvalidate,\n\t\tvalidateWithScope,\n\t\tlist,\n\t\trevoke,\n\t\trotate,\n\t\thandleRequest,\n\t};\n}\n","import type { KavachPlugin } from \"../plugin/types.js\";\nimport type { ApiKeyManagerConfig } from \"./api-key-manager.js\";\nimport { createApiKeyManagerModule } from \"./api-key-manager.js\";\n\nexport type { ApiKeyManagerConfig };\n\n// ---------------------------------------------------------------------------\n// Helpers\n// ---------------------------------------------------------------------------\n\nfunction jsonResponse(body: unknown, status = 200): Response {\n\treturn new Response(JSON.stringify(body), {\n\t\tstatus,\n\t\theaders: { \"Content-Type\": \"application/json\" },\n\t});\n}\n\nasync function parseBody(request: Request): Promise<Record<string, unknown>> {\n\ttry {\n\t\treturn (await request.json()) as Record<string, unknown>;\n\t} catch {\n\t\treturn {};\n\t}\n}\n\n// ---------------------------------------------------------------------------\n// Plugin factory\n// ---------------------------------------------------------------------------\n\nexport function apiKeys(config?: ApiKeyManagerConfig): KavachPlugin {\n\treturn {\n\t\tid: \"kavach-api-key\",\n\n\t\tasync init(ctx): Promise<undefined> {\n\t\t\tconst module = createApiKeyManagerModule(config ?? {}, ctx.db);\n\n\t\t\t// POST /auth/api-keys\n\t\t\t// Creates a new API key for the authenticated user. Returns the full\n\t\t\t// key once — it is never stored in plaintext and cannot be retrieved again.\n\t\t\tctx.addEndpoint({\n\t\t\t\tmethod: \"POST\",\n\t\t\t\tpath: \"/auth/api-keys\",\n\t\t\t\tmetadata: {\n\t\t\t\t\trequireAuth: true,\n\t\t\t\t\tdescription: \"Create a new API key for the authenticated user\",\n\t\t\t\t},\n\t\t\t\tasync handler(request, endpointCtx) {\n\t\t\t\t\tconst user = await endpointCtx.getUser(request);\n\t\t\t\t\tif (!user) {\n\t\t\t\t\t\treturn jsonResponse({ error: \"Authentication required\" }, 401);\n\t\t\t\t\t}\n\n\t\t\t\t\tconst body = await parseBody(request);\n\t\t\t\t\tconst name = typeof body.name === \"string\" ? body.name.trim() : null;\n\t\t\t\t\tconst permissions = Array.isArray(body.permissions) ? body.permissions : null;\n\n\t\t\t\t\tif (!name || !permissions) {\n\t\t\t\t\t\treturn jsonResponse({ error: \"Missing required fields: name, permissions\" }, 400);\n\t\t\t\t\t}\n\n\t\t\t\t\tconst expiresAt = body.expiresAt ? new Date(body.expiresAt as string) : undefined;\n\n\t\t\t\t\ttry {\n\t\t\t\t\t\tconst result = await module.create({\n\t\t\t\t\t\t\tuserId: user.id,\n\t\t\t\t\t\t\tname,\n\t\t\t\t\t\t\tpermissions: permissions as string[],\n\t\t\t\t\t\t\texpiresAt,\n\t\t\t\t\t\t});\n\t\t\t\t\t\treturn jsonResponse(result, 201);\n\t\t\t\t\t} catch (err) {\n\t\t\t\t\t\treturn jsonResponse(\n\t\t\t\t\t\t\t{ error: err instanceof Error ? err.message : \"Failed to create API key\" },\n\t\t\t\t\t\t\t500,\n\t\t\t\t\t\t);\n\t\t\t\t\t}\n\t\t\t\t},\n\t\t\t});\n\n\t\t\t// GET /auth/api-keys\n\t\t\t// Lists all API keys for the authenticated user (hashes and prefixes only —\n\t\t\t// full keys are never returned after creation).\n\t\t\tctx.addEndpoint({\n\t\t\t\tmethod: \"GET\",\n\t\t\t\tpath: \"/auth/api-keys\",\n\t\t\t\tmetadata: {\n\t\t\t\t\trequireAuth: true,\n\t\t\t\t\tdescription: \"List API keys for the authenticated user\",\n\t\t\t\t},\n\t\t\t\tasync handler(request, endpointCtx) {\n\t\t\t\t\tconst user = await endpointCtx.getUser(request);\n\t\t\t\t\tif (!user) {\n\t\t\t\t\t\treturn jsonResponse({ error: \"Authentication required\" }, 401);\n\t\t\t\t\t}\n\n\t\t\t\t\tconst keys = await module.list(user.id);\n\t\t\t\t\treturn jsonResponse({ apiKeys: keys });\n\t\t\t\t},\n\t\t\t});\n\n\t\t\t// DELETE /auth/api-keys/:id\n\t\t\t// Revokes an API key. The key must belong to the authenticated user.\n\t\t\tctx.addEndpoint({\n\t\t\t\tmethod: \"DELETE\",\n\t\t\t\tpath: \"/auth/api-keys/:id\",\n\t\t\t\tmetadata: {\n\t\t\t\t\trequireAuth: true,\n\t\t\t\t\tdescription: \"Revoke an API key for the authenticated user\",\n\t\t\t\t},\n\t\t\t\tasync handler(request, endpointCtx) {\n\t\t\t\t\tconst user = await endpointCtx.getUser(request);\n\t\t\t\t\tif (!user) {\n\t\t\t\t\t\treturn jsonResponse({ error: \"Authentication required\" }, 401);\n\t\t\t\t\t}\n\n\t\t\t\t\tconst url = new URL(request.url);\n\t\t\t\t\tconst segments = url.pathname.split(\"/\").filter(Boolean);\n\t\t\t\t\t// Expected: [\"auth\", \"api-keys\", \"<id>\"]\n\t\t\t\t\tconst keyId = segments[2];\n\n\t\t\t\t\tif (!keyId) {\n\t\t\t\t\t\treturn jsonResponse({ error: \"Missing API key ID in path\" }, 400);\n\t\t\t\t\t}\n\n\t\t\t\t\t// Confirm ownership before revoking.\n\t\t\t\t\tconst keys = await module.list(user.id);\n\t\t\t\t\tconst owned = keys.some((k) => k.id === decodeURIComponent(keyId));\n\t\t\t\t\tif (!owned) {\n\t\t\t\t\t\treturn jsonResponse({ error: \"API key not found\" }, 404);\n\t\t\t\t\t}\n\n\t\t\t\t\tawait module.revoke(decodeURIComponent(keyId));\n\t\t\t\t\treturn jsonResponse({ revoked: true });\n\t\t\t\t},\n\t\t\t});\n\n\t\t\t// POST /auth/api-keys/:id/rotate\n\t\t\t// Revokes the existing key and issues a new one with identical settings.\n\t\t\t// Returns the new key once — the same one-time-display rule applies.\n\t\t\tctx.addEndpoint({\n\t\t\t\tmethod: \"POST\",\n\t\t\t\tpath: \"/auth/api-keys/:id/rotate\",\n\t\t\t\tmetadata: {\n\t\t\t\t\trequireAuth: true,\n\t\t\t\t\tdescription: \"Rotate an API key — revokes the old one and returns a new key\",\n\t\t\t\t},\n\t\t\t\tasync handler(request, endpointCtx) {\n\t\t\t\t\tconst user = await endpointCtx.getUser(request);\n\t\t\t\t\tif (!user) {\n\t\t\t\t\t\treturn jsonResponse({ error: \"Authentication required\" }, 401);\n\t\t\t\t\t}\n\n\t\t\t\t\tconst url = new URL(request.url);\n\t\t\t\t\tconst segments = url.pathname.split(\"/\").filter(Boolean);\n\t\t\t\t\t// Expected: [\"auth\", \"api-keys\", \"<id>\", \"rotate\"]\n\t\t\t\t\tconst keyId = segments[2];\n\n\t\t\t\t\tif (!keyId) {\n\t\t\t\t\t\treturn jsonResponse({ error: \"Missing API key ID in path\" }, 400);\n\t\t\t\t\t}\n\n\t\t\t\t\t// Confirm ownership before rotating.\n\t\t\t\t\tconst keys = await module.list(user.id);\n\t\t\t\t\tconst owned = keys.some((k) => k.id === decodeURIComponent(keyId));\n\t\t\t\t\tif (!owned) {\n\t\t\t\t\t\treturn jsonResponse({ error: \"API key not found\" }, 404);\n\t\t\t\t\t}\n\n\t\t\t\t\ttry {\n\t\t\t\t\t\tconst result = await module.rotate(decodeURIComponent(keyId));\n\t\t\t\t\t\treturn jsonResponse(result);\n\t\t\t\t\t} catch (err) {\n\t\t\t\t\t\treturn jsonResponse(\n\t\t\t\t\t\t\t{ error: err instanceof Error ? err.message : \"Failed to rotate API key\" },\n\t\t\t\t\t\t\t400,\n\t\t\t\t\t\t);\n\t\t\t\t\t}\n\t\t\t\t},\n\t\t\t});\n\t\t},\n\t};\n}\n","/**\n * Captcha integration for KavachOS.\n *\n * Supports reCAPTCHA v2/v3, hCaptcha, and Cloudflare Turnstile. All three\n * providers share the same verification pattern: POST form-encoded data with\n * `secret` and `response` (the client token) to a provider-specific endpoint.\n *\n * @example\n * ```typescript\n * const kavach = await createKavach({\n * database: { provider: 'sqlite', url: 'kavach.db' },\n * captcha: {\n * provider: 'turnstile',\n * secretKey: process.env.TURNSTILE_SECRET,\n * },\n * });\n *\n * // In a route handler\n * const captchaToken = request.headers.get('X-Captcha-Token') ?? '';\n * const result = await kavach.captcha?.verify(captchaToken);\n * if (!result?.success) return new Response('Captcha failed', { status: 403 });\n * ```\n */\n\n// ---------------------------------------------------------------------------\n// Public types\n// ---------------------------------------------------------------------------\n\nexport interface CaptchaConfig {\n\t/** Captcha provider */\n\tprovider: \"recaptcha\" | \"hcaptcha\" | \"turnstile\";\n\t/** Secret key from the provider dashboard */\n\tsecretKey: string;\n\t/**\n\t * Auth endpoint names that require captcha verification.\n\t * Default: ['sign-up', 'sign-in', 'reset-password']\n\t */\n\tprotectedEndpoints?: string[];\n\t/**\n\t * Minimum score for reCAPTCHA v3 (0.0 to 1.0).\n\t * Requests scoring below this are rejected. Default: 0.5\n\t */\n\tminScore?: number;\n}\n\nexport interface CaptchaVerifyResult {\n\tsuccess: boolean;\n\tscore?: number;\n\terror?: string;\n}\n\nexport interface CaptchaModule {\n\t/** Verify a client-side captcha token. */\n\tverify: (token: string, ip?: string) => Promise<CaptchaVerifyResult>;\n\t/**\n\t * Check the captcha token from the request's `X-Captcha-Token` header.\n\t * Returns `{ valid: false }` when the header is missing or verification fails.\n\t */\n\tmiddleware: (request: Request) => Promise<{ valid: boolean; error?: string }>;\n}\n\n// ---------------------------------------------------------------------------\n// Provider endpoints\n// ---------------------------------------------------------------------------\n\nconst PROVIDER_URLS: Record<CaptchaConfig[\"provider\"], string> = {\n\trecaptcha: \"https://www.google.com/recaptcha/api/siteverify\",\n\thcaptcha: \"https://hcaptcha.com/siteverify\",\n\tturnstile: \"https://challenges.cloudflare.com/turnstile/v0/siteverify\",\n};\n\n// ---------------------------------------------------------------------------\n// Types for provider responses\n// ---------------------------------------------------------------------------\n\ninterface RecaptchaResponse {\n\tsuccess: boolean;\n\tscore?: number;\n\taction?: string;\n\tchallenge_ts?: string;\n\thostname?: string;\n\t\"error-codes\"?: string[];\n}\n\ninterface HcaptchaResponse {\n\tsuccess: boolean;\n\tscore?: number;\n\t\"error-codes\"?: string[];\n}\n\ninterface TurnstileResponse {\n\tsuccess: boolean;\n\t\"error-codes\"?: string[];\n}\n\ntype ProviderResponse = RecaptchaResponse | HcaptchaResponse | TurnstileResponse;\n\n// ---------------------------------------------------------------------------\n// Defaults\n// ---------------------------------------------------------------------------\n\n// const DEFAULT_PROTECTED_ENDPOINTS = [\"sign-up\", \"sign-in\", \"reset-password\"];\nconst DEFAULT_MIN_SCORE = 0.5;\n\n// ---------------------------------------------------------------------------\n// Factory\n// ---------------------------------------------------------------------------\n\nexport function createCaptchaModule(config: CaptchaConfig): CaptchaModule {\n\tconst verifyUrl = PROVIDER_URLS[config.provider];\n\tconst minScore = config.minScore ?? DEFAULT_MIN_SCORE;\n\n\tasync function verify(token: string, ip?: string): Promise<CaptchaVerifyResult> {\n\t\tif (!token) {\n\t\t\treturn { success: false, error: \"Missing captcha token\" };\n\t\t}\n\n\t\tconst params = new URLSearchParams({\n\t\t\tsecret: config.secretKey,\n\t\t\tresponse: token,\n\t\t});\n\n\t\tif (ip) {\n\t\t\tparams.set(\"remoteip\", ip);\n\t\t}\n\n\t\tlet data: ProviderResponse;\n\t\ttry {\n\t\t\tconst response = await fetch(verifyUrl, {\n\t\t\t\tmethod: \"POST\",\n\t\t\t\theaders: { \"Content-Type\": \"application/x-www-form-urlencoded\" },\n\t\t\t\tbody: params.toString(),\n\t\t\t});\n\n\t\t\tif (!response.ok) {\n\t\t\t\treturn {\n\t\t\t\t\tsuccess: false,\n\t\t\t\t\terror: `Provider returned HTTP ${response.status}`,\n\t\t\t\t};\n\t\t\t}\n\n\t\t\tdata = (await response.json()) as ProviderResponse;\n\t\t} catch (err) {\n\t\t\treturn {\n\t\t\t\tsuccess: false,\n\t\t\t\terror: err instanceof Error ? err.message : \"Network error\",\n\t\t\t};\n\t\t}\n\n\t\tif (!data.success) {\n\t\t\tconst codes =\n\t\t\t\t\"error-codes\" in data && Array.isArray(data[\"error-codes\"])\n\t\t\t\t\t? (data[\"error-codes\"] as string[]).join(\", \")\n\t\t\t\t\t: \"unknown\";\n\t\t\treturn { success: false, error: `Captcha failed: ${codes}` };\n\t\t}\n\n\t\t// reCAPTCHA v3 score check\n\t\tif (config.provider === \"recaptcha\" && \"score\" in data && data.score !== undefined) {\n\t\t\tconst score = data.score;\n\t\t\tif (score < minScore) {\n\t\t\t\treturn {\n\t\t\t\t\tsuccess: false,\n\t\t\t\t\tscore,\n\t\t\t\t\terror: `Score ${score} below minimum ${minScore}`,\n\t\t\t\t};\n\t\t\t}\n\t\t\treturn { success: true, score };\n\t\t}\n\n\t\t// hCaptcha may return a score\n\t\tif (config.provider === \"hcaptcha\" && \"score\" in data && data.score !== undefined) {\n\t\t\treturn { success: true, score: data.score };\n\t\t}\n\n\t\treturn { success: true };\n\t}\n\n\tasync function middleware(request: Request): Promise<{ valid: boolean; error?: string }> {\n\t\tconst token = request.headers.get(\"X-Captcha-Token\");\n\t\tif (!token) {\n\t\t\treturn { valid: false, error: \"Missing X-Captcha-Token header\" };\n\t\t}\n\n\t\tconst ip =\n\t\t\trequest.headers.get(\"CF-Connecting-IP\") ??\n\t\t\trequest.headers.get(\"X-Forwarded-For\")?.split(\",\")[0]?.trim() ??\n\t\t\tundefined;\n\n\t\tconst result = await verify(token, ip);\n\t\treturn result.success ? { valid: true } : { valid: false, error: result.error };\n\t}\n\n\treturn { verify, middleware };\n}\n","/**\n * Custom session fields plugin for KavachOS.\n *\n * Lets callers attach arbitrary data to sessions at creation time and read or\n * update that data later. Everything is stored in the existing\n * `session.metadata.custom` sub-key — no new database columns are required.\n *\n * Two integration points:\n *\n * 1. `defaultFields` — merged into every new session automatically.\n * 2. `onSessionCreate` — async callback that receives the userId (and\n * optionally the originating Request) and returns additional fields to\n * merge. Runs once per session, during the plugin's `onSessionCreate` hook.\n *\n * @example\n * ```typescript\n * import { createKavach } from 'kavachos';\n * import { customSession } from 'kavachos/auth';\n *\n * const kavach = await createKavach({\n * database: { provider: 'sqlite', url: 'kavach.db' },\n * auth: { session: { secret: process.env.SESSION_SECRET } },\n * plugins: [\n * customSession({\n * defaultFields: { theme: 'dark' },\n * onSessionCreate: async (userId) => ({ lastSeen: Date.now() }),\n * }),\n * ],\n * });\n *\n * // After a session is created via kavach.auth.session.create(...)\n * const mod = kavach.plugins.getContext().customSession as CustomSessionModule;\n * const fields = await mod.getSessionFields(session.id);\n * // => { theme: 'dark', lastSeen: 1234567890 }\n * ```\n */\n\nimport { eq } from \"drizzle-orm\";\nimport type { Database } from \"../db/database.js\";\nimport { sessions } from \"../db/schema.js\";\nimport type { KavachPlugin } from \"../plugin/types.js\";\n\n// ---------------------------------------------------------------------------\n// Public types\n// ---------------------------------------------------------------------------\n\nexport interface CustomSessionConfig {\n\t/** Fields merged into every new session's metadata.custom on creation. */\n\tdefaultFields?: Record<string, unknown>;\n\t/**\n\t * Hook called when a new session is being created.\n\t *\n\t * The return value is merged into `session.metadata.custom` alongside any\n\t * `defaultFields`. If both define the same key, the hook's value wins.\n\t */\n\tonSessionCreate?: (userId: string, request?: Request) => Promise<Record<string, unknown>>;\n}\n\nexport interface CustomSessionModule {\n\t/**\n\t * Return the custom fields stored in `session.metadata.custom`.\n\t *\n\t * Returns `null` when the session does not exist or has no custom data.\n\t */\n\tgetSessionFields(sessionId: string): Promise<Record<string, unknown> | null>;\n\t/**\n\t * Merge `fields` into `session.metadata.custom`, overwriting any keys that\n\t * already exist. Existing keys not present in `fields` are preserved.\n\t */\n\tupdateSessionFields(sessionId: string, fields: Record<string, unknown>): Promise<void>;\n}\n\n// ---------------------------------------------------------------------------\n// Module factory (used directly or via the KavachPlugin wrapper below)\n// ---------------------------------------------------------------------------\n\nexport function createCustomSessionModule(\n\t_config: CustomSessionConfig,\n\tdb: Database,\n): CustomSessionModule {\n\tasync function getSessionFields(sessionId: string): Promise<Record<string, unknown> | null> {\n\t\tconst rows = await db\n\t\t\t.select({ metadata: sessions.metadata })\n\t\t\t.from(sessions)\n\t\t\t.where(eq(sessions.id, sessionId));\n\n\t\tconst row = rows[0];\n\t\tif (!row) return null;\n\n\t\tconst meta = row.metadata;\n\t\tif (meta === null || meta === undefined) return null;\n\n\t\tconst custom = (meta as Record<string, unknown>).custom;\n\t\tif (custom === undefined || custom === null) return null;\n\t\tif (typeof custom !== \"object\" || Array.isArray(custom)) return null;\n\n\t\treturn custom as Record<string, unknown>;\n\t}\n\n\tasync function updateSessionFields(\n\t\tsessionId: string,\n\t\tfields: Record<string, unknown>,\n\t): Promise<void> {\n\t\tconst rows = await db\n\t\t\t.select({ metadata: sessions.metadata })\n\t\t\t.from(sessions)\n\t\t\t.where(eq(sessions.id, sessionId));\n\n\t\tconst row = rows[0];\n\t\tif (!row) {\n\t\t\tthrow new Error(`CustomSessionModule: session not found: ${sessionId}`);\n\t\t}\n\n\t\tconst existing = (row.metadata ?? {}) as Record<string, unknown>;\n\t\tconst existingCustom =\n\t\t\texisting.custom !== null &&\n\t\t\texisting.custom !== undefined &&\n\t\t\ttypeof existing.custom === \"object\" &&\n\t\t\t!Array.isArray(existing.custom)\n\t\t\t\t? (existing.custom as Record<string, unknown>)\n\t\t\t\t: {};\n\n\t\tconst updatedMeta: Record<string, unknown> = {\n\t\t\t...existing,\n\t\t\tcustom: { ...existingCustom, ...fields },\n\t\t};\n\n\t\tawait db.update(sessions).set({ metadata: updatedMeta }).where(eq(sessions.id, sessionId));\n\t}\n\n\treturn { getSessionFields, updateSessionFields };\n}\n\n// ---------------------------------------------------------------------------\n// Plugin factory\n// ---------------------------------------------------------------------------\n\nexport function customSession(config: CustomSessionConfig = {}): KavachPlugin {\n\treturn {\n\t\tid: \"kavach-custom-session\",\n\n\t\thooks: {\n\t\t\t/**\n\t\t\t * Fired by the plugin runner after a session record is inserted.\n\t\t\t *\n\t\t\t * Merges defaultFields + onSessionCreate result into\n\t\t\t * `session.metadata.custom`. The session row already exists in the\n\t\t\t * database at this point so we can issue an UPDATE.\n\t\t\t */\n\t\t\tasync onSessionCreate(userId: string): Promise<Record<string, unknown> | undefined> {\n\t\t\t\tconst base = config.defaultFields ?? {};\n\t\t\t\tconst dynamic = config.onSessionCreate ? await config.onSessionCreate(userId) : {};\n\t\t\t\tconst merged = { ...base, ...dynamic };\n\n\t\t\t\t// Return the custom key so the runner can merge it into metadata.\n\t\t\t\t// We signal the presence of custom fields via the return value.\n\t\t\t\tif (Object.keys(merged).length === 0) return undefined;\n\t\t\t\treturn { custom: merged };\n\t\t\t},\n\t\t},\n\n\t\tasync init(ctx) {\n\t\t\tconst mod = createCustomSessionModule(config, ctx.db);\n\n\t\t\t// GET /auth/session/:id/fields — read custom fields from a session\n\t\t\tctx.addEndpoint({\n\t\t\t\tmethod: \"GET\",\n\t\t\t\tpath: \"/auth/session/fields\",\n\t\t\t\tmetadata: {\n\t\t\t\t\trequireAuth: true,\n\t\t\t\t\tdescription: \"Get custom fields for the authenticated session\",\n\t\t\t\t},\n\t\t\t\tasync handler(request, _endpointCtx) {\n\t\t\t\t\t// Expect ?sessionId=<id> query param\n\t\t\t\t\tconst url = new URL(request.url);\n\t\t\t\t\tconst sessionId = url.searchParams.get(\"sessionId\");\n\t\t\t\t\tif (!sessionId) {\n\t\t\t\t\t\treturn jsonResponse({ error: \"Missing required query parameter: sessionId\" }, 400);\n\t\t\t\t\t}\n\n\t\t\t\t\ttry {\n\t\t\t\t\t\tconst fields = await mod.getSessionFields(sessionId);\n\t\t\t\t\t\treturn jsonResponse({ fields: fields ?? {} });\n\t\t\t\t\t} catch (err) {\n\t\t\t\t\t\treturn jsonResponse(\n\t\t\t\t\t\t\t{ error: err instanceof Error ? err.message : \"Failed to get session fields\" },\n\t\t\t\t\t\t\t500,\n\t\t\t\t\t\t);\n\t\t\t\t\t}\n\t\t\t\t},\n\t\t\t});\n\n\t\t\t// PATCH /auth/session/fields — update custom fields on a session\n\t\t\tctx.addEndpoint({\n\t\t\t\tmethod: \"PATCH\",\n\t\t\t\tpath: \"/auth/session/fields\",\n\t\t\t\tmetadata: {\n\t\t\t\t\trequireAuth: true,\n\t\t\t\t\tdescription: \"Update custom fields on a session\",\n\t\t\t\t},\n\t\t\t\tasync handler(request, _endpointCtx) {\n\t\t\t\t\tlet body: Record<string, unknown>;\n\t\t\t\t\ttry {\n\t\t\t\t\t\tbody = (await request.json()) as Record<string, unknown>;\n\t\t\t\t\t} catch {\n\t\t\t\t\t\treturn jsonResponse({ error: \"Invalid JSON body\" }, 400);\n\t\t\t\t\t}\n\n\t\t\t\t\tconst sessionId = typeof body.sessionId === \"string\" ? body.sessionId : null;\n\t\t\t\t\tif (!sessionId) {\n\t\t\t\t\t\treturn jsonResponse({ error: \"Missing required field: sessionId\" }, 400);\n\t\t\t\t\t}\n\n\t\t\t\t\tconst fields =\n\t\t\t\t\t\tbody.fields !== null &&\n\t\t\t\t\t\tbody.fields !== undefined &&\n\t\t\t\t\t\ttypeof body.fields === \"object\" &&\n\t\t\t\t\t\t!Array.isArray(body.fields)\n\t\t\t\t\t\t\t? (body.fields as Record<string, unknown>)\n\t\t\t\t\t\t\t: null;\n\n\t\t\t\t\tif (!fields) {\n\t\t\t\t\t\treturn jsonResponse({ error: \"Missing or invalid field: fields\" }, 400);\n\t\t\t\t\t}\n\n\t\t\t\t\ttry {\n\t\t\t\t\t\tawait mod.updateSessionFields(sessionId, fields);\n\t\t\t\t\t\treturn jsonResponse({ updated: true });\n\t\t\t\t\t} catch (err) {\n\t\t\t\t\t\tconst message = err instanceof Error ? err.message : \"Update failed\";\n\t\t\t\t\t\tconst status = message.includes(\"not found\") ? 404 : 500;\n\t\t\t\t\t\treturn jsonResponse({ error: message }, status);\n\t\t\t\t\t}\n\t\t\t\t},\n\t\t\t});\n\n\t\t\treturn {\n\t\t\t\tcontext: { customSession: mod },\n\t\t\t};\n\t\t},\n\t};\n}\n\n// ---------------------------------------------------------------------------\n// Helpers\n// ---------------------------------------------------------------------------\n\nfunction jsonResponse(body: unknown, status = 200): Response {\n\treturn new Response(JSON.stringify(body), {\n\t\tstatus,\n\t\theaders: { \"Content-Type\": \"application/json\" },\n\t});\n}\n","/**\n * OAuth Device Authorization Grant (RFC 8628) for KavachOS.\n *\n * Supports TVs, CLI tools, smart displays, and any device where the user\n * cannot easily type a URL or complete an interactive login flow. The device\n * requests a short code, the user approves on a secondary device (phone /\n * browser), and the original device polls until authorization is granted.\n *\n * @example\n * ```typescript\n * const deviceAuth = createDeviceAuthModule({\n * verificationUri: 'https://example.com/device',\n * });\n *\n * // 1. CLI tool requests codes\n * const { userCode, verificationUri } = await deviceAuth.requestCode();\n * console.log(`Visit ${verificationUri} and enter: ${userCode}`);\n *\n * // 2. Poll from CLI\n * const status = await deviceAuth.checkAuthorization(deviceCode);\n *\n * // 3. User approves on browser after logging in\n * await deviceAuth.authorize(userCode, userId);\n * ```\n */\n\nimport { randomBytes } from \"node:crypto\";\n\n// ---------------------------------------------------------------------------\n// Public types\n// ---------------------------------------------------------------------------\n\nexport interface DeviceAuthConfig {\n\t/** Code length for the human-readable user code segment (default: 4, produces \"XXXX-XXXX\") */\n\tcodeLength?: number;\n\t/** Code expiry in seconds (default: 900 = 15 min) */\n\tcodeExpirySeconds?: number;\n\t/** Polling interval in seconds (default: 5) */\n\tpollIntervalSeconds?: number;\n\t/** Verification URL shown to user */\n\tverificationUri: string;\n}\n\nexport interface DeviceCodeResponse {\n\tdeviceCode: string;\n\tuserCode: string;\n\tverificationUri: string;\n\tverificationUriComplete: string;\n\texpiresIn: number;\n\tinterval: number;\n}\n\nexport type DeviceAuthStatus =\n\t| { status: \"pending\" }\n\t| { status: \"authorized\"; userId: string }\n\t| { status: \"expired\" }\n\t| { status: \"denied\" };\n\nexport interface DeviceAuthModule {\n\t/** Start device auth flow: returns device_code, user_code, verification_uri */\n\trequestCode(): Promise<DeviceCodeResponse>;\n\t/** Check if user has authorized (called by polling device) */\n\tcheckAuthorization(deviceCode: string): Promise<DeviceAuthStatus>;\n\t/** Authorize a device (called after user logs in on phone/browser) */\n\tauthorize(userCode: string, userId: string): Promise<void>;\n\t/** Deny a device code (user explicitly rejects) */\n\tdeny(userCode: string): Promise<void>;\n\t/** Handle HTTP requests for the device auth endpoints */\n\thandleRequest(request: Request): Promise<Response | null>;\n}\n\n// ---------------------------------------------------------------------------\n// Internal types\n// ---------------------------------------------------------------------------\n\ntype DeviceGrantState = \"pending\" | \"authorized\" | \"denied\";\n\ninterface DeviceGrant {\n\tdeviceCode: string;\n\tuserCode: string;\n\texpiresAt: number;\n\tstate: DeviceGrantState;\n\tuserId?: string;\n\t/** Tracks last poll time for slow_down detection */\n\tlastPolledAt?: number;\n}\n\n// ---------------------------------------------------------------------------\n// Constants\n// ---------------------------------------------------------------------------\n\nconst DEFAULT_CODE_LENGTH = 4;\nconst DEFAULT_CODE_EXPIRY_SECONDS = 900;\nconst DEFAULT_POLL_INTERVAL_SECONDS = 5;\nconst USER_CODE_ALPHABET = \"BCDFGHJKLMNPQRSTVWXZ\"; // consonants only, avoids ambiguous chars\n// Minimum ms between polls before we ask the client to slow down\nconst SLOW_DOWN_THRESHOLD_MS = 4_000;\n\n// ---------------------------------------------------------------------------\n// Helpers\n// ---------------------------------------------------------------------------\n\nfunction jsonResponse(body: unknown, status = 200): Response {\n\treturn new Response(JSON.stringify(body), {\n\t\tstatus,\n\t\theaders: { \"Content-Type\": \"application/json\" },\n\t});\n}\n\nasync function parseBody(request: Request): Promise<Record<string, unknown>> {\n\ttry {\n\t\treturn (await request.json()) as Record<string, unknown>;\n\t} catch {\n\t\treturn {};\n\t}\n}\n\nfunction generateDeviceCode(): string {\n\treturn randomBytes(32).toString(\"hex\");\n}\n\n/**\n * Generate a human-readable user code of the form \"XXXX-XXXX\".\n * Uses a consonant-only alphabet to avoid ambiguous characters and\n * accidental profanity.\n */\nfunction generateUserCode(segmentLength: number): string {\n\tconst bytes = randomBytes(segmentLength * 2);\n\tconst chars: string[] = [];\n\tfor (let i = 0; i < segmentLength * 2; i++) {\n\t\tconst byte = bytes[i] ?? 0;\n\t\tconst char = USER_CODE_ALPHABET[byte % USER_CODE_ALPHABET.length] ?? \"B\";\n\t\tchars.push(char);\n\t}\n\treturn `${chars.slice(0, segmentLength).join(\"\")}-${chars.slice(segmentLength).join(\"\")}`;\n}\n\nfunction normaliseUserCode(raw: string): string {\n\treturn raw.trim().toUpperCase().replace(/[\\s-]/g, \"\");\n}\n\n// ---------------------------------------------------------------------------\n// Factory\n// ---------------------------------------------------------------------------\n\nexport function createDeviceAuthModule(config: DeviceAuthConfig): DeviceAuthModule {\n\tconst segmentLength = config.codeLength ?? DEFAULT_CODE_LENGTH;\n\tconst codeExpiryMs = (config.codeExpirySeconds ?? DEFAULT_CODE_EXPIRY_SECONDS) * 1000;\n\tconst pollIntervalSeconds = config.pollIntervalSeconds ?? DEFAULT_POLL_INTERVAL_SECONDS;\n\n\t// In-memory grant store: deviceCode -> DeviceGrant\n\tconst grantsByDevice = new Map<string, DeviceGrant>();\n\t// Secondary index: normalised userCode -> deviceCode\n\tconst deviceByUserCode = new Map<string, string>();\n\n\tfunction purgeExpired(): void {\n\t\tconst now = Date.now();\n\t\tfor (const [deviceCode, grant] of grantsByDevice) {\n\t\t\tif (grant.expiresAt <= now) {\n\t\t\t\tdeviceByUserCode.delete(normaliseUserCode(grant.userCode));\n\t\t\t\tgrantsByDevice.delete(deviceCode);\n\t\t\t}\n\t\t}\n\t}\n\n\tasync function requestCode(): Promise<DeviceCodeResponse> {\n\t\tpurgeExpired();\n\n\t\tconst deviceCode = generateDeviceCode();\n\t\tconst userCode = generateUserCode(segmentLength);\n\t\tconst expiresAt = Date.now() + codeExpiryMs;\n\n\t\tconst grant: DeviceGrant = {\n\t\t\tdeviceCode,\n\t\t\tuserCode,\n\t\t\texpiresAt,\n\t\t\tstate: \"pending\",\n\t\t};\n\n\t\tgrantsByDevice.set(deviceCode, grant);\n\t\tdeviceByUserCode.set(normaliseUserCode(userCode), deviceCode);\n\n\t\tconst verificationUriComplete = `${config.verificationUri}?user_code=${encodeURIComponent(userCode)}`;\n\n\t\treturn {\n\t\t\tdeviceCode,\n\t\t\tuserCode,\n\t\t\tverificationUri: config.verificationUri,\n\t\t\tverificationUriComplete,\n\t\t\texpiresIn: Math.floor(codeExpiryMs / 1000),\n\t\t\tinterval: pollIntervalSeconds,\n\t\t};\n\t}\n\n\tasync function checkAuthorization(deviceCode: string): Promise<DeviceAuthStatus> {\n\t\tpurgeExpired();\n\n\t\tconst grant = grantsByDevice.get(deviceCode);\n\n\t\tif (!grant) {\n\t\t\t// Code was never issued or already purged after expiry\n\t\t\treturn { status: \"expired\" };\n\t\t}\n\n\t\tif (grant.expiresAt <= Date.now()) {\n\t\t\tdeviceByUserCode.delete(normaliseUserCode(grant.userCode));\n\t\t\tgrantsByDevice.delete(deviceCode);\n\t\t\treturn { status: \"expired\" };\n\t\t}\n\n\t\tconst now = Date.now();\n\n\t\tif (grant.state === \"authorized\" && grant.userId) {\n\t\t\treturn { status: \"authorized\", userId: grant.userId };\n\t\t}\n\n\t\tif (grant.state === \"denied\") {\n\t\t\treturn { status: \"denied\" };\n\t\t}\n\n\t\t// Update last polled time (for slow_down detection upstream)\n\t\tgrant.lastPolledAt = now;\n\n\t\treturn { status: \"pending\" };\n\t}\n\n\tasync function authorize(userCode: string, userId: string): Promise<void> {\n\t\tpurgeExpired();\n\n\t\tconst normalised = normaliseUserCode(userCode);\n\t\tconst deviceCode = deviceByUserCode.get(normalised);\n\n\t\tif (!deviceCode) {\n\t\t\tthrow new Error(\"User code not found or expired\");\n\t\t}\n\n\t\tconst grant = grantsByDevice.get(deviceCode);\n\t\tif (!grant || grant.expiresAt <= Date.now()) {\n\t\t\tdeviceByUserCode.delete(normalised);\n\t\t\tif (deviceCode) grantsByDevice.delete(deviceCode);\n\t\t\tthrow new Error(\"Device code expired\");\n\t\t}\n\n\t\tif (grant.state !== \"pending\") {\n\t\t\tthrow new Error(`Device code already ${grant.state}`);\n\t\t}\n\n\t\tgrant.state = \"authorized\";\n\t\tgrant.userId = userId;\n\t}\n\n\tasync function deny(userCode: string): Promise<void> {\n\t\tpurgeExpired();\n\n\t\tconst normalised = normaliseUserCode(userCode);\n\t\tconst deviceCode = deviceByUserCode.get(normalised);\n\n\t\tif (!deviceCode) {\n\t\t\tthrow new Error(\"User code not found or expired\");\n\t\t}\n\n\t\tconst grant = grantsByDevice.get(deviceCode);\n\t\tif (!grant || grant.expiresAt <= Date.now()) {\n\t\t\tdeviceByUserCode.delete(normalised);\n\t\t\tif (deviceCode) grantsByDevice.delete(deviceCode);\n\t\t\tthrow new Error(\"Device code expired\");\n\t\t}\n\n\t\tif (grant.state !== \"pending\") {\n\t\t\tthrow new Error(`Device code already ${grant.state}`);\n\t\t}\n\n\t\tgrant.state = \"denied\";\n\t}\n\n\tasync function handleRequest(request: Request): Promise<Response | null> {\n\t\tconst url = new URL(request.url);\n\t\tconst { method, pathname } = { method: request.method, pathname: url.pathname };\n\n\t\t// POST /auth/device/code\n\t\tif (method === \"POST\" && pathname.endsWith(\"/auth/device/code\")) {\n\t\t\tconst response = await requestCode();\n\t\t\treturn jsonResponse({\n\t\t\t\tdevice_code: response.deviceCode,\n\t\t\t\tuser_code: response.userCode,\n\t\t\t\tverification_uri: response.verificationUri,\n\t\t\t\tverification_uri_complete: response.verificationUriComplete,\n\t\t\t\texpires_in: response.expiresIn,\n\t\t\t\tinterval: response.interval,\n\t\t\t});\n\t\t}\n\n\t\t// POST /auth/device/token — polling endpoint (RFC 8628 §3.4)\n\t\tif (method === \"POST\" && pathname.endsWith(\"/auth/device/token\")) {\n\t\t\tconst body = await parseBody(request);\n\t\t\tconst deviceCode = typeof body.device_code === \"string\" ? body.device_code : null;\n\n\t\t\tif (!deviceCode) {\n\t\t\t\treturn jsonResponse(\n\t\t\t\t\t{ error: \"invalid_request\", error_description: \"Missing device_code\" },\n\t\t\t\t\t400,\n\t\t\t\t);\n\t\t\t}\n\n\t\t\t// Slow-down detection\n\t\t\tconst grant = grantsByDevice.get(deviceCode);\n\t\t\tif (grant?.lastPolledAt && Date.now() - grant.lastPolledAt < SLOW_DOWN_THRESHOLD_MS) {\n\t\t\t\treturn jsonResponse(\n\t\t\t\t\t{\n\t\t\t\t\t\terror: \"slow_down\",\n\t\t\t\t\t\terror_description: \"Polling too frequently\",\n\t\t\t\t\t\tinterval: pollIntervalSeconds + 5,\n\t\t\t\t\t},\n\t\t\t\t\t400,\n\t\t\t\t);\n\t\t\t}\n\n\t\t\tconst status = await checkAuthorization(deviceCode);\n\n\t\t\tif (status.status === \"authorized\") {\n\t\t\t\treturn jsonResponse({ authorized: true, user_id: status.userId });\n\t\t\t}\n\n\t\t\tif (status.status === \"pending\") {\n\t\t\t\treturn jsonResponse(\n\t\t\t\t\t{\n\t\t\t\t\t\terror: \"authorization_pending\",\n\t\t\t\t\t\terror_description: \"The user has not yet authorized the device\",\n\t\t\t\t\t},\n\t\t\t\t\t400,\n\t\t\t\t);\n\t\t\t}\n\n\t\t\tif (status.status === \"denied\") {\n\t\t\t\treturn jsonResponse(\n\t\t\t\t\t{\n\t\t\t\t\t\terror: \"access_denied\",\n\t\t\t\t\t\terror_description: \"The user denied the authorization request\",\n\t\t\t\t\t},\n\t\t\t\t\t400,\n\t\t\t\t);\n\t\t\t}\n\n\t\t\t// expired\n\t\t\treturn jsonResponse(\n\t\t\t\t{\n\t\t\t\t\terror: \"expired_token\",\n\t\t\t\t\terror_description: \"The device code has expired\",\n\t\t\t\t},\n\t\t\t\t400,\n\t\t\t);\n\t\t}\n\n\t\t// POST /auth/device/authorize — user approval (requires auth handled by caller)\n\t\tif (method === \"POST\" && pathname.endsWith(\"/auth/device/authorize\")) {\n\t\t\tconst body = await parseBody(request);\n\t\t\tconst userCode = typeof body.user_code === \"string\" ? body.user_code : null;\n\t\t\tconst userId = typeof body.user_id === \"string\" ? body.user_id : null;\n\t\t\tconst action = typeof body.action === \"string\" ? body.action : \"approve\";\n\n\t\t\tif (!userCode || !userId) {\n\t\t\t\treturn jsonResponse(\n\t\t\t\t\t{ error: \"invalid_request\", error_description: \"Missing user_code or user_id\" },\n\t\t\t\t\t400,\n\t\t\t\t);\n\t\t\t}\n\n\t\t\ttry {\n\t\t\t\tif (action === \"deny\") {\n\t\t\t\t\tawait deny(userCode);\n\t\t\t\t\treturn jsonResponse({ denied: true });\n\t\t\t\t}\n\t\t\t\tawait authorize(userCode, userId);\n\t\t\t\treturn jsonResponse({ authorized: true });\n\t\t\t} catch (err) {\n\t\t\t\treturn jsonResponse(\n\t\t\t\t\t{\n\t\t\t\t\t\terror: \"invalid_request\",\n\t\t\t\t\t\terror_description: err instanceof Error ? err.message : \"Authorization failed\",\n\t\t\t\t\t},\n\t\t\t\t\t400,\n\t\t\t\t);\n\t\t\t}\n\t\t}\n\n\t\treturn null;\n\t}\n\n\treturn { requestCode, checkAuthorization, authorize, deny, handleRequest };\n}\n\n// ---------------------------------------------------------------------------\n// Plugin factory\n// ---------------------------------------------------------------------------\n\nimport type { KavachPlugin } from \"../plugin/types.js\";\n\nexport function deviceAuth(config: DeviceAuthConfig): KavachPlugin {\n\treturn {\n\t\tid: \"kavach-device-auth\",\n\n\t\tasync init(ctx): Promise<undefined> {\n\t\t\tconst mod = createDeviceAuthModule(config);\n\n\t\t\t// POST /auth/device/code\n\t\t\tctx.addEndpoint({\n\t\t\t\tmethod: \"POST\",\n\t\t\t\tpath: \"/auth/device/code\",\n\t\t\t\tmetadata: {\n\t\t\t\t\tdescription: \"Request a device code and user code for the device authorization flow\",\n\t\t\t\t\trateLimit: { window: 60_000, max: 30 },\n\t\t\t\t},\n\t\t\t\tasync handler(_request, _endpointCtx) {\n\t\t\t\t\tconst response = await mod.requestCode();\n\t\t\t\t\treturn new Response(\n\t\t\t\t\t\tJSON.stringify({\n\t\t\t\t\t\t\tdevice_code: response.deviceCode,\n\t\t\t\t\t\t\tuser_code: response.userCode,\n\t\t\t\t\t\t\tverification_uri: response.verificationUri,\n\t\t\t\t\t\t\tverification_uri_complete: response.verificationUriComplete,\n\t\t\t\t\t\t\texpires_in: response.expiresIn,\n\t\t\t\t\t\t\tinterval: response.interval,\n\t\t\t\t\t\t}),\n\t\t\t\t\t\t{ status: 200, headers: { \"Content-Type\": \"application/json\" } },\n\t\t\t\t\t);\n\t\t\t\t},\n\t\t\t});\n\n\t\t\t// POST /auth/device/token\n\t\t\tctx.addEndpoint({\n\t\t\t\tmethod: \"POST\",\n\t\t\t\tpath: \"/auth/device/token\",\n\t\t\t\tmetadata: {\n\t\t\t\t\tdescription: \"Poll for device authorization status (RFC 8628)\",\n\t\t\t\t\trateLimit: { window: 10_000, max: 5 },\n\t\t\t\t},\n\t\t\t\tasync handler(request, _endpointCtx) {\n\t\t\t\t\tlet body: Record<string, unknown>;\n\t\t\t\t\ttry {\n\t\t\t\t\t\tbody = (await request.json()) as Record<string, unknown>;\n\t\t\t\t\t} catch {\n\t\t\t\t\t\tbody = {};\n\t\t\t\t\t}\n\n\t\t\t\t\tconst deviceCode = typeof body.device_code === \"string\" ? body.device_code : null;\n\t\t\t\t\tif (!deviceCode) {\n\t\t\t\t\t\treturn new Response(\n\t\t\t\t\t\t\tJSON.stringify({\n\t\t\t\t\t\t\t\terror: \"invalid_request\",\n\t\t\t\t\t\t\t\terror_description: \"Missing device_code\",\n\t\t\t\t\t\t\t}),\n\t\t\t\t\t\t\t{ status: 400, headers: { \"Content-Type\": \"application/json\" } },\n\t\t\t\t\t\t);\n\t\t\t\t\t}\n\n\t\t\t\t\tconst status = await mod.checkAuthorization(deviceCode);\n\n\t\t\t\t\tif (status.status === \"authorized\") {\n\t\t\t\t\t\treturn new Response(JSON.stringify({ authorized: true, user_id: status.userId }), {\n\t\t\t\t\t\t\tstatus: 200,\n\t\t\t\t\t\t\theaders: { \"Content-Type\": \"application/json\" },\n\t\t\t\t\t\t});\n\t\t\t\t\t}\n\n\t\t\t\t\tconst errorMap: Record<string, { error: string; error_description: string }> = {\n\t\t\t\t\t\tpending: {\n\t\t\t\t\t\t\terror: \"authorization_pending\",\n\t\t\t\t\t\t\terror_description: \"The user has not yet authorized the device\",\n\t\t\t\t\t\t},\n\t\t\t\t\t\tdenied: {\n\t\t\t\t\t\t\terror: \"access_denied\",\n\t\t\t\t\t\t\terror_description: \"The user denied the authorization request\",\n\t\t\t\t\t\t},\n\t\t\t\t\t\texpired: {\n\t\t\t\t\t\t\terror: \"expired_token\",\n\t\t\t\t\t\t\terror_description: \"The device code has expired\",\n\t\t\t\t\t\t},\n\t\t\t\t\t};\n\n\t\t\t\t\tconst errorBody = errorMap[status.status];\n\t\t\t\t\treturn new Response(JSON.stringify(errorBody), {\n\t\t\t\t\t\tstatus: 400,\n\t\t\t\t\t\theaders: { \"Content-Type\": \"application/json\" },\n\t\t\t\t\t});\n\t\t\t\t},\n\t\t\t});\n\n\t\t\t// POST /auth/device/authorize\n\t\t\tctx.addEndpoint({\n\t\t\t\tmethod: \"POST\",\n\t\t\t\tpath: \"/auth/device/authorize\",\n\t\t\t\tmetadata: {\n\t\t\t\t\trequireAuth: true,\n\t\t\t\t\tdescription: \"User approves or denies a device authorization request\",\n\t\t\t\t},\n\t\t\t\tasync handler(request, endpointCtx) {\n\t\t\t\t\tconst user = await endpointCtx.getUser(request);\n\t\t\t\t\tif (!user) {\n\t\t\t\t\t\treturn new Response(JSON.stringify({ error: \"Authentication required\" }), {\n\t\t\t\t\t\t\tstatus: 401,\n\t\t\t\t\t\t\theaders: { \"Content-Type\": \"application/json\" },\n\t\t\t\t\t\t});\n\t\t\t\t\t}\n\n\t\t\t\t\tlet body: Record<string, unknown>;\n\t\t\t\t\ttry {\n\t\t\t\t\t\tbody = (await request.json()) as Record<string, unknown>;\n\t\t\t\t\t} catch {\n\t\t\t\t\t\tbody = {};\n\t\t\t\t\t}\n\n\t\t\t\t\tconst userCode = typeof body.user_code === \"string\" ? body.user_code : null;\n\t\t\t\t\tconst action = typeof body.action === \"string\" ? body.action : \"approve\";\n\n\t\t\t\t\tif (!userCode) {\n\t\t\t\t\t\treturn new Response(\n\t\t\t\t\t\t\tJSON.stringify({\n\t\t\t\t\t\t\t\terror: \"invalid_request\",\n\t\t\t\t\t\t\t\terror_description: \"Missing user_code\",\n\t\t\t\t\t\t\t}),\n\t\t\t\t\t\t\t{ status: 400, headers: { \"Content-Type\": \"application/json\" } },\n\t\t\t\t\t\t);\n\t\t\t\t\t}\n\n\t\t\t\t\ttry {\n\t\t\t\t\t\tif (action === \"deny\") {\n\t\t\t\t\t\t\tawait mod.deny(userCode);\n\t\t\t\t\t\t\treturn new Response(JSON.stringify({ denied: true }), {\n\t\t\t\t\t\t\t\tstatus: 200,\n\t\t\t\t\t\t\t\theaders: { \"Content-Type\": \"application/json\" },\n\t\t\t\t\t\t\t});\n\t\t\t\t\t\t}\n\t\t\t\t\t\tawait mod.authorize(userCode, user.id);\n\t\t\t\t\t\treturn new Response(JSON.stringify({ authorized: true }), {\n\t\t\t\t\t\t\tstatus: 200,\n\t\t\t\t\t\t\theaders: { \"Content-Type\": \"application/json\" },\n\t\t\t\t\t\t});\n\t\t\t\t\t} catch (err) {\n\t\t\t\t\t\treturn new Response(\n\t\t\t\t\t\t\tJSON.stringify({\n\t\t\t\t\t\t\t\terror: \"invalid_request\",\n\t\t\t\t\t\t\t\terror_description: err instanceof Error ? err.message : \"Authorization failed\",\n\t\t\t\t\t\t\t}),\n\t\t\t\t\t\t\t{ status: 400, headers: { \"Content-Type\": \"application/json\" } },\n\t\t\t\t\t\t);\n\t\t\t\t\t}\n\t\t\t\t},\n\t\t\t});\n\n\t\t\treturn undefined;\n\t\t},\n\t};\n}\n","/**\n * Email OTP authentication for KavachOS.\n *\n * Sends a short numeric code to the user's email. The code is hashed before\n * storage so a database compromise does not leak valid codes. Brute-force is\n * limited by a configurable `maxAttempts` counter per code record.\n *\n * @example\n * ```typescript\n * const kavach = await createKavach({\n * database: { provider: 'sqlite', url: 'kavach.db' },\n * auth: { session: { secret: process.env.SESSION_SECRET } },\n * emailOtp: {\n * sendOtp: async (email, code) => {\n * await resend.emails.send({ to: email, subject: `Your code: ${code}` });\n * },\n * },\n * });\n * ```\n */\n\nimport { createHash, randomUUID } from \"node:crypto\";\nimport { and, eq, gt } from \"drizzle-orm\";\nimport type { Database } from \"../db/database.js\";\nimport { emailOtps, users } from \"../db/schema.js\";\nimport type { SessionManager } from \"../session/session.js\";\n\n// ---------------------------------------------------------------------------\n// Public types\n// ---------------------------------------------------------------------------\n\nexport interface EmailOtpConfig {\n\t/** Send the OTP code via email. */\n\tsendOtp: (email: string, code: string) => Promise<void>;\n\t/** Digit length of the generated code (default: 6) */\n\tcodeLength?: number;\n\t/** Code expiry in seconds (default: 300 = 5 minutes) */\n\tcodeExpiry?: number;\n\t/** Max verification attempts before the code is invalidated (default: 5) */\n\tmaxAttempts?: number;\n}\n\nexport interface EmailOtpModule {\n\t/** Send a one-time code to the email. */\n\tsendCode: (email: string) => Promise<{ sent: boolean }>;\n\t/**\n\t * Verify an OTP code for the given email.\n\t * Returns null when the code is wrong, expired, or max attempts exceeded.\n\t */\n\tverifyCode: (\n\t\temail: string,\n\t\tcode: string,\n\t) => Promise<{\n\t\tuser: { id: string; email: string };\n\t\tsession: { token: string; expiresAt: Date };\n\t} | null>;\n\t/**\n\t * Handle an incoming HTTP request.\n\t *\n\t * - `POST /auth/otp/send` – JSON body `{ email: string }`\n\t * - `POST /auth/otp/verify` – JSON body `{ email: string; code: string }`\n\t *\n\t * Returns null when the path does not match.\n\t */\n\thandleRequest: (request: Request) => Promise<Response | null>;\n}\n\n// ---------------------------------------------------------------------------\n// Defaults\n// ---------------------------------------------------------------------------\n\nconst DEFAULT_CODE_LENGTH = 6;\nconst DEFAULT_CODE_EXPIRY_SECONDS = 300; // 5 minutes\nconst DEFAULT_MAX_ATTEMPTS = 5;\n\n// ---------------------------------------------------------------------------\n// Helpers\n// ---------------------------------------------------------------------------\n\nfunction hashCode(code: string): string {\n\treturn createHash(\"sha256\").update(code).digest(\"hex\");\n}\n\nfunction generateNumericCode(length: number): string {\n\t// Build the code digit-by-digit using randomUUID entropy (avoid modulo bias).\n\t// Each hex digit maps to 0-15; we take digits 0-9 and retry for A-F.\n\tconst digits: string[] = [];\n\twhile (digits.length < length) {\n\t\t// randomUUID gives 32 hex chars — plenty of entropy per call.\n\t\tfor (const char of randomUUID().replace(/-/g, \"\")) {\n\t\t\tif (digits.length >= length) break;\n\t\t\tconst num = parseInt(char, 16);\n\t\t\tif (num < 10) digits.push(String(num));\n\t\t}\n\t}\n\treturn digits.join(\"\");\n}\n\n// ---------------------------------------------------------------------------\n// Factory\n// ---------------------------------------------------------------------------\n\nexport function createEmailOtpModule(\n\tconfig: EmailOtpConfig,\n\tdb: Database,\n\tsessionManager: SessionManager,\n): EmailOtpModule {\n\tconst codeLength = config.codeLength ?? DEFAULT_CODE_LENGTH;\n\tconst codeExpiry = config.codeExpiry ?? DEFAULT_CODE_EXPIRY_SECONDS;\n\tconst maxAttempts = config.maxAttempts ?? DEFAULT_MAX_ATTEMPTS;\n\n\t// ── helpers ─────────────────────────────────────────────────────────────\n\n\tasync function findOrCreateUser(email: string): Promise<{ id: string; email: string }> {\n\t\tconst existing = await db\n\t\t\t.select({ id: users.id, email: users.email })\n\t\t\t.from(users)\n\t\t\t.where(eq(users.email, email));\n\n\t\tif (existing[0]) return { id: existing[0].id, email: existing[0].email };\n\n\t\tconst id = randomUUID();\n\t\tconst now = new Date();\n\t\tawait db.insert(users).values({\n\t\t\tid,\n\t\t\temail,\n\t\t\tcreatedAt: now,\n\t\t\tupdatedAt: now,\n\t\t});\n\n\t\treturn { id, email };\n\t}\n\n\t// ── public API ───────────────────────────────────────────────────────────\n\n\tasync function sendCode(email: string): Promise<{ sent: boolean }> {\n\t\tconst code = generateNumericCode(codeLength);\n\t\tconst now = new Date();\n\t\tconst expiresAt = new Date(now.getTime() + codeExpiry * 1000);\n\n\t\t// Delete any previous OTP records for this email before inserting a new one\n\t\t// so there is always at most one active record per address.\n\t\tawait db.delete(emailOtps).where(eq(emailOtps.email, email));\n\n\t\tawait db.insert(emailOtps).values({\n\t\t\tid: randomUUID(),\n\t\t\temail,\n\t\t\tcodeHash: hashCode(code),\n\t\t\texpiresAt,\n\t\t\tattempts: 0,\n\t\t\tcreatedAt: now,\n\t\t});\n\n\t\tawait config.sendOtp(email, code);\n\n\t\treturn { sent: true };\n\t}\n\n\tasync function verifyCode(\n\t\temail: string,\n\t\tcode: string,\n\t): Promise<{\n\t\tuser: { id: string; email: string };\n\t\tsession: { token: string; expiresAt: Date };\n\t} | null> {\n\t\tconst now = new Date();\n\n\t\tconst rows = await db\n\t\t\t.select()\n\t\t\t.from(emailOtps)\n\t\t\t.where(and(eq(emailOtps.email, email), gt(emailOtps.expiresAt, now)));\n\n\t\tconst record = rows[0];\n\t\tif (!record) return null;\n\n\t\t// Check attempt count before doing anything else.\n\t\tif (record.attempts >= maxAttempts) return null;\n\n\t\t// Increment attempts (do this before checking the code to prevent timing\n\t\t// attacks where an attacker probes whether the attempt counter is at max).\n\t\tawait db\n\t\t\t.update(emailOtps)\n\t\t\t.set({ attempts: record.attempts + 1 })\n\t\t\t.where(eq(emailOtps.id, record.id));\n\n\t\tif (hashCode(code) !== record.codeHash) return null;\n\n\t\t// Code is correct — remove the record to prevent re-use.\n\t\tawait db.delete(emailOtps).where(eq(emailOtps.id, record.id));\n\n\t\tconst user = await findOrCreateUser(email);\n\t\tconst { token: sessionToken, session } = await sessionManager.create(user.id);\n\n\t\treturn {\n\t\t\tuser,\n\t\t\tsession: { token: sessionToken, expiresAt: session.expiresAt },\n\t\t};\n\t}\n\n\tasync function handleRequest(request: Request): Promise<Response | null> {\n\t\tconst url = new URL(request.url);\n\t\tconst pathname = url.pathname;\n\n\t\tif (request.method !== \"POST\") return null;\n\n\t\t// POST /auth/otp/send\n\t\tif (pathname === \"/auth/otp/send\") {\n\t\t\tlet body: unknown;\n\t\t\ttry {\n\t\t\t\tbody = await request.json();\n\t\t\t} catch {\n\t\t\t\treturn new Response(JSON.stringify({ error: \"Invalid JSON body\" }), {\n\t\t\t\t\tstatus: 400,\n\t\t\t\t\theaders: { \"Content-Type\": \"application/json\" },\n\t\t\t\t});\n\t\t\t}\n\n\t\t\tif (\n\t\t\t\ttypeof body !== \"object\" ||\n\t\t\t\tbody === null ||\n\t\t\t\ttypeof (body as Record<string, unknown>).email !== \"string\"\n\t\t\t) {\n\t\t\t\treturn new Response(JSON.stringify({ error: \"Missing required field: email\" }), {\n\t\t\t\t\tstatus: 400,\n\t\t\t\t\theaders: { \"Content-Type\": \"application/json\" },\n\t\t\t\t});\n\t\t\t}\n\n\t\t\tconst email = String((body as Record<string, unknown>).email)\n\t\t\t\t.trim()\n\t\t\t\t.toLowerCase();\n\t\t\tconst result = await sendCode(email);\n\t\t\treturn new Response(JSON.stringify(result), {\n\t\t\t\tstatus: 200,\n\t\t\t\theaders: { \"Content-Type\": \"application/json\" },\n\t\t\t});\n\t\t}\n\n\t\t// POST /auth/otp/verify\n\t\tif (pathname === \"/auth/otp/verify\") {\n\t\t\tlet body: unknown;\n\t\t\ttry {\n\t\t\t\tbody = await request.json();\n\t\t\t} catch {\n\t\t\t\treturn new Response(JSON.stringify({ error: \"Invalid JSON body\" }), {\n\t\t\t\t\tstatus: 400,\n\t\t\t\t\theaders: { \"Content-Type\": \"application/json\" },\n\t\t\t\t});\n\t\t\t}\n\n\t\t\tconst b = body as Record<string, unknown>;\n\t\t\tif (typeof b.email !== \"string\" || typeof b.code !== \"string\") {\n\t\t\t\treturn new Response(JSON.stringify({ error: \"Missing required fields: email, code\" }), {\n\t\t\t\t\tstatus: 400,\n\t\t\t\t\theaders: { \"Content-Type\": \"application/json\" },\n\t\t\t\t});\n\t\t\t}\n\n\t\t\tconst email = b.email.trim().toLowerCase();\n\t\t\tconst result = await verifyCode(email, b.code.trim());\n\n\t\t\tif (!result) {\n\t\t\t\treturn new Response(JSON.stringify({ error: \"Invalid or expired OTP code\" }), {\n\t\t\t\t\tstatus: 401,\n\t\t\t\t\theaders: { \"Content-Type\": \"application/json\" },\n\t\t\t\t});\n\t\t\t}\n\n\t\t\treturn new Response(JSON.stringify(result), {\n\t\t\t\tstatus: 200,\n\t\t\t\theaders: { \"Content-Type\": \"application/json\" },\n\t\t\t});\n\t\t}\n\n\t\treturn null;\n\t}\n\n\treturn { sendCode, verifyCode, handleRequest };\n}\n","import type { KavachPlugin } from \"../plugin/types.js\";\nimport { createSessionManager } from \"../session/session.js\";\nimport type { EmailOtpConfig } from \"./email-otp.js\";\nimport { createEmailOtpModule } from \"./email-otp.js\";\n\nexport type { EmailOtpConfig };\n\n// ---------------------------------------------------------------------------\n// Helpers\n// ---------------------------------------------------------------------------\n\nfunction jsonResponse(body: unknown, status = 200): Response {\n\treturn new Response(JSON.stringify(body), {\n\t\tstatus,\n\t\theaders: { \"Content-Type\": \"application/json\" },\n\t});\n}\n\nasync function parseBody(request: Request): Promise<Record<string, unknown>> {\n\ttry {\n\t\treturn (await request.json()) as Record<string, unknown>;\n\t} catch {\n\t\treturn {};\n\t}\n}\n\n// ---------------------------------------------------------------------------\n// Plugin factory\n// ---------------------------------------------------------------------------\n\nexport function emailOtp(config: EmailOtpConfig): KavachPlugin {\n\treturn {\n\t\tid: \"kavach-email-otp\",\n\n\t\tasync init(ctx): Promise<undefined> {\n\t\t\tconst sessionConfig = ctx.config.auth?.session;\n\t\t\tif (!sessionConfig) {\n\t\t\t\tthrow new Error(\n\t\t\t\t\t\"kavach-email-otp plugin requires auth.session to be configured so that sessions can be issued on successful verification.\",\n\t\t\t\t);\n\t\t\t}\n\n\t\t\tconst sessionManager = createSessionManager(sessionConfig, ctx.db);\n\t\t\tconst module = createEmailOtpModule(config, ctx.db, sessionManager);\n\n\t\t\t// POST /auth/email-otp/send\n\t\t\t// Accepts { email: string } and sends an OTP code to that address.\n\t\t\tctx.addEndpoint({\n\t\t\t\tmethod: \"POST\",\n\t\t\t\tpath: \"/auth/email-otp/send\",\n\t\t\t\tmetadata: {\n\t\t\t\t\trateLimit: { window: 60, max: 5 },\n\t\t\t\t\tdescription: \"Send a one-time passcode to the provided email address\",\n\t\t\t\t},\n\t\t\t\tasync handler(request) {\n\t\t\t\t\tconst body = await parseBody(request);\n\t\t\t\t\tconst rawEmail = typeof body.email === \"string\" ? body.email.trim().toLowerCase() : null;\n\n\t\t\t\t\tif (!rawEmail) {\n\t\t\t\t\t\treturn jsonResponse({ error: \"Missing required field: email\" }, 400);\n\t\t\t\t\t}\n\n\t\t\t\t\ttry {\n\t\t\t\t\t\tconst result = await module.sendCode(rawEmail);\n\t\t\t\t\t\treturn jsonResponse(result);\n\t\t\t\t\t} catch (err) {\n\t\t\t\t\t\treturn jsonResponse(\n\t\t\t\t\t\t\t{ error: err instanceof Error ? err.message : \"Failed to send OTP\" },\n\t\t\t\t\t\t\t500,\n\t\t\t\t\t\t);\n\t\t\t\t\t}\n\t\t\t\t},\n\t\t\t});\n\n\t\t\t// POST /auth/email-otp/verify\n\t\t\t// Accepts { email: string; code: string } and returns user + session on success.\n\t\t\tctx.addEndpoint({\n\t\t\t\tmethod: \"POST\",\n\t\t\t\tpath: \"/auth/email-otp/verify\",\n\t\t\t\tmetadata: {\n\t\t\t\t\trateLimit: { window: 60, max: 10 },\n\t\t\t\t\tdescription: \"Verify an OTP code and return a session on success\",\n\t\t\t\t},\n\t\t\t\tasync handler(request) {\n\t\t\t\t\tconst body = await parseBody(request);\n\t\t\t\t\tconst rawEmail = typeof body.email === \"string\" ? body.email.trim().toLowerCase() : null;\n\t\t\t\t\tconst code = typeof body.code === \"string\" ? body.code.trim() : null;\n\n\t\t\t\t\tif (!rawEmail || !code) {\n\t\t\t\t\t\treturn jsonResponse({ error: \"Missing required fields: email, code\" }, 400);\n\t\t\t\t\t}\n\n\t\t\t\t\tconst result = await module.verifyCode(rawEmail, code);\n\n\t\t\t\t\tif (!result) {\n\t\t\t\t\t\treturn jsonResponse({ error: \"Invalid or expired OTP code\" }, 401);\n\t\t\t\t\t}\n\n\t\t\t\t\treturn jsonResponse(result);\n\t\t\t\t},\n\t\t\t});\n\t\t},\n\t};\n}\n","/**\n * GDPR module for KavachOS.\n *\n * Implements Article 17 (right to erasure) and Article 20 (right to data\n * portability) for user accounts. Compliance-critical: every data removal\n * path is explicit about which tables are affected.\n *\n * @example\n * ```typescript\n * const gdpr = createGdprModule(db);\n *\n * // Export all data for a user\n * const export = await gdpr.exportUserData(userId);\n *\n * // Delete account, keeping anonymized audit trail\n * const result = await gdpr.deleteUser(userId, { keepAuditLogs: true });\n *\n * // Anonymize PII but keep the account (e.g., for orgs that require it)\n * await gdpr.anonymizeUser(userId);\n * ```\n */\n\nimport { createHash } from \"node:crypto\";\nimport { eq, inArray, or, sql } from \"drizzle-orm\";\nimport type { Database } from \"../db/database.js\";\nimport {\n\tagents,\n\tapiKeys,\n\tapprovalRequests,\n\tauditLogs,\n\tbudgetPolicies,\n\tdelegationChains,\n\temailOtps,\n\tmagicLinks,\n\toauthAccessTokens,\n\toauthAuthorizationCodes,\n\torganizations,\n\torgMembers,\n\tpasskeyCredentials,\n\tsessions,\n\ttotpRecords,\n\tusers,\n} from \"../db/schema.js\";\n\n// ---------------------------------------------------------------------------\n// Public types\n// ---------------------------------------------------------------------------\n\nexport interface UserDataExport {\n\tuser: { id: string; email: string; name: string | null; createdAt: string };\n\tagents: Array<{ id: string; name: string; type: string; status: string; createdAt: string }>;\n\tsessions: Array<{ id: string; createdAt: string; expiresAt: string }>;\n\tauditLogs: Array<{ action: string; resource: string; result: string; timestamp: string }>;\n\tdelegations: Array<{ fromAgent: string; toAgent: string; createdAt: string }>;\n\torganizations: Array<{ id: string; name: string; role: string }>;\n\tapiKeys: Array<{ id: string; name: string; createdAt: string }>;\n\texportedAt: string;\n}\n\nexport interface DeleteOptions {\n\t/**\n\t * Keep anonymized audit logs (default: true).\n\t *\n\t * Required for most compliance frameworks — audit records must survive\n\t * account deletion. User/agent identity is replaced with a stable hash so\n\t * aggregate reporting remains consistent across deleted accounts.\n\t */\n\tkeepAuditLogs?: boolean;\n\t/**\n\t * Also delete organizations owned by this user (default: false).\n\t *\n\t * When false, ownership is left in place so other members are unaffected.\n\t * Set to true only when the org has no other members or its data should\n\t * also be erased.\n\t */\n\tdeleteOrganizations?: boolean;\n}\n\nexport interface DeleteResult {\n\tdeletedAgents: number;\n\tdeletedSessions: number;\n\tdeletedDelegations: number;\n\tdeletedApiKeys: number;\n\tanonymizedAuditLogs: number;\n}\n\nexport interface GdprModule {\n\t/** Export all user data as a structured JSON object (GDPR Article 20). */\n\texportUserData(userId: string): Promise<UserDataExport>;\n\n\t/** Delete all user data (GDPR Article 17). Returns counts of removed records. */\n\tdeleteUser(userId: string, options?: DeleteOptions): Promise<DeleteResult>;\n\n\t/**\n\t * Anonymize user data instead of deleting.\n\t *\n\t * Replaces PII (email, name) with deterministic anonymous values while\n\t * keeping the account structure intact. Useful when org membership or\n\t * audit referential integrity must be preserved.\n\t */\n\tanonymizeUser(userId: string): Promise<void>;\n}\n\n// ---------------------------------------------------------------------------\n// Helpers\n// ---------------------------------------------------------------------------\n\n/**\n * Produce a stable short hash for an ID so anonymized audit logs from the\n * same deleted account are still groupable in aggregate reports.\n */\nfunction stableHash(id: string): string {\n\treturn createHash(\"sha256\").update(id).digest(\"hex\").slice(0, 12);\n}\n\nfunction anonymizedUserId(userId: string): string {\n\treturn `[deleted-${stableHash(userId)}]`;\n}\n\nfunction anonymizedEmail(userId: string): string {\n\treturn `deleted-${stableHash(userId)}@anon.invalid`;\n}\n\n// ---------------------------------------------------------------------------\n// Factory\n// ---------------------------------------------------------------------------\n\nexport function createGdprModule(db: Database): GdprModule {\n\tasync function exportUserData(userId: string): Promise<UserDataExport> {\n\t\t// User record\n\t\tconst userRows = await db.select().from(users).where(eq(users.id, userId));\n\t\tconst user = userRows[0];\n\t\tif (!user) {\n\t\t\tthrow new Error(`User \"${userId}\" not found`);\n\t\t}\n\n\t\t// Agents owned by this user\n\t\tconst agentRows = await db\n\t\t\t.select({\n\t\t\t\tid: agents.id,\n\t\t\t\tname: agents.name,\n\t\t\t\ttype: agents.type,\n\t\t\t\tstatus: agents.status,\n\t\t\t\tcreatedAt: agents.createdAt,\n\t\t\t})\n\t\t\t.from(agents)\n\t\t\t.where(eq(agents.ownerId, userId));\n\n\t\tconst agentIds = agentRows.map((a) => a.id);\n\n\t\t// Active sessions\n\t\tconst sessionRows = await db\n\t\t\t.select({ id: sessions.id, createdAt: sessions.createdAt, expiresAt: sessions.expiresAt })\n\t\t\t.from(sessions)\n\t\t\t.where(eq(sessions.userId, userId));\n\n\t\t// Audit logs attributed to this user\n\t\tconst auditRows =\n\t\t\tagentIds.length > 0\n\t\t\t\t? await db\n\t\t\t\t\t\t.select({\n\t\t\t\t\t\t\taction: auditLogs.action,\n\t\t\t\t\t\t\tresource: auditLogs.resource,\n\t\t\t\t\t\t\tresult: auditLogs.result,\n\t\t\t\t\t\t\ttimestamp: auditLogs.timestamp,\n\t\t\t\t\t\t})\n\t\t\t\t\t\t.from(auditLogs)\n\t\t\t\t\t\t.where(eq(auditLogs.userId, userId))\n\t\t\t\t: [];\n\n\t\t// Delegation chains involving any of the user's agents\n\t\tconst delegationRows =\n\t\t\tagentIds.length > 0\n\t\t\t\t? await db\n\t\t\t\t\t\t.select({\n\t\t\t\t\t\t\tfromAgentId: delegationChains.fromAgentId,\n\t\t\t\t\t\t\ttoAgentId: delegationChains.toAgentId,\n\t\t\t\t\t\t\tcreatedAt: delegationChains.createdAt,\n\t\t\t\t\t\t})\n\t\t\t\t\t\t.from(delegationChains)\n\t\t\t\t\t\t.where(\n\t\t\t\t\t\t\tor(\n\t\t\t\t\t\t\t\tinArray(delegationChains.fromAgentId, agentIds),\n\t\t\t\t\t\t\t\tinArray(delegationChains.toAgentId, agentIds),\n\t\t\t\t\t\t\t),\n\t\t\t\t\t\t)\n\t\t\t\t: [];\n\n\t\t// Organization memberships\n\t\tconst memberRows = await db\n\t\t\t.select({\n\t\t\t\torgId: orgMembers.orgId,\n\t\t\t\trole: orgMembers.role,\n\t\t\t})\n\t\t\t.from(orgMembers)\n\t\t\t.where(eq(orgMembers.userId, userId));\n\n\t\tconst orgIds = memberRows.map((m) => m.orgId);\n\n\t\tconst orgRows =\n\t\t\torgIds.length > 0\n\t\t\t\t? await db\n\t\t\t\t\t\t.select({ id: organizations.id, name: organizations.name })\n\t\t\t\t\t\t.from(organizations)\n\t\t\t\t\t\t.where(inArray(organizations.id, orgIds))\n\t\t\t\t: [];\n\n\t\tconst orgById = new Map(orgRows.map((o) => [o.id, o.name]));\n\n\t\t// API keys\n\t\tconst apiKeyRows = await db\n\t\t\t.select({ id: apiKeys.id, name: apiKeys.name, createdAt: apiKeys.createdAt })\n\t\t\t.from(apiKeys)\n\t\t\t.where(eq(apiKeys.userId, userId));\n\n\t\treturn {\n\t\t\tuser: {\n\t\t\t\tid: user.id,\n\t\t\t\temail: user.email,\n\t\t\t\tname: user.name ?? null,\n\t\t\t\tcreatedAt: user.createdAt.toISOString(),\n\t\t\t},\n\t\t\tagents: agentRows.map((a) => ({\n\t\t\t\tid: a.id,\n\t\t\t\tname: a.name,\n\t\t\t\ttype: a.type,\n\t\t\t\tstatus: a.status,\n\t\t\t\tcreatedAt: a.createdAt.toISOString(),\n\t\t\t})),\n\t\t\tsessions: sessionRows.map((s) => ({\n\t\t\t\tid: s.id,\n\t\t\t\tcreatedAt: s.createdAt.toISOString(),\n\t\t\t\texpiresAt: s.expiresAt.toISOString(),\n\t\t\t})),\n\t\t\tauditLogs: auditRows.map((a) => ({\n\t\t\t\taction: a.action,\n\t\t\t\tresource: a.resource,\n\t\t\t\tresult: a.result,\n\t\t\t\ttimestamp: a.timestamp.toISOString(),\n\t\t\t})),\n\t\t\tdelegations: delegationRows.map((d) => ({\n\t\t\t\tfromAgent: d.fromAgentId,\n\t\t\t\ttoAgent: d.toAgentId,\n\t\t\t\tcreatedAt: d.createdAt.toISOString(),\n\t\t\t})),\n\t\t\torganizations: memberRows.map((m) => ({\n\t\t\t\tid: m.orgId,\n\t\t\t\tname: orgById.get(m.orgId) ?? m.orgId,\n\t\t\t\trole: m.role,\n\t\t\t})),\n\t\t\tapiKeys: apiKeyRows.map((k) => ({\n\t\t\t\tid: k.id,\n\t\t\t\tname: k.name,\n\t\t\t\tcreatedAt: k.createdAt.toISOString(),\n\t\t\t})),\n\t\t\texportedAt: new Date().toISOString(),\n\t\t};\n\t}\n\n\tasync function deleteUser(userId: string, options?: DeleteOptions): Promise<DeleteResult> {\n\t\tconst keepAuditLogs = options?.keepAuditLogs ?? true;\n\t\tconst deleteOrgs = options?.deleteOrganizations ?? false;\n\n\t\t// Resolve all agents owned by this user before we start deleting\n\t\tconst agentRows = await db\n\t\t\t.select({ id: agents.id })\n\t\t\t.from(agents)\n\t\t\t.where(eq(agents.ownerId, userId));\n\n\t\tconst agentIds = agentRows.map((a) => a.id);\n\n\t\t// 1. Revoke all agents (preserve rows for FK references from audit logs)\n\t\tif (agentIds.length > 0) {\n\t\t\tawait db\n\t\t\t\t.update(agents)\n\t\t\t\t.set({ status: \"revoked\", updatedAt: new Date() })\n\t\t\t\t.where(eq(agents.ownerId, userId));\n\t\t}\n\n\t\t// 2. Delete all sessions\n\t\tconst sessionRows = await db\n\t\t\t.select({ id: sessions.id })\n\t\t\t.from(sessions)\n\t\t\t.where(eq(sessions.userId, userId));\n\n\t\tconst deletedSessions = sessionRows.length;\n\t\tawait db.delete(sessions).where(eq(sessions.userId, userId));\n\n\t\t// 3. Delete delegation chains (both directions for user's agents)\n\t\tlet deletedDelegations = 0;\n\t\tif (agentIds.length > 0) {\n\t\t\tconst delegationRows = await db\n\t\t\t\t.select({ id: delegationChains.id })\n\t\t\t\t.from(delegationChains)\n\t\t\t\t.where(\n\t\t\t\t\tor(\n\t\t\t\t\t\tinArray(delegationChains.fromAgentId, agentIds),\n\t\t\t\t\t\tinArray(delegationChains.toAgentId, agentIds),\n\t\t\t\t\t),\n\t\t\t\t);\n\n\t\t\tdeletedDelegations = delegationRows.length;\n\n\t\t\tif (delegationRows.length > 0) {\n\t\t\t\tconst delegationIds = delegationRows.map((d) => d.id);\n\t\t\t\tawait db.delete(delegationChains).where(inArray(delegationChains.id, delegationIds));\n\t\t\t}\n\t\t}\n\n\t\t// 4. Delete API keys\n\t\tconst apiKeyRows = await db\n\t\t\t.select({ id: apiKeys.id })\n\t\t\t.from(apiKeys)\n\t\t\t.where(eq(apiKeys.userId, userId));\n\n\t\tconst deletedApiKeys = apiKeyRows.length;\n\t\tawait db.delete(apiKeys).where(eq(apiKeys.userId, userId));\n\n\t\t// 5. Handle audit logs\n\t\tlet anonymizedAuditLogs = 0;\n\n\t\tif (agentIds.length > 0) {\n\t\t\tif (keepAuditLogs) {\n\t\t\t\t// Replace userId and agentId with stable anonymous tokens.\n\t\t\t\t// The hash is deterministic so aggregate reports can still\n\t\t\t\t// group all actions from the same deleted account.\n\t\t\t\t//\n\t\t\t\t// The audit log FK columns are NOT NULL and reference users/agents,\n\t\t\t\t// so we must temporarily disable FK enforcement to store the\n\t\t\t\t// anonymized placeholder. We re-enable it immediately after.\n\t\t\t\tconst anonUserId = anonymizedUserId(userId);\n\n\t\t\t\tawait db.run(sql`PRAGMA foreign_keys = OFF`);\n\t\t\t\ttry {\n\t\t\t\t\tfor (const agentId of agentIds) {\n\t\t\t\t\t\tconst anonAgentId = anonymizedUserId(agentId);\n\t\t\t\t\t\tconst affectedRows = await db\n\t\t\t\t\t\t\t.select({ id: auditLogs.id })\n\t\t\t\t\t\t\t.from(auditLogs)\n\t\t\t\t\t\t\t.where(eq(auditLogs.agentId, agentId));\n\n\t\t\t\t\t\tif (affectedRows.length > 0) {\n\t\t\t\t\t\t\tawait db\n\t\t\t\t\t\t\t\t.update(auditLogs)\n\t\t\t\t\t\t\t\t.set({ userId: anonUserId, agentId: anonAgentId })\n\t\t\t\t\t\t\t\t.where(eq(auditLogs.agentId, agentId));\n\n\t\t\t\t\t\t\tanonymizedAuditLogs += affectedRows.length;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t} finally {\n\t\t\t\t\tawait db.run(sql`PRAGMA foreign_keys = ON`);\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\t// Hard delete — caller has opted out of audit retention.\n\t\t\t\t// Deleting child rows (audit logs) does not violate FK constraints.\n\t\t\t\tconst affectedRows = await db\n\t\t\t\t\t.select({ id: auditLogs.id })\n\t\t\t\t\t.from(auditLogs)\n\t\t\t\t\t.where(eq(auditLogs.userId, userId));\n\n\t\t\t\tanonymizedAuditLogs = affectedRows.length;\n\n\t\t\t\tif (affectedRows.length > 0) {\n\t\t\t\t\tawait db.delete(auditLogs).where(eq(auditLogs.userId, userId));\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t// 6. Remove approval requests linked to this user.\n\t\t// User still exists at this point — FK to users.id is satisfied.\n\t\tawait db.delete(approvalRequests).where(eq(approvalRequests.userId, userId));\n\n\t\t// 7. Remove budget policies scoped to this user\n\t\tawait db.delete(budgetPolicies).where(eq(budgetPolicies.userId, userId));\n\n\t\t// 8. Remove OAuth tokens issued to this user\n\t\tawait db.delete(oauthAccessTokens).where(eq(oauthAccessTokens.userId, userId));\n\t\tawait db.delete(oauthAuthorizationCodes).where(eq(oauthAuthorizationCodes.userId, userId));\n\n\t\t// 9. Remove passwordless auth records tied to email — look up email first\n\t\tconst userRows = await db\n\t\t\t.select({ email: users.email })\n\t\t\t.from(users)\n\t\t\t.where(eq(users.id, userId));\n\n\t\tconst userEmail = userRows[0]?.email;\n\t\tif (userEmail) {\n\t\t\tawait db.delete(magicLinks).where(eq(magicLinks.email, userEmail));\n\t\t\tawait db.delete(emailOtps).where(eq(emailOtps.email, userEmail));\n\t\t}\n\n\t\t// 10. Remove TOTP records (FK to users.id — no cascade)\n\t\tawait db.delete(totpRecords).where(eq(totpRecords.userId, userId));\n\n\t\t// 11. Remove passkey credentials (FK to users.id — no cascade)\n\t\tawait db.delete(passkeyCredentials).where(eq(passkeyCredentials.userId, userId));\n\n\t\t// 12. Remove org memberships (not the orgs themselves unless requested)\n\t\tawait db.delete(orgMembers).where(eq(orgMembers.userId, userId));\n\n\t\tif (deleteOrgs) {\n\t\t\t// Delete orgs owned by this user — cascade removes members/invitations/roles\n\t\t\tawait db.delete(organizations).where(eq(organizations.ownerId, userId));\n\t\t}\n\n\t\t// 13. Delete the user record.\n\t\t//\n\t\t// When keepAuditLogs=true the agent rows are kept (status=revoked) to\n\t\t// preserve the anonymized audit log agentId references. The agents'\n\t\t// ownerId column still references the user row, so we must disable FK\n\t\t// checks for the final user deletion.\n\t\t//\n\t\t// When keepAuditLogs=false we delete the agent rows first so we can\n\t\t// delete the user row without disabling FK enforcement.\n\t\tif (!keepAuditLogs && agentIds.length > 0) {\n\t\t\tawait db.delete(agents).where(eq(agents.ownerId, userId));\n\t\t\tawait db.delete(users).where(eq(users.id, userId));\n\t\t} else {\n\t\t\t// Agents remain — FK enforcement must be suspended to allow deleting\n\t\t\t// the parent user row while revoked agent rows still reference it.\n\t\t\tawait db.run(sql`PRAGMA foreign_keys = OFF`);\n\t\t\ttry {\n\t\t\t\tawait db.delete(users).where(eq(users.id, userId));\n\t\t\t} finally {\n\t\t\t\tawait db.run(sql`PRAGMA foreign_keys = ON`);\n\t\t\t}\n\t\t}\n\n\t\treturn {\n\t\t\tdeletedAgents: agentIds.length,\n\t\t\tdeletedSessions,\n\t\t\tdeletedDelegations,\n\t\t\tdeletedApiKeys,\n\t\t\tanonymizedAuditLogs,\n\t\t};\n\t}\n\n\tasync function anonymizeUser(userId: string): Promise<void> {\n\t\tconst anonEmail = anonymizedEmail(userId);\n\n\t\tawait db\n\t\t\t.update(users)\n\t\t\t.set({\n\t\t\t\temail: anonEmail,\n\t\t\t\tname: null,\n\t\t\t\texternalId: null,\n\t\t\t\tmetadata: {},\n\t\t\t\tupdatedAt: new Date(),\n\t\t\t})\n\t\t\t.where(eq(users.id, userId));\n\n\t\t// Remove any passwordless credentials bound to the original email.\n\t\t// We need the original email to delete them, so we look it up first —\n\t\t// but by now it's already been overwritten. Callers should export or\n\t\t// delete those records before calling anonymizeUser if needed.\n\t\t// Instead we delete by userId where the schema allows it (TOTP, passkeys).\n\t\tawait db.delete(totpRecords).where(eq(totpRecords.userId, userId));\n\t\tawait db.delete(passkeyCredentials).where(eq(passkeyCredentials.userId, userId));\n\t}\n\n\treturn { exportUserData, deleteUser, anonymizeUser };\n}\n","/**\n * GDPR plugin for KavachOS.\n *\n * Exposes three self-service endpoints that authenticated users can call\n * to exercise their data rights under GDPR Articles 17 and 20.\n *\n * Endpoints:\n * GET /auth/gdpr/export – download a JSON export of all personal data\n * DELETE /auth/gdpr/delete – permanently delete the account\n * POST /auth/gdpr/anonymize – strip PII but keep the account shell\n *\n * @example\n * ```typescript\n * import { createKavach } from 'kavachos';\n * import { gdpr } from 'kavachos/auth';\n *\n * const kavach = await createKavach({\n * database: { provider: 'sqlite', url: 'kavach.db' },\n * plugins: [gdpr()],\n * });\n * ```\n */\n\nimport type { KavachPlugin } from \"../plugin/types.js\";\nimport { createGdprModule } from \"./gdpr.js\";\n\n// ---------------------------------------------------------------------------\n// Helpers\n// ---------------------------------------------------------------------------\n\nfunction jsonResponse(body: unknown, status = 200): Response {\n\treturn new Response(JSON.stringify(body), {\n\t\tstatus,\n\t\theaders: { \"Content-Type\": \"application/json\" },\n\t});\n}\n\nasync function parseBody(request: Request): Promise<Record<string, unknown>> {\n\ttry {\n\t\treturn (await request.json()) as Record<string, unknown>;\n\t} catch {\n\t\treturn {};\n\t}\n}\n\n// ---------------------------------------------------------------------------\n// Plugin factory\n// ---------------------------------------------------------------------------\n\nexport function gdpr(): KavachPlugin {\n\treturn {\n\t\tid: \"kavach-gdpr\",\n\n\t\tasync init(ctx): Promise<undefined> {\n\t\t\tconst module = createGdprModule(ctx.db);\n\n\t\t\t// GET /auth/gdpr/export\n\t\t\t// Returns a full JSON export of the authenticated user's data.\n\t\t\tctx.addEndpoint({\n\t\t\t\tmethod: \"GET\",\n\t\t\t\tpath: \"/auth/gdpr/export\",\n\t\t\t\tmetadata: {\n\t\t\t\t\trequireAuth: true,\n\t\t\t\t\tdescription: \"Export all personal data for the authenticated user (GDPR Art. 20)\",\n\t\t\t\t},\n\t\t\t\tasync handler(request, endpointCtx) {\n\t\t\t\t\tconst user = await endpointCtx.getUser(request);\n\t\t\t\t\tif (!user) {\n\t\t\t\t\t\treturn jsonResponse({ error: \"Authentication required\" }, 401);\n\t\t\t\t\t}\n\n\t\t\t\t\ttry {\n\t\t\t\t\t\tconst data = await module.exportUserData(user.id);\n\t\t\t\t\t\treturn jsonResponse(data);\n\t\t\t\t\t} catch (err) {\n\t\t\t\t\t\treturn jsonResponse(\n\t\t\t\t\t\t\t{ error: err instanceof Error ? err.message : \"Export failed\" },\n\t\t\t\t\t\t\t500,\n\t\t\t\t\t\t);\n\t\t\t\t\t}\n\t\t\t\t},\n\t\t\t});\n\n\t\t\t// DELETE /auth/gdpr/delete\n\t\t\t// Permanently deletes the authenticated user's account and all associated data.\n\t\t\t// Requires a confirmation body: { confirm: \"delete my account\" }\n\t\t\tctx.addEndpoint({\n\t\t\t\tmethod: \"DELETE\",\n\t\t\t\tpath: \"/auth/gdpr/delete\",\n\t\t\t\tmetadata: {\n\t\t\t\t\trequireAuth: true,\n\t\t\t\t\tdescription: \"Delete account and all personal data (GDPR Art. 17)\",\n\t\t\t\t},\n\t\t\t\tasync handler(request, endpointCtx) {\n\t\t\t\t\tconst user = await endpointCtx.getUser(request);\n\t\t\t\t\tif (!user) {\n\t\t\t\t\t\treturn jsonResponse({ error: \"Authentication required\" }, 401);\n\t\t\t\t\t}\n\n\t\t\t\t\tconst body = await parseBody(request);\n\n\t\t\t\t\t// Require explicit confirmation to prevent accidental deletion\n\t\t\t\t\tif (body.confirm !== \"delete my account\") {\n\t\t\t\t\t\treturn jsonResponse(\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\terror:\n\t\t\t\t\t\t\t\t\t'Confirmation required. Send { \"confirm\": \"delete my account\" } in the request body.',\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t400,\n\t\t\t\t\t\t);\n\t\t\t\t\t}\n\n\t\t\t\t\tconst keepAuditLogs = typeof body.keepAuditLogs === \"boolean\" ? body.keepAuditLogs : true;\n\t\t\t\t\tconst deleteOrganizations =\n\t\t\t\t\t\ttypeof body.deleteOrganizations === \"boolean\" ? body.deleteOrganizations : false;\n\n\t\t\t\t\ttry {\n\t\t\t\t\t\tconst result = await module.deleteUser(user.id, {\n\t\t\t\t\t\t\tkeepAuditLogs,\n\t\t\t\t\t\t\tdeleteOrganizations,\n\t\t\t\t\t\t});\n\t\t\t\t\t\treturn jsonResponse({ success: true, ...result });\n\t\t\t\t\t} catch (err) {\n\t\t\t\t\t\treturn jsonResponse(\n\t\t\t\t\t\t\t{ error: err instanceof Error ? err.message : \"Deletion failed\" },\n\t\t\t\t\t\t\t500,\n\t\t\t\t\t\t);\n\t\t\t\t\t}\n\t\t\t\t},\n\t\t\t});\n\n\t\t\t// POST /auth/gdpr/anonymize\n\t\t\t// Replaces PII with anonymized values, keeping the account structure intact.\n\t\t\tctx.addEndpoint({\n\t\t\t\tmethod: \"POST\",\n\t\t\t\tpath: \"/auth/gdpr/anonymize\",\n\t\t\t\tmetadata: {\n\t\t\t\t\trequireAuth: true,\n\t\t\t\t\tdescription: \"Anonymize personal data while preserving account structure\",\n\t\t\t\t},\n\t\t\t\tasync handler(request, endpointCtx) {\n\t\t\t\t\tconst user = await endpointCtx.getUser(request);\n\t\t\t\t\tif (!user) {\n\t\t\t\t\t\treturn jsonResponse({ error: \"Authentication required\" }, 401);\n\t\t\t\t\t}\n\n\t\t\t\t\ttry {\n\t\t\t\t\t\tawait module.anonymizeUser(user.id);\n\t\t\t\t\t\treturn jsonResponse({ success: true });\n\t\t\t\t\t} catch (err) {\n\t\t\t\t\t\treturn jsonResponse(\n\t\t\t\t\t\t\t{ error: err instanceof Error ? err.message : \"Anonymization failed\" },\n\t\t\t\t\t\t\t500,\n\t\t\t\t\t\t);\n\t\t\t\t\t}\n\t\t\t\t},\n\t\t\t});\n\n\t\t\treturn undefined;\n\t\t},\n\t};\n}\n","/**\n * Have I Been Pwned password checking for KavachOS.\n *\n * Uses the k-anonymity model: only the first 5 hex characters of the SHA-1\n * hash are sent to the API. The full hash (and the password itself) never\n * leave the process.\n *\n * @see https://haveibeenpwned.com/API/v3#PwnedPasswords\n */\n\nimport { createHash } from \"node:crypto\";\n\n// ---------------------------------------------------------------------------\n// Public types\n// ---------------------------------------------------------------------------\n\nexport interface HibpConfig {\n\t/** Reject passwords seen in more than N breaches (default: 0, reject any). */\n\tthreshold?: number;\n\t/** Custom API base URL, e.g. for a self-hosted HIBP instance. */\n\tapiUrl?: string;\n\t/** Request timeout in milliseconds (default: 5000). */\n\ttimeoutMs?: number;\n\t/**\n\t * What to do when the HIBP API is unreachable or returns an error.\n\t * - `'allow'` – treat the password as clean and let the user continue.\n\t * - `'block'` – reject the password to be safe.\n\t * Default: `'allow'`.\n\t */\n\tonError?: \"allow\" | \"block\";\n}\n\nexport interface HibpModule {\n\t/**\n\t * Check whether the password appears in any known data breach.\n\t * Returns the number of times it has been seen, or 0 if clean / API error\n\t * with `onError: 'allow'`.\n\t */\n\tcheck(password: string): Promise<number>;\n\t/**\n\t * Like `check`, but throws a `HibpBreachedError` when the breach count\n\t * exceeds the configured threshold.\n\t */\n\tenforce(password: string): Promise<void>;\n}\n\nexport class HibpBreachedError extends Error {\n\treadonly count: number;\n\n\tconstructor(count: number) {\n\t\tsuper(`Password has appeared in ${count} known data breach${count === 1 ? \"\" : \"es\"}`);\n\t\tthis.name = \"HibpBreachedError\";\n\t\tthis.count = count;\n\t}\n}\n\n// ---------------------------------------------------------------------------\n// SHA-1 helper (browser-safe path via node:crypto)\n// ---------------------------------------------------------------------------\n\nfunction sha1Hex(input: string): string {\n\treturn createHash(\"sha1\").update(input, \"utf8\").digest(\"hex\").toUpperCase();\n}\n\n// ---------------------------------------------------------------------------\n// Response parser\n// ---------------------------------------------------------------------------\n\n/**\n * Parse the HIBP range response body.\n *\n * Each line is `<SUFFIX>:<COUNT>` where SUFFIX is the hash minus the first 5\n * characters (already stripped by the API).\n */\nfunction parseRangeResponse(body: string): Map<string, number> {\n\tconst entries = new Map<string, number>();\n\n\tfor (const line of body.split(\"\\n\")) {\n\t\tconst trimmed = line.trim();\n\t\tif (!trimmed) continue;\n\n\t\tconst colonIdx = trimmed.indexOf(\":\");\n\t\tif (colonIdx === -1) continue;\n\n\t\tconst suffix = trimmed.slice(0, colonIdx).toUpperCase();\n\t\tconst count = parseInt(trimmed.slice(colonIdx + 1), 10);\n\n\t\tif (suffix && !Number.isNaN(count)) {\n\t\t\tentries.set(suffix, count);\n\t\t}\n\t}\n\n\treturn entries;\n}\n\n// ---------------------------------------------------------------------------\n// Module factory\n// ---------------------------------------------------------------------------\n\nexport function createHibpModule(config?: HibpConfig): HibpModule {\n\tconst threshold = config?.threshold ?? 0;\n\tconst apiUrl = (config?.apiUrl ?? \"https://api.pwnedpasswords.com\").replace(/\\/$/, \"\");\n\tconst timeoutMs = config?.timeoutMs ?? 5000;\n\tconst onError = config?.onError ?? \"allow\";\n\n\tasync function check(password: string): Promise<number> {\n\t\tconst hash = sha1Hex(password);\n\t\t// k-anonymity: only the prefix leaves this process\n\t\tconst prefix = hash.slice(0, 5);\n\t\tconst suffix = hash.slice(5);\n\n\t\tlet body: string;\n\n\t\ttry {\n\t\t\tconst response = await fetch(`${apiUrl}/range/${prefix}`, {\n\t\t\t\theaders: {\n\t\t\t\t\t// Ask the API not to pad results (reduces response size)\n\t\t\t\t\t\"Add-Padding\": \"false\",\n\t\t\t\t},\n\t\t\t\tsignal: AbortSignal.timeout(timeoutMs),\n\t\t\t});\n\n\t\t\tif (!response.ok) {\n\t\t\t\tthrow new Error(`HIBP API returned HTTP ${response.status}`);\n\t\t\t}\n\n\t\t\tbody = await response.text();\n\t\t} catch (err) {\n\t\t\tif (onError === \"block\") {\n\t\t\t\t// Surface a distinct error so callers can distinguish API failure\n\t\t\t\t// from a confirmed breach\n\t\t\t\tthrow new HibpApiError(err instanceof Error ? err.message : \"HIBP API request failed\");\n\t\t\t}\n\t\t\t// onError === 'allow' — treat as clean\n\t\t\treturn 0;\n\t\t}\n\n\t\tconst entries = parseRangeResponse(body);\n\t\treturn entries.get(suffix) ?? 0;\n\t}\n\n\tasync function enforce(password: string): Promise<void> {\n\t\tconst count = await check(password);\n\n\t\tif (count > threshold) {\n\t\t\tthrow new HibpBreachedError(count);\n\t\t}\n\t}\n\n\treturn { check, enforce };\n}\n\nexport class HibpApiError extends Error {\n\tconstructor(message: string) {\n\t\tsuper(message);\n\t\tthis.name = \"HibpApiError\";\n\t}\n}\n","/**\n * JWT session plugin for KavachOS.\n *\n * Issues short-lived access JWTs and long-lived refresh tokens for general-purpose\n * session management. This is distinct from the internal OIDC provider JWT — this\n * plugin is for apps that want to vend their own session tokens without running a\n * full OIDC flow.\n *\n * Access tokens are stateless JWTs (no DB lookup on verify). Refresh tokens are\n * opaque random strings stored hashed in the database, soft-revoked on use.\n *\n * @example\n * ```typescript\n * const sessions = createJwtSessionModule({\n * secret: process.env.SESSION_SECRET,\n * issuer: 'https://myapp.com',\n * customClaims: (user) => ({ role: user.role, org: user.orgId }),\n * }, db);\n *\n * // On login\n * const result = await sessions.createSession({ id: user.id, email: user.email });\n * if (result.success) {\n * const { accessToken, refreshToken, expiresIn } = result.data;\n * }\n *\n * // On API request\n * const verified = await sessions.verifySession(bearerToken);\n * if (verified.success) {\n * const { userId, claims } = verified.data;\n * }\n *\n * // On token refresh\n * const refreshed = await sessions.refreshSession(refreshToken);\n *\n * // On logout\n * await sessions.revokeSession(refreshToken);\n * ```\n */\n\nimport { createHash, randomBytes } from \"node:crypto\";\nimport { and, eq, gt } from \"drizzle-orm\";\nimport type { JWTPayload, JWTVerifyOptions } from \"jose\";\nimport { importJWK, jwtVerify, SignJWT } from \"jose\";\nimport { z } from \"zod\";\nimport type { Database } from \"../db/database.js\";\nimport { jwtRefreshTokens } from \"../db/schema.js\";\nimport type { KavachError, Result } from \"../mcp/types.js\";\n\n// ---------------------------------------------------------------------------\n// Re-export shared types\n// ---------------------------------------------------------------------------\n\nexport type { KavachError, Result };\n\n// ---------------------------------------------------------------------------\n// Public types\n// ---------------------------------------------------------------------------\n\nexport interface JwtSessionConfig {\n\t/** Signing key. A plain string uses HMAC-SHA256 (must be >= 32 chars).\n\t * Pass a `CryptoKey` or `JsonWebKey` for RSA/EC algorithms. */\n\tsecret: string | CryptoKey | JsonWebKey;\n\t/** JWT algorithm. Defaults to 'HS256' for string secrets, 'RS256' for keys. */\n\talgorithm?: string;\n\t/** Access token TTL in seconds. Default: 900 (15 min). */\n\taccessTokenTtl?: number;\n\t/** Refresh token TTL in seconds. Default: 604800 (7 days). */\n\trefreshTokenTtl?: number;\n\t/** JWT `iss` claim. */\n\tissuer?: string;\n\t/** JWT `aud` claim. */\n\taudience?: string;\n\t/** Attach extra claims to the access token payload. */\n\tcustomClaims?: (user: { id: string; email?: string; name?: string }) => Record<string, unknown>;\n}\n\nexport interface SessionUser {\n\tid: string;\n\temail?: string;\n\tname?: string;\n\timage?: string;\n}\n\nexport interface SessionTokens {\n\taccessToken: string;\n\trefreshToken: string;\n\t/** Seconds until the access token expires (mirrors `accessTokenTtl`). */\n\texpiresIn: number;\n}\n\nexport interface VerifiedSession {\n\tuserId: string;\n\temail?: string;\n\tname?: string;\n\tclaims: Record<string, unknown>;\n}\n\nexport interface JwtSessionModule {\n\t/**\n\t * Issue a new access + refresh token pair for the given user.\n\t *\n\t * The refresh token is stored hashed. The raw value is returned once and\n\t * cannot be recovered from the database.\n\t */\n\tcreateSession(user: SessionUser): Promise<Result<SessionTokens>>;\n\n\t/**\n\t * Verify an access token and return the embedded claims.\n\t *\n\t * Does not touch the database. Fails on expiry, wrong signature, or issuer/\n\t * audience mismatch.\n\t */\n\tverifySession(token: string): Promise<Result<VerifiedSession>>;\n\n\t/**\n\t * Exchange a refresh token for a new access + refresh token pair.\n\t *\n\t * The incoming refresh token is soft-revoked (marked used) on success.\n\t * A brand-new refresh token is issued so that each refresh rotates the token.\n\t */\n\trefreshSession(refreshToken: string): Promise<Result<SessionTokens>>;\n\n\t/**\n\t * Revoke a refresh token, preventing any further refreshes.\n\t *\n\t * Calling this on an already-revoked or unknown token is a no-op (returns\n\t * success) so that logout endpoints are idempotent.\n\t */\n\trevokeSession(refreshToken: string): Promise<Result<void>>;\n}\n\n// ---------------------------------------------------------------------------\n// Validation\n// ---------------------------------------------------------------------------\n\nconst configSchema = z.object({\n\tsecret: z.union([z.string().min(1), z.instanceof(Object)]),\n\talgorithm: z.string().optional(),\n\taccessTokenTtl: z.number().int().positive().optional(),\n\trefreshTokenTtl: z.number().int().positive().optional(),\n\tissuer: z.string().optional(),\n\taudience: z.string().optional(),\n\tcustomClaims: z.function().optional(),\n});\n\n// ---------------------------------------------------------------------------\n// Constants\n// ---------------------------------------------------------------------------\n\nconst DEFAULT_ACCESS_TTL = 900; // 15 min\nconst DEFAULT_REFRESH_TTL = 604_800; // 7 days\nconst REFRESH_TOKEN_BYTES = 32;\n\n// ---------------------------------------------------------------------------\n// Internal helpers\n// ---------------------------------------------------------------------------\n\nfunction makeError(code: string, message: string, details?: Record<string, unknown>): KavachError {\n\treturn { code, message, ...(details !== undefined ? { details } : {}) };\n}\n\nfunction hashToken(raw: string): string {\n\treturn createHash(\"sha256\").update(raw, \"utf8\").digest(\"hex\");\n}\n\nfunction generateRefreshToken(): string {\n\treturn randomBytes(REFRESH_TOKEN_BYTES).toString(\"hex\");\n}\n\n/**\n * Resolve the `secret` field into a value that `jose` can use for signing and\n * verification.\n *\n * - String secrets → `Uint8Array` (raw HMAC key bytes — the canonical jose\n * pattern for HS256/HS384/HS512).\n * - `CryptoKey` → returned as-is (RSA/EC keys).\n * - `JsonWebKey` → imported via `jose.importJWK` and returned as `CryptoKey`.\n */\nasync function resolveSigningKey(\n\tsecret: string | CryptoKey | JsonWebKey,\n\talgorithm: string,\n): Promise<Uint8Array | CryptoKey> {\n\tif (typeof secret === \"string\") {\n\t\t// Encode directly to Uint8Array — jose accepts this for HMAC algorithms\n\t\t// without needing to go through crypto.subtle.importKey.\n\t\treturn new TextEncoder().encode(secret);\n\t}\n\n\tif (secret instanceof CryptoKey) {\n\t\treturn secret;\n\t}\n\n\t// JsonWebKey\n\tconst imported = await importJWK(secret as Parameters<typeof importJWK>[0], algorithm);\n\treturn imported as CryptoKey;\n}\n\n/**\n * Derive the default algorithm from the secret type if the caller did not\n * specify one explicitly.\n */\nfunction defaultAlgorithm(secret: string | CryptoKey | JsonWebKey): string {\n\tif (typeof secret === \"string\") return \"HS256\";\n\tif (secret instanceof CryptoKey) {\n\t\tconst name = (secret as CryptoKey).algorithm.name;\n\t\tif (name === \"HMAC\") return \"HS256\";\n\t\tif (name === \"RSASSA-PKCS1-v1_5\") return \"RS256\";\n\t\tif (name === \"ECDSA\") return \"ES256\";\n\t}\n\t// JsonWebKey: infer from `kty`\n\tconst jwk = secret as JsonWebKey;\n\tif (jwk.kty === \"RSA\") return \"RS256\";\n\tif (jwk.kty === \"EC\") return \"ES256\";\n\treturn \"HS256\";\n}\n\n// ---------------------------------------------------------------------------\n// Factory\n// ---------------------------------------------------------------------------\n\n/**\n * Create a JWT session module backed by the provided database.\n *\n * The module is stateless beyond the database — multiple instances sharing\n * the same DB are safe and will honour each other's revocations.\n */\nexport function createJwtSessionModule(config: JwtSessionConfig, db: Database): JwtSessionModule {\n\tconst parsed = configSchema.safeParse(config);\n\tif (!parsed.success) {\n\t\tthrow new Error(\n\t\t\t`JwtSessionModule: invalid config — ${parsed.error.errors[0]?.message ?? \"unknown\"}`,\n\t\t);\n\t}\n\n\tconst algorithm = config.algorithm ?? defaultAlgorithm(config.secret);\n\tconst accessTtl = config.accessTokenTtl ?? DEFAULT_ACCESS_TTL;\n\tconst refreshTtl = config.refreshTokenTtl ?? DEFAULT_REFRESH_TTL;\n\n\t// Resolve the signing key once and cache it. Because key derivation is\n\t// async we lazily initialise on first use via a promise that all concurrent\n\t// callers share.\n\tlet signingKeyPromise: Promise<Uint8Array | CryptoKey> | null = null;\n\n\tfunction getSigningKey(): Promise<Uint8Array | CryptoKey> {\n\t\tif (signingKeyPromise === null) {\n\t\t\tsigningKeyPromise = resolveSigningKey(config.secret, algorithm);\n\t\t}\n\t\treturn signingKeyPromise;\n\t}\n\n\t// ── createSession ────────────────────────────────────────────────────────\n\n\tasync function createSession(user: SessionUser): Promise<Result<SessionTokens>> {\n\t\tif (!user.id || typeof user.id !== \"string\" || user.id.trim() === \"\") {\n\t\t\treturn {\n\t\t\t\tsuccess: false,\n\t\t\t\terror: makeError(\"INVALID_INPUT\", \"user.id must not be empty\"),\n\t\t\t};\n\t\t}\n\n\t\ttry {\n\t\t\tconst key = await getSigningKey();\n\t\t\tconst now = Math.floor(Date.now() / 1000);\n\n\t\t\tconst claimsFromUser: Record<string, unknown> = {};\n\t\t\tif (config.customClaims) {\n\t\t\t\tconst extra = config.customClaims({\n\t\t\t\t\tid: user.id,\n\t\t\t\t\t...(user.email !== undefined ? { email: user.email } : {}),\n\t\t\t\t\t...(user.name !== undefined ? { name: user.name } : {}),\n\t\t\t\t});\n\t\t\t\tObject.assign(claimsFromUser, extra);\n\t\t\t}\n\n\t\t\t// Build access token\n\t\t\tlet builder = new SignJWT({\n\t\t\t\tsub: user.id,\n\t\t\t\t...(user.email !== undefined ? { email: user.email } : {}),\n\t\t\t\t...(user.name !== undefined ? { name: user.name } : {}),\n\t\t\t\t...claimsFromUser,\n\t\t\t} as JWTPayload)\n\t\t\t\t.setProtectedHeader({ alg: algorithm })\n\t\t\t\t.setIssuedAt(now)\n\t\t\t\t.setExpirationTime(now + accessTtl);\n\n\t\t\tif (config.issuer) builder = builder.setIssuer(config.issuer);\n\t\t\tif (config.audience) builder = builder.setAudience(config.audience);\n\n\t\t\tconst accessToken = await builder.sign(key);\n\n\t\t\t// Build refresh token and persist hash\n\t\t\tconst rawRefresh = generateRefreshToken();\n\t\t\tconst refreshHash = hashToken(rawRefresh);\n\t\t\tconst expiresAt = new Date((now + refreshTtl) * 1000);\n\n\t\t\tawait db.insert(jwtRefreshTokens).values({\n\t\t\t\tid: crypto.randomUUID(),\n\t\t\t\ttokenHash: refreshHash,\n\t\t\t\tuserId: user.id,\n\t\t\t\tused: false,\n\t\t\t\texpiresAt,\n\t\t\t\tcreatedAt: new Date(now * 1000),\n\t\t\t});\n\n\t\t\treturn {\n\t\t\t\tsuccess: true,\n\t\t\t\tdata: { accessToken, refreshToken: rawRefresh, expiresIn: accessTtl },\n\t\t\t};\n\t\t} catch (err) {\n\t\t\treturn {\n\t\t\t\tsuccess: false,\n\t\t\t\terror: makeError(\n\t\t\t\t\t\"CREATE_SESSION_FAILED\",\n\t\t\t\t\terr instanceof Error ? err.message : \"Failed to create session\",\n\t\t\t\t),\n\t\t\t};\n\t\t}\n\t}\n\n\t// ── verifySession ────────────────────────────────────────────────────────\n\n\tasync function verifySession(token: string): Promise<Result<VerifiedSession>> {\n\t\tif (typeof token !== \"string\" || token.trim() === \"\") {\n\t\t\treturn {\n\t\t\t\tsuccess: false,\n\t\t\t\terror: makeError(\"INVALID_INPUT\", \"token must not be empty\"),\n\t\t\t};\n\t\t}\n\n\t\ttry {\n\t\t\tconst key = await getSigningKey();\n\n\t\t\tconst verifyOptions: JWTVerifyOptions = { algorithms: [algorithm] };\n\t\t\tif (config.issuer) verifyOptions.issuer = config.issuer;\n\t\t\tif (config.audience) verifyOptions.audience = config.audience;\n\n\t\t\tconst { payload } = await jwtVerify(token, key, verifyOptions);\n\n\t\t\tconst userId = payload.sub;\n\t\t\tif (!userId) {\n\t\t\t\treturn {\n\t\t\t\t\tsuccess: false,\n\t\t\t\t\terror: makeError(\"INVALID_TOKEN\", \"Token has no sub claim\"),\n\t\t\t\t};\n\t\t\t}\n\n\t\t\t// Pull well-known claims out; everything else becomes `claims`\n\t\t\tconst { sub, iss, aud, iat, exp, nbf, jti, email, name, ...rest } = payload as JWTPayload & {\n\t\t\t\temail?: string;\n\t\t\t\tname?: string;\n\t\t\t\t[key: string]: unknown;\n\t\t\t};\n\n\t\t\tconst claims: Record<string, unknown> = { ...rest };\n\t\t\tif (iss !== undefined) claims.iss = iss;\n\t\t\tif (aud !== undefined) claims.aud = aud;\n\t\t\tif (iat !== undefined) claims.iat = iat;\n\t\t\tif (exp !== undefined) claims.exp = exp;\n\t\t\tif (nbf !== undefined) claims.nbf = nbf;\n\t\t\tif (jti !== undefined) claims.jti = jti;\n\n\t\t\treturn {\n\t\t\t\tsuccess: true,\n\t\t\t\tdata: {\n\t\t\t\t\tuserId,\n\t\t\t\t\t...(typeof email === \"string\" ? { email } : {}),\n\t\t\t\t\t...(typeof name === \"string\" ? { name } : {}),\n\t\t\t\t\tclaims,\n\t\t\t\t},\n\t\t\t};\n\t\t} catch (err) {\n\t\t\tconst message = err instanceof Error ? err.message : \"Token verification failed\";\n\n\t\t\t// Normalise jose error codes\n\t\t\tif (message.includes(\"expired\") || message.includes(\"exp\")) {\n\t\t\t\treturn { success: false, error: makeError(\"TOKEN_EXPIRED\", \"Token has expired\") };\n\t\t\t}\n\t\t\tif (message.includes(\"signature\") || message.includes(\"invalid\")) {\n\t\t\t\treturn {\n\t\t\t\t\tsuccess: false,\n\t\t\t\t\terror: makeError(\"INVALID_TOKEN\", \"Token signature is invalid\"),\n\t\t\t\t};\n\t\t\t}\n\t\t\tif (message.includes(\"issuer\") || message.includes(\"iss\")) {\n\t\t\t\treturn {\n\t\t\t\t\tsuccess: false,\n\t\t\t\t\terror: makeError(\"ISSUER_MISMATCH\", \"Token issuer does not match\"),\n\t\t\t\t};\n\t\t\t}\n\t\t\tif (message.includes(\"audience\") || message.includes(\"aud\")) {\n\t\t\t\treturn {\n\t\t\t\t\tsuccess: false,\n\t\t\t\t\terror: makeError(\"AUDIENCE_MISMATCH\", \"Token audience does not match\"),\n\t\t\t\t};\n\t\t\t}\n\n\t\t\treturn { success: false, error: makeError(\"INVALID_TOKEN\", message) };\n\t\t}\n\t}\n\n\t// ── refreshSession ───────────────────────────────────────────────────────\n\n\tasync function refreshSession(refreshToken: string): Promise<Result<SessionTokens>> {\n\t\tif (typeof refreshToken !== \"string\" || refreshToken.trim() === \"\") {\n\t\t\treturn {\n\t\t\t\tsuccess: false,\n\t\t\t\terror: makeError(\"INVALID_INPUT\", \"refreshToken must not be empty\"),\n\t\t\t};\n\t\t}\n\n\t\tconst tokenHash = hashToken(refreshToken);\n\t\tconst now = new Date();\n\n\t\ttry {\n\t\t\tconst rows = await db\n\t\t\t\t.select()\n\t\t\t\t.from(jwtRefreshTokens)\n\t\t\t\t.where(eq(jwtRefreshTokens.tokenHash, tokenHash));\n\n\t\t\tconst record = rows[0];\n\n\t\t\tif (!record) {\n\t\t\t\treturn {\n\t\t\t\t\tsuccess: false,\n\t\t\t\t\terror: makeError(\"REFRESH_TOKEN_NOT_FOUND\", \"Refresh token not found\"),\n\t\t\t\t};\n\t\t\t}\n\n\t\t\tif (record.used) {\n\t\t\t\treturn {\n\t\t\t\t\tsuccess: false,\n\t\t\t\t\terror: makeError(\"REFRESH_TOKEN_USED\", \"Refresh token has already been used\"),\n\t\t\t\t};\n\t\t\t}\n\n\t\t\tif (record.expiresAt <= now) {\n\t\t\t\treturn {\n\t\t\t\t\tsuccess: false,\n\t\t\t\t\terror: makeError(\"REFRESH_TOKEN_EXPIRED\", \"Refresh token has expired\"),\n\t\t\t\t};\n\t\t\t}\n\n\t\t\t// Mark the old token as used before issuing a new pair (rotate)\n\t\t\tawait db\n\t\t\t\t.update(jwtRefreshTokens)\n\t\t\t\t.set({ used: true })\n\t\t\t\t.where(and(eq(jwtRefreshTokens.id, record.id), eq(jwtRefreshTokens.used, false)));\n\n\t\t\t// Issue new token pair for the same user\n\t\t\treturn createSession({ id: record.userId });\n\t\t} catch (err) {\n\t\t\treturn {\n\t\t\t\tsuccess: false,\n\t\t\t\terror: makeError(\n\t\t\t\t\t\"REFRESH_SESSION_FAILED\",\n\t\t\t\t\terr instanceof Error ? err.message : \"Failed to refresh session\",\n\t\t\t\t),\n\t\t\t};\n\t\t}\n\t}\n\n\t// ── revokeSession ────────────────────────────────────────────────────────\n\n\tasync function revokeSession(refreshToken: string): Promise<Result<void>> {\n\t\tif (typeof refreshToken !== \"string\" || refreshToken.trim() === \"\") {\n\t\t\treturn {\n\t\t\t\tsuccess: false,\n\t\t\t\terror: makeError(\"INVALID_INPUT\", \"refreshToken must not be empty\"),\n\t\t\t};\n\t\t}\n\n\t\tconst tokenHash = hashToken(refreshToken);\n\n\t\ttry {\n\t\t\tconst rows = await db\n\t\t\t\t.select({ id: jwtRefreshTokens.id, used: jwtRefreshTokens.used })\n\t\t\t\t.from(jwtRefreshTokens)\n\t\t\t\t.where(\n\t\t\t\t\tand(\n\t\t\t\t\t\teq(jwtRefreshTokens.tokenHash, tokenHash),\n\t\t\t\t\t\teq(jwtRefreshTokens.used, false),\n\t\t\t\t\t\tgt(jwtRefreshTokens.expiresAt, new Date()),\n\t\t\t\t\t),\n\t\t\t\t);\n\n\t\t\tif (rows.length > 0 && rows[0]) {\n\t\t\t\tawait db\n\t\t\t\t\t.update(jwtRefreshTokens)\n\t\t\t\t\t.set({ used: true })\n\t\t\t\t\t.where(eq(jwtRefreshTokens.id, rows[0].id));\n\t\t\t}\n\n\t\t\t// Idempotent: unknown or already-revoked tokens are treated as success\n\t\t\treturn { success: true, data: undefined };\n\t\t} catch (err) {\n\t\t\treturn {\n\t\t\t\tsuccess: false,\n\t\t\t\terror: makeError(\n\t\t\t\t\t\"REVOKE_SESSION_FAILED\",\n\t\t\t\t\terr instanceof Error ? err.message : \"Failed to revoke session\",\n\t\t\t\t),\n\t\t\t};\n\t\t}\n\t}\n\n\treturn { createSession, verifySession, refreshSession, revokeSession };\n}\n","/**\n * Last login tracking module for KavachOS.\n *\n * Records each successful authentication event per user, capturing the method\n * used, optional IP address, optional user agent, and timestamp. A rolling\n * window of recent logins is kept — older entries beyond the configured limit\n * are pruned on every write so storage stays bounded.\n *\n * @example\n * ```typescript\n * const loginHistory = createLastLoginModule({}, db);\n *\n * // After a successful sign-in\n * await loginHistory.recordLogin({\n * userId: 'usr_123',\n * method: 'magic-link',\n * ip: request.headers.get('x-forwarded-for') ?? undefined,\n * userAgent: request.headers.get('user-agent') ?? undefined,\n * });\n *\n * // Show the user their last login on a security page\n * const result = await loginHistory.getLastLogin('usr_123');\n * if (result.success) {\n * console.log(result.data?.method, result.data?.timestamp);\n * }\n * ```\n */\n\nimport { and, desc, eq, notInArray } from \"drizzle-orm\";\nimport { z } from \"zod\";\nimport type { Database } from \"../db/database.js\";\nimport { loginHistory } from \"../db/schema.js\";\nimport type { KavachError, Result } from \"../mcp/types.js\";\n\n// ---------------------------------------------------------------------------\n// Re-export shared types for callers that import from this module\n// ---------------------------------------------------------------------------\n\nexport type { KavachError, Result };\n\n// ---------------------------------------------------------------------------\n// Public types\n// ---------------------------------------------------------------------------\n\n/**\n * All supported login methods.\n *\n * For OAuth providers use the `oauth:{provider}` pattern, e.g. `oauth:github`,\n * `oauth:google`, `oauth:microsoft`.\n */\nexport type LoginMethod =\n\t| \"email-password\"\n\t| \"magic-link\"\n\t| \"email-otp\"\n\t| \"passkey\"\n\t| `oauth:${string}`\n\t| \"username-password\"\n\t| \"phone-sms\"\n\t| \"siwe\"\n\t| \"device-auth\"\n\t| \"anonymous\"\n\t| \"api-key\";\n\nexport interface LastLoginConfig {\n\t/**\n\t * Maximum number of login events to retain per user.\n\t * Older rows beyond this limit are deleted on every `recordLogin` call.\n\t * Default: 10.\n\t */\n\tmaxHistoryPerUser?: number;\n}\n\nexport interface RecordLoginInput {\n\tuserId: string;\n\tmethod: LoginMethod;\n\t/** Caller IP address. Stored as-is; normalise before passing if needed. */\n\tip?: string;\n\t/** Raw value of the User-Agent request header. */\n\tuserAgent?: string;\n}\n\nexport interface LoginEvent {\n\tid: string;\n\tuserId: string;\n\tmethod: LoginMethod;\n\tip: string | null;\n\tuserAgent: string | null;\n\ttimestamp: Date;\n}\n\nexport interface LastLoginModule {\n\t/**\n\t * Record a successful login event for a user.\n\t *\n\t * If the total stored events for that user exceed `maxHistoryPerUser`, the\n\t * oldest events are deleted so only the most recent N are kept.\n\t */\n\trecordLogin(input: RecordLoginInput): Promise<Result<LoginEvent>>;\n\n\t/**\n\t * Retrieve the single most recent login event for a user.\n\t *\n\t * Returns `null` in `data` when no history exists for the user.\n\t */\n\tgetLastLogin(userId: string): Promise<Result<LoginEvent | null>>;\n\n\t/**\n\t * Return login history for a user, newest first.\n\t *\n\t * @param userId The user to look up.\n\t * @param limit Maximum number of events to return. Defaults to `maxHistoryPerUser`.\n\t */\n\tgetLoginHistory(userId: string, limit?: number): Promise<Result<LoginEvent[]>>;\n}\n\n// ---------------------------------------------------------------------------\n// Zod validation\n// ---------------------------------------------------------------------------\n\nconst LOGIN_METHOD_BASE_VALUES = [\n\t\"email-password\",\n\t\"magic-link\",\n\t\"email-otp\",\n\t\"passkey\",\n\t\"username-password\",\n\t\"phone-sms\",\n\t\"siwe\",\n\t\"device-auth\",\n\t\"anonymous\",\n\t\"api-key\",\n] as const;\n\nconst recordLoginInputSchema = z.object({\n\tuserId: z.string().min(1, \"userId must not be empty\"),\n\tmethod: z.union([\n\t\tz.enum(LOGIN_METHOD_BASE_VALUES),\n\t\t// oauth:{provider} — provider must be at least one character\n\t\tz.string().regex(/^oauth:[a-z0-9_-]+$/i, \"OAuth method must match oauth:{provider}\"),\n\t]),\n\tip: z.string().min(1).optional(),\n\tuserAgent: z.string().min(1).optional(),\n});\n\n// ---------------------------------------------------------------------------\n// Constants\n// ---------------------------------------------------------------------------\n\nconst DEFAULT_MAX_HISTORY = 10;\n\n// ---------------------------------------------------------------------------\n// Internal helpers\n// ---------------------------------------------------------------------------\n\nfunction makeError(code: string, message: string, details?: Record<string, unknown>): KavachError {\n\treturn { code, message, ...(details !== undefined ? { details } : {}) };\n}\n\nfunction rowToLoginEvent(row: {\n\tid: string;\n\tuserId: string;\n\tmethod: string;\n\tip: string | null;\n\tuserAgent: string | null;\n\ttimestamp: Date;\n}): LoginEvent {\n\treturn {\n\t\tid: row.id,\n\t\tuserId: row.userId,\n\t\tmethod: row.method as LoginMethod,\n\t\tip: row.ip,\n\t\tuserAgent: row.userAgent,\n\t\ttimestamp: row.timestamp,\n\t};\n}\n\n// ---------------------------------------------------------------------------\n// Factory\n// ---------------------------------------------------------------------------\n\n/**\n * Create a last-login tracking module backed by the provided database.\n *\n * The module is stateless — safe to instantiate multiple times against the\n * same database.\n */\nexport function createLastLoginModule(config: LastLoginConfig, db: Database): LastLoginModule {\n\tconst maxHistory = config.maxHistoryPerUser ?? DEFAULT_MAX_HISTORY;\n\n\t// ── recordLogin ──────────────────────────────────────────────────────────\n\n\tasync function recordLogin(input: RecordLoginInput): Promise<Result<LoginEvent>> {\n\t\tconst parsed = recordLoginInputSchema.safeParse(input);\n\t\tif (!parsed.success) {\n\t\t\treturn {\n\t\t\t\tsuccess: false,\n\t\t\t\terror: makeError(\"INVALID_INPUT\", parsed.error.errors[0]?.message ?? \"Invalid input\", {\n\t\t\t\t\tissues: parsed.error.errors,\n\t\t\t\t}),\n\t\t\t};\n\t\t}\n\n\t\tconst { userId, method, ip, userAgent } = parsed.data;\n\t\tconst now = new Date();\n\t\tconst id = crypto.randomUUID();\n\n\t\ttry {\n\t\t\tawait db.insert(loginHistory).values({\n\t\t\t\tid,\n\t\t\t\tuserId,\n\t\t\t\tmethod,\n\t\t\t\tip: ip ?? null,\n\t\t\t\tuserAgent: userAgent ?? null,\n\t\t\t\ttimestamp: now,\n\t\t\t});\n\n\t\t\t// Prune rows beyond the limit for this user. Select the IDs to keep\n\t\t\t// (newest N), then delete everything else. Done in two queries to stay\n\t\t\t// compatible with SQLite which does not support DELETE with ORDER BY\n\t\t\t// or LIMIT directly in all versions.\n\t\t\tconst keepRows = await db\n\t\t\t\t.select({ id: loginHistory.id })\n\t\t\t\t.from(loginHistory)\n\t\t\t\t.where(eq(loginHistory.userId, userId))\n\t\t\t\t.orderBy(desc(loginHistory.timestamp))\n\t\t\t\t.limit(maxHistory);\n\n\t\t\tif (keepRows.length >= maxHistory) {\n\t\t\t\tconst keepIds = keepRows.map((r) => r.id);\n\t\t\t\tawait db\n\t\t\t\t\t.delete(loginHistory)\n\t\t\t\t\t.where(and(eq(loginHistory.userId, userId), notInArray(loginHistory.id, keepIds)));\n\t\t\t}\n\n\t\t\treturn {\n\t\t\t\tsuccess: true,\n\t\t\t\tdata: {\n\t\t\t\t\tid,\n\t\t\t\t\tuserId,\n\t\t\t\t\tmethod: method as LoginMethod,\n\t\t\t\t\tip: ip ?? null,\n\t\t\t\t\tuserAgent: userAgent ?? null,\n\t\t\t\t\ttimestamp: now,\n\t\t\t\t},\n\t\t\t};\n\t\t} catch (err) {\n\t\t\treturn {\n\t\t\t\tsuccess: false,\n\t\t\t\terror: makeError(\n\t\t\t\t\t\"RECORD_LOGIN_FAILED\",\n\t\t\t\t\terr instanceof Error ? err.message : \"Failed to record login\",\n\t\t\t\t),\n\t\t\t};\n\t\t}\n\t}\n\n\t// ── getLastLogin ─────────────────────────────────────────────────────────\n\n\tasync function getLastLogin(userId: string): Promise<Result<LoginEvent | null>> {\n\t\tif (typeof userId !== \"string\" || userId.trim() === \"\") {\n\t\t\treturn { success: false, error: makeError(\"INVALID_INPUT\", \"userId must not be empty\") };\n\t\t}\n\n\t\ttry {\n\t\t\tconst rows = await db\n\t\t\t\t.select()\n\t\t\t\t.from(loginHistory)\n\t\t\t\t.where(eq(loginHistory.userId, userId))\n\t\t\t\t.orderBy(desc(loginHistory.timestamp))\n\t\t\t\t.limit(1);\n\n\t\t\tconst row = rows[0];\n\t\t\treturn { success: true, data: row ? rowToLoginEvent(row) : null };\n\t\t} catch (err) {\n\t\t\treturn {\n\t\t\t\tsuccess: false,\n\t\t\t\terror: makeError(\n\t\t\t\t\t\"GET_LAST_LOGIN_FAILED\",\n\t\t\t\t\terr instanceof Error ? err.message : \"Failed to get last login\",\n\t\t\t\t),\n\t\t\t};\n\t\t}\n\t}\n\n\t// ── getLoginHistory ───────────────────────────────────────────────────────\n\n\tasync function getLoginHistory(userId: string, limit?: number): Promise<Result<LoginEvent[]>> {\n\t\tif (typeof userId !== \"string\" || userId.trim() === \"\") {\n\t\t\treturn { success: false, error: makeError(\"INVALID_INPUT\", \"userId must not be empty\") };\n\t\t}\n\n\t\tconst effectiveLimit = limit !== undefined && limit > 0 ? limit : maxHistory;\n\n\t\ttry {\n\t\t\tconst rows = await db\n\t\t\t\t.select()\n\t\t\t\t.from(loginHistory)\n\t\t\t\t.where(eq(loginHistory.userId, userId))\n\t\t\t\t.orderBy(desc(loginHistory.timestamp))\n\t\t\t\t.limit(effectiveLimit);\n\n\t\t\treturn { success: true, data: rows.map(rowToLoginEvent) };\n\t\t} catch (err) {\n\t\t\treturn {\n\t\t\t\tsuccess: false,\n\t\t\t\terror: makeError(\n\t\t\t\t\t\"GET_LOGIN_HISTORY_FAILED\",\n\t\t\t\t\terr instanceof Error ? err.message : \"Failed to get login history\",\n\t\t\t\t),\n\t\t\t};\n\t\t}\n\t}\n\n\treturn { recordLogin, getLastLogin, getLoginHistory };\n}\n","/**\n * Magic link authentication for KavachOS.\n *\n * Sends a one-time-use signed link to the user's email. When the link is\n * clicked the token is verified, the user is found or created, and a session\n * is returned. The transport (SMTP, Resend, SES, etc.) is provided by the\n * caller via `sendMagicLink`.\n *\n * @example\n * ```typescript\n * const kavach = await createKavach({\n * database: { provider: 'sqlite', url: 'kavach.db' },\n * auth: { session: { secret: process.env.SESSION_SECRET } },\n * magicLink: {\n * appUrl: 'https://app.example.com',\n * sendMagicLink: async (email, _token, url) => {\n * await resend.emails.send({ to: email, subject: 'Sign in', html: `<a href=\"${url}\">Sign in</a>` });\n * },\n * },\n * });\n *\n * // In your route handler\n * const response = await kavach.magicLink.handleRequest(request);\n * if (response) return response;\n * ```\n */\n\nimport { randomBytes, randomUUID } from \"node:crypto\";\nimport { and, eq, gt } from \"drizzle-orm\";\nimport type { Database } from \"../db/database.js\";\nimport { magicLinks, users } from \"../db/schema.js\";\nimport type { SessionManager } from \"../session/session.js\";\n\n// ---------------------------------------------------------------------------\n// Public types\n// ---------------------------------------------------------------------------\n\nexport interface MagicLinkConfig {\n\t/** Send the magic link email. You provide the transport. */\n\tsendMagicLink: (email: string, token: string, url: string) => Promise<void>;\n\t/** Base URL for magic link (e.g. \"https://app.example.com\") */\n\tappUrl: string;\n\t/** Token expiry in seconds (default: 900 = 15 minutes) */\n\ttokenExpiry?: number;\n\t/** Callback path (default: \"/auth/magic-link/verify\") */\n\tcallbackPath?: string;\n}\n\nexport interface MagicLinkModule {\n\t/** Send a magic link to the user's email. */\n\tsendLink: (email: string) => Promise<{ sent: boolean }>;\n\t/**\n\t * Verify a magic link token and create a session.\n\t * Returns null when the token is invalid, expired, or already used.\n\t */\n\tverify: (token: string) => Promise<{\n\t\tuser: { id: string; email: string };\n\t\tsession: { token: string; expiresAt: Date };\n\t} | null>;\n\t/**\n\t * Handle an incoming HTTP request.\n\t *\n\t * - `POST /auth/magic-link/send` – JSON body `{ email: string }`\n\t * - `GET /auth/magic-link/verify?token=<token>`\n\t *\n\t * Returns null when the path does not match (so callers can fall through\n\t * to other handlers).\n\t */\n\thandleRequest: (request: Request) => Promise<Response | null>;\n}\n\n// ---------------------------------------------------------------------------\n// Defaults\n// ---------------------------------------------------------------------------\n\nconst DEFAULT_EXPIRY_SECONDS = 900; // 15 minutes\nconst DEFAULT_CALLBACK_PATH = \"/auth/magic-link/verify\";\n\n// ---------------------------------------------------------------------------\n// Factory\n// ---------------------------------------------------------------------------\n\nexport function createMagicLinkModule(\n\tconfig: MagicLinkConfig,\n\tdb: Database,\n\tsessionManager: SessionManager,\n): MagicLinkModule {\n\tconst tokenExpiry = config.tokenExpiry ?? DEFAULT_EXPIRY_SECONDS;\n\tconst callbackPath = config.callbackPath ?? DEFAULT_CALLBACK_PATH;\n\n\t// ── helpers ─────────────────────────────────────────────────────────────\n\n\t/** Find an existing user by email or create a new one. */\n\tasync function findOrCreateUser(email: string): Promise<{ id: string; email: string }> {\n\t\tconst existing = await db\n\t\t\t.select({ id: users.id, email: users.email })\n\t\t\t.from(users)\n\t\t\t.where(eq(users.email, email));\n\n\t\tif (existing[0]) return { id: existing[0].id, email: existing[0].email };\n\n\t\tconst id = randomUUID();\n\t\tconst now = new Date();\n\t\tawait db.insert(users).values({\n\t\t\tid,\n\t\t\temail,\n\t\t\tcreatedAt: now,\n\t\t\tupdatedAt: now,\n\t\t});\n\n\t\treturn { id, email };\n\t}\n\n\t// ── public API ───────────────────────────────────────────────────────────\n\n\tasync function sendLink(email: string): Promise<{ sent: boolean }> {\n\t\tconst token = randomBytes(32).toString(\"hex\");\n\t\tconst now = new Date();\n\t\tconst expiresAt = new Date(now.getTime() + tokenExpiry * 1000);\n\n\t\t// Ensure the user record exists before issuing a link.\n\t\tawait findOrCreateUser(email);\n\n\t\tawait db.insert(magicLinks).values({\n\t\t\tid: randomUUID(),\n\t\t\temail,\n\t\t\ttoken,\n\t\t\texpiresAt,\n\t\t\tused: false,\n\t\t\tcreatedAt: now,\n\t\t});\n\n\t\tconst url = `${config.appUrl}${callbackPath}?token=${token}`;\n\t\tawait config.sendMagicLink(email, token, url);\n\n\t\treturn { sent: true };\n\t}\n\n\tasync function verify(token: string): Promise<{\n\t\tuser: { id: string; email: string };\n\t\tsession: { token: string; expiresAt: Date };\n\t} | null> {\n\t\tconst now = new Date();\n\n\t\tconst rows = await db\n\t\t\t.select()\n\t\t\t.from(magicLinks)\n\t\t\t.where(\n\t\t\t\tand(eq(magicLinks.token, token), eq(magicLinks.used, false), gt(magicLinks.expiresAt, now)),\n\t\t\t);\n\n\t\tconst link = rows[0];\n\t\tif (!link) return null;\n\n\t\t// Mark as used immediately to prevent replay.\n\t\tawait db.update(magicLinks).set({ used: true }).where(eq(magicLinks.id, link.id));\n\n\t\tconst user = await findOrCreateUser(link.email);\n\t\tconst { token: sessionToken, session } = await sessionManager.create(user.id);\n\n\t\treturn {\n\t\t\tuser,\n\t\t\tsession: { token: sessionToken, expiresAt: session.expiresAt },\n\t\t};\n\t}\n\n\tasync function handleRequest(request: Request): Promise<Response | null> {\n\t\tconst url = new URL(request.url);\n\t\tconst pathname = url.pathname;\n\n\t\t// POST /auth/magic-link/send\n\t\tif (request.method === \"POST\" && pathname === \"/auth/magic-link/send\") {\n\t\t\tlet body: unknown;\n\t\t\ttry {\n\t\t\t\tbody = await request.json();\n\t\t\t} catch {\n\t\t\t\treturn new Response(JSON.stringify({ error: \"Invalid JSON body\" }), {\n\t\t\t\t\tstatus: 400,\n\t\t\t\t\theaders: { \"Content-Type\": \"application/json\" },\n\t\t\t\t});\n\t\t\t}\n\n\t\t\tif (\n\t\t\t\ttypeof body !== \"object\" ||\n\t\t\t\tbody === null ||\n\t\t\t\ttypeof (body as Record<string, unknown>).email !== \"string\"\n\t\t\t) {\n\t\t\t\treturn new Response(JSON.stringify({ error: \"Missing required field: email\" }), {\n\t\t\t\t\tstatus: 400,\n\t\t\t\t\theaders: { \"Content-Type\": \"application/json\" },\n\t\t\t\t});\n\t\t\t}\n\n\t\t\tconst email = String((body as Record<string, unknown>).email)\n\t\t\t\t.trim()\n\t\t\t\t.toLowerCase();\n\t\t\tconst result = await sendLink(email);\n\t\t\treturn new Response(JSON.stringify(result), {\n\t\t\t\tstatus: 200,\n\t\t\t\theaders: { \"Content-Type\": \"application/json\" },\n\t\t\t});\n\t\t}\n\n\t\t// GET /auth/magic-link/verify?token=...\n\t\tif (request.method === \"GET\" && pathname === callbackPath) {\n\t\t\tconst token = url.searchParams.get(\"token\");\n\t\t\tif (!token) {\n\t\t\t\treturn new Response(JSON.stringify({ error: \"Missing token parameter\" }), {\n\t\t\t\t\tstatus: 400,\n\t\t\t\t\theaders: { \"Content-Type\": \"application/json\" },\n\t\t\t\t});\n\t\t\t}\n\n\t\t\tconst result = await verify(token);\n\t\t\tif (!result) {\n\t\t\t\treturn new Response(JSON.stringify({ error: \"Invalid or expired magic link\" }), {\n\t\t\t\t\tstatus: 401,\n\t\t\t\t\theaders: { \"Content-Type\": \"application/json\" },\n\t\t\t\t});\n\t\t\t}\n\n\t\t\treturn new Response(JSON.stringify(result), {\n\t\t\t\tstatus: 200,\n\t\t\t\theaders: { \"Content-Type\": \"application/json\" },\n\t\t\t});\n\t\t}\n\n\t\treturn null;\n\t}\n\n\treturn { sendLink, verify, handleRequest };\n}\n","/**\n * Higher-order function that wraps a plugin endpoint handler with IP-based\n * rate limiting. When the limit is exceeded it responds with 429 and a\n * Retry-After header before the wrapped handler is ever called.\n */\n\nimport type { PluginEndpoint } from \"../plugin/types.js\";\nimport type { RateLimiter } from \"./rate-limiter.js\";\n\nexport interface RateLimitMiddlewareOptions {\n\t/**\n\t * Derive the rate-limit key from the incoming request.\n\t *\n\t * Defaults to the first non-empty value of:\n\t * x-forwarded-for → first IP in the comma-separated list\n\t * x-real-ip\n\t * \"unknown\"\n\t */\n\tkeyExtractor?: (request: Request) => string;\n}\n\nfunction defaultKeyExtractor(request: Request): string {\n\tconst forwarded = request.headers.get(\"x-forwarded-for\");\n\tif (forwarded) {\n\t\tconst first = (forwarded.split(\",\")[0] ?? \"\").trim();\n\t\tif (first) return first;\n\t}\n\tconst real = request.headers.get(\"x-real-ip\");\n\tif (real) return real.trim();\n\treturn \"unknown\";\n}\n\nexport function withRateLimit(\n\thandler: PluginEndpoint[\"handler\"],\n\tlimiter: RateLimiter,\n\toptions?: RateLimitMiddlewareOptions,\n): PluginEndpoint[\"handler\"] {\n\tconst extractKey = options?.keyExtractor ?? defaultKeyExtractor;\n\n\treturn async function rateLimitedHandler(request, ctx) {\n\t\tconst key = extractKey(request);\n\t\tconst result = limiter.check(key);\n\n\t\tif (!result.allowed) {\n\t\t\tconst retryAfter = Math.ceil((result.resetAt.getTime() - Date.now()) / 1000);\n\t\t\treturn new Response(\n\t\t\t\tJSON.stringify({ error: { code: \"RATE_LIMITED\", message: \"Too many requests\" } }),\n\t\t\t\t{\n\t\t\t\t\tstatus: 429,\n\t\t\t\t\theaders: {\n\t\t\t\t\t\t\"Content-Type\": \"application/json\",\n\t\t\t\t\t\t\"Retry-After\": String(Math.max(retryAfter, 1)),\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t);\n\t\t}\n\n\t\treturn handler(request, ctx);\n\t};\n}\n","/**\n * In-memory sliding window rate limiter for auth endpoints.\n *\n * Uses a Map keyed by the caller-supplied string (typically an IP address).\n * Each entry stores a list of request timestamps within the current window.\n * Expired timestamps are pruned on every check so memory stays bounded.\n */\n\nexport interface RateLimitConfig {\n\t/** Max requests allowed within the window */\n\tmax: number;\n\t/** Window duration in seconds */\n\twindow: number;\n}\n\nexport interface RateLimitResult {\n\tallowed: boolean;\n\t/** Requests remaining in the current window */\n\tremaining: number;\n\t/** When the oldest in-window request expires and a slot re-opens */\n\tresetAt: Date;\n}\n\nexport interface RateLimiter {\n\t/** Check whether the key is within its limit. Consumes one slot when allowed. */\n\tcheck(key: string): RateLimitResult;\n\t/** Clear all recorded hits for a key (useful in tests or on successful auth). */\n\treset(key: string): void;\n}\n\nexport function createRateLimiter(config: RateLimitConfig): RateLimiter {\n\tconst { max, window: windowSeconds } = config;\n\tconst windowMs = windowSeconds * 1000;\n\n\t// Map<key, sorted list of hit timestamps (ms since epoch)>\n\tconst store = new Map<string, number[]>();\n\n\tfunction prune(timestamps: number[], now: number): number[] {\n\t\tconst cutoff = now - windowMs;\n\t\t// Timestamps are appended in order, so we can slice from the front.\n\t\tlet i = 0;\n\t\twhile (i < timestamps.length && (timestamps[i] ?? Infinity) <= cutoff) {\n\t\t\ti++;\n\t\t}\n\t\treturn i === 0 ? timestamps : timestamps.slice(i);\n\t}\n\n\treturn {\n\t\tcheck(key: string): RateLimitResult {\n\t\t\tconst now = Date.now();\n\t\t\tconst raw = store.get(key) ?? [];\n\t\t\tconst hits = prune(raw, now);\n\n\t\t\tif (hits.length >= max) {\n\t\t\t\t// The window resets when the oldest hit exits the window.\n\t\t\t\t// hits is non-empty here (length >= max >= 1), so the index is safe.\n\t\t\t\tconst oldest = hits[0] ?? now;\n\t\t\t\tconst resetAt = new Date(oldest + windowMs);\n\t\t\t\tstore.set(key, hits);\n\t\t\t\treturn { allowed: false, remaining: 0, resetAt };\n\t\t\t}\n\n\t\t\thits.push(now);\n\t\t\tstore.set(key, hits);\n\n\t\t\tconst remaining = max - hits.length;\n\t\t\t// hits has at least one entry (the one we just pushed).\n\t\t\tconst oldest = hits[0] ?? now;\n\t\t\tconst resetAt = new Date(oldest + windowMs);\n\t\t\treturn { allowed: true, remaining, resetAt };\n\t\t},\n\n\t\treset(key: string): void {\n\t\t\tstore.delete(key);\n\t\t},\n\t};\n}\n","import type { KavachPlugin } from \"../plugin/types.js\";\nimport { createSessionManager } from \"../session/session.js\";\nimport type { MagicLinkConfig } from \"./magic-link.js\";\nimport { createMagicLinkModule } from \"./magic-link.js\";\nimport { withRateLimit } from \"./rate-limit-middleware.js\";\nimport { createRateLimiter } from \"./rate-limiter.js\";\n\n// Re-export the config type so callers can import from this file.\nexport type { MagicLinkConfig };\n\n// ---------------------------------------------------------------------------\n// Plugin factory\n// ---------------------------------------------------------------------------\n\nexport function magicLink(config: MagicLinkConfig): KavachPlugin {\n\treturn {\n\t\tid: \"kavach-magic-link\",\n\n\t\tasync init(ctx): Promise<undefined> {\n\t\t\tconst sessionConfig = ctx.config.auth?.session;\n\t\t\tif (!sessionConfig) {\n\t\t\t\tthrow new Error(\n\t\t\t\t\t\"kavach-magic-link plugin requires auth.session to be configured so that sessions can be issued on successful verification.\",\n\t\t\t\t);\n\t\t\t}\n\n\t\t\tconst sessionManager = createSessionManager(sessionConfig, ctx.db);\n\t\t\tconst module = createMagicLinkModule(config, ctx.db, sessionManager);\n\n\t\t\tconst sendLimiter = createRateLimiter({ max: 5, window: 60 });\n\n\t\t\t// POST /auth/magic-link/send\n\t\t\t// Accepts { email: string } and sends a magic link to that address.\n\t\t\tctx.addEndpoint({\n\t\t\t\tmethod: \"POST\",\n\t\t\t\tpath: \"/auth/magic-link/send\",\n\t\t\t\tmetadata: {\n\t\t\t\t\trateLimit: { window: 60, max: 5 },\n\t\t\t\t\tdescription: \"Send a magic link to the provided email address\",\n\t\t\t\t},\n\t\t\t\thandler: withRateLimit(async (request) => {\n\t\t\t\t\tlet body: unknown;\n\t\t\t\t\ttry {\n\t\t\t\t\t\tbody = await request.json();\n\t\t\t\t\t} catch {\n\t\t\t\t\t\treturn new Response(JSON.stringify({ error: \"Invalid JSON body\" }), {\n\t\t\t\t\t\t\tstatus: 400,\n\t\t\t\t\t\t\theaders: { \"Content-Type\": \"application/json\" },\n\t\t\t\t\t\t});\n\t\t\t\t\t}\n\n\t\t\t\t\tconst b = body as Record<string, unknown>;\n\t\t\t\t\tconst rawEmail = typeof b.email === \"string\" ? b.email.trim().toLowerCase() : null;\n\n\t\t\t\t\tif (!rawEmail) {\n\t\t\t\t\t\treturn new Response(JSON.stringify({ error: \"Missing required field: email\" }), {\n\t\t\t\t\t\t\tstatus: 400,\n\t\t\t\t\t\t\theaders: { \"Content-Type\": \"application/json\" },\n\t\t\t\t\t\t});\n\t\t\t\t\t}\n\n\t\t\t\t\ttry {\n\t\t\t\t\t\tconst result = await module.sendLink(rawEmail);\n\t\t\t\t\t\treturn new Response(JSON.stringify(result), {\n\t\t\t\t\t\t\tstatus: 200,\n\t\t\t\t\t\t\theaders: { \"Content-Type\": \"application/json\" },\n\t\t\t\t\t\t});\n\t\t\t\t\t} catch (err) {\n\t\t\t\t\t\treturn new Response(\n\t\t\t\t\t\t\tJSON.stringify({\n\t\t\t\t\t\t\t\terror: err instanceof Error ? err.message : \"Failed to send magic link\",\n\t\t\t\t\t\t\t}),\n\t\t\t\t\t\t\t{ status: 500, headers: { \"Content-Type\": \"application/json\" } },\n\t\t\t\t\t\t);\n\t\t\t\t\t}\n\t\t\t\t}, sendLimiter),\n\t\t\t});\n\n\t\t\t// GET /auth/magic-link/verify\n\t\t\t// Accepts ?token=<token> and returns user + session on success.\n\t\t\tctx.addEndpoint({\n\t\t\t\tmethod: \"GET\",\n\t\t\t\tpath: \"/auth/magic-link/verify\",\n\t\t\t\tmetadata: {\n\t\t\t\t\tdescription: \"Verify a magic link token and return a session\",\n\t\t\t\t},\n\t\t\t\tasync handler(request) {\n\t\t\t\t\tconst url = new URL(request.url);\n\t\t\t\t\tconst token = url.searchParams.get(\"token\");\n\n\t\t\t\t\tif (!token) {\n\t\t\t\t\t\treturn new Response(JSON.stringify({ error: \"Missing token query parameter\" }), {\n\t\t\t\t\t\t\tstatus: 400,\n\t\t\t\t\t\t\theaders: { \"Content-Type\": \"application/json\" },\n\t\t\t\t\t\t});\n\t\t\t\t\t}\n\n\t\t\t\t\tconst result = await module.verify(token);\n\n\t\t\t\t\tif (!result) {\n\t\t\t\t\t\treturn new Response(JSON.stringify({ error: \"Invalid or expired magic link\" }), {\n\t\t\t\t\t\t\tstatus: 401,\n\t\t\t\t\t\t\theaders: { \"Content-Type\": \"application/json\" },\n\t\t\t\t\t\t});\n\t\t\t\t\t}\n\n\t\t\t\t\treturn new Response(JSON.stringify(result), {\n\t\t\t\t\t\tstatus: 200,\n\t\t\t\t\t\theaders: { \"Content-Type\": \"application/json\" },\n\t\t\t\t\t});\n\t\t\t\t},\n\t\t\t});\n\t\t},\n\t};\n}\n","/**\n * PKCE (Proof Key for Code Exchange) helpers using the Web Crypto API.\n *\n * All operations are async and use `crypto.subtle` — no Node.js-specific\n * APIs so the code runs on edge runtimes and browsers unchanged.\n *\n * Spec: https://datatracker.ietf.org/doc/html/rfc7636\n */\n\n/** Length of the generated code verifier in bytes (maps to ~86 base64url chars). */\nconst VERIFIER_BYTE_LENGTH = 64;\n\n/**\n * Generate a cryptographically random PKCE code verifier.\n *\n * The verifier is `VERIFIER_BYTE_LENGTH` random bytes encoded as\n * base64url (no padding), satisfying RFC 7636 §4.1.\n */\nexport function generateCodeVerifier(): string {\n\tconst bytes = new Uint8Array(VERIFIER_BYTE_LENGTH);\n\tcrypto.getRandomValues(bytes);\n\treturn base64url(bytes);\n}\n\n/**\n * Derive the S256 code challenge from a code verifier.\n *\n * `code_challenge = BASE64URL(SHA256(ASCII(code_verifier)))`\n *\n * @param codeVerifier A value previously returned by `generateCodeVerifier`.\n */\nexport async function deriveCodeChallenge(codeVerifier: string): Promise<string> {\n\tconst encoded = new TextEncoder().encode(codeVerifier);\n\tconst digest = await crypto.subtle.digest(\"SHA-256\", encoded);\n\treturn base64url(new Uint8Array(digest));\n}\n\n/**\n * Encode a `Uint8Array` as base64url (RFC 4648 §5, no padding).\n */\nfunction base64url(bytes: Uint8Array): string {\n\t// btoa operates on binary strings\n\tlet binary = \"\";\n\tfor (let i = 0; i < bytes.length; i++) {\n\t\tbinary += String.fromCharCode(bytes[i] as number);\n\t}\n\treturn btoa(binary).replace(/\\+/g, \"-\").replace(/\\//g, \"_\").replace(/=/g, \"\");\n}\n","/**\n * OAuth proxy module for mobile apps.\n *\n * Mobile apps cannot safely store OAuth client secrets. This module acts as a\n * server-side intermediary: the mobile app redirects to the provider via\n * KavachOS, which holds the secret and exchanges the authorization code for\n * tokens on the app's behalf.\n *\n * Flow:\n * 1. Mobile app calls GET /auth/oauth-proxy/start?provider=google&redirect_uri=myapp://callback\n * 2. KavachOS validates redirect_uri, stores proxy state, returns provider auth URL.\n * 3. User authenticates with the provider in a browser.\n * 4. Provider redirects to KavachOS callback with code + state.\n * 5. KavachOS exchanges the code (using the server-held client secret), then\n * redirects the mobile app to its custom scheme URL with tokens as query params.\n *\n * Security:\n * - redirect_uri is validated against an explicit allowlist — no open redirects.\n * - Proxy state is a random UUID stored in memory with a 10-minute TTL.\n * - PKCE passthrough: the mobile app may supply a code_challenge; KavachOS\n * forwards it to the provider and passes the verifier back via the callback.\n */\n\nimport { randomUUID } from \"node:crypto\";\nimport { generateCodeVerifier } from \"./oauth/pkce.js\";\nimport type { OAuthProvider } from \"./oauth/types.js\";\nimport type { RateLimiter } from \"./rate-limiter.js\";\nimport { createRateLimiter } from \"./rate-limiter.js\";\n\n// ---------------------------------------------------------------------------\n// Public types\n// ---------------------------------------------------------------------------\n\nexport interface OAuthProxyConfig {\n\t/**\n\t * Allowed redirect URIs for mobile apps (e.g. `\"myapp://callback\"`).\n\t * Only exact matches or scheme-prefix matches (when entry ends with `://`)\n\t * are allowed. No wildcards. This is an allowlist — anything not listed\n\t * will be rejected.\n\t */\n\tallowedRedirectUris: string[];\n\t/** Rate limit per IP. Defaults to 20 requests per 60 seconds. */\n\trateLimit?: { max: number; windowSeconds: number };\n\t/**\n\t * How long a proxy state entry lives in seconds.\n\t * Defaults to 600 (10 minutes).\n\t */\n\tstateTtlSeconds?: number;\n}\n\nexport interface ProxyTokens {\n\taccessToken: string;\n\trefreshToken?: string;\n\tidToken?: string;\n\texpiresIn?: number;\n}\n\nexport interface OAuthProxyModule {\n\t/**\n\t * Start the proxy flow.\n\t *\n\t * Validates `redirectUri` against the allowlist, generates a PKCE verifier,\n\t * stores proxy state keyed by an opaque `proxyState` value, and returns the\n\t * provider authorization URL for the caller to redirect to.\n\t *\n\t * @param provider Provider ID (must be in `providers` map).\n\t * @param redirectUri Mobile app callback URI. Must be in `allowedRedirectUris`.\n\t * @param state Optional caller-supplied state passed back on completion.\n\t * @param codeChallenge Optional PKCE code challenge from the mobile app (S256).\n\t */\n\tstartFlow(\n\t\tprovider: string,\n\t\tredirectUri: string,\n\t\tstate?: string,\n\t\tcodeChallenge?: string,\n\t): Promise<{ authUrl: string; proxyState: string }>;\n\n\t/**\n\t * Handle the provider callback.\n\t *\n\t * Looks up the stored proxy state, exchanges the code with the provider,\n\t * and returns the final redirect URL for the mobile app plus the raw tokens.\n\t *\n\t * @param code Authorization code from the provider.\n\t * @param proxyState The opaque state value returned by `startFlow`.\n\t */\n\thandleCallback(\n\t\tcode: string,\n\t\tproxyState: string,\n\t): Promise<{ redirectUrl: string; tokens: ProxyTokens }>;\n\n\t/** Route HTTP requests to the proxy endpoints. Returns null if no match. */\n\thandleRequest(request: Request): Promise<Response | null>;\n}\n\n// ---------------------------------------------------------------------------\n// Internal state entry\n// ---------------------------------------------------------------------------\n\ninterface ProxyStateEntry {\n\tprovider: string;\n\tredirectUri: string;\n\t/** Caller's own state value (forwarded to the mobile app on completion). */\n\tcallerState: string | undefined;\n\t/** PKCE verifier KavachOS generated for the provider exchange. */\n\tserverCodeVerifier: string;\n\t/** KavachOS's redirect URI pointing back to the callback endpoint. */\n\tserverRedirectUri: string;\n\texpiresAt: number;\n}\n\n// ---------------------------------------------------------------------------\n// Helpers\n// ---------------------------------------------------------------------------\n\nconst DEFAULT_STATE_TTL_SECONDS = 600;\nconst DEFAULT_RATE_LIMIT = { max: 20, windowSeconds: 60 };\n\n/** Returns true when `uri` is in the allowlist. */\nfunction isAllowedRedirectUri(uri: string, allowedRedirectUris: string[]): boolean {\n\tfor (const allowed of allowedRedirectUris) {\n\t\t// Exact match.\n\t\tif (uri === allowed) return true;\n\t\t// Scheme-only entry (e.g. \"myapp://\") — allow any URI under that scheme.\n\t\tif (allowed.endsWith(\"://\") && uri.startsWith(allowed)) return true;\n\t}\n\treturn false;\n}\n\nfunction jsonError(message: string, status: number): Response {\n\treturn new Response(JSON.stringify({ error: message }), {\n\t\tstatus,\n\t\theaders: { \"Content-Type\": \"application/json\" },\n\t});\n}\n\nfunction getClientIp(request: Request): string {\n\treturn (\n\t\trequest.headers.get(\"x-forwarded-for\")?.split(\",\")[0]?.trim() ??\n\t\trequest.headers.get(\"x-real-ip\") ??\n\t\t\"unknown\"\n\t);\n}\n\n// ---------------------------------------------------------------------------\n// Factory\n// ---------------------------------------------------------------------------\n\nexport function createOAuthProxyModule(\n\tconfig: OAuthProxyConfig,\n\tproviders: Record<string, OAuthProvider>,\n\t/** Base URL of the KavachOS server, e.g. \"https://auth.example.com\". */\n\tbaseUrl: string,\n): OAuthProxyModule {\n\tconst ttlMs = (config.stateTtlSeconds ?? DEFAULT_STATE_TTL_SECONDS) * 1000;\n\tconst rl = config.rateLimit ?? DEFAULT_RATE_LIMIT;\n\tconst rateLimiter: RateLimiter = createRateLimiter({ max: rl.max, window: rl.windowSeconds });\n\n\t// In-memory state store — keyed by opaque proxyState UUID.\n\tconst stateStore = new Map<string, ProxyStateEntry>();\n\n\t// The KavachOS-side callback URL registered with the provider.\n\tconst serverCallbackUri = `${baseUrl.replace(/\\/$/, \"\")}/auth/oauth-proxy/callback`;\n\n\t// ---------------------------------------------------------------------------\n\t// Periodic cleanup: prune expired entries whenever we write.\n\t// ---------------------------------------------------------------------------\n\n\tfunction pruneExpired(): void {\n\t\tconst now = Date.now();\n\t\tfor (const [key, entry] of stateStore) {\n\t\t\tif (entry.expiresAt <= now) {\n\t\t\t\tstateStore.delete(key);\n\t\t\t}\n\t\t}\n\t}\n\n\t// ---------------------------------------------------------------------------\n\t// startFlow\n\t// ---------------------------------------------------------------------------\n\n\tasync function startFlow(\n\t\tproviderId: string,\n\t\tredirectUri: string,\n\t\tcallerState?: string,\n\t\t_codeChallenge?: string,\n\t): Promise<{ authUrl: string; proxyState: string }> {\n\t\tif (!isAllowedRedirectUri(redirectUri, config.allowedRedirectUris)) {\n\t\t\tthrow new OAuthProxyError(\n\t\t\t\t\"redirect_uri_not_allowed\",\n\t\t\t\t`Redirect URI is not in the allowlist: ${redirectUri}`,\n\t\t\t);\n\t\t}\n\n\t\tconst provider = providers[providerId];\n\t\tif (!provider) {\n\t\t\tthrow new OAuthProxyError(\"unknown_provider\", `Unknown OAuth provider: ${providerId}`);\n\t\t}\n\n\t\tpruneExpired();\n\n\t\tconst proxyState = randomUUID();\n\t\tconst serverCodeVerifier = generateCodeVerifier();\n\t\tconst expiresAt = Date.now() + ttlMs;\n\n\t\tstateStore.set(proxyState, {\n\t\t\tprovider: providerId,\n\t\t\tredirectUri,\n\t\t\tcallerState,\n\t\t\tserverCodeVerifier,\n\t\t\tserverRedirectUri: serverCallbackUri,\n\t\t\texpiresAt,\n\t\t});\n\n\t\t// The state we pass to the provider encodes our proxyState so the callback\n\t\t// can look it up. We keep it as-is; the provider will round-trip it.\n\t\tconst authUrl = await provider.getAuthorizationUrl(\n\t\t\tproxyState,\n\t\t\tserverCodeVerifier,\n\t\t\tserverCallbackUri,\n\t\t);\n\n\t\treturn { authUrl, proxyState };\n\t}\n\n\t// ---------------------------------------------------------------------------\n\t// handleCallback\n\t// ---------------------------------------------------------------------------\n\n\tasync function handleCallback(\n\t\tcode: string,\n\t\tproxyState: string,\n\t): Promise<{ redirectUrl: string; tokens: ProxyTokens }> {\n\t\tconst entry = stateStore.get(proxyState);\n\n\t\tif (!entry) {\n\t\t\tthrow new OAuthProxyError(\"invalid_state\", \"Unknown or already-used proxy state.\");\n\t\t}\n\n\t\tif (entry.expiresAt <= Date.now()) {\n\t\t\tstateStore.delete(proxyState);\n\t\t\tthrow new OAuthProxyError(\"state_expired\", \"Proxy state has expired. Start the flow again.\");\n\t\t}\n\n\t\t// Consume — delete before the network call to prevent replay.\n\t\tstateStore.delete(proxyState);\n\n\t\tconst provider = providers[entry.provider];\n\t\tif (!provider) {\n\t\t\tthrow new OAuthProxyError(\n\t\t\t\t\"unknown_provider\",\n\t\t\t\t`Provider \"${entry.provider}\" is no longer configured.`,\n\t\t\t);\n\t\t}\n\n\t\t// Exchange the code using the server-held client secret.\n\t\tconst providerTokens = await provider.exchangeCode(\n\t\t\tcode,\n\t\t\tentry.serverCodeVerifier,\n\t\t\tentry.serverRedirectUri,\n\t\t);\n\n\t\t// Build the mobile app redirect URL. Tokens are passed as query params\n\t\t// so custom-scheme handlers can read them from the URL on all platforms.\n\t\tconst params = new URLSearchParams();\n\t\tparams.set(\"access_token\", providerTokens.accessToken);\n\t\tif (providerTokens.refreshToken) {\n\t\t\tparams.set(\"refresh_token\", providerTokens.refreshToken);\n\t\t}\n\t\tif (providerTokens.expiresIn !== undefined) {\n\t\t\tparams.set(\"expires_in\", String(providerTokens.expiresIn));\n\t\t}\n\t\t// Forward id_token if the provider included one in the raw response.\n\t\tconst rawIdToken = providerTokens.raw.id_token;\n\t\tif (typeof rawIdToken === \"string\") {\n\t\t\tparams.set(\"id_token\", rawIdToken);\n\t\t}\n\t\tif (entry.callerState) {\n\t\t\tparams.set(\"state\", entry.callerState);\n\t\t}\n\n\t\tconst separator = entry.redirectUri.includes(\"?\") ? \"&\" : \"?\";\n\t\tconst redirectUrl = `${entry.redirectUri}${separator}${params.toString()}`;\n\n\t\tconst tokens: ProxyTokens = {\n\t\t\taccessToken: providerTokens.accessToken,\n\t\t\trefreshToken: providerTokens.refreshToken,\n\t\t\tidToken: typeof rawIdToken === \"string\" ? rawIdToken : undefined,\n\t\t\texpiresIn: providerTokens.expiresIn,\n\t\t};\n\n\t\treturn { redirectUrl, tokens };\n\t}\n\n\t// ---------------------------------------------------------------------------\n\t// handleRequest\n\t// ---------------------------------------------------------------------------\n\n\tasync function handleRequest(request: Request): Promise<Response | null> {\n\t\tconst url = new URL(request.url);\n\t\tconst pathname = url.pathname.replace(/\\/$/, \"\");\n\n\t\t// ── GET /auth/oauth-proxy/start ──────────────────────────────────────────\n\n\t\tif (request.method === \"GET\" && pathname.endsWith(\"/auth/oauth-proxy/start\")) {\n\t\t\tconst ip = getClientIp(request);\n\t\t\tconst rlResult = rateLimiter.check(ip);\n\t\t\tif (!rlResult.allowed) {\n\t\t\t\treturn jsonError(\"Too many requests\", 429);\n\t\t\t}\n\n\t\t\tconst provider = url.searchParams.get(\"provider\");\n\t\t\tconst redirectUri = url.searchParams.get(\"redirect_uri\");\n\t\t\tconst callerState = url.searchParams.get(\"state\") ?? undefined;\n\t\t\tconst codeChallenge = url.searchParams.get(\"code_challenge\") ?? undefined;\n\n\t\t\tif (!provider) {\n\t\t\t\treturn jsonError(\"Missing required query parameter: provider\", 400);\n\t\t\t}\n\t\t\tif (!redirectUri) {\n\t\t\t\treturn jsonError(\"Missing required query parameter: redirect_uri\", 400);\n\t\t\t}\n\n\t\t\ttry {\n\t\t\t\tconst result = await startFlow(provider, redirectUri, callerState, codeChallenge);\n\t\t\t\treturn new Response(JSON.stringify(result), {\n\t\t\t\t\tstatus: 200,\n\t\t\t\t\theaders: { \"Content-Type\": \"application/json\" },\n\t\t\t\t});\n\t\t\t} catch (err) {\n\t\t\t\tif (err instanceof OAuthProxyError) {\n\t\t\t\t\tconst status = err.code === \"redirect_uri_not_allowed\" ? 400 : 400;\n\t\t\t\t\treturn jsonError(err.message, status);\n\t\t\t\t}\n\t\t\t\treturn jsonError(\"Failed to start OAuth proxy flow\", 500);\n\t\t\t}\n\t\t}\n\n\t\t// ── GET /auth/oauth-proxy/callback ───────────────────────────────────────\n\n\t\tif (request.method === \"GET\" && pathname.endsWith(\"/auth/oauth-proxy/callback\")) {\n\t\t\tconst code = url.searchParams.get(\"code\");\n\t\t\tconst proxyState = url.searchParams.get(\"state\");\n\t\t\tconst errorParam = url.searchParams.get(\"error\");\n\n\t\t\tif (errorParam) {\n\t\t\t\t// Provider returned an error — we need to redirect the mobile app to\n\t\t\t\t// an error state. Try to look up the state to find the redirect_uri.\n\t\t\t\tconst entry = proxyState ? stateStore.get(proxyState) : undefined;\n\t\t\t\tif (entry) {\n\t\t\t\t\tstateStore.delete(proxyState as string);\n\t\t\t\t\tconst params = new URLSearchParams({ error: errorParam });\n\t\t\t\t\tif (entry.callerState) params.set(\"state\", entry.callerState);\n\t\t\t\t\tconst sep = entry.redirectUri.includes(\"?\") ? \"&\" : \"?\";\n\t\t\t\t\treturn Response.redirect(`${entry.redirectUri}${sep}${params.toString()}`, 302);\n\t\t\t\t}\n\t\t\t\treturn jsonError(`Provider returned error: ${errorParam}`, 400);\n\t\t\t}\n\n\t\t\tif (!code) {\n\t\t\t\treturn jsonError(\"Missing required query parameter: code\", 400);\n\t\t\t}\n\t\t\tif (!proxyState) {\n\t\t\t\treturn jsonError(\"Missing required query parameter: state\", 400);\n\t\t\t}\n\n\t\t\ttry {\n\t\t\t\tconst { redirectUrl } = await handleCallback(code, proxyState);\n\t\t\t\treturn Response.redirect(redirectUrl, 302);\n\t\t\t} catch (err) {\n\t\t\t\tif (err instanceof OAuthProxyError) {\n\t\t\t\t\treturn jsonError(err.message, 400);\n\t\t\t\t}\n\t\t\t\treturn jsonError(\"OAuth callback failed\", 500);\n\t\t\t}\n\t\t}\n\n\t\treturn null;\n\t}\n\n\treturn { startFlow, handleCallback, handleRequest };\n}\n\n// ---------------------------------------------------------------------------\n// Error class\n// ---------------------------------------------------------------------------\n\nexport class OAuthProxyError extends Error {\n\treadonly code: string;\n\n\tconstructor(code: string, message: string) {\n\t\tsuper(message);\n\t\tthis.name = \"OAuthProxyError\";\n\t\tthis.code = code;\n\t}\n}\n","import type { KavachPlugin } from \"../plugin/types.js\";\nimport type { OAuthProvider } from \"./oauth/types.js\";\nimport type { OAuthProxyConfig } from \"./oauth-proxy.js\";\nimport { createOAuthProxyModule } from \"./oauth-proxy.js\";\n\nexport interface OAuthProxyPluginConfig extends OAuthProxyConfig {\n\t/**\n\t * Provider instances to make available for the proxy.\n\t * Keys are the provider IDs used in the `provider` query parameter.\n\t *\n\t * @example\n\t * ```typescript\n\t * import { createGoogleProvider } from 'kavachos/auth/oauth/providers/google';\n\t *\n\t * oauthProxy({\n\t * providers: {\n\t * google: createGoogleProvider({ clientId: '...', clientSecret: '...' }),\n\t * },\n\t * allowedRedirectUris: ['com.example.app://callback'],\n\t * })\n\t * ```\n\t */\n\tproviders: Record<string, OAuthProvider>;\n}\n\nexport function oauthProxy(config: OAuthProxyPluginConfig): KavachPlugin {\n\treturn {\n\t\tid: \"kavach-oauth-proxy\",\n\n\t\tasync init(ctx): Promise<undefined> {\n\t\t\tconst baseUrl = (ctx.config as unknown as { baseUrl?: string }).baseUrl;\n\n\t\t\tif (!baseUrl) {\n\t\t\t\tthrow new Error(\n\t\t\t\t\t\"oauthProxy plugin requires `baseUrl` to be set in the KavachOS config so it can construct the server-side callback URL.\",\n\t\t\t\t);\n\t\t\t}\n\n\t\t\tconst mod = createOAuthProxyModule(config, config.providers, baseUrl);\n\n\t\t\t// Delegate all matching requests to the module. The module owns\n\t\t\t// route matching, rate limiting, and response construction.\n\n\t\t\t// GET /auth/oauth-proxy/start\n\t\t\tctx.addEndpoint({\n\t\t\t\tmethod: \"GET\",\n\t\t\t\tpath: \"/auth/oauth-proxy/start\",\n\t\t\t\tmetadata: {\n\t\t\t\t\tdescription:\n\t\t\t\t\t\t\"Start an OAuth proxy flow for a mobile app. Returns the provider authorization URL.\",\n\t\t\t\t\trateLimit: {\n\t\t\t\t\t\twindow: (config.rateLimit?.windowSeconds ?? 60) * 1000,\n\t\t\t\t\t\tmax: config.rateLimit?.max ?? 20,\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t\tasync handler(request) {\n\t\t\t\t\tconst response = await mod.handleRequest(request);\n\t\t\t\t\t// The module always returns a response for this path; the null\n\t\t\t\t\t// branch cannot be reached here in practice, but we need to\n\t\t\t\t\t// satisfy the type system.\n\t\t\t\t\treturn (\n\t\t\t\t\t\tresponse ?? new Response(JSON.stringify({ error: \"Not handled\" }), { status: 500 })\n\t\t\t\t\t);\n\t\t\t\t},\n\t\t\t});\n\n\t\t\t// GET /auth/oauth-proxy/callback\n\t\t\tctx.addEndpoint({\n\t\t\t\tmethod: \"GET\",\n\t\t\t\tpath: \"/auth/oauth-proxy/callback\",\n\t\t\t\tmetadata: {\n\t\t\t\t\tdescription:\n\t\t\t\t\t\t\"Provider callback endpoint. Exchanges the authorization code and redirects the mobile app.\",\n\t\t\t\t},\n\t\t\t\tasync handler(request) {\n\t\t\t\t\tconst response = await mod.handleRequest(request);\n\t\t\t\t\treturn (\n\t\t\t\t\t\tresponse ?? new Response(JSON.stringify({ error: \"Not handled\" }), { status: 500 })\n\t\t\t\t\t);\n\t\t\t\t},\n\t\t\t});\n\n\t\t\treturn undefined;\n\t\t},\n\t};\n}\n","/**\n * OIDC Provider module for KavachOS.\n *\n * Turns KavachOS into a full OpenID Connect identity provider (IdP).\n * External applications can register as OIDC clients and authenticate\n * their users against KavachOS using standard authorization code flow\n * with PKCE, ID tokens, refresh tokens, discovery, and JWKS.\n *\n * @example\n * ```typescript\n * import { generateKeyPair } from 'jose';\n * import { createOidcProviderModule } from 'kavachos/auth';\n *\n * const { privateKey } = await generateKeyPair('RS256');\n * const oidc = createOidcProviderModule(\n * {\n * issuer: 'https://auth.example.com',\n * signingKey: privateKey,\n * },\n * db,\n * getUserClaims,\n * );\n *\n * // Register a client\n * const client = await oidc.registerClient({\n * clientName: 'My App',\n * redirectUris: ['https://app.example.com/callback'],\n * });\n *\n * // Discovery\n * const doc = oidc.getDiscoveryDocument();\n * ```\n */\n\nimport { createHash, randomBytes } from \"node:crypto\";\nimport { eq } from \"drizzle-orm\";\nimport * as jose from \"jose\";\nimport { z } from \"zod\";\nimport type { Database } from \"../db/database.js\";\nimport { oidcAuthCodes, oidcClients, oidcRefreshTokens } from \"../db/schema.js\";\nimport type { KavachError, Result } from \"../mcp/types.js\";\n\n// ---------------------------------------------------------------------------\n// Re-export shared types\n// ---------------------------------------------------------------------------\n\nexport type { KavachError, Result };\n\n// ---------------------------------------------------------------------------\n// Public types\n// ---------------------------------------------------------------------------\n\nexport interface OidcProviderConfig {\n\t/** Issuer identifier, e.g. \"https://auth.example.com\". Must be a URL. */\n\tissuer: string;\n\t/** Private key used to sign ID tokens and access tokens (RSA or EC). */\n\tsigningKey: CryptoKey | jose.JWK;\n\t/** JWT signing algorithm. Default: 'RS256'. */\n\tsigningAlgorithm?: string;\n\t/** Access token lifetime in seconds. Default: 3600 (1 hour). */\n\taccessTokenTtl?: number;\n\t/** Refresh token lifetime in seconds. Default: 2592000 (30 days). */\n\trefreshTokenTtl?: number;\n\t/** Authorization code lifetime in seconds. Default: 600 (10 minutes). */\n\tauthCodeTtl?: number;\n\t/** ID token lifetime in seconds. Default: 3600 (1 hour). */\n\tidTokenTtl?: number;\n\t/** Scopes this provider supports. Default: ['openid', 'profile', 'email']. */\n\tsupportedScopes?: string[];\n}\n\nexport interface RegisterClientInput {\n\tclientName: string;\n\tredirectUris: string[];\n\tgrantTypes?: string[];\n\tresponseTypes?: string[];\n\tscopes?: string[];\n\ttokenEndpointAuthMethod?: string;\n}\n\nexport interface OidcClient {\n\tclientId: string;\n\tclientSecret: string | null;\n\tclientName: string;\n\tredirectUris: string[];\n\tgrantTypes: string[];\n\tresponseTypes: string[];\n\tscopes: string[];\n\ttokenEndpointAuthMethod: string;\n\tcreatedAt: Date;\n}\n\nexport interface AuthorizeParams {\n\tclientId: string;\n\tredirectUri: string;\n\tresponseType: string;\n\tscope: string;\n\tstate?: string;\n\tnonce?: string;\n\tcodeChallenge?: string;\n\tcodeChallengeMethod?: string;\n\t/** The authenticated user's ID. Must be resolved before calling authorize. */\n\tuserId: string;\n}\n\nexport interface TokenParams {\n\tgrantType: string;\n\t// authorization_code grant\n\tcode?: string;\n\tredirectUri?: string;\n\tcodeVerifier?: string;\n\t// refresh_token grant\n\trefreshToken?: string;\n\t// Client authentication\n\tclientId: string;\n\tclientSecret?: string;\n}\n\nexport interface TokenResponse {\n\taccessToken: string;\n\tidToken: string;\n\trefreshToken: string;\n\ttokenType: \"Bearer\";\n\texpiresIn: number;\n}\n\nexport interface UserInfoClaims {\n\tsub: string;\n\temail?: string;\n\tname?: string;\n\tpicture?: string;\n\temailVerified?: boolean;\n}\n\nexport interface AccessTokenClaims {\n\tsub: string;\n\tiss: string;\n\taud: string;\n\texp: number;\n\tiat: number;\n\tjti: string;\n\tscope: string;\n\tclientId: string;\n}\n\nexport interface OidcDiscoveryDocument {\n\tissuer: string;\n\tauthorization_endpoint: string;\n\ttoken_endpoint: string;\n\tuserinfo_endpoint: string;\n\tjwks_uri: string;\n\tregistration_endpoint: string;\n\tscopes_supported: string[];\n\tresponse_types_supported: string[];\n\tgrant_types_supported: string[];\n\tsubject_types_supported: string[];\n\tid_token_signing_alg_values_supported: string[];\n\ttoken_endpoint_auth_methods_supported: string[];\n\tclaims_supported: string[];\n\tcode_challenge_methods_supported: string[];\n}\n\nexport interface JsonWebKeySet {\n\tkeys: jose.JWK[];\n}\n\n/** Callback to resolve user claims for ID tokens and the userinfo endpoint. */\nexport type GetUserClaimsFn = (userId: string, scopes: string[]) => Promise<UserInfoClaims>;\n\nexport interface OidcProviderModule {\n\tregisterClient(input: RegisterClientInput): Promise<Result<OidcClient>>;\n\tgetClient(clientId: string): Promise<Result<OidcClient>>;\n\tdeleteClient(clientId: string): Promise<Result<void>>;\n\tauthorize(params: AuthorizeParams): Promise<Result<{ code: string; state?: string }>>;\n\texchangeToken(params: TokenParams): Promise<Result<TokenResponse>>;\n\tgetUserInfo(accessToken: string): Promise<Result<UserInfoClaims>>;\n\tgetDiscoveryDocument(): OidcDiscoveryDocument;\n\tgetJwks(): Promise<JsonWebKeySet>;\n\tvalidateAccessToken(token: string): Promise<Result<AccessTokenClaims>>;\n}\n\n// ---------------------------------------------------------------------------\n// Zod schemas\n// ---------------------------------------------------------------------------\n\nconst registerClientSchema = z.object({\n\tclientName: z.string().min(1, \"clientName must not be empty\"),\n\tredirectUris: z.array(z.string().url()).min(1, \"at least one redirectUri is required\"),\n\tgrantTypes: z\n\t\t.array(z.enum([\"authorization_code\", \"refresh_token\"]))\n\t\t.default([\"authorization_code\", \"refresh_token\"])\n\t\t.optional(),\n\tresponseTypes: z\n\t\t.array(z.enum([\"code\"]))\n\t\t.default([\"code\"])\n\t\t.optional(),\n\tscopes: z.array(z.string()).optional(),\n\ttokenEndpointAuthMethod: z\n\t\t.enum([\"client_secret_post\", \"client_secret_basic\"])\n\t\t.default(\"client_secret_post\")\n\t\t.optional(),\n});\n\nconst authorizeSchema = z.object({\n\tclientId: z.string().min(1),\n\tredirectUri: z.string().min(1),\n\tresponseType: z.literal(\"code\"),\n\tscope: z.string().min(1),\n\tstate: z.string().optional(),\n\tnonce: z.string().optional(),\n\tcodeChallenge: z.string().optional(),\n\tcodeChallengeMethod: z.enum([\"S256\"]).optional(),\n\tuserId: z.string().min(1),\n});\n\nconst tokenSchema = z.discriminatedUnion(\"grantType\", [\n\tz.object({\n\t\tgrantType: z.literal(\"authorization_code\"),\n\t\tcode: z.string().min(1),\n\t\tredirectUri: z.string().min(1),\n\t\tcodeVerifier: z.string().optional(),\n\t\tclientId: z.string().min(1),\n\t\tclientSecret: z.string().optional(),\n\t}),\n\tz.object({\n\t\tgrantType: z.literal(\"refresh_token\"),\n\t\trefreshToken: z.string().min(1),\n\t\tclientId: z.string().min(1),\n\t\tclientSecret: z.string().optional(),\n\t}),\n]);\n\n// ---------------------------------------------------------------------------\n// Constants\n// ---------------------------------------------------------------------------\n\nconst DEFAULT_ACCESS_TOKEN_TTL = 3600;\nconst DEFAULT_REFRESH_TOKEN_TTL = 86400 * 30;\nconst DEFAULT_AUTH_CODE_TTL = 600;\nconst DEFAULT_ID_TOKEN_TTL = 3600;\nconst DEFAULT_SIGNING_ALG = \"RS256\";\nconst DEFAULT_SCOPES = [\"openid\", \"profile\", \"email\"];\nconst CLIENT_ID_BYTE_LENGTH = 16;\nconst CLIENT_SECRET_BYTE_LENGTH = 32;\nconst AUTH_CODE_BYTE_LENGTH = 32;\nconst REFRESH_TOKEN_BYTE_LENGTH = 32;\n\n// ---------------------------------------------------------------------------\n// Internal helpers\n// ---------------------------------------------------------------------------\n\nfunction makeError(code: string, message: string, details?: Record<string, unknown>): KavachError {\n\treturn { code, message, ...(details !== undefined ? { details } : {}) };\n}\n\nfunction generateRandomHex(bytes: number): string {\n\treturn randomBytes(bytes).toString(\"hex\");\n}\n\nfunction hashSecret(raw: string): string {\n\treturn createHash(\"sha256\").update(raw).digest(\"hex\");\n}\n\nasync function computeS256Challenge(codeVerifier: string): Promise<string> {\n\tconst encoder = new TextEncoder();\n\tconst data = encoder.encode(codeVerifier);\n\tconst digest = await globalThis.crypto.subtle.digest(\"SHA-256\", data);\n\treturn jose.base64url.encode(new Uint8Array(digest));\n}\n\n// ---------------------------------------------------------------------------\n// Factory\n// ---------------------------------------------------------------------------\n\n/**\n * Create an OIDC Provider module that turns KavachOS into an identity provider.\n *\n * @param config Provider configuration (issuer, signing key, TTLs).\n * @param db Drizzle database instance.\n * @param getUserClaims Callback that resolves user claims given a userId and scopes.\n */\nexport function createOidcProviderModule(\n\tconfig: OidcProviderConfig,\n\tdb: Database,\n\tgetUserClaims: GetUserClaimsFn,\n): OidcProviderModule {\n\tconst issuer = config.issuer;\n\tconst signingAlg = config.signingAlgorithm ?? DEFAULT_SIGNING_ALG;\n\tconst accessTokenTtl = config.accessTokenTtl ?? DEFAULT_ACCESS_TOKEN_TTL;\n\tconst refreshTokenTtl = config.refreshTokenTtl ?? DEFAULT_REFRESH_TOKEN_TTL;\n\tconst authCodeTtl = config.authCodeTtl ?? DEFAULT_AUTH_CODE_TTL;\n\tconst idTokenTtl = config.idTokenTtl ?? DEFAULT_ID_TOKEN_TTL;\n\tconst supportedScopes = config.supportedScopes ?? DEFAULT_SCOPES;\n\n\t// Resolve the signing key (CryptoKey or JWK -> CryptoKey)\n\tlet signingKeyPromise: Promise<CryptoKey> | undefined;\n\tlet publicJwkPromise: Promise<jose.JWK> | undefined;\n\n\tasync function getSigningKey(): Promise<CryptoKey> {\n\t\tif (!signingKeyPromise) {\n\t\t\tsigningKeyPromise = (async () => {\n\t\t\t\tif (config.signingKey instanceof CryptoKey) {\n\t\t\t\t\treturn config.signingKey;\n\t\t\t\t}\n\t\t\t\t// It's a JWK object — asymmetric algorithms always produce CryptoKey\n\t\t\t\tconst imported = await jose.importJWK(config.signingKey as jose.JWK, signingAlg);\n\t\t\t\treturn imported as CryptoKey;\n\t\t\t})();\n\t\t}\n\t\treturn signingKeyPromise;\n\t}\n\n\tasync function getPublicJwk(): Promise<jose.JWK> {\n\t\tif (!publicJwkPromise) {\n\t\t\tpublicJwkPromise = (async () => {\n\t\t\t\tlet jwk: jose.JWK;\n\t\t\t\tif (config.signingKey instanceof CryptoKey) {\n\t\t\t\t\tjwk = await jose.exportJWK(config.signingKey);\n\t\t\t\t} else {\n\t\t\t\t\t// Input was already a JWK — use it directly without import/export round-trip\n\t\t\t\t\tjwk = { ...(config.signingKey as jose.JWK) };\n\t\t\t\t}\n\t\t\t\t// Strip private key components — only expose the public key\n\t\t\t\tconst { d, p, q, dp, dq, qi, k, ...publicComponents } = jwk;\n\t\t\t\treturn { ...publicComponents, alg: signingAlg, use: \"sig\", kid: \"kavach-oidc-1\" };\n\t\t\t})();\n\t\t}\n\t\treturn publicJwkPromise;\n\t}\n\n\t// ── registerClient ──────────────────────────────────────────────────────\n\n\tasync function registerClient(input: RegisterClientInput): Promise<Result<OidcClient>> {\n\t\tconst parsed = registerClientSchema.safeParse(input);\n\t\tif (!parsed.success) {\n\t\t\treturn {\n\t\t\t\tsuccess: false,\n\t\t\t\terror: makeError(\"INVALID_INPUT\", parsed.error.errors[0]?.message ?? \"Invalid input\", {\n\t\t\t\t\tissues: parsed.error.errors,\n\t\t\t\t}),\n\t\t\t};\n\t\t}\n\n\t\tconst {\n\t\t\tclientName,\n\t\t\tredirectUris,\n\t\t\tgrantTypes = [\"authorization_code\", \"refresh_token\"],\n\t\t\tresponseTypes = [\"code\"],\n\t\t\tscopes = supportedScopes,\n\t\t\ttokenEndpointAuthMethod = \"client_secret_post\",\n\t\t} = parsed.data;\n\n\t\tconst clientId = generateRandomHex(CLIENT_ID_BYTE_LENGTH);\n\t\tconst rawSecret = generateRandomHex(CLIENT_SECRET_BYTE_LENGTH);\n\t\tconst secretHash = hashSecret(rawSecret);\n\t\tconst now = new Date();\n\n\t\ttry {\n\t\t\tawait db.insert(oidcClients).values({\n\t\t\t\tid: crypto.randomUUID(),\n\t\t\t\tclientId,\n\t\t\t\tclientSecretHash: secretHash,\n\t\t\t\tclientName,\n\t\t\t\tredirectUris,\n\t\t\t\tgrantTypes,\n\t\t\t\tresponseTypes,\n\t\t\t\tscopes,\n\t\t\t\ttokenEndpointAuthMethod,\n\t\t\t\tcreatedAt: now,\n\t\t\t\tupdatedAt: now,\n\t\t\t});\n\n\t\t\treturn {\n\t\t\t\tsuccess: true,\n\t\t\t\tdata: {\n\t\t\t\t\tclientId,\n\t\t\t\t\tclientSecret: rawSecret,\n\t\t\t\t\tclientName,\n\t\t\t\t\tredirectUris,\n\t\t\t\t\tgrantTypes,\n\t\t\t\t\tresponseTypes,\n\t\t\t\t\tscopes,\n\t\t\t\t\ttokenEndpointAuthMethod,\n\t\t\t\t\tcreatedAt: now,\n\t\t\t\t},\n\t\t\t};\n\t\t} catch (err) {\n\t\t\treturn {\n\t\t\t\tsuccess: false,\n\t\t\t\terror: makeError(\n\t\t\t\t\t\"CLIENT_REGISTRATION_FAILED\",\n\t\t\t\t\terr instanceof Error ? err.message : \"Failed to register client\",\n\t\t\t\t),\n\t\t\t};\n\t\t}\n\t}\n\n\t// ── getClient ───────────────────────────────────────────────────────────\n\n\tasync function getClient(clientId: string): Promise<Result<OidcClient>> {\n\t\tif (!clientId || clientId.trim() === \"\") {\n\t\t\treturn { success: false, error: makeError(\"INVALID_INPUT\", \"clientId must not be empty\") };\n\t\t}\n\n\t\tconst rows = await db.select().from(oidcClients).where(eq(oidcClients.clientId, clientId));\n\n\t\tconst row = rows[0];\n\t\tif (!row) {\n\t\t\treturn { success: false, error: makeError(\"CLIENT_NOT_FOUND\", \"Client not found\") };\n\t\t}\n\n\t\treturn {\n\t\t\tsuccess: true,\n\t\t\tdata: {\n\t\t\t\tclientId: row.clientId,\n\t\t\t\tclientSecret: null, // Never return the hashed secret\n\t\t\t\tclientName: row.clientName,\n\t\t\t\tredirectUris: row.redirectUris,\n\t\t\t\tgrantTypes: row.grantTypes,\n\t\t\t\tresponseTypes: row.responseTypes,\n\t\t\t\tscopes: row.scopes,\n\t\t\t\ttokenEndpointAuthMethod: row.tokenEndpointAuthMethod,\n\t\t\t\tcreatedAt: row.createdAt,\n\t\t\t},\n\t\t};\n\t}\n\n\t// ── deleteClient ────────────────────────────────────────────────────────\n\n\tasync function deleteClient(clientId: string): Promise<Result<void>> {\n\t\tif (!clientId || clientId.trim() === \"\") {\n\t\t\treturn { success: false, error: makeError(\"INVALID_INPUT\", \"clientId must not be empty\") };\n\t\t}\n\n\t\tconst rows = await db\n\t\t\t.select({ id: oidcClients.id })\n\t\t\t.from(oidcClients)\n\t\t\t.where(eq(oidcClients.clientId, clientId));\n\n\t\tif (rows.length === 0) {\n\t\t\treturn { success: false, error: makeError(\"CLIENT_NOT_FOUND\", \"Client not found\") };\n\t\t}\n\n\t\ttry {\n\t\t\tawait db.delete(oidcClients).where(eq(oidcClients.clientId, clientId));\n\t\t\treturn { success: true, data: undefined };\n\t\t} catch (err) {\n\t\t\treturn {\n\t\t\t\tsuccess: false,\n\t\t\t\terror: makeError(\n\t\t\t\t\t\"CLIENT_DELETE_FAILED\",\n\t\t\t\t\terr instanceof Error ? err.message : \"Failed to delete client\",\n\t\t\t\t),\n\t\t\t};\n\t\t}\n\t}\n\n\t// ── authorize ───────────────────────────────────────────────────────────\n\n\tasync function authorize(\n\t\tparams: AuthorizeParams,\n\t): Promise<Result<{ code: string; state?: string }>> {\n\t\tconst parsed = authorizeSchema.safeParse(params);\n\t\tif (!parsed.success) {\n\t\t\treturn {\n\t\t\t\tsuccess: false,\n\t\t\t\terror: makeError(\"INVALID_INPUT\", parsed.error.errors[0]?.message ?? \"Invalid input\", {\n\t\t\t\t\tissues: parsed.error.errors,\n\t\t\t\t}),\n\t\t\t};\n\t\t}\n\n\t\tconst {\n\t\t\tclientId,\n\t\t\tredirectUri,\n\t\t\tscope,\n\t\t\tstate,\n\t\t\tnonce,\n\t\t\tcodeChallenge,\n\t\t\tcodeChallengeMethod,\n\t\t\tuserId,\n\t\t} = parsed.data;\n\n\t\t// Validate client exists\n\t\tconst clientRows = await db\n\t\t\t.select()\n\t\t\t.from(oidcClients)\n\t\t\t.where(eq(oidcClients.clientId, clientId));\n\n\t\tconst client = clientRows[0];\n\t\tif (!client) {\n\t\t\treturn { success: false, error: makeError(\"CLIENT_NOT_FOUND\", \"Client not found\") };\n\t\t}\n\n\t\t// Validate redirect URI\n\t\tif (!client.redirectUris.includes(redirectUri)) {\n\t\t\treturn {\n\t\t\t\tsuccess: false,\n\t\t\t\terror: makeError(\"INVALID_REDIRECT_URI\", \"redirect_uri is not registered for this client\"),\n\t\t\t};\n\t\t}\n\n\t\t// Validate requested scopes\n\t\tconst requestedScopes = scope.split(\" \").filter(Boolean);\n\t\tfor (const s of requestedScopes) {\n\t\t\tif (!supportedScopes.includes(s)) {\n\t\t\t\treturn {\n\t\t\t\t\tsuccess: false,\n\t\t\t\t\terror: makeError(\"INVALID_SCOPE\", `Scope \"${s}\" is not supported`, {\n\t\t\t\t\t\tsupported: supportedScopes,\n\t\t\t\t\t}),\n\t\t\t\t};\n\t\t\t}\n\t\t}\n\n\t\t// Generate authorization code\n\t\tconst code = generateRandomHex(AUTH_CODE_BYTE_LENGTH);\n\t\tconst codeHash = hashSecret(code);\n\t\tconst now = new Date();\n\t\tconst expiresAt = new Date(now.getTime() + authCodeTtl * 1000);\n\n\t\ttry {\n\t\t\tawait db.insert(oidcAuthCodes).values({\n\t\t\t\tid: crypto.randomUUID(),\n\t\t\t\tcodeHash,\n\t\t\t\tclientId,\n\t\t\t\tuserId,\n\t\t\t\tredirectUri,\n\t\t\t\tscopes: scope,\n\t\t\t\tnonce: nonce ?? null,\n\t\t\t\tcodeChallenge: codeChallenge ?? null,\n\t\t\t\tcodeChallengeMethod: codeChallengeMethod ?? null,\n\t\t\t\tused: false,\n\t\t\t\texpiresAt,\n\t\t\t\tcreatedAt: now,\n\t\t\t});\n\n\t\t\treturn {\n\t\t\t\tsuccess: true,\n\t\t\t\tdata: { code, ...(state !== undefined ? { state } : {}) },\n\t\t\t};\n\t\t} catch (err) {\n\t\t\treturn {\n\t\t\t\tsuccess: false,\n\t\t\t\terror: makeError(\n\t\t\t\t\t\"AUTHORIZE_FAILED\",\n\t\t\t\t\terr instanceof Error ? err.message : \"Failed to create authorization code\",\n\t\t\t\t),\n\t\t\t};\n\t\t}\n\t}\n\n\t// ── exchangeToken ───────────────────────────────────────────────────────\n\n\tasync function exchangeToken(params: TokenParams): Promise<Result<TokenResponse>> {\n\t\tconst parsed = tokenSchema.safeParse(params);\n\t\tif (!parsed.success) {\n\t\t\treturn {\n\t\t\t\tsuccess: false,\n\t\t\t\terror: makeError(\"INVALID_INPUT\", parsed.error.errors[0]?.message ?? \"Invalid input\", {\n\t\t\t\t\tissues: parsed.error.errors,\n\t\t\t\t}),\n\t\t\t};\n\t\t}\n\n\t\tconst data = parsed.data;\n\n\t\tif (data.grantType === \"authorization_code\") {\n\t\t\treturn handleAuthCodeGrant(data);\n\t\t}\n\n\t\treturn handleRefreshGrant(data);\n\t}\n\n\tasync function handleAuthCodeGrant(data: {\n\t\tgrantType: \"authorization_code\";\n\t\tcode: string;\n\t\tredirectUri: string;\n\t\tcodeVerifier?: string;\n\t\tclientId: string;\n\t\tclientSecret?: string;\n\t}): Promise<Result<TokenResponse>> {\n\t\tconst { code, redirectUri, codeVerifier, clientId, clientSecret } = data;\n\t\tconst codeHash = hashSecret(code);\n\n\t\t// Find the auth code\n\t\tconst codeRows = await db\n\t\t\t.select()\n\t\t\t.from(oidcAuthCodes)\n\t\t\t.where(eq(oidcAuthCodes.codeHash, codeHash));\n\n\t\tconst authCode = codeRows[0];\n\t\tif (!authCode) {\n\t\t\treturn { success: false, error: makeError(\"INVALID_CODE\", \"Authorization code not found\") };\n\t\t}\n\n\t\t// Check if already used\n\t\tif (authCode.used) {\n\t\t\treturn {\n\t\t\t\tsuccess: false,\n\t\t\t\terror: makeError(\"CODE_ALREADY_USED\", \"Authorization code has already been used\"),\n\t\t\t};\n\t\t}\n\n\t\t// Check expiry\n\t\tif (authCode.expiresAt <= new Date()) {\n\t\t\treturn {\n\t\t\t\tsuccess: false,\n\t\t\t\terror: makeError(\"CODE_EXPIRED\", \"Authorization code has expired\"),\n\t\t\t};\n\t\t}\n\n\t\t// Mark as used immediately to prevent replay\n\t\tawait db.update(oidcAuthCodes).set({ used: true }).where(eq(oidcAuthCodes.id, authCode.id));\n\n\t\t// Validate client\n\t\tif (authCode.clientId !== clientId) {\n\t\t\treturn {\n\t\t\t\tsuccess: false,\n\t\t\t\terror: makeError(\"CLIENT_MISMATCH\", \"client_id does not match the code\"),\n\t\t\t};\n\t\t}\n\n\t\t// Validate client secret\n\t\tconst clientResult = await authenticateClient(clientId, clientSecret);\n\t\tif (!clientResult.success) {\n\t\t\treturn clientResult;\n\t\t}\n\n\t\t// Validate redirect URI\n\t\tif (authCode.redirectUri !== redirectUri) {\n\t\t\treturn {\n\t\t\t\tsuccess: false,\n\t\t\t\terror: makeError(\"REDIRECT_URI_MISMATCH\", \"redirect_uri does not match\"),\n\t\t\t};\n\t\t}\n\n\t\t// Validate PKCE\n\t\tif (authCode.codeChallenge) {\n\t\t\tif (!codeVerifier) {\n\t\t\t\treturn {\n\t\t\t\t\tsuccess: false,\n\t\t\t\t\terror: makeError(\"PKCE_REQUIRED\", \"code_verifier is required\"),\n\t\t\t\t};\n\t\t\t}\n\t\t\tconst computedChallenge = await computeS256Challenge(codeVerifier);\n\t\t\tif (computedChallenge !== authCode.codeChallenge) {\n\t\t\t\treturn {\n\t\t\t\t\tsuccess: false,\n\t\t\t\t\terror: makeError(\"PKCE_MISMATCH\", \"code_verifier does not match code_challenge\"),\n\t\t\t\t};\n\t\t\t}\n\t\t}\n\n\t\t// Generate tokens\n\t\tconst scopes = authCode.scopes.split(\" \").filter(Boolean);\n\t\treturn generateTokenSet(authCode.userId, clientId, scopes, authCode.nonce);\n\t}\n\n\tasync function handleRefreshGrant(data: {\n\t\tgrantType: \"refresh_token\";\n\t\trefreshToken: string;\n\t\tclientId: string;\n\t\tclientSecret?: string;\n\t}): Promise<Result<TokenResponse>> {\n\t\tconst { refreshToken, clientId, clientSecret } = data;\n\t\tconst tokenHash = hashSecret(refreshToken);\n\n\t\t// Authenticate client\n\t\tconst clientResult = await authenticateClient(clientId, clientSecret);\n\t\tif (!clientResult.success) {\n\t\t\treturn clientResult;\n\t\t}\n\n\t\t// Find the refresh token\n\t\tconst rows = await db\n\t\t\t.select()\n\t\t\t.from(oidcRefreshTokens)\n\t\t\t.where(eq(oidcRefreshTokens.tokenHash, tokenHash));\n\n\t\tconst record = rows[0];\n\t\tif (!record) {\n\t\t\treturn {\n\t\t\t\tsuccess: false,\n\t\t\t\terror: makeError(\"INVALID_REFRESH_TOKEN\", \"Refresh token not found\"),\n\t\t\t};\n\t\t}\n\n\t\tif (record.clientId !== clientId) {\n\t\t\treturn {\n\t\t\t\tsuccess: false,\n\t\t\t\terror: makeError(\"CLIENT_MISMATCH\", \"client_id does not match the refresh token\"),\n\t\t\t};\n\t\t}\n\n\t\tif (record.expiresAt <= new Date()) {\n\t\t\treturn {\n\t\t\t\tsuccess: false,\n\t\t\t\terror: makeError(\"REFRESH_TOKEN_EXPIRED\", \"Refresh token has expired\"),\n\t\t\t};\n\t\t}\n\n\t\tif (record.revoked) {\n\t\t\treturn {\n\t\t\t\tsuccess: false,\n\t\t\t\terror: makeError(\"REFRESH_TOKEN_REVOKED\", \"Refresh token has been revoked\"),\n\t\t\t};\n\t\t}\n\n\t\t// Revoke old refresh token (rotation)\n\t\tawait db\n\t\t\t.update(oidcRefreshTokens)\n\t\t\t.set({ revoked: true })\n\t\t\t.where(eq(oidcRefreshTokens.id, record.id));\n\n\t\t// Issue new token set\n\t\tconst scopes = record.scopes.split(\" \").filter(Boolean);\n\t\treturn generateTokenSet(record.userId, clientId, scopes, null);\n\t}\n\n\tasync function authenticateClient(\n\t\tclientId: string,\n\t\tclientSecret?: string,\n\t): Promise<Result<{ verified: true }>> {\n\t\tconst rows = await db.select().from(oidcClients).where(eq(oidcClients.clientId, clientId));\n\n\t\tconst client = rows[0];\n\t\tif (!client) {\n\t\t\treturn { success: false, error: makeError(\"CLIENT_NOT_FOUND\", \"Client not found\") };\n\t\t}\n\n\t\tif (client.clientSecretHash) {\n\t\t\tif (!clientSecret) {\n\t\t\t\treturn {\n\t\t\t\t\tsuccess: false,\n\t\t\t\t\terror: makeError(\"CLIENT_AUTH_REQUIRED\", \"client_secret is required\"),\n\t\t\t\t};\n\t\t\t}\n\t\t\tif (hashSecret(clientSecret) !== client.clientSecretHash) {\n\t\t\t\treturn {\n\t\t\t\t\tsuccess: false,\n\t\t\t\t\terror: makeError(\"INVALID_CLIENT_SECRET\", \"Invalid client credentials\"),\n\t\t\t\t};\n\t\t\t}\n\t\t}\n\n\t\treturn { success: true, data: { verified: true } };\n\t}\n\n\tasync function generateTokenSet(\n\t\tuserId: string,\n\t\tclientId: string,\n\t\tscopes: string[],\n\t\tnonce: string | null,\n\t): Promise<Result<TokenResponse>> {\n\t\tconst key = await getSigningKey();\n\t\tconst now = Math.floor(Date.now() / 1000);\n\t\tconst jti = crypto.randomUUID();\n\n\t\t// Access token (JWT)\n\t\tconst accessTokenBuilder = new jose.SignJWT({\n\t\t\tscope: scopes.join(\" \"),\n\t\t\tclient_id: clientId,\n\t\t})\n\t\t\t.setProtectedHeader({ alg: signingAlg, kid: \"kavach-oidc-1\" })\n\t\t\t.setIssuer(issuer)\n\t\t\t.setSubject(userId)\n\t\t\t.setAudience(clientId)\n\t\t\t.setIssuedAt(now)\n\t\t\t.setExpirationTime(now + accessTokenTtl)\n\t\t\t.setJti(jti);\n\n\t\tconst accessToken = await accessTokenBuilder.sign(key);\n\n\t\t// ID token (JWT)\n\t\tconst userClaims = await getUserClaims(userId, scopes);\n\t\tconst idTokenPayload: Record<string, unknown> = {\n\t\t\t...userClaims,\n\t\t\tazp: clientId,\n\t\t};\n\t\tif (nonce) {\n\t\t\tidTokenPayload.nonce = nonce;\n\t\t}\n\t\t// Add at_hash (access token hash)\n\t\tconst atHashBuffer = createHash(\"sha256\").update(accessToken).digest();\n\t\tconst atHashHalf = atHashBuffer.subarray(0, atHashBuffer.length / 2);\n\t\tidTokenPayload.at_hash = jose.base64url.encode(atHashHalf);\n\n\t\tconst idToken = await new jose.SignJWT(idTokenPayload)\n\t\t\t.setProtectedHeader({ alg: signingAlg, kid: \"kavach-oidc-1\" })\n\t\t\t.setIssuer(issuer)\n\t\t\t.setSubject(userId)\n\t\t\t.setAudience(clientId)\n\t\t\t.setIssuedAt(now)\n\t\t\t.setExpirationTime(now + idTokenTtl)\n\t\t\t.sign(key);\n\n\t\t// Refresh token (opaque)\n\t\tconst rawRefreshToken = generateRandomHex(REFRESH_TOKEN_BYTE_LENGTH);\n\t\tconst refreshTokenHash = hashSecret(rawRefreshToken);\n\t\tconst refreshExpiresAt = new Date((now + refreshTokenTtl) * 1000);\n\n\t\ttry {\n\t\t\tawait db.insert(oidcRefreshTokens).values({\n\t\t\t\tid: crypto.randomUUID(),\n\t\t\t\ttokenHash: refreshTokenHash,\n\t\t\t\tclientId,\n\t\t\t\tuserId,\n\t\t\t\tscopes: scopes.join(\" \"),\n\t\t\t\trevoked: false,\n\t\t\t\texpiresAt: refreshExpiresAt,\n\t\t\t\tcreatedAt: new Date(),\n\t\t\t});\n\t\t} catch (err) {\n\t\t\treturn {\n\t\t\t\tsuccess: false,\n\t\t\t\terror: makeError(\n\t\t\t\t\t\"TOKEN_GENERATION_FAILED\",\n\t\t\t\t\terr instanceof Error ? err.message : \"Failed to store refresh token\",\n\t\t\t\t),\n\t\t\t};\n\t\t}\n\n\t\treturn {\n\t\t\tsuccess: true,\n\t\t\tdata: {\n\t\t\t\taccessToken,\n\t\t\t\tidToken,\n\t\t\t\trefreshToken: rawRefreshToken,\n\t\t\t\ttokenType: \"Bearer\",\n\t\t\t\texpiresIn: accessTokenTtl,\n\t\t\t},\n\t\t};\n\t}\n\n\t// ── getUserInfo ─────────────────────────────────────────────────────────\n\n\tasync function getUserInfo(accessToken: string): Promise<Result<UserInfoClaims>> {\n\t\tconst validation = await validateAccessToken(accessToken);\n\t\tif (!validation.success) {\n\t\t\treturn validation;\n\t\t}\n\n\t\tconst { sub, scope } = validation.data;\n\t\tconst scopes = scope.split(\" \").filter(Boolean);\n\n\t\ttry {\n\t\t\tconst claims = await getUserClaims(sub, scopes);\n\t\t\treturn { success: true, data: claims };\n\t\t} catch (err) {\n\t\t\treturn {\n\t\t\t\tsuccess: false,\n\t\t\t\terror: makeError(\n\t\t\t\t\t\"USERINFO_FAILED\",\n\t\t\t\t\terr instanceof Error ? err.message : \"Failed to retrieve user info\",\n\t\t\t\t),\n\t\t\t};\n\t\t}\n\t}\n\n\t// ── getDiscoveryDocument ────────────────────────────────────────────────\n\n\tfunction getDiscoveryDocument(): OidcDiscoveryDocument {\n\t\treturn {\n\t\t\tissuer,\n\t\t\tauthorization_endpoint: `${issuer}/authorize`,\n\t\t\ttoken_endpoint: `${issuer}/token`,\n\t\t\tuserinfo_endpoint: `${issuer}/userinfo`,\n\t\t\tjwks_uri: `${issuer}/.well-known/jwks.json`,\n\t\t\tregistration_endpoint: `${issuer}/register`,\n\t\t\tscopes_supported: supportedScopes,\n\t\t\tresponse_types_supported: [\"code\"],\n\t\t\tgrant_types_supported: [\"authorization_code\", \"refresh_token\"],\n\t\t\tsubject_types_supported: [\"public\"],\n\t\t\tid_token_signing_alg_values_supported: [signingAlg],\n\t\t\ttoken_endpoint_auth_methods_supported: [\"client_secret_post\", \"client_secret_basic\"],\n\t\t\tclaims_supported: [\n\t\t\t\t\"sub\",\n\t\t\t\t\"iss\",\n\t\t\t\t\"aud\",\n\t\t\t\t\"exp\",\n\t\t\t\t\"iat\",\n\t\t\t\t\"nonce\",\n\t\t\t\t\"email\",\n\t\t\t\t\"name\",\n\t\t\t\t\"picture\",\n\t\t\t\t\"email_verified\",\n\t\t\t],\n\t\t\tcode_challenge_methods_supported: [\"S256\"],\n\t\t};\n\t}\n\n\t// ── getJwks ─────────────────────────────────────────────────────────────\n\n\tasync function getJwks(): Promise<JsonWebKeySet> {\n\t\tconst publicJwk = await getPublicJwk();\n\t\treturn { keys: [publicJwk] };\n\t}\n\n\t// ── validateAccessToken ─────────────────────────────────────────────────\n\n\tasync function validateAccessToken(token: string): Promise<Result<AccessTokenClaims>> {\n\t\tif (!token || token.trim() === \"\") {\n\t\t\treturn { success: false, error: makeError(\"INVALID_INPUT\", \"token must not be empty\") };\n\t\t}\n\n\t\ttry {\n\t\t\tconst publicJwk = await getPublicJwk();\n\t\t\tconst key = await jose.importJWK(publicJwk, signingAlg);\n\t\t\tconst { payload } = await jose.jwtVerify(token, key, {\n\t\t\t\tissuer,\n\t\t\t});\n\n\t\t\treturn {\n\t\t\t\tsuccess: true,\n\t\t\t\tdata: {\n\t\t\t\t\tsub: payload.sub as string,\n\t\t\t\t\tiss: payload.iss as string,\n\t\t\t\t\taud: payload.aud as string,\n\t\t\t\t\texp: payload.exp as number,\n\t\t\t\t\tiat: payload.iat as number,\n\t\t\t\t\tjti: payload.jti as string,\n\t\t\t\t\tscope: (payload as Record<string, unknown>).scope as string,\n\t\t\t\t\tclientId: (payload as Record<string, unknown>).client_id as string,\n\t\t\t\t},\n\t\t\t};\n\t\t} catch (err) {\n\t\t\tif (err instanceof jose.errors.JWTExpired) {\n\t\t\t\treturn { success: false, error: makeError(\"TOKEN_EXPIRED\", \"Access token has expired\") };\n\t\t\t}\n\t\t\treturn {\n\t\t\t\tsuccess: false,\n\t\t\t\terror: makeError(\n\t\t\t\t\t\"TOKEN_VALIDATION_FAILED\",\n\t\t\t\t\terr instanceof Error ? err.message : \"Failed to validate access token\",\n\t\t\t\t),\n\t\t\t};\n\t\t}\n\t}\n\n\treturn {\n\t\tregisterClient,\n\t\tgetClient,\n\t\tdeleteClient,\n\t\tauthorize,\n\t\texchangeToken,\n\t\tgetUserInfo,\n\t\tgetDiscoveryDocument,\n\t\tgetJwks,\n\t\tvalidateAccessToken,\n\t};\n}\n","/**\n * Google One Tap authentication for KavachOS.\n *\n * Verifies a Google ID token (issued by the Google Identity Services JS\n * library) server-side via Google's public JWKS endpoint. No Google SDK\n * required. Uses `jose` for JWT verification — the same library used\n * elsewhere in KavachOS.\n *\n * Flow:\n * 1. Front-end includes the Google Identity Services script and mounts the\n * One Tap prompt.\n * 2. On sign-in the browser POSTs the `credential` (ID token) to\n * POST /auth/one-tap/callback.\n * 3. This module verifies the token, finds or creates the user, and returns\n * a session.\n *\n * CSRF: Google's JS library sets a `g_csrf_token` cookie and includes the\n * same value in the POST body. Both must match.\n *\n * @example\n * ```typescript\n * const kavach = await createKavach({\n * database: { provider: 'sqlite', url: 'kavach.db' },\n * auth: { session: { secret: process.env.SESSION_SECRET } },\n * });\n *\n * // Use via plugin\n * import { oneTap } from 'kavachos/auth';\n * // plugins: [oneTap({ clientId: process.env.GOOGLE_CLIENT_ID })]\n *\n * // Or use the module directly\n * const tap = createOneTapModule({ clientId: '...' }, db, sessionManager);\n * const googleUser = await tap.verify(idToken);\n * ```\n */\n\nimport { randomUUID } from \"node:crypto\";\nimport { eq } from \"drizzle-orm\";\nimport { createRemoteJWKSet, jwtVerify } from \"jose\";\nimport type { Database } from \"../db/database.js\";\nimport { users } from \"../db/schema.js\";\nimport type { SessionManager } from \"../session/session.js\";\n\n// ---------------------------------------------------------------------------\n// Constants\n// ---------------------------------------------------------------------------\n\nconst GOOGLE_JWKS_URL = \"https://www.googleapis.com/oauth2/v3/certs\";\nconst GOOGLE_ISSUERS = [\"https://accounts.google.com\", \"accounts.google.com\"] as const;\nconst DEFAULT_CSRF_COOKIE_NAME = \"g_csrf_token\";\n\n// Lazily created — jose caches JWKS internally after first fetch.\nlet cachedJwks: ReturnType<typeof createRemoteJWKSet> | null = null;\n\nfunction getJwks(): ReturnType<typeof createRemoteJWKSet> {\n\tif (!cachedJwks) {\n\t\tcachedJwks = createRemoteJWKSet(new URL(GOOGLE_JWKS_URL));\n\t}\n\treturn cachedJwks;\n}\n\n// ---------------------------------------------------------------------------\n// Public types\n// ---------------------------------------------------------------------------\n\nexport interface OneTapConfig {\n\t/** Google OAuth client ID */\n\tclientId: string;\n\t/** Auto-create user if not found (default: true) */\n\tautoCreateUser?: boolean;\n\t/** CSRF token cookie name (default: \"g_csrf_token\") */\n\tcsrfCookieName?: string;\n}\n\nexport interface GoogleUser {\n\t/** Google user ID (stable, use this as the external ID) */\n\tsub: string;\n\temail: string;\n\temailVerified: boolean;\n\tname: string;\n\tgivenName?: string;\n\tfamilyName?: string;\n\tpicture?: string;\n}\n\nexport interface OneTapModule {\n\t/**\n\t * Verify a Google ID token and return the decoded user claims.\n\t * Throws if the token is invalid, expired, or issued for the wrong audience.\n\t */\n\tverify(idToken: string): Promise<GoogleUser>;\n\t/**\n\t * Handle the POST callback from Google's JS library.\n\t *\n\t * Expects `application/x-www-form-urlencoded` with `credential` and\n\t * `g_csrf_token` fields (plus the matching CSRF cookie). Returns a JSON\n\t * response with `{ user, session }` on success or null when the path does\n\t * not match (allowing fall-through to other handlers).\n\t */\n\thandleRequest(request: Request): Promise<Response | null>;\n}\n\n// ---------------------------------------------------------------------------\n// Errors\n// ---------------------------------------------------------------------------\n\nexport class OneTapVerifyError extends Error {\n\tconstructor(\n\t\tmessage: string,\n\t\tpublic readonly code: string,\n\t) {\n\t\tsuper(message);\n\t\tthis.name = \"OneTapVerifyError\";\n\t}\n}\n\n// ---------------------------------------------------------------------------\n// Google JWT payload shape\n// ---------------------------------------------------------------------------\n\ninterface GoogleIdTokenPayload {\n\tsub: string;\n\temail: string;\n\temail_verified?: boolean;\n\tname?: string;\n\tgiven_name?: string;\n\tfamily_name?: string;\n\tpicture?: string;\n\tiss: string;\n\taud: string;\n\texp: number;\n\tiat: number;\n}\n\n// ---------------------------------------------------------------------------\n// Factory\n// ---------------------------------------------------------------------------\n\nexport function createOneTapModule(\n\tconfig: OneTapConfig,\n\tdb: Database,\n\tsessionManager: SessionManager,\n): OneTapModule {\n\tconst autoCreateUser = config.autoCreateUser ?? true;\n\tconst csrfCookieName = config.csrfCookieName ?? DEFAULT_CSRF_COOKIE_NAME;\n\tconst callbackPath = \"/auth/one-tap/callback\";\n\n\t// ── verify ────────────────────────────────────────────────────────────\n\n\tasync function verify(idToken: string): Promise<GoogleUser> {\n\t\tlet payload: GoogleIdTokenPayload;\n\n\t\ttry {\n\t\t\tconst jwks = getJwks();\n\t\t\tconst { payload: raw } = await jwtVerify(idToken, jwks, {\n\t\t\t\tissuer: [...GOOGLE_ISSUERS],\n\t\t\t\taudience: config.clientId,\n\t\t\t});\n\t\t\tpayload = raw as unknown as GoogleIdTokenPayload;\n\t\t} catch (err) {\n\t\t\tconst message = err instanceof Error ? err.message : \"JWT verification failed\";\n\t\t\tthrow new OneTapVerifyError(\n\t\t\t\t`Google ID token verification failed: ${message}`,\n\t\t\t\t\"INVALID_TOKEN\",\n\t\t\t);\n\t\t}\n\n\t\tif (!payload.email) {\n\t\t\tthrow new OneTapVerifyError(\"Google ID token is missing email claim\", \"MISSING_EMAIL\");\n\t\t}\n\n\t\tif (!payload.sub) {\n\t\t\tthrow new OneTapVerifyError(\"Google ID token is missing sub claim\", \"MISSING_SUB\");\n\t\t}\n\n\t\treturn {\n\t\t\tsub: payload.sub,\n\t\t\temail: payload.email,\n\t\t\temailVerified: payload.email_verified === true,\n\t\t\tname: payload.name ?? payload.email,\n\t\t\tgivenName: payload.given_name,\n\t\t\tfamilyName: payload.family_name,\n\t\t\tpicture: payload.picture,\n\t\t};\n\t}\n\n\t// ── findOrCreate user ─────────────────────────────────────────────────\n\n\tasync function findOrCreateUser(googleUser: GoogleUser): Promise<{ id: string; email: string }> {\n\t\t// Look up by email first.\n\t\tconst existing = await db\n\t\t\t.select({ id: users.id, email: users.email })\n\t\t\t.from(users)\n\t\t\t.where(eq(users.email, googleUser.email));\n\n\t\tif (existing[0]) {\n\t\t\treturn { id: existing[0].id, email: existing[0].email };\n\t\t}\n\n\t\tif (!autoCreateUser) {\n\t\t\tthrow new OneTapVerifyError(`No account found for ${googleUser.email}`, \"USER_NOT_FOUND\");\n\t\t}\n\n\t\tconst id = randomUUID();\n\t\tconst now = new Date();\n\n\t\tawait db.insert(users).values({\n\t\t\tid,\n\t\t\temail: googleUser.email,\n\t\t\tname: googleUser.name,\n\t\t\texternalId: googleUser.sub,\n\t\t\texternalProvider: \"google\",\n\t\t\tcreatedAt: now,\n\t\t\tupdatedAt: now,\n\t\t});\n\n\t\treturn { id, email: googleUser.email };\n\t}\n\n\t// ── CSRF helpers ──────────────────────────────────────────────────────\n\n\tfunction getCsrfCookie(request: Request): string | null {\n\t\tconst cookieHeader = request.headers.get(\"cookie\") ?? \"\";\n\t\tfor (const part of cookieHeader.split(\";\")) {\n\t\t\tconst trimmed = part.trim();\n\t\t\tconst eqIdx = trimmed.indexOf(\"=\");\n\t\t\tif (eqIdx === -1) continue;\n\t\t\tconst name = trimmed.slice(0, eqIdx).trim();\n\t\t\tif (name === csrfCookieName) {\n\t\t\t\treturn trimmed.slice(eqIdx + 1).trim();\n\t\t\t}\n\t\t}\n\t\treturn null;\n\t}\n\n\t// ── handleRequest ─────────────────────────────────────────────────────\n\n\tasync function handleRequest(request: Request): Promise<Response | null> {\n\t\tconst url = new URL(request.url);\n\n\t\tif (request.method !== \"POST\" || url.pathname !== callbackPath) {\n\t\t\treturn null;\n\t\t}\n\n\t\t// Parse form body (Google JS library sends application/x-www-form-urlencoded).\n\t\tlet formData: URLSearchParams;\n\t\ttry {\n\t\t\tconst text = await request.text();\n\t\t\tformData = new URLSearchParams(text);\n\t\t} catch {\n\t\t\treturn jsonResponse({ error: \"Failed to parse request body\" }, 400);\n\t\t}\n\n\t\tconst credential = formData.get(\"credential\");\n\t\tconst bodyToken = formData.get(csrfCookieName);\n\n\t\tif (!credential) {\n\t\t\treturn jsonResponse({ error: \"Missing credential field\" }, 400);\n\t\t}\n\n\t\t// CSRF check: cookie and body field must both exist and match.\n\t\tconst cookieToken = getCsrfCookie(request);\n\t\tif (!cookieToken || !bodyToken || cookieToken !== bodyToken) {\n\t\t\treturn jsonResponse({ error: \"CSRF token mismatch\" }, 403);\n\t\t}\n\n\t\tlet googleUser: GoogleUser;\n\t\ttry {\n\t\t\tgoogleUser = await verify(credential);\n\t\t} catch (err) {\n\t\t\tif (err instanceof OneTapVerifyError && err.code === \"USER_NOT_FOUND\") {\n\t\t\t\treturn jsonResponse({ error: err.message }, 403);\n\t\t\t}\n\t\t\treturn jsonResponse(\n\t\t\t\t{ error: err instanceof Error ? err.message : \"Token verification failed\" },\n\t\t\t\t401,\n\t\t\t);\n\t\t}\n\n\t\tlet user: { id: string; email: string };\n\t\ttry {\n\t\t\tuser = await findOrCreateUser(googleUser);\n\t\t} catch (err) {\n\t\t\tif (err instanceof OneTapVerifyError && err.code === \"USER_NOT_FOUND\") {\n\t\t\t\treturn jsonResponse({ error: err.message }, 403);\n\t\t\t}\n\t\t\treturn jsonResponse(\n\t\t\t\t{ error: err instanceof Error ? err.message : \"Failed to resolve user\" },\n\t\t\t\t500,\n\t\t\t);\n\t\t}\n\n\t\tconst { token: sessionToken, session } = await sessionManager.create(user.id);\n\n\t\treturn jsonResponse({\n\t\t\tuser: { id: user.id, email: user.email },\n\t\t\tsession: { token: sessionToken, expiresAt: session.expiresAt },\n\t\t});\n\t}\n\n\treturn { verify, handleRequest };\n}\n\n// ---------------------------------------------------------------------------\n// Helpers\n// ---------------------------------------------------------------------------\n\nfunction jsonResponse(body: unknown, status = 200): Response {\n\treturn new Response(JSON.stringify(body), {\n\t\tstatus,\n\t\theaders: { \"Content-Type\": \"application/json\" },\n\t});\n}\n","import type { KavachPlugin } from \"../plugin/types.js\";\nimport { createSessionManager } from \"../session/session.js\";\nimport type { OneTapConfig } from \"./one-tap.js\";\nimport { createOneTapModule } from \"./one-tap.js\";\n\nexport type { OneTapConfig };\n\n// ---------------------------------------------------------------------------\n// Plugin factory\n// ---------------------------------------------------------------------------\n\nexport function oneTap(config: OneTapConfig): KavachPlugin {\n\treturn {\n\t\tid: \"kavach-one-tap\",\n\n\t\tasync init(ctx): Promise<undefined> {\n\t\t\tconst sessionConfig = ctx.config.auth?.session;\n\t\t\tif (!sessionConfig) {\n\t\t\t\tthrow new Error(\n\t\t\t\t\t\"kavach-one-tap plugin requires auth.session to be configured so that sessions can be issued on successful sign-in.\",\n\t\t\t\t);\n\t\t\t}\n\n\t\t\tconst sessionManager = createSessionManager(sessionConfig, ctx.db);\n\t\t\tconst module = createOneTapModule(config, ctx.db, sessionManager);\n\n\t\t\t// POST /auth/one-tap/callback\n\t\t\t// Accepts application/x-www-form-urlencoded from Google's JS library.\n\t\t\t// Fields: credential (ID token) + g_csrf_token (must match cookie).\n\t\t\tctx.addEndpoint({\n\t\t\t\tmethod: \"POST\",\n\t\t\t\tpath: \"/auth/one-tap/callback\",\n\t\t\t\tmetadata: {\n\t\t\t\t\trateLimit: { window: 60, max: 20 },\n\t\t\t\t\tdescription: \"Verify a Google One Tap ID token and return a session\",\n\t\t\t\t},\n\t\t\t\tasync handler(request) {\n\t\t\t\t\tconst response = await module.handleRequest(request);\n\t\t\t\t\t// handleRequest returns null only when path does not match.\n\t\t\t\t\t// Since this handler is only called for the exact path, null\n\t\t\t\t\t// means something unexpected happened — return a generic error.\n\t\t\t\t\tif (!response) {\n\t\t\t\t\t\treturn new Response(JSON.stringify({ error: \"Unexpected routing error\" }), {\n\t\t\t\t\t\t\tstatus: 500,\n\t\t\t\t\t\t\theaders: { \"Content-Type\": \"application/json\" },\n\t\t\t\t\t\t});\n\t\t\t\t\t}\n\t\t\t\t\treturn response;\n\t\t\t\t},\n\t\t\t});\n\t\t},\n\t};\n}\n","/**\n * One-time token module for KavachOS.\n *\n * Issues single-use tokens for email verification, password resets,\n * invitations, and custom flows. The raw token is returned to the caller\n * once and never persisted — only a SHA-256 hash is stored. Tokens are\n * invalidated on first use or when they expire.\n *\n * @example\n * ```typescript\n * const tokens = createOneTimeTokenModule({}, db);\n *\n * // Create a password-reset token\n * const result = await tokens.createToken({\n * purpose: 'password-reset',\n * identifier: 'alice@example.com',\n * ttlSeconds: 1800,\n * });\n * if (result.success) {\n * await mailer.send({ to: 'alice@example.com', token: result.data.token });\n * }\n *\n * // Validate (and consume) on the reset page\n * const validation = await tokens.validateToken(incomingToken, 'password-reset');\n * if (validation.success) {\n * // validation.data.identifier === 'alice@example.com'\n * }\n * ```\n */\n\nimport { createHash, randomBytes } from \"node:crypto\";\nimport { and, eq, gt } from \"drizzle-orm\";\nimport { z } from \"zod\";\nimport type { Database } from \"../db/database.js\";\nimport { oneTimeTokens } from \"../db/schema.js\";\nimport type { KavachError, Result } from \"../mcp/types.js\";\n\n// ---------------------------------------------------------------------------\n// Re-export shared types for callers that import from this module\n// ---------------------------------------------------------------------------\n\nexport type { KavachError, Result };\n\n// ---------------------------------------------------------------------------\n// Public types\n// ---------------------------------------------------------------------------\n\n/** Token purpose discriminator. Use 'custom' for any application-specific flow. */\nexport type OneTimeTokenPurpose = \"email-verify\" | \"password-reset\" | \"invitation\" | \"custom\";\n\nexport interface OneTimeTokenConfig {\n\t/** Default TTL in seconds when none is specified per-call. Default: 3600 (1 hour). */\n\tdefaultTtlSeconds?: number;\n}\n\nexport interface CreateTokenInput {\n\tpurpose: OneTimeTokenPurpose;\n\t/** Email address, user ID, or any caller-supplied key that scopes the token. */\n\tidentifier: string;\n\t/** Arbitrary data to associate with the token (e.g. org ID, invited role). */\n\tmetadata?: Record<string, unknown>;\n\t/** Override the module-level default TTL for this token only. */\n\tttlSeconds?: number;\n}\n\nexport interface ValidateTokenResult {\n\tidentifier: string;\n\tmetadata?: Record<string, unknown>;\n}\n\nexport interface RevokeTokensResult {\n\tcount: number;\n}\n\nexport interface OneTimeTokenModule {\n\t/**\n\t * Create a new one-time token.\n\t *\n\t * Returns the raw token (hex string) exactly once. Store it in your email\n\t * or link — it cannot be recovered from the database afterwards.\n\t */\n\tcreateToken(input: CreateTokenInput): Promise<Result<{ token: string; expiresAt: Date }>>;\n\n\t/**\n\t * Validate a token and mark it as used.\n\t *\n\t * Fails when the token is unknown, already used, expired, or belongs to a\n\t * different purpose. On success the token is consumed immediately.\n\t */\n\tvalidateToken(token: string, purpose: string): Promise<Result<ValidateTokenResult>>;\n\n\t/**\n\t * Revoke all active tokens for an identifier, optionally scoped to a purpose.\n\t *\n\t * Useful for invalidating outstanding password-reset links when a user\n\t * changes their password through another flow, or for cleaning up on account\n\t * deletion.\n\t */\n\trevokeTokens(identifier: string, purpose?: string): Promise<Result<RevokeTokensResult>>;\n}\n\n// ---------------------------------------------------------------------------\n// Zod validation schemas\n// ---------------------------------------------------------------------------\n\nconst PURPOSE_VALUES = [\"email-verify\", \"password-reset\", \"invitation\", \"custom\"] as const;\n\nconst createTokenInputSchema = z.object({\n\tpurpose: z.enum(PURPOSE_VALUES),\n\tidentifier: z.string().min(1, \"identifier must not be empty\"),\n\tmetadata: z.record(z.unknown()).optional(),\n\tttlSeconds: z.number().int().positive().optional(),\n});\n\n// ---------------------------------------------------------------------------\n// Constants\n// ---------------------------------------------------------------------------\n\nconst DEFAULT_TTL_SECONDS = 3600; // 1 hour\nconst TOKEN_BYTE_LENGTH = 32; // 256-bit token — 64 hex chars when encoded\n\n// ---------------------------------------------------------------------------\n// Internal helpers\n// ---------------------------------------------------------------------------\n\nfunction hashToken(raw: string): string {\n\treturn createHash(\"sha256\").update(raw).digest(\"hex\");\n}\n\nfunction generateRawToken(): string {\n\treturn randomBytes(TOKEN_BYTE_LENGTH).toString(\"hex\");\n}\n\nfunction makeError(code: string, message: string, details?: Record<string, unknown>): KavachError {\n\treturn { code, message, ...(details !== undefined ? { details } : {}) };\n}\n\n// ---------------------------------------------------------------------------\n// Factory\n// ---------------------------------------------------------------------------\n\n/**\n * Create a one-time token module backed by the provided database.\n *\n * The module is stateless — no in-memory caches — so multiple instances\n * sharing the same database are safe.\n */\nexport function createOneTimeTokenModule(\n\tconfig: OneTimeTokenConfig,\n\tdb: Database,\n): OneTimeTokenModule {\n\tconst defaultTtl = config.defaultTtlSeconds ?? DEFAULT_TTL_SECONDS;\n\n\t// ── createToken ──────────────────────────────────────────────────────────\n\n\tasync function createToken(\n\t\tinput: CreateTokenInput,\n\t): Promise<Result<{ token: string; expiresAt: Date }>> {\n\t\tconst parsed = createTokenInputSchema.safeParse(input);\n\t\tif (!parsed.success) {\n\t\t\treturn {\n\t\t\t\tsuccess: false,\n\t\t\t\terror: makeError(\"INVALID_INPUT\", parsed.error.errors[0]?.message ?? \"Invalid input\", {\n\t\t\t\t\tissues: parsed.error.errors,\n\t\t\t\t}),\n\t\t\t};\n\t\t}\n\n\t\tconst { purpose, identifier, metadata, ttlSeconds } = parsed.data;\n\t\tconst raw = generateRawToken();\n\t\tconst tokenHash = hashToken(raw);\n\t\tconst now = new Date();\n\t\tconst expiresAt = new Date(now.getTime() + (ttlSeconds ?? defaultTtl) * 1000);\n\n\t\ttry {\n\t\t\tawait db.insert(oneTimeTokens).values({\n\t\t\t\tid: crypto.randomUUID(),\n\t\t\t\ttokenHash,\n\t\t\t\tpurpose,\n\t\t\t\tidentifier,\n\t\t\t\tmetadata: metadata ?? null,\n\t\t\t\tused: false,\n\t\t\t\texpiresAt,\n\t\t\t\tcreatedAt: now,\n\t\t\t});\n\n\t\t\treturn { success: true, data: { token: raw, expiresAt } };\n\t\t} catch (err) {\n\t\t\treturn {\n\t\t\t\tsuccess: false,\n\t\t\t\terror: makeError(\n\t\t\t\t\t\"CREATE_TOKEN_FAILED\",\n\t\t\t\t\terr instanceof Error ? err.message : \"Failed to create token\",\n\t\t\t\t),\n\t\t\t};\n\t\t}\n\t}\n\n\t// ── validateToken ────────────────────────────────────────────────────────\n\n\tasync function validateToken(\n\t\ttoken: string,\n\t\tpurpose: string,\n\t): Promise<Result<ValidateTokenResult>> {\n\t\tif (typeof token !== \"string\" || token.trim() === \"\") {\n\t\t\treturn { success: false, error: makeError(\"INVALID_INPUT\", \"token must not be empty\") };\n\t\t}\n\t\tif (typeof purpose !== \"string\" || purpose.trim() === \"\") {\n\t\t\treturn { success: false, error: makeError(\"INVALID_INPUT\", \"purpose must not be empty\") };\n\t\t}\n\n\t\tconst tokenHash = hashToken(token);\n\t\tconst now = new Date();\n\n\t\tconst rows = await db\n\t\t\t.select()\n\t\t\t.from(oneTimeTokens)\n\t\t\t.where(eq(oneTimeTokens.tokenHash, tokenHash));\n\n\t\tconst record = rows[0];\n\n\t\tif (!record) {\n\t\t\treturn { success: false, error: makeError(\"TOKEN_NOT_FOUND\", \"Token not found\") };\n\t\t}\n\n\t\tif (record.used) {\n\t\t\treturn {\n\t\t\t\tsuccess: false,\n\t\t\t\terror: makeError(\"TOKEN_ALREADY_USED\", \"Token has already been used\"),\n\t\t\t};\n\t\t}\n\n\t\tif (record.expiresAt <= now) {\n\t\t\treturn { success: false, error: makeError(\"TOKEN_EXPIRED\", \"Token has expired\") };\n\t\t}\n\n\t\tif (record.purpose !== purpose) {\n\t\t\treturn {\n\t\t\t\tsuccess: false,\n\t\t\t\terror: makeError(\"TOKEN_PURPOSE_MISMATCH\", \"Token purpose does not match\", {\n\t\t\t\t\texpected: purpose,\n\t\t\t\t\tactual: record.purpose,\n\t\t\t\t}),\n\t\t\t};\n\t\t}\n\n\t\t// Mark used before returning to guarantee exactly-once semantics even\n\t\t// under concurrent requests — the unique index on token_hash ensures\n\t\t// any race will fail at the DB level on a duplicate mark.\n\t\ttry {\n\t\t\tawait db\n\t\t\t\t.update(oneTimeTokens)\n\t\t\t\t.set({ used: true })\n\t\t\t\t.where(and(eq(oneTimeTokens.id, record.id), eq(oneTimeTokens.used, false)));\n\t\t} catch (err) {\n\t\t\treturn {\n\t\t\t\tsuccess: false,\n\t\t\t\terror: makeError(\n\t\t\t\t\t\"CONSUME_TOKEN_FAILED\",\n\t\t\t\t\terr instanceof Error ? err.message : \"Failed to consume token\",\n\t\t\t\t),\n\t\t\t};\n\t\t}\n\n\t\treturn {\n\t\t\tsuccess: true,\n\t\t\tdata: {\n\t\t\t\tidentifier: record.identifier,\n\t\t\t\t...(record.metadata !== null && record.metadata !== undefined\n\t\t\t\t\t? { metadata: record.metadata }\n\t\t\t\t\t: {}),\n\t\t\t},\n\t\t};\n\t}\n\n\t// ── revokeTokens ─────────────────────────────────────────────────────────\n\n\tasync function revokeTokens(\n\t\tidentifier: string,\n\t\tpurpose?: string,\n\t): Promise<Result<RevokeTokensResult>> {\n\t\tif (typeof identifier !== \"string\" || identifier.trim() === \"\") {\n\t\t\treturn { success: false, error: makeError(\"INVALID_INPUT\", \"identifier must not be empty\") };\n\t\t}\n\n\t\t// Validate purpose when supplied so we never issue a WHERE with a value\n\t\t// that will never match a typed enum column.\n\t\tlet typedPurpose: OneTimeTokenPurpose | undefined;\n\t\tif (purpose !== undefined) {\n\t\t\tconst parsed = z.enum(PURPOSE_VALUES).safeParse(purpose);\n\t\t\tif (!parsed.success) {\n\t\t\t\treturn {\n\t\t\t\t\tsuccess: false,\n\t\t\t\t\terror: makeError(\"INVALID_INPUT\", `Unknown purpose: ${purpose}`),\n\t\t\t\t};\n\t\t\t}\n\t\t\ttypedPurpose = parsed.data;\n\t\t}\n\n\t\ttry {\n\t\t\t// Count active (not yet used, not yet expired) matching tokens before\n\t\t\t// updating so we can return an accurate count.\n\t\t\tconst now = new Date();\n\n\t\t\tconst whereClause =\n\t\t\t\ttypedPurpose !== undefined\n\t\t\t\t\t? and(\n\t\t\t\t\t\t\teq(oneTimeTokens.identifier, identifier),\n\t\t\t\t\t\t\teq(oneTimeTokens.purpose, typedPurpose),\n\t\t\t\t\t\t\teq(oneTimeTokens.used, false),\n\t\t\t\t\t\t\tgt(oneTimeTokens.expiresAt, now),\n\t\t\t\t\t\t)\n\t\t\t\t\t: and(\n\t\t\t\t\t\t\teq(oneTimeTokens.identifier, identifier),\n\t\t\t\t\t\t\teq(oneTimeTokens.used, false),\n\t\t\t\t\t\t\tgt(oneTimeTokens.expiresAt, now),\n\t\t\t\t\t\t);\n\n\t\t\tconst matching = await db\n\t\t\t\t.select({ id: oneTimeTokens.id })\n\t\t\t\t.from(oneTimeTokens)\n\t\t\t\t.where(whereClause);\n\n\t\t\tif (matching.length === 0) {\n\t\t\t\treturn { success: true, data: { count: 0 } };\n\t\t\t}\n\n\t\t\t// Mark all matched tokens as used (soft-revoke). Re-use the same\n\t\t\t// clause — `now` is still valid since this is synchronous within the\n\t\t\t// same try block.\n\t\t\tawait db.update(oneTimeTokens).set({ used: true }).where(whereClause);\n\n\t\t\treturn { success: true, data: { count: matching.length } };\n\t\t} catch (err) {\n\t\t\treturn {\n\t\t\t\tsuccess: false,\n\t\t\t\terror: makeError(\n\t\t\t\t\t\"REVOKE_TOKENS_FAILED\",\n\t\t\t\t\terr instanceof Error ? err.message : \"Failed to revoke tokens\",\n\t\t\t\t),\n\t\t\t};\n\t\t}\n\t}\n\n\treturn { createToken, validateToken, revokeTokens };\n}\n","/**\n * OpenAPI 3.1 spec generation plugin for KavachOS.\n *\n * Generates a complete OpenAPI document from KavachOS's registered auth\n * endpoints. Useful for serving at `/api/kavach/openapi.json` or wiring\n * into Swagger UI / Scalar.\n *\n * @example\n * ```typescript\n * import { createOpenApiModule } from 'kavachos/auth';\n *\n * const openapi = createOpenApiModule();\n * const spec = openapi.generateSpec({\n * title: 'My App Auth API',\n * serverUrl: 'https://api.example.com',\n * include: ['auth', 'sessions', 'api-keys'],\n * });\n *\n * // In your request handler:\n * const response = openapi.handleRequest(request);\n * if (response) return response;\n * ```\n */\n\n// ---------------------------------------------------------------------------\n// Public types\n// ---------------------------------------------------------------------------\n\nexport type EndpointGroup =\n\t| \"agents\"\n\t| \"auth\"\n\t| \"oauth\"\n\t| \"mcp\"\n\t| \"admin\"\n\t| \"organizations\"\n\t| \"sessions\"\n\t| \"api-keys\"\n\t| \"webhooks\";\n\nexport interface OpenApiConfig {\n\t/** API title shown in spec. Default: \"KavachOS API\" */\n\ttitle?: string;\n\t/** Spec version string. Default: \"0.0.1\" */\n\tversion?: string;\n\t/** Short description of the API */\n\tdescription?: string;\n\t/** Server base URL. Default: \"/\" */\n\tserverUrl?: string;\n\t/** Path prefix for all KavachOS endpoints. Default: \"/api/kavach\" */\n\tbasePath?: string;\n\t/**\n\t * Limit which endpoint groups are included in the spec.\n\t * When omitted all groups are included.\n\t */\n\tinclude?: EndpointGroup[];\n}\n\n// ── OpenAPI 3.1 document shape (plain objects, JSON-serializable) ────────────\n\nexport interface OpenApiInfo {\n\ttitle: string;\n\tversion: string;\n\tdescription?: string;\n}\n\nexport interface OpenApiServer {\n\turl: string;\n}\n\nexport interface OpenApiSchema {\n\ttype?: string;\n\tproperties?: Record<string, OpenApiSchema>;\n\trequired?: string[];\n\titems?: OpenApiSchema;\n\tdescription?: string;\n\texample?: unknown;\n\tenum?: unknown[];\n\tformat?: string;\n\tnullable?: boolean;\n\tadditionalProperties?: boolean | OpenApiSchema;\n\toneOf?: OpenApiSchema[];\n}\n\nexport interface OpenApiMediaType {\n\tschema: OpenApiSchema;\n}\n\nexport interface OpenApiRequestBody {\n\trequired?: boolean;\n\tcontent: Record<string, OpenApiMediaType>;\n}\n\nexport interface OpenApiResponse {\n\tdescription: string;\n\tcontent?: Record<string, OpenApiMediaType>;\n}\n\nexport interface OpenApiSecurityRequirement {\n\t[schemeName: string]: string[];\n}\n\nexport interface OpenApiOperation {\n\toperationId: string;\n\tsummary: string;\n\ttags: string[];\n\tsecurity?: OpenApiSecurityRequirement[];\n\trequestBody?: OpenApiRequestBody;\n\tresponses: Record<string, OpenApiResponse>;\n\tparameters?: OpenApiParameter[];\n}\n\nexport interface OpenApiParameter {\n\tname: string;\n\tin: \"path\" | \"query\" | \"header\" | \"cookie\";\n\trequired?: boolean;\n\tschema: OpenApiSchema;\n\tdescription?: string;\n}\n\nexport interface OpenApiPathItem {\n\tget?: OpenApiOperation;\n\tpost?: OpenApiOperation;\n\tput?: OpenApiOperation;\n\tpatch?: OpenApiOperation;\n\tdelete?: OpenApiOperation;\n}\n\nexport interface OpenApiSecurityScheme {\n\ttype: string;\n\tscheme?: string;\n\tbearerFormat?: string;\n\tdescription?: string;\n\tin?: string;\n\tname?: string;\n\tflows?: Record<string, unknown>;\n}\n\nexport interface OpenApiComponents {\n\tsecuritySchemes: Record<string, OpenApiSecurityScheme>;\n\tschemas: Record<string, OpenApiSchema>;\n}\n\nexport interface OpenApiDocument {\n\topenapi: \"3.1.0\";\n\tinfo: OpenApiInfo;\n\tservers: OpenApiServer[];\n\tpaths: Record<string, OpenApiPathItem>;\n\tcomponents: OpenApiComponents;\n\ttags: Array<{ name: string; description?: string }>;\n}\n\nexport interface OpenApiModule {\n\t/** Generate a complete OpenAPI 3.1.0 document */\n\tgenerateSpec(config?: OpenApiConfig): OpenApiDocument;\n\t/**\n\t * Handle an HTTP request for the spec JSON.\n\t *\n\t * Returns a `Response` with the spec when the request path ends with\n\t * `/openapi.json`. Returns `null` for any other path so the caller's\n\t * routing continues normally.\n\t */\n\thandleRequest(request: Request, config?: OpenApiConfig): Response | null;\n}\n\n// ---------------------------------------------------------------------------\n// Constants\n// ---------------------------------------------------------------------------\n\nconst DEFAULT_TITLE = \"KavachOS API\";\nconst DEFAULT_VERSION = \"0.0.1\";\nconst DEFAULT_SERVER_URL = \"/\";\nconst DEFAULT_BASE_PATH = \"/api/kavach\";\n\n// ---------------------------------------------------------------------------\n// Shared schema fragments\n// ---------------------------------------------------------------------------\n\nconst ERROR_SCHEMA: OpenApiSchema = {\n\ttype: \"object\",\n\tproperties: {\n\t\tcode: { type: \"string\", description: \"Machine-readable error code\" },\n\t\tmessage: { type: \"string\", description: \"Human-readable error message\" },\n\t\tdetails: {\n\t\t\ttype: \"object\",\n\t\t\tadditionalProperties: true,\n\t\t\tdescription: \"Optional structured error details\",\n\t\t},\n\t},\n\trequired: [\"code\", \"message\"],\n};\n\nconst ERROR_RESPONSE_SCHEMA: OpenApiSchema = {\n\ttype: \"object\",\n\tproperties: {\n\t\tsuccess: { type: \"boolean\", example: false },\n\t\terror: ERROR_SCHEMA,\n\t},\n\trequired: [\"success\", \"error\"],\n};\n\nconst BEARER_SECURITY: OpenApiSecurityRequirement[] = [{ BearerAuth: [] }];\n\n// ---------------------------------------------------------------------------\n// Shared response builders\n// ---------------------------------------------------------------------------\n\nfunction errorResponses(\n\tincludeAuth = true,\n\tincludeNotFound = false,\n): Record<string, OpenApiResponse> {\n\tconst responses: Record<string, OpenApiResponse> = {\n\t\t\"400\": {\n\t\t\tdescription: \"Invalid request body or parameters\",\n\t\t\tcontent: { \"application/json\": { schema: ERROR_RESPONSE_SCHEMA } },\n\t\t},\n\t};\n\tif (includeAuth) {\n\t\tresponses[\"401\"] = {\n\t\t\tdescription: \"Missing or invalid authentication token\",\n\t\t\tcontent: { \"application/json\": { schema: ERROR_RESPONSE_SCHEMA } },\n\t\t};\n\t}\n\tif (includeNotFound) {\n\t\tresponses[\"404\"] = {\n\t\t\tdescription: \"Resource not found\",\n\t\t\tcontent: { \"application/json\": { schema: ERROR_RESPONSE_SCHEMA } },\n\t\t};\n\t}\n\treturn responses;\n}\n\nfunction jsonBody(schema: OpenApiSchema, required = true): OpenApiRequestBody {\n\treturn {\n\t\trequired,\n\t\tcontent: { \"application/json\": { schema } },\n\t};\n}\n\nfunction jsonOk(schema: OpenApiSchema): Record<string, OpenApiResponse> {\n\treturn {\n\t\t\"200\": {\n\t\t\tdescription: \"Success\",\n\t\t\tcontent: { \"application/json\": { schema } },\n\t\t},\n\t};\n}\n\nfunction pathParam(name: string, description?: string): OpenApiParameter {\n\treturn {\n\t\tname,\n\t\tin: \"path\",\n\t\trequired: true,\n\t\tschema: { type: \"string\" },\n\t\t...(description !== undefined ? { description } : {}),\n\t};\n}\n\n// ---------------------------------------------------------------------------\n// Endpoint group definitions\n// ---------------------------------------------------------------------------\n\nfunction agentsPaths(base: string): Record<string, OpenApiPathItem> {\n\tconst agentSchema: OpenApiSchema = {\n\t\ttype: \"object\",\n\t\tproperties: {\n\t\t\tid: { type: \"string\" },\n\t\t\townerId: { type: \"string\" },\n\t\t\ttenantId: { type: \"string\", nullable: true },\n\t\t\tname: { type: \"string\" },\n\t\t\ttype: { type: \"string\", enum: [\"autonomous\", \"delegated\", \"service\"] },\n\t\t\ttoken: { type: \"string\" },\n\t\t\tstatus: { type: \"string\", enum: [\"active\", \"revoked\", \"expired\"] },\n\t\t\texpiresAt: { type: \"string\", format: \"date-time\", nullable: true },\n\t\t\tcreatedAt: { type: \"string\", format: \"date-time\" },\n\t\t\tupdatedAt: { type: \"string\", format: \"date-time\" },\n\t\t},\n\t\trequired: [\"id\", \"ownerId\", \"name\", \"type\", \"token\", \"status\", \"createdAt\", \"updatedAt\"],\n\t};\n\n\tconst createAgentBody: OpenApiSchema = {\n\t\ttype: \"object\",\n\t\tproperties: {\n\t\t\townerId: { type: \"string\" },\n\t\t\tname: { type: \"string\" },\n\t\t\ttype: { type: \"string\", enum: [\"autonomous\", \"delegated\", \"service\"] },\n\t\t\tpermissions: {\n\t\t\t\ttype: \"array\",\n\t\t\t\titems: {\n\t\t\t\t\ttype: \"object\",\n\t\t\t\t\tproperties: {\n\t\t\t\t\t\tresource: { type: \"string\" },\n\t\t\t\t\t\tactions: { type: \"array\", items: { type: \"string\" } },\n\t\t\t\t\t},\n\t\t\t\t\trequired: [\"resource\", \"actions\"],\n\t\t\t\t},\n\t\t\t},\n\t\t\texpiresAt: { type: \"string\", format: \"date-time\" },\n\t\t},\n\t\trequired: [\"ownerId\", \"name\", \"type\", \"permissions\"],\n\t};\n\n\treturn {\n\t\t[`${base}/agents`]: {\n\t\t\tpost: {\n\t\t\t\toperationId: \"createAgent\",\n\t\t\t\tsummary: \"Create a new agent identity\",\n\t\t\t\ttags: [\"Agents\"],\n\t\t\t\tsecurity: BEARER_SECURITY,\n\t\t\t\trequestBody: jsonBody(createAgentBody),\n\t\t\t\tresponses: {\n\t\t\t\t\t...jsonOk(agentSchema),\n\t\t\t\t\t...errorResponses(true, false),\n\t\t\t\t},\n\t\t\t},\n\t\t\tget: {\n\t\t\t\toperationId: \"listAgents\",\n\t\t\t\tsummary: \"List agent identities\",\n\t\t\t\ttags: [\"Agents\"],\n\t\t\t\tsecurity: BEARER_SECURITY,\n\t\t\t\tresponses: {\n\t\t\t\t\t...jsonOk({ type: \"array\", items: agentSchema }),\n\t\t\t\t\t...errorResponses(true, false),\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t\t[`${base}/agents/{id}`]: {\n\t\t\tget: {\n\t\t\t\toperationId: \"getAgent\",\n\t\t\t\tsummary: \"Get an agent by ID\",\n\t\t\t\ttags: [\"Agents\"],\n\t\t\t\tsecurity: BEARER_SECURITY,\n\t\t\t\tparameters: [pathParam(\"id\", \"Agent ID\")],\n\t\t\t\tresponses: {\n\t\t\t\t\t...jsonOk(agentSchema),\n\t\t\t\t\t...errorResponses(true, true),\n\t\t\t\t},\n\t\t\t},\n\t\t\tdelete: {\n\t\t\t\toperationId: \"deleteAgent\",\n\t\t\t\tsummary: \"Delete (revoke) an agent\",\n\t\t\t\ttags: [\"Agents\"],\n\t\t\t\tsecurity: BEARER_SECURITY,\n\t\t\t\tparameters: [pathParam(\"id\", \"Agent ID\")],\n\t\t\t\tresponses: {\n\t\t\t\t\t\"204\": { description: \"Agent deleted\" },\n\t\t\t\t\t...errorResponses(true, true),\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t\t[`${base}/agents/{id}/rotate`]: {\n\t\t\tpost: {\n\t\t\t\toperationId: \"rotateAgent\",\n\t\t\t\tsummary: \"Rotate an agent token\",\n\t\t\t\ttags: [\"Agents\"],\n\t\t\t\tsecurity: BEARER_SECURITY,\n\t\t\t\tparameters: [pathParam(\"id\", \"Agent ID\")],\n\t\t\t\tresponses: {\n\t\t\t\t\t...jsonOk(agentSchema),\n\t\t\t\t\t...errorResponses(true, true),\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t};\n}\n\nfunction authPaths(base: string): Record<string, OpenApiPathItem> {\n\tconst sessionSchema: OpenApiSchema = {\n\t\ttype: \"object\",\n\t\tproperties: {\n\t\t\tid: { type: \"string\" },\n\t\t\tuserId: { type: \"string\" },\n\t\t\ttoken: { type: \"string\" },\n\t\t\texpiresAt: { type: \"string\", format: \"date-time\" },\n\t\t\tcreatedAt: { type: \"string\", format: \"date-time\" },\n\t\t},\n\t\trequired: [\"id\", \"userId\", \"token\", \"expiresAt\", \"createdAt\"],\n\t};\n\n\tconst userSchema: OpenApiSchema = {\n\t\ttype: \"object\",\n\t\tproperties: {\n\t\t\tid: { type: \"string\" },\n\t\t\temail: { type: \"string\", format: \"email\" },\n\t\t\tname: { type: \"string\", nullable: true },\n\t\t\tcreatedAt: { type: \"string\", format: \"date-time\" },\n\t\t},\n\t\trequired: [\"id\", \"email\", \"createdAt\"],\n\t};\n\n\tconst emailPasswordBody: OpenApiSchema = {\n\t\ttype: \"object\",\n\t\tproperties: {\n\t\t\temail: { type: \"string\", format: \"email\" },\n\t\t\tpassword: { type: \"string\", format: \"password\" },\n\t\t},\n\t\trequired: [\"email\", \"password\"],\n\t};\n\n\tconst signInOkSchema: OpenApiSchema = {\n\t\ttype: \"object\",\n\t\tproperties: {\n\t\t\tsuccess: { type: \"boolean\", example: true },\n\t\t\tdata: {\n\t\t\t\ttype: \"object\",\n\t\t\t\tproperties: {\n\t\t\t\t\tuser: userSchema,\n\t\t\t\t\tsession: sessionSchema,\n\t\t\t\t},\n\t\t\t\trequired: [\"user\", \"session\"],\n\t\t\t},\n\t\t},\n\t\trequired: [\"success\", \"data\"],\n\t};\n\n\treturn {\n\t\t[`${base}/sign-in/email`]: {\n\t\t\tpost: {\n\t\t\t\toperationId: \"signInEmail\",\n\t\t\t\tsummary: \"Sign in with email and password\",\n\t\t\t\ttags: [\"Auth\"],\n\t\t\t\trequestBody: jsonBody(emailPasswordBody),\n\t\t\t\tresponses: {\n\t\t\t\t\t...jsonOk(signInOkSchema),\n\t\t\t\t\t...errorResponses(false, false),\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t\t[`${base}/sign-up/email`]: {\n\t\t\tpost: {\n\t\t\t\toperationId: \"signUpEmail\",\n\t\t\t\tsummary: \"Create a new account with email and password\",\n\t\t\t\ttags: [\"Auth\"],\n\t\t\t\trequestBody: jsonBody({\n\t\t\t\t\ttype: \"object\",\n\t\t\t\t\tproperties: {\n\t\t\t\t\t\temail: { type: \"string\", format: \"email\" },\n\t\t\t\t\t\tpassword: { type: \"string\", format: \"password\" },\n\t\t\t\t\t\tname: { type: \"string\" },\n\t\t\t\t\t},\n\t\t\t\t\trequired: [\"email\", \"password\"],\n\t\t\t\t}),\n\t\t\t\tresponses: {\n\t\t\t\t\t...jsonOk(signInOkSchema),\n\t\t\t\t\t...errorResponses(false, false),\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t\t[`${base}/sign-out`]: {\n\t\t\tpost: {\n\t\t\t\toperationId: \"signOut\",\n\t\t\t\tsummary: \"Sign out and invalidate the current session\",\n\t\t\t\ttags: [\"Auth\"],\n\t\t\t\tsecurity: BEARER_SECURITY,\n\t\t\t\tresponses: {\n\t\t\t\t\t\"204\": { description: \"Signed out successfully\" },\n\t\t\t\t\t...errorResponses(true, false),\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t\t[`${base}/session`]: {\n\t\t\tget: {\n\t\t\t\toperationId: \"getSession\",\n\t\t\t\tsummary: \"Get the current session and user\",\n\t\t\t\ttags: [\"Auth\"],\n\t\t\t\tsecurity: BEARER_SECURITY,\n\t\t\t\tresponses: {\n\t\t\t\t\t...jsonOk(signInOkSchema),\n\t\t\t\t\t...errorResponses(true, false),\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t\t[`${base}/auth/magic-link/send`]: {\n\t\t\tpost: {\n\t\t\t\toperationId: \"sendMagicLink\",\n\t\t\t\tsummary: \"Send a magic link to an email address\",\n\t\t\t\ttags: [\"Auth\"],\n\t\t\t\trequestBody: jsonBody({\n\t\t\t\t\ttype: \"object\",\n\t\t\t\t\tproperties: { email: { type: \"string\", format: \"email\" } },\n\t\t\t\t\trequired: [\"email\"],\n\t\t\t\t}),\n\t\t\t\tresponses: {\n\t\t\t\t\t\"204\": { description: \"Magic link sent\" },\n\t\t\t\t\t...errorResponses(false, false),\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t\t[`${base}/auth/magic-link/verify`]: {\n\t\t\tpost: {\n\t\t\t\toperationId: \"verifyMagicLink\",\n\t\t\t\tsummary: \"Verify a magic link token and create a session\",\n\t\t\t\ttags: [\"Auth\"],\n\t\t\t\trequestBody: jsonBody({\n\t\t\t\t\ttype: \"object\",\n\t\t\t\t\tproperties: { token: { type: \"string\" } },\n\t\t\t\t\trequired: [\"token\"],\n\t\t\t\t}),\n\t\t\t\tresponses: {\n\t\t\t\t\t...jsonOk(signInOkSchema),\n\t\t\t\t\t...errorResponses(false, false),\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t\t[`${base}/auth/email-otp/send`]: {\n\t\t\tpost: {\n\t\t\t\toperationId: \"sendEmailOtp\",\n\t\t\t\tsummary: \"Send a one-time passcode to an email address\",\n\t\t\t\ttags: [\"Auth\"],\n\t\t\t\trequestBody: jsonBody({\n\t\t\t\t\ttype: \"object\",\n\t\t\t\t\tproperties: { email: { type: \"string\", format: \"email\" } },\n\t\t\t\t\trequired: [\"email\"],\n\t\t\t\t}),\n\t\t\t\tresponses: {\n\t\t\t\t\t\"204\": { description: \"OTP sent\" },\n\t\t\t\t\t...errorResponses(false, false),\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t\t[`${base}/auth/email-otp/verify`]: {\n\t\t\tpost: {\n\t\t\t\toperationId: \"verifyEmailOtp\",\n\t\t\t\tsummary: \"Verify an email OTP and create a session\",\n\t\t\t\ttags: [\"Auth\"],\n\t\t\t\trequestBody: jsonBody({\n\t\t\t\t\ttype: \"object\",\n\t\t\t\t\tproperties: {\n\t\t\t\t\t\temail: { type: \"string\", format: \"email\" },\n\t\t\t\t\t\tcode: { type: \"string\" },\n\t\t\t\t\t},\n\t\t\t\t\trequired: [\"email\", \"code\"],\n\t\t\t\t}),\n\t\t\t\tresponses: {\n\t\t\t\t\t...jsonOk(signInOkSchema),\n\t\t\t\t\t...errorResponses(false, false),\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t\t[`${base}/auth/forgot-password`]: {\n\t\t\tpost: {\n\t\t\t\toperationId: \"forgotPassword\",\n\t\t\t\tsummary: \"Request a password reset email\",\n\t\t\t\ttags: [\"Auth\"],\n\t\t\t\trequestBody: jsonBody({\n\t\t\t\t\ttype: \"object\",\n\t\t\t\t\tproperties: { email: { type: \"string\", format: \"email\" } },\n\t\t\t\t\trequired: [\"email\"],\n\t\t\t\t}),\n\t\t\t\tresponses: {\n\t\t\t\t\t\"204\": { description: \"Reset email sent\" },\n\t\t\t\t\t...errorResponses(false, false),\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t\t[`${base}/auth/reset-password`]: {\n\t\t\tpost: {\n\t\t\t\toperationId: \"resetPassword\",\n\t\t\t\tsummary: \"Reset a password using a token from email\",\n\t\t\t\ttags: [\"Auth\"],\n\t\t\t\trequestBody: jsonBody({\n\t\t\t\t\ttype: \"object\",\n\t\t\t\t\tproperties: {\n\t\t\t\t\t\ttoken: { type: \"string\" },\n\t\t\t\t\t\tpassword: { type: \"string\", format: \"password\" },\n\t\t\t\t\t},\n\t\t\t\t\trequired: [\"token\", \"password\"],\n\t\t\t\t}),\n\t\t\t\tresponses: {\n\t\t\t\t\t\"204\": { description: \"Password reset successfully\" },\n\t\t\t\t\t...errorResponses(false, false),\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t\t[`${base}/auth/two-factor/verify`]: {\n\t\t\tpost: {\n\t\t\t\toperationId: \"verifyTwoFactor\",\n\t\t\t\tsummary: \"Verify a TOTP code for two-factor authentication\",\n\t\t\t\ttags: [\"Auth\"],\n\t\t\t\tsecurity: BEARER_SECURITY,\n\t\t\t\trequestBody: jsonBody({\n\t\t\t\t\ttype: \"object\",\n\t\t\t\t\tproperties: { code: { type: \"string\", description: \"6-digit TOTP code\" } },\n\t\t\t\t\trequired: [\"code\"],\n\t\t\t\t}),\n\t\t\t\tresponses: {\n\t\t\t\t\t...jsonOk(signInOkSchema),\n\t\t\t\t\t...errorResponses(true, false),\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t};\n}\n\nfunction oauthPaths(base: string): Record<string, OpenApiPathItem> {\n\treturn {\n\t\t[`${base}/auth/{provider}`]: {\n\t\t\tget: {\n\t\t\t\toperationId: \"oauthRedirect\",\n\t\t\t\tsummary: \"Redirect to OAuth provider authorization page\",\n\t\t\t\ttags: [\"OAuth\"],\n\t\t\t\tparameters: [pathParam(\"provider\", \"OAuth provider name (e.g. google, github, discord)\")],\n\t\t\t\tresponses: {\n\t\t\t\t\t\"302\": { description: \"Redirect to provider\" },\n\t\t\t\t\t...errorResponses(false, false),\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t\t[`${base}/auth/{provider}/callback`]: {\n\t\t\tget: {\n\t\t\t\toperationId: \"oauthCallback\",\n\t\t\t\tsummary: \"Handle OAuth provider callback and create session\",\n\t\t\t\ttags: [\"OAuth\"],\n\t\t\t\tparameters: [\n\t\t\t\t\tpathParam(\"provider\", \"OAuth provider name\"),\n\t\t\t\t\t{\n\t\t\t\t\t\tname: \"code\",\n\t\t\t\t\t\tin: \"query\",\n\t\t\t\t\t\trequired: true,\n\t\t\t\t\t\tschema: { type: \"string\" },\n\t\t\t\t\t\tdescription: \"Authorization code from provider\",\n\t\t\t\t\t},\n\t\t\t\t\t{\n\t\t\t\t\t\tname: \"state\",\n\t\t\t\t\t\tin: \"query\",\n\t\t\t\t\t\trequired: false,\n\t\t\t\t\t\tschema: { type: \"string\" },\n\t\t\t\t\t\tdescription: \"CSRF state parameter\",\n\t\t\t\t\t},\n\t\t\t\t],\n\t\t\t\tresponses: {\n\t\t\t\t\t\"302\": { description: \"Redirect after authentication\" },\n\t\t\t\t\t...errorResponses(false, false),\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t};\n}\n\nfunction mcpPaths(base: string): Record<string, OpenApiPathItem> {\n\tconst tokenResponseSchema: OpenApiSchema = {\n\t\ttype: \"object\",\n\t\tproperties: {\n\t\t\taccess_token: { type: \"string\" },\n\t\t\ttoken_type: { type: \"string\", enum: [\"Bearer\"] },\n\t\t\texpires_in: { type: \"integer\" },\n\t\t\trefresh_token: { type: \"string\" },\n\t\t\tscope: { type: \"string\" },\n\t\t},\n\t\trequired: [\"access_token\", \"token_type\", \"expires_in\"],\n\t};\n\n\treturn {\n\t\t[`${base}/mcp/authorize`]: {\n\t\t\tget: {\n\t\t\t\toperationId: \"mcpAuthorize\",\n\t\t\t\tsummary: \"OAuth 2.1 authorization endpoint (PKCE S256 required)\",\n\t\t\t\ttags: [\"MCP\"],\n\t\t\t\tparameters: [\n\t\t\t\t\t{\n\t\t\t\t\t\tname: \"response_type\",\n\t\t\t\t\t\tin: \"query\",\n\t\t\t\t\t\trequired: true,\n\t\t\t\t\t\tschema: { type: \"string\", enum: [\"code\"] },\n\t\t\t\t\t},\n\t\t\t\t\t{ name: \"client_id\", in: \"query\", required: true, schema: { type: \"string\" } },\n\t\t\t\t\t{ name: \"redirect_uri\", in: \"query\", required: true, schema: { type: \"string\" } },\n\t\t\t\t\t{ name: \"code_challenge\", in: \"query\", required: true, schema: { type: \"string\" } },\n\t\t\t\t\t{\n\t\t\t\t\t\tname: \"code_challenge_method\",\n\t\t\t\t\t\tin: \"query\",\n\t\t\t\t\t\trequired: true,\n\t\t\t\t\t\tschema: { type: \"string\", enum: [\"S256\"] },\n\t\t\t\t\t},\n\t\t\t\t\t{ name: \"scope\", in: \"query\", required: false, schema: { type: \"string\" } },\n\t\t\t\t\t{ name: \"state\", in: \"query\", required: false, schema: { type: \"string\" } },\n\t\t\t\t\t{ name: \"resource\", in: \"query\", required: false, schema: { type: \"string\" } },\n\t\t\t\t],\n\t\t\t\tresponses: {\n\t\t\t\t\t\"302\": { description: \"Redirect to login page or callback\" },\n\t\t\t\t\t...errorResponses(false, false),\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t\t[`${base}/mcp/token`]: {\n\t\t\tpost: {\n\t\t\t\toperationId: \"mcpToken\",\n\t\t\t\tsummary: \"OAuth 2.1 token endpoint\",\n\t\t\t\ttags: [\"MCP\"],\n\t\t\t\trequestBody: {\n\t\t\t\t\trequired: true,\n\t\t\t\t\tcontent: {\n\t\t\t\t\t\t\"application/x-www-form-urlencoded\": {\n\t\t\t\t\t\t\tschema: {\n\t\t\t\t\t\t\t\ttype: \"object\",\n\t\t\t\t\t\t\t\tproperties: {\n\t\t\t\t\t\t\t\t\tgrant_type: {\n\t\t\t\t\t\t\t\t\t\ttype: \"string\",\n\t\t\t\t\t\t\t\t\t\tenum: [\"authorization_code\", \"refresh_token\"],\n\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\tcode: { type: \"string\" },\n\t\t\t\t\t\t\t\t\tredirect_uri: { type: \"string\" },\n\t\t\t\t\t\t\t\t\tclient_id: { type: \"string\" },\n\t\t\t\t\t\t\t\t\tclient_secret: { type: \"string\" },\n\t\t\t\t\t\t\t\t\tcode_verifier: { type: \"string\" },\n\t\t\t\t\t\t\t\t\trefresh_token: { type: \"string\" },\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\trequired: [\"grant_type\"],\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t\tresponses: {\n\t\t\t\t\t...jsonOk(tokenResponseSchema),\n\t\t\t\t\t...errorResponses(false, false),\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t\t[`${base}/mcp/register`]: {\n\t\t\tpost: {\n\t\t\t\toperationId: \"mcpRegisterClient\",\n\t\t\t\tsummary: \"Dynamic client registration (RFC 7591)\",\n\t\t\t\ttags: [\"MCP\"],\n\t\t\t\trequestBody: jsonBody({\n\t\t\t\t\ttype: \"object\",\n\t\t\t\t\tproperties: {\n\t\t\t\t\t\tredirect_uris: { type: \"array\", items: { type: \"string\", format: \"uri\" } },\n\t\t\t\t\t\tclient_name: { type: \"string\" },\n\t\t\t\t\t\tclient_uri: { type: \"string\", format: \"uri\" },\n\t\t\t\t\t\tgrant_types: { type: \"array\", items: { type: \"string\" } },\n\t\t\t\t\t\tscope: { type: \"string\" },\n\t\t\t\t\t},\n\t\t\t\t\trequired: [\"redirect_uris\"],\n\t\t\t\t}),\n\t\t\t\tresponses: {\n\t\t\t\t\t\"201\": {\n\t\t\t\t\t\tdescription: \"Client registered\",\n\t\t\t\t\t\tcontent: {\n\t\t\t\t\t\t\t\"application/json\": {\n\t\t\t\t\t\t\t\tschema: {\n\t\t\t\t\t\t\t\t\ttype: \"object\",\n\t\t\t\t\t\t\t\t\tproperties: {\n\t\t\t\t\t\t\t\t\t\tclient_id: { type: \"string\" },\n\t\t\t\t\t\t\t\t\t\tclient_secret: { type: \"string\" },\n\t\t\t\t\t\t\t\t\t\tclient_id_issued_at: { type: \"integer\" },\n\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\trequired: [\"client_id\", \"client_id_issued_at\"],\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t\t...errorResponses(false, false),\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t\t[`${base}/.well-known/oauth-authorization-server`]: {\n\t\t\tget: {\n\t\t\t\toperationId: \"mcpServerMetadata\",\n\t\t\t\tsummary: \"OAuth 2.0 Authorization Server Metadata (RFC 8414)\",\n\t\t\t\ttags: [\"MCP\"],\n\t\t\t\tresponses: {\n\t\t\t\t\t\"200\": {\n\t\t\t\t\t\tdescription: \"Authorization server metadata\",\n\t\t\t\t\t\tcontent: {\n\t\t\t\t\t\t\t\"application/json\": {\n\t\t\t\t\t\t\t\tschema: {\n\t\t\t\t\t\t\t\t\ttype: \"object\",\n\t\t\t\t\t\t\t\t\tproperties: {\n\t\t\t\t\t\t\t\t\t\tissuer: { type: \"string\" },\n\t\t\t\t\t\t\t\t\t\tauthorization_endpoint: { type: \"string\" },\n\t\t\t\t\t\t\t\t\t\ttoken_endpoint: { type: \"string\" },\n\t\t\t\t\t\t\t\t\t\tregistration_endpoint: { type: \"string\" },\n\t\t\t\t\t\t\t\t\t\tscopes_supported: { type: \"array\", items: { type: \"string\" } },\n\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\trequired: [\n\t\t\t\t\t\t\t\t\t\t\"issuer\",\n\t\t\t\t\t\t\t\t\t\t\"authorization_endpoint\",\n\t\t\t\t\t\t\t\t\t\t\"token_endpoint\",\n\t\t\t\t\t\t\t\t\t\t\"registration_endpoint\",\n\t\t\t\t\t\t\t\t\t],\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t};\n}\n\nfunction adminPaths(base: string): Record<string, OpenApiPathItem> {\n\tconst adminUserSchema: OpenApiSchema = {\n\t\ttype: \"object\",\n\t\tproperties: {\n\t\t\tid: { type: \"string\" },\n\t\t\temail: { type: \"string\", format: \"email\" },\n\t\t\tname: { type: \"string\", nullable: true },\n\t\t\tbanned: { type: \"boolean\" },\n\t\t\tbannedReason: { type: \"string\", nullable: true },\n\t\t\tcreatedAt: { type: \"string\", format: \"date-time\" },\n\t\t},\n\t\trequired: [\"id\", \"email\", \"banned\", \"createdAt\"],\n\t};\n\n\treturn {\n\t\t[`${base}/admin/users`]: {\n\t\t\tget: {\n\t\t\t\toperationId: \"adminListUsers\",\n\t\t\t\tsummary: \"List all users (admin only)\",\n\t\t\t\ttags: [\"Admin\"],\n\t\t\t\tsecurity: BEARER_SECURITY,\n\t\t\t\tresponses: {\n\t\t\t\t\t...jsonOk({ type: \"array\", items: adminUserSchema }),\n\t\t\t\t\t...errorResponses(true, false),\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t\t[`${base}/admin/users/{id}/ban`]: {\n\t\t\tpost: {\n\t\t\t\toperationId: \"adminBanUser\",\n\t\t\t\tsummary: \"Ban a user account\",\n\t\t\t\ttags: [\"Admin\"],\n\t\t\t\tsecurity: BEARER_SECURITY,\n\t\t\t\tparameters: [pathParam(\"id\", \"User ID\")],\n\t\t\t\trequestBody: jsonBody({\n\t\t\t\t\ttype: \"object\",\n\t\t\t\t\tproperties: { reason: { type: \"string\" } },\n\t\t\t\t\trequired: [],\n\t\t\t\t}),\n\t\t\t\tresponses: {\n\t\t\t\t\t\"204\": { description: \"User banned\" },\n\t\t\t\t\t...errorResponses(true, true),\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t\t[`${base}/admin/users/{id}/unban`]: {\n\t\t\tpost: {\n\t\t\t\toperationId: \"adminUnbanUser\",\n\t\t\t\tsummary: \"Unban a user account\",\n\t\t\t\ttags: [\"Admin\"],\n\t\t\t\tsecurity: BEARER_SECURITY,\n\t\t\t\tparameters: [pathParam(\"id\", \"User ID\")],\n\t\t\t\tresponses: {\n\t\t\t\t\t\"204\": { description: \"User unbanned\" },\n\t\t\t\t\t...errorResponses(true, true),\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t\t[`${base}/admin/users/{id}`]: {\n\t\t\tdelete: {\n\t\t\t\toperationId: \"adminDeleteUser\",\n\t\t\t\tsummary: \"Delete a user account permanently\",\n\t\t\t\ttags: [\"Admin\"],\n\t\t\t\tsecurity: BEARER_SECURITY,\n\t\t\t\tparameters: [pathParam(\"id\", \"User ID\")],\n\t\t\t\tresponses: {\n\t\t\t\t\t\"204\": { description: \"User deleted\" },\n\t\t\t\t\t...errorResponses(true, true),\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t};\n}\n\nfunction organizationsPaths(base: string): Record<string, OpenApiPathItem> {\n\tconst orgSchema: OpenApiSchema = {\n\t\ttype: \"object\",\n\t\tproperties: {\n\t\t\tid: { type: \"string\" },\n\t\t\tname: { type: \"string\" },\n\t\t\tslug: { type: \"string\" },\n\t\t\tcreatedAt: { type: \"string\", format: \"date-time\" },\n\t\t},\n\t\trequired: [\"id\", \"name\", \"slug\", \"createdAt\"],\n\t};\n\n\treturn {\n\t\t[`${base}/organizations`]: {\n\t\t\tpost: {\n\t\t\t\toperationId: \"createOrganization\",\n\t\t\t\tsummary: \"Create a new organization\",\n\t\t\t\ttags: [\"Organizations\"],\n\t\t\t\tsecurity: BEARER_SECURITY,\n\t\t\t\trequestBody: jsonBody({\n\t\t\t\t\ttype: \"object\",\n\t\t\t\t\tproperties: {\n\t\t\t\t\t\tname: { type: \"string\" },\n\t\t\t\t\t\tslug: { type: \"string\" },\n\t\t\t\t\t},\n\t\t\t\t\trequired: [\"name\"],\n\t\t\t\t}),\n\t\t\t\tresponses: {\n\t\t\t\t\t...jsonOk(orgSchema),\n\t\t\t\t\t...errorResponses(true, false),\n\t\t\t\t},\n\t\t\t},\n\t\t\tget: {\n\t\t\t\toperationId: \"listOrganizations\",\n\t\t\t\tsummary: \"List organizations the current user belongs to\",\n\t\t\t\ttags: [\"Organizations\"],\n\t\t\t\tsecurity: BEARER_SECURITY,\n\t\t\t\tresponses: {\n\t\t\t\t\t...jsonOk({ type: \"array\", items: orgSchema }),\n\t\t\t\t\t...errorResponses(true, false),\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t\t[`${base}/organizations/{id}/members`]: {\n\t\t\tpost: {\n\t\t\t\toperationId: \"addOrganizationMember\",\n\t\t\t\tsummary: \"Add a member to an organization\",\n\t\t\t\ttags: [\"Organizations\"],\n\t\t\t\tsecurity: BEARER_SECURITY,\n\t\t\t\tparameters: [pathParam(\"id\", \"Organization ID\")],\n\t\t\t\trequestBody: jsonBody({\n\t\t\t\t\ttype: \"object\",\n\t\t\t\t\tproperties: {\n\t\t\t\t\t\tuserId: { type: \"string\" },\n\t\t\t\t\t\trole: { type: \"string\", enum: [\"owner\", \"admin\", \"member\", \"viewer\"] },\n\t\t\t\t\t},\n\t\t\t\t\trequired: [\"userId\", \"role\"],\n\t\t\t\t}),\n\t\t\t\tresponses: {\n\t\t\t\t\t\"204\": { description: \"Member added\" },\n\t\t\t\t\t...errorResponses(true, true),\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t};\n}\n\nfunction sessionsPaths(base: string): Record<string, OpenApiPathItem> {\n\tconst sessionSchema: OpenApiSchema = {\n\t\ttype: \"object\",\n\t\tproperties: {\n\t\t\tid: { type: \"string\" },\n\t\t\tuserId: { type: \"string\" },\n\t\t\tuserAgent: { type: \"string\", nullable: true },\n\t\t\tipAddress: { type: \"string\", nullable: true },\n\t\t\texpiresAt: { type: \"string\", format: \"date-time\" },\n\t\t\tcreatedAt: { type: \"string\", format: \"date-time\" },\n\t\t\tcurrent: { type: \"boolean\", description: \"True if this is the active session\" },\n\t\t},\n\t\trequired: [\"id\", \"userId\", \"expiresAt\", \"createdAt\", \"current\"],\n\t};\n\n\treturn {\n\t\t[`${base}/sessions`]: {\n\t\t\tget: {\n\t\t\t\toperationId: \"listSessions\",\n\t\t\t\tsummary: \"List active sessions for the current user\",\n\t\t\t\ttags: [\"Sessions\"],\n\t\t\t\tsecurity: BEARER_SECURITY,\n\t\t\t\tresponses: {\n\t\t\t\t\t...jsonOk({ type: \"array\", items: sessionSchema }),\n\t\t\t\t\t...errorResponses(true, false),\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t\t[`${base}/sessions/{id}`]: {\n\t\t\tdelete: {\n\t\t\t\toperationId: \"deleteSession\",\n\t\t\t\tsummary: \"Revoke a session by ID\",\n\t\t\t\ttags: [\"Sessions\"],\n\t\t\t\tsecurity: BEARER_SECURITY,\n\t\t\t\tparameters: [pathParam(\"id\", \"Session ID\")],\n\t\t\t\tresponses: {\n\t\t\t\t\t\"204\": { description: \"Session revoked\" },\n\t\t\t\t\t...errorResponses(true, true),\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t};\n}\n\nfunction apiKeysPaths(base: string): Record<string, OpenApiPathItem> {\n\tconst apiKeySchema: OpenApiSchema = {\n\t\ttype: \"object\",\n\t\tproperties: {\n\t\t\tid: { type: \"string\" },\n\t\t\tname: { type: \"string\" },\n\t\t\tprefix: { type: \"string\", description: \"First 8 characters of the key (for display)\" },\n\t\t\tscopes: { type: \"array\", items: { type: \"string\" } },\n\t\t\texpiresAt: { type: \"string\", format: \"date-time\", nullable: true },\n\t\t\tcreatedAt: { type: \"string\", format: \"date-time\" },\n\t\t},\n\t\trequired: [\"id\", \"name\", \"prefix\", \"scopes\", \"createdAt\"],\n\t};\n\n\tconst createApiKeyResponseSchema: OpenApiSchema = {\n\t\ttype: \"object\",\n\t\tproperties: {\n\t\t\t...apiKeySchema.properties,\n\t\t\tkey: { type: \"string\", description: \"Full API key — shown once, store securely\" },\n\t\t},\n\t\trequired: [...(apiKeySchema.required ?? []), \"key\"],\n\t};\n\n\treturn {\n\t\t[`${base}/api-keys`]: {\n\t\t\tpost: {\n\t\t\t\toperationId: \"createApiKey\",\n\t\t\t\tsummary: \"Create a new API key\",\n\t\t\t\ttags: [\"API Keys\"],\n\t\t\t\tsecurity: BEARER_SECURITY,\n\t\t\t\trequestBody: jsonBody({\n\t\t\t\t\ttype: \"object\",\n\t\t\t\t\tproperties: {\n\t\t\t\t\t\tname: { type: \"string\" },\n\t\t\t\t\t\tscopes: { type: \"array\", items: { type: \"string\" } },\n\t\t\t\t\t\texpiresAt: { type: \"string\", format: \"date-time\" },\n\t\t\t\t\t},\n\t\t\t\t\trequired: [\"name\", \"scopes\"],\n\t\t\t\t}),\n\t\t\t\tresponses: {\n\t\t\t\t\t...jsonOk(createApiKeyResponseSchema),\n\t\t\t\t\t...errorResponses(true, false),\n\t\t\t\t},\n\t\t\t},\n\t\t\tget: {\n\t\t\t\toperationId: \"listApiKeys\",\n\t\t\t\tsummary: \"List API keys for the current user\",\n\t\t\t\ttags: [\"API Keys\"],\n\t\t\t\tsecurity: BEARER_SECURITY,\n\t\t\t\tresponses: {\n\t\t\t\t\t...jsonOk({ type: \"array\", items: apiKeySchema }),\n\t\t\t\t\t...errorResponses(true, false),\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t\t[`${base}/api-keys/{id}`]: {\n\t\t\tdelete: {\n\t\t\t\toperationId: \"deleteApiKey\",\n\t\t\t\tsummary: \"Delete an API key\",\n\t\t\t\ttags: [\"API Keys\"],\n\t\t\t\tsecurity: BEARER_SECURITY,\n\t\t\t\tparameters: [pathParam(\"id\", \"API Key ID\")],\n\t\t\t\tresponses: {\n\t\t\t\t\t\"204\": { description: \"API key deleted\" },\n\t\t\t\t\t...errorResponses(true, true),\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t\t[`${base}/api-keys/{id}/rotate`]: {\n\t\t\tpost: {\n\t\t\t\toperationId: \"rotateApiKey\",\n\t\t\t\tsummary: \"Rotate an API key — returns a new key value\",\n\t\t\t\ttags: [\"API Keys\"],\n\t\t\t\tsecurity: BEARER_SECURITY,\n\t\t\t\tparameters: [pathParam(\"id\", \"API Key ID\")],\n\t\t\t\tresponses: {\n\t\t\t\t\t...jsonOk(createApiKeyResponseSchema),\n\t\t\t\t\t...errorResponses(true, true),\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t};\n}\n\nfunction webhooksPaths(base: string): Record<string, OpenApiPathItem> {\n\tconst webhookSchema: OpenApiSchema = {\n\t\ttype: \"object\",\n\t\tproperties: {\n\t\t\tid: { type: \"string\" },\n\t\t\turl: { type: \"string\", format: \"uri\" },\n\t\t\tevents: { type: \"array\", items: { type: \"string\" } },\n\t\t\tactive: { type: \"boolean\" },\n\t\t\tcreatedAt: { type: \"string\", format: \"date-time\" },\n\t\t},\n\t\trequired: [\"id\", \"url\", \"events\", \"active\", \"createdAt\"],\n\t};\n\n\treturn {\n\t\t[`${base}/webhooks`]: {\n\t\t\tpost: {\n\t\t\t\toperationId: \"createWebhook\",\n\t\t\t\tsummary: \"Register a webhook endpoint\",\n\t\t\t\ttags: [\"Webhooks\"],\n\t\t\t\tsecurity: BEARER_SECURITY,\n\t\t\t\trequestBody: jsonBody({\n\t\t\t\t\ttype: \"object\",\n\t\t\t\t\tproperties: {\n\t\t\t\t\t\turl: { type: \"string\", format: \"uri\" },\n\t\t\t\t\t\tevents: { type: \"array\", items: { type: \"string\" } },\n\t\t\t\t\t\tsecret: { type: \"string\", description: \"Signing secret for HMAC verification\" },\n\t\t\t\t\t},\n\t\t\t\t\trequired: [\"url\", \"events\"],\n\t\t\t\t}),\n\t\t\t\tresponses: {\n\t\t\t\t\t...jsonOk(webhookSchema),\n\t\t\t\t\t...errorResponses(true, false),\n\t\t\t\t},\n\t\t\t},\n\t\t\tget: {\n\t\t\t\toperationId: \"listWebhooks\",\n\t\t\t\tsummary: \"List registered webhook endpoints\",\n\t\t\t\ttags: [\"Webhooks\"],\n\t\t\t\tsecurity: BEARER_SECURITY,\n\t\t\t\tresponses: {\n\t\t\t\t\t...jsonOk({ type: \"array\", items: webhookSchema }),\n\t\t\t\t\t...errorResponses(true, false),\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t\t[`${base}/webhooks/{id}`]: {\n\t\t\tdelete: {\n\t\t\t\toperationId: \"deleteWebhook\",\n\t\t\t\tsummary: \"Remove a webhook endpoint\",\n\t\t\t\ttags: [\"Webhooks\"],\n\t\t\t\tsecurity: BEARER_SECURITY,\n\t\t\t\tparameters: [pathParam(\"id\", \"Webhook ID\")],\n\t\t\t\tresponses: {\n\t\t\t\t\t\"204\": { description: \"Webhook removed\" },\n\t\t\t\t\t...errorResponses(true, true),\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t};\n}\n\n// ---------------------------------------------------------------------------\n// Tag definitions\n// ---------------------------------------------------------------------------\n\nconst ALL_TAGS: Array<{ name: string; description: string }> = [\n\t{ name: \"Agents\", description: \"Agent identity management\" },\n\t{\n\t\tname: \"Auth\",\n\t\tdescription: \"Email/password, magic link, OTP, and two-factor authentication\",\n\t},\n\t{ name: \"OAuth\", description: \"Third-party OAuth provider authentication\" },\n\t{ name: \"MCP\", description: \"OAuth 2.1 authorization server for AI agents (RFC 8414, 7591)\" },\n\t{ name: \"Admin\", description: \"Administrative user management operations\" },\n\t{\n\t\tname: \"Organizations\",\n\t\tdescription: \"Multi-tenant organization management and RBAC\",\n\t},\n\t{ name: \"Sessions\", description: \"Session lifecycle management\" },\n\t{ name: \"API Keys\", description: \"Static API key management with permission scopes\" },\n\t{ name: \"Webhooks\", description: \"Webhook endpoint registration and management\" },\n];\n\nconst GROUP_TAG_MAP: Record<EndpointGroup, string> = {\n\tagents: \"Agents\",\n\tauth: \"Auth\",\n\toauth: \"OAuth\",\n\tmcp: \"MCP\",\n\tadmin: \"Admin\",\n\torganizations: \"Organizations\",\n\tsessions: \"Sessions\",\n\t\"api-keys\": \"API Keys\",\n\twebhooks: \"Webhooks\",\n};\n\n// ---------------------------------------------------------------------------\n// Path builder registry\n// ---------------------------------------------------------------------------\n\ntype PathBuilder = (base: string) => Record<string, OpenApiPathItem>;\n\nconst GROUP_BUILDERS: Record<EndpointGroup, PathBuilder> = {\n\tagents: agentsPaths,\n\tauth: authPaths,\n\toauth: oauthPaths,\n\tmcp: mcpPaths,\n\tadmin: adminPaths,\n\torganizations: organizationsPaths,\n\tsessions: sessionsPaths,\n\t\"api-keys\": apiKeysPaths,\n\twebhooks: webhooksPaths,\n};\n\nconst ALL_GROUPS: EndpointGroup[] = [\n\t\"agents\",\n\t\"auth\",\n\t\"oauth\",\n\t\"mcp\",\n\t\"admin\",\n\t\"organizations\",\n\t\"sessions\",\n\t\"api-keys\",\n\t\"webhooks\",\n];\n\n// ---------------------------------------------------------------------------\n// Factory\n// ---------------------------------------------------------------------------\n\n/**\n * Create an OpenAPI module that generates KavachOS API specifications.\n *\n * The returned module is stateless and safe to share across requests.\n */\nexport function createOpenApiModule(): OpenApiModule {\n\tfunction generateSpec(config: OpenApiConfig = {}): OpenApiDocument {\n\t\tconst title = config.title ?? DEFAULT_TITLE;\n\t\tconst version = config.version ?? DEFAULT_VERSION;\n\t\tconst serverUrl = config.serverUrl ?? DEFAULT_SERVER_URL;\n\t\tconst basePath = config.basePath ?? DEFAULT_BASE_PATH;\n\t\tconst groups = config.include ?? ALL_GROUPS;\n\n\t\t// Build paths from each selected group\n\t\tconst paths: Record<string, OpenApiPathItem> = {};\n\t\tfor (const group of groups) {\n\t\t\tconst builder = GROUP_BUILDERS[group];\n\t\t\tconst groupPaths = builder(basePath);\n\t\t\tfor (const [path, item] of Object.entries(groupPaths)) {\n\t\t\t\tpaths[path] = item;\n\t\t\t}\n\t\t}\n\n\t\t// Build tags — include only those for selected groups\n\t\tconst selectedTagNames = new Set(groups.map((g) => GROUP_TAG_MAP[g]));\n\t\tconst tags = ALL_TAGS.filter((t) => selectedTagNames.has(t.name));\n\n\t\tconst info: OpenApiInfo = {\n\t\t\ttitle,\n\t\t\tversion,\n\t\t\t...(config.description !== undefined ? { description: config.description } : {}),\n\t\t};\n\n\t\treturn {\n\t\t\topenapi: \"3.1.0\",\n\t\t\tinfo,\n\t\t\tservers: [{ url: serverUrl }],\n\t\t\tpaths,\n\t\t\tcomponents: {\n\t\t\t\tsecuritySchemes: {\n\t\t\t\t\tBearerAuth: {\n\t\t\t\t\t\ttype: \"http\",\n\t\t\t\t\t\tscheme: \"bearer\",\n\t\t\t\t\t\tbearerFormat: \"JWT\",\n\t\t\t\t\t\tdescription: \"KavachOS session token or agent token\",\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t\tschemas: {\n\t\t\t\t\tError: ERROR_SCHEMA,\n\t\t\t\t\tErrorResponse: ERROR_RESPONSE_SCHEMA,\n\t\t\t\t},\n\t\t\t},\n\t\t\ttags,\n\t\t};\n\t}\n\n\tfunction handleRequest(request: Request, config?: OpenApiConfig): Response | null {\n\t\tconst url = new URL(request.url);\n\t\tif (!url.pathname.endsWith(\"/openapi.json\")) {\n\t\t\treturn null;\n\t\t}\n\n\t\tconst spec = generateSpec(config);\n\t\treturn new Response(JSON.stringify(spec, null, 2), {\n\t\t\tstatus: 200,\n\t\t\theaders: {\n\t\t\t\t\"Content-Type\": \"application/json\",\n\t\t\t\t\"Cache-Control\": \"public, max-age=3600\",\n\t\t\t},\n\t\t});\n\t}\n\n\treturn { generateSpec, handleRequest };\n}\n","/**\n * Organizations + RBAC module for KavachOS.\n *\n * Provides organization CRUD, membership management, invitation flows,\n * and role-based permission checking. Uses the kavach_organizations,\n * kavach_org_members, kavach_org_invitations, and kavach_org_roles tables.\n */\n\nimport { randomUUID } from \"node:crypto\";\nimport { and, eq } from \"drizzle-orm\";\nimport type { Database } from \"../db/database.js\";\nimport { organizations, orgInvitations, orgMembers, orgRoles } from \"../db/schema.js\";\n\n// ---------------------------------------------------------------------------\n// Public types\n// ---------------------------------------------------------------------------\n\nexport interface OrgConfig {\n\t/** Default roles for new organizations */\n\tdefaultRoles?: OrgRole[];\n\t/** Max members per org (default: 100) */\n\tmaxMembers?: number;\n\t/** Max orgs a user can create (default: 5) */\n\tmaxOrgsPerUser?: number;\n\t/** Allow custom roles (default: true) */\n\tallowCustomRoles?: boolean;\n\t/** Invitation expiry in milliseconds (default: 7 days) */\n\tinvitationExpiryMs?: number;\n\t/** Max pending invitations per org per hour (default: 50) */\n\tmaxInvitationsPerHour?: number;\n}\n\nexport interface Organization {\n\tid: string;\n\tname: string;\n\tslug: string;\n\townerId: string;\n\tmetadata?: Record<string, unknown>;\n\tcreatedAt: Date;\n\tupdatedAt: Date;\n}\n\nexport interface OrgMember {\n\tid: string;\n\torgId: string;\n\tuserId: string;\n\trole: string;\n\tjoinedAt: Date;\n}\n\nexport interface OrgRole {\n\tname: string;\n\tpermissions: string[];\n}\n\nexport interface OrgInvitation {\n\tid: string;\n\torgId: string;\n\temail: string;\n\trole: string;\n\tinvitedBy: string;\n\tstatus: \"pending\" | \"accepted\" | \"expired\";\n\texpiresAt: Date;\n\tcreatedAt: Date;\n}\n\nexport interface OrgModule {\n\tcreate: (input: {\n\t\tname: string;\n\t\tslug: string;\n\t\townerId: string;\n\t\tmetadata?: Record<string, unknown>;\n\t}) => Promise<Organization>;\n\tget: (orgId: string) => Promise<Organization | null>;\n\tgetBySlug: (slug: string) => Promise<Organization | null>;\n\tlist: (userId: string) => Promise<Organization[]>;\n\tupdate: (\n\t\torgId: string,\n\t\tinput: { name?: string; metadata?: Record<string, unknown> },\n\t) => Promise<Organization>;\n\tremove: (orgId: string) => Promise<void>;\n\n\taddMember: (orgId: string, userId: string, role: string) => Promise<OrgMember>;\n\tremoveMember: (orgId: string, userId: string) => Promise<void>;\n\tupdateMemberRole: (orgId: string, userId: string, role: string) => Promise<OrgMember>;\n\tgetMembers: (orgId: string) => Promise<OrgMember[]>;\n\tgetMember: (orgId: string, userId: string) => Promise<OrgMember | null>;\n\n\tinvite: (input: {\n\t\torgId: string;\n\t\temail: string;\n\t\trole: string;\n\t\tinvitedBy: string;\n\t}) => Promise<OrgInvitation>;\n\tacceptInvitation: (invitationId: string, userId: string) => Promise<OrgMember>;\n\tlistInvitations: (orgId: string) => Promise<OrgInvitation[]>;\n\trevokeInvitation: (invitationId: string) => Promise<void>;\n\n\thasPermission: (orgId: string, userId: string, permission: string) => Promise<boolean>;\n\tgetRoles: (orgId: string) => Promise<OrgRole[]>;\n\tcreateRole: (orgId: string, role: OrgRole) => Promise<OrgRole>;\n\tremoveRole: (orgId: string, roleName: string) => Promise<void>;\n\n\ttransferOwnership: (\n\t\torgId: string,\n\t\tcurrentOwnerId: string,\n\t\tnewOwnerId: string,\n\t) => Promise<Organization>;\n\tdeclineInvitation: (invitationId: string) => Promise<void>;\n\n\thandleRequest: (request: Request) => Promise<Response | null>;\n}\n\n// ---------------------------------------------------------------------------\n// Defaults\n// ---------------------------------------------------------------------------\n\nconst DEFAULT_ROLES: OrgRole[] = [\n\t{\n\t\tname: \"owner\",\n\t\tpermissions: [\n\t\t\t\"org:manage\",\n\t\t\t\"org:delete\",\n\t\t\t\"members:invite\",\n\t\t\t\"members:remove\",\n\t\t\t\"members:roles\",\n\t\t\t\"agents:create\",\n\t\t\t\"agents:revoke\",\n\t\t\t\"agents:manage\",\n\t\t\t\"roles:manage\",\n\t\t],\n\t},\n\t{\n\t\tname: \"admin\",\n\t\tpermissions: [\n\t\t\t\"members:invite\",\n\t\t\t\"members:remove\",\n\t\t\t\"agents:create\",\n\t\t\t\"agents:revoke\",\n\t\t\t\"agents:manage\",\n\t\t],\n\t},\n\t{\n\t\tname: \"member\",\n\t\tpermissions: [\"agents:create\", \"agents:manage\"],\n\t},\n\t{\n\t\tname: \"viewer\",\n\t\tpermissions: [],\n\t},\n];\n\nconst DEFAULT_MAX_MEMBERS = 100;\nconst DEFAULT_MAX_ORGS_PER_USER = 5;\nconst INVITATION_EXPIRY_MS = 7 * 24 * 60 * 60 * 1000; // 7 days\nconst DEFAULT_MAX_INVITATIONS_PER_HOUR = 50;\n\n// ---------------------------------------------------------------------------\n// Helpers\n// ---------------------------------------------------------------------------\n\nfunction slugRegex(): RegExp {\n\treturn /^[a-z0-9]+(?:-[a-z0-9]+)*$/;\n}\n\nfunction makeOrgId(): string {\n\treturn `org_${randomUUID().replace(/-/g, \"\")}`;\n}\n\nfunction makeMemberId(): string {\n\treturn `mem_${randomUUID().replace(/-/g, \"\")}`;\n}\n\nfunction makeInvId(): string {\n\treturn `inv_${randomUUID().replace(/-/g, \"\")}`;\n}\n\nfunction makeRoleId(): string {\n\treturn `rol_${randomUUID().replace(/-/g, \"\")}`;\n}\n\nfunction rowToOrg(row: {\n\tid: string;\n\tname: string;\n\tslug: string;\n\townerId: string;\n\tmetadata: Record<string, unknown> | null;\n\tcreatedAt: Date;\n\tupdatedAt: Date;\n}): Organization {\n\treturn {\n\t\tid: row.id,\n\t\tname: row.name,\n\t\tslug: row.slug,\n\t\townerId: row.ownerId,\n\t\tmetadata: row.metadata ?? undefined,\n\t\tcreatedAt: row.createdAt,\n\t\tupdatedAt: row.updatedAt,\n\t};\n}\n\nfunction rowToMember(row: {\n\tid: string;\n\torgId: string;\n\tuserId: string;\n\trole: string;\n\tjoinedAt: Date;\n}): OrgMember {\n\treturn {\n\t\tid: row.id,\n\t\torgId: row.orgId,\n\t\tuserId: row.userId,\n\t\trole: row.role,\n\t\tjoinedAt: row.joinedAt,\n\t};\n}\n\nfunction rowToInvitation(row: {\n\tid: string;\n\torgId: string;\n\temail: string;\n\trole: string;\n\tinvitedBy: string;\n\tstatus: string;\n\texpiresAt: Date;\n\tcreatedAt: Date;\n}): OrgInvitation {\n\treturn {\n\t\tid: row.id,\n\t\torgId: row.orgId,\n\t\temail: row.email,\n\t\trole: row.role,\n\t\tinvitedBy: row.invitedBy,\n\t\tstatus: row.status as OrgInvitation[\"status\"],\n\t\texpiresAt: row.expiresAt,\n\t\tcreatedAt: row.createdAt,\n\t};\n}\n\nfunction jsonResponse(body: unknown, status = 200): Response {\n\treturn new Response(JSON.stringify(body), {\n\t\tstatus,\n\t\theaders: { \"Content-Type\": \"application/json\" },\n\t});\n}\n\nfunction errorResponse(message: string, status: number): Response {\n\treturn jsonResponse({ error: message }, status);\n}\n\n// ---------------------------------------------------------------------------\n// Factory\n// ---------------------------------------------------------------------------\n\nexport function createOrgModule(config: OrgConfig, db: Database): OrgModule {\n\tconst maxMembers = config.maxMembers ?? DEFAULT_MAX_MEMBERS;\n\tconst maxOrgsPerUser = config.maxOrgsPerUser ?? DEFAULT_MAX_ORGS_PER_USER;\n\tconst allowCustomRoles = config.allowCustomRoles ?? true;\n\tconst defaultRoles = config.defaultRoles ?? DEFAULT_ROLES;\n\tconst invitationExpiryMs = config.invitationExpiryMs ?? INVITATION_EXPIRY_MS;\n\tconst maxInvitationsPerHour = config.maxInvitationsPerHour ?? DEFAULT_MAX_INVITATIONS_PER_HOUR;\n\n\t// ── org CRUD ─────────────────────────────────────────────────────────────\n\n\tasync function create(input: {\n\t\tname: string;\n\t\tslug: string;\n\t\townerId: string;\n\t\tmetadata?: Record<string, unknown>;\n\t}): Promise<Organization> {\n\t\tif (!slugRegex().test(input.slug)) {\n\t\t\tthrow new Error(\n\t\t\t\t`Invalid slug \"${input.slug}\". Use lowercase letters, numbers, and hyphens only.`,\n\t\t\t);\n\t\t}\n\n\t\t// Enforce maxOrgsPerUser\n\t\tconst existing = await db\n\t\t\t.select({ id: organizations.id })\n\t\t\t.from(organizations)\n\t\t\t.where(eq(organizations.ownerId, input.ownerId));\n\t\tif (existing.length >= maxOrgsPerUser) {\n\t\t\tthrow new Error(\n\t\t\t\t`User \"${input.ownerId}\" has reached the maximum of ${maxOrgsPerUser} organizations.`,\n\t\t\t);\n\t\t}\n\n\t\t// Slug uniqueness\n\t\tconst slugConflict = await db\n\t\t\t.select({ id: organizations.id })\n\t\t\t.from(organizations)\n\t\t\t.where(eq(organizations.slug, input.slug))\n\t\t\t.limit(1);\n\t\tif (slugConflict.length > 0) {\n\t\t\tthrow new Error(`Organization with slug \"${input.slug}\" already exists.`);\n\t\t}\n\n\t\tconst id = makeOrgId();\n\t\tconst now = new Date();\n\n\t\tawait db.insert(organizations).values({\n\t\t\tid,\n\t\t\tname: input.name,\n\t\t\tslug: input.slug,\n\t\t\townerId: input.ownerId,\n\t\t\tmetadata: input.metadata ?? null,\n\t\t\tcreatedAt: now,\n\t\t\tupdatedAt: now,\n\t\t});\n\n\t\t// Add owner as member with \"owner\" role\n\t\tawait db.insert(orgMembers).values({\n\t\t\tid: makeMemberId(),\n\t\t\torgId: id,\n\t\t\tuserId: input.ownerId,\n\t\t\trole: \"owner\",\n\t\t\tjoinedAt: now,\n\t\t});\n\n\t\t// Seed default roles\n\t\tfor (const role of defaultRoles) {\n\t\t\tawait db.insert(orgRoles).values({\n\t\t\t\tid: makeRoleId(),\n\t\t\t\torgId: id,\n\t\t\t\tname: role.name,\n\t\t\t\tpermissions: role.permissions,\n\t\t\t});\n\t\t}\n\n\t\treturn {\n\t\t\tid,\n\t\t\tname: input.name,\n\t\t\tslug: input.slug,\n\t\t\townerId: input.ownerId,\n\t\t\tmetadata: input.metadata,\n\t\t\tcreatedAt: now,\n\t\t\tupdatedAt: now,\n\t\t};\n\t}\n\n\tasync function get(orgId: string): Promise<Organization | null> {\n\t\tconst rows = await db.select().from(organizations).where(eq(organizations.id, orgId)).limit(1);\n\t\tconst row = rows[0];\n\t\tif (!row) return null;\n\t\treturn rowToOrg(row);\n\t}\n\n\tasync function getBySlug(slug: string): Promise<Organization | null> {\n\t\tconst rows = await db.select().from(organizations).where(eq(organizations.slug, slug)).limit(1);\n\t\tconst row = rows[0];\n\t\tif (!row) return null;\n\t\treturn rowToOrg(row);\n\t}\n\n\tasync function list(userId: string): Promise<Organization[]> {\n\t\t// Get all orgs the user is a member of\n\t\tconst memberRows = await db\n\t\t\t.select({ orgId: orgMembers.orgId })\n\t\t\t.from(orgMembers)\n\t\t\t.where(eq(orgMembers.userId, userId));\n\n\t\tif (memberRows.length === 0) return [];\n\n\t\tconst orgIds = memberRows.map((r) => r.orgId);\n\t\tconst allOrgs = await db.select().from(organizations);\n\t\treturn allOrgs.filter((org) => orgIds.includes(org.id)).map(rowToOrg);\n\t}\n\n\tasync function update(\n\t\torgId: string,\n\t\tinput: { name?: string; metadata?: Record<string, unknown> },\n\t): Promise<Organization> {\n\t\tconst existing = await get(orgId);\n\t\tif (!existing) throw new Error(`Organization \"${orgId}\" not found.`);\n\n\t\tconst now = new Date();\n\t\tawait db\n\t\t\t.update(organizations)\n\t\t\t.set({\n\t\t\t\tname: input.name ?? existing.name,\n\t\t\t\tmetadata:\n\t\t\t\t\tinput.metadata !== undefined\n\t\t\t\t\t\t? { ...(existing.metadata ?? {}), ...input.metadata }\n\t\t\t\t\t\t: (existing.metadata ?? null),\n\t\t\t\tupdatedAt: now,\n\t\t\t})\n\t\t\t.where(eq(organizations.id, orgId));\n\n\t\tconst updated = await get(orgId);\n\t\tif (!updated) throw new Error(`Organization \"${orgId}\" disappeared after update.`);\n\t\treturn updated;\n\t}\n\n\tasync function remove(orgId: string): Promise<void> {\n\t\tconst existing = await get(orgId);\n\t\tif (!existing) throw new Error(`Organization \"${orgId}\" not found.`);\n\t\t// Explicit cascade: remove members, invitations, and roles before the org\n\t\t// (FK ON DELETE CASCADE may not be enabled in all SQLite configs)\n\t\tawait db.delete(orgMembers).where(eq(orgMembers.orgId, orgId));\n\t\tawait db.delete(orgInvitations).where(eq(orgInvitations.orgId, orgId));\n\t\tawait db.delete(orgRoles).where(eq(orgRoles.orgId, orgId));\n\t\tawait db.delete(organizations).where(eq(organizations.id, orgId));\n\t}\n\n\t// ── members ──────────────────────────────────────────────────────────────\n\n\tasync function addMember(orgId: string, userId: string, role: string): Promise<OrgMember> {\n\t\tconst org = await get(orgId);\n\t\tif (!org) throw new Error(`Organization \"${orgId}\" not found.`);\n\n\t\t// Validate role exists\n\t\tconst roleRows = await db\n\t\t\t.select()\n\t\t\t.from(orgRoles)\n\t\t\t.where(and(eq(orgRoles.orgId, orgId), eq(orgRoles.name, role)))\n\t\t\t.limit(1);\n\t\tif (roleRows.length === 0) throw new Error(`Role \"${role}\" does not exist in org \"${orgId}\".`);\n\n\t\t// Check member cap\n\t\tconst currentMembers = await db\n\t\t\t.select({ id: orgMembers.id })\n\t\t\t.from(orgMembers)\n\t\t\t.where(eq(orgMembers.orgId, orgId));\n\t\tif (currentMembers.length >= maxMembers) {\n\t\t\tthrow new Error(`Organization \"${orgId}\" has reached the maximum of ${maxMembers} members.`);\n\t\t}\n\n\t\t// Check already a member\n\t\tconst already = await db\n\t\t\t.select()\n\t\t\t.from(orgMembers)\n\t\t\t.where(and(eq(orgMembers.orgId, orgId), eq(orgMembers.userId, userId)))\n\t\t\t.limit(1);\n\t\tif (already.length > 0) {\n\t\t\tthrow new Error(`User \"${userId}\" is already a member of org \"${orgId}\".`);\n\t\t}\n\n\t\tconst id = makeMemberId();\n\t\tconst joinedAt = new Date();\n\n\t\tawait db.insert(orgMembers).values({ id, orgId, userId, role, joinedAt });\n\n\t\treturn { id, orgId, userId, role, joinedAt };\n\t}\n\n\tasync function removeMember(orgId: string, userId: string): Promise<void> {\n\t\t// Prevent removing the last owner (would lock out the org)\n\t\tconst member = await getMember(orgId, userId);\n\t\tif (member?.role === \"owner\") {\n\t\t\tconst owners = await db\n\t\t\t\t.select({ id: orgMembers.id })\n\t\t\t\t.from(orgMembers)\n\t\t\t\t.where(and(eq(orgMembers.orgId, orgId), eq(orgMembers.role, \"owner\")));\n\t\t\tif (owners.length <= 1) {\n\t\t\t\tthrow new Error(\n\t\t\t\t\t`Cannot remove the last owner of org \"${orgId}\". Transfer ownership first.`,\n\t\t\t\t);\n\t\t\t}\n\t\t}\n\n\t\tawait db\n\t\t\t.delete(orgMembers)\n\t\t\t.where(and(eq(orgMembers.orgId, orgId), eq(orgMembers.userId, userId)));\n\t}\n\n\tasync function updateMemberRole(orgId: string, userId: string, role: string): Promise<OrgMember> {\n\t\t// Validate role exists\n\t\tconst roleRows = await db\n\t\t\t.select()\n\t\t\t.from(orgRoles)\n\t\t\t.where(and(eq(orgRoles.orgId, orgId), eq(orgRoles.name, role)))\n\t\t\t.limit(1);\n\t\tif (roleRows.length === 0) throw new Error(`Role \"${role}\" does not exist in org \"${orgId}\".`);\n\n\t\t// Prevent demoting the last owner\n\t\tif (role !== \"owner\") {\n\t\t\tconst currentMember = await getMember(orgId, userId);\n\t\t\tif (currentMember?.role === \"owner\") {\n\t\t\t\tconst owners = await db\n\t\t\t\t\t.select({ id: orgMembers.id })\n\t\t\t\t\t.from(orgMembers)\n\t\t\t\t\t.where(and(eq(orgMembers.orgId, orgId), eq(orgMembers.role, \"owner\")));\n\t\t\t\tif (owners.length <= 1) {\n\t\t\t\t\tthrow new Error(\n\t\t\t\t\t\t`Cannot demote the last owner of org \"${orgId}\". Transfer ownership first.`,\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tawait db\n\t\t\t.update(orgMembers)\n\t\t\t.set({ role })\n\t\t\t.where(and(eq(orgMembers.orgId, orgId), eq(orgMembers.userId, userId)));\n\n\t\tconst member = await getMember(orgId, userId);\n\t\tif (!member) throw new Error(`Member \"${userId}\" not found in org \"${orgId}\".`);\n\t\treturn member;\n\t}\n\n\tasync function getMembers(orgId: string): Promise<OrgMember[]> {\n\t\tconst rows = await db.select().from(orgMembers).where(eq(orgMembers.orgId, orgId));\n\t\treturn rows.map(rowToMember);\n\t}\n\n\tasync function getMember(orgId: string, userId: string): Promise<OrgMember | null> {\n\t\tconst rows = await db\n\t\t\t.select()\n\t\t\t.from(orgMembers)\n\t\t\t.where(and(eq(orgMembers.orgId, orgId), eq(orgMembers.userId, userId)))\n\t\t\t.limit(1);\n\t\tconst row = rows[0];\n\t\tif (!row) return null;\n\t\treturn rowToMember(row);\n\t}\n\n\t// ── invitations ──────────────────────────────────────────────────────────\n\n\tasync function invite(input: {\n\t\torgId: string;\n\t\temail: string;\n\t\trole: string;\n\t\tinvitedBy: string;\n\t}): Promise<OrgInvitation> {\n\t\tconst org = await get(input.orgId);\n\t\tif (!org) throw new Error(`Organization \"${input.orgId}\" not found.`);\n\n\t\t// Validate role exists\n\t\tconst roleRows = await db\n\t\t\t.select()\n\t\t\t.from(orgRoles)\n\t\t\t.where(and(eq(orgRoles.orgId, input.orgId), eq(orgRoles.name, input.role)))\n\t\t\t.limit(1);\n\t\tif (roleRows.length === 0) {\n\t\t\tthrow new Error(`Role \"${input.role}\" does not exist in org \"${input.orgId}\".`);\n\t\t}\n\n\t\t// Reject duplicate pending invitation for the same email in this org\n\t\tconst duplicateInvite = await db\n\t\t\t.select({ id: orgInvitations.id })\n\t\t\t.from(orgInvitations)\n\t\t\t.where(\n\t\t\t\tand(\n\t\t\t\t\teq(orgInvitations.orgId, input.orgId),\n\t\t\t\t\teq(orgInvitations.email, input.email),\n\t\t\t\t\teq(orgInvitations.status, \"pending\"),\n\t\t\t\t),\n\t\t\t)\n\t\t\t.limit(1);\n\t\tif (duplicateInvite.length > 0) {\n\t\t\tthrow new Error(\n\t\t\t\t`A pending invitation for \"${input.email}\" already exists in org \"${input.orgId}\".`,\n\t\t\t);\n\t\t}\n\n\t\t// Rate limit: max invitations per hour per org\n\t\tconst oneHourAgo = new Date(Date.now() - 60 * 60 * 1000);\n\t\tconst allOrgInvites = await db\n\t\t\t.select({ id: orgInvitations.id, createdAt: orgInvitations.createdAt })\n\t\t\t.from(orgInvitations)\n\t\t\t.where(eq(orgInvitations.orgId, input.orgId));\n\t\tconst recentInviteCount = allOrgInvites.filter((inv) => inv.createdAt >= oneHourAgo).length;\n\t\tif (recentInviteCount >= maxInvitationsPerHour) {\n\t\t\tthrow new Error(\n\t\t\t\t`Invitation rate limit reached for org \"${input.orgId}\". Max ${maxInvitationsPerHour} per hour.`,\n\t\t\t);\n\t\t}\n\n\t\tconst id = makeInvId();\n\t\tconst now = new Date();\n\t\tconst expiresAt = new Date(now.getTime() + invitationExpiryMs);\n\n\t\tawait db.insert(orgInvitations).values({\n\t\t\tid,\n\t\t\torgId: input.orgId,\n\t\t\temail: input.email,\n\t\t\trole: input.role,\n\t\t\tinvitedBy: input.invitedBy,\n\t\t\tstatus: \"pending\",\n\t\t\texpiresAt,\n\t\t\tcreatedAt: now,\n\t\t});\n\n\t\treturn {\n\t\t\tid,\n\t\t\torgId: input.orgId,\n\t\t\temail: input.email,\n\t\t\trole: input.role,\n\t\t\tinvitedBy: input.invitedBy,\n\t\t\tstatus: \"pending\",\n\t\t\texpiresAt,\n\t\t\tcreatedAt: now,\n\t\t};\n\t}\n\n\tasync function acceptInvitation(invitationId: string, userId: string): Promise<OrgMember> {\n\t\tconst rows = await db\n\t\t\t.select()\n\t\t\t.from(orgInvitations)\n\t\t\t.where(eq(orgInvitations.id, invitationId))\n\t\t\t.limit(1);\n\t\tconst inv = rows[0];\n\t\tif (!inv) throw new Error(`Invitation \"${invitationId}\" not found.`);\n\n\t\tif (inv.status !== \"pending\") {\n\t\t\tthrow new Error(`Invitation \"${invitationId}\" is not pending (status: ${inv.status}).`);\n\t\t}\n\n\t\tconst now = new Date();\n\t\tif (inv.expiresAt < now) {\n\t\t\t// Mark expired in DB\n\t\t\tawait db\n\t\t\t\t.update(orgInvitations)\n\t\t\t\t.set({ status: \"expired\" })\n\t\t\t\t.where(eq(orgInvitations.id, invitationId));\n\t\t\tthrow new Error(`Invitation \"${invitationId}\" has expired.`);\n\t\t}\n\n\t\t// Add member (will throw if already a member or cap hit)\n\t\tconst member = await addMember(inv.orgId, userId, inv.role);\n\n\t\t// Mark accepted\n\t\tawait db\n\t\t\t.update(orgInvitations)\n\t\t\t.set({ status: \"accepted\" })\n\t\t\t.where(eq(orgInvitations.id, invitationId));\n\n\t\treturn member;\n\t}\n\n\tasync function listInvitations(orgId: string): Promise<OrgInvitation[]> {\n\t\tconst rows = await db.select().from(orgInvitations).where(eq(orgInvitations.orgId, orgId));\n\t\treturn rows.map(rowToInvitation);\n\t}\n\n\tasync function revokeInvitation(invitationId: string): Promise<void> {\n\t\tawait db.delete(orgInvitations).where(eq(orgInvitations.id, invitationId));\n\t}\n\n\t// ── roles & permissions ──────────────────────────────────────────────────\n\n\tasync function hasPermission(\n\t\torgId: string,\n\t\tuserId: string,\n\t\tpermission: string,\n\t): Promise<boolean> {\n\t\tconst member = await getMember(orgId, userId);\n\t\tif (!member) return false;\n\n\t\t// Owner has all permissions\n\t\tif (member.role === \"owner\") return true;\n\n\t\t// Look up role permissions\n\t\tconst roleRows = await db\n\t\t\t.select()\n\t\t\t.from(orgRoles)\n\t\t\t.where(and(eq(orgRoles.orgId, orgId), eq(orgRoles.name, member.role)))\n\t\t\t.limit(1);\n\t\tconst roleRow = roleRows[0];\n\t\tif (!roleRow) return false;\n\n\t\treturn (roleRow.permissions as string[]).includes(permission);\n\t}\n\n\tasync function getRoles(orgId: string): Promise<OrgRole[]> {\n\t\tconst rows = await db.select().from(orgRoles).where(eq(orgRoles.orgId, orgId));\n\t\treturn rows.map((r) => ({\n\t\t\tname: r.name,\n\t\t\tpermissions: r.permissions as string[],\n\t\t}));\n\t}\n\n\tasync function createRole(orgId: string, role: OrgRole): Promise<OrgRole> {\n\t\tif (!allowCustomRoles) {\n\t\t\tthrow new Error(\"Custom roles are not allowed in this configuration.\");\n\t\t}\n\n\t\tconst org = await get(orgId);\n\t\tif (!org) throw new Error(`Organization \"${orgId}\" not found.`);\n\n\t\t// Check for duplicate\n\t\tconst existing = await db\n\t\t\t.select({ id: orgRoles.id })\n\t\t\t.from(orgRoles)\n\t\t\t.where(and(eq(orgRoles.orgId, orgId), eq(orgRoles.name, role.name)))\n\t\t\t.limit(1);\n\t\tif (existing.length > 0) {\n\t\t\tthrow new Error(`Role \"${role.name}\" already exists in org \"${orgId}\".`);\n\t\t}\n\n\t\tawait db.insert(orgRoles).values({\n\t\t\tid: makeRoleId(),\n\t\t\torgId,\n\t\t\tname: role.name,\n\t\t\tpermissions: role.permissions,\n\t\t});\n\n\t\treturn role;\n\t}\n\n\tasync function removeRole(orgId: string, roleName: string): Promise<void> {\n\t\tawait db.delete(orgRoles).where(and(eq(orgRoles.orgId, orgId), eq(orgRoles.name, roleName)));\n\t}\n\n\t// ── ownership transfer ──────────────────────────────────────────────────\n\n\tasync function transferOwnership(\n\t\torgId: string,\n\t\tcurrentOwnerId: string,\n\t\tnewOwnerId: string,\n\t): Promise<Organization> {\n\t\tconst org = await get(orgId);\n\t\tif (!org) throw new Error(`Organization \"${orgId}\" not found.`);\n\n\t\tif (org.ownerId !== currentOwnerId) {\n\t\t\tthrow new Error(`User \"${currentOwnerId}\" is not the owner of org \"${orgId}\".`);\n\t\t}\n\n\t\t// New owner must be a member\n\t\tconst newOwnerMember = await getMember(orgId, newOwnerId);\n\t\tif (!newOwnerMember) {\n\t\t\tthrow new Error(`User \"${newOwnerId}\" is not a member of org \"${orgId}\".`);\n\t\t}\n\n\t\t// Update org owner\n\t\tconst now = new Date();\n\t\tawait db\n\t\t\t.update(organizations)\n\t\t\t.set({ ownerId: newOwnerId, updatedAt: now })\n\t\t\t.where(eq(organizations.id, orgId));\n\n\t\t// Promote new owner to \"owner\" role\n\t\tawait db\n\t\t\t.update(orgMembers)\n\t\t\t.set({ role: \"owner\" })\n\t\t\t.where(and(eq(orgMembers.orgId, orgId), eq(orgMembers.userId, newOwnerId)));\n\n\t\t// Demote current owner to \"admin\" (they stay as a member)\n\t\tawait db\n\t\t\t.update(orgMembers)\n\t\t\t.set({ role: \"admin\" })\n\t\t\t.where(and(eq(orgMembers.orgId, orgId), eq(orgMembers.userId, currentOwnerId)));\n\n\t\tconst updated = await get(orgId);\n\t\tif (!updated) throw new Error(`Organization \"${orgId}\" disappeared after ownership transfer.`);\n\t\treturn updated;\n\t}\n\n\t// ── decline invitation ──────────────────────────────────────────────────\n\n\tasync function declineInvitation(invitationId: string): Promise<void> {\n\t\tconst rows = await db\n\t\t\t.select()\n\t\t\t.from(orgInvitations)\n\t\t\t.where(eq(orgInvitations.id, invitationId))\n\t\t\t.limit(1);\n\t\tconst inv = rows[0];\n\t\tif (!inv) throw new Error(`Invitation \"${invitationId}\" not found.`);\n\t\tif (inv.status !== \"pending\") {\n\t\t\tthrow new Error(`Invitation \"${invitationId}\" is not pending (status: ${inv.status}).`);\n\t\t}\n\t\t// Delete the invitation (one-time use: no need to keep declined invitations)\n\t\tawait db.delete(orgInvitations).where(eq(orgInvitations.id, invitationId));\n\t}\n\n\t// ── HTTP handler ─────────────────────────────────────────────────────────\n\n\tasync function handleRequest(request: Request): Promise<Response | null> {\n\t\tconst url = new URL(request.url);\n\t\tconst { pathname } = url;\n\t\tconst method = request.method.toUpperCase();\n\n\t\t// POST /auth/org\n\t\tif (method === \"POST\" && pathname === \"/auth/org\") {\n\t\t\ttry {\n\t\t\t\tconst body = (await request.json()) as {\n\t\t\t\t\tname: string;\n\t\t\t\t\tslug: string;\n\t\t\t\t\townerId: string;\n\t\t\t\t\tmetadata?: Record<string, unknown>;\n\t\t\t\t};\n\t\t\t\tconst org = await create(body);\n\t\t\t\treturn jsonResponse(org, 201);\n\t\t\t} catch (err) {\n\t\t\t\treturn errorResponse(err instanceof Error ? err.message : \"Unknown error\", 400);\n\t\t\t}\n\t\t}\n\n\t\t// GET /auth/org/user/:userId\n\t\tconst userOrgMatch = pathname.match(/^\\/auth\\/org\\/user\\/([^/]+)$/);\n\t\tif (method === \"GET\" && userOrgMatch) {\n\t\t\tconst userId = userOrgMatch[1];\n\t\t\tif (!userId) return errorResponse(\"Missing userId\", 400);\n\t\t\tconst orgs = await list(userId);\n\t\t\treturn jsonResponse(orgs);\n\t\t}\n\n\t\t// Routes with orgId: /auth/org/:orgId or /auth/org/:orgId/...\n\t\tconst orgBaseMatch = pathname.match(/^\\/auth\\/org\\/([^/]+)(\\/.*)?$/);\n\t\tif (!orgBaseMatch) return null;\n\n\t\tconst orgId = orgBaseMatch[1];\n\t\tif (!orgId) return null;\n\n\t\tconst subPath = orgBaseMatch[2] ?? \"\";\n\n\t\t// GET /auth/org/:orgId\n\t\tif (method === \"GET\" && subPath === \"\") {\n\t\t\tconst org = await get(orgId);\n\t\t\tif (!org) return errorResponse(\"Organization not found\", 404);\n\t\t\treturn jsonResponse(org);\n\t\t}\n\n\t\t// PATCH /auth/org/:orgId\n\t\tif (method === \"PATCH\" && subPath === \"\") {\n\t\t\ttry {\n\t\t\t\tconst body = (await request.json()) as {\n\t\t\t\t\tname?: string;\n\t\t\t\t\tmetadata?: Record<string, unknown>;\n\t\t\t\t};\n\t\t\t\tconst org = await update(orgId, body);\n\t\t\t\treturn jsonResponse(org);\n\t\t\t} catch (err) {\n\t\t\t\treturn errorResponse(err instanceof Error ? err.message : \"Unknown error\", 400);\n\t\t\t}\n\t\t}\n\n\t\t// DELETE /auth/org/:orgId\n\t\tif (method === \"DELETE\" && subPath === \"\") {\n\t\t\ttry {\n\t\t\t\tawait remove(orgId);\n\t\t\t\treturn jsonResponse({ success: true });\n\t\t\t} catch (err) {\n\t\t\t\treturn errorResponse(err instanceof Error ? err.message : \"Unknown error\", 400);\n\t\t\t}\n\t\t}\n\n\t\t// POST /auth/org/:orgId/members\n\t\tif (method === \"POST\" && subPath === \"/members\") {\n\t\t\ttry {\n\t\t\t\tconst body = (await request.json()) as { userId: string; role: string };\n\t\t\t\tconst member = await addMember(orgId, body.userId, body.role);\n\t\t\t\treturn jsonResponse(member, 201);\n\t\t\t} catch (err) {\n\t\t\t\treturn errorResponse(err instanceof Error ? err.message : \"Unknown error\", 400);\n\t\t\t}\n\t\t}\n\n\t\t// GET /auth/org/:orgId/members\n\t\tif (method === \"GET\" && subPath === \"/members\") {\n\t\t\tconst members = await getMembers(orgId);\n\t\t\treturn jsonResponse(members);\n\t\t}\n\n\t\t// PATCH /auth/org/:orgId/members/:userId\n\t\tconst memberMatch = subPath.match(/^\\/members\\/([^/]+)$/);\n\t\tif (method === \"PATCH\" && memberMatch) {\n\t\t\tconst userId = memberMatch[1];\n\t\t\tif (!userId) return errorResponse(\"Missing userId\", 400);\n\t\t\ttry {\n\t\t\t\tconst body = (await request.json()) as { role: string };\n\t\t\t\tconst member = await updateMemberRole(orgId, userId, body.role);\n\t\t\t\treturn jsonResponse(member);\n\t\t\t} catch (err) {\n\t\t\t\treturn errorResponse(err instanceof Error ? err.message : \"Unknown error\", 400);\n\t\t\t}\n\t\t}\n\n\t\t// DELETE /auth/org/:orgId/members/:userId\n\t\tif (method === \"DELETE\" && memberMatch) {\n\t\t\tconst userId = memberMatch[1];\n\t\t\tif (!userId) return errorResponse(\"Missing userId\", 400);\n\t\t\tawait removeMember(orgId, userId);\n\t\t\treturn jsonResponse({ success: true });\n\t\t}\n\n\t\t// POST /auth/org/:orgId/invite\n\t\tif (method === \"POST\" && subPath === \"/invite\") {\n\t\t\ttry {\n\t\t\t\tconst body = (await request.json()) as {\n\t\t\t\t\temail: string;\n\t\t\t\t\trole: string;\n\t\t\t\t\tinvitedBy: string;\n\t\t\t\t};\n\t\t\t\tconst invitation = await invite({ orgId, ...body });\n\t\t\t\treturn jsonResponse(invitation, 201);\n\t\t\t} catch (err) {\n\t\t\t\treturn errorResponse(err instanceof Error ? err.message : \"Unknown error\", 400);\n\t\t\t}\n\t\t}\n\n\t\t// GET /auth/org/:orgId/invitations\n\t\tif (method === \"GET\" && subPath === \"/invitations\") {\n\t\t\tconst invitations = await listInvitations(orgId);\n\t\t\treturn jsonResponse(invitations);\n\t\t}\n\n\t\t// GET /auth/org/:orgId/permissions/:userId/:permission\n\t\tconst permMatch = subPath.match(/^\\/permissions\\/([^/]+)\\/([^/]+)$/);\n\t\tif (method === \"GET\" && permMatch) {\n\t\t\tconst userId = permMatch[1];\n\t\t\tconst permission = permMatch[2];\n\t\t\tif (!userId || !permission) return errorResponse(\"Missing userId or permission\", 400);\n\t\t\tconst allowed = await hasPermission(orgId, userId, permission);\n\t\t\treturn jsonResponse({ allowed });\n\t\t}\n\n\t\t// POST /auth/org/:orgId/roles\n\t\tif (method === \"POST\" && subPath === \"/roles\") {\n\t\t\ttry {\n\t\t\t\tconst body = (await request.json()) as OrgRole;\n\t\t\t\tconst role = await createRole(orgId, body);\n\t\t\t\treturn jsonResponse(role, 201);\n\t\t\t} catch (err) {\n\t\t\t\treturn errorResponse(err instanceof Error ? err.message : \"Unknown error\", 400);\n\t\t\t}\n\t\t}\n\n\t\t// GET /auth/org/:orgId/roles\n\t\tif (method === \"GET\" && subPath === \"/roles\") {\n\t\t\tconst roles = await getRoles(orgId);\n\t\t\treturn jsonResponse(roles);\n\t\t}\n\n\t\treturn null;\n\t}\n\n\t// POST /auth/org/invite/:invitationId/accept and DELETE /auth/org/invite/:invitationId\n\t// are matched inside handleRequest via a secondary pass when orgId catches \"invite\"\n\t// We need a top-level check before the orgId route for invite-specific paths.\n\n\tasync function handleRequestWithInviteRoutes(request: Request): Promise<Response | null> {\n\t\tconst url = new URL(request.url);\n\t\tconst { pathname } = url;\n\t\tconst method = request.method.toUpperCase();\n\n\t\t// POST /auth/org/invite/:invitationId/accept\n\t\tconst acceptMatch = pathname.match(/^\\/auth\\/org\\/invite\\/([^/]+)\\/accept$/);\n\t\tif (method === \"POST\" && acceptMatch) {\n\t\t\tconst invitationId = acceptMatch[1];\n\t\t\tif (!invitationId) return errorResponse(\"Missing invitationId\", 400);\n\t\t\ttry {\n\t\t\t\tconst body = (await request.json()) as { userId: string };\n\t\t\t\tconst member = await acceptInvitation(invitationId, body.userId);\n\t\t\t\treturn jsonResponse(member, 201);\n\t\t\t} catch (err) {\n\t\t\t\treturn errorResponse(err instanceof Error ? err.message : \"Unknown error\", 400);\n\t\t\t}\n\t\t}\n\n\t\t// DELETE /auth/org/invite/:invitationId\n\t\tconst revokeMatch = pathname.match(/^\\/auth\\/org\\/invite\\/([^/]+)$/);\n\t\tif (method === \"DELETE\" && revokeMatch) {\n\t\t\tconst invitationId = revokeMatch[1];\n\t\t\tif (!invitationId) return errorResponse(\"Missing invitationId\", 400);\n\t\t\tawait revokeInvitation(invitationId);\n\t\t\treturn jsonResponse({ success: true });\n\t\t}\n\n\t\treturn handleRequest(request);\n\t}\n\n\treturn {\n\t\tcreate,\n\t\tget,\n\t\tgetBySlug,\n\t\tlist,\n\t\tupdate,\n\t\tremove,\n\t\taddMember,\n\t\tremoveMember,\n\t\tupdateMemberRole,\n\t\tgetMembers,\n\t\tgetMember,\n\t\tinvite,\n\t\tacceptInvitation,\n\t\tlistInvitations,\n\t\trevokeInvitation,\n\t\thasPermission,\n\t\tgetRoles,\n\t\tcreateRole,\n\t\tremoveRole,\n\t\ttransferOwnership,\n\t\tdeclineInvitation,\n\t\thandleRequest: handleRequestWithInviteRoutes,\n\t};\n}\n","import type { KavachPlugin } from \"../plugin/types.js\";\nimport type { OrgConfig } from \"./organization.js\";\nimport { createOrgModule } from \"./organization.js\";\n\nexport type { OrgConfig };\n\n// ---------------------------------------------------------------------------\n// Helpers\n// ---------------------------------------------------------------------------\n\nfunction jsonResponse(body: unknown, status = 200): Response {\n\treturn new Response(JSON.stringify(body), {\n\t\tstatus,\n\t\theaders: { \"Content-Type\": \"application/json\" },\n\t});\n}\n\nasync function parseBody(request: Request): Promise<Record<string, unknown>> {\n\ttry {\n\t\treturn (await request.json()) as Record<string, unknown>;\n\t} catch {\n\t\treturn {};\n\t}\n}\n\n// Admin roles that can perform privileged member management actions.\nconst ADMIN_ROLES = new Set([\"owner\", \"admin\"]);\n\n// ---------------------------------------------------------------------------\n// Plugin factory\n// ---------------------------------------------------------------------------\n\nexport function organization(config?: OrgConfig): KavachPlugin {\n\treturn {\n\t\tid: \"kavach-organization\",\n\n\t\tasync init(ctx): Promise<undefined> {\n\t\t\tconst module = createOrgModule(config ?? {}, ctx.db);\n\n\t\t\t// POST /auth/org/create\n\t\t\t// Creates a new organization. The authenticated user becomes owner.\n\t\t\tctx.addEndpoint({\n\t\t\t\tmethod: \"POST\",\n\t\t\t\tpath: \"/auth/org/create\",\n\t\t\t\tmetadata: {\n\t\t\t\t\trequireAuth: true,\n\t\t\t\t\tdescription: \"Create a new organization owned by the authenticated user\",\n\t\t\t\t},\n\t\t\t\tasync handler(request, endpointCtx) {\n\t\t\t\t\tconst user = await endpointCtx.getUser(request);\n\t\t\t\t\tif (!user) {\n\t\t\t\t\t\treturn jsonResponse({ error: \"Authentication required\" }, 401);\n\t\t\t\t\t}\n\n\t\t\t\t\tconst body = await parseBody(request);\n\t\t\t\t\tconst name = typeof body.name === \"string\" ? body.name.trim() : null;\n\t\t\t\t\tconst slug = typeof body.slug === \"string\" ? body.slug.trim() : null;\n\n\t\t\t\t\tif (!name || !slug) {\n\t\t\t\t\t\treturn jsonResponse({ error: \"Missing required fields: name, slug\" }, 400);\n\t\t\t\t\t}\n\n\t\t\t\t\tconst metadata =\n\t\t\t\t\t\tbody.metadata !== undefined &&\n\t\t\t\t\t\ttypeof body.metadata === \"object\" &&\n\t\t\t\t\t\tbody.metadata !== null\n\t\t\t\t\t\t\t? (body.metadata as Record<string, unknown>)\n\t\t\t\t\t\t\t: undefined;\n\n\t\t\t\t\ttry {\n\t\t\t\t\t\tconst org = await module.create({ name, slug, ownerId: user.id, metadata });\n\t\t\t\t\t\treturn jsonResponse(org, 201);\n\t\t\t\t\t} catch (err) {\n\t\t\t\t\t\treturn jsonResponse(\n\t\t\t\t\t\t\t{ error: err instanceof Error ? err.message : \"Failed to create organization\" },\n\t\t\t\t\t\t\t400,\n\t\t\t\t\t\t);\n\t\t\t\t\t}\n\t\t\t\t},\n\t\t\t});\n\n\t\t\t// GET /auth/org/list\n\t\t\t// Returns all organizations the authenticated user is a member of.\n\t\t\tctx.addEndpoint({\n\t\t\t\tmethod: \"GET\",\n\t\t\t\tpath: \"/auth/org/list\",\n\t\t\t\tmetadata: {\n\t\t\t\t\trequireAuth: true,\n\t\t\t\t\tdescription: \"List organizations the authenticated user belongs to\",\n\t\t\t\t},\n\t\t\t\tasync handler(request, endpointCtx) {\n\t\t\t\t\tconst user = await endpointCtx.getUser(request);\n\t\t\t\t\tif (!user) {\n\t\t\t\t\t\treturn jsonResponse({ error: \"Authentication required\" }, 401);\n\t\t\t\t\t}\n\n\t\t\t\t\tconst orgs = await module.list(user.id);\n\t\t\t\t\treturn jsonResponse({ organizations: orgs });\n\t\t\t\t},\n\t\t\t});\n\n\t\t\t// POST /auth/org/:id/invite\n\t\t\t// Invites a user by email to an organization. Requires admin or owner role.\n\t\t\tctx.addEndpoint({\n\t\t\t\tmethod: \"POST\",\n\t\t\t\tpath: \"/auth/org/:id/invite\",\n\t\t\t\tmetadata: {\n\t\t\t\t\trequireAuth: true,\n\t\t\t\t\tdescription: \"Invite a user to the organization (admin or owner only)\",\n\t\t\t\t},\n\t\t\t\tasync handler(request, endpointCtx) {\n\t\t\t\t\tconst user = await endpointCtx.getUser(request);\n\t\t\t\t\tif (!user) {\n\t\t\t\t\t\treturn jsonResponse({ error: \"Authentication required\" }, 401);\n\t\t\t\t\t}\n\n\t\t\t\t\tconst url = new URL(request.url);\n\t\t\t\t\tconst segments = url.pathname.split(\"/\").filter(Boolean);\n\t\t\t\t\t// Expected: [\"auth\", \"org\", \"<id>\", \"invite\"]\n\t\t\t\t\tconst orgId = segments[2];\n\n\t\t\t\t\tif (!orgId) {\n\t\t\t\t\t\treturn jsonResponse({ error: \"Missing organization ID in path\" }, 400);\n\t\t\t\t\t}\n\n\t\t\t\t\t// Verify caller has admin or owner role in this org.\n\t\t\t\t\tconst member = await module.getMember(orgId, user.id);\n\t\t\t\t\tif (!member || !ADMIN_ROLES.has(member.role)) {\n\t\t\t\t\t\treturn jsonResponse({ error: \"Admin or owner role required\" }, 403);\n\t\t\t\t\t}\n\n\t\t\t\t\tconst body = await parseBody(request);\n\t\t\t\t\tconst email = typeof body.email === \"string\" ? body.email.trim().toLowerCase() : null;\n\t\t\t\t\tconst role = typeof body.role === \"string\" ? body.role : \"member\";\n\n\t\t\t\t\tif (!email) {\n\t\t\t\t\t\treturn jsonResponse({ error: \"Missing required field: email\" }, 400);\n\t\t\t\t\t}\n\n\t\t\t\t\ttry {\n\t\t\t\t\t\tconst invitation = await module.invite({\n\t\t\t\t\t\t\torgId,\n\t\t\t\t\t\t\temail,\n\t\t\t\t\t\t\trole,\n\t\t\t\t\t\t\tinvitedBy: user.id,\n\t\t\t\t\t\t});\n\t\t\t\t\t\treturn jsonResponse(invitation, 201);\n\t\t\t\t\t} catch (err) {\n\t\t\t\t\t\treturn jsonResponse(\n\t\t\t\t\t\t\t{ error: err instanceof Error ? err.message : \"Failed to send invitation\" },\n\t\t\t\t\t\t\t400,\n\t\t\t\t\t\t);\n\t\t\t\t\t}\n\t\t\t\t},\n\t\t\t});\n\n\t\t\t// POST /auth/org/:id/members\n\t\t\t// Lists all members of the organization.\n\t\t\tctx.addEndpoint({\n\t\t\t\tmethod: \"POST\",\n\t\t\t\tpath: \"/auth/org/:id/members\",\n\t\t\t\tmetadata: {\n\t\t\t\t\trequireAuth: true,\n\t\t\t\t\tdescription: \"List members of the organization\",\n\t\t\t\t},\n\t\t\t\tasync handler(request, endpointCtx) {\n\t\t\t\t\tconst user = await endpointCtx.getUser(request);\n\t\t\t\t\tif (!user) {\n\t\t\t\t\t\treturn jsonResponse({ error: \"Authentication required\" }, 401);\n\t\t\t\t\t}\n\n\t\t\t\t\tconst url = new URL(request.url);\n\t\t\t\t\tconst segments = url.pathname.split(\"/\").filter(Boolean);\n\t\t\t\t\t// Expected: [\"auth\", \"org\", \"<id>\", \"members\"]\n\t\t\t\t\tconst orgId = segments[2];\n\n\t\t\t\t\tif (!orgId) {\n\t\t\t\t\t\treturn jsonResponse({ error: \"Missing organization ID in path\" }, 400);\n\t\t\t\t\t}\n\n\t\t\t\t\t// Verify caller is a member of the org before exposing the member list.\n\t\t\t\t\tconst callerMember = await module.getMember(orgId, user.id);\n\t\t\t\t\tif (!callerMember) {\n\t\t\t\t\t\treturn jsonResponse({ error: \"You are not a member of this organization\" }, 403);\n\t\t\t\t\t}\n\n\t\t\t\t\tconst members = await module.getMembers(orgId);\n\t\t\t\t\treturn jsonResponse({ members });\n\t\t\t\t},\n\t\t\t});\n\n\t\t\t// PATCH /auth/org/:id/members/:userId\n\t\t\t// Updates a member's role. Requires admin or owner.\n\t\t\tctx.addEndpoint({\n\t\t\t\tmethod: \"PATCH\",\n\t\t\t\tpath: \"/auth/org/:id/members/:userId\",\n\t\t\t\tmetadata: {\n\t\t\t\t\trequireAuth: true,\n\t\t\t\t\tdescription: \"Update a member's role (admin or owner only)\",\n\t\t\t\t},\n\t\t\t\tasync handler(request, endpointCtx) {\n\t\t\t\t\tconst user = await endpointCtx.getUser(request);\n\t\t\t\t\tif (!user) {\n\t\t\t\t\t\treturn jsonResponse({ error: \"Authentication required\" }, 401);\n\t\t\t\t\t}\n\n\t\t\t\t\tconst url = new URL(request.url);\n\t\t\t\t\tconst segments = url.pathname.split(\"/\").filter(Boolean);\n\t\t\t\t\t// Expected: [\"auth\", \"org\", \"<id>\", \"members\", \"<userId>\"]\n\t\t\t\t\tconst orgId = segments[2];\n\t\t\t\t\tconst targetUserId = segments[4];\n\n\t\t\t\t\tif (!orgId || !targetUserId) {\n\t\t\t\t\t\treturn jsonResponse({ error: \"Missing organization ID or user ID in path\" }, 400);\n\t\t\t\t\t}\n\n\t\t\t\t\tconst callerMember = await module.getMember(orgId, user.id);\n\t\t\t\t\tif (!callerMember || !ADMIN_ROLES.has(callerMember.role)) {\n\t\t\t\t\t\treturn jsonResponse({ error: \"Admin or owner role required\" }, 403);\n\t\t\t\t\t}\n\n\t\t\t\t\tconst body = await parseBody(request);\n\t\t\t\t\tconst role = typeof body.role === \"string\" ? body.role : null;\n\n\t\t\t\t\tif (!role) {\n\t\t\t\t\t\treturn jsonResponse({ error: \"Missing required field: role\" }, 400);\n\t\t\t\t\t}\n\n\t\t\t\t\ttry {\n\t\t\t\t\t\tconst member = await module.updateMemberRole(orgId, targetUserId, role);\n\t\t\t\t\t\treturn jsonResponse(member);\n\t\t\t\t\t} catch (err) {\n\t\t\t\t\t\treturn jsonResponse(\n\t\t\t\t\t\t\t{ error: err instanceof Error ? err.message : \"Failed to update member role\" },\n\t\t\t\t\t\t\t400,\n\t\t\t\t\t\t);\n\t\t\t\t\t}\n\t\t\t\t},\n\t\t\t});\n\n\t\t\t// DELETE /auth/org/:id/members/:userId\n\t\t\t// Removes a member from the organization. Requires admin or owner.\n\t\t\tctx.addEndpoint({\n\t\t\t\tmethod: \"DELETE\",\n\t\t\t\tpath: \"/auth/org/:id/members/:userId\",\n\t\t\t\tmetadata: {\n\t\t\t\t\trequireAuth: true,\n\t\t\t\t\tdescription: \"Remove a member from the organization (admin or owner only)\",\n\t\t\t\t},\n\t\t\t\tasync handler(request, endpointCtx) {\n\t\t\t\t\tconst user = await endpointCtx.getUser(request);\n\t\t\t\t\tif (!user) {\n\t\t\t\t\t\treturn jsonResponse({ error: \"Authentication required\" }, 401);\n\t\t\t\t\t}\n\n\t\t\t\t\tconst url = new URL(request.url);\n\t\t\t\t\tconst segments = url.pathname.split(\"/\").filter(Boolean);\n\t\t\t\t\t// Expected: [\"auth\", \"org\", \"<id>\", \"members\", \"<userId>\"]\n\t\t\t\t\tconst orgId = segments[2];\n\t\t\t\t\tconst targetUserId = segments[4];\n\n\t\t\t\t\tif (!orgId || !targetUserId) {\n\t\t\t\t\t\treturn jsonResponse({ error: \"Missing organization ID or user ID in path\" }, 400);\n\t\t\t\t\t}\n\n\t\t\t\t\tconst callerMember = await module.getMember(orgId, user.id);\n\t\t\t\t\tif (!callerMember || !ADMIN_ROLES.has(callerMember.role)) {\n\t\t\t\t\t\treturn jsonResponse({ error: \"Admin or owner role required\" }, 403);\n\t\t\t\t\t}\n\n\t\t\t\t\ttry {\n\t\t\t\t\t\tawait module.removeMember(orgId, targetUserId);\n\t\t\t\t\t\treturn jsonResponse({ removed: true });\n\t\t\t\t\t} catch (err) {\n\t\t\t\t\t\treturn jsonResponse(\n\t\t\t\t\t\t\t{ error: err instanceof Error ? err.message : \"Failed to remove member\" },\n\t\t\t\t\t\t\t400,\n\t\t\t\t\t\t);\n\t\t\t\t\t}\n\t\t\t\t},\n\t\t\t});\n\t\t},\n\t};\n}\n","/**\n * Minimal CBOR decoder (RFC 7049) for WebAuthn attestation objects.\n *\n * Handles the subset of CBOR used by authenticators:\n * Major type 0 -- unsigned integer\n * Major type 1 -- negative integer\n * Major type 2 -- byte string\n * Major type 3 -- text string\n * Major type 4 -- array\n * Major type 5 -- map\n * Major type 7 -- simple values (true, false, null, float)\n *\n * Security limits:\n * - Maximum input size: 1 MB\n * - Maximum nesting depth: 32\n * - Indefinite-length items are rejected\n */\n\n/** Maximum CBOR input size in bytes (1 MB). */\nconst MAX_CBOR_INPUT_SIZE = 1_048_576;\n\n/** Maximum nesting depth for arrays/maps. */\nconst MAX_CBOR_DEPTH = 32;\n\ninterface DecoderState {\n\tdata: Uint8Array;\n\toffset: number;\n\tdepth: number;\n}\n\nfunction readByte(state: DecoderState): number {\n\tconst byte = state.data[state.offset];\n\tif (byte === undefined) throw new Error(\"CBOR: unexpected end of data\");\n\tstate.offset++;\n\treturn byte;\n}\n\nfunction readBytes(state: DecoderState, length: number): Uint8Array {\n\tif (length > state.data.length - state.offset) {\n\t\tthrow new Error(\"CBOR: unexpected end of data\");\n\t}\n\tconst end = state.offset + length;\n\tconst slice = state.data.slice(state.offset, end);\n\tstate.offset = end;\n\treturn slice;\n}\n\nfunction readUint(state: DecoderState, additionalInfo: number): number {\n\tif (additionalInfo <= 23) return additionalInfo;\n\tif (additionalInfo === 24) return readByte(state);\n\tif (additionalInfo === 25) {\n\t\tconst b = readBytes(state, 2);\n\t\treturn ((b[0] ?? 0) << 8) | (b[1] ?? 0);\n\t}\n\tif (additionalInfo === 26) {\n\t\tconst b = readBytes(state, 4);\n\t\treturn (((b[0] ?? 0) << 24) | ((b[1] ?? 0) << 16) | ((b[2] ?? 0) << 8) | (b[3] ?? 0)) >>> 0;\n\t}\n\tif (additionalInfo === 27) {\n\t\t// 64-bit -- we only handle values that fit in a JS number safely\n\t\tconst b = readBytes(state, 8);\n\t\tconst hi = ((b[0] ?? 0) * 0x1000000 + (b[1] ?? 0)) * 0x10000 + ((b[2] ?? 0) << 8) + (b[3] ?? 0);\n\t\tconst lo = ((b[4] ?? 0) * 0x1000000 + (b[5] ?? 0)) * 0x10000 + ((b[6] ?? 0) << 8) + (b[7] ?? 0);\n\t\treturn hi * 0x100000000 + lo;\n\t}\n\tif (additionalInfo === 31) {\n\t\tthrow new Error(\"CBOR: indefinite-length items are not supported\");\n\t}\n\tthrow new Error(`CBOR: unsupported additional info ${additionalInfo} for uint`);\n}\n\nfunction decodeItem(state: DecoderState): unknown {\n\tconst initialByte = readByte(state);\n\tconst majorType = (initialByte >> 5) & 0x07;\n\tconst additionalInfo = initialByte & 0x1f;\n\n\tswitch (majorType) {\n\t\tcase 0: {\n\t\t\t// Unsigned integer\n\t\t\treturn readUint(state, additionalInfo);\n\t\t}\n\n\t\tcase 1: {\n\t\t\t// Negative integer: -1 - n\n\t\t\tconst n = readUint(state, additionalInfo);\n\t\t\treturn -1 - n;\n\t\t}\n\n\t\tcase 2: {\n\t\t\t// Byte string\n\t\t\tif (additionalInfo === 31) {\n\t\t\t\tthrow new Error(\"CBOR: indefinite-length byte strings are not supported\");\n\t\t\t}\n\t\t\tconst length = readUint(state, additionalInfo);\n\t\t\treturn readBytes(state, length);\n\t\t}\n\n\t\tcase 3: {\n\t\t\t// Text string\n\t\t\tif (additionalInfo === 31) {\n\t\t\t\tthrow new Error(\"CBOR: indefinite-length text strings are not supported\");\n\t\t\t}\n\t\t\tconst length = readUint(state, additionalInfo);\n\t\t\tconst bytes = readBytes(state, length);\n\t\t\treturn new TextDecoder().decode(bytes);\n\t\t}\n\n\t\tcase 4: {\n\t\t\t// Array\n\t\t\tif (additionalInfo === 31) {\n\t\t\t\tthrow new Error(\"CBOR: indefinite-length arrays are not supported\");\n\t\t\t}\n\t\t\tstate.depth++;\n\t\t\tif (state.depth > MAX_CBOR_DEPTH) {\n\t\t\t\tthrow new Error(`CBOR: nesting depth exceeds maximum of ${MAX_CBOR_DEPTH}`);\n\t\t\t}\n\t\t\tconst count = readUint(state, additionalInfo);\n\t\t\tconst arr: unknown[] = [];\n\t\t\tfor (let i = 0; i < count; i++) {\n\t\t\t\tarr.push(decodeItem(state));\n\t\t\t}\n\t\t\tstate.depth--;\n\t\t\treturn arr;\n\t\t}\n\n\t\tcase 5: {\n\t\t\t// Map\n\t\t\tif (additionalInfo === 31) {\n\t\t\t\tthrow new Error(\"CBOR: indefinite-length maps are not supported\");\n\t\t\t}\n\t\t\tstate.depth++;\n\t\t\tif (state.depth > MAX_CBOR_DEPTH) {\n\t\t\t\tthrow new Error(`CBOR: nesting depth exceeds maximum of ${MAX_CBOR_DEPTH}`);\n\t\t\t}\n\t\t\tconst count = readUint(state, additionalInfo);\n\t\t\tconst map = new Map<unknown, unknown>();\n\t\t\tfor (let i = 0; i < count; i++) {\n\t\t\t\tconst key = decodeItem(state);\n\t\t\t\tconst value = decodeItem(state);\n\t\t\t\tmap.set(key, value);\n\t\t\t}\n\t\t\tstate.depth--;\n\t\t\treturn map;\n\t\t}\n\n\t\tcase 7: {\n\t\t\t// Simple values and floats\n\t\t\tif (additionalInfo === 20) return false;\n\t\t\tif (additionalInfo === 21) return true;\n\t\t\tif (additionalInfo === 22) return null;\n\t\t\tif (additionalInfo === 25) {\n\t\t\t\t// IEEE 754 half-precision float (16-bit)\n\t\t\t\tconst b = readBytes(state, 2);\n\t\t\t\tconst half = ((b[0] ?? 0) << 8) | (b[1] ?? 0);\n\t\t\t\tconst exp = (half >> 10) & 0x1f;\n\t\t\t\tconst mant = half & 0x3ff;\n\t\t\t\tconst sign = half >> 15 ? -1 : 1;\n\t\t\t\tlet val: number;\n\t\t\t\tif (exp === 0) val = sign * 5.96046e-8 * mant;\n\t\t\t\telse if (exp === 31) val = mant ? NaN : sign * Infinity;\n\t\t\t\telse val = sign * 2 ** (exp - 15) * (1 + mant / 1024);\n\t\t\t\treturn val;\n\t\t\t}\n\t\t\tif (additionalInfo === 26) {\n\t\t\t\t// IEEE 754 single-precision float\n\t\t\t\tconst b = readBytes(state, 4);\n\t\t\t\tconst buf = new ArrayBuffer(4);\n\t\t\t\tnew Uint8Array(buf).set(b);\n\t\t\t\treturn new DataView(buf).getFloat32(0, false);\n\t\t\t}\n\t\t\tif (additionalInfo === 27) {\n\t\t\t\t// IEEE 754 double-precision float\n\t\t\t\tconst b = readBytes(state, 8);\n\t\t\t\tconst buf = new ArrayBuffer(8);\n\t\t\t\tnew Uint8Array(buf).set(b);\n\t\t\t\treturn new DataView(buf).getFloat64(0, false);\n\t\t\t}\n\t\t\tthrow new Error(`CBOR: unsupported simple value ${additionalInfo}`);\n\t\t}\n\n\t\tdefault:\n\t\t\tthrow new Error(`CBOR: unsupported major type ${majorType}`);\n\t}\n}\n\n/**\n * Decode a CBOR-encoded byte array into a JavaScript value.\n *\n * Maps are decoded as `Map<unknown, unknown>` to preserve numeric keys\n * (COSE keys use negative integers).\n *\n * Enforces size and depth limits to prevent denial of service.\n */\nexport function decodeCbor(data: Uint8Array): unknown {\n\tif (data.length > MAX_CBOR_INPUT_SIZE) {\n\t\tthrow new Error(`CBOR: input size ${data.length} exceeds maximum of ${MAX_CBOR_INPUT_SIZE}`);\n\t}\n\tif (data.length === 0) {\n\t\tthrow new Error(\"CBOR: empty input\");\n\t}\n\tconst state: DecoderState = { data, offset: 0, depth: 0 };\n\treturn decodeItem(state);\n}\n","/**\n * Passkey / WebAuthn authentication for KavachOS.\n *\n * Implements server-side WebAuthn (Level 2) without external libraries.\n * Uses Web Crypto API (via node:crypto's webcrypto) for signature verification\n * and a minimal CBOR decoder for attestation object parsing.\n *\n * Flow:\n * Registration\n * 1. getRegistrationOptions(userId, userName) -> send to browser\n * 2. browser calls navigator.credentials.create(options)\n * 3. verifyRegistration(userId, response) -> stores credential\n *\n * Authentication\n * 1. getAuthenticationOptions(userId?) -> send to browser\n * 2. browser calls navigator.credentials.get(options)\n * 3. verifyAuthentication(response) -> returns userId + credential\n */\n\nimport { randomBytes, timingSafeEqual, webcrypto } from \"node:crypto\";\nimport { and, eq, lt } from \"drizzle-orm\";\nimport type { Database } from \"../db/database.js\";\nimport { passkeyChallenges, passkeyCredentials } from \"../db/schema.js\";\nimport { decodeCbor } from \"./cbor.js\";\n\n// ---------------------------------------------------------------------------\n// Error codes\n// ---------------------------------------------------------------------------\n\nexport const PASSKEY_ERROR = {\n\tCHALLENGE_NOT_FOUND: \"CHALLENGE_NOT_FOUND\",\n\tCHALLENGE_EXPIRED: \"CHALLENGE_EXPIRED\",\n\tCHALLENGE_REPLAY: \"CHALLENGE_REPLAY\",\n\tORIGIN_MISMATCH: \"ORIGIN_MISMATCH\",\n\tRPID_MISMATCH: \"RPID_MISMATCH\",\n\tCLIENT_DATA_TYPE_MISMATCH: \"CLIENT_DATA_TYPE_MISMATCH\",\n\tUSER_NOT_PRESENT: \"USER_NOT_PRESENT\",\n\tUSER_NOT_VERIFIED: \"USER_NOT_VERIFIED\",\n\tCREDENTIAL_NOT_FOUND: \"CREDENTIAL_NOT_FOUND\",\n\tCREDENTIAL_ALREADY_EXISTS: \"CREDENTIAL_ALREADY_EXISTS\",\n\tSIGNATURE_INVALID: \"SIGNATURE_INVALID\",\n\tSIGN_COUNT_ROLLBACK: \"SIGN_COUNT_ROLLBACK\",\n\tMISSING_ATTESTATION_DATA: \"MISSING_ATTESTATION_DATA\",\n\tINVALID_ATTESTATION: \"INVALID_ATTESTATION\",\n\tUNSUPPORTED_ALGORITHM: \"UNSUPPORTED_ALGORITHM\",\n\tINVALID_COSE_KEY: \"INVALID_COSE_KEY\",\n\tINVALID_CLIENT_DATA: \"INVALID_CLIENT_DATA\",\n} as const;\n\nexport class PasskeyError extends Error {\n\treadonly code: string;\n\n\tconstructor(code: string, message: string) {\n\t\tsuper(message);\n\t\tthis.name = \"PasskeyError\";\n\t\tthis.code = code;\n\t}\n}\n\n// ---------------------------------------------------------------------------\n// Public types\n// ---------------------------------------------------------------------------\n\nexport interface PasskeyConfig {\n\t/** Relying Party name (your app name) */\n\trpName: string;\n\t/** Relying Party ID (your domain, e.g., \"example.com\") */\n\trpId: string;\n\t/** Expected origin (e.g., \"https://example.com\") */\n\torigin: string | string[];\n\t/** Attestation preference (default: \"none\") */\n\tattestation?: \"none\" | \"indirect\" | \"direct\";\n\t/** User verification requirement (default: \"preferred\") */\n\tuserVerification?: \"required\" | \"preferred\" | \"discouraged\";\n\t/** Challenge timeout in ms (default: 60000, max: 300000) */\n\tchallengeTimeout?: number;\n}\n\nexport interface PasskeyCredential {\n\tid: string;\n\tcredentialId: string;\n\tpublicKey: string;\n\tcounter: number;\n\tuserId: string;\n\tdeviceName?: string;\n\ttransports?: string[];\n\tcreatedAt: Date;\n\tlastUsedAt: Date;\n}\n\nexport interface PasskeyModule {\n\tgetRegistrationOptions: (\n\t\tuserId: string,\n\t\tuserName: string,\n\t) => Promise<{\n\t\tchallenge: string;\n\t\trp: { name: string; id: string };\n\t\tuser: { id: string; name: string; displayName: string };\n\t\tpubKeyCredParams: Array<{ type: \"public-key\"; alg: number }>;\n\t\ttimeout: number;\n\t\tattestation: string;\n\t\tauthenticatorSelection: {\n\t\t\tuserVerification: string;\n\t\t\tresidentKey: string;\n\t\t\trequireResidentKey: boolean;\n\t\t};\n\t\texcludeCredentials: Array<{ id: string; type: \"public-key\"; transports?: string[] }>;\n\t}>;\n\n\tverifyRegistration: (\n\t\tuserId: string,\n\t\tresponse: {\n\t\t\tid: string;\n\t\t\trawId: string;\n\t\t\ttype: \"public-key\";\n\t\t\tresponse: {\n\t\t\t\tclientDataJSON: string;\n\t\t\t\tattestationObject: string;\n\t\t\t};\n\t\t\tdeviceName?: string;\n\t\t\ttransports?: string[];\n\t\t},\n\t) => Promise<{ credential: PasskeyCredential }>;\n\n\tgetAuthenticationOptions: (userId?: string) => Promise<{\n\t\tchallenge: string;\n\t\trpId: string;\n\t\ttimeout: number;\n\t\tuserVerification: string;\n\t\tallowCredentials: Array<{ id: string; type: \"public-key\"; transports?: string[] }>;\n\t}>;\n\n\tverifyAuthentication: (response: {\n\t\tid: string;\n\t\trawId: string;\n\t\ttype: \"public-key\";\n\t\tresponse: {\n\t\t\tclientDataJSON: string;\n\t\t\tauthenticatorData: string;\n\t\t\tsignature: string;\n\t\t};\n\t}) => Promise<{ userId: string; credential: PasskeyCredential }>;\n\n\tlistCredentials: (userId: string) => Promise<PasskeyCredential[]>;\n\tremoveCredential: (credentialId: string, userId: string) => Promise<void>;\n\thandleRequest: (request: Request) => Promise<Response | null>;\n}\n\n// ---------------------------------------------------------------------------\n// Internal types\n// ---------------------------------------------------------------------------\n\ninterface CoseKey {\n\tkty: number;\n\talg: number;\n\tcrv?: number;\n\tx?: Uint8Array;\n\ty?: Uint8Array;\n\t/** RSA modulus (COSE map key -1 for kty=3) */\n\tn?: Uint8Array;\n\t/** RSA exponent (COSE map key -2 for kty=3) */\n\te?: Uint8Array;\n}\n\n// COSE key type constants (OKP=1, EC2=2 used implicitly by algorithm detection)\nconst COSE_KTY_RSA = 3;\n\n// COSE algorithm constants\nconst COSE_ALG_ES256 = -7;\nconst COSE_ALG_ES384 = -35;\nconst COSE_ALG_ES512 = -36;\nconst COSE_ALG_RS256 = -257;\nconst COSE_ALG_EDDSA = -8;\n\n/** Maximum challenge timeout: 5 minutes */\nconst MAX_CHALLENGE_TIMEOUT = 300_000;\n\n/** Default challenge timeout: 60 seconds */\nconst DEFAULT_CHALLENGE_TIMEOUT = 60_000;\n\n// ---------------------------------------------------------------------------\n// Base64url helpers (no Buffer -- uses btoa/atob via Uint8Array)\n// ---------------------------------------------------------------------------\n\nfunction toBase64Url(bytes: Uint8Array): string {\n\tlet binary = \"\";\n\tfor (let i = 0; i < bytes.length; i++) {\n\t\tbinary += String.fromCharCode(bytes[i] as number);\n\t}\n\tconst b64 = btoa(binary);\n\treturn b64.replace(/\\+/g, \"-\").replace(/\\//g, \"_\").replace(/=/g, \"\");\n}\n\nfunction fromBase64Url(str: string): Uint8Array {\n\tconst padded = str.replace(/-/g, \"+\").replace(/_/g, \"/\");\n\tconst pad = padded.length % 4;\n\tconst b64 = pad ? padded + \"=\".repeat(4 - pad) : padded;\n\tconst binary = atob(b64);\n\tconst bytes = new Uint8Array(binary.length);\n\tfor (let i = 0; i < binary.length; i++) {\n\t\tbytes[i] = binary.charCodeAt(i);\n\t}\n\treturn bytes;\n}\n\n// ---------------------------------------------------------------------------\n// Crypto helpers\n// ---------------------------------------------------------------------------\n\nasync function sha256(data: Uint8Array): Promise<Uint8Array> {\n\tconst hash = await webcrypto.subtle.digest(\"SHA-256\", data);\n\treturn new Uint8Array(hash);\n}\n\n/**\n * Constant-time byte comparison using node:crypto timingSafeEqual.\n * Prevents timing side-channel attacks on hash comparisons.\n */\nfunction bytesEqual(a: Uint8Array, b: Uint8Array): boolean {\n\tif (a.length !== b.length) return false;\n\treturn timingSafeEqual(a, b);\n}\n\n// ---------------------------------------------------------------------------\n// COSE key parsing and verification\n// ---------------------------------------------------------------------------\n\nfunction parseCoseKey(coseMap: Map<unknown, unknown>): CoseKey {\n\tconst kty = coseMap.get(1) as number;\n\tconst alg = coseMap.get(3) as number;\n\n\tif (typeof kty !== \"number\" || typeof alg !== \"number\") {\n\t\tthrow new PasskeyError(\n\t\t\tPASSKEY_ERROR.INVALID_COSE_KEY,\n\t\t\t\"COSE key missing required kty or alg fields\",\n\t\t);\n\t}\n\n\tif (kty === COSE_KTY_RSA) {\n\t\t// RSA: n is at map key -1, e is at map key -2\n\t\tconst n = coseMap.get(-1) as Uint8Array | undefined;\n\t\tconst e = coseMap.get(-2) as Uint8Array | undefined;\n\t\treturn { kty, alg, n, e };\n\t}\n\n\t// EC2 or OKP\n\tconst crv = coseMap.get(-1) as number | undefined;\n\tconst x = coseMap.get(-2) as Uint8Array | undefined;\n\tconst y = coseMap.get(-3) as Uint8Array | undefined;\n\treturn { kty, alg, crv, x, y };\n}\n\n/**\n * Returns the expected coordinate size in bytes for a given COSE EC algorithm.\n */\nfunction ecCoordSize(alg: number): number {\n\tswitch (alg) {\n\t\tcase COSE_ALG_ES256:\n\t\t\treturn 32;\n\t\tcase COSE_ALG_ES384:\n\t\t\treturn 48;\n\t\tcase COSE_ALG_ES512:\n\t\t\treturn 66;\n\t\tdefault:\n\t\t\treturn 32;\n\t}\n}\n\nasync function verifySignatureES(\n\tcoseKey: CoseKey,\n\tdata: Uint8Array,\n\tsignature: Uint8Array,\n\tnamedCurve: string,\n\thash: string,\n): Promise<boolean> {\n\tif (!coseKey.x || !coseKey.y) {\n\t\tthrow new PasskeyError(PASSKEY_ERROR.INVALID_COSE_KEY, \"Missing EC key coordinates\");\n\t}\n\n\tconst jwk = {\n\t\tkty: \"EC\",\n\t\tcrv: namedCurve,\n\t\tx: toBase64Url(coseKey.x),\n\t\ty: toBase64Url(coseKey.y),\n\t};\n\n\tconst key = await webcrypto.subtle.importKey(\"jwk\", jwk, { name: \"ECDSA\", namedCurve }, false, [\n\t\t\"verify\",\n\t]);\n\n\t// WebAuthn signatures use DER-encoded ECDSA; Web Crypto expects raw (r||s)\n\tconst rawSig = derToRaw(signature, ecCoordSize(coseKey.alg));\n\n\treturn webcrypto.subtle.verify({ name: \"ECDSA\", hash: { name: hash } }, key, rawSig, data);\n}\n\n/**\n * Convert DER-encoded ECDSA signature to raw (r||s) format.\n * DER format: 0x30 len 0x02 rLen r 0x02 sLen s\n *\n * @param coordSize - Expected coordinate size in bytes (32 for P-256, 48 for P-384, 66 for P-521)\n */\nfunction derToRaw(der: Uint8Array, coordSize: number): Uint8Array {\n\tif (der[0] !== 0x30) return der; // not DER, assume already raw\n\tlet offset = 2; // skip 0x30 and total length\n\tif (der[1] === 0x81) offset = 3; // long form length\n\n\t// Read r\n\tif (der[offset] !== 0x02) {\n\t\tthrow new PasskeyError(PASSKEY_ERROR.SIGNATURE_INVALID, \"Invalid DER: expected 0x02 for r\");\n\t}\n\toffset++;\n\tconst rLen = der[offset] ?? 0;\n\toffset++;\n\tconst rBytes = der.slice(offset, offset + rLen);\n\toffset += rLen;\n\n\t// Read s\n\tif (der[offset] !== 0x02) {\n\t\tthrow new PasskeyError(PASSKEY_ERROR.SIGNATURE_INVALID, \"Invalid DER: expected 0x02 for s\");\n\t}\n\toffset++;\n\tconst sLen = der[offset] ?? 0;\n\toffset++;\n\tconst sBytes = der.slice(offset, offset + sLen);\n\n\t// Strip leading zero padding (DER uses it to signal positive integers)\n\tconst r = rBytes[0] === 0 ? rBytes.slice(1) : rBytes;\n\tconst s = sBytes[0] === 0 ? sBytes.slice(1) : sBytes;\n\n\t// Pad to correct coordinate size\n\tconst raw = new Uint8Array(coordSize * 2);\n\traw.set(r, coordSize - r.length);\n\traw.set(s, coordSize * 2 - s.length);\n\treturn raw;\n}\n\nasync function verifySignatureRSA(\n\tcoseKey: CoseKey,\n\tdata: Uint8Array,\n\tsignature: Uint8Array,\n): Promise<boolean> {\n\tif (!coseKey.n || !coseKey.e) {\n\t\tthrow new PasskeyError(PASSKEY_ERROR.INVALID_COSE_KEY, \"Missing RSA key modulus or exponent\");\n\t}\n\n\tconst jwk = {\n\t\tkty: \"RSA\",\n\t\tn: toBase64Url(coseKey.n),\n\t\te: toBase64Url(coseKey.e),\n\t\talg: \"RS256\",\n\t};\n\n\tconst key = await webcrypto.subtle.importKey(\n\t\t\"jwk\",\n\t\tjwk,\n\t\t{ name: \"RSASSA-PKCS1-v1_5\", hash: { name: \"SHA-256\" } },\n\t\tfalse,\n\t\t[\"verify\"],\n\t);\n\n\treturn webcrypto.subtle.verify(\"RSASSA-PKCS1-v1_5\", key, signature, data);\n}\n\nasync function verifySignatureEdDSA(\n\tcoseKey: CoseKey,\n\tdata: Uint8Array,\n\tsignature: Uint8Array,\n): Promise<boolean> {\n\tif (!coseKey.x) {\n\t\tthrow new PasskeyError(PASSKEY_ERROR.INVALID_COSE_KEY, \"Missing EdDSA public key x\");\n\t}\n\n\tconst jwk = {\n\t\tkty: \"OKP\",\n\t\tcrv: \"Ed25519\",\n\t\tx: toBase64Url(coseKey.x),\n\t};\n\n\tconst key = await webcrypto.subtle.importKey(\"jwk\", jwk, { name: \"Ed25519\" }, false, [\"verify\"]);\n\n\treturn webcrypto.subtle.verify({ name: \"Ed25519\" }, key, signature, data);\n}\n\nasync function verifyCoseSignature(\n\tpublicKeyCbor: Uint8Array,\n\tdata: Uint8Array,\n\tsignature: Uint8Array,\n): Promise<boolean> {\n\tconst decoded = decodeCbor(publicKeyCbor);\n\tif (!(decoded instanceof Map)) {\n\t\tthrow new PasskeyError(PASSKEY_ERROR.INVALID_COSE_KEY, \"COSE key is not a CBOR map\");\n\t}\n\n\tconst coseKey = parseCoseKey(decoded);\n\n\tswitch (coseKey.alg) {\n\t\tcase COSE_ALG_ES256:\n\t\t\treturn verifySignatureES(coseKey, data, signature, \"P-256\", \"SHA-256\");\n\t\tcase COSE_ALG_ES384:\n\t\t\treturn verifySignatureES(coseKey, data, signature, \"P-384\", \"SHA-384\");\n\t\tcase COSE_ALG_ES512:\n\t\t\treturn verifySignatureES(coseKey, data, signature, \"P-521\", \"SHA-512\");\n\t\tcase COSE_ALG_RS256:\n\t\t\treturn verifySignatureRSA(coseKey, data, signature);\n\t\tcase COSE_ALG_EDDSA:\n\t\t\treturn verifySignatureEdDSA(coseKey, data, signature);\n\t\tdefault:\n\t\t\tthrow new PasskeyError(\n\t\t\t\tPASSKEY_ERROR.UNSUPPORTED_ALGORITHM,\n\t\t\t\t`Unsupported COSE algorithm: ${coseKey.alg}`,\n\t\t\t);\n\t}\n}\n\n// ---------------------------------------------------------------------------\n// AuthData parsing\n// ---------------------------------------------------------------------------\n\ninterface ParsedAuthData {\n\trpIdHash: Uint8Array;\n\tflags: number;\n\tsignCount: number;\n\tattestedCredentialData?: {\n\t\taaguid: Uint8Array;\n\t\tcredentialId: Uint8Array;\n\t\tcredentialPublicKey: Uint8Array;\n\t\tcredentialPublicKeyOffset: number;\n\t};\n}\n\nconst FLAG_UP = 0x01; // user present\nconst FLAG_UV = 0x04; // user verified\nconst FLAG_AT = 0x40; // attested credential data included\n\nfunction parseAuthData(authData: Uint8Array): ParsedAuthData {\n\tif (authData.length < 37) {\n\t\tthrow new PasskeyError(PASSKEY_ERROR.INVALID_ATTESTATION, \"authData too short\");\n\t}\n\n\tconst rpIdHash = authData.slice(0, 32);\n\tconst flags = authData[32] ?? 0;\n\tconst signCount =\n\t\t(((authData[33] ?? 0) << 24) |\n\t\t\t((authData[34] ?? 0) << 16) |\n\t\t\t((authData[35] ?? 0) << 8) |\n\t\t\t(authData[36] ?? 0)) >>>\n\t\t0;\n\n\tlet attestedCredentialData: ParsedAuthData[\"attestedCredentialData\"];\n\n\tif (flags & FLAG_AT) {\n\t\tif (authData.length < 55) {\n\t\t\tthrow new PasskeyError(\n\t\t\t\tPASSKEY_ERROR.INVALID_ATTESTATION,\n\t\t\t\t\"authData too short for attested credential data\",\n\t\t\t);\n\t\t}\n\n\t\tconst aaguid = authData.slice(37, 53);\n\t\tconst credentialIdLength = ((authData[53] ?? 0) << 8) | (authData[54] ?? 0);\n\n\t\tif (authData.length < 55 + credentialIdLength) {\n\t\t\tthrow new PasskeyError(\n\t\t\t\tPASSKEY_ERROR.INVALID_ATTESTATION,\n\t\t\t\t\"authData too short for credential ID\",\n\t\t\t);\n\t\t}\n\n\t\tconst credentialId = authData.slice(55, 55 + credentialIdLength);\n\t\tconst credentialPublicKeyOffset = 55 + credentialIdLength;\n\t\tconst credentialPublicKey = authData.slice(credentialPublicKeyOffset);\n\n\t\tattestedCredentialData = {\n\t\t\taaguid,\n\t\t\tcredentialId,\n\t\t\tcredentialPublicKey,\n\t\t\tcredentialPublicKeyOffset,\n\t\t};\n\t}\n\n\treturn { rpIdHash, flags, signCount, attestedCredentialData };\n}\n\n// ---------------------------------------------------------------------------\n// HTTP helpers\n// ---------------------------------------------------------------------------\n\nfunction jsonResponse(body: unknown, status = 200): Response {\n\treturn new Response(JSON.stringify(body), {\n\t\tstatus,\n\t\theaders: { \"Content-Type\": \"application/json\" },\n\t});\n}\n\nasync function parseBody(request: Request): Promise<Record<string, unknown>> {\n\ttry {\n\t\treturn (await request.json()) as Record<string, unknown>;\n\t} catch {\n\t\treturn {};\n\t}\n}\n\nfunction getPathSegments(url: URL): string[] {\n\treturn url.pathname.split(\"/\").filter(Boolean);\n}\n\n// ---------------------------------------------------------------------------\n// Origin validation\n// ---------------------------------------------------------------------------\n\nfunction isOriginAllowed(origin: string, allowed: string | string[]): boolean {\n\tconst origins = Array.isArray(allowed) ? allowed : [allowed];\n\treturn origins.includes(origin);\n}\n\n// ---------------------------------------------------------------------------\n// Module factory\n// ---------------------------------------------------------------------------\n\nexport function createPasskeyModule(config: PasskeyConfig, db: Database): PasskeyModule {\n\tconst timeout = Math.min(\n\t\tconfig.challengeTimeout ?? DEFAULT_CHALLENGE_TIMEOUT,\n\t\tMAX_CHALLENGE_TIMEOUT,\n\t);\n\tconst userVerification = config.userVerification ?? \"preferred\";\n\tconst attestation = config.attestation ?? \"none\";\n\n\t// ── getRegistrationOptions ───────────────────────────────────────────────\n\n\tasync function getRegistrationOptions(\n\t\tuserId: string,\n\t\tuserName: string,\n\t): ReturnType<PasskeyModule[\"getRegistrationOptions\"]> {\n\t\t// Clean up expired challenges\n\t\tawait db.delete(passkeyChallenges).where(lt(passkeyChallenges.expiresAt, new Date()));\n\n\t\tconst challengeBytes = randomBytes(32);\n\t\tconst challenge = toBase64Url(challengeBytes);\n\t\tconst id = randomBytes(16).toString(\"hex\");\n\t\tconst now = new Date();\n\t\tconst expiresAt = new Date(now.getTime() + timeout);\n\n\t\tawait db.insert(passkeyChallenges).values({\n\t\t\tid,\n\t\t\tchallenge,\n\t\t\tuserId,\n\t\t\ttype: \"registration\",\n\t\t\texpiresAt,\n\t\t\tcreatedAt: now,\n\t\t});\n\n\t\t// Get existing credentials to exclude\n\t\tconst existing = await db\n\t\t\t.select()\n\t\t\t.from(passkeyCredentials)\n\t\t\t.where(eq(passkeyCredentials.userId, userId));\n\n\t\tconst excludeCredentials = existing.map((c) => ({\n\t\t\tid: c.credentialId,\n\t\t\ttype: \"public-key\" as const,\n\t\t\ttransports: c.transports ? (JSON.parse(c.transports as string) as string[]) : undefined,\n\t\t}));\n\n\t\treturn {\n\t\t\tchallenge,\n\t\t\trp: { name: config.rpName, id: config.rpId },\n\t\t\tuser: { id: userId, name: userName, displayName: userName },\n\t\t\tpubKeyCredParams: [\n\t\t\t\t{ type: \"public-key\", alg: COSE_ALG_ES256 },\n\t\t\t\t{ type: \"public-key\", alg: COSE_ALG_RS256 },\n\t\t\t\t{ type: \"public-key\", alg: COSE_ALG_EDDSA },\n\t\t\t],\n\t\t\ttimeout,\n\t\t\tattestation,\n\t\t\tauthenticatorSelection: {\n\t\t\t\tuserVerification,\n\t\t\t\tresidentKey: \"preferred\",\n\t\t\t\trequireResidentKey: false,\n\t\t\t},\n\t\t\texcludeCredentials,\n\t\t};\n\t}\n\n\t// ── verifyRegistration ───────────────────────────────────────────────────\n\n\tasync function verifyRegistration(\n\t\tuserId: string,\n\t\tresponse: Parameters<PasskeyModule[\"verifyRegistration\"]>[1],\n\t): ReturnType<PasskeyModule[\"verifyRegistration\"]> {\n\t\t// 1. Decode clientDataJSON\n\t\tconst clientDataBytes = fromBase64Url(response.response.clientDataJSON);\n\t\tlet clientData: { type: string; challenge: string; origin: string; crossOrigin?: boolean };\n\t\ttry {\n\t\t\tclientData = JSON.parse(new TextDecoder().decode(clientDataBytes)) as {\n\t\t\t\ttype: string;\n\t\t\t\tchallenge: string;\n\t\t\t\torigin: string;\n\t\t\t\tcrossOrigin?: boolean;\n\t\t\t};\n\t\t} catch {\n\t\t\tthrow new PasskeyError(PASSKEY_ERROR.INVALID_CLIENT_DATA, \"Failed to parse clientDataJSON\");\n\t\t}\n\n\t\t// 1a. Reject cross-origin iframes explicitly\n\t\tif (clientData.crossOrigin === true) {\n\t\t\tthrow new PasskeyError(\n\t\t\t\tPASSKEY_ERROR.ORIGIN_MISMATCH,\n\t\t\t\t\"Cross-origin WebAuthn requests are not allowed\",\n\t\t\t);\n\t\t}\n\n\t\tif (clientData.type !== \"webauthn.create\") {\n\t\t\tthrow new PasskeyError(\n\t\t\t\tPASSKEY_ERROR.CLIENT_DATA_TYPE_MISMATCH,\n\t\t\t\t`Expected type \"webauthn.create\", got \"${clientData.type}\"`,\n\t\t\t);\n\t\t}\n\t\tif (!isOriginAllowed(clientData.origin, config.origin)) {\n\t\t\tthrow new PasskeyError(\n\t\t\t\tPASSKEY_ERROR.ORIGIN_MISMATCH,\n\t\t\t\t`Origin mismatch: got \"${clientData.origin}\"`,\n\t\t\t);\n\t\t}\n\n\t\t// 2. Verify challenge\n\t\tconst challengeRows = await db\n\t\t\t.select()\n\t\t\t.from(passkeyChallenges)\n\t\t\t.where(\n\t\t\t\tand(\n\t\t\t\t\teq(passkeyChallenges.challenge, clientData.challenge),\n\t\t\t\t\teq(passkeyChallenges.userId, userId),\n\t\t\t\t\teq(passkeyChallenges.type, \"registration\"),\n\t\t\t\t),\n\t\t\t);\n\n\t\tconst challengeRow = challengeRows[0];\n\t\tif (!challengeRow) {\n\t\t\tthrow new PasskeyError(\n\t\t\t\tPASSKEY_ERROR.CHALLENGE_NOT_FOUND,\n\t\t\t\t\"Challenge not found or already used\",\n\t\t\t);\n\t\t}\n\n\t\t// Delete the challenge FIRST (one-time use, prevent replay even if later steps fail)\n\t\tawait db.delete(passkeyChallenges).where(eq(passkeyChallenges.id, challengeRow.id));\n\n\t\tif (challengeRow.expiresAt < new Date()) {\n\t\t\tthrow new PasskeyError(PASSKEY_ERROR.CHALLENGE_EXPIRED, \"Challenge expired\");\n\t\t}\n\n\t\t// 3. Decode attestationObject (CBOR)\n\t\tconst attestationBytes = fromBase64Url(response.response.attestationObject);\n\t\tconst attestationObj = decodeCbor(attestationBytes);\n\t\tif (!(attestationObj instanceof Map)) {\n\t\t\tthrow new PasskeyError(PASSKEY_ERROR.INVALID_ATTESTATION, \"Invalid attestation object\");\n\t\t}\n\n\t\tconst authDataRaw = attestationObj.get(\"authData\") as Uint8Array;\n\t\tif (!authDataRaw || !(authDataRaw instanceof Uint8Array)) {\n\t\t\tthrow new PasskeyError(\n\t\t\t\tPASSKEY_ERROR.INVALID_ATTESTATION,\n\t\t\t\t\"Missing authData in attestation object\",\n\t\t\t);\n\t\t}\n\n\t\t// 4. Parse authData\n\t\tconst authData = parseAuthData(authDataRaw);\n\n\t\t// 5. Verify rpIdHash\n\t\tconst expectedRpIdHash = new Uint8Array(\n\t\t\tawait webcrypto.subtle.digest(\"SHA-256\", new TextEncoder().encode(config.rpId)),\n\t\t);\n\t\tif (!bytesEqual(authData.rpIdHash, expectedRpIdHash)) {\n\t\t\tthrow new PasskeyError(PASSKEY_ERROR.RPID_MISMATCH, \"rpIdHash mismatch\");\n\t\t}\n\n\t\t// 6. Verify user present flag\n\t\tif (!(authData.flags & FLAG_UP)) {\n\t\t\tthrow new PasskeyError(PASSKEY_ERROR.USER_NOT_PRESENT, \"User present flag not set\");\n\t\t}\n\n\t\t// 6a. Verify user verified flag when required\n\t\tif (userVerification === \"required\" && !(authData.flags & FLAG_UV)) {\n\t\t\tthrow new PasskeyError(\n\t\t\t\tPASSKEY_ERROR.USER_NOT_VERIFIED,\n\t\t\t\t\"User verified flag not set but required\",\n\t\t\t);\n\t\t}\n\n\t\t// 7. Extract credential data\n\t\tif (!authData.attestedCredentialData) {\n\t\t\tthrow new PasskeyError(\n\t\t\t\tPASSKEY_ERROR.MISSING_ATTESTATION_DATA,\n\t\t\t\t\"No attested credential data in authData\",\n\t\t\t);\n\t\t}\n\n\t\tconst { credentialId, credentialPublicKey } = authData.attestedCredentialData;\n\t\tconst credentialIdB64 = toBase64Url(credentialId);\n\t\tconst publicKeyB64 = toBase64Url(credentialPublicKey);\n\n\t\t// 8. Check for duplicate credential ID\n\t\tconst existing = await db\n\t\t\t.select()\n\t\t\t.from(passkeyCredentials)\n\t\t\t.where(eq(passkeyCredentials.credentialId, credentialIdB64));\n\n\t\tif (existing.length > 0) {\n\t\t\tthrow new PasskeyError(\n\t\t\t\tPASSKEY_ERROR.CREDENTIAL_ALREADY_EXISTS,\n\t\t\t\t\"Credential already registered\",\n\t\t\t);\n\t\t}\n\n\t\t// 9. Store credential\n\t\tconst now = new Date();\n\t\tconst id = randomBytes(16).toString(\"hex\");\n\n\t\tconst transports = response.transports ? JSON.stringify(response.transports) : null;\n\n\t\tawait db.insert(passkeyCredentials).values({\n\t\t\tid,\n\t\t\tuserId,\n\t\t\tcredentialId: credentialIdB64,\n\t\t\tpublicKey: publicKeyB64,\n\t\t\tcounter: authData.signCount,\n\t\t\tdeviceName: response.deviceName ?? null,\n\t\t\ttransports,\n\t\t\tcreatedAt: now,\n\t\t\tlastUsedAt: now,\n\t\t});\n\n\t\tconst credential: PasskeyCredential = {\n\t\t\tid,\n\t\t\tcredentialId: credentialIdB64,\n\t\t\tpublicKey: publicKeyB64,\n\t\t\tcounter: authData.signCount,\n\t\t\tuserId,\n\t\t\tdeviceName: response.deviceName,\n\t\t\ttransports: response.transports,\n\t\t\tcreatedAt: now,\n\t\t\tlastUsedAt: now,\n\t\t};\n\n\t\treturn { credential };\n\t}\n\n\t// ── getAuthenticationOptions ─────────────────────────────────────────────\n\n\tasync function getAuthenticationOptions(\n\t\tuserId?: string,\n\t): ReturnType<PasskeyModule[\"getAuthenticationOptions\"]> {\n\t\tawait db.delete(passkeyChallenges).where(lt(passkeyChallenges.expiresAt, new Date()));\n\n\t\tconst challengeBytes = randomBytes(32);\n\t\tconst challenge = toBase64Url(challengeBytes);\n\t\tconst id = randomBytes(16).toString(\"hex\");\n\t\tconst now = new Date();\n\t\tconst expiresAt = new Date(now.getTime() + timeout);\n\n\t\tawait db.insert(passkeyChallenges).values({\n\t\t\tid,\n\t\t\tchallenge,\n\t\t\tuserId: userId ?? null,\n\t\t\ttype: \"authentication\",\n\t\t\texpiresAt,\n\t\t\tcreatedAt: now,\n\t\t});\n\n\t\tlet allowCredentials: Array<{ id: string; type: \"public-key\"; transports?: string[] }> = [];\n\n\t\tif (userId) {\n\t\t\tconst creds = await db\n\t\t\t\t.select()\n\t\t\t\t.from(passkeyCredentials)\n\t\t\t\t.where(eq(passkeyCredentials.userId, userId));\n\n\t\t\tallowCredentials = creds.map((c) => ({\n\t\t\t\tid: c.credentialId,\n\t\t\t\ttype: \"public-key\" as const,\n\t\t\t\ttransports: c.transports ? (JSON.parse(c.transports as string) as string[]) : undefined,\n\t\t\t}));\n\t\t}\n\n\t\treturn {\n\t\t\tchallenge,\n\t\t\trpId: config.rpId,\n\t\t\ttimeout,\n\t\t\tuserVerification,\n\t\t\tallowCredentials,\n\t\t};\n\t}\n\n\t// ── verifyAuthentication ─────────────────────────────────────────────────\n\n\tasync function verifyAuthentication(\n\t\tresponse: Parameters<PasskeyModule[\"verifyAuthentication\"]>[0],\n\t): ReturnType<PasskeyModule[\"verifyAuthentication\"]> {\n\t\t// 1. Decode clientDataJSON\n\t\tconst clientDataBytes = fromBase64Url(response.response.clientDataJSON);\n\t\tlet clientData: { type: string; challenge: string; origin: string; crossOrigin?: boolean };\n\t\ttry {\n\t\t\tclientData = JSON.parse(new TextDecoder().decode(clientDataBytes)) as {\n\t\t\t\ttype: string;\n\t\t\t\tchallenge: string;\n\t\t\t\torigin: string;\n\t\t\t\tcrossOrigin?: boolean;\n\t\t\t};\n\t\t} catch {\n\t\t\tthrow new PasskeyError(PASSKEY_ERROR.INVALID_CLIENT_DATA, \"Failed to parse clientDataJSON\");\n\t\t}\n\n\t\t// 1a. Reject cross-origin iframes\n\t\tif (clientData.crossOrigin === true) {\n\t\t\tthrow new PasskeyError(\n\t\t\t\tPASSKEY_ERROR.ORIGIN_MISMATCH,\n\t\t\t\t\"Cross-origin WebAuthn requests are not allowed\",\n\t\t\t);\n\t\t}\n\n\t\tif (clientData.type !== \"webauthn.get\") {\n\t\t\tthrow new PasskeyError(\n\t\t\t\tPASSKEY_ERROR.CLIENT_DATA_TYPE_MISMATCH,\n\t\t\t\t`Expected type \"webauthn.get\", got \"${clientData.type}\"`,\n\t\t\t);\n\t\t}\n\t\tif (!isOriginAllowed(clientData.origin, config.origin)) {\n\t\t\tthrow new PasskeyError(\n\t\t\t\tPASSKEY_ERROR.ORIGIN_MISMATCH,\n\t\t\t\t`Origin mismatch: got \"${clientData.origin}\"`,\n\t\t\t);\n\t\t}\n\n\t\t// 2. Verify challenge\n\t\tconst challengeRows = await db\n\t\t\t.select()\n\t\t\t.from(passkeyChallenges)\n\t\t\t.where(\n\t\t\t\tand(\n\t\t\t\t\teq(passkeyChallenges.challenge, clientData.challenge),\n\t\t\t\t\teq(passkeyChallenges.type, \"authentication\"),\n\t\t\t\t),\n\t\t\t);\n\n\t\tconst challengeRow = challengeRows[0];\n\t\tif (!challengeRow) {\n\t\t\tthrow new PasskeyError(\n\t\t\t\tPASSKEY_ERROR.CHALLENGE_NOT_FOUND,\n\t\t\t\t\"Challenge not found or already used\",\n\t\t\t);\n\t\t}\n\n\t\t// Delete the challenge FIRST (one-time use, prevent replay even if later steps fail)\n\t\tawait db.delete(passkeyChallenges).where(eq(passkeyChallenges.id, challengeRow.id));\n\n\t\tif (challengeRow.expiresAt < new Date()) {\n\t\t\tthrow new PasskeyError(PASSKEY_ERROR.CHALLENGE_EXPIRED, \"Challenge expired\");\n\t\t}\n\n\t\t// 3. Look up credential\n\t\tconst credentialId = response.id;\n\t\tconst credRows = await db\n\t\t\t.select()\n\t\t\t.from(passkeyCredentials)\n\t\t\t.where(eq(passkeyCredentials.credentialId, credentialId));\n\n\t\tconst credRow = credRows[0];\n\t\tif (!credRow) {\n\t\t\tthrow new PasskeyError(PASSKEY_ERROR.CREDENTIAL_NOT_FOUND, \"Credential not found\");\n\t\t}\n\n\t\t// 4. Parse authenticatorData\n\t\tconst authDataBytes = fromBase64Url(response.response.authenticatorData);\n\t\tconst authData = parseAuthData(authDataBytes);\n\n\t\t// 5. Verify rpIdHash\n\t\tconst expectedRpIdHash = new Uint8Array(\n\t\t\tawait webcrypto.subtle.digest(\"SHA-256\", new TextEncoder().encode(config.rpId)),\n\t\t);\n\t\tif (!bytesEqual(authData.rpIdHash, expectedRpIdHash)) {\n\t\t\tthrow new PasskeyError(PASSKEY_ERROR.RPID_MISMATCH, \"rpIdHash mismatch\");\n\t\t}\n\n\t\t// 6. Verify user present flag\n\t\tif (!(authData.flags & FLAG_UP)) {\n\t\t\tthrow new PasskeyError(PASSKEY_ERROR.USER_NOT_PRESENT, \"User present flag not set\");\n\t\t}\n\n\t\t// 6a. Verify user verified flag when required\n\t\tif (userVerification === \"required\" && !(authData.flags & FLAG_UV)) {\n\t\t\tthrow new PasskeyError(\n\t\t\t\tPASSKEY_ERROR.USER_NOT_VERIFIED,\n\t\t\t\t\"User verified flag not set but required\",\n\t\t\t);\n\t\t}\n\n\t\t// 7. Verify signature\n\t\t// Data to verify: authData || SHA-256(clientDataJSON)\n\t\tconst clientDataHash = await sha256(clientDataBytes);\n\t\tconst signedData = new Uint8Array(authDataBytes.length + clientDataHash.length);\n\t\tsignedData.set(authDataBytes, 0);\n\t\tsignedData.set(clientDataHash, authDataBytes.length);\n\n\t\tconst signature = fromBase64Url(response.response.signature);\n\t\tconst publicKeyBytes = fromBase64Url(credRow.publicKey);\n\n\t\tlet valid: boolean;\n\t\ttry {\n\t\t\tvalid = await verifyCoseSignature(publicKeyBytes, signedData, signature);\n\t\t} catch (err) {\n\t\t\tif (err instanceof PasskeyError) throw err;\n\t\t\tthrow new PasskeyError(PASSKEY_ERROR.SIGNATURE_INVALID, \"Signature verification failed\");\n\t\t}\n\n\t\tif (!valid) {\n\t\t\tthrow new PasskeyError(PASSKEY_ERROR.SIGNATURE_INVALID, \"Signature verification failed\");\n\t\t}\n\n\t\t// 8. Check counter (clone detection)\n\t\t// If both the stored counter and the new counter are 0, the authenticator\n\t\t// does not support counters and we skip the check.\n\t\tif (credRow.counter > 0 && authData.signCount <= credRow.counter) {\n\t\t\tthrow new PasskeyError(\n\t\t\t\tPASSKEY_ERROR.SIGN_COUNT_ROLLBACK,\n\t\t\t\t`Sign count rollback detected: stored=${credRow.counter}, received=${authData.signCount}`,\n\t\t\t);\n\t\t}\n\n\t\t// 9. Update counter and lastUsedAt\n\t\tconst now = new Date();\n\t\tawait db\n\t\t\t.update(passkeyCredentials)\n\t\t\t.set({ counter: authData.signCount, lastUsedAt: now })\n\t\t\t.where(eq(passkeyCredentials.id, credRow.id));\n\n\t\tconst credential: PasskeyCredential = {\n\t\t\tid: credRow.id,\n\t\t\tcredentialId: credRow.credentialId,\n\t\t\tpublicKey: credRow.publicKey,\n\t\t\tcounter: authData.signCount,\n\t\t\tuserId: credRow.userId,\n\t\t\tdeviceName: credRow.deviceName ?? undefined,\n\t\t\ttransports: credRow.transports\n\t\t\t\t? (JSON.parse(credRow.transports as string) as string[])\n\t\t\t\t: undefined,\n\t\t\tcreatedAt: credRow.createdAt,\n\t\t\tlastUsedAt: now,\n\t\t};\n\n\t\treturn { userId: credRow.userId, credential };\n\t}\n\n\t// ── listCredentials ──────────────────────────────────────────────────────\n\n\tasync function listCredentials(userId: string): Promise<PasskeyCredential[]> {\n\t\tconst rows = await db\n\t\t\t.select()\n\t\t\t.from(passkeyCredentials)\n\t\t\t.where(eq(passkeyCredentials.userId, userId));\n\n\t\treturn rows.map((r) => ({\n\t\t\tid: r.id,\n\t\t\tcredentialId: r.credentialId,\n\t\t\tpublicKey: r.publicKey,\n\t\t\tcounter: r.counter,\n\t\t\tuserId: r.userId,\n\t\t\tdeviceName: r.deviceName ?? undefined,\n\t\t\ttransports: r.transports ? (JSON.parse(r.transports as string) as string[]) : undefined,\n\t\t\tcreatedAt: r.createdAt,\n\t\t\tlastUsedAt: r.lastUsedAt,\n\t\t}));\n\t}\n\n\t// ── removeCredential ─────────────────────────────────────────────────────\n\n\tasync function removeCredential(credentialId: string, userId: string): Promise<void> {\n\t\tawait db\n\t\t\t.delete(passkeyCredentials)\n\t\t\t.where(\n\t\t\t\tand(\n\t\t\t\t\teq(passkeyCredentials.credentialId, credentialId),\n\t\t\t\t\teq(passkeyCredentials.userId, userId),\n\t\t\t\t),\n\t\t\t);\n\t}\n\n\t// ── handleRequest ────────────────────────────────────────────────────────\n\n\tasync function handleRequest(request: Request): Promise<Response | null> {\n\t\tconst url = new URL(request.url);\n\t\tconst method = request.method.toUpperCase();\n\t\tconst segments = getPathSegments(url);\n\n\t\t// POST /auth/passkey/register/options\n\t\tif (\n\t\t\tmethod === \"POST\" &&\n\t\t\tsegments.length === 4 &&\n\t\t\tsegments[1] === \"passkey\" &&\n\t\t\tsegments[2] === \"register\" &&\n\t\t\tsegments[3] === \"options\"\n\t\t) {\n\t\t\tconst body = await parseBody(request);\n\t\t\tconst userId = typeof body.userId === \"string\" ? body.userId : null;\n\t\t\tconst userName = typeof body.userName === \"string\" ? body.userName : null;\n\t\t\tif (!userId || !userName) {\n\t\t\t\treturn jsonResponse({ error: \"userId and userName required\" }, 400);\n\t\t\t}\n\t\t\ttry {\n\t\t\t\tconst options = await getRegistrationOptions(userId, userName);\n\t\t\t\treturn jsonResponse(options);\n\t\t\t} catch (err) {\n\t\t\t\tconst message = err instanceof Error ? err.message : \"Failed to generate options\";\n\t\t\t\tconst code = err instanceof PasskeyError ? err.code : \"INTERNAL_ERROR\";\n\t\t\t\treturn jsonResponse({ error: message, code }, 500);\n\t\t\t}\n\t\t}\n\n\t\t// POST /auth/passkey/register/verify\n\t\tif (\n\t\t\tmethod === \"POST\" &&\n\t\t\tsegments.length === 4 &&\n\t\t\tsegments[1] === \"passkey\" &&\n\t\t\tsegments[2] === \"register\" &&\n\t\t\tsegments[3] === \"verify\"\n\t\t) {\n\t\t\tconst body = await parseBody(request);\n\t\t\tconst userId = typeof body.userId === \"string\" ? body.userId : null;\n\t\t\tif (!userId) return jsonResponse({ error: \"userId required\" }, 400);\n\n\t\t\tconst resp = body.response as Parameters<PasskeyModule[\"verifyRegistration\"]>[1] | undefined;\n\t\t\tif (!resp) return jsonResponse({ error: \"response required\" }, 400);\n\n\t\t\ttry {\n\t\t\t\tconst result = await verifyRegistration(userId, resp);\n\t\t\t\treturn jsonResponse(result);\n\t\t\t} catch (err) {\n\t\t\t\tconst message = err instanceof Error ? err.message : \"Registration failed\";\n\t\t\t\tconst code = err instanceof PasskeyError ? err.code : \"INTERNAL_ERROR\";\n\t\t\t\treturn jsonResponse({ error: message, code }, 400);\n\t\t\t}\n\t\t}\n\n\t\t// POST /auth/passkey/login/options\n\t\tif (\n\t\t\tmethod === \"POST\" &&\n\t\t\tsegments.length === 4 &&\n\t\t\tsegments[1] === \"passkey\" &&\n\t\t\tsegments[2] === \"login\" &&\n\t\t\tsegments[3] === \"options\"\n\t\t) {\n\t\t\tconst body = await parseBody(request);\n\t\t\tconst userId = typeof body.userId === \"string\" ? body.userId : undefined;\n\t\t\ttry {\n\t\t\t\tconst options = await getAuthenticationOptions(userId);\n\t\t\t\treturn jsonResponse(options);\n\t\t\t} catch (err) {\n\t\t\t\tconst message = err instanceof Error ? err.message : \"Failed to generate options\";\n\t\t\t\tconst code = err instanceof PasskeyError ? err.code : \"INTERNAL_ERROR\";\n\t\t\t\treturn jsonResponse({ error: message, code }, 500);\n\t\t\t}\n\t\t}\n\n\t\t// POST /auth/passkey/login/verify\n\t\tif (\n\t\t\tmethod === \"POST\" &&\n\t\t\tsegments.length === 4 &&\n\t\t\tsegments[1] === \"passkey\" &&\n\t\t\tsegments[2] === \"login\" &&\n\t\t\tsegments[3] === \"verify\"\n\t\t) {\n\t\t\tconst body = await parseBody(request);\n\t\t\tconst resp = body.response as\n\t\t\t\t| Parameters<PasskeyModule[\"verifyAuthentication\"]>[0]\n\t\t\t\t| undefined;\n\t\t\tif (!resp) return jsonResponse({ error: \"response required\" }, 400);\n\n\t\t\ttry {\n\t\t\t\tconst result = await verifyAuthentication(resp);\n\t\t\t\treturn jsonResponse(result);\n\t\t\t} catch (err) {\n\t\t\t\tconst message = err instanceof Error ? err.message : \"Authentication failed\";\n\t\t\t\tconst code = err instanceof PasskeyError ? err.code : \"INTERNAL_ERROR\";\n\t\t\t\treturn jsonResponse({ error: message, code }, 401);\n\t\t\t}\n\t\t}\n\n\t\t// GET /auth/passkey/credentials\n\t\tif (\n\t\t\tmethod === \"GET\" &&\n\t\t\tsegments.length === 3 &&\n\t\t\tsegments[1] === \"passkey\" &&\n\t\t\tsegments[2] === \"credentials\"\n\t\t) {\n\t\t\tconst userId = url.searchParams.get(\"userId\");\n\t\t\tif (!userId) return jsonResponse({ error: \"userId query param required\" }, 400);\n\n\t\t\ttry {\n\t\t\t\tconst creds = await listCredentials(userId);\n\t\t\t\treturn jsonResponse({ credentials: creds });\n\t\t\t} catch (err) {\n\t\t\t\tconst message = err instanceof Error ? err.message : \"Failed to list credentials\";\n\t\t\t\treturn jsonResponse({ error: message }, 500);\n\t\t\t}\n\t\t}\n\n\t\t// DELETE /auth/passkey/credentials/:id\n\t\tif (\n\t\t\tmethod === \"DELETE\" &&\n\t\t\tsegments.length === 4 &&\n\t\t\tsegments[1] === \"passkey\" &&\n\t\t\tsegments[2] === \"credentials\"\n\t\t) {\n\t\t\tconst credentialId = segments[3];\n\t\t\tif (!credentialId) return jsonResponse({ error: \"Credential ID required\" }, 400);\n\n\t\t\tconst body = await parseBody(request);\n\t\t\tconst userId = typeof body.userId === \"string\" ? body.userId : null;\n\t\t\tif (!userId) return jsonResponse({ error: \"userId required\" }, 400);\n\n\t\t\ttry {\n\t\t\t\tawait removeCredential(credentialId, userId);\n\t\t\t\treturn jsonResponse({ removed: true });\n\t\t\t} catch (err) {\n\t\t\t\tconst message = err instanceof Error ? err.message : \"Failed to remove credential\";\n\t\t\t\treturn jsonResponse({ error: message }, 500);\n\t\t\t}\n\t\t}\n\n\t\treturn null;\n\t}\n\n\treturn {\n\t\tgetRegistrationOptions,\n\t\tverifyRegistration,\n\t\tgetAuthenticationOptions,\n\t\tverifyAuthentication,\n\t\tlistCredentials,\n\t\tremoveCredential,\n\t\thandleRequest,\n\t};\n}\n","import type { KavachPlugin } from \"../plugin/types.js\";\nimport type { PasskeyConfig } from \"./passkey.js\";\nimport { createPasskeyModule } from \"./passkey.js\";\n\nexport type { PasskeyConfig };\n\n// ---------------------------------------------------------------------------\n// Helpers\n// ---------------------------------------------------------------------------\n\nfunction jsonResponse(body: unknown, status = 200): Response {\n\treturn new Response(JSON.stringify(body), {\n\t\tstatus,\n\t\theaders: { \"Content-Type\": \"application/json\" },\n\t});\n}\n\nasync function parseBody(request: Request): Promise<Record<string, unknown>> {\n\ttry {\n\t\treturn (await request.json()) as Record<string, unknown>;\n\t} catch {\n\t\treturn {};\n\t}\n}\n\n// ---------------------------------------------------------------------------\n// Plugin factory\n// ---------------------------------------------------------------------------\n\nexport function passkey(config: PasskeyConfig): KavachPlugin {\n\treturn {\n\t\tid: \"kavach-passkey\",\n\n\t\tasync init(ctx): Promise<undefined> {\n\t\t\tconst module = createPasskeyModule(config, ctx.db);\n\n\t\t\t// POST /auth/passkey/register/options\n\t\t\t// Accepts { userId: string; userName: string } and returns WebAuthn\n\t\t\t// registration options to pass to navigator.credentials.create().\n\t\t\tctx.addEndpoint({\n\t\t\t\tmethod: \"POST\",\n\t\t\t\tpath: \"/auth/passkey/register/options\",\n\t\t\t\tmetadata: {\n\t\t\t\t\trequireAuth: true,\n\t\t\t\t\tdescription: \"Get WebAuthn registration options for the authenticated user\",\n\t\t\t\t},\n\t\t\t\tasync handler(request, endpointCtx) {\n\t\t\t\t\tconst user = await endpointCtx.getUser(request);\n\t\t\t\t\tif (!user) {\n\t\t\t\t\t\treturn jsonResponse({ error: \"Authentication required\" }, 401);\n\t\t\t\t\t}\n\n\t\t\t\t\tconst body = await parseBody(request);\n\t\t\t\t\tconst userId = typeof body.userId === \"string\" ? body.userId : user.id;\n\t\t\t\t\tconst userName =\n\t\t\t\t\t\ttypeof body.userName === \"string\" ? body.userName : (user.email ?? user.id);\n\n\t\t\t\t\ttry {\n\t\t\t\t\t\tconst options = await module.getRegistrationOptions(userId, userName);\n\t\t\t\t\t\treturn jsonResponse(options);\n\t\t\t\t\t} catch (err) {\n\t\t\t\t\t\treturn jsonResponse(\n\t\t\t\t\t\t\t{ error: err instanceof Error ? err.message : \"Failed to generate options\" },\n\t\t\t\t\t\t\t500,\n\t\t\t\t\t\t);\n\t\t\t\t\t}\n\t\t\t\t},\n\t\t\t});\n\n\t\t\t// POST /auth/passkey/register/verify\n\t\t\t// Accepts the PublicKeyCredential response from the browser and stores\n\t\t\t// the credential after verifying the attestation.\n\t\t\tctx.addEndpoint({\n\t\t\t\tmethod: \"POST\",\n\t\t\t\tpath: \"/auth/passkey/register/verify\",\n\t\t\t\tmetadata: {\n\t\t\t\t\trequireAuth: true,\n\t\t\t\t\tdescription: \"Verify WebAuthn registration and store the credential\",\n\t\t\t\t},\n\t\t\t\tasync handler(request, endpointCtx) {\n\t\t\t\t\tconst user = await endpointCtx.getUser(request);\n\t\t\t\t\tif (!user) {\n\t\t\t\t\t\treturn jsonResponse({ error: \"Authentication required\" }, 401);\n\t\t\t\t\t}\n\n\t\t\t\t\tconst body = await parseBody(request);\n\t\t\t\t\tconst userId = typeof body.userId === \"string\" ? body.userId : user.id;\n\t\t\t\t\tconst response = body.response as\n\t\t\t\t\t\t| Parameters<typeof module.verifyRegistration>[1]\n\t\t\t\t\t\t| undefined;\n\n\t\t\t\t\tif (!response) {\n\t\t\t\t\t\treturn jsonResponse({ error: \"Missing required field: response\" }, 400);\n\t\t\t\t\t}\n\n\t\t\t\t\ttry {\n\t\t\t\t\t\tconst result = await module.verifyRegistration(userId, response);\n\t\t\t\t\t\treturn jsonResponse(result);\n\t\t\t\t\t} catch (err) {\n\t\t\t\t\t\treturn jsonResponse(\n\t\t\t\t\t\t\t{ error: err instanceof Error ? err.message : \"Registration failed\" },\n\t\t\t\t\t\t\t400,\n\t\t\t\t\t\t);\n\t\t\t\t\t}\n\t\t\t\t},\n\t\t\t});\n\n\t\t\t// POST /auth/passkey/authenticate/options\n\t\t\t// Returns a WebAuthn authentication challenge. Pass userId to limit\n\t\t\t// the allowed credentials to those belonging to that user.\n\t\t\tctx.addEndpoint({\n\t\t\t\tmethod: \"POST\",\n\t\t\t\tpath: \"/auth/passkey/authenticate/options\",\n\t\t\t\tmetadata: {\n\t\t\t\t\tdescription: \"Get WebAuthn authentication options\",\n\t\t\t\t},\n\t\t\t\tasync handler(request) {\n\t\t\t\t\tconst body = await parseBody(request);\n\t\t\t\t\tconst userId = typeof body.userId === \"string\" ? body.userId : undefined;\n\n\t\t\t\t\ttry {\n\t\t\t\t\t\tconst options = await module.getAuthenticationOptions(userId);\n\t\t\t\t\t\treturn jsonResponse(options);\n\t\t\t\t\t} catch (err) {\n\t\t\t\t\t\treturn jsonResponse(\n\t\t\t\t\t\t\t{ error: err instanceof Error ? err.message : \"Failed to generate options\" },\n\t\t\t\t\t\t\t500,\n\t\t\t\t\t\t);\n\t\t\t\t\t}\n\t\t\t\t},\n\t\t\t});\n\n\t\t\t// POST /auth/passkey/authenticate/verify\n\t\t\t// Verifies the authenticator assertion and returns userId + credential.\n\t\t\tctx.addEndpoint({\n\t\t\t\tmethod: \"POST\",\n\t\t\t\tpath: \"/auth/passkey/authenticate/verify\",\n\t\t\t\tmetadata: {\n\t\t\t\t\tdescription: \"Verify a WebAuthn assertion and return the authenticated user\",\n\t\t\t\t},\n\t\t\t\tasync handler(request) {\n\t\t\t\t\tconst body = await parseBody(request);\n\t\t\t\t\tconst response = body.response as\n\t\t\t\t\t\t| Parameters<typeof module.verifyAuthentication>[0]\n\t\t\t\t\t\t| undefined;\n\n\t\t\t\t\tif (!response) {\n\t\t\t\t\t\treturn jsonResponse({ error: \"Missing required field: response\" }, 400);\n\t\t\t\t\t}\n\n\t\t\t\t\ttry {\n\t\t\t\t\t\tconst result = await module.verifyAuthentication(response);\n\t\t\t\t\t\tif (!result) {\n\t\t\t\t\t\t\treturn jsonResponse({ error: \"Authentication failed\" }, 401);\n\t\t\t\t\t\t}\n\t\t\t\t\t\treturn jsonResponse(result);\n\t\t\t\t\t} catch (err) {\n\t\t\t\t\t\treturn jsonResponse(\n\t\t\t\t\t\t\t{ error: err instanceof Error ? err.message : \"Authentication failed\" },\n\t\t\t\t\t\t\t401,\n\t\t\t\t\t\t);\n\t\t\t\t\t}\n\t\t\t\t},\n\t\t\t});\n\n\t\t\t// GET /auth/passkey/credentials\n\t\t\t// Lists all passkey credentials for the authenticated user.\n\t\t\tctx.addEndpoint({\n\t\t\t\tmethod: \"GET\",\n\t\t\t\tpath: \"/auth/passkey/credentials\",\n\t\t\t\tmetadata: {\n\t\t\t\t\trequireAuth: true,\n\t\t\t\t\tdescription: \"List passkey credentials for the authenticated user\",\n\t\t\t\t},\n\t\t\t\tasync handler(request, endpointCtx) {\n\t\t\t\t\tconst user = await endpointCtx.getUser(request);\n\t\t\t\t\tif (!user) {\n\t\t\t\t\t\treturn jsonResponse({ error: \"Authentication required\" }, 401);\n\t\t\t\t\t}\n\n\t\t\t\t\ttry {\n\t\t\t\t\t\tconst credentials = await module.listCredentials(user.id);\n\t\t\t\t\t\treturn jsonResponse({ credentials });\n\t\t\t\t\t} catch (err) {\n\t\t\t\t\t\treturn jsonResponse(\n\t\t\t\t\t\t\t{ error: err instanceof Error ? err.message : \"Failed to list credentials\" },\n\t\t\t\t\t\t\t500,\n\t\t\t\t\t\t);\n\t\t\t\t\t}\n\t\t\t\t},\n\t\t\t});\n\n\t\t\t// DELETE /auth/passkey/credentials/:id\n\t\t\t// Removes a specific passkey credential belonging to the authenticated user.\n\t\t\tctx.addEndpoint({\n\t\t\t\tmethod: \"DELETE\",\n\t\t\t\tpath: \"/auth/passkey/credentials/:id\",\n\t\t\t\tmetadata: {\n\t\t\t\t\trequireAuth: true,\n\t\t\t\t\tdescription: \"Remove a passkey credential for the authenticated user\",\n\t\t\t\t},\n\t\t\t\tasync handler(request, endpointCtx) {\n\t\t\t\t\tconst user = await endpointCtx.getUser(request);\n\t\t\t\t\tif (!user) {\n\t\t\t\t\t\treturn jsonResponse({ error: \"Authentication required\" }, 401);\n\t\t\t\t\t}\n\n\t\t\t\t\tconst url = new URL(request.url);\n\t\t\t\t\tconst segments = url.pathname.split(\"/\").filter(Boolean);\n\t\t\t\t\t// Expected: [\"auth\", \"passkey\", \"credentials\", \"<id>\"]\n\t\t\t\t\tconst credentialId = segments[3];\n\n\t\t\t\t\tif (!credentialId) {\n\t\t\t\t\t\treturn jsonResponse({ error: \"Missing credential ID in path\" }, 400);\n\t\t\t\t\t}\n\n\t\t\t\t\ttry {\n\t\t\t\t\t\tawait module.removeCredential(credentialId, user.id);\n\t\t\t\t\t\treturn jsonResponse({ removed: true });\n\t\t\t\t\t} catch (err) {\n\t\t\t\t\t\treturn jsonResponse(\n\t\t\t\t\t\t\t{ error: err instanceof Error ? err.message : \"Failed to remove credential\" },\n\t\t\t\t\t\t\t500,\n\t\t\t\t\t\t);\n\t\t\t\t\t}\n\t\t\t\t},\n\t\t\t});\n\t\t},\n\t};\n}\n","/**\n * Phone number (SMS OTP) authentication for KavachOS.\n *\n * Generates a short numeric code, hashes it with SHA-256 before storage, and\n * calls the caller-provided `sendSms` function. On verification the hash is\n * compared in constant time to prevent timing attacks.\n *\n * @example\n * ```typescript\n * const kavach = await createKavach({\n * database: { provider: 'sqlite', url: 'kavach.db' },\n * auth: { session: { secret: process.env.SESSION_SECRET } },\n * phone: {\n * sendSms: async (phone, code) => {\n * await twilio.messages.create({ to: phone, body: `Your code: ${code}` });\n * },\n * },\n * });\n * ```\n */\n\nimport { createHash, randomUUID, timingSafeEqual } from \"node:crypto\";\nimport { and, eq, gt } from \"drizzle-orm\";\nimport type { Database } from \"../db/database.js\";\nimport { phoneVerifications, users } from \"../db/schema.js\";\nimport type { SessionManager } from \"../session/session.js\";\n\n// ---------------------------------------------------------------------------\n// Public types\n// ---------------------------------------------------------------------------\n\nexport interface PhoneAuthConfig {\n\t/** Called to deliver the OTP code to the user via SMS. */\n\tsendSms: (phoneNumber: string, code: string) => Promise<void>;\n\t/** Digit length of the generated code (default: 6) */\n\tcodeLength?: number;\n\t/** Code expiry in seconds (default: 300) */\n\tcodeExpiry?: number;\n\t/** Max verification attempts before code is invalidated (default: 5) */\n\tmaxAttempts?: number;\n}\n\nexport interface PhoneAuthModule {\n\t/** Send a one-time code to the phone number. */\n\tsendCode: (phoneNumber: string) => Promise<{ sent: boolean }>;\n\t/**\n\t * Verify the code for the given phone number.\n\t * Returns null when the code is wrong, expired, or attempts exceeded.\n\t */\n\tverifyCode: (\n\t\tphoneNumber: string,\n\t\tcode: string,\n\t) => Promise<{\n\t\tuser: { id: string; phone: string };\n\t\tsession: { token: string; expiresAt: Date };\n\t} | null>;\n\t/**\n\t * Handle an incoming HTTP request.\n\t *\n\t * - `POST /auth/phone/send-code` – JSON body `{ phoneNumber: string }`\n\t * - `POST /auth/phone/verify` – JSON body `{ phoneNumber: string; code: string }`\n\t *\n\t * Returns null when the path does not match.\n\t */\n\thandleRequest: (request: Request) => Promise<Response | null>;\n}\n\n// ---------------------------------------------------------------------------\n// Defaults\n// ---------------------------------------------------------------------------\n\nconst DEFAULT_CODE_LENGTH = 6;\nconst DEFAULT_CODE_EXPIRY_SECONDS = 300;\nconst DEFAULT_MAX_ATTEMPTS = 5;\n\n// ---------------------------------------------------------------------------\n// Helpers\n// ---------------------------------------------------------------------------\n\nfunction hashCode(code: string): string {\n\treturn createHash(\"sha256\").update(code).digest(\"hex\");\n}\n\nfunction codesEqual(stored: string, candidate: string): boolean {\n\tconst a = Buffer.from(stored, \"hex\");\n\tconst b = Buffer.from(hashCode(candidate), \"hex\");\n\tif (a.byteLength !== b.byteLength) return false;\n\treturn timingSafeEqual(a, b);\n}\n\nfunction generateNumericCode(length: number): string {\n\tconst digits: string[] = [];\n\twhile (digits.length < length) {\n\t\tfor (const char of randomUUID().replace(/-/g, \"\")) {\n\t\t\tif (digits.length >= length) break;\n\t\t\tconst num = parseInt(char, 16);\n\t\t\tif (num < 10) digits.push(String(num));\n\t\t}\n\t}\n\treturn digits.join(\"\");\n}\n\nfunction normalisePhone(phone: string): string {\n\t// Remove all whitespace; caller is responsible for E.164 formatting\n\treturn phone.replace(/\\s+/g, \"\");\n}\n\nfunction jsonResponse(body: unknown, status = 200): Response {\n\treturn new Response(JSON.stringify(body), {\n\t\tstatus,\n\t\theaders: { \"Content-Type\": \"application/json\" },\n\t});\n}\n\n// ---------------------------------------------------------------------------\n// Factory\n// ---------------------------------------------------------------------------\n\nexport function createPhoneAuthModule(\n\tconfig: PhoneAuthConfig,\n\tdb: Database,\n\tsessionManager: SessionManager,\n): PhoneAuthModule {\n\tconst codeLength = config.codeLength ?? DEFAULT_CODE_LENGTH;\n\tconst codeExpiry = config.codeExpiry ?? DEFAULT_CODE_EXPIRY_SECONDS;\n\tconst maxAttempts = config.maxAttempts ?? DEFAULT_MAX_ATTEMPTS;\n\n\tasync function findOrCreateUser(phone: string): Promise<{ id: string; phone: string }> {\n\t\t// Look up user by phone number stored in metadata\n\t\tconst allUsers = await db.select({ id: users.id, metadata: users.metadata }).from(users);\n\n\t\tfor (const u of allUsers) {\n\t\t\tif (u.metadata?.phone === phone) {\n\t\t\t\treturn { id: u.id, phone };\n\t\t\t}\n\t\t}\n\n\t\tconst id = randomUUID();\n\t\tconst now = new Date();\n\t\tawait db.insert(users).values({\n\t\t\tid,\n\t\t\temail: `${phone.replace(/\\+/g, \"\")}@phone.local`,\n\t\t\tmetadata: { phone },\n\t\t\tcreatedAt: now,\n\t\t\tupdatedAt: now,\n\t\t});\n\n\t\treturn { id, phone };\n\t}\n\n\t// ── public API ─────────────────────────────────────────────────────────\n\n\tasync function sendCode(phoneNumber: string): Promise<{ sent: boolean }> {\n\t\tconst phone = normalisePhone(phoneNumber);\n\t\tconst code = generateNumericCode(codeLength);\n\t\tconst now = new Date();\n\t\tconst expiresAt = new Date(now.getTime() + codeExpiry * 1000);\n\n\t\t// Replace any existing record for this phone number\n\t\tawait db.delete(phoneVerifications).where(eq(phoneVerifications.phoneNumber, phone));\n\n\t\tawait db.insert(phoneVerifications).values({\n\t\t\tid: randomUUID(),\n\t\t\tphoneNumber: phone,\n\t\t\tcodeHash: hashCode(code),\n\t\t\tattempts: 0,\n\t\t\texpiresAt,\n\t\t\tcreatedAt: now,\n\t\t});\n\n\t\tawait config.sendSms(phone, code);\n\n\t\treturn { sent: true };\n\t}\n\n\tasync function verifyCode(\n\t\tphoneNumber: string,\n\t\tcode: string,\n\t): Promise<{\n\t\tuser: { id: string; phone: string };\n\t\tsession: { token: string; expiresAt: Date };\n\t} | null> {\n\t\tconst phone = normalisePhone(phoneNumber);\n\t\tconst now = new Date();\n\n\t\tconst rows = await db\n\t\t\t.select()\n\t\t\t.from(phoneVerifications)\n\t\t\t.where(and(eq(phoneVerifications.phoneNumber, phone), gt(phoneVerifications.expiresAt, now)));\n\n\t\tconst record = rows[0];\n\t\tif (!record) return null;\n\n\t\tif (record.attempts >= maxAttempts) return null;\n\n\t\t// Increment attempts before checking — prevents timing probes\n\t\tawait db\n\t\t\t.update(phoneVerifications)\n\t\t\t.set({ attempts: record.attempts + 1 })\n\t\t\t.where(eq(phoneVerifications.id, record.id));\n\n\t\tif (!codesEqual(record.codeHash, code)) return null;\n\n\t\t// Code verified — remove record to prevent re-use\n\t\tawait db.delete(phoneVerifications).where(eq(phoneVerifications.id, record.id));\n\n\t\tconst user = await findOrCreateUser(phone);\n\t\tconst { token, session } = await sessionManager.create(user.id);\n\n\t\treturn {\n\t\t\tuser,\n\t\t\tsession: { token, expiresAt: session.expiresAt },\n\t\t};\n\t}\n\n\tconst HANDLED_PATHS = new Set([\"/auth/phone/send-code\", \"/auth/phone/verify\"]);\n\n\tasync function handleRequest(request: Request): Promise<Response | null> {\n\t\tif (request.method !== \"POST\") return null;\n\n\t\tconst url = new URL(request.url);\n\t\tconst { pathname } = url;\n\n\t\tif (!HANDLED_PATHS.has(pathname)) return null;\n\n\t\tlet body: unknown;\n\t\ttry {\n\t\t\tbody = await request.json();\n\t\t} catch {\n\t\t\treturn jsonResponse({ error: \"Invalid JSON body\" }, 400);\n\t\t}\n\n\t\tconst b = body as Record<string, unknown>;\n\n\t\tif (pathname === \"/auth/phone/send-code\") {\n\t\t\tif (typeof b.phoneNumber !== \"string\") {\n\t\t\t\treturn jsonResponse({ error: \"Missing required field: phoneNumber\" }, 400);\n\t\t\t}\n\t\t\tconst result = await sendCode(b.phoneNumber);\n\t\t\treturn jsonResponse(result);\n\t\t}\n\n\t\tif (pathname === \"/auth/phone/verify\") {\n\t\t\tif (typeof b.phoneNumber !== \"string\" || typeof b.code !== \"string\") {\n\t\t\t\treturn jsonResponse({ error: \"Missing required fields: phoneNumber, code\" }, 400);\n\t\t\t}\n\t\t\tconst result = await verifyCode(b.phoneNumber, b.code);\n\t\t\tif (!result) {\n\t\t\t\treturn jsonResponse({ error: \"Invalid or expired code\" }, 401);\n\t\t\t}\n\t\t\treturn jsonResponse(result);\n\t\t}\n\n\t\treturn null;\n\t}\n\n\treturn { sendCode, verifyCode, handleRequest };\n}\n","/**\n * Polar payment integration for KavachOS.\n *\n * Links Polar customers to KavachOS users, handles subscription lifecycle\n * webhooks, and stores subscription status. Uses Polar's REST API directly\n * via fetch — no Polar SDK dependency.\n *\n * @example\n * ```typescript\n * import { createPolarModule } from 'kavachos/auth';\n *\n * const polar = createPolarModule({\n * accessToken: process.env.POLAR_ACCESS_TOKEN!,\n * webhookSecret: process.env.POLAR_WEBHOOK_SECRET!,\n * sandbox: process.env.NODE_ENV !== 'production',\n * onSubscriptionChange: async (userId, sub) => {\n * console.log(`User ${userId} subscription: ${sub.status}`);\n * },\n * }, db);\n *\n * const { url } = await polar.createCheckout(userId, 'product_xxx', {\n * successUrl: 'https://example.com/success',\n * });\n * ```\n */\n\nimport { eq } from \"drizzle-orm\";\nimport type { Database } from \"../db/database.js\";\nimport { users } from \"../db/schema.js\";\n\n// ---------------------------------------------------------------------------\n// Public types\n// ---------------------------------------------------------------------------\n\nexport interface PolarConfig {\n\t/** Polar access token */\n\taccessToken: string;\n\t/** Polar webhook secret for HMAC-SHA256 signature verification */\n\twebhookSecret: string;\n\t/** Optional organization ID to scope requests */\n\torganizationId?: string;\n\t/** Use sandbox.polar.sh instead of polar.sh (default: false) */\n\tsandbox?: boolean;\n\t/** Callback fired whenever subscription data changes for a user */\n\tonSubscriptionChange?: (userId: string, subscription: PolarSubscription) => Promise<void>;\n}\n\nexport interface PolarSubscription {\n\tid: string;\n\tstatus: \"active\" | \"canceled\" | \"incomplete\" | \"past_due\" | \"trialing\" | \"unpaid\";\n\tproductId: string;\n\tcurrentPeriodEnd: Date;\n\tcancelAtPeriodEnd: boolean;\n}\n\nexport interface PolarModule {\n\t/** Create a Polar checkout session and return its URL + ID */\n\tcreateCheckout(\n\t\tuserId: string,\n\t\tproductId: string,\n\t\toptions?: { successUrl?: string; customerEmail?: string },\n\t): Promise<{ url: string; id: string }>;\n\t/** Return current subscription info for a user from the database */\n\tgetSubscription(userId: string): Promise<PolarSubscription | null>;\n\t/** Verify Polar webhook signature and dispatch to internal handlers */\n\thandleWebhook(request: Request): Promise<Response>;\n\t/** Route an incoming HTTP request to the appropriate handler (returns null if path unmatched) */\n\thandleRequest(request: Request): Promise<Response | null>;\n}\n\n// ---------------------------------------------------------------------------\n// Internal Polar REST types (minimal — only fields we use)\n// ---------------------------------------------------------------------------\n\ninterface PolarCheckoutResponse {\n\tid: string;\n\turl: string;\n\tcustomer_id: string | null;\n}\n\ninterface PolarSubscriptionResponse {\n\tid: string;\n\tstatus: string;\n\tproduct_id: string;\n\tcustomer_id: string;\n\tcurrent_period_end: string;\n\tcancel_at_period_end: boolean;\n\tuser_id?: string | null;\n\tmetadata?: Record<string, string> | null;\n}\n\ninterface PolarWebhookEvent {\n\ttype: string;\n\tdata: Record<string, unknown>;\n}\n\n// ---------------------------------------------------------------------------\n// Polar REST API client helpers\n// ---------------------------------------------------------------------------\n\nconst POLAR_API_BASE = \"https://api.polar.sh/v1\";\nconst POLAR_SANDBOX_API_BASE = \"https://sandbox.api.polar.sh/v1\";\n\nasync function polarRequest<T>(\n\taccessToken: string,\n\tbaseUrl: string,\n\tmethod: \"GET\" | \"POST\",\n\tpath: string,\n\tbody?: Record<string, unknown>,\n): Promise<T> {\n\tconst url = `${baseUrl}${path}`;\n\tconst headers: Record<string, string> = {\n\t\tAuthorization: `Bearer ${accessToken}`,\n\t\t\"Content-Type\": \"application/json\",\n\t\tAccept: \"application/json\",\n\t};\n\n\tconst response = await fetch(url, {\n\t\tmethod,\n\t\theaders,\n\t\tbody: body !== undefined ? JSON.stringify(body) : undefined,\n\t});\n\n\tconst json = (await response.json()) as { detail?: string; message?: string } & T;\n\n\tif (!response.ok) {\n\t\tconst message =\n\t\t\t(json as { detail?: string }).detail ??\n\t\t\t(json as { message?: string }).message ??\n\t\t\t`Polar API error: ${response.status}`;\n\t\tthrow new Error(message);\n\t}\n\n\treturn json as T;\n}\n\n// ---------------------------------------------------------------------------\n// Webhook signature verification (HMAC-SHA256)\n// ---------------------------------------------------------------------------\n\nasync function verifyWebhookSignature(\n\tpayload: string,\n\tsignatureHeader: string,\n\twebhookSecret: string,\n): Promise<PolarWebhookEvent> {\n\t// Polar sends: webhook-signature: sha256=<hex>\n\tconst prefix = \"sha256=\";\n\tconst receivedSig = signatureHeader.startsWith(prefix)\n\t\t? signatureHeader.slice(prefix.length)\n\t\t: null;\n\n\tif (!receivedSig) {\n\t\tthrow new Error(\"Invalid webhook-signature header format\");\n\t}\n\n\tconst encoder = new TextEncoder();\n\tconst keyData = encoder.encode(webhookSecret);\n\tconst msgData = encoder.encode(payload);\n\n\tconst cryptoKey = await crypto.subtle.importKey(\n\t\t\"raw\",\n\t\tkeyData,\n\t\t{ name: \"HMAC\", hash: \"SHA-256\" },\n\t\tfalse,\n\t\t[\"sign\"],\n\t);\n\n\tconst signatureBuffer = await crypto.subtle.sign(\"HMAC\", cryptoKey, msgData);\n\tconst expectedSig = Array.from(new Uint8Array(signatureBuffer))\n\t\t.map((b) => b.toString(16).padStart(2, \"0\"))\n\t\t.join(\"\");\n\n\t// Constant-time comparison\n\tif (receivedSig.length !== expectedSig.length) {\n\t\tthrow new Error(\"Polar webhook signature verification failed\");\n\t}\n\n\tconst a = encoder.encode(receivedSig);\n\tconst b = encoder.encode(expectedSig);\n\tlet diff = 0;\n\tfor (let i = 0; i < a.length; i++) {\n\t\tdiff |= (a[i] ?? 0) ^ (b[i] ?? 0);\n\t}\n\n\tif (diff !== 0) {\n\t\tthrow new Error(\"Polar webhook signature verification failed\");\n\t}\n\n\treturn JSON.parse(payload) as PolarWebhookEvent;\n}\n\n// ---------------------------------------------------------------------------\n// Module factory\n// ---------------------------------------------------------------------------\n\nexport function createPolarModule(config: PolarConfig, db: Database): PolarModule {\n\tconst baseUrl = config.sandbox ? POLAR_SANDBOX_API_BASE : POLAR_API_BASE;\n\n\tfunction api<T>(\n\t\tmethod: \"GET\" | \"POST\",\n\t\tpath: string,\n\t\tbody?: Record<string, unknown>,\n\t): Promise<T> {\n\t\treturn polarRequest<T>(config.accessToken, baseUrl, method, path, body);\n\t}\n\n\t// -------------------------------------------------------------------------\n\t// Internal helpers\n\t// -------------------------------------------------------------------------\n\n\tasync function getUserRow(userId: string) {\n\t\tconst rows = await db.select().from(users).where(eq(users.id, userId)).limit(1);\n\t\treturn rows[0] ?? null;\n\t}\n\n\tasync function findUserByPolarCustomerId(customerId: string) {\n\t\tconst rows = await db\n\t\t\t.select()\n\t\t\t.from(users)\n\t\t\t.where(eq(users.polarCustomerId, customerId))\n\t\t\t.limit(1);\n\t\treturn rows[0] ?? null;\n\t}\n\n\tasync function persistSubscription(\n\t\tuserId: string,\n\t\tsub: PolarSubscriptionResponse,\n\t): Promise<PolarSubscription> {\n\t\tconst currentPeriodEnd = new Date(sub.current_period_end);\n\t\tconst status = sub.status as PolarSubscription[\"status\"];\n\n\t\tawait db\n\t\t\t.update(users)\n\t\t\t.set({\n\t\t\t\tpolarSubscriptionId: sub.id,\n\t\t\t\tpolarSubscriptionStatus: sub.status,\n\t\t\t\tpolarProductId: sub.product_id,\n\t\t\t\tpolarCurrentPeriodEnd: currentPeriodEnd,\n\t\t\t\tpolarCancelAtPeriodEnd: sub.cancel_at_period_end,\n\t\t\t\tupdatedAt: new Date(),\n\t\t\t})\n\t\t\t.where(eq(users.id, userId));\n\n\t\tconst info: PolarSubscription = {\n\t\t\tid: sub.id,\n\t\t\tstatus,\n\t\t\tproductId: sub.product_id,\n\t\t\tcurrentPeriodEnd,\n\t\t\tcancelAtPeriodEnd: sub.cancel_at_period_end,\n\t\t};\n\n\t\tif (config.onSubscriptionChange) {\n\t\t\tawait config.onSubscriptionChange(userId, info);\n\t\t}\n\n\t\treturn info;\n\t}\n\n\tasync function clearSubscription(userId: string): Promise<void> {\n\t\tawait db\n\t\t\t.update(users)\n\t\t\t.set({\n\t\t\t\tpolarSubscriptionId: null,\n\t\t\t\tpolarSubscriptionStatus: \"canceled\",\n\t\t\t\tpolarProductId: null,\n\t\t\t\tpolarCurrentPeriodEnd: null,\n\t\t\t\tpolarCancelAtPeriodEnd: false,\n\t\t\t\tupdatedAt: new Date(),\n\t\t\t})\n\t\t\t.where(eq(users.id, userId));\n\t}\n\n\t// -------------------------------------------------------------------------\n\t// Webhook event handlers\n\t// -------------------------------------------------------------------------\n\n\tasync function handleSubscriptionCreatedOrUpdated(obj: Record<string, unknown>): Promise<void> {\n\t\tconst sub = obj as unknown as PolarSubscriptionResponse;\n\n\t\t// Resolve userId from metadata or customer lookup\n\t\tlet userId: string | null = null;\n\n\t\tconst metadata = sub.metadata;\n\t\tif (metadata && typeof metadata === \"object\" && typeof metadata.kavach_user_id === \"string\") {\n\t\t\tuserId = metadata.kavach_user_id;\n\t\t}\n\n\t\tif (!userId && sub.customer_id) {\n\t\t\tconst user = await findUserByPolarCustomerId(sub.customer_id);\n\t\t\tuserId = user?.id ?? null;\n\t\t}\n\n\t\tif (!userId) return;\n\n\t\t// Link the customer ID if not yet stored\n\t\tconst userRow = await getUserRow(userId);\n\t\tif (userRow && !userRow.polarCustomerId && sub.customer_id) {\n\t\t\tawait db\n\t\t\t\t.update(users)\n\t\t\t\t.set({ polarCustomerId: sub.customer_id, updatedAt: new Date() })\n\t\t\t\t.where(eq(users.id, userId));\n\t\t}\n\n\t\tawait persistSubscription(userId, sub);\n\t}\n\n\tasync function handleSubscriptionRevoked(obj: Record<string, unknown>): Promise<void> {\n\t\tconst sub = obj as unknown as PolarSubscriptionResponse;\n\n\t\tlet userId: string | null = null;\n\n\t\tconst metadata = sub.metadata;\n\t\tif (metadata && typeof metadata === \"object\" && typeof metadata.kavach_user_id === \"string\") {\n\t\t\tuserId = metadata.kavach_user_id;\n\t\t}\n\n\t\tif (!userId && sub.customer_id) {\n\t\t\tconst user = await findUserByPolarCustomerId(sub.customer_id);\n\t\t\tuserId = user?.id ?? null;\n\t\t}\n\n\t\tif (!userId) return;\n\n\t\tawait clearSubscription(userId);\n\n\t\tif (config.onSubscriptionChange) {\n\t\t\tawait config.onSubscriptionChange(userId, {\n\t\t\t\tid: sub.id,\n\t\t\t\tstatus: \"canceled\",\n\t\t\t\tproductId: sub.product_id,\n\t\t\t\tcurrentPeriodEnd: new Date(sub.current_period_end),\n\t\t\t\tcancelAtPeriodEnd: false,\n\t\t\t});\n\t\t}\n\t}\n\n\t// -------------------------------------------------------------------------\n\t// Public API\n\t// -------------------------------------------------------------------------\n\n\tasync function createCheckout(\n\t\tuserId: string,\n\t\tproductId: string,\n\t\toptions: { successUrl?: string; customerEmail?: string } = {},\n\t): Promise<{ url: string; id: string }> {\n\t\tconst userRow = await getUserRow(userId);\n\t\tif (!userRow) {\n\t\t\tthrow new Error(`User not found: ${userId}`);\n\t\t}\n\n\t\tconst body: Record<string, unknown> = {\n\t\t\tproduct_id: productId,\n\t\t\tmetadata: { kavach_user_id: userId },\n\t\t};\n\n\t\tif (options.successUrl) {\n\t\t\tbody.success_url = options.successUrl;\n\t\t}\n\n\t\tif (options.customerEmail ?? userRow.email) {\n\t\t\tbody.customer_email = options.customerEmail ?? userRow.email;\n\t\t}\n\n\t\tif (config.organizationId) {\n\t\t\tbody.organization_id = config.organizationId;\n\t\t}\n\n\t\tconst checkout = await api<PolarCheckoutResponse>(\"POST\", \"/checkouts/custom\", body);\n\n\t\treturn { url: checkout.url, id: checkout.id };\n\t}\n\n\tasync function getSubscription(userId: string): Promise<PolarSubscription | null> {\n\t\tconst row = await getUserRow(userId);\n\t\tif (\n\t\t\t!row?.polarSubscriptionId ||\n\t\t\t!row.polarSubscriptionStatus ||\n\t\t\t!row.polarProductId ||\n\t\t\t!row.polarCurrentPeriodEnd\n\t\t) {\n\t\t\treturn null;\n\t\t}\n\n\t\treturn {\n\t\t\tid: row.polarSubscriptionId,\n\t\t\tstatus: row.polarSubscriptionStatus as PolarSubscription[\"status\"],\n\t\t\tproductId: row.polarProductId,\n\t\t\tcurrentPeriodEnd: row.polarCurrentPeriodEnd,\n\t\t\tcancelAtPeriodEnd: row.polarCancelAtPeriodEnd,\n\t\t};\n\t}\n\n\tasync function handleWebhook(request: Request): Promise<Response> {\n\t\tconst signatureHeader = request.headers.get(\"webhook-signature\");\n\t\tif (!signatureHeader) {\n\t\t\treturn new Response(JSON.stringify({ error: \"Missing webhook-signature header\" }), {\n\t\t\t\tstatus: 400,\n\t\t\t\theaders: { \"Content-Type\": \"application/json\" },\n\t\t\t});\n\t\t}\n\n\t\tlet payload: string;\n\t\ttry {\n\t\t\tpayload = await request.text();\n\t\t} catch {\n\t\t\treturn new Response(JSON.stringify({ error: \"Failed to read request body\" }), {\n\t\t\t\tstatus: 400,\n\t\t\t\theaders: { \"Content-Type\": \"application/json\" },\n\t\t\t});\n\t\t}\n\n\t\tlet event: PolarWebhookEvent;\n\t\ttry {\n\t\t\tevent = await verifyWebhookSignature(payload, signatureHeader, config.webhookSecret);\n\t\t} catch (err) {\n\t\t\treturn new Response(\n\t\t\t\tJSON.stringify({\n\t\t\t\t\terror: err instanceof Error ? err.message : \"Webhook verification failed\",\n\t\t\t\t}),\n\t\t\t\t{ status: 400, headers: { \"Content-Type\": \"application/json\" } },\n\t\t\t);\n\t\t}\n\n\t\ttry {\n\t\t\tswitch (event.type) {\n\t\t\t\tcase \"subscription.created\":\n\t\t\t\tcase \"subscription.updated\":\n\t\t\t\t\tawait handleSubscriptionCreatedOrUpdated(event.data);\n\t\t\t\t\tbreak;\n\t\t\t\tcase \"subscription.revoked\":\n\t\t\t\t\tawait handleSubscriptionRevoked(event.data);\n\t\t\t\t\tbreak;\n\t\t\t\t// Other event types are silently ignored\n\t\t\t}\n\t\t} catch (err) {\n\t\t\treturn new Response(\n\t\t\t\tJSON.stringify({\n\t\t\t\t\terror: err instanceof Error ? err.message : \"Webhook handler error\",\n\t\t\t\t}),\n\t\t\t\t{ status: 500, headers: { \"Content-Type\": \"application/json\" } },\n\t\t\t);\n\t\t}\n\n\t\treturn new Response(JSON.stringify({ received: true }), {\n\t\t\tstatus: 200,\n\t\t\theaders: { \"Content-Type\": \"application/json\" },\n\t\t});\n\t}\n\n\tasync function handleRequest(request: Request): Promise<Response | null> {\n\t\tconst url = new URL(request.url);\n\t\tconst path = url.pathname;\n\n\t\tif (request.method === \"POST\" && path.endsWith(\"/auth/polar/webhook\")) {\n\t\t\treturn handleWebhook(request);\n\t\t}\n\n\t\treturn null;\n\t}\n\n\treturn {\n\t\tcreateCheckout,\n\t\tgetSubscription,\n\t\thandleWebhook,\n\t\thandleRequest,\n\t};\n}\n","import type { KavachPlugin } from \"../plugin/types.js\";\nimport type { PolarConfig } from \"./polar.js\";\nimport { createPolarModule } from \"./polar.js\";\n\nexport type { PolarConfig };\n\n// ---------------------------------------------------------------------------\n// Helpers\n// ---------------------------------------------------------------------------\n\nfunction json(body: unknown, status = 200): Response {\n\treturn new Response(JSON.stringify(body), {\n\t\tstatus,\n\t\theaders: { \"Content-Type\": \"application/json\" },\n\t});\n}\n\nasync function parseBody(request: Request): Promise<Record<string, unknown>> {\n\ttry {\n\t\treturn (await request.json()) as Record<string, unknown>;\n\t} catch {\n\t\treturn {};\n\t}\n}\n\n// ---------------------------------------------------------------------------\n// Plugin factory\n// ---------------------------------------------------------------------------\n\nexport function polar(config: PolarConfig): KavachPlugin {\n\treturn {\n\t\tid: \"kavach-polar\",\n\n\t\tasync init(ctx): Promise<undefined> {\n\t\t\tconst module = createPolarModule(config, ctx.db);\n\n\t\t\t// POST /auth/polar/checkout\n\t\t\t// Creates a Polar checkout session for the authenticated user.\n\t\t\t// Body: { productId: string, successUrl?: string, customerEmail?: string }\n\t\t\tctx.addEndpoint({\n\t\t\t\tmethod: \"POST\",\n\t\t\t\tpath: \"/auth/polar/checkout\",\n\t\t\t\tmetadata: {\n\t\t\t\t\trequireAuth: true,\n\t\t\t\t\tdescription: \"Create a Polar checkout session for the authenticated user\",\n\t\t\t\t},\n\t\t\t\tasync handler(request, endpointCtx) {\n\t\t\t\t\tconst user = await endpointCtx.getUser(request);\n\t\t\t\t\tif (!user) {\n\t\t\t\t\t\treturn json({ error: \"Authentication required\" }, 401);\n\t\t\t\t\t}\n\n\t\t\t\t\tconst body = await parseBody(request);\n\t\t\t\t\tconst productId = typeof body.productId === \"string\" ? body.productId.trim() : null;\n\t\t\t\t\tif (!productId) {\n\t\t\t\t\t\treturn json({ error: \"Missing required field: productId\" }, 400);\n\t\t\t\t\t}\n\n\t\t\t\t\tconst successUrl = typeof body.successUrl === \"string\" ? body.successUrl : undefined;\n\t\t\t\t\tconst customerEmail =\n\t\t\t\t\t\ttypeof body.customerEmail === \"string\" ? body.customerEmail : undefined;\n\n\t\t\t\t\ttry {\n\t\t\t\t\t\tconst result = await module.createCheckout(user.id, productId, {\n\t\t\t\t\t\t\tsuccessUrl,\n\t\t\t\t\t\t\tcustomerEmail,\n\t\t\t\t\t\t});\n\t\t\t\t\t\treturn json(result);\n\t\t\t\t\t} catch (err) {\n\t\t\t\t\t\treturn json(\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\terror: err instanceof Error ? err.message : \"Failed to create checkout session\",\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t500,\n\t\t\t\t\t\t);\n\t\t\t\t\t}\n\t\t\t\t},\n\t\t\t});\n\n\t\t\t// GET /auth/polar/subscription\n\t\t\t// Returns the current subscription status for the authenticated user.\n\t\t\tctx.addEndpoint({\n\t\t\t\tmethod: \"GET\",\n\t\t\t\tpath: \"/auth/polar/subscription\",\n\t\t\t\tmetadata: {\n\t\t\t\t\trequireAuth: true,\n\t\t\t\t\tdescription: \"Get the current Polar subscription status for the authenticated user\",\n\t\t\t\t},\n\t\t\t\tasync handler(request, endpointCtx) {\n\t\t\t\t\tconst user = await endpointCtx.getUser(request);\n\t\t\t\t\tif (!user) {\n\t\t\t\t\t\treturn json({ error: \"Authentication required\" }, 401);\n\t\t\t\t\t}\n\n\t\t\t\t\tconst subscription = await module.getSubscription(user.id);\n\t\t\t\t\treturn json({ subscription });\n\t\t\t\t},\n\t\t\t});\n\n\t\t\t// POST /auth/polar/webhook\n\t\t\t// Receives Polar webhook events. No session auth — verified by HMAC-SHA256 signature.\n\t\t\tctx.addEndpoint({\n\t\t\t\tmethod: \"POST\",\n\t\t\t\tpath: \"/auth/polar/webhook\",\n\t\t\t\tmetadata: {\n\t\t\t\t\tdescription: \"Handle Polar webhook events (HMAC-SHA256 signature verified)\",\n\t\t\t\t},\n\t\t\t\tasync handler(request) {\n\t\t\t\t\treturn module.handleWebhook(request);\n\t\t\t\t},\n\t\t\t});\n\t\t},\n\t};\n}\n","/**\n * SCIM 2.0 directory sync for KavachOS.\n *\n * Implements RFC 7644 (SCIM 2.0 protocol) to allow enterprise identity\n * providers (Okta, Azure AD, Google Workspace) to provision and deprovision\n * users and groups automatically.\n *\n * Users map to kavach_users. Groups map to kavach_organizations.\n *\n * @example\n * ```typescript\n * import { createScimModule } from 'kavachos/auth';\n *\n * const scim = createScimModule({\n * bearerToken: process.env.SCIM_TOKEN,\n * onProvision: async (user) => {\n * console.log('Provisioned:', user.userName);\n * },\n * }, db);\n *\n * // In your request handler:\n * const response = await scim.handleRequest(request);\n * ```\n */\n\nimport { and, eq, like, sql } from \"drizzle-orm\";\nimport type { Database } from \"../db/database.js\";\nimport { organizations, orgMembers, users } from \"../db/schema.js\";\n\n// ---------------------------------------------------------------------------\n// Public types\n// ---------------------------------------------------------------------------\n\nexport interface ScimConfig {\n\t/** Bearer token for SCIM API authentication */\n\tbearerToken: string;\n\t/** Whether to auto-create users on provision (default: true) */\n\tautoCreateUsers?: boolean;\n\t/** Whether to auto-deactivate users on deprovision (default: true) */\n\tautoDeactivateUsers?: boolean;\n\t/** Callback when user is provisioned */\n\tonProvision?: (user: ScimUser) => Promise<void>;\n\t/** Callback when user is deprovisioned */\n\tonDeprovision?: (userId: string) => Promise<void>;\n}\n\nexport interface ScimUser {\n\tid: string;\n\tuserName: string;\n\tname?: { givenName?: string; familyName?: string };\n\temails?: Array<{ value: string; primary?: boolean }>;\n\tactive?: boolean;\n\texternalId?: string;\n}\n\nexport interface ScimGroup {\n\tid: string;\n\tdisplayName: string;\n\texternalId?: string;\n\tmembers?: Array<{ value: string; display?: string }>;\n}\n\nexport interface ScimModule {\n\thandleRequest(request: Request): Promise<Response | null>;\n}\n\n// ---------------------------------------------------------------------------\n// Internal row types\n// ---------------------------------------------------------------------------\n\ninterface UserRow {\n\tid: string;\n\temail: string;\n\tname: string | null;\n\tusername: string | null;\n\texternalId: string | null;\n\texternalProvider: string | null;\n\tbanned: number;\n\tmetadata: Record<string, unknown> | null;\n\tcreatedAt: Date;\n\tupdatedAt: Date;\n}\n\ninterface OrgRow {\n\tid: string;\n\tname: string;\n\tslug: string;\n\townerId: string;\n\tmetadata: Record<string, unknown> | null;\n\tcreatedAt: Date;\n\tupdatedAt: Date;\n}\n\ninterface OrgMemberRow {\n\tid: string;\n\torgId: string;\n\tuserId: string;\n\trole: string;\n\tjoinedAt: Date;\n}\n\n// ---------------------------------------------------------------------------\n// SCIM constants\n// ---------------------------------------------------------------------------\n\nconst SCIM_CONTENT_TYPE = \"application/scim+json\";\n\nconst SCHEMA_USER = \"urn:ietf:params:scim:schemas:core:2.0:User\";\nconst SCHEMA_GROUP = \"urn:ietf:params:scim:schemas:core:2.0:Group\";\nconst SCHEMA_LIST = \"urn:ietf:params:scim:api:messages:2.0:ListResponse\";\nconst SCHEMA_PATCH = \"urn:ietf:params:scim:api:messages:2.0:PatchOp\";\nconst SCHEMA_ERROR = \"urn:ietf:params:scim:api:messages:2.0:Error\";\n\nconst SCHEMA_SP_CONFIG = \"urn:ietf:params:scim:schemas:core:2.0:ServiceProviderConfig\";\nconst SCHEMA_RESOURCE_TYPE = \"urn:ietf:params:scim:schemas:core:2.0:ResourceType\";\n\n// ---------------------------------------------------------------------------\n// Helpers\n// ---------------------------------------------------------------------------\n\nfunction scimResponse(body: unknown, status = 200): Response {\n\treturn new Response(JSON.stringify(body), {\n\t\tstatus,\n\t\theaders: { \"Content-Type\": SCIM_CONTENT_TYPE },\n\t});\n}\n\nfunction scimError(detail: string, status: number, scimType?: string): Response {\n\treturn scimResponse(\n\t\t{\n\t\t\tschemas: [SCHEMA_ERROR],\n\t\t\tdetail,\n\t\t\tstatus,\n\t\t\t...(scimType ? { scimType } : {}),\n\t\t},\n\t\tstatus,\n\t);\n}\n\nfunction generateId(): string {\n\treturn crypto.randomUUID().replace(/-/g, \"\");\n}\n\nfunction toIso(date: Date): string {\n\treturn date.toISOString();\n}\n\n/** Extract the last path segment after the given prefix segment. */\nfunction extractId(pathname: string, prefix: string): string | null {\n\tconst segments = pathname.split(\"/\").filter(Boolean);\n\tconst idx = segments.indexOf(prefix);\n\tif (idx === -1 || idx + 1 >= segments.length) return null;\n\tconst seg = segments[idx + 1];\n\treturn seg !== undefined ? decodeURIComponent(seg) : null;\n}\n\n// ---------------------------------------------------------------------------\n// Mapping functions\n// ---------------------------------------------------------------------------\n\nfunction userRowToScim(row: UserRow, baseUrl: string): Record<string, unknown> {\n\tconst primaryEmail = row.email;\n\tconst meta = row.metadata ?? {};\n\tconst active = meta[\"scim:active\"] !== false && row.banned === 0;\n\n\treturn {\n\t\tschemas: [SCHEMA_USER],\n\t\tid: row.id,\n\t\texternalId: row.externalId ?? undefined,\n\t\tuserName: row.username ?? row.email,\n\t\tname: {\n\t\t\tformatted: row.name ?? undefined,\n\t\t\tgivenName: (meta[\"scim:givenName\"] as string | undefined) ?? undefined,\n\t\t\tfamilyName: (meta[\"scim:familyName\"] as string | undefined) ?? undefined,\n\t\t},\n\t\tdisplayName: row.name ?? undefined,\n\t\temails: [{ value: primaryEmail, primary: true, type: \"work\" }],\n\t\tactive,\n\t\tmeta: {\n\t\t\tresourceType: \"User\",\n\t\t\tcreated: toIso(row.createdAt),\n\t\t\tlastModified: toIso(row.updatedAt),\n\t\t\tlocation: `${baseUrl}/scim/v2/Users/${row.id}`,\n\t\t},\n\t};\n}\n\nfunction orgRowToScim(\n\trow: OrgRow,\n\tmembers: OrgMemberRow[],\n\tmemberEmails: Map<string, string>,\n\tbaseUrl: string,\n): Record<string, unknown> {\n\tconst meta = row.metadata ?? {};\n\n\treturn {\n\t\tschemas: [SCHEMA_GROUP],\n\t\tid: row.id,\n\t\texternalId: (meta[\"scim:externalId\"] as string | undefined) ?? undefined,\n\t\tdisplayName: row.name,\n\t\tmembers: members.map((m) => ({\n\t\t\tvalue: m.userId,\n\t\t\tdisplay: memberEmails.get(m.userId) ?? m.userId,\n\t\t\t$ref: `${baseUrl}/scim/v2/Users/${m.userId}`,\n\t\t})),\n\t\tmeta: {\n\t\t\tresourceType: \"Group\",\n\t\t\tcreated: toIso(row.createdAt),\n\t\t\tlastModified: toIso(row.updatedAt),\n\t\t\tlocation: `${baseUrl}/scim/v2/Groups/${row.id}`,\n\t\t},\n\t};\n}\n\n// ---------------------------------------------------------------------------\n// Filter parsing (RFC 7644 §3.4.2.2)\n// Only supports simple attribute eq/co/sw/pr comparisons joined by \"and\"\n// ---------------------------------------------------------------------------\n\ntype FilterOp = \"eq\" | \"co\" | \"sw\" | \"pr\";\n\ninterface FilterClause {\n\tattribute: string;\n\top: FilterOp;\n\tvalue?: string;\n}\n\nfunction parseScimFilter(filter: string): FilterClause[] {\n\tconst clauses: FilterClause[] = [];\n\t// Split by \" and \" (case-insensitive)\n\tconst parts = filter.split(/\\s+and\\s+/i);\n\tfor (const part of parts) {\n\t\tconst trimmed = part.trim();\n\t\t// Match: attribute op \"value\" or attribute pr\n\t\tconst matchWithValue = trimmed.match(/^(\\S+)\\s+(eq|co|sw)\\s+\"([^\"]*)\"$/i);\n\t\tif (matchWithValue) {\n\t\t\tclauses.push({\n\t\t\t\tattribute: (matchWithValue[1] as string).toLowerCase(),\n\t\t\t\top: (matchWithValue[2] as string).toLowerCase() as FilterOp,\n\t\t\t\tvalue: matchWithValue[3] as string,\n\t\t\t});\n\t\t\tcontinue;\n\t\t}\n\t\tconst matchPr = trimmed.match(/^(\\S+)\\s+pr$/i);\n\t\tif (matchPr) {\n\t\t\tclauses.push({ attribute: (matchPr[1] as string).toLowerCase(), op: \"pr\" });\n\t\t}\n\t}\n\treturn clauses;\n}\n\n// ---------------------------------------------------------------------------\n// PATCH operation types (RFC 7644 §3.5.2)\n// ---------------------------------------------------------------------------\n\ninterface PatchOperation {\n\top: \"add\" | \"replace\" | \"remove\";\n\tpath?: string;\n\tvalue?: unknown;\n}\n\ninterface PatchBody {\n\tschemas: string[];\n\tOperations: PatchOperation[];\n}\n\n// ---------------------------------------------------------------------------\n// Module factory\n// ---------------------------------------------------------------------------\n\nexport function createScimModule(config: ScimConfig, db: Database): ScimModule {\n\tconst {\n\t\tbearerToken,\n\t\tautoCreateUsers = true,\n\t\tautoDeactivateUsers = true,\n\t\tonProvision,\n\t\tonDeprovision,\n\t} = config;\n\n\t// -------------------------------------------------------------------------\n\t// Auth guard\n\t// -------------------------------------------------------------------------\n\n\tfunction isAuthorized(request: Request): boolean {\n\t\tconst authHeader = request.headers.get(\"Authorization\");\n\t\tif (!authHeader) return false;\n\t\tconst [scheme, token] = authHeader.split(\" \");\n\t\treturn scheme?.toLowerCase() === \"bearer\" && token === bearerToken;\n\t}\n\n\t// -------------------------------------------------------------------------\n\t// Base URL extraction\n\t// -------------------------------------------------------------------------\n\n\tfunction getBaseUrl(request: Request): string {\n\t\tconst url = new URL(request.url);\n\t\treturn `${url.protocol}//${url.host}`;\n\t}\n\n\t// -------------------------------------------------------------------------\n\t// User handlers\n\t// -------------------------------------------------------------------------\n\n\tasync function handleListUsers(request: Request): Promise<Response> {\n\t\tconst url = new URL(request.url);\n\t\tconst filterParam = url.searchParams.get(\"filter\") ?? \"\";\n\t\tconst startIndex = Math.max(1, parseInt(url.searchParams.get(\"startIndex\") ?? \"1\", 10));\n\t\tconst count = Math.min(200, parseInt(url.searchParams.get(\"count\") ?? \"100\", 10));\n\t\tconst baseUrl = getBaseUrl(request);\n\n\t\t// Build filter conditions\n\t\tconst conditions = [];\n\t\tif (filterParam) {\n\t\t\tconst clauses = parseScimFilter(filterParam);\n\t\t\tfor (const clause of clauses) {\n\t\t\t\tif (clause.attribute === \"username\" && clause.value !== undefined) {\n\t\t\t\t\tif (clause.op === \"eq\") {\n\t\t\t\t\t\tconditions.push(\n\t\t\t\t\t\t\tsql`(${users.username} = ${clause.value} OR ${users.email} = ${clause.value})`,\n\t\t\t\t\t\t);\n\t\t\t\t\t} else if (clause.op === \"co\") {\n\t\t\t\t\t\tconditions.push(\n\t\t\t\t\t\t\tsql`(${users.username} LIKE ${`%${clause.value}%`} OR ${users.email} LIKE ${`%${clause.value}%`})`,\n\t\t\t\t\t\t);\n\t\t\t\t\t} else if (clause.op === \"sw\") {\n\t\t\t\t\t\tconditions.push(\n\t\t\t\t\t\t\tsql`(${users.username} LIKE ${`${clause.value}%`} OR ${users.email} LIKE ${`${clause.value}%`})`,\n\t\t\t\t\t\t);\n\t\t\t\t\t}\n\t\t\t\t} else if (clause.attribute === \"emails.value\" && clause.value !== undefined) {\n\t\t\t\t\tif (clause.op === \"eq\") {\n\t\t\t\t\t\tconditions.push(eq(users.email, clause.value));\n\t\t\t\t\t} else if (clause.op === \"co\") {\n\t\t\t\t\t\tconditions.push(like(users.email, `%${clause.value}%`));\n\t\t\t\t\t} else if (clause.op === \"sw\") {\n\t\t\t\t\t\tconditions.push(like(users.email, `${clause.value}%`));\n\t\t\t\t\t}\n\t\t\t\t} else if (clause.attribute === \"externalid\" && clause.value !== undefined) {\n\t\t\t\t\tif (clause.op === \"eq\") {\n\t\t\t\t\t\tconditions.push(eq(users.externalId, clause.value));\n\t\t\t\t\t}\n\t\t\t\t} else if (clause.attribute === \"active\") {\n\t\t\t\t\tif (clause.op === \"eq\" && clause.value === \"false\") {\n\t\t\t\t\t\tconditions.push(eq(users.banned, 1));\n\t\t\t\t\t} else if (clause.op === \"eq\" && clause.value === \"true\") {\n\t\t\t\t\t\tconditions.push(eq(users.banned, 0));\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tconst whereClause = conditions.length > 0 ? and(...conditions) : undefined;\n\n\t\t// Count query\n\t\tconst countRows = await db\n\t\t\t.select({ count: sql<number>`count(*)` })\n\t\t\t.from(users)\n\t\t\t.where(whereClause);\n\t\tconst totalResults = Number(countRows[0]?.count ?? 0);\n\n\t\t// Data query with pagination (startIndex is 1-based)\n\t\tconst offset = startIndex - 1;\n\t\tconst rows = (await db\n\t\t\t.select()\n\t\t\t.from(users)\n\t\t\t.where(whereClause)\n\t\t\t.limit(count)\n\t\t\t.offset(offset)) as UserRow[];\n\n\t\treturn scimResponse({\n\t\t\tschemas: [SCHEMA_LIST],\n\t\t\ttotalResults,\n\t\t\tstartIndex,\n\t\t\titemsPerPage: rows.length,\n\t\t\tResources: rows.map((r) => userRowToScim(r, baseUrl)),\n\t\t});\n\t}\n\n\tasync function handleGetUser(request: Request, userId: string): Promise<Response> {\n\t\tconst baseUrl = getBaseUrl(request);\n\t\tconst rows = (await db.select().from(users).where(eq(users.id, userId)).limit(1)) as UserRow[];\n\t\tconst row = rows[0];\n\t\tif (!row) return scimError(\"User not found\", 404, \"noTarget\");\n\t\treturn scimResponse(userRowToScim(row, baseUrl));\n\t}\n\n\tasync function handleCreateUser(request: Request): Promise<Response> {\n\t\tif (!autoCreateUsers) {\n\t\t\treturn scimError(\"User provisioning is disabled\", 403);\n\t\t}\n\n\t\tlet body: Record<string, unknown>;\n\t\ttry {\n\t\t\tbody = (await request.json()) as Record<string, unknown>;\n\t\t} catch {\n\t\t\treturn scimError(\"Invalid JSON body\", 400, \"invalidValue\");\n\t\t}\n\n\t\tconst userName = body.userName as string | undefined;\n\t\tif (!userName) {\n\t\t\treturn scimError(\"userName is required\", 400, \"invalidValue\");\n\t\t}\n\n\t\t// Extract email\n\t\tconst emailsRaw = body.emails as Array<{ value: string; primary?: boolean }> | undefined;\n\t\tconst primaryEmail =\n\t\t\temailsRaw?.find((e) => e.primary)?.value ?? emailsRaw?.[0]?.value ?? userName;\n\n\t\t// Extract name parts\n\t\tconst nameRaw = body.name as\n\t\t\t| { givenName?: string; familyName?: string; formatted?: string }\n\t\t\t| undefined;\n\t\tconst givenName = nameRaw?.givenName;\n\t\tconst familyName = nameRaw?.familyName;\n\t\tconst nameFromParts = [givenName, familyName].filter(Boolean).join(\" \") || null;\n\t\tconst displayName = (body.displayName as string | undefined) ?? nameFromParts;\n\n\t\tconst externalId = (body.externalId as string | undefined) ?? null;\n\t\tconst active = (body.active as boolean | undefined) ?? true;\n\n\t\t// Check if user already exists by email or userName\n\t\tconst existing = (await db\n\t\t\t.select()\n\t\t\t.from(users)\n\t\t\t.where(sql`${users.email} = ${primaryEmail} OR ${users.username} = ${userName}`)\n\t\t\t.limit(1)) as UserRow[];\n\n\t\tif (existing.length > 0) {\n\t\t\treturn scimError(\"User already exists\", 409, \"uniqueness\");\n\t\t}\n\n\t\tconst id = `u_scim_${generateId()}`;\n\t\tconst now = new Date();\n\n\t\tconst metadata: Record<string, unknown> = {\n\t\t\t\"scim:active\": active,\n\t\t\t\"scim:provisioned\": true,\n\t\t};\n\t\tif (givenName) metadata[\"scim:givenName\"] = givenName;\n\t\tif (familyName) metadata[\"scim:familyName\"] = familyName;\n\n\t\tawait db.insert(users).values({\n\t\t\tid,\n\t\t\temail: primaryEmail,\n\t\t\tname: displayName,\n\t\t\tusername: userName !== primaryEmail ? userName : null,\n\t\t\texternalId,\n\t\t\texternalProvider: \"scim\",\n\t\t\tbanned: active ? 0 : 1,\n\t\t\tmetadata,\n\t\t\tcreatedAt: now,\n\t\t\tupdatedAt: now,\n\t\t});\n\n\t\tconst createdRows = (await db\n\t\t\t.select()\n\t\t\t.from(users)\n\t\t\t.where(eq(users.id, id))\n\t\t\t.limit(1)) as UserRow[];\n\t\tconst created = createdRows[0] as UserRow;\n\n\t\tconst scimUser: ScimUser = {\n\t\t\tid,\n\t\t\tuserName,\n\t\t\tname: { givenName, familyName },\n\t\t\temails: [{ value: primaryEmail, primary: true }],\n\t\t\tactive,\n\t\t\texternalId: externalId ?? undefined,\n\t\t};\n\n\t\tif (onProvision) {\n\t\t\tawait onProvision(scimUser);\n\t\t}\n\n\t\tconst baseUrl = getBaseUrl(request);\n\t\treturn scimResponse(userRowToScim(created, baseUrl), 201);\n\t}\n\n\tasync function handleReplaceUser(request: Request, userId: string): Promise<Response> {\n\t\tconst rows = (await db.select().from(users).where(eq(users.id, userId)).limit(1)) as UserRow[];\n\t\tconst existing = rows[0];\n\t\tif (!existing) return scimError(\"User not found\", 404, \"noTarget\");\n\n\t\tlet body: Record<string, unknown>;\n\t\ttry {\n\t\t\tbody = (await request.json()) as Record<string, unknown>;\n\t\t} catch {\n\t\t\treturn scimError(\"Invalid JSON body\", 400, \"invalidValue\");\n\t\t}\n\n\t\tconst userName = (body.userName as string | undefined) ?? existing.username ?? existing.email;\n\t\tconst emailsRaw = body.emails as Array<{ value: string; primary?: boolean }> | undefined;\n\t\tconst primaryEmail =\n\t\t\temailsRaw?.find((e) => e.primary)?.value ?? emailsRaw?.[0]?.value ?? existing.email;\n\n\t\tconst nameRaw = body.name as\n\t\t\t| { givenName?: string; familyName?: string; formatted?: string }\n\t\t\t| undefined;\n\t\tconst givenName = nameRaw?.givenName;\n\t\tconst familyName = nameRaw?.familyName;\n\t\tconst nameFromParts = [givenName, familyName].filter(Boolean).join(\" \") || null;\n\t\tconst displayName = (body.displayName as string | undefined) ?? nameFromParts ?? existing.name;\n\n\t\tconst externalId = (body.externalId as string | undefined) ?? existing.externalId;\n\t\tconst active = (body.active as boolean | undefined) ?? true;\n\n\t\tconst existingMeta = existing.metadata ?? {};\n\t\tconst metadata: Record<string, unknown> = {\n\t\t\t...existingMeta,\n\t\t\t\"scim:active\": active,\n\t\t};\n\t\tif (givenName !== undefined) metadata[\"scim:givenName\"] = givenName;\n\t\tif (familyName !== undefined) metadata[\"scim:familyName\"] = familyName;\n\n\t\tconst now = new Date();\n\t\tawait db\n\t\t\t.update(users)\n\t\t\t.set({\n\t\t\t\temail: primaryEmail,\n\t\t\t\tname: displayName ?? null,\n\t\t\t\tusername: userName !== primaryEmail ? userName : existing.username,\n\t\t\t\texternalId,\n\t\t\t\tbanned: active ? 0 : 1,\n\t\t\t\tmetadata,\n\t\t\t\tupdatedAt: now,\n\t\t\t})\n\t\t\t.where(eq(users.id, userId));\n\n\t\tconst updatedRows = (await db\n\t\t\t.select()\n\t\t\t.from(users)\n\t\t\t.where(eq(users.id, userId))\n\t\t\t.limit(1)) as UserRow[];\n\t\tconst baseUrl = getBaseUrl(request);\n\t\treturn scimResponse(userRowToScim(updatedRows[0] as UserRow, baseUrl));\n\t}\n\n\tasync function handlePatchUser(request: Request, userId: string): Promise<Response> {\n\t\tconst rows = (await db.select().from(users).where(eq(users.id, userId)).limit(1)) as UserRow[];\n\t\tconst current = rows[0];\n\t\tif (!current) return scimError(\"User not found\", 404, \"noTarget\");\n\n\t\tlet body: PatchBody;\n\t\ttry {\n\t\t\tbody = (await request.json()) as PatchBody;\n\t\t} catch {\n\t\t\treturn scimError(\"Invalid JSON body\", 400, \"invalidValue\");\n\t\t}\n\n\t\tif (\n\t\t\t!body.schemas?.includes(SCHEMA_PATCH) ||\n\t\t\t!Array.isArray(body.Operations) ||\n\t\t\tbody.Operations.length === 0\n\t\t) {\n\t\t\treturn scimError(\"Invalid PATCH body: missing Operations\", 400, \"invalidValue\");\n\t\t}\n\n\t\tconst updatedMeta: Record<string, unknown> = { ...(current.metadata ?? {}) };\n\t\tlet email = current.email;\n\t\tlet name = current.name;\n\t\tlet username = current.username;\n\t\tlet banned = current.banned;\n\t\tlet externalId = current.externalId;\n\n\t\tfor (const op of body.Operations) {\n\t\t\tconst opLower = op.op?.toLowerCase() as \"add\" | \"replace\" | \"remove\" | undefined;\n\t\t\tif (!opLower || ![\"add\", \"replace\", \"remove\"].includes(opLower)) continue;\n\n\t\t\tconst path = op.path?.toLowerCase();\n\n\t\t\tif (opLower === \"remove\") {\n\t\t\t\tif (path === \"active\") {\n\t\t\t\t\tupdatedMeta[\"scim:active\"] = false;\n\t\t\t\t\tbanned = autoDeactivateUsers ? 1 : 0;\n\t\t\t\t}\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\t// add / replace\n\t\t\tif (path === \"active\" || path === \"urn:ietf:params:scim:schemas:core:2.0:user:active\") {\n\t\t\t\tconst active = op.value === true || op.value === \"true\";\n\t\t\t\tupdatedMeta[\"scim:active\"] = active;\n\t\t\t\tbanned = active ? 0 : autoDeactivateUsers ? 1 : 0;\n\t\t\t} else if (\n\t\t\t\tpath === \"username\" ||\n\t\t\t\tpath === \"urn:ietf:params:scim:schemas:core:2.0:user:username\"\n\t\t\t) {\n\t\t\t\tusername = typeof op.value === \"string\" ? op.value : username;\n\t\t\t} else if (path === \"displayname\") {\n\t\t\t\tname = typeof op.value === \"string\" ? op.value : name;\n\t\t\t} else if (path === \"name.givenname\") {\n\t\t\t\tupdatedMeta[\"scim:givenName\"] = op.value;\n\t\t\t} else if (path === \"name.familyname\") {\n\t\t\t\tupdatedMeta[\"scim:familyName\"] = op.value;\n\t\t\t} else if (path === \"externalid\") {\n\t\t\t\texternalId = typeof op.value === \"string\" ? op.value : externalId;\n\t\t\t} else if (path === \"emails\" || path?.startsWith(\"emails[\")) {\n\t\t\t\t// Handle emails array replacement\n\t\t\t\tconst emailsVal = op.value as Array<{ value: string; primary?: boolean }> | undefined;\n\t\t\t\tif (Array.isArray(emailsVal)) {\n\t\t\t\t\tconst primary = emailsVal.find((e) => e.primary)?.value ?? emailsVal[0]?.value;\n\t\t\t\t\tif (primary) email = primary;\n\t\t\t\t}\n\t\t\t} else if (!path) {\n\t\t\t\t// No path: value is an object with attributes to set\n\t\t\t\tconst val = op.value as Record<string, unknown> | undefined;\n\t\t\t\tif (val && typeof val === \"object\") {\n\t\t\t\t\tif (\"active\" in val) {\n\t\t\t\t\t\tconst active = val.active === true || val.active === \"true\";\n\t\t\t\t\t\tupdatedMeta[\"scim:active\"] = active;\n\t\t\t\t\t\tbanned = active ? 0 : autoDeactivateUsers ? 1 : 0;\n\t\t\t\t\t}\n\t\t\t\t\tif (\"displayName\" in val && typeof val.displayName === \"string\") {\n\t\t\t\t\t\tname = val.displayName;\n\t\t\t\t\t}\n\t\t\t\t\tif (\"userName\" in val && typeof val.userName === \"string\") {\n\t\t\t\t\t\tusername = val.userName;\n\t\t\t\t\t}\n\t\t\t\t\tif (\"externalId\" in val && typeof val.externalId === \"string\") {\n\t\t\t\t\t\texternalId = val.externalId;\n\t\t\t\t\t}\n\t\t\t\t\tconst nameVal = val.name as { givenName?: string; familyName?: string } | undefined;\n\t\t\t\t\tif (nameVal) {\n\t\t\t\t\t\tif (nameVal.givenName !== undefined) updatedMeta[\"scim:givenName\"] = nameVal.givenName;\n\t\t\t\t\t\tif (nameVal.familyName !== undefined)\n\t\t\t\t\t\t\tupdatedMeta[\"scim:familyName\"] = nameVal.familyName;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tconst now = new Date();\n\t\tawait db\n\t\t\t.update(users)\n\t\t\t.set({ email, name, username, banned, externalId, metadata: updatedMeta, updatedAt: now })\n\t\t\t.where(eq(users.id, userId));\n\n\t\tconst updatedRows = (await db\n\t\t\t.select()\n\t\t\t.from(users)\n\t\t\t.where(eq(users.id, userId))\n\t\t\t.limit(1)) as UserRow[];\n\t\tconst baseUrl = getBaseUrl(request);\n\t\treturn scimResponse(userRowToScim(updatedRows[0] as UserRow, baseUrl));\n\t}\n\n\tasync function handleDeleteUser(_request: Request, userId: string): Promise<Response> {\n\t\tconst rows = (await db.select().from(users).where(eq(users.id, userId)).limit(1)) as UserRow[];\n\t\tconst row = rows[0];\n\t\tif (!row) return scimError(\"User not found\", 404, \"noTarget\");\n\n\t\tif (autoDeactivateUsers) {\n\t\t\t// Soft delete: deactivate rather than destroy\n\t\t\tconst now = new Date();\n\t\t\tconst meta = { ...(row.metadata ?? {}), \"scim:active\": false, \"scim:deprovisioned\": true };\n\t\t\tawait db\n\t\t\t\t.update(users)\n\t\t\t\t.set({ banned: 1, metadata: meta, updatedAt: now })\n\t\t\t\t.where(eq(users.id, userId));\n\t\t} else {\n\t\t\tawait db.delete(users).where(eq(users.id, userId));\n\t\t}\n\n\t\tif (onDeprovision) {\n\t\t\tawait onDeprovision(userId);\n\t\t}\n\n\t\treturn new Response(null, { status: 204 });\n\t}\n\n\t// -------------------------------------------------------------------------\n\t// Group handlers\n\t// -------------------------------------------------------------------------\n\n\tasync function getMembersForOrg(orgId: string): Promise<OrgMemberRow[]> {\n\t\treturn (await db\n\t\t\t.select()\n\t\t\t.from(orgMembers)\n\t\t\t.where(eq(orgMembers.orgId, orgId))) as OrgMemberRow[];\n\t}\n\n\tasync function getMemberEmails(memberRows: OrgMemberRow[]): Promise<Map<string, string>> {\n\t\tif (memberRows.length === 0) return new Map();\n\t\tconst ids = memberRows.map((m) => m.userId);\n\t\tconst emailRows = (await db\n\t\t\t.select({ id: users.id, email: users.email })\n\t\t\t.from(users)\n\t\t\t.where(sql`${users.id} IN ${ids}`)) as { id: string; email: string }[];\n\t\treturn new Map(emailRows.map((r) => [r.id, r.email]));\n\t}\n\n\tasync function handleListGroups(request: Request): Promise<Response> {\n\t\tconst url = new URL(request.url);\n\t\tconst filterParam = url.searchParams.get(\"filter\") ?? \"\";\n\t\tconst startIndex = Math.max(1, parseInt(url.searchParams.get(\"startIndex\") ?? \"1\", 10));\n\t\tconst count = Math.min(200, parseInt(url.searchParams.get(\"count\") ?? \"100\", 10));\n\t\tconst baseUrl = getBaseUrl(request);\n\n\t\tconst conditions = [];\n\t\tif (filterParam) {\n\t\t\tconst clauses = parseScimFilter(filterParam);\n\t\t\tfor (const clause of clauses) {\n\t\t\t\tif (clause.attribute === \"displayname\" && clause.value !== undefined) {\n\t\t\t\t\tif (clause.op === \"eq\") {\n\t\t\t\t\t\tconditions.push(eq(organizations.name, clause.value));\n\t\t\t\t\t} else if (clause.op === \"co\") {\n\t\t\t\t\t\tconditions.push(like(organizations.name, `%${clause.value}%`));\n\t\t\t\t\t} else if (clause.op === \"sw\") {\n\t\t\t\t\t\tconditions.push(like(organizations.name, `${clause.value}%`));\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tconst whereClause = conditions.length > 0 ? and(...conditions) : undefined;\n\n\t\tconst countRows = await db\n\t\t\t.select({ count: sql<number>`count(*)` })\n\t\t\t.from(organizations)\n\t\t\t.where(whereClause);\n\t\tconst totalResults = Number(countRows[0]?.count ?? 0);\n\n\t\tconst offset = startIndex - 1;\n\t\tconst orgRows = (await db\n\t\t\t.select()\n\t\t\t.from(organizations)\n\t\t\t.where(whereClause)\n\t\t\t.limit(count)\n\t\t\t.offset(offset)) as OrgRow[];\n\n\t\t// Fetch members for each org\n\t\tconst resources = await Promise.all(\n\t\t\torgRows.map(async (org) => {\n\t\t\t\tconst members = await getMembersForOrg(org.id);\n\t\t\t\tconst memberEmails = await getMemberEmails(members);\n\t\t\t\treturn orgRowToScim(org, members, memberEmails, baseUrl);\n\t\t\t}),\n\t\t);\n\n\t\treturn scimResponse({\n\t\t\tschemas: [SCHEMA_LIST],\n\t\t\ttotalResults,\n\t\t\tstartIndex,\n\t\t\titemsPerPage: orgRows.length,\n\t\t\tResources: resources,\n\t\t});\n\t}\n\n\tasync function handleGetGroup(request: Request, groupId: string): Promise<Response> {\n\t\tconst baseUrl = getBaseUrl(request);\n\t\tconst orgRows = (await db\n\t\t\t.select()\n\t\t\t.from(organizations)\n\t\t\t.where(eq(organizations.id, groupId))\n\t\t\t.limit(1)) as OrgRow[];\n\t\tconst orgRow = orgRows[0];\n\t\tif (!orgRow) return scimError(\"Group not found\", 404, \"noTarget\");\n\n\t\tconst members = await getMembersForOrg(groupId);\n\t\tconst memberEmails = await getMemberEmails(members);\n\t\treturn scimResponse(orgRowToScim(orgRow, members, memberEmails, baseUrl));\n\t}\n\n\tasync function handleCreateGroup(request: Request): Promise<Response> {\n\t\tlet body: Record<string, unknown>;\n\t\ttry {\n\t\t\tbody = (await request.json()) as Record<string, unknown>;\n\t\t} catch {\n\t\t\treturn scimError(\"Invalid JSON body\", 400, \"invalidValue\");\n\t\t}\n\n\t\tconst displayName = body.displayName as string | undefined;\n\t\tif (!displayName) {\n\t\t\treturn scimError(\"displayName is required\", 400, \"invalidValue\");\n\t\t}\n\n\t\tconst externalId = (body.externalId as string | undefined) ?? null;\n\n\t\t// Generate a URL-safe slug\n\t\tconst slug = displayName\n\t\t\t.toLowerCase()\n\t\t\t.replace(/[^a-z0-9]+/g, \"-\")\n\t\t\t.replace(/^-|-$/g, \"\")\n\t\t\t.slice(0, 50);\n\n\t\t// Ensure slug uniqueness\n\t\tconst existingSlug = (await db\n\t\t\t.select({ id: organizations.id })\n\t\t\t.from(organizations)\n\t\t\t.where(eq(organizations.slug, slug))\n\t\t\t.limit(1)) as { id: string }[];\n\n\t\tconst finalSlug = existingSlug.length > 0 ? `${slug}-${generateId().slice(0, 8)}` : slug;\n\n\t\tconst id = `org_scim_${generateId()}`;\n\t\tconst now = new Date();\n\n\t\t// SCIM groups need an owner — use a system placeholder stored in metadata\n\t\t// The ownerId column is not null, so we use a convention: store \"scim\" owner reference\n\t\t// We require at least one member in the members array to serve as owner,\n\t\t// or fall back to the first user in the DB.\n\t\tconst membersRaw = body.members as Array<{ value: string }> | undefined;\n\t\tconst ownerCandidateId = membersRaw?.[0]?.value;\n\n\t\tlet ownerId: string;\n\t\tif (ownerCandidateId) {\n\t\t\townerId = ownerCandidateId;\n\t\t} else {\n\t\t\t// Fall back to first user in DB\n\t\t\tconst firstUser = (await db.select({ id: users.id }).from(users).limit(1)) as {\n\t\t\t\tid: string;\n\t\t\t}[];\n\t\t\tconst firstUserRow = firstUser[0];\n\t\t\tif (!firstUserRow) {\n\t\t\t\treturn scimError(\n\t\t\t\t\t\"Cannot create group: no users exist to assign as owner\",\n\t\t\t\t\t422,\n\t\t\t\t\t\"invalidValue\",\n\t\t\t\t);\n\t\t\t}\n\t\t\townerId = firstUserRow.id;\n\t\t}\n\n\t\tconst metadata: Record<string, unknown> = { \"scim:provisioned\": true };\n\t\tif (externalId) metadata[\"scim:externalId\"] = externalId;\n\n\t\tawait db.insert(organizations).values({\n\t\t\tid,\n\t\t\tname: displayName,\n\t\t\tslug: finalSlug,\n\t\t\townerId,\n\t\t\tmetadata,\n\t\t\tcreatedAt: now,\n\t\t\tupdatedAt: now,\n\t\t});\n\n\t\t// Add initial members\n\t\tif (membersRaw && membersRaw.length > 0) {\n\t\t\tconst memberInserts = membersRaw.map((m) => ({\n\t\t\t\tid: `om_scim_${generateId()}`,\n\t\t\t\torgId: id,\n\t\t\t\tuserId: m.value,\n\t\t\t\trole: \"member\",\n\t\t\t\tjoinedAt: now,\n\t\t\t}));\n\t\t\tawait db.insert(orgMembers).values(memberInserts);\n\t\t}\n\n\t\tconst orgRows = (await db\n\t\t\t.select()\n\t\t\t.from(organizations)\n\t\t\t.where(eq(organizations.id, id))\n\t\t\t.limit(1)) as OrgRow[];\n\t\tconst createdMembers = await getMembersForOrg(id);\n\t\tconst memberEmails = await getMemberEmails(createdMembers);\n\t\tconst baseUrl = getBaseUrl(request);\n\t\treturn scimResponse(\n\t\t\torgRowToScim(orgRows[0] as OrgRow, createdMembers, memberEmails, baseUrl),\n\t\t\t201,\n\t\t);\n\t}\n\n\tasync function handleReplaceGroup(request: Request, groupId: string): Promise<Response> {\n\t\tconst orgRows = (await db\n\t\t\t.select()\n\t\t\t.from(organizations)\n\t\t\t.where(eq(organizations.id, groupId))\n\t\t\t.limit(1)) as OrgRow[];\n\t\tconst existingOrg = orgRows[0];\n\t\tif (!existingOrg) return scimError(\"Group not found\", 404, \"noTarget\");\n\n\t\tlet body: Record<string, unknown>;\n\t\ttry {\n\t\t\tbody = (await request.json()) as Record<string, unknown>;\n\t\t} catch {\n\t\t\treturn scimError(\"Invalid JSON body\", 400, \"invalidValue\");\n\t\t}\n\n\t\tconst displayName = (body.displayName as string | undefined) ?? existingOrg.name;\n\t\tconst externalId = (body.externalId as string | undefined) ?? null;\n\t\tconst membersRaw = body.members as Array<{ value: string }> | undefined;\n\n\t\tconst existingMeta = existingOrg.metadata ?? {};\n\t\tconst metadata: Record<string, unknown> = { ...existingMeta };\n\t\tif (externalId) metadata[\"scim:externalId\"] = externalId;\n\t\telse metadata[\"scim:externalId\"] = undefined;\n\n\t\tconst now = new Date();\n\t\tawait db\n\t\t\t.update(organizations)\n\t\t\t.set({ name: displayName, metadata, updatedAt: now })\n\t\t\t.where(eq(organizations.id, groupId));\n\n\t\t// Replace member list if provided\n\t\tif (membersRaw !== undefined) {\n\t\t\tawait db.delete(orgMembers).where(eq(orgMembers.orgId, groupId));\n\t\t\tif (membersRaw.length > 0) {\n\t\t\t\tconst memberInserts = membersRaw.map((m) => ({\n\t\t\t\t\tid: `om_scim_${generateId()}`,\n\t\t\t\t\torgId: groupId,\n\t\t\t\t\tuserId: m.value,\n\t\t\t\t\trole: \"member\",\n\t\t\t\t\tjoinedAt: now,\n\t\t\t\t}));\n\t\t\t\tawait db.insert(orgMembers).values(memberInserts);\n\t\t\t}\n\t\t}\n\n\t\tconst updatedOrg = (await db\n\t\t\t.select()\n\t\t\t.from(organizations)\n\t\t\t.where(eq(organizations.id, groupId))\n\t\t\t.limit(1)) as OrgRow[];\n\t\tconst members = await getMembersForOrg(groupId);\n\t\tconst memberEmails = await getMemberEmails(members);\n\t\tconst baseUrl = getBaseUrl(request);\n\t\treturn scimResponse(orgRowToScim(updatedOrg[0] as OrgRow, members, memberEmails, baseUrl));\n\t}\n\n\tasync function handlePatchGroup(request: Request, groupId: string): Promise<Response> {\n\t\tconst orgRows = (await db\n\t\t\t.select()\n\t\t\t.from(organizations)\n\t\t\t.where(eq(organizations.id, groupId))\n\t\t\t.limit(1)) as OrgRow[];\n\t\tconst current = orgRows[0];\n\t\tif (!current) return scimError(\"Group not found\", 404, \"noTarget\");\n\n\t\tlet body: PatchBody;\n\t\ttry {\n\t\t\tbody = (await request.json()) as PatchBody;\n\t\t} catch {\n\t\t\treturn scimError(\"Invalid JSON body\", 400, \"invalidValue\");\n\t\t}\n\n\t\tif (\n\t\t\t!body.schemas?.includes(SCHEMA_PATCH) ||\n\t\t\t!Array.isArray(body.Operations) ||\n\t\t\tbody.Operations.length === 0\n\t\t) {\n\t\t\treturn scimError(\"Invalid PATCH body: missing Operations\", 400, \"invalidValue\");\n\t\t}\n\n\t\tlet displayName = current.name;\n\t\tconst updatedMeta: Record<string, unknown> = { ...(current.metadata ?? {}) };\n\t\tconst now = new Date();\n\n\t\tfor (const op of body.Operations) {\n\t\t\tconst opLower = op.op?.toLowerCase() as \"add\" | \"replace\" | \"remove\" | undefined;\n\t\t\tif (!opLower) continue;\n\t\t\tconst path = op.path?.toLowerCase();\n\n\t\t\tif (opLower === \"replace\" && path === \"displayname\") {\n\t\t\t\tdisplayName = typeof op.value === \"string\" ? op.value : displayName;\n\t\t\t} else if (opLower === \"add\" && (path === \"members\" || !path)) {\n\t\t\t\tconst val = op.value as Record<string, unknown> | Array<{ value: string }> | undefined;\n\t\t\t\t// Could be array of members or object with displayName\n\t\t\t\tif (Array.isArray(val)) {\n\t\t\t\t\tfor (const m of val) {\n\t\t\t\t\t\tif (typeof m.value === \"string\") {\n\t\t\t\t\t\t\t// Check if already a member\n\t\t\t\t\t\t\tconst existing = (await db\n\t\t\t\t\t\t\t\t.select({ id: orgMembers.id })\n\t\t\t\t\t\t\t\t.from(orgMembers)\n\t\t\t\t\t\t\t\t.where(and(eq(orgMembers.orgId, groupId), eq(orgMembers.userId, m.value)))\n\t\t\t\t\t\t\t\t.limit(1)) as { id: string }[];\n\t\t\t\t\t\t\tif (existing.length === 0) {\n\t\t\t\t\t\t\t\tawait db.insert(orgMembers).values({\n\t\t\t\t\t\t\t\t\tid: `om_scim_${generateId()}`,\n\t\t\t\t\t\t\t\t\torgId: groupId,\n\t\t\t\t\t\t\t\t\tuserId: m.value,\n\t\t\t\t\t\t\t\t\trole: \"member\",\n\t\t\t\t\t\t\t\t\tjoinedAt: now,\n\t\t\t\t\t\t\t\t});\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t} else if (val && typeof val === \"object\" && \"displayName\" in val) {\n\t\t\t\t\tdisplayName = (val as Record<string, unknown>).displayName as string;\n\t\t\t\t}\n\t\t\t} else if (opLower === \"remove\" && path?.startsWith(\"members\")) {\n\t\t\t\t// path could be \"members\" (remove all) or \"members[value eq \\\"userId\\\"]\"\n\t\t\t\tconst matchId = op.path?.match(/members\\[value\\s+eq\\s+\"([^\"]+)\"\\]/i);\n\t\t\t\tif (matchId) {\n\t\t\t\t\tconst targetUserId = matchId[1];\n\t\t\t\t\tif (targetUserId) {\n\t\t\t\t\t\tawait db\n\t\t\t\t\t\t\t.delete(orgMembers)\n\t\t\t\t\t\t\t.where(and(eq(orgMembers.orgId, groupId), eq(orgMembers.userId, targetUserId)));\n\t\t\t\t\t}\n\t\t\t\t} else if (path === \"members\") {\n\t\t\t\t\t// Remove specific members from value array\n\t\t\t\t\tconst val = op.value as Array<{ value: string }> | undefined;\n\t\t\t\t\tif (Array.isArray(val)) {\n\t\t\t\t\t\tfor (const m of val) {\n\t\t\t\t\t\t\tif (typeof m.value === \"string\") {\n\t\t\t\t\t\t\t\tawait db\n\t\t\t\t\t\t\t\t\t.delete(orgMembers)\n\t\t\t\t\t\t\t\t\t.where(and(eq(orgMembers.orgId, groupId), eq(orgMembers.userId, m.value)));\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t} else {\n\t\t\t\t\t\tawait db.delete(orgMembers).where(eq(orgMembers.orgId, groupId));\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tawait db\n\t\t\t.update(organizations)\n\t\t\t.set({ name: displayName, metadata: updatedMeta, updatedAt: now })\n\t\t\t.where(eq(organizations.id, groupId));\n\n\t\tconst updatedOrg = (await db\n\t\t\t.select()\n\t\t\t.from(organizations)\n\t\t\t.where(eq(organizations.id, groupId))\n\t\t\t.limit(1)) as OrgRow[];\n\t\tconst members = await getMembersForOrg(groupId);\n\t\tconst memberEmails = await getMemberEmails(members);\n\t\tconst baseUrl = getBaseUrl(request);\n\t\treturn scimResponse(orgRowToScim(updatedOrg[0] as OrgRow, members, memberEmails, baseUrl));\n\t}\n\n\tasync function handleDeleteGroup(_request: Request, groupId: string): Promise<Response> {\n\t\tconst orgRows = (await db\n\t\t\t.select()\n\t\t\t.from(organizations)\n\t\t\t.where(eq(organizations.id, groupId))\n\t\t\t.limit(1)) as OrgRow[];\n\t\tif (orgRows.length === 0) return scimError(\"Group not found\", 404, \"noTarget\");\n\n\t\tawait db.delete(orgMembers).where(eq(orgMembers.orgId, groupId));\n\t\tawait db.delete(organizations).where(eq(organizations.id, groupId));\n\n\t\treturn new Response(null, { status: 204 });\n\t}\n\n\t// -------------------------------------------------------------------------\n\t// Discovery endpoints\n\t// -------------------------------------------------------------------------\n\n\tfunction handleServiceProviderConfig(request: Request): Response {\n\t\tconst baseUrl = getBaseUrl(request);\n\t\treturn scimResponse({\n\t\t\tschemas: [SCHEMA_SP_CONFIG],\n\t\t\tdocumentationUri: \"https://kavachos.dev/docs/scim\",\n\t\t\tpatch: { supported: true },\n\t\t\tbulk: { supported: false, maxOperations: 0, maxPayloadSize: 0 },\n\t\t\tfilter: { supported: true, maxResults: 200 },\n\t\t\tchangePassword: { supported: false },\n\t\t\tsort: { supported: false },\n\t\t\tetag: { supported: false },\n\t\t\tauthenticationSchemes: [\n\t\t\t\t{\n\t\t\t\t\ttype: \"oauthbearertoken\",\n\t\t\t\t\tname: \"OAuth Bearer Token\",\n\t\t\t\t\tdescription: \"Authentication scheme using OAuth Bearer Token\",\n\t\t\t\t\tspecUri: \"https://www.rfc-editor.org/rfc/rfc6750\",\n\t\t\t\t\tprimary: true,\n\t\t\t\t},\n\t\t\t],\n\t\t\tmeta: {\n\t\t\t\tresourceType: \"ServiceProviderConfig\",\n\t\t\t\tlocation: `${baseUrl}/scim/v2/ServiceProviderConfig`,\n\t\t\t},\n\t\t});\n\t}\n\n\tfunction handleSchemas(request: Request): Response {\n\t\tconst baseUrl = getBaseUrl(request);\n\t\treturn scimResponse({\n\t\t\tschemas: [SCHEMA_LIST],\n\t\t\ttotalResults: 2,\n\t\t\tstartIndex: 1,\n\t\t\titemsPerPage: 2,\n\t\t\tResources: [\n\t\t\t\t{\n\t\t\t\t\tschemas: [\"urn:ietf:params:scim:schemas:core:2.0:Schema\"],\n\t\t\t\t\tid: SCHEMA_USER,\n\t\t\t\t\tname: \"User\",\n\t\t\t\t\tdescription: \"User Account\",\n\t\t\t\t\tattributes: [\n\t\t\t\t\t\t{ name: \"userName\", type: \"string\", required: true, uniqueness: \"server\" },\n\t\t\t\t\t\t{ name: \"displayName\", type: \"string\", required: false },\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tname: \"name\",\n\t\t\t\t\t\t\ttype: \"complex\",\n\t\t\t\t\t\t\trequired: false,\n\t\t\t\t\t\t\tsubAttributes: [\n\t\t\t\t\t\t\t\t{ name: \"givenName\", type: \"string\" },\n\t\t\t\t\t\t\t\t{ name: \"familyName\", type: \"string\" },\n\t\t\t\t\t\t\t\t{ name: \"formatted\", type: \"string\" },\n\t\t\t\t\t\t\t],\n\t\t\t\t\t\t},\n\t\t\t\t\t\t{ name: \"emails\", type: \"complex\", multiValued: true, required: false },\n\t\t\t\t\t\t{ name: \"active\", type: \"boolean\", required: false },\n\t\t\t\t\t\t{ name: \"externalId\", type: \"string\", required: false },\n\t\t\t\t\t],\n\t\t\t\t\tmeta: {\n\t\t\t\t\t\tresourceType: \"Schema\",\n\t\t\t\t\t\tlocation: `${baseUrl}/scim/v2/Schemas/${SCHEMA_USER}`,\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\tschemas: [\"urn:ietf:params:scim:schemas:core:2.0:Schema\"],\n\t\t\t\t\tid: SCHEMA_GROUP,\n\t\t\t\t\tname: \"Group\",\n\t\t\t\t\tdescription: \"Group\",\n\t\t\t\t\tattributes: [\n\t\t\t\t\t\t{ name: \"displayName\", type: \"string\", required: true },\n\t\t\t\t\t\t{ name: \"members\", type: \"complex\", multiValued: true, required: false },\n\t\t\t\t\t\t{ name: \"externalId\", type: \"string\", required: false },\n\t\t\t\t\t],\n\t\t\t\t\tmeta: {\n\t\t\t\t\t\tresourceType: \"Schema\",\n\t\t\t\t\t\tlocation: `${baseUrl}/scim/v2/Schemas/${SCHEMA_GROUP}`,\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t],\n\t\t});\n\t}\n\n\tfunction handleResourceTypes(request: Request): Response {\n\t\tconst baseUrl = getBaseUrl(request);\n\t\treturn scimResponse({\n\t\t\tschemas: [SCHEMA_LIST],\n\t\t\ttotalResults: 2,\n\t\t\tstartIndex: 1,\n\t\t\titemsPerPage: 2,\n\t\t\tResources: [\n\t\t\t\t{\n\t\t\t\t\tschemas: [SCHEMA_RESOURCE_TYPE],\n\t\t\t\t\tid: \"User\",\n\t\t\t\t\tname: \"User\",\n\t\t\t\t\tendpoint: \"/Users\",\n\t\t\t\t\tdescription: \"User Account\",\n\t\t\t\t\tschema: SCHEMA_USER,\n\t\t\t\t\tmeta: {\n\t\t\t\t\t\tresourceType: \"ResourceType\",\n\t\t\t\t\t\tlocation: `${baseUrl}/scim/v2/ResourceTypes/User`,\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\tschemas: [SCHEMA_RESOURCE_TYPE],\n\t\t\t\t\tid: \"Group\",\n\t\t\t\t\tname: \"Group\",\n\t\t\t\t\tendpoint: \"/Groups\",\n\t\t\t\t\tdescription: \"Group\",\n\t\t\t\t\tschema: SCHEMA_GROUP,\n\t\t\t\t\tmeta: {\n\t\t\t\t\t\tresourceType: \"ResourceType\",\n\t\t\t\t\t\tlocation: `${baseUrl}/scim/v2/ResourceTypes/Group`,\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t],\n\t\t});\n\t}\n\n\t// -------------------------------------------------------------------------\n\t// Request router\n\t// -------------------------------------------------------------------------\n\n\tasync function handleRequest(request: Request): Promise<Response | null> {\n\t\tconst url = new URL(request.url);\n\t\tconst pathname = url.pathname;\n\n\t\t// Only handle /scim/v2/ paths\n\t\tif (!pathname.includes(\"/scim/v2/\")) return null;\n\n\t\t// Auth check on all SCIM routes\n\t\tif (!isAuthorized(request)) {\n\t\t\treturn scimError(\"Unauthorized: valid Bearer token required\", 401);\n\t\t}\n\n\t\tconst method = request.method.toUpperCase();\n\n\t\t// Discovery — no ID extraction needed\n\t\tif (method === \"GET\" && pathname.endsWith(\"/scim/v2/ServiceProviderConfig\")) {\n\t\t\treturn handleServiceProviderConfig(request);\n\t\t}\n\t\tif (method === \"GET\" && pathname.endsWith(\"/scim/v2/Schemas\")) {\n\t\t\treturn handleSchemas(request);\n\t\t}\n\t\tif (method === \"GET\" && pathname.endsWith(\"/scim/v2/ResourceTypes\")) {\n\t\t\treturn handleResourceTypes(request);\n\t\t}\n\n\t\t// Users collection\n\t\tif (method === \"GET\" && /\\/scim\\/v2\\/Users\\/?$/.test(pathname)) {\n\t\t\treturn handleListUsers(request);\n\t\t}\n\t\tif (method === \"POST\" && /\\/scim\\/v2\\/Users\\/?$/.test(pathname)) {\n\t\t\treturn handleCreateUser(request);\n\t\t}\n\n\t\t// Users by ID\n\t\tconst userId = extractId(pathname, \"Users\");\n\t\tif (userId) {\n\t\t\tif (method === \"GET\") return handleGetUser(request, userId);\n\t\t\tif (method === \"PUT\") return handleReplaceUser(request, userId);\n\t\t\tif (method === \"PATCH\") return handlePatchUser(request, userId);\n\t\t\tif (method === \"DELETE\") return handleDeleteUser(request, userId);\n\t\t}\n\n\t\t// Groups collection\n\t\tif (method === \"GET\" && /\\/scim\\/v2\\/Groups\\/?$/.test(pathname)) {\n\t\t\treturn handleListGroups(request);\n\t\t}\n\t\tif (method === \"POST\" && /\\/scim\\/v2\\/Groups\\/?$/.test(pathname)) {\n\t\t\treturn handleCreateGroup(request);\n\t\t}\n\n\t\t// Groups by ID\n\t\tconst groupId = extractId(pathname, \"Groups\");\n\t\tif (groupId) {\n\t\t\tif (method === \"GET\") return handleGetGroup(request, groupId);\n\t\t\tif (method === \"PUT\") return handleReplaceGroup(request, groupId);\n\t\t\tif (method === \"PATCH\") return handlePatchGroup(request, groupId);\n\t\t\tif (method === \"DELETE\") return handleDeleteGroup(request, groupId);\n\t\t}\n\n\t\treturn null;\n\t}\n\n\treturn { handleRequest };\n}\n","import type { KavachPlugin } from \"../plugin/types.js\";\nimport type { ScimConfig } from \"./scim.js\";\nimport { createScimModule } from \"./scim.js\";\n\nexport type { ScimConfig };\n\n// ---------------------------------------------------------------------------\n// Plugin factory\n// ---------------------------------------------------------------------------\n\n/**\n * SCIM 2.0 directory sync plugin for KavachOS.\n *\n * Mounts SCIM endpoints under `/scim/v2/` so enterprise IdPs (Okta, Azure AD,\n * Google Workspace) can provision and deprovision users and groups.\n *\n * All endpoints require a static Bearer token supplied via `config.bearerToken`.\n *\n * @example\n * ```typescript\n * import { createKavach } from 'kavachos';\n * import { scim } from 'kavachos/auth';\n *\n * const kavach = await createKavach({\n * database: { provider: 'sqlite', url: 'kavach.db' },\n * plugins: [\n * scim({\n * bearerToken: process.env.SCIM_TOKEN,\n * onProvision: async (user) => {\n * await sendWelcomeEmail(user.emails?.[0]?.value);\n * },\n * }),\n * ],\n * });\n * ```\n */\nexport function scim(config: ScimConfig): KavachPlugin {\n\treturn {\n\t\tid: \"kavach-scim\",\n\n\t\tasync init(ctx): Promise<undefined> {\n\t\t\tconst module = createScimModule(config, ctx.db);\n\n\t\t\t// We register a single catch-all GET handler per method and let the\n\t\t\t// module's internal router do path matching. The plugin endpoint\n\t\t\t// system uses exact path matching, so we register wildcard-style\n\t\t\t// paths for each SCIM sub-resource and method combination.\n\t\t\t//\n\t\t\t// Discovery\n\t\t\tctx.addEndpoint({\n\t\t\t\tmethod: \"GET\",\n\t\t\t\tpath: \"/scim/v2/ServiceProviderConfig\",\n\t\t\t\tmetadata: { description: \"SCIM service provider configuration (RFC 7643)\" },\n\t\t\t\tasync handler(request) {\n\t\t\t\t\treturn (await module.handleRequest(request)) as Response;\n\t\t\t\t},\n\t\t\t});\n\n\t\t\tctx.addEndpoint({\n\t\t\t\tmethod: \"GET\",\n\t\t\t\tpath: \"/scim/v2/Schemas\",\n\t\t\t\tmetadata: { description: \"SCIM schema definitions\" },\n\t\t\t\tasync handler(request) {\n\t\t\t\t\treturn (await module.handleRequest(request)) as Response;\n\t\t\t\t},\n\t\t\t});\n\n\t\t\tctx.addEndpoint({\n\t\t\t\tmethod: \"GET\",\n\t\t\t\tpath: \"/scim/v2/ResourceTypes\",\n\t\t\t\tmetadata: { description: \"SCIM resource type definitions\" },\n\t\t\t\tasync handler(request) {\n\t\t\t\t\treturn (await module.handleRequest(request)) as Response;\n\t\t\t\t},\n\t\t\t});\n\n\t\t\t// Users collection\n\t\t\tctx.addEndpoint({\n\t\t\t\tmethod: \"GET\",\n\t\t\t\tpath: \"/scim/v2/Users\",\n\t\t\t\tmetadata: { description: \"List SCIM users (RFC 7644)\" },\n\t\t\t\tasync handler(request) {\n\t\t\t\t\treturn (await module.handleRequest(request)) as Response;\n\t\t\t\t},\n\t\t\t});\n\n\t\t\tctx.addEndpoint({\n\t\t\t\tmethod: \"POST\",\n\t\t\t\tpath: \"/scim/v2/Users\",\n\t\t\t\tmetadata: { description: \"Create (provision) a SCIM user\" },\n\t\t\t\tasync handler(request) {\n\t\t\t\t\treturn (await module.handleRequest(request)) as Response;\n\t\t\t\t},\n\t\t\t});\n\n\t\t\t// Users by ID\n\t\t\tctx.addEndpoint({\n\t\t\t\tmethod: \"GET\",\n\t\t\t\tpath: \"/scim/v2/Users/:id\",\n\t\t\t\tmetadata: { description: \"Get a SCIM user by ID\" },\n\t\t\t\tasync handler(request) {\n\t\t\t\t\treturn (await module.handleRequest(request)) as Response;\n\t\t\t\t},\n\t\t\t});\n\n\t\t\tctx.addEndpoint({\n\t\t\t\tmethod: \"PUT\",\n\t\t\t\tpath: \"/scim/v2/Users/:id\",\n\t\t\t\tmetadata: { description: \"Replace a SCIM user\" },\n\t\t\t\tasync handler(request) {\n\t\t\t\t\treturn (await module.handleRequest(request)) as Response;\n\t\t\t\t},\n\t\t\t});\n\n\t\t\tctx.addEndpoint({\n\t\t\t\tmethod: \"PATCH\",\n\t\t\t\tpath: \"/scim/v2/Users/:id\",\n\t\t\t\tmetadata: { description: \"Partially update a SCIM user\" },\n\t\t\t\tasync handler(request) {\n\t\t\t\t\treturn (await module.handleRequest(request)) as Response;\n\t\t\t\t},\n\t\t\t});\n\n\t\t\tctx.addEndpoint({\n\t\t\t\tmethod: \"DELETE\",\n\t\t\t\tpath: \"/scim/v2/Users/:id\",\n\t\t\t\tmetadata: { description: \"Deprovision a SCIM user\" },\n\t\t\t\tasync handler(request) {\n\t\t\t\t\treturn (await module.handleRequest(request)) as Response;\n\t\t\t\t},\n\t\t\t});\n\n\t\t\t// Groups collection\n\t\t\tctx.addEndpoint({\n\t\t\t\tmethod: \"GET\",\n\t\t\t\tpath: \"/scim/v2/Groups\",\n\t\t\t\tmetadata: { description: \"List SCIM groups (mapped to organizations)\" },\n\t\t\t\tasync handler(request) {\n\t\t\t\t\treturn (await module.handleRequest(request)) as Response;\n\t\t\t\t},\n\t\t\t});\n\n\t\t\tctx.addEndpoint({\n\t\t\t\tmethod: \"POST\",\n\t\t\t\tpath: \"/scim/v2/Groups\",\n\t\t\t\tmetadata: { description: \"Create a SCIM group\" },\n\t\t\t\tasync handler(request) {\n\t\t\t\t\treturn (await module.handleRequest(request)) as Response;\n\t\t\t\t},\n\t\t\t});\n\n\t\t\t// Groups by ID\n\t\t\tctx.addEndpoint({\n\t\t\t\tmethod: \"GET\",\n\t\t\t\tpath: \"/scim/v2/Groups/:id\",\n\t\t\t\tmetadata: { description: \"Get a SCIM group by ID\" },\n\t\t\t\tasync handler(request) {\n\t\t\t\t\treturn (await module.handleRequest(request)) as Response;\n\t\t\t\t},\n\t\t\t});\n\n\t\t\tctx.addEndpoint({\n\t\t\t\tmethod: \"PUT\",\n\t\t\t\tpath: \"/scim/v2/Groups/:id\",\n\t\t\t\tmetadata: { description: \"Replace a SCIM group\" },\n\t\t\t\tasync handler(request) {\n\t\t\t\t\treturn (await module.handleRequest(request)) as Response;\n\t\t\t\t},\n\t\t\t});\n\n\t\t\tctx.addEndpoint({\n\t\t\t\tmethod: \"PATCH\",\n\t\t\t\tpath: \"/scim/v2/Groups/:id\",\n\t\t\t\tmetadata: { description: \"Partially update a SCIM group\" },\n\t\t\t\tasync handler(request) {\n\t\t\t\t\treturn (await module.handleRequest(request)) as Response;\n\t\t\t\t},\n\t\t\t});\n\n\t\t\tctx.addEndpoint({\n\t\t\t\tmethod: \"DELETE\",\n\t\t\t\tpath: \"/scim/v2/Groups/:id\",\n\t\t\t\tmetadata: { description: \"Delete a SCIM group\" },\n\t\t\t\tasync handler(request) {\n\t\t\t\t\treturn (await module.handleRequest(request)) as Response;\n\t\t\t\t},\n\t\t\t});\n\t\t},\n\t};\n}\n","/**\n * Sign In With Ethereum (SIWE) for KavachOS.\n *\n * Authenticates users by verifying an Ethereum wallet signature per EIP-4361.\n * Full secp256k1 recovery requires ethers or viem as peer deps — this module\n * validates message format and nonce integrity. Add a `verify` override via\n * `verifySignature` option when you want cryptographic proof.\n *\n * @example\n * ```typescript\n * const siwe = createSiweModule({\n * domain: 'example.com',\n * uri: 'https://example.com',\n * statement: 'Sign in to Example App',\n * });\n *\n * // 1. Frontend requests a nonce\n * const nonce = await siwe.generateNonce();\n *\n * // 2. Frontend builds the message and asks wallet to sign it\n * const message = siwe.buildMessage('0xAbc...', nonce, 1);\n *\n * // 3. Frontend submits message + signature\n * const { address, chainId } = await siwe.verify(message, signature);\n * ```\n */\n\nimport { randomBytes } from \"node:crypto\";\n\n// ---------------------------------------------------------------------------\n// Public types\n// ---------------------------------------------------------------------------\n\nexport interface SiweConfig {\n\t/** Your app's domain (e.g., \"example.com\") */\n\tdomain: string;\n\t/** URI (e.g., \"https://example.com\") */\n\turi: string;\n\t/** Statement shown in wallet (optional) */\n\tstatement?: string;\n\t/** Nonce TTL in seconds (default: 300) */\n\tnonceTtlSeconds?: number;\n\t/**\n\t * Optional signature verifier. Called with the EIP-4361 message and\n\t * hex signature. Should return the recovered Ethereum address.\n\t * When omitted, the module trusts the address from the message body\n\t * (suitable for development; add viem/ethers recovery in production).\n\t */\n\tverifySignature?: (message: string, signature: string) => Promise<string>;\n}\n\nexport interface SiweModule {\n\t/** Generate a nonce for the SIWE message */\n\tgenerateNonce(): Promise<string>;\n\t/** Build the EIP-4361 message for the wallet to sign */\n\tbuildMessage(address: string, nonce: string, chainId?: number): string;\n\t/** Verify the signed message and return the Ethereum address */\n\tverify(message: string, signature: string): Promise<{ address: string; chainId: number }>;\n\t/** Handle full SIWE auth flow via HTTP */\n\thandleRequest(request: Request): Promise<Response | null>;\n}\n\nexport interface SiweVerifyResult {\n\taddress: string;\n\tchainId: number;\n}\n\n// ---------------------------------------------------------------------------\n// Internal types\n// ---------------------------------------------------------------------------\n\ninterface NonceEntry {\n\texpiresAt: number;\n}\n\ninterface ParsedSiweMessage {\n\tdomain: string;\n\taddress: string;\n\turi: string;\n\tversion: string;\n\tchainId: number;\n\tnonce: string;\n\tissuedAt: string;\n\tstatement?: string;\n}\n\n// ---------------------------------------------------------------------------\n// Constants\n// ---------------------------------------------------------------------------\n\nconst DEFAULT_NONCE_TTL_SECONDS = 300;\nconst SIWE_VERSION = \"1\";\n\n// ---------------------------------------------------------------------------\n// Helpers\n// ---------------------------------------------------------------------------\n\nfunction jsonResponse(body: unknown, status = 200): Response {\n\treturn new Response(JSON.stringify(body), {\n\t\tstatus,\n\t\theaders: { \"Content-Type\": \"application/json\" },\n\t});\n}\n\nasync function parseBody(request: Request): Promise<Record<string, unknown>> {\n\ttry {\n\t\treturn (await request.json()) as Record<string, unknown>;\n\t} catch {\n\t\treturn {};\n\t}\n}\n\nfunction generateHexNonce(byteLength = 16): string {\n\treturn randomBytes(byteLength).toString(\"hex\");\n}\n\n/**\n * Parse an EIP-4361 message into its structured fields.\n * Returns null if the message does not match the expected format.\n */\nfunction parseSiweMessage(message: string): ParsedSiweMessage | null {\n\tconst lines = message.split(\"\\n\");\n\tif (lines.length < 9) return null;\n\n\t// Line 0: \"${domain} wants you to sign in with your Ethereum account:\"\n\tconst domainLine = lines[0] ?? \"\";\n\tconst domainMatch = /^(.+) wants you to sign in with your Ethereum account:$/.exec(domainLine);\n\tif (!domainMatch) return null;\n\tconst domain = domainMatch[1] ?? \"\";\n\n\t// Line 1: (blank)\n\t// Line 2: Ethereum address\n\tconst address = lines[2]?.trim();\n\tif (!address || !/^0x[0-9a-fA-F]{40}$/.test(address)) return null;\n\n\t// Line 3: (blank)\n\t// Lines 4+: key-value fields, possibly a statement before URI\n\tlet idx = 4;\n\n\t// Optional statement block: non-empty line before \"URI:\" field\n\tlet statement: string | undefined;\n\tconst lineAtIdx = lines[idx];\n\tif (lineAtIdx && !lineAtIdx.startsWith(\"URI:\")) {\n\t\tstatement = lineAtIdx;\n\t\tidx++;\n\t\t// blank line after statement\n\t\tif (lines[idx] === \"\") idx++;\n\t}\n\n\tconst fieldLines = lines.slice(idx);\n\tconst fields: Record<string, string> = {};\n\tfor (const line of fieldLines) {\n\t\tconst colonIdx = line.indexOf(\": \");\n\t\tif (colonIdx === -1) continue;\n\t\tconst key = line.slice(0, colonIdx).trim();\n\t\tconst value = line.slice(colonIdx + 2).trim();\n\t\tfields[key] = value;\n\t}\n\n\tconst fieldUri = fields.URI;\n\tconst fieldVersion = fields.Version;\n\tconst fieldChainId = fields[\"Chain ID\"];\n\tconst fieldNonce = fields.Nonce;\n\tconst fieldIssuedAt = fields[\"Issued At\"];\n\n\tif (!fieldUri || !fieldVersion || !fieldChainId || !fieldNonce || !fieldIssuedAt) {\n\t\treturn null;\n\t}\n\n\tconst chainId = parseInt(fieldChainId, 10);\n\tif (Number.isNaN(chainId)) return null;\n\n\treturn {\n\t\tdomain,\n\t\taddress,\n\t\turi: fieldUri,\n\t\tversion: fieldVersion,\n\t\tchainId,\n\t\tnonce: fieldNonce,\n\t\tissuedAt: fieldIssuedAt,\n\t\tstatement,\n\t};\n}\n\n// ---------------------------------------------------------------------------\n// Factory\n// ---------------------------------------------------------------------------\n\nexport function createSiweModule(config: SiweConfig): SiweModule {\n\tconst nonceTtlMs = (config.nonceTtlSeconds ?? DEFAULT_NONCE_TTL_SECONDS) * 1000;\n\n\t// In-memory nonce store: nonce -> expiry timestamp\n\tconst nonceStore = new Map<string, NonceEntry>();\n\n\tfunction purgeExpiredNonces(): void {\n\t\tconst now = Date.now();\n\t\tfor (const [nonce, entry] of nonceStore) {\n\t\t\tif (entry.expiresAt <= now) {\n\t\t\t\tnonceStore.delete(nonce);\n\t\t\t}\n\t\t}\n\t}\n\n\tasync function generateNonce(): Promise<string> {\n\t\tpurgeExpiredNonces();\n\t\tconst nonce = generateHexNonce();\n\t\tnonceStore.set(nonce, { expiresAt: Date.now() + nonceTtlMs });\n\t\treturn nonce;\n\t}\n\n\tfunction buildMessage(address: string, nonce: string, chainId = 1): string {\n\t\tconst lines: string[] = [\n\t\t\t`${config.domain} wants you to sign in with your Ethereum account:`,\n\t\t\t\"\",\n\t\t\taddress,\n\t\t\t\"\",\n\t\t];\n\n\t\tif (config.statement) {\n\t\t\tlines.push(config.statement, \"\");\n\t\t}\n\n\t\tlines.push(\n\t\t\t`URI: ${config.uri}`,\n\t\t\t`Version: ${SIWE_VERSION}`,\n\t\t\t`Chain ID: ${chainId}`,\n\t\t\t`Nonce: ${nonce}`,\n\t\t\t`Issued At: ${new Date().toISOString()}`,\n\t\t);\n\n\t\treturn lines.join(\"\\n\");\n\t}\n\n\tasync function verify(message: string, signature: string): Promise<SiweVerifyResult> {\n\t\tconst parsed = parseSiweMessage(message);\n\t\tif (!parsed) {\n\t\t\tthrow new Error(\"Invalid SIWE message format\");\n\t\t}\n\n\t\t// Domain check\n\t\tif (parsed.domain !== config.domain) {\n\t\t\tthrow new Error(`Domain mismatch: expected ${config.domain}, got ${parsed.domain}`);\n\t\t}\n\n\t\t// URI check\n\t\tif (parsed.uri !== config.uri) {\n\t\t\tthrow new Error(`URI mismatch: expected ${config.uri}, got ${parsed.uri}`);\n\t\t}\n\n\t\t// Version check\n\t\tif (parsed.version !== SIWE_VERSION) {\n\t\t\tthrow new Error(`Unsupported SIWE version: ${parsed.version}`);\n\t\t}\n\n\t\t// Nonce check\n\t\tconst nonceEntry = nonceStore.get(parsed.nonce);\n\t\tif (!nonceEntry) {\n\t\t\tthrow new Error(\"Nonce not found or already used\");\n\t\t}\n\t\tif (nonceEntry.expiresAt <= Date.now()) {\n\t\t\tnonceStore.delete(parsed.nonce);\n\t\t\tthrow new Error(\"Nonce expired\");\n\t\t}\n\n\t\t// Consume nonce (single use)\n\t\tnonceStore.delete(parsed.nonce);\n\n\t\t// Signature verification\n\t\tlet verifiedAddress: string;\n\t\tif (config.verifySignature) {\n\t\t\tverifiedAddress = await config.verifySignature(message, signature);\n\t\t} else {\n\t\t\t// Trust-the-message mode: signature presence is checked but not cryptographically verified.\n\t\t\t// Suitable for development. Add verifySignature for production.\n\t\t\tif (!signature || signature.length < 10) {\n\t\t\t\tthrow new Error(\"Signature is required\");\n\t\t\t}\n\t\t\tverifiedAddress = parsed.address;\n\t\t}\n\n\t\t// Normalise to checksum-style lowercase for comparison\n\t\tif (verifiedAddress.toLowerCase() !== parsed.address.toLowerCase()) {\n\t\t\tthrow new Error(\"Signature does not match address\");\n\t\t}\n\n\t\treturn { address: parsed.address, chainId: parsed.chainId };\n\t}\n\n\tasync function handleRequest(request: Request): Promise<Response | null> {\n\t\tconst url = new URL(request.url);\n\t\tconst { method, pathname } = { method: request.method, pathname: url.pathname };\n\n\t\t// GET /auth/siwe/nonce\n\t\tif (method === \"GET\" && pathname.endsWith(\"/auth/siwe/nonce\")) {\n\t\t\tconst nonce = await generateNonce();\n\t\t\treturn jsonResponse({ nonce });\n\t\t}\n\n\t\t// POST /auth/siwe/verify\n\t\tif (method === \"POST\" && pathname.endsWith(\"/auth/siwe/verify\")) {\n\t\t\tconst body = await parseBody(request);\n\t\t\tconst message = typeof body.message === \"string\" ? body.message : null;\n\t\t\tconst signature = typeof body.signature === \"string\" ? body.signature : null;\n\n\t\t\tif (!message || !signature) {\n\t\t\t\treturn jsonResponse({ error: \"Missing required fields: message, signature\" }, 400);\n\t\t\t}\n\n\t\t\ttry {\n\t\t\t\tconst result = await verify(message, signature);\n\t\t\t\treturn jsonResponse({ address: result.address, chainId: result.chainId });\n\t\t\t} catch (err) {\n\t\t\t\treturn jsonResponse(\n\t\t\t\t\t{ error: err instanceof Error ? err.message : \"Verification failed\" },\n\t\t\t\t\t400,\n\t\t\t\t);\n\t\t\t}\n\t\t}\n\n\t\treturn null;\n\t}\n\n\treturn { generateNonce, buildMessage, verify, handleRequest };\n}\n\n// ---------------------------------------------------------------------------\n// Plugin factory\n// ---------------------------------------------------------------------------\n\nimport type { KavachPlugin } from \"../plugin/types.js\";\n\nexport function siwe(config: SiweConfig): KavachPlugin {\n\treturn {\n\t\tid: \"kavach-siwe\",\n\n\t\tasync init(ctx): Promise<undefined> {\n\t\t\tconst mod = createSiweModule(config);\n\n\t\t\t// GET /auth/siwe/nonce\n\t\t\tctx.addEndpoint({\n\t\t\t\tmethod: \"GET\",\n\t\t\t\tpath: \"/auth/siwe/nonce\",\n\t\t\t\tmetadata: {\n\t\t\t\t\tdescription: \"Generate a SIWE nonce for wallet signing\",\n\t\t\t\t\trateLimit: { window: 60_000, max: 60 },\n\t\t\t\t},\n\t\t\t\tasync handler(_request, _endpointCtx) {\n\t\t\t\t\tconst nonce = await mod.generateNonce();\n\t\t\t\t\treturn new Response(JSON.stringify({ nonce }), {\n\t\t\t\t\t\tstatus: 200,\n\t\t\t\t\t\theaders: { \"Content-Type\": \"application/json\" },\n\t\t\t\t\t});\n\t\t\t\t},\n\t\t\t});\n\n\t\t\t// POST /auth/siwe/verify\n\t\t\tctx.addEndpoint({\n\t\t\t\tmethod: \"POST\",\n\t\t\t\tpath: \"/auth/siwe/verify\",\n\t\t\t\tmetadata: {\n\t\t\t\t\tdescription: \"Verify a SIWE-signed message and return the Ethereum address\",\n\t\t\t\t\trateLimit: { window: 60_000, max: 20 },\n\t\t\t\t},\n\t\t\t\tasync handler(request, _endpointCtx) {\n\t\t\t\t\tlet body: Record<string, unknown>;\n\t\t\t\t\ttry {\n\t\t\t\t\t\tbody = (await request.json()) as Record<string, unknown>;\n\t\t\t\t\t} catch {\n\t\t\t\t\t\tbody = {};\n\t\t\t\t\t}\n\n\t\t\t\t\tconst message = typeof body.message === \"string\" ? body.message : null;\n\t\t\t\t\tconst signature = typeof body.signature === \"string\" ? body.signature : null;\n\n\t\t\t\t\tif (!message || !signature) {\n\t\t\t\t\t\treturn new Response(\n\t\t\t\t\t\t\tJSON.stringify({ error: \"Missing required fields: message, signature\" }),\n\t\t\t\t\t\t\t{ status: 400, headers: { \"Content-Type\": \"application/json\" } },\n\t\t\t\t\t\t);\n\t\t\t\t\t}\n\n\t\t\t\t\ttry {\n\t\t\t\t\t\tconst result = await mod.verify(message, signature);\n\t\t\t\t\t\treturn new Response(\n\t\t\t\t\t\t\tJSON.stringify({ address: result.address, chainId: result.chainId }),\n\t\t\t\t\t\t\t{ status: 200, headers: { \"Content-Type\": \"application/json\" } },\n\t\t\t\t\t\t);\n\t\t\t\t\t} catch (err) {\n\t\t\t\t\t\treturn new Response(\n\t\t\t\t\t\t\tJSON.stringify({\n\t\t\t\t\t\t\t\terror: err instanceof Error ? err.message : \"Verification failed\",\n\t\t\t\t\t\t\t}),\n\t\t\t\t\t\t\t{ status: 400, headers: { \"Content-Type\": \"application/json\" } },\n\t\t\t\t\t\t);\n\t\t\t\t\t}\n\t\t\t\t},\n\t\t\t});\n\n\t\t\treturn undefined;\n\t\t},\n\t};\n}\n","/**\n * SSO (SAML 2.0 + OIDC) authentication for KavachOS.\n *\n * Supports enterprise SSO via SAML 2.0 identity providers (Okta, Azure AD,\n * Google Workspace) and generic OIDC providers. Connections are linked to\n * organizations and routed by email domain.\n *\n * Security hardening:\n * - Proper XML parsing with namespace support (no regex)\n * - XXE prevention (entity expansion blocked)\n * - SAML condition validation (NotBefore, NotOnOrAfter, Audience, Destination)\n * - InResponseTo tracking (replay prevention)\n * - Signature digest verification\n * - OIDC nonce validation\n * - State parameter expiry\n * - Rate limiting on SSO login attempts\n * - Audit trail logging\n *\n * @example\n * ```typescript\n * const kavach = await createKavach({\n * database: { provider: 'sqlite', url: 'kavach.db' },\n * sso: {\n * saml: [{ id: 'okta', name: 'Okta', entryPoint: '...', issuer: '...', cert: '...', callbackUrl: '...' }],\n * },\n * });\n *\n * // Get SAML auth URL (redirect user to this)\n * const url = await kavach.sso.getSamlAuthUrl(connectionId);\n * ```\n */\n\nimport { createHash, createVerify, randomBytes, randomUUID } from \"node:crypto\";\nimport { TextEncoder as NodeTextEncoder } from \"node:util\";\nimport { deflateRaw } from \"node:zlib\";\nimport { and, eq } from \"drizzle-orm\";\nimport { createRemoteJWKSet, jwtVerify } from \"jose\";\nimport type { Database } from \"../db/database.js\";\nimport { ssoConnections } from \"../db/schema.js\";\n\n// ---------------------------------------------------------------------------\n// Error codes\n// ---------------------------------------------------------------------------\n\nconst SSO_ERROR = {\n\tCONNECTION_NOT_FOUND: \"SSO_CONNECTION_NOT_FOUND\",\n\tCONNECTION_TYPE_MISMATCH: \"SSO_CONNECTION_TYPE_MISMATCH\",\n\tPROVIDER_NOT_CONFIGURED: \"SSO_PROVIDER_NOT_CONFIGURED\",\n\tSAML_SIGNATURE_INVALID: \"SAML_SIGNATURE_INVALID\",\n\tSAML_SIGNATURE_MISSING: \"SAML_SIGNATURE_MISSING\",\n\tSAML_DIGEST_MISMATCH: \"SAML_DIGEST_MISMATCH\",\n\tSAML_MISSING_NAMEID: \"SAML_MISSING_NAMEID\",\n\tSAML_MISSING_ASSERTION: \"SAML_MISSING_ASSERTION\",\n\tSAML_CONDITION_NOT_MET: \"SAML_CONDITION_NOT_MET\",\n\tSAML_AUDIENCE_MISMATCH: \"SAML_AUDIENCE_MISMATCH\",\n\tSAML_DESTINATION_MISMATCH: \"SAML_DESTINATION_MISMATCH\",\n\tSAML_ISSUER_MISMATCH: \"SAML_ISSUER_MISMATCH\",\n\tSAML_REPLAY_DETECTED: \"SAML_REPLAY_DETECTED\",\n\tSAML_ENCRYPTED_NOT_SUPPORTED: \"SAML_ENCRYPTED_NOT_SUPPORTED\",\n\tSAML_XML_PARSE_ERROR: \"SAML_XML_PARSE_ERROR\",\n\tSAML_XXE_DETECTED: \"SAML_XXE_DETECTED\",\n\tOIDC_DISCOVERY_FAILED: \"OIDC_DISCOVERY_FAILED\",\n\tOIDC_TOKEN_EXCHANGE_FAILED: \"OIDC_TOKEN_EXCHANGE_FAILED\",\n\tOIDC_NONCE_MISMATCH: \"OIDC_NONCE_MISMATCH\",\n\tOIDC_MISSING_EMAIL: \"OIDC_MISSING_EMAIL\",\n\tSTATE_EXPIRED: \"SSO_STATE_EXPIRED\",\n\tRATE_LIMITED: \"SSO_RATE_LIMITED\",\n} as const;\n\n// ---------------------------------------------------------------------------\n// Public types\n// ---------------------------------------------------------------------------\n\nexport interface SsoConfig {\n\t/** SAML Identity Provider configurations */\n\tsaml?: SamlProvider[];\n\t/** OIDC Identity Provider configurations */\n\toidc?: OidcProvider[];\n\t/** State parameter TTL in seconds (default: 300 = 5 minutes) */\n\tstateTtlSeconds?: number;\n\t/** Rate limit: max SSO attempts per IP per window (default: 10) */\n\trateLimitMax?: number;\n\t/** Rate limit window in seconds (default: 60) */\n\trateLimitWindowSeconds?: number;\n\t/** Audit log callback */\n\tonAuditEvent?: (event: SsoAuditEvent) => void;\n}\n\nexport interface SamlProvider {\n\tid: string;\n\tname: string;\n\tentryPoint: string;\n\tissuer: string;\n\tcert: string;\n\tcallbackUrl: string;\n\twantAuthnResponseSigned?: boolean;\n\t/** Our entity ID (used for Audience validation). Defaults to issuer. */\n\tentityId?: string;\n\t/** Clock skew tolerance in seconds (default: 120) */\n\tclockSkewSeconds?: number;\n}\n\nexport interface OidcProvider {\n\tid: string;\n\tname: string;\n\tissuer: string;\n\tclientId: string;\n\tclientSecret: string;\n\tcallbackUrl: string;\n\tscopes?: string[];\n\t/** Token endpoint auth method: 'client_secret_post' or 'client_secret_basic' (default: 'client_secret_post') */\n\ttokenEndpointAuthMethod?: \"client_secret_post\" | \"client_secret_basic\";\n}\n\nexport interface SsoConnection {\n\tid: string;\n\torgId: string;\n\tproviderId: string;\n\ttype: \"saml\" | \"oidc\";\n\tdomain: string;\n\tenabled: boolean;\n\tcreatedAt: Date;\n}\n\nexport interface SsoAuditEvent {\n\ttype:\n\t\t| \"sso_login_attempt\"\n\t\t| \"sso_login_success\"\n\t\t| \"sso_login_failure\"\n\t\t| \"sso_connection_created\"\n\t\t| \"sso_connection_removed\";\n\tconnectionId?: string;\n\tproviderId?: string;\n\temail?: string;\n\terror?: string;\n\ttimestamp: Date;\n\tmetadata?: Record<string, unknown>;\n}\n\nexport interface SsoModule {\n\tcreateConnection: (input: {\n\t\torgId: string;\n\t\tproviderId: string;\n\t\ttype: \"saml\" | \"oidc\";\n\t\tdomain: string;\n\t}) => Promise<SsoConnection>;\n\tgetConnectionByDomain: (domain: string) => Promise<SsoConnection | null>;\n\tlistConnections: (orgId: string) => Promise<SsoConnection[]>;\n\tremoveConnection: (connectionId: string) => Promise<void>;\n\tgetSamlAuthUrl: (connectionId: string, relayState?: string) => Promise<string>;\n\thandleSamlResponse: (\n\t\tconnectionId: string,\n\t\tsamlResponse: string,\n\t\texpectedRequestId?: string,\n\t) => Promise<{ user: { id: string; email: string; name?: string }; orgId: string }>;\n\tgetOidcAuthUrl: (connectionId: string, state?: string, nonce?: string) => Promise<string>;\n\thandleOidcCallback: (\n\t\tconnectionId: string,\n\t\tcode: string,\n\t\texpectedNonce?: string,\n\t) => Promise<{ user: { id: string; email: string; name?: string }; orgId: string }>;\n\thandleRequest: (request: Request) => Promise<Response | null>;\n\t/** Generate a state token with embedded timestamp for expiry checking */\n\tgenerateState: () => string;\n\t/** Validate a state token has not expired */\n\tvalidateState: (state: string) => boolean;\n}\n\n// ---------------------------------------------------------------------------\n// Minimal XML parser (no regex for structure)\n// ---------------------------------------------------------------------------\n\n/**\n * Parsed XML node. This is a minimal representation that handles namespaces,\n * attributes, text content, and child nodes. Good enough for SAML responses\n * without pulling in a full XML library.\n */\ninterface XmlNode {\n\t/** Local name (without namespace prefix) */\n\tlocalName: string;\n\t/** Namespace prefix (empty string if none) */\n\tprefix: string;\n\t/** Full tag name as it appears in the XML (prefix:localName or localName) */\n\ttagName: string;\n\t/** Attributes as key-value pairs (attribute names include prefix if present) */\n\tattributes: Map<string, string>;\n\t/** Child nodes */\n\tchildren: XmlNode[];\n\t/** Text content (concatenated text nodes) */\n\ttextContent: string;\n\t/** Raw inner XML (for signature verification) */\n\trawInnerXml: string;\n\t/** Raw outer XML (for signature verification) */\n\trawOuterXml: string;\n}\n\nclass SsoError extends Error {\n\tconstructor(\n\t\tpublic readonly code: string,\n\t\tmessage: string,\n\t) {\n\t\tsuper(message);\n\t\tthis.name = \"SsoError\";\n\t}\n}\n\n/**\n * Check for XXE attack patterns in XML. Rejects any DOCTYPE declarations\n * since SAML responses should never contain them.\n */\nfunction checkXxe(xml: string): void {\n\t// Reject any DOCTYPE declarations - SAML responses must not contain them\n\tif (/<!DOCTYPE/i.test(xml)) {\n\t\tthrow new SsoError(\n\t\t\tSSO_ERROR.SAML_XXE_DETECTED,\n\t\t\t\"XML contains DOCTYPE declaration which is not allowed in SAML responses\",\n\t\t);\n\t}\n\t// Reject entity declarations\n\tif (/<!ENTITY/i.test(xml)) {\n\t\tthrow new SsoError(\n\t\t\tSSO_ERROR.SAML_XXE_DETECTED,\n\t\t\t\"XML contains ENTITY declaration which is not allowed in SAML responses\",\n\t\t);\n\t}\n\t// Reject CDATA sections that could contain entity references\n\tif (/�*0;|�*0;/i.test(xml)) {\n\t\tthrow new SsoError(SSO_ERROR.SAML_XXE_DETECTED, \"XML contains null character entity reference\");\n\t}\n}\n\n/** Strip XML comments from the input. */\nfunction stripXmlComments(xml: string): string {\n\tlet result = \"\";\n\tlet i = 0;\n\twhile (i < xml.length) {\n\t\tif (xml[i] === \"<\" && xml[i + 1] === \"!\" && xml[i + 2] === \"-\" && xml[i + 3] === \"-\") {\n\t\t\t// Find end of comment\n\t\t\tconst endIdx = xml.indexOf(\"-->\", i + 4);\n\t\t\tif (endIdx === -1) {\n\t\t\t\tthrow new SsoError(SSO_ERROR.SAML_XML_PARSE_ERROR, \"Unterminated XML comment\");\n\t\t\t}\n\t\t\ti = endIdx + 3;\n\t\t} else {\n\t\t\tresult += xml[i];\n\t\t\ti++;\n\t\t}\n\t}\n\treturn result;\n}\n\n/** Parse an attribute value, handling both single and double quotes. */\nfunction parseAttributes(attrString: string): Map<string, string> {\n\tconst attrs = new Map<string, string>();\n\tlet i = 0;\n\tconst s = attrString.trim();\n\n\twhile (i < s.length) {\n\t\t// Skip whitespace\n\t\twhile (i < s.length && /\\s/.test(s[i] as string)) i++;\n\t\tif (i >= s.length) break;\n\n\t\t// Read attribute name\n\t\tlet name = \"\";\n\t\twhile (i < s.length && s[i] !== \"=\" && !/\\s/.test(s[i] as string)) {\n\t\t\tname += s[i];\n\t\t\ti++;\n\t\t}\n\t\tif (!name) break;\n\n\t\t// Skip whitespace around =\n\t\twhile (i < s.length && /\\s/.test(s[i] as string)) i++;\n\t\tif (i >= s.length || s[i] !== \"=\") break;\n\t\ti++; // skip =\n\t\twhile (i < s.length && /\\s/.test(s[i] as string)) i++;\n\n\t\t// Read attribute value\n\t\tconst quote = s[i];\n\t\tif (quote !== '\"' && quote !== \"'\") break;\n\t\ti++; // skip opening quote\n\n\t\tlet value = \"\";\n\t\twhile (i < s.length && s[i] !== quote) {\n\t\t\tif (s[i] === \"&\") {\n\t\t\t\t// Handle basic XML entities\n\t\t\t\tconst entityEnd = s.indexOf(\";\", i);\n\t\t\t\tif (entityEnd === -1) break;\n\t\t\t\tconst entity = s.substring(i, entityEnd + 1);\n\t\t\t\tswitch (entity) {\n\t\t\t\t\tcase \"&\":\n\t\t\t\t\t\tvalue += \"&\";\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase \"<\":\n\t\t\t\t\t\tvalue += \"<\";\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase \">\":\n\t\t\t\t\t\tvalue += \">\";\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase \"'\":\n\t\t\t\t\t\tvalue += \"'\";\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase \""\":\n\t\t\t\t\t\tvalue += '\"';\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tdefault:\n\t\t\t\t\t\tvalue += entity;\n\t\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\ti = entityEnd + 1;\n\t\t\t} else {\n\t\t\t\tvalue += s[i];\n\t\t\t\ti++;\n\t\t\t}\n\t\t}\n\t\ti++; // skip closing quote\n\n\t\tattrs.set(name, value);\n\t}\n\n\treturn attrs;\n}\n\n/** Split a tag name into prefix and local name. */\nfunction splitTagName(tagName: string): { prefix: string; localName: string } {\n\tconst colonIdx = tagName.indexOf(\":\");\n\tif (colonIdx === -1) return { prefix: \"\", localName: tagName };\n\treturn { prefix: tagName.substring(0, colonIdx), localName: tagName.substring(colonIdx + 1) };\n}\n\n/**\n * Parse XML into a tree of XmlNodes. This is a minimal parser that handles\n * the subset of XML found in SAML responses. It is NOT a general-purpose\n * XML parser.\n */\nfunction parseXml(xml: string): XmlNode {\n\tcheckXxe(xml);\n\tconst cleaned = stripXmlComments(xml).trim();\n\n\t// Find the first element\n\tconst rootResult = parseElement(cleaned, 0);\n\tif (!rootResult) {\n\t\tthrow new SsoError(\n\t\t\tSSO_ERROR.SAML_XML_PARSE_ERROR,\n\t\t\t\"Failed to parse XML: no root element found\",\n\t\t);\n\t}\n\treturn rootResult.node;\n}\n\ninterface ParseResult {\n\tnode: XmlNode;\n\tendIndex: number;\n}\n\nfunction parseElement(xml: string, startIdx: number): ParseResult | null {\n\tlet i = startIdx;\n\n\t// Skip whitespace and processing instructions\n\twhile (i < xml.length) {\n\t\twhile (i < xml.length && /\\s/.test(xml[i] as string)) i++;\n\t\tif (i >= xml.length) return null;\n\n\t\tif (xml[i] === \"<\" && xml[i + 1] === \"?\") {\n\t\t\t// Processing instruction - skip to ?>\n\t\t\tconst piEnd = xml.indexOf(\"?>\", i + 2);\n\t\t\tif (piEnd === -1) return null;\n\t\t\ti = piEnd + 2;\n\t\t\tcontinue;\n\t\t}\n\t\tbreak;\n\t}\n\n\tif (i >= xml.length || xml[i] !== \"<\") return null;\n\ti++; // skip <\n\n\t// Read tag name\n\tlet tagName = \"\";\n\twhile (i < xml.length && xml[i] !== \">\" && xml[i] !== \"/\" && !/\\s/.test(xml[i] as string)) {\n\t\ttagName += xml[i];\n\t\ti++;\n\t}\n\n\tif (!tagName) return null;\n\n\t// Read attributes\n\tlet attrString = \"\";\n\twhile (i < xml.length && xml[i] !== \">\" && !(xml[i] === \"/\" && xml[i + 1] === \">\")) {\n\t\tattrString += xml[i];\n\t\ti++;\n\t}\n\n\tconst attributes = parseAttributes(attrString);\n\tconst { prefix, localName } = splitTagName(tagName);\n\n\t// Self-closing tag?\n\tif (xml[i] === \"/\" && xml[i + 1] === \">\") {\n\t\tconst outerXml = xml.substring(startIdx, i + 2);\n\t\treturn {\n\t\t\tnode: {\n\t\t\t\tlocalName,\n\t\t\t\tprefix,\n\t\t\t\ttagName,\n\t\t\t\tattributes,\n\t\t\t\tchildren: [],\n\t\t\t\ttextContent: \"\",\n\t\t\t\trawInnerXml: \"\",\n\t\t\t\trawOuterXml: outerXml,\n\t\t\t},\n\t\t\tendIndex: i + 2,\n\t\t};\n\t}\n\n\tif (xml[i] !== \">\") return null;\n\ti++; // skip >\n\n\tconst contentStart = i;\n\n\t// Parse children and text content\n\tconst children: XmlNode[] = [];\n\tlet textContent = \"\";\n\n\twhile (i < xml.length) {\n\t\tif (xml[i] === \"<\") {\n\t\t\t// Check for CDATA\n\t\t\tif (xml.substring(i, i + 9) === \"<![CDATA[\") {\n\t\t\t\tconst cdataEnd = xml.indexOf(\"]]>\", i + 9);\n\t\t\t\tif (cdataEnd === -1) {\n\t\t\t\t\tthrow new SsoError(SSO_ERROR.SAML_XML_PARSE_ERROR, \"Unterminated CDATA section\");\n\t\t\t\t}\n\t\t\t\ttextContent += xml.substring(i + 9, cdataEnd);\n\t\t\t\ti = cdataEnd + 3;\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\t// Check for closing tag\n\t\t\tif (xml[i + 1] === \"/\") {\n\t\t\t\t// Verify it matches our tag\n\t\t\t\tconst closeTagStart = i + 2;\n\t\t\t\tlet closeTagName = \"\";\n\t\t\t\tlet ci = closeTagStart;\n\t\t\t\twhile (ci < xml.length && xml[ci] !== \">\" && !/\\s/.test(xml[ci] as string)) {\n\t\t\t\t\tcloseTagName += xml[ci];\n\t\t\t\t\tci++;\n\t\t\t\t}\n\t\t\t\t// Skip whitespace before >\n\t\t\t\twhile (ci < xml.length && xml[ci] !== \">\") ci++;\n\n\t\t\t\tif (closeTagName === tagName) {\n\t\t\t\t\tconst rawInnerXml = xml.substring(contentStart, i);\n\t\t\t\t\tconst rawOuterXml = xml.substring(startIdx, ci + 1);\n\t\t\t\t\treturn {\n\t\t\t\t\t\tnode: {\n\t\t\t\t\t\t\tlocalName,\n\t\t\t\t\t\t\tprefix,\n\t\t\t\t\t\t\ttagName,\n\t\t\t\t\t\t\tattributes,\n\t\t\t\t\t\t\tchildren,\n\t\t\t\t\t\t\ttextContent: textContent.trim(),\n\t\t\t\t\t\t\trawInnerXml,\n\t\t\t\t\t\t\trawOuterXml,\n\t\t\t\t\t\t},\n\t\t\t\t\t\tendIndex: ci + 1,\n\t\t\t\t\t};\n\t\t\t\t}\n\t\t\t\t// Not our closing tag - error\n\t\t\t\tthrow new SsoError(\n\t\t\t\t\tSSO_ERROR.SAML_XML_PARSE_ERROR,\n\t\t\t\t\t`Mismatched closing tag: expected </${tagName}> but found </${closeTagName}>`,\n\t\t\t\t);\n\t\t\t}\n\n\t\t\t// Child element\n\t\t\tconst childResult = parseElement(xml, i);\n\t\t\tif (childResult) {\n\t\t\t\tchildren.push(childResult.node);\n\t\t\t\ti = childResult.endIndex;\n\t\t\t} else {\n\t\t\t\ti++;\n\t\t\t}\n\t\t} else {\n\t\t\t// Text content - decode basic entities\n\t\t\tlet ch = xml[i] as string;\n\t\t\tif (ch === \"&\") {\n\t\t\t\tconst entityEnd = xml.indexOf(\";\", i);\n\t\t\t\tif (entityEnd !== -1) {\n\t\t\t\t\tconst entity = xml.substring(i, entityEnd + 1);\n\t\t\t\t\tswitch (entity) {\n\t\t\t\t\t\tcase \"&\":\n\t\t\t\t\t\t\tch = \"&\";\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase \"<\":\n\t\t\t\t\t\t\tch = \"<\";\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase \">\":\n\t\t\t\t\t\t\tch = \">\";\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase \"'\":\n\t\t\t\t\t\t\tch = \"'\";\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase \""\":\n\t\t\t\t\t\t\tch = '\"';\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tdefault:\n\t\t\t\t\t\t\tch = entity;\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t\ti = entityEnd + 1;\n\t\t\t\t} else {\n\t\t\t\t\ti++;\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\ti++;\n\t\t\t}\n\t\t\ttextContent += ch;\n\t\t}\n\t}\n\n\tthrow new SsoError(SSO_ERROR.SAML_XML_PARSE_ERROR, `Unterminated element: <${tagName}>`);\n}\n\n// ---------------------------------------------------------------------------\n// XML query helpers\n// ---------------------------------------------------------------------------\n\n/**\n * Find the first descendant node matching a local name (namespace-agnostic).\n */\nfunction findElement(node: XmlNode, localName: string): XmlNode | null {\n\tif (node.localName === localName) return node;\n\tfor (const child of node.children) {\n\t\tconst found = findElement(child, localName);\n\t\tif (found) return found;\n\t}\n\treturn null;\n}\n\n/**\n * Find all descendant nodes matching a local name.\n */\nfunction findAllElements(node: XmlNode, localName: string): XmlNode[] {\n\tconst results: XmlNode[] = [];\n\tif (node.localName === localName) results.push(node);\n\tfor (const child of node.children) {\n\t\tresults.push(...findAllElements(child, localName));\n\t}\n\treturn results;\n}\n\n/**\n * Get the text content of a descendant element by local name.\n */\nfunction getElementText(node: XmlNode, localName: string): string | null {\n\tconst el = findElement(node, localName);\n\tif (!el) return null;\n\t// If the element has children with text, concatenate\n\tif (el.textContent) return el.textContent;\n\t// Check children for text nodes\n\tif (el.children.length > 0) {\n\t\treturn (\n\t\t\tel.children\n\t\t\t\t.map((c) => c.textContent)\n\t\t\t\t.join(\"\")\n\t\t\t\t.trim() || null\n\t\t);\n\t}\n\treturn null;\n}\n\n/**\n * Get a SAML attribute value by Name from within an AttributeStatement.\n */\nfunction getSamlAttributeValue(assertion: XmlNode, attributeName: string): string | null {\n\tconst attrStatement = findElement(assertion, \"AttributeStatement\");\n\tif (!attrStatement) return null;\n\n\tfor (const attr of findAllElements(attrStatement, \"Attribute\")) {\n\t\tconst name = attr.attributes.get(\"Name\");\n\t\tif (name === attributeName) {\n\t\t\tconst valueNode = findElement(attr, \"AttributeValue\");\n\t\t\tif (valueNode) return valueNode.textContent || null;\n\t\t}\n\t}\n\treturn null;\n}\n\n// ---------------------------------------------------------------------------\n// SAML helpers\n// ---------------------------------------------------------------------------\n\nfunction deflateRawAsync(input: string): Promise<Uint8Array> {\n\tconst encoder = new NodeTextEncoder();\n\treturn new Promise((resolve, reject) => {\n\t\tdeflateRaw(encoder.encode(input), (err, result) => {\n\t\t\tif (err) reject(err);\n\t\t\telse resolve(new Uint8Array(result));\n\t\t});\n\t});\n}\n\nfunction uint8ArrayToBase64(bytes: Uint8Array): string {\n\tlet binary = \"\";\n\tfor (let i = 0; i < bytes.length; i++) {\n\t\tbinary += String.fromCharCode(bytes[i] as number);\n\t}\n\treturn btoa(binary);\n}\n\n/** Build a SAML AuthnRequest and return the request ID + encoded request. */\nasync function buildSamlAuthnRequest(\n\tprovider: SamlProvider,\n): Promise<{ requestId: string; encoded: string }> {\n\tconst requestId = `_${randomBytes(16).toString(\"hex\")}`;\n\tconst now = new Date().toISOString();\n\n\tconst xml = `<samlp:AuthnRequest xmlns:samlp=\"urn:oasis:names:tc:SAML:2.0:protocol\" ID=\"${requestId}\" Version=\"2.0\" IssueInstant=\"${now}\" Destination=\"${provider.entryPoint}\" AssertionConsumerServiceURL=\"${provider.callbackUrl}\"><saml:Issuer xmlns:saml=\"urn:oasis:names:tc:SAML:2.0:assertion\">${provider.entityId ?? provider.issuer}</saml:Issuer></samlp:AuthnRequest>`;\n\n\tconst deflated = await deflateRawAsync(xml);\n\tconst b64 = uint8ArrayToBase64(deflated);\n\treturn { requestId, encoded: encodeURIComponent(b64) };\n}\n\n/**\n * Verify the XML signature on a SAML response or assertion.\n *\n * This verifies:\n * 1. The SignedInfo block exists and contains a Reference\n * 2. The digest of the referenced content matches the DigestValue\n * 3. The signature over SignedInfo is valid against the IdP certificate\n * 4. The signature algorithm is RSA-SHA256 or RSA-SHA1\n */\nfunction verifySamlSignature(doc: XmlNode, certPem: string): boolean {\n\tconst signatureNode = findElement(doc, \"Signature\");\n\tif (!signatureNode) return false;\n\n\tconst signedInfoNode = findElement(signatureNode, \"SignedInfo\");\n\tconst sigValueNode = findElement(signatureNode, \"SignatureValue\");\n\tif (!signedInfoNode || !sigValueNode) return false;\n\n\tconst sigValue = sigValueNode.textContent.replace(/\\s/g, \"\");\n\tif (!sigValue) return false;\n\n\t// Determine signature algorithm\n\tconst signatureMethodNode = findElement(signedInfoNode, \"SignatureMethod\");\n\tconst algorithm = signatureMethodNode?.attributes.get(\"Algorithm\") ?? \"\";\n\n\tlet nodeAlgo: string;\n\tif (algorithm.includes(\"rsa-sha256\") || algorithm.includes(\"RSA-SHA256\")) {\n\t\tnodeAlgo = \"RSA-SHA256\";\n\t} else if (algorithm.includes(\"rsa-sha1\") || algorithm.includes(\"RSA-SHA1\")) {\n\t\tnodeAlgo = \"RSA-SHA1\";\n\t} else {\n\t\t// Default to SHA256\n\t\tnodeAlgo = \"RSA-SHA256\";\n\t}\n\n\t// Verify digest\n\tconst referenceNode = findElement(signedInfoNode, \"Reference\");\n\tif (referenceNode) {\n\t\tconst digestValueNode = findElement(referenceNode, \"DigestValue\");\n\t\tconst digestMethodNode = findElement(referenceNode, \"DigestMethod\");\n\t\tif (digestValueNode && digestMethodNode) {\n\t\t\tconst expectedDigest = digestValueNode.textContent.replace(/\\s/g, \"\");\n\t\t\tconst digestAlgo = digestMethodNode.attributes.get(\"Algorithm\") ?? \"\";\n\n\t\t\tconst refUri = referenceNode.attributes.get(\"URI\") ?? \"\";\n\t\t\t// Find the referenced element (URI is #id)\n\t\t\tconst refId = refUri.startsWith(\"#\") ? refUri.substring(1) : \"\";\n\n\t\t\tlet referencedContent = \"\";\n\t\t\tif (refId) {\n\t\t\t\t// Find the element with matching ID\n\t\t\t\tconst findById = (node: XmlNode): XmlNode | null => {\n\t\t\t\t\tconst id =\n\t\t\t\t\t\tnode.attributes.get(\"ID\") ?? node.attributes.get(\"Id\") ?? node.attributes.get(\"id\");\n\t\t\t\t\tif (id === refId) return node;\n\t\t\t\t\tfor (const child of node.children) {\n\t\t\t\t\t\tconst found = findById(child);\n\t\t\t\t\t\tif (found) return found;\n\t\t\t\t\t}\n\t\t\t\t\treturn null;\n\t\t\t\t};\n\t\t\t\tconst referencedNode = findById(doc);\n\t\t\t\tif (referencedNode) {\n\t\t\t\t\t// For enveloped signature transform, we need the content without the Signature element\n\t\t\t\t\treferencedContent = removeSignatureFromXml(referencedNode.rawOuterXml);\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\t// Empty URI means the whole document\n\t\t\t\treferencedContent = removeSignatureFromXml(doc.rawOuterXml);\n\t\t\t}\n\n\t\t\tif (referencedContent && expectedDigest) {\n\t\t\t\tlet hashAlgo: string;\n\t\t\t\tif (digestAlgo.includes(\"sha256\") || digestAlgo.includes(\"SHA256\")) {\n\t\t\t\t\thashAlgo = \"sha256\";\n\t\t\t\t} else if (digestAlgo.includes(\"sha1\") || digestAlgo.includes(\"SHA1\")) {\n\t\t\t\t\thashAlgo = \"sha1\";\n\t\t\t\t} else {\n\t\t\t\t\thashAlgo = \"sha256\";\n\t\t\t\t}\n\n\t\t\t\tconst actualDigest = createHash(hashAlgo).update(referencedContent).digest(\"base64\");\n\t\t\t\tif (actualDigest !== expectedDigest) {\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\t// Normalize certificate\n\tconst normalizedCert = certPem.includes(\"-----\")\n\t\t? certPem\n\t\t: `-----BEGIN CERTIFICATE-----\\n${certPem}\\n-----END CERTIFICATE-----`;\n\n\t// Verify signature over SignedInfo\n\tconst verifier = createVerify(nodeAlgo);\n\tverifier.update(signedInfoNode.rawOuterXml);\n\ttry {\n\t\treturn verifier.verify(normalizedCert, sigValue, \"base64\");\n\t} catch {\n\t\treturn false;\n\t}\n}\n\n/** Remove <Signature> element from XML string (for enveloped signature transform). */\nfunction removeSignatureFromXml(xml: string): string {\n\t// Find and remove the Signature element - handles namespace prefixes\n\t// This is one place where we use pattern matching on the raw XML string,\n\t// but only for removal of a well-defined element, not for data extraction.\n\tlet result = xml;\n\tconst sigOpenPatterns = [\n\t\t/<ds:Signature\\b[\\s\\S]*?<\\/ds:Signature>/,\n\t\t/<Signature\\b[\\s\\S]*?<\\/Signature>/,\n\t\t/<\\w+:Signature\\b[\\s\\S]*?<\\/\\w+:Signature>/,\n\t];\n\tfor (const pattern of sigOpenPatterns) {\n\t\tresult = result.replace(pattern, \"\");\n\t}\n\treturn result;\n}\n\ninterface ParsedSamlResponse {\n\temail: string;\n\tname?: string;\n}\n\n/**\n * Parse and validate a SAML response.\n *\n * Validates:\n * - Signature is present and valid\n * - Assertion exists (encrypted assertions are rejected with clear error)\n * - InResponseTo matches expected request ID (if provided)\n * - Destination matches our ACS URL\n * - Issuer matches configured IdP\n * - NotBefore / NotOnOrAfter conditions\n * - Audience restriction\n * - NameID is present\n */\nfunction parseSamlResponse(\n\tsamlResponse: string,\n\tprovider: SamlProvider,\n\texpectedRequestId?: string,\n): ParsedSamlResponse {\n\tconst decoded = atob(samlResponse);\n\n\t// Parse XML properly\n\tlet doc: XmlNode;\n\ttry {\n\t\tdoc = parseXml(decoded);\n\t} catch (err) {\n\t\tif (err instanceof SsoError) throw err;\n\t\tthrow new SsoError(\n\t\t\tSSO_ERROR.SAML_XML_PARSE_ERROR,\n\t\t\t`Failed to parse SAML response XML: ${err instanceof Error ? err.message : \"unknown error\"}`,\n\t\t);\n\t}\n\n\t// Check for encrypted assertions (not supported yet)\n\tconst encryptedAssertion = findElement(doc, \"EncryptedAssertion\");\n\tif (encryptedAssertion) {\n\t\tthrow new SsoError(\n\t\t\tSSO_ERROR.SAML_ENCRYPTED_NOT_SUPPORTED,\n\t\t\t\"Encrypted SAML assertions are not supported. Configure your IdP to send unencrypted assertions.\",\n\t\t);\n\t}\n\n\t// Verify signature\n\tconst wantSigned = provider.wantAuthnResponseSigned !== false;\n\tif (wantSigned) {\n\t\tconst signatureNode = findElement(doc, \"Signature\");\n\t\tif (!signatureNode) {\n\t\t\tthrow new SsoError(\n\t\t\t\tSSO_ERROR.SAML_SIGNATURE_MISSING,\n\t\t\t\t\"SAML response is not signed but signature is required\",\n\t\t\t);\n\t\t}\n\t\tif (!verifySamlSignature(doc, provider.cert)) {\n\t\t\tthrow new SsoError(\n\t\t\t\tSSO_ERROR.SAML_SIGNATURE_INVALID,\n\t\t\t\t\"SAML response signature verification failed\",\n\t\t\t);\n\t\t}\n\t}\n\n\t// Find Assertion\n\tconst assertion = findElement(doc, \"Assertion\");\n\tif (!assertion) {\n\t\tthrow new SsoError(\n\t\t\tSSO_ERROR.SAML_MISSING_ASSERTION,\n\t\t\t\"SAML response does not contain an Assertion element\",\n\t\t);\n\t}\n\n\t// Validate InResponseTo (replay prevention)\n\tconst responseInResponseTo = doc.attributes.get(\"InResponseTo\");\n\tif (expectedRequestId && responseInResponseTo && responseInResponseTo !== expectedRequestId) {\n\t\tthrow new SsoError(\n\t\t\tSSO_ERROR.SAML_REPLAY_DETECTED,\n\t\t\t`InResponseTo mismatch: expected \"${expectedRequestId}\" but got \"${responseInResponseTo}\"`,\n\t\t);\n\t}\n\n\t// Validate Destination\n\tconst destination = doc.attributes.get(\"Destination\");\n\tif (destination && destination !== provider.callbackUrl) {\n\t\tthrow new SsoError(\n\t\t\tSSO_ERROR.SAML_DESTINATION_MISMATCH,\n\t\t\t`Destination mismatch: expected \"${provider.callbackUrl}\" but got \"${destination}\"`,\n\t\t);\n\t}\n\n\t// Validate Issuer (response level)\n\tconst responseIssuer = getElementText(doc, \"Issuer\");\n\t// Also check assertion-level issuer\n\tconst assertionIssuer = getElementText(assertion, \"Issuer\");\n\tconst expectedEntityId = provider.entityId ?? provider.issuer;\n\n\t// The Issuer in the response should be the IdP's entity ID, not ours.\n\t// But we need to verify the assertion issuer matches what we expect from the IdP.\n\t// For the response-level Issuer, this is the IdP's identifier.\n\t// We don't validate the response Issuer against our entityId - that would be wrong.\n\t// Instead, if the IdP sent a known issuer it should be consistent with assertionIssuer.\n\tif (assertionIssuer && responseIssuer && assertionIssuer !== responseIssuer) {\n\t\tthrow new SsoError(\n\t\t\tSSO_ERROR.SAML_ISSUER_MISMATCH,\n\t\t\t\"Assertion Issuer does not match Response Issuer\",\n\t\t);\n\t}\n\n\t// Validate Conditions\n\tconst conditions = findElement(assertion, \"Conditions\");\n\tif (conditions) {\n\t\tconst clockSkewMs = (provider.clockSkewSeconds ?? 120) * 1000;\n\t\tconst now = Date.now();\n\n\t\tconst notBefore = conditions.attributes.get(\"NotBefore\");\n\t\tif (notBefore) {\n\t\t\tconst notBeforeTime = new Date(notBefore).getTime();\n\t\t\tif (now < notBeforeTime - clockSkewMs) {\n\t\t\t\tthrow new SsoError(\n\t\t\t\t\tSSO_ERROR.SAML_CONDITION_NOT_MET,\n\t\t\t\t\t`Assertion is not yet valid (NotBefore: ${notBefore})`,\n\t\t\t\t);\n\t\t\t}\n\t\t}\n\n\t\tconst notOnOrAfter = conditions.attributes.get(\"NotOnOrAfter\");\n\t\tif (notOnOrAfter) {\n\t\t\tconst notOnOrAfterTime = new Date(notOnOrAfter).getTime();\n\t\t\tif (now >= notOnOrAfterTime + clockSkewMs) {\n\t\t\t\tthrow new SsoError(\n\t\t\t\t\tSSO_ERROR.SAML_CONDITION_NOT_MET,\n\t\t\t\t\t`Assertion has expired (NotOnOrAfter: ${notOnOrAfter})`,\n\t\t\t\t);\n\t\t\t}\n\t\t}\n\n\t\t// Validate Audience\n\t\tconst audienceRestriction = findElement(conditions, \"AudienceRestriction\");\n\t\tif (audienceRestriction) {\n\t\t\tconst audiences = findAllElements(audienceRestriction, \"Audience\");\n\t\t\tif (audiences.length > 0) {\n\t\t\t\tconst audienceValues = audiences.map((a) => a.textContent.trim());\n\t\t\t\tif (!audienceValues.includes(expectedEntityId)) {\n\t\t\t\t\tthrow new SsoError(\n\t\t\t\t\t\tSSO_ERROR.SAML_AUDIENCE_MISMATCH,\n\t\t\t\t\t\t`Audience mismatch: expected \"${expectedEntityId}\" but got [${audienceValues.join(\", \")}]`,\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\t// Also check SubjectConfirmationData for NotOnOrAfter\n\tconst subjectConfirmationData = findElement(assertion, \"SubjectConfirmationData\");\n\tif (subjectConfirmationData) {\n\t\tconst scdNotOnOrAfter = subjectConfirmationData.attributes.get(\"NotOnOrAfter\");\n\t\tif (scdNotOnOrAfter) {\n\t\t\tconst clockSkewMs = (provider.clockSkewSeconds ?? 120) * 1000;\n\t\t\tconst expiry = new Date(scdNotOnOrAfter).getTime();\n\t\t\tif (Date.now() >= expiry + clockSkewMs) {\n\t\t\t\tthrow new SsoError(\n\t\t\t\t\tSSO_ERROR.SAML_CONDITION_NOT_MET,\n\t\t\t\t\t`SubjectConfirmationData has expired (NotOnOrAfter: ${scdNotOnOrAfter})`,\n\t\t\t\t);\n\t\t\t}\n\t\t}\n\n\t\t// Validate InResponseTo at subject level too\n\t\tconst scdInResponseTo = subjectConfirmationData.attributes.get(\"InResponseTo\");\n\t\tif (expectedRequestId && scdInResponseTo && scdInResponseTo !== expectedRequestId) {\n\t\t\tthrow new SsoError(\n\t\t\t\tSSO_ERROR.SAML_REPLAY_DETECTED,\n\t\t\t\t`SubjectConfirmationData InResponseTo mismatch`,\n\t\t\t);\n\t\t}\n\t}\n\n\t// Extract NameID\n\tconst nameIdText = getElementText(assertion, \"NameID\");\n\tif (!nameIdText) {\n\t\tthrow new SsoError(SSO_ERROR.SAML_MISSING_NAMEID, \"SAML Assertion does not contain a NameID\");\n\t}\n\tconst email = nameIdText.trim();\n\n\t// Extract display name from common attribute names\n\tconst firstName =\n\t\tgetSamlAttributeValue(assertion, \"firstName\") ??\n\t\tgetSamlAttributeValue(assertion, \"givenName\") ??\n\t\tgetSamlAttributeValue(\n\t\t\tassertion,\n\t\t\t\"http://schemas.xmlsoap.org/ws/2005/05/identity/claims/givenname\",\n\t\t) ??\n\t\t\"\";\n\tconst lastName =\n\t\tgetSamlAttributeValue(assertion, \"lastName\") ??\n\t\tgetSamlAttributeValue(assertion, \"surname\") ??\n\t\tgetSamlAttributeValue(\n\t\t\tassertion,\n\t\t\t\"http://schemas.xmlsoap.org/ws/2005/05/identity/claims/surname\",\n\t\t) ??\n\t\t\"\";\n\n\tconst name = [firstName, lastName].filter(Boolean).join(\" \") || undefined;\n\n\treturn { email, name };\n}\n\n// ---------------------------------------------------------------------------\n// OIDC helpers\n// ---------------------------------------------------------------------------\n\ninterface OidcDiscoveryResponse {\n\tauthorization_endpoint: string;\n\ttoken_endpoint: string;\n\tjwks_uri: string;\n\tuserinfo_endpoint?: string;\n}\n\nasync function fetchOidcDiscovery(issuer: string): Promise<OidcDiscoveryResponse> {\n\tconst url = `${issuer.replace(/\\/$/, \"\")}/.well-known/openid-configuration`;\n\tconst res = await fetch(url);\n\tif (!res.ok) {\n\t\tthrow new SsoError(\n\t\t\tSSO_ERROR.OIDC_DISCOVERY_FAILED,\n\t\t\t`OIDC discovery failed: HTTP ${res.status}`,\n\t\t);\n\t}\n\treturn res.json() as Promise<OidcDiscoveryResponse>;\n}\n\ninterface OidcTokenResponse {\n\taccess_token: string;\n\tid_token: string;\n\ttoken_type: string;\n\texpires_in?: number;\n}\n\n// ---------------------------------------------------------------------------\n// Rate limiter (in-memory sliding window)\n// ---------------------------------------------------------------------------\n\ninterface RateLimitEntry {\n\ttimestamps: number[];\n}\n\nclass RateLimiter {\n\tprivate readonly entries = new Map<string, RateLimitEntry>();\n\tprivate readonly maxAttempts: number;\n\tprivate readonly windowMs: number;\n\n\tconstructor(maxAttempts: number, windowSeconds: number) {\n\t\tthis.maxAttempts = maxAttempts;\n\t\tthis.windowMs = windowSeconds * 1000;\n\t}\n\n\tcheck(key: string): boolean {\n\t\tconst now = Date.now();\n\t\tconst entry = this.entries.get(key);\n\n\t\tif (!entry) {\n\t\t\tthis.entries.set(key, { timestamps: [now] });\n\t\t\treturn true;\n\t\t}\n\n\t\t// Prune old timestamps\n\t\tentry.timestamps = entry.timestamps.filter((t) => now - t < this.windowMs);\n\t\tif (entry.timestamps.length >= this.maxAttempts) {\n\t\t\treturn false;\n\t\t}\n\n\t\tentry.timestamps.push(now);\n\t\treturn true;\n\t}\n\n\t/** Clear stale entries to prevent memory leak. */\n\tprune(): void {\n\t\tconst now = Date.now();\n\t\tfor (const [key, entry] of this.entries) {\n\t\t\tentry.timestamps = entry.timestamps.filter((t) => now - t < this.windowMs);\n\t\t\tif (entry.timestamps.length === 0) {\n\t\t\t\tthis.entries.delete(key);\n\t\t\t}\n\t\t}\n\t}\n}\n\n// ---------------------------------------------------------------------------\n// State token helpers\n// ---------------------------------------------------------------------------\n\n/** Encode a timestamp into a state token for expiry checking. */\nfunction encodeState(stateTtlSeconds: number): string {\n\tconst now = Date.now();\n\tconst expires = now + stateTtlSeconds * 1000;\n\tconst random = randomBytes(16).toString(\"hex\");\n\t// Format: random.timestamp\n\tconst payload = `${random}.${expires}`;\n\t// Simple HMAC-like integrity check using the random component\n\tconst hash = createHash(\"sha256\").update(payload).digest(\"hex\").slice(0, 8);\n\treturn `${payload}.${hash}`;\n}\n\nfunction validateStateToken(state: string): boolean {\n\tconst parts = state.split(\".\");\n\tif (parts.length !== 3) return false;\n\n\tconst [random, expiresStr, hash] = parts as [string, string, string];\n\tconst payload = `${random}.${expiresStr}`;\n\tconst expectedHash = createHash(\"sha256\").update(payload).digest(\"hex\").slice(0, 8);\n\n\tif (hash !== expectedHash) return false;\n\n\tconst expires = Number.parseInt(expiresStr, 10);\n\tif (Number.isNaN(expires)) return false;\n\n\treturn Date.now() < expires;\n}\n\n// ---------------------------------------------------------------------------\n// Row mapper\n// ---------------------------------------------------------------------------\n\nfunction rowToConnection(row: {\n\tid: string;\n\torgId: string;\n\tproviderId: string;\n\ttype: string;\n\tdomain: string;\n\tenabled: number;\n\tcreatedAt: Date;\n}): SsoConnection {\n\treturn {\n\t\tid: row.id,\n\t\torgId: row.orgId,\n\t\tproviderId: row.providerId,\n\t\ttype: row.type as \"saml\" | \"oidc\",\n\t\tdomain: row.domain,\n\t\tenabled: row.enabled === 1,\n\t\tcreatedAt: row.createdAt,\n\t};\n}\n\n// ---------------------------------------------------------------------------\n// Factory\n// ---------------------------------------------------------------------------\n\nexport function createSsoModule(config: SsoConfig, db: Database): SsoModule {\n\tconst samlProviders = new Map<string, SamlProvider>((config.saml ?? []).map((p) => [p.id, p]));\n\tconst oidcProviders = new Map<string, OidcProvider>((config.oidc ?? []).map((p) => [p.id, p]));\n\tconst stateTtlSeconds = config.stateTtlSeconds ?? 300;\n\tconst rateLimiter = new RateLimiter(\n\t\tconfig.rateLimitMax ?? 10,\n\t\tconfig.rateLimitWindowSeconds ?? 60,\n\t);\n\tconst auditLog = config.onAuditEvent ?? (() => {});\n\n\t// Periodic cleanup of rate limiter entries (every 5 minutes)\n\tconst pruneInterval = setInterval(() => rateLimiter.prune(), 5 * 60 * 1000);\n\t// Allow the process to exit without waiting for this timer\n\tif (typeof pruneInterval === \"object\" && \"unref\" in pruneInterval) {\n\t\tpruneInterval.unref();\n\t}\n\n\tfunction emitAudit(event: Omit<SsoAuditEvent, \"timestamp\">): void {\n\t\tauditLog({ ...event, timestamp: new Date() });\n\t}\n\n\tasync function createConnection(input: {\n\t\torgId: string;\n\t\tproviderId: string;\n\t\ttype: \"saml\" | \"oidc\";\n\t\tdomain: string;\n\t}): Promise<SsoConnection> {\n\t\tconst id = `sso_${randomUUID().replace(/-/g, \"\")}`;\n\t\tconst now = new Date();\n\n\t\tawait db.insert(ssoConnections).values({\n\t\t\tid,\n\t\t\torgId: input.orgId,\n\t\t\tproviderId: input.providerId,\n\t\t\ttype: input.type,\n\t\t\tdomain: input.domain.toLowerCase(),\n\t\t\tenabled: 1,\n\t\t\tcreatedAt: now,\n\t\t});\n\n\t\temitAudit({\n\t\t\ttype: \"sso_connection_created\",\n\t\t\tconnectionId: id,\n\t\t\tproviderId: input.providerId,\n\t\t\tmetadata: { orgId: input.orgId, domain: input.domain.toLowerCase() },\n\t\t});\n\n\t\treturn {\n\t\t\tid,\n\t\t\torgId: input.orgId,\n\t\t\tproviderId: input.providerId,\n\t\t\ttype: input.type,\n\t\t\tdomain: input.domain.toLowerCase(),\n\t\t\tenabled: true,\n\t\t\tcreatedAt: now,\n\t\t};\n\t}\n\n\tasync function getConnectionByDomain(domain: string): Promise<SsoConnection | null> {\n\t\tconst rows = await db\n\t\t\t.select()\n\t\t\t.from(ssoConnections)\n\t\t\t.where(and(eq(ssoConnections.domain, domain.toLowerCase()), eq(ssoConnections.enabled, 1)));\n\t\tconst row = rows[0];\n\t\tif (!row) return null;\n\t\treturn rowToConnection(row);\n\t}\n\n\tasync function listConnections(orgId: string): Promise<SsoConnection[]> {\n\t\tconst rows = await db.select().from(ssoConnections).where(eq(ssoConnections.orgId, orgId));\n\t\treturn rows.map(rowToConnection);\n\t}\n\n\tasync function removeConnection(connectionId: string): Promise<void> {\n\t\tawait db.delete(ssoConnections).where(eq(ssoConnections.id, connectionId));\n\t\temitAudit({\n\t\t\ttype: \"sso_connection_removed\",\n\t\t\tconnectionId,\n\t\t});\n\t}\n\n\tasync function getSamlAuthUrl(connectionId: string, relayState?: string): Promise<string> {\n\t\tconst rows = await db.select().from(ssoConnections).where(eq(ssoConnections.id, connectionId));\n\t\tconst conn = rows[0];\n\t\tif (!conn)\n\t\t\tthrow new SsoError(\n\t\t\t\tSSO_ERROR.CONNECTION_NOT_FOUND,\n\t\t\t\t`SSO connection \"${connectionId}\" not found`,\n\t\t\t);\n\t\tif (conn.type !== \"saml\") {\n\t\t\tthrow new SsoError(\n\t\t\t\tSSO_ERROR.CONNECTION_TYPE_MISMATCH,\n\t\t\t\t`Connection \"${connectionId}\" is not a SAML connection`,\n\t\t\t);\n\t\t}\n\n\t\tconst provider = samlProviders.get(conn.providerId);\n\t\tif (!provider)\n\t\t\tthrow new SsoError(\n\t\t\t\tSSO_ERROR.PROVIDER_NOT_CONFIGURED,\n\t\t\t\t`SAML provider \"${conn.providerId}\" not configured`,\n\t\t\t);\n\n\t\tconst { encoded } = await buildSamlAuthnRequest(provider);\n\t\tconst url = new URL(provider.entryPoint);\n\t\turl.searchParams.set(\"SAMLRequest\", encoded);\n\t\tif (relayState) url.searchParams.set(\"RelayState\", relayState);\n\n\t\treturn url.toString();\n\t}\n\n\tasync function handleSamlResponse(\n\t\tconnectionId: string,\n\t\tsamlResponse: string,\n\t\texpectedRequestId?: string,\n\t): Promise<{ user: { id: string; email: string; name?: string }; orgId: string }> {\n\t\temitAudit({ type: \"sso_login_attempt\", connectionId, metadata: { protocol: \"saml\" } });\n\n\t\t// Rate limit\n\t\tif (!rateLimiter.check(`saml:${connectionId}`)) {\n\t\t\temitAudit({ type: \"sso_login_failure\", connectionId, error: \"Rate limited\" });\n\t\t\tthrow new SsoError(\n\t\t\t\tSSO_ERROR.RATE_LIMITED,\n\t\t\t\t\"Too many SSO login attempts. Please try again later.\",\n\t\t\t);\n\t\t}\n\n\t\tconst rows = await db.select().from(ssoConnections).where(eq(ssoConnections.id, connectionId));\n\t\tconst conn = rows[0];\n\t\tif (!conn)\n\t\t\tthrow new SsoError(\n\t\t\t\tSSO_ERROR.CONNECTION_NOT_FOUND,\n\t\t\t\t`SSO connection \"${connectionId}\" not found`,\n\t\t\t);\n\n\t\tconst provider = samlProviders.get(conn.providerId);\n\t\tif (!provider)\n\t\t\tthrow new SsoError(\n\t\t\t\tSSO_ERROR.PROVIDER_NOT_CONFIGURED,\n\t\t\t\t`SAML provider \"${conn.providerId}\" not configured`,\n\t\t\t);\n\n\t\ttry {\n\t\t\tconst { email, name } = parseSamlResponse(samlResponse, provider, expectedRequestId);\n\n\t\t\tconst userId = `saml_${createHash(\"sha256\").update(`${conn.providerId}:${email}`).digest(\"hex\").slice(0, 32)}`;\n\n\t\t\temitAudit({\n\t\t\t\ttype: \"sso_login_success\",\n\t\t\t\tconnectionId,\n\t\t\t\tproviderId: conn.providerId,\n\t\t\t\temail,\n\t\t\t});\n\n\t\t\treturn {\n\t\t\t\tuser: { id: userId, email, name },\n\t\t\t\torgId: conn.orgId,\n\t\t\t};\n\t\t} catch (err) {\n\t\t\temitAudit({\n\t\t\t\ttype: \"sso_login_failure\",\n\t\t\t\tconnectionId,\n\t\t\t\tproviderId: conn.providerId,\n\t\t\t\terror: err instanceof Error ? err.message : \"Unknown error\",\n\t\t\t});\n\t\t\tthrow err;\n\t\t}\n\t}\n\n\tasync function getOidcAuthUrl(\n\t\tconnectionId: string,\n\t\tstate?: string,\n\t\tnonce?: string,\n\t): Promise<string> {\n\t\tconst rows = await db.select().from(ssoConnections).where(eq(ssoConnections.id, connectionId));\n\t\tconst conn = rows[0];\n\t\tif (!conn)\n\t\t\tthrow new SsoError(\n\t\t\t\tSSO_ERROR.CONNECTION_NOT_FOUND,\n\t\t\t\t`SSO connection \"${connectionId}\" not found`,\n\t\t\t);\n\t\tif (conn.type !== \"oidc\") {\n\t\t\tthrow new SsoError(\n\t\t\t\tSSO_ERROR.CONNECTION_TYPE_MISMATCH,\n\t\t\t\t`Connection \"${connectionId}\" is not an OIDC connection`,\n\t\t\t);\n\t\t}\n\n\t\tconst provider = oidcProviders.get(conn.providerId);\n\t\tif (!provider)\n\t\t\tthrow new SsoError(\n\t\t\t\tSSO_ERROR.PROVIDER_NOT_CONFIGURED,\n\t\t\t\t`OIDC provider \"${conn.providerId}\" not configured`,\n\t\t\t);\n\n\t\tconst discovery = await fetchOidcDiscovery(provider.issuer);\n\t\tconst scopes = (provider.scopes ?? [\"openid\", \"profile\", \"email\"]).join(\" \");\n\n\t\tconst url = new URL(discovery.authorization_endpoint);\n\t\turl.searchParams.set(\"response_type\", \"code\");\n\t\turl.searchParams.set(\"client_id\", provider.clientId);\n\t\turl.searchParams.set(\"redirect_uri\", provider.callbackUrl);\n\t\turl.searchParams.set(\"scope\", scopes);\n\t\tif (state) url.searchParams.set(\"state\", state);\n\t\tif (nonce) url.searchParams.set(\"nonce\", nonce);\n\n\t\treturn url.toString();\n\t}\n\n\tasync function handleOidcCallback(\n\t\tconnectionId: string,\n\t\tcode: string,\n\t\texpectedNonce?: string,\n\t): Promise<{ user: { id: string; email: string; name?: string }; orgId: string }> {\n\t\temitAudit({ type: \"sso_login_attempt\", connectionId, metadata: { protocol: \"oidc\" } });\n\n\t\t// Rate limit\n\t\tif (!rateLimiter.check(`oidc:${connectionId}`)) {\n\t\t\temitAudit({ type: \"sso_login_failure\", connectionId, error: \"Rate limited\" });\n\t\t\tthrow new SsoError(\n\t\t\t\tSSO_ERROR.RATE_LIMITED,\n\t\t\t\t\"Too many SSO login attempts. Please try again later.\",\n\t\t\t);\n\t\t}\n\n\t\tconst rows = await db.select().from(ssoConnections).where(eq(ssoConnections.id, connectionId));\n\t\tconst conn = rows[0];\n\t\tif (!conn)\n\t\t\tthrow new SsoError(\n\t\t\t\tSSO_ERROR.CONNECTION_NOT_FOUND,\n\t\t\t\t`SSO connection \"${connectionId}\" not found`,\n\t\t\t);\n\n\t\tconst provider = oidcProviders.get(conn.providerId);\n\t\tif (!provider)\n\t\t\tthrow new SsoError(\n\t\t\t\tSSO_ERROR.PROVIDER_NOT_CONFIGURED,\n\t\t\t\t`OIDC provider \"${conn.providerId}\" not configured`,\n\t\t\t);\n\n\t\tconst discovery = await fetchOidcDiscovery(provider.issuer);\n\t\tconst authMethod = provider.tokenEndpointAuthMethod ?? \"client_secret_post\";\n\n\t\t// Build token request\n\t\tconst params = new URLSearchParams({\n\t\t\tgrant_type: \"authorization_code\",\n\t\t\tcode,\n\t\t\tredirect_uri: provider.callbackUrl,\n\t\t});\n\n\t\tconst headers: Record<string, string> = {\n\t\t\t\"Content-Type\": \"application/x-www-form-urlencoded\",\n\t\t};\n\n\t\tif (authMethod === \"client_secret_basic\") {\n\t\t\tconst credentials = btoa(\n\t\t\t\t`${encodeURIComponent(provider.clientId)}:${encodeURIComponent(provider.clientSecret)}`,\n\t\t\t);\n\t\t\theaders.Authorization = `Basic ${credentials}`;\n\t\t} else {\n\t\t\t// client_secret_post (default)\n\t\t\tparams.set(\"client_id\", provider.clientId);\n\t\t\tparams.set(\"client_secret\", provider.clientSecret);\n\t\t}\n\n\t\tconst tokenRes = await fetch(discovery.token_endpoint, {\n\t\t\tmethod: \"POST\",\n\t\t\theaders,\n\t\t\tbody: params.toString(),\n\t\t});\n\t\tif (!tokenRes.ok) {\n\t\t\temitAudit({\n\t\t\t\ttype: \"sso_login_failure\",\n\t\t\t\tconnectionId,\n\t\t\t\tproviderId: conn.providerId,\n\t\t\t\terror: `Token exchange failed: HTTP ${tokenRes.status}`,\n\t\t\t});\n\t\t\tthrow new SsoError(\n\t\t\t\tSSO_ERROR.OIDC_TOKEN_EXCHANGE_FAILED,\n\t\t\t\t`OIDC token exchange failed: HTTP ${tokenRes.status}`,\n\t\t\t);\n\t\t}\n\n\t\tconst tokens = (await tokenRes.json()) as OidcTokenResponse;\n\n\t\t// Verify id_token with JWKS\n\t\tconst jwks = createRemoteJWKSet(new URL(discovery.jwks_uri));\n\t\tconst { payload } = await jwtVerify(tokens.id_token, jwks, {\n\t\t\tissuer: provider.issuer,\n\t\t\taudience: provider.clientId,\n\t\t});\n\n\t\t// Validate nonce if expected\n\t\tif (expectedNonce) {\n\t\t\tconst tokenNonce = payload.nonce as string | undefined;\n\t\t\tif (tokenNonce !== expectedNonce) {\n\t\t\t\temitAudit({\n\t\t\t\t\ttype: \"sso_login_failure\",\n\t\t\t\t\tconnectionId,\n\t\t\t\t\tproviderId: conn.providerId,\n\t\t\t\t\terror: \"Nonce mismatch\",\n\t\t\t\t});\n\t\t\t\tthrow new SsoError(\n\t\t\t\t\tSSO_ERROR.OIDC_NONCE_MISMATCH,\n\t\t\t\t\t`OIDC nonce mismatch: expected \"${expectedNonce}\" but got \"${tokenNonce ?? \"(none)\"}\"`,\n\t\t\t\t);\n\t\t\t}\n\t\t}\n\n\t\t// Validate at_hash if present\n\t\tif (payload.at_hash && tokens.access_token) {\n\t\t\tconst atHash = payload.at_hash as string;\n\t\t\t// at_hash is the base64url encoding of the left half of the hash of the access_token\n\t\t\t// Determine hash algorithm from id_token header (default SHA-256)\n\t\t\tconst accessTokenHash = createHash(\"sha256\").update(tokens.access_token).digest();\n\t\t\tconst leftHalf = accessTokenHash.subarray(0, accessTokenHash.length / 2);\n\t\t\tconst expectedAtHash = uint8ArrayToBase64Url(leftHalf);\n\t\t\tif (atHash !== expectedAtHash) {\n\t\t\t\temitAudit({\n\t\t\t\t\ttype: \"sso_login_failure\",\n\t\t\t\t\tconnectionId,\n\t\t\t\t\terror: \"at_hash mismatch\",\n\t\t\t\t});\n\t\t\t\tthrow new SsoError(SSO_ERROR.OIDC_TOKEN_EXCHANGE_FAILED, \"OIDC at_hash validation failed\");\n\t\t\t}\n\t\t}\n\n\t\tconst email = payload.email as string | undefined;\n\t\tif (!email) {\n\t\t\tthrow new SsoError(\n\t\t\t\tSSO_ERROR.OIDC_MISSING_EMAIL,\n\t\t\t\t\"OIDC id_token does not contain an email claim\",\n\t\t\t);\n\t\t}\n\t\tconst name = (payload.name as string | undefined) ?? undefined;\n\n\t\tconst userId = `oidc_${createHash(\"sha256\").update(`${conn.providerId}:${payload.sub}`).digest(\"hex\").slice(0, 32)}`;\n\n\t\temitAudit({\n\t\t\ttype: \"sso_login_success\",\n\t\t\tconnectionId,\n\t\t\tproviderId: conn.providerId,\n\t\t\temail,\n\t\t});\n\n\t\treturn {\n\t\t\tuser: { id: userId, email, name },\n\t\t\torgId: conn.orgId,\n\t\t};\n\t}\n\n\tfunction generateState(): string {\n\t\treturn encodeState(stateTtlSeconds);\n\t}\n\n\tfunction validateState(state: string): boolean {\n\t\treturn validateStateToken(state);\n\t}\n\n\tasync function handleRequest(request: Request): Promise<Response | null> {\n\t\tconst url = new URL(request.url);\n\t\tconst { pathname } = url;\n\t\tconst { method } = request;\n\n\t\tconst json = (data: unknown, status = 200) =>\n\t\t\tnew Response(JSON.stringify(data), {\n\t\t\t\tstatus,\n\t\t\t\theaders: { \"Content-Type\": \"application/json\" },\n\t\t\t});\n\n\t\t// POST /auth/sso/connections\n\t\tif (method === \"POST\" && pathname === \"/auth/sso/connections\") {\n\t\t\tlet body: unknown;\n\t\t\ttry {\n\t\t\t\tbody = await request.json();\n\t\t\t} catch {\n\t\t\t\treturn json({ error: \"Invalid JSON body\" }, 400);\n\t\t\t}\n\t\t\tconst b = body as Record<string, unknown>;\n\t\t\tif (\n\t\t\t\ttypeof b.orgId !== \"string\" ||\n\t\t\t\ttypeof b.providerId !== \"string\" ||\n\t\t\t\ttypeof b.type !== \"string\" ||\n\t\t\t\ttypeof b.domain !== \"string\"\n\t\t\t) {\n\t\t\t\treturn json({ error: \"Missing required fields: orgId, providerId, type, domain\" }, 400);\n\t\t\t}\n\t\t\tif (b.type !== \"saml\" && b.type !== \"oidc\") {\n\t\t\t\treturn json({ error: \"type must be 'saml' or 'oidc'\" }, 400);\n\t\t\t}\n\t\t\tconst conn = await createConnection({\n\t\t\t\torgId: b.orgId,\n\t\t\t\tproviderId: b.providerId,\n\t\t\t\ttype: b.type,\n\t\t\t\tdomain: b.domain,\n\t\t\t});\n\t\t\treturn json(conn, 201);\n\t\t}\n\n\t\t// GET /auth/sso/connections/:orgId\n\t\tconst listMatch = /^\\/auth\\/sso\\/connections\\/([^/]+)$/.exec(pathname);\n\t\tif (method === \"GET\" && listMatch) {\n\t\t\tconst orgId = decodeURIComponent(listMatch[1] ?? \"\");\n\t\t\tconst conns = await listConnections(orgId);\n\t\t\treturn json(conns);\n\t\t}\n\n\t\t// DELETE /auth/sso/connections/:id\n\t\tconst deleteMatch = /^\\/auth\\/sso\\/connections\\/([^/]+)$/.exec(pathname);\n\t\tif (method === \"DELETE\" && deleteMatch) {\n\t\t\tconst connId = decodeURIComponent(deleteMatch[1] ?? \"\");\n\t\t\tawait removeConnection(connId);\n\t\t\treturn json({ success: true });\n\t\t}\n\n\t\t// GET /auth/sso/saml/:connectionId (redirect to IdP)\n\t\tconst samlInitMatch = /^\\/auth\\/sso\\/saml\\/([^/]+)$/.exec(pathname);\n\t\tif (method === \"GET\" && samlInitMatch) {\n\t\t\tconst connId = decodeURIComponent(samlInitMatch[1] ?? \"\");\n\t\t\tconst relayState = url.searchParams.get(\"relayState\") ?? undefined;\n\t\t\ttry {\n\t\t\t\tconst authUrl = await getSamlAuthUrl(connId, relayState);\n\t\t\t\treturn new Response(null, { status: 302, headers: { Location: authUrl } });\n\t\t\t} catch (err) {\n\t\t\t\treturn json({ error: err instanceof Error ? err.message : \"Unknown error\" }, 400);\n\t\t\t}\n\t\t}\n\n\t\t// POST /auth/sso/saml/:connectionId/acs\n\t\tconst samlAcsMatch = /^\\/auth\\/sso\\/saml\\/([^/]+)\\/acs$/.exec(pathname);\n\t\tif (method === \"POST\" && samlAcsMatch) {\n\t\t\tconst connId = decodeURIComponent(samlAcsMatch[1] ?? \"\");\n\t\t\tlet samlResponse: string;\n\t\t\ttry {\n\t\t\t\tconst formData = await request.formData();\n\t\t\t\tconst val = formData.get(\"SAMLResponse\");\n\t\t\t\tif (typeof val !== \"string\") throw new Error(\"Missing SAMLResponse\");\n\t\t\t\tsamlResponse = val;\n\t\t\t} catch {\n\t\t\t\treturn json({ error: \"Missing or invalid SAMLResponse\" }, 400);\n\t\t\t}\n\t\t\ttry {\n\t\t\t\tconst result = await handleSamlResponse(connId, samlResponse);\n\t\t\t\treturn json(result);\n\t\t\t} catch (err) {\n\t\t\t\tconst status = err instanceof SsoError && err.code === SSO_ERROR.RATE_LIMITED ? 429 : 401;\n\t\t\t\treturn json(\n\t\t\t\t\t{\n\t\t\t\t\t\terror: err instanceof Error ? err.message : \"SAML error\",\n\t\t\t\t\t\tcode: err instanceof SsoError ? err.code : \"SAML_ERROR\",\n\t\t\t\t\t},\n\t\t\t\t\tstatus,\n\t\t\t\t);\n\t\t\t}\n\t\t}\n\n\t\t// GET /auth/sso/oidc/:connectionId (redirect to IdP)\n\t\tconst oidcInitMatch = /^\\/auth\\/sso\\/oidc\\/([^/]+)$/.exec(pathname);\n\t\tif (method === \"GET\" && oidcInitMatch) {\n\t\t\tconst connId = decodeURIComponent(oidcInitMatch[1] ?? \"\");\n\t\t\tconst state = url.searchParams.get(\"state\") ?? undefined;\n\t\t\tconst nonce = url.searchParams.get(\"nonce\") ?? undefined;\n\t\t\ttry {\n\t\t\t\tconst authUrl = await getOidcAuthUrl(connId, state, nonce);\n\t\t\t\treturn new Response(null, { status: 302, headers: { Location: authUrl } });\n\t\t\t} catch (err) {\n\t\t\t\treturn json({ error: err instanceof Error ? err.message : \"Unknown error\" }, 400);\n\t\t\t}\n\t\t}\n\n\t\t// GET /auth/sso/oidc/:connectionId/callback\n\t\tconst oidcCbMatch = /^\\/auth\\/sso\\/oidc\\/([^/]+)\\/callback$/.exec(pathname);\n\t\tif (method === \"GET\" && oidcCbMatch) {\n\t\t\tconst connId = decodeURIComponent(oidcCbMatch[1] ?? \"\");\n\t\t\tconst code = url.searchParams.get(\"code\");\n\t\t\tif (!code) return json({ error: \"Missing code parameter\" }, 400);\n\t\t\ttry {\n\t\t\t\tconst result = await handleOidcCallback(connId, code);\n\t\t\t\treturn json(result);\n\t\t\t} catch (err) {\n\t\t\t\tconst status = err instanceof SsoError && err.code === SSO_ERROR.RATE_LIMITED ? 429 : 401;\n\t\t\t\treturn json(\n\t\t\t\t\t{\n\t\t\t\t\t\terror: err instanceof Error ? err.message : \"OIDC error\",\n\t\t\t\t\t\tcode: err instanceof SsoError ? err.code : \"OIDC_ERROR\",\n\t\t\t\t\t},\n\t\t\t\t\tstatus,\n\t\t\t\t);\n\t\t\t}\n\t\t}\n\n\t\treturn null;\n\t}\n\n\treturn {\n\t\tcreateConnection,\n\t\tgetConnectionByDomain,\n\t\tlistConnections,\n\t\tremoveConnection,\n\t\tgetSamlAuthUrl,\n\t\thandleSamlResponse,\n\t\tgetOidcAuthUrl,\n\t\thandleOidcCallback,\n\t\thandleRequest,\n\t\tgenerateState,\n\t\tvalidateState,\n\t};\n}\n\n// ---------------------------------------------------------------------------\n// Exported for testing\n// ---------------------------------------------------------------------------\n\nexport type { XmlNode };\nexport {\n\tcheckXxe,\n\tencodeState,\n\tfindAllElements,\n\tfindElement,\n\tgetElementText,\n\tgetSamlAttributeValue,\n\tparseXml,\n\tSSO_ERROR,\n\tSsoError,\n\tstripXmlComments,\n\tvalidateStateToken,\n\tverifySamlSignature,\n};\n\n// ---------------------------------------------------------------------------\n// Internal helpers\n// ---------------------------------------------------------------------------\n\nfunction uint8ArrayToBase64Url(bytes: Uint8Array): string {\n\treturn uint8ArrayToBase64(bytes).replace(/\\+/g, \"-\").replace(/\\//g, \"_\").replace(/=+$/, \"\");\n}\n","/**\n * Stripe payment integration for KavachOS.\n *\n * Links Stripe customers to KavachOS users, handles subscription lifecycle\n * webhooks, and stores subscription status. Uses Stripe's REST API directly\n * via fetch — no Stripe SDK dependency.\n *\n * @example\n * ```typescript\n * import { createStripeModule } from 'kavachos/auth';\n *\n * const stripe = createStripeModule({\n * secretKey: process.env.STRIPE_SECRET_KEY!,\n * webhookSecret: process.env.STRIPE_WEBHOOK_SECRET!,\n * autoCreateCustomer: true,\n * }, db);\n *\n * const customerId = await stripe.createCustomer(userId, email, name);\n * const { url } = await stripe.createCheckoutSession(userId, priceId, {\n * successUrl: 'https://example.com/success',\n * cancelUrl: 'https://example.com/cancel',\n * });\n * ```\n */\n\nimport { eq } from \"drizzle-orm\";\nimport type { Database } from \"../db/database.js\";\nimport { users } from \"../db/schema.js\";\n\n// ---------------------------------------------------------------------------\n// Public types\n// ---------------------------------------------------------------------------\n\nexport interface StripeConfig {\n\t/** Stripe secret key (sk_live_... or sk_test_...) */\n\tsecretKey: string;\n\t/** Stripe webhook signing secret (whsec_...) */\n\twebhookSecret: string;\n\t/** Auto-create a Stripe customer when the user record is referenced (default: true) */\n\tautoCreateCustomer?: boolean;\n\t/** Stripe API version (default: \"2024-12-18.acacia\") */\n\tapiVersion?: string;\n\t/** Callback fired whenever subscription data changes for a user */\n\tonSubscriptionChange?: (userId: string, subscription: SubscriptionInfo) => Promise<void>;\n}\n\nexport interface SubscriptionInfo {\n\tid: string;\n\tstatus: \"active\" | \"canceled\" | \"past_due\" | \"trialing\" | \"unpaid\" | \"incomplete\";\n\tpriceId: string;\n\tcurrentPeriodEnd: Date;\n\tcancelAtPeriodEnd: boolean;\n}\n\nexport interface CheckoutOptions {\n\tsuccessUrl?: string;\n\tcancelUrl?: string;\n\ttrialDays?: number;\n\tmetadata?: Record<string, string>;\n}\n\nexport interface StripeModule {\n\t/** Create a Stripe customer for a user and persist the customer ID */\n\tcreateCustomer(userId: string, email: string, name?: string): Promise<string>;\n\t/** Get the Stripe customer ID stored for a user */\n\tgetCustomerId(userId: string): Promise<string | null>;\n\t/** Create a Stripe Checkout Session and return its URL + ID */\n\tcreateCheckoutSession(\n\t\tuserId: string,\n\t\tpriceId: string,\n\t\toptions?: CheckoutOptions,\n\t): Promise<{ url: string; sessionId: string }>;\n\t/** Create a Stripe Billing Portal session and return its URL */\n\tcreatePortalSession(userId: string, returnUrl: string): Promise<{ url: string }>;\n\t/** Return current subscription info for a user from the database */\n\tgetSubscription(userId: string): Promise<SubscriptionInfo | null>;\n\t/** Verify Stripe webhook signature and dispatch to internal handlers */\n\thandleWebhook(request: Request): Promise<Response>;\n\t/** Route an incoming HTTP request to the appropriate handler (returns null if path unmatched) */\n\thandleRequest(request: Request): Promise<Response | null>;\n}\n\n// ---------------------------------------------------------------------------\n// Internal Stripe REST types (minimal — only fields we use)\n// ---------------------------------------------------------------------------\n\ninterface StripeCustomer {\n\tid: string;\n\temail: string | null;\n\tname: string | null;\n}\n\ninterface StripeCheckoutSession {\n\tid: string;\n\turl: string | null;\n\tcustomer: string | null;\n\tsubscription: string | null;\n}\n\ninterface StripeBillingPortalSession {\n\turl: string;\n}\n\ninterface StripeSubscription {\n\tid: string;\n\tstatus: string;\n\tcustomer: string;\n\tcancel_at_period_end: boolean;\n\tcurrent_period_end: number;\n\titems: {\n\t\tdata: Array<{ price: { id: string } }>;\n\t};\n}\n\ninterface StripeInvoice {\n\tid: string;\n\tcustomer: string;\n\tsubscription: string | null;\n}\n\ninterface StripeEvent {\n\tid: string;\n\ttype: string;\n\tdata: { object: Record<string, unknown> };\n}\n\n// ---------------------------------------------------------------------------\n// Stripe REST API client helpers\n// ---------------------------------------------------------------------------\n\nconst STRIPE_API_BASE = \"https://api.stripe.com/v1\";\nconst DEFAULT_API_VERSION = \"2024-12-18.acacia\";\n\n/** Encode a plain object as application/x-www-form-urlencoded, supporting nested objects */\nfunction formEncode(params: Record<string, unknown>, prefix = \"\"): string {\n\tconst parts: string[] = [];\n\n\tfor (const [key, value] of Object.entries(params)) {\n\t\tif (value === undefined || value === null) continue;\n\n\t\tconst encodedKey = prefix ? `${prefix}[${encodeURIComponent(key)}]` : encodeURIComponent(key);\n\n\t\tif (typeof value === \"object\" && !Array.isArray(value)) {\n\t\t\tconst nested = formEncode(value as Record<string, unknown>, encodedKey);\n\t\t\tif (nested) parts.push(nested);\n\t\t} else if (Array.isArray(value)) {\n\t\t\tfor (const item of value) {\n\t\t\t\tparts.push(`${encodedKey}[]=${encodeURIComponent(String(item))}`);\n\t\t\t}\n\t\t} else {\n\t\t\tparts.push(`${encodedKey}=${encodeURIComponent(String(value))}`);\n\t\t}\n\t}\n\n\treturn parts.join(\"&\");\n}\n\nasync function stripeRequest<T>(\n\tsecretKey: string,\n\tapiVersion: string,\n\tmethod: \"GET\" | \"POST\",\n\tpath: string,\n\tbody?: Record<string, unknown>,\n): Promise<T> {\n\tconst url = `${STRIPE_API_BASE}${path}`;\n\tconst headers: Record<string, string> = {\n\t\tAuthorization: `Bearer ${secretKey}`,\n\t\t\"Stripe-Version\": apiVersion,\n\t};\n\n\tlet bodyStr: string | undefined;\n\tif (body && method === \"POST\") {\n\t\theaders[\"Content-Type\"] = \"application/x-www-form-urlencoded\";\n\t\tbodyStr = formEncode(body);\n\t}\n\n\tconst response = await fetch(url, {\n\t\tmethod,\n\t\theaders,\n\t\tbody: bodyStr,\n\t});\n\n\tconst json = (await response.json()) as { error?: { message: string } } & T;\n\n\tif (!response.ok) {\n\t\tconst message = json.error?.message ?? `Stripe API error: ${response.status}`;\n\t\tthrow new Error(message);\n\t}\n\n\treturn json as T;\n}\n\n// ---------------------------------------------------------------------------\n// Webhook signature verification (constant-time HMAC-SHA256)\n// ---------------------------------------------------------------------------\n\nasync function verifyWebhookSignature(\n\tpayload: string,\n\tsignatureHeader: string,\n\twebhookSecret: string,\n): Promise<StripeEvent> {\n\t// Parse Stripe-Signature header: t=<timestamp>,v1=<sig1>,v1=<sig2>,...\n\tconst parts: Record<string, string[]> = {};\n\tfor (const part of signatureHeader.split(\",\")) {\n\t\tconst eqIdx = part.indexOf(\"=\");\n\t\tif (eqIdx === -1) continue;\n\t\tconst k = part.slice(0, eqIdx);\n\t\tconst v = part.slice(eqIdx + 1);\n\t\tif (!parts[k]) parts[k] = [];\n\t\tparts[k].push(v);\n\t}\n\n\tconst timestamp = parts.t?.[0];\n\tconst signatures = parts.v1 ?? [];\n\n\tif (!timestamp || signatures.length === 0) {\n\t\tthrow new Error(\"Invalid Stripe-Signature header\");\n\t}\n\n\t// Reject payloads older than 5 minutes\n\tconst now = Math.floor(Date.now() / 1000);\n\tif (Math.abs(now - parseInt(timestamp, 10)) > 300) {\n\t\tthrow new Error(\"Stripe webhook timestamp is too old\");\n\t}\n\n\tconst signedPayload = `${timestamp}.${payload}`;\n\n\t// Derive expected signature using Web Crypto API (avoids Buffer)\n\tconst encoder = new TextEncoder();\n\tconst keyData = encoder.encode(webhookSecret);\n\tconst msgData = encoder.encode(signedPayload);\n\n\tconst cryptoKey = await crypto.subtle.importKey(\n\t\t\"raw\",\n\t\tkeyData,\n\t\t{ name: \"HMAC\", hash: \"SHA-256\" },\n\t\tfalse,\n\t\t[\"sign\"],\n\t);\n\n\tconst signatureBuffer = await crypto.subtle.sign(\"HMAC\", cryptoKey, msgData);\n\tconst expectedSig = Array.from(new Uint8Array(signatureBuffer))\n\t\t.map((b) => b.toString(16).padStart(2, \"0\"))\n\t\t.join(\"\");\n\n\t// Constant-time comparison — compare against all v1 signatures\n\tlet verified = false;\n\tfor (const sig of signatures) {\n\t\tif (sig.length !== expectedSig.length) continue;\n\n\t\t// Encode both as Uint8Array and XOR all bytes (constant-time)\n\t\tconst a = encoder.encode(sig);\n\t\tconst b = encoder.encode(expectedSig);\n\t\tlet diff = 0;\n\t\tfor (let i = 0; i < a.length; i++) {\n\t\t\tdiff |= (a[i] ?? 0) ^ (b[i] ?? 0);\n\t\t}\n\t\tif (diff === 0) {\n\t\t\tverified = true;\n\t\t\tbreak;\n\t\t}\n\t}\n\n\tif (!verified) {\n\t\tthrow new Error(\"Stripe webhook signature verification failed\");\n\t}\n\n\treturn JSON.parse(payload) as StripeEvent;\n}\n\n// ---------------------------------------------------------------------------\n// Module factory\n// ---------------------------------------------------------------------------\n\nexport function createStripeModule(config: StripeConfig, db: Database): StripeModule {\n\tconst apiVersion = config.apiVersion ?? DEFAULT_API_VERSION;\n\n\tfunction api<T>(\n\t\tmethod: \"GET\" | \"POST\",\n\t\tpath: string,\n\t\tbody?: Record<string, unknown>,\n\t): Promise<T> {\n\t\treturn stripeRequest<T>(config.secretKey, apiVersion, method, path, body);\n\t}\n\n\t// -------------------------------------------------------------------------\n\t// Internal helpers\n\t// -------------------------------------------------------------------------\n\n\tasync function getUserRow(userId: string) {\n\t\tconst rows = await db.select().from(users).where(eq(users.id, userId)).limit(1);\n\t\treturn rows[0] ?? null;\n\t}\n\n\tasync function findUserByCustomerId(customerId: string) {\n\t\tconst rows = await db\n\t\t\t.select()\n\t\t\t.from(users)\n\t\t\t.where(eq(users.stripeCustomerId, customerId))\n\t\t\t.limit(1);\n\t\treturn rows[0] ?? null;\n\t}\n\n\tasync function persistSubscription(\n\t\tuserId: string,\n\t\tsub: StripeSubscription,\n\t): Promise<SubscriptionInfo> {\n\t\tconst priceId = sub.items.data[0]?.price.id ?? \"\";\n\t\tconst currentPeriodEnd = new Date(sub.current_period_end * 1000);\n\t\tconst status = sub.status as SubscriptionInfo[\"status\"];\n\n\t\tawait db\n\t\t\t.update(users)\n\t\t\t.set({\n\t\t\t\tstripeSubscriptionId: sub.id,\n\t\t\t\tstripeSubscriptionStatus: sub.status,\n\t\t\t\tstripePriceId: priceId,\n\t\t\t\tstripeCurrentPeriodEnd: currentPeriodEnd,\n\t\t\t\tstripeCancelAtPeriodEnd: sub.cancel_at_period_end,\n\t\t\t\tupdatedAt: new Date(),\n\t\t\t})\n\t\t\t.where(eq(users.id, userId));\n\n\t\tconst info: SubscriptionInfo = {\n\t\t\tid: sub.id,\n\t\t\tstatus,\n\t\t\tpriceId,\n\t\t\tcurrentPeriodEnd,\n\t\t\tcancelAtPeriodEnd: sub.cancel_at_period_end,\n\t\t};\n\n\t\tif (config.onSubscriptionChange) {\n\t\t\tawait config.onSubscriptionChange(userId, info);\n\t\t}\n\n\t\treturn info;\n\t}\n\n\tasync function clearSubscription(userId: string): Promise<void> {\n\t\tawait db\n\t\t\t.update(users)\n\t\t\t.set({\n\t\t\t\tstripeSubscriptionId: null,\n\t\t\t\tstripeSubscriptionStatus: \"canceled\",\n\t\t\t\tstripePriceId: null,\n\t\t\t\tstripeCurrentPeriodEnd: null,\n\t\t\t\tstripeCancelAtPeriodEnd: false,\n\t\t\t\tupdatedAt: new Date(),\n\t\t\t})\n\t\t\t.where(eq(users.id, userId));\n\t}\n\n\t// -------------------------------------------------------------------------\n\t// Webhook event handlers\n\t// -------------------------------------------------------------------------\n\n\tasync function handleCheckoutSessionCompleted(obj: Record<string, unknown>): Promise<void> {\n\t\tconst session = obj as {\n\t\t\tcustomer: string | null;\n\t\t\tsubscription: string | null;\n\t\t\tclient_reference_id: string | null;\n\t\t\tmetadata: Record<string, string> | null;\n\t\t};\n\n\t\tconst customerId = session.customer;\n\t\tconst subscriptionId = session.subscription;\n\t\tif (!customerId || !subscriptionId) return;\n\n\t\t// Resolve userId — prefer client_reference_id, fall back to DB lookup\n\t\tlet userId: string | null = session.client_reference_id ?? null;\n\t\tif (!userId) {\n\t\t\tconst user = await findUserByCustomerId(customerId);\n\t\t\tuserId = user?.id ?? null;\n\t\t}\n\t\tif (!userId) return;\n\n\t\t// Persist the customer ID if it is not yet linked\n\t\tconst userRow = await getUserRow(userId);\n\t\tif (!userRow?.stripeCustomerId) {\n\t\t\tawait db\n\t\t\t\t.update(users)\n\t\t\t\t.set({ stripeCustomerId: customerId, updatedAt: new Date() })\n\t\t\t\t.where(eq(users.id, userId));\n\t\t}\n\n\t\t// Fetch full subscription data and persist\n\t\tconst sub = await api<StripeSubscription>(\"GET\", `/subscriptions/${subscriptionId}`);\n\t\tawait persistSubscription(userId, sub);\n\t}\n\n\tasync function handleSubscriptionEvent(\n\t\tobj: Record<string, unknown>,\n\t\tdeleted = false,\n\t): Promise<void> {\n\t\tconst sub = obj as unknown as StripeSubscription;\n\t\tconst customerId = sub.customer;\n\n\t\tconst userRow = await findUserByCustomerId(customerId);\n\t\tif (!userRow) return;\n\n\t\tif (deleted) {\n\t\t\tawait clearSubscription(userRow.id);\n\t\t\tif (config.onSubscriptionChange) {\n\t\t\t\tawait config.onSubscriptionChange(userRow.id, {\n\t\t\t\t\tid: sub.id,\n\t\t\t\t\tstatus: \"canceled\",\n\t\t\t\t\tpriceId: sub.items.data[0]?.price.id ?? \"\",\n\t\t\t\t\tcurrentPeriodEnd: new Date(sub.current_period_end * 1000),\n\t\t\t\t\tcancelAtPeriodEnd: false,\n\t\t\t\t});\n\t\t\t}\n\t\t} else {\n\t\t\tawait persistSubscription(userRow.id, sub);\n\t\t}\n\t}\n\n\tasync function handleInvoicePaymentFailed(obj: Record<string, unknown>): Promise<void> {\n\t\tconst invoice = obj as unknown as StripeInvoice;\n\t\tif (!invoice.subscription) return;\n\n\t\tconst userRow = await findUserByCustomerId(invoice.customer);\n\t\tif (!userRow) return;\n\n\t\tawait db\n\t\t\t.update(users)\n\t\t\t.set({ stripeSubscriptionStatus: \"past_due\", updatedAt: new Date() })\n\t\t\t.where(eq(users.id, userRow.id));\n\n\t\tif (userRow.stripeSubscriptionId && config.onSubscriptionChange) {\n\t\t\tawait config.onSubscriptionChange(userRow.id, {\n\t\t\t\tid: userRow.stripeSubscriptionId,\n\t\t\t\tstatus: \"past_due\",\n\t\t\t\tpriceId: userRow.stripePriceId ?? \"\",\n\t\t\t\tcurrentPeriodEnd: userRow.stripeCurrentPeriodEnd ?? new Date(),\n\t\t\t\tcancelAtPeriodEnd: userRow.stripeCancelAtPeriodEnd,\n\t\t\t});\n\t\t}\n\t}\n\n\t// -------------------------------------------------------------------------\n\t// Public API\n\t// -------------------------------------------------------------------------\n\n\tasync function createCustomer(userId: string, email: string, name?: string): Promise<string> {\n\t\tconst customer = await api<StripeCustomer>(\"POST\", \"/customers\", {\n\t\t\temail,\n\t\t\t...(name ? { name } : {}),\n\t\t\tmetadata: { kavach_user_id: userId },\n\t\t});\n\n\t\tawait db\n\t\t\t.update(users)\n\t\t\t.set({ stripeCustomerId: customer.id, updatedAt: new Date() })\n\t\t\t.where(eq(users.id, userId));\n\n\t\treturn customer.id;\n\t}\n\n\tasync function getCustomerId(userId: string): Promise<string | null> {\n\t\tconst row = await getUserRow(userId);\n\t\treturn row?.stripeCustomerId ?? null;\n\t}\n\n\tasync function createCheckoutSession(\n\t\tuserId: string,\n\t\tpriceId: string,\n\t\toptions: CheckoutOptions = {},\n\t): Promise<{ url: string; sessionId: string }> {\n\t\tlet customerId = await getCustomerId(userId);\n\n\t\tif (!customerId && (config.autoCreateCustomer ?? true)) {\n\t\t\tconst userRow = await getUserRow(userId);\n\t\t\tif (!userRow) throw new Error(`User not found: ${userId}`);\n\t\t\tcustomerId = await createCustomer(userId, userRow.email, userRow.name ?? undefined);\n\t\t}\n\n\t\tif (!customerId) {\n\t\t\tthrow new Error(`No Stripe customer for user ${userId}. Set autoCreateCustomer: true.`);\n\t\t}\n\n\t\tconst sessionParams: Record<string, unknown> = {\n\t\t\tcustomer: customerId,\n\t\t\tmode: \"subscription\",\n\t\t\tclient_reference_id: userId,\n\t\t\t\"line_items[0][price]\": priceId,\n\t\t\t\"line_items[0][quantity]\": \"1\",\n\t\t\tsuccess_url: options.successUrl ?? \"https://example.com/success\",\n\t\t\tcancel_url: options.cancelUrl ?? \"https://example.com/cancel\",\n\t\t};\n\n\t\tif (options.trialDays && options.trialDays > 0) {\n\t\t\tsessionParams[\"subscription_data[trial_period_days]\"] = String(options.trialDays);\n\t\t}\n\n\t\tif (options.metadata) {\n\t\t\tfor (const [k, v] of Object.entries(options.metadata)) {\n\t\t\t\tsessionParams[`metadata[${k}]`] = v;\n\t\t\t}\n\t\t}\n\n\t\tconst session = await api<StripeCheckoutSession>(\"POST\", \"/checkout/sessions\", sessionParams);\n\n\t\tif (!session.url) {\n\t\t\tthrow new Error(\"Stripe did not return a checkout URL\");\n\t\t}\n\n\t\treturn { url: session.url, sessionId: session.id };\n\t}\n\n\tasync function createPortalSession(userId: string, returnUrl: string): Promise<{ url: string }> {\n\t\tconst customerId = await getCustomerId(userId);\n\t\tif (!customerId) {\n\t\t\tthrow new Error(`No Stripe customer for user ${userId}`);\n\t\t}\n\n\t\tconst portal = await api<StripeBillingPortalSession>(\"POST\", \"/billing_portal/sessions\", {\n\t\t\tcustomer: customerId,\n\t\t\treturn_url: returnUrl,\n\t\t});\n\n\t\treturn { url: portal.url };\n\t}\n\n\tasync function getSubscription(userId: string): Promise<SubscriptionInfo | null> {\n\t\tconst row = await getUserRow(userId);\n\t\tif (\n\t\t\t!row?.stripeSubscriptionId ||\n\t\t\t!row.stripeSubscriptionStatus ||\n\t\t\t!row.stripePriceId ||\n\t\t\t!row.stripeCurrentPeriodEnd\n\t\t) {\n\t\t\treturn null;\n\t\t}\n\n\t\treturn {\n\t\t\tid: row.stripeSubscriptionId,\n\t\t\tstatus: row.stripeSubscriptionStatus as SubscriptionInfo[\"status\"],\n\t\t\tpriceId: row.stripePriceId,\n\t\t\tcurrentPeriodEnd: row.stripeCurrentPeriodEnd,\n\t\t\tcancelAtPeriodEnd: row.stripeCancelAtPeriodEnd,\n\t\t};\n\t}\n\n\tasync function handleWebhook(request: Request): Promise<Response> {\n\t\tconst signatureHeader = request.headers.get(\"stripe-signature\");\n\t\tif (!signatureHeader) {\n\t\t\treturn new Response(JSON.stringify({ error: \"Missing Stripe-Signature header\" }), {\n\t\t\t\tstatus: 400,\n\t\t\t\theaders: { \"Content-Type\": \"application/json\" },\n\t\t\t});\n\t\t}\n\n\t\tlet payload: string;\n\t\ttry {\n\t\t\tpayload = await request.text();\n\t\t} catch {\n\t\t\treturn new Response(JSON.stringify({ error: \"Failed to read request body\" }), {\n\t\t\t\tstatus: 400,\n\t\t\t\theaders: { \"Content-Type\": \"application/json\" },\n\t\t\t});\n\t\t}\n\n\t\tlet event: StripeEvent;\n\t\ttry {\n\t\t\tevent = await verifyWebhookSignature(payload, signatureHeader, config.webhookSecret);\n\t\t} catch (err) {\n\t\t\treturn new Response(\n\t\t\t\tJSON.stringify({\n\t\t\t\t\terror: err instanceof Error ? err.message : \"Webhook verification failed\",\n\t\t\t\t}),\n\t\t\t\t{ status: 400, headers: { \"Content-Type\": \"application/json\" } },\n\t\t\t);\n\t\t}\n\n\t\ttry {\n\t\t\tswitch (event.type) {\n\t\t\t\tcase \"checkout.session.completed\":\n\t\t\t\t\tawait handleCheckoutSessionCompleted(event.data.object);\n\t\t\t\t\tbreak;\n\t\t\t\tcase \"customer.subscription.created\":\n\t\t\t\tcase \"customer.subscription.updated\":\n\t\t\t\t\tawait handleSubscriptionEvent(event.data.object, false);\n\t\t\t\t\tbreak;\n\t\t\t\tcase \"customer.subscription.deleted\":\n\t\t\t\t\tawait handleSubscriptionEvent(event.data.object, true);\n\t\t\t\t\tbreak;\n\t\t\t\tcase \"invoice.payment_failed\":\n\t\t\t\t\tawait handleInvoicePaymentFailed(event.data.object);\n\t\t\t\t\tbreak;\n\t\t\t\t// Other event types are silently ignored\n\t\t\t}\n\t\t} catch (err) {\n\t\t\treturn new Response(\n\t\t\t\tJSON.stringify({\n\t\t\t\t\terror: err instanceof Error ? err.message : \"Webhook handler error\",\n\t\t\t\t}),\n\t\t\t\t{ status: 500, headers: { \"Content-Type\": \"application/json\" } },\n\t\t\t);\n\t\t}\n\n\t\treturn new Response(JSON.stringify({ received: true }), {\n\t\t\tstatus: 200,\n\t\t\theaders: { \"Content-Type\": \"application/json\" },\n\t\t});\n\t}\n\n\tasync function handleRequest(request: Request): Promise<Response | null> {\n\t\tconst url = new URL(request.url);\n\t\tconst path = url.pathname;\n\n\t\tif (request.method === \"POST\" && path.endsWith(\"/auth/stripe/webhook\")) {\n\t\t\treturn handleWebhook(request);\n\t\t}\n\t\tif (request.method === \"POST\" && path.endsWith(\"/auth/stripe/checkout\")) {\n\t\t\treturn null; // handled by plugin endpoint\n\t\t}\n\t\tif (request.method === \"POST\" && path.endsWith(\"/auth/stripe/portal\")) {\n\t\t\treturn null; // handled by plugin endpoint\n\t\t}\n\t\tif (request.method === \"GET\" && path.endsWith(\"/auth/stripe/subscription\")) {\n\t\t\treturn null; // handled by plugin endpoint\n\t\t}\n\n\t\treturn null;\n\t}\n\n\treturn {\n\t\tcreateCustomer,\n\t\tgetCustomerId,\n\t\tcreateCheckoutSession,\n\t\tcreatePortalSession,\n\t\tgetSubscription,\n\t\thandleWebhook,\n\t\thandleRequest,\n\t};\n}\n","import type { KavachPlugin } from \"../plugin/types.js\";\nimport type { StripeConfig } from \"./stripe.js\";\nimport { createStripeModule } from \"./stripe.js\";\n\nexport type { StripeConfig };\n\n// ---------------------------------------------------------------------------\n// Helpers\n// ---------------------------------------------------------------------------\n\nfunction json(body: unknown, status = 200): Response {\n\treturn new Response(JSON.stringify(body), {\n\t\tstatus,\n\t\theaders: { \"Content-Type\": \"application/json\" },\n\t});\n}\n\nasync function parseBody(request: Request): Promise<Record<string, unknown>> {\n\ttry {\n\t\treturn (await request.json()) as Record<string, unknown>;\n\t} catch {\n\t\treturn {};\n\t}\n}\n\n// ---------------------------------------------------------------------------\n// Plugin factory\n// ---------------------------------------------------------------------------\n\nexport function stripe(config: StripeConfig): KavachPlugin {\n\treturn {\n\t\tid: \"kavach-stripe\",\n\n\t\tasync init(ctx): Promise<undefined> {\n\t\t\tconst module = createStripeModule(config, ctx.db);\n\n\t\t\t// POST /auth/stripe/checkout\n\t\t\t// Creates a Stripe Checkout Session for the authenticated user.\n\t\t\t// Body: { priceId: string, successUrl?: string, cancelUrl?: string,\n\t\t\t// trialDays?: number, metadata?: Record<string, string> }\n\t\t\tctx.addEndpoint({\n\t\t\t\tmethod: \"POST\",\n\t\t\t\tpath: \"/auth/stripe/checkout\",\n\t\t\t\tmetadata: {\n\t\t\t\t\trequireAuth: true,\n\t\t\t\t\tdescription: \"Create a Stripe Checkout Session for the authenticated user\",\n\t\t\t\t},\n\t\t\t\tasync handler(request, endpointCtx) {\n\t\t\t\t\tconst user = await endpointCtx.getUser(request);\n\t\t\t\t\tif (!user) {\n\t\t\t\t\t\treturn json({ error: \"Authentication required\" }, 401);\n\t\t\t\t\t}\n\n\t\t\t\t\tconst body = await parseBody(request);\n\t\t\t\t\tconst priceId = typeof body.priceId === \"string\" ? body.priceId.trim() : null;\n\t\t\t\t\tif (!priceId) {\n\t\t\t\t\t\treturn json({ error: \"Missing required field: priceId\" }, 400);\n\t\t\t\t\t}\n\n\t\t\t\t\tconst successUrl = typeof body.successUrl === \"string\" ? body.successUrl : undefined;\n\t\t\t\t\tconst cancelUrl = typeof body.cancelUrl === \"string\" ? body.cancelUrl : undefined;\n\t\t\t\t\tconst trialDays = typeof body.trialDays === \"number\" ? body.trialDays : undefined;\n\t\t\t\t\tconst metadata =\n\t\t\t\t\t\tbody.metadata != null &&\n\t\t\t\t\t\ttypeof body.metadata === \"object\" &&\n\t\t\t\t\t\t!Array.isArray(body.metadata)\n\t\t\t\t\t\t\t? (body.metadata as Record<string, string>)\n\t\t\t\t\t\t\t: undefined;\n\n\t\t\t\t\ttry {\n\t\t\t\t\t\tconst result = await module.createCheckoutSession(user.id, priceId, {\n\t\t\t\t\t\t\tsuccessUrl,\n\t\t\t\t\t\t\tcancelUrl,\n\t\t\t\t\t\t\ttrialDays,\n\t\t\t\t\t\t\tmetadata,\n\t\t\t\t\t\t});\n\t\t\t\t\t\treturn json(result);\n\t\t\t\t\t} catch (err) {\n\t\t\t\t\t\treturn json(\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\terror: err instanceof Error ? err.message : \"Failed to create checkout session\",\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t500,\n\t\t\t\t\t\t);\n\t\t\t\t\t}\n\t\t\t\t},\n\t\t\t});\n\n\t\t\t// POST /auth/stripe/portal\n\t\t\t// Creates a Stripe Billing Portal session for the authenticated user.\n\t\t\t// Body: { returnUrl: string }\n\t\t\tctx.addEndpoint({\n\t\t\t\tmethod: \"POST\",\n\t\t\t\tpath: \"/auth/stripe/portal\",\n\t\t\t\tmetadata: {\n\t\t\t\t\trequireAuth: true,\n\t\t\t\t\tdescription: \"Create a Stripe Billing Portal session for the authenticated user\",\n\t\t\t\t},\n\t\t\t\tasync handler(request, endpointCtx) {\n\t\t\t\t\tconst user = await endpointCtx.getUser(request);\n\t\t\t\t\tif (!user) {\n\t\t\t\t\t\treturn json({ error: \"Authentication required\" }, 401);\n\t\t\t\t\t}\n\n\t\t\t\t\tconst body = await parseBody(request);\n\t\t\t\t\tconst returnUrl = typeof body.returnUrl === \"string\" ? body.returnUrl.trim() : null;\n\t\t\t\t\tif (!returnUrl) {\n\t\t\t\t\t\treturn json({ error: \"Missing required field: returnUrl\" }, 400);\n\t\t\t\t\t}\n\n\t\t\t\t\ttry {\n\t\t\t\t\t\tconst result = await module.createPortalSession(user.id, returnUrl);\n\t\t\t\t\t\treturn json(result);\n\t\t\t\t\t} catch (err) {\n\t\t\t\t\t\treturn json(\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\terror: err instanceof Error ? err.message : \"Failed to create portal session\",\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t500,\n\t\t\t\t\t\t);\n\t\t\t\t\t}\n\t\t\t\t},\n\t\t\t});\n\n\t\t\t// GET /auth/stripe/subscription\n\t\t\t// Returns the current subscription status for the authenticated user.\n\t\t\tctx.addEndpoint({\n\t\t\t\tmethod: \"GET\",\n\t\t\t\tpath: \"/auth/stripe/subscription\",\n\t\t\t\tmetadata: {\n\t\t\t\t\trequireAuth: true,\n\t\t\t\t\tdescription: \"Get the current subscription status for the authenticated user\",\n\t\t\t\t},\n\t\t\t\tasync handler(request, endpointCtx) {\n\t\t\t\t\tconst user = await endpointCtx.getUser(request);\n\t\t\t\t\tif (!user) {\n\t\t\t\t\t\treturn json({ error: \"Authentication required\" }, 401);\n\t\t\t\t\t}\n\n\t\t\t\t\tconst subscription = await module.getSubscription(user.id);\n\t\t\t\t\treturn json({ subscription });\n\t\t\t\t},\n\t\t\t});\n\n\t\t\t// POST /auth/stripe/webhook\n\t\t\t// Receives Stripe webhook events. No session auth — verified by HMAC signature.\n\t\t\tctx.addEndpoint({\n\t\t\t\tmethod: \"POST\",\n\t\t\t\tpath: \"/auth/stripe/webhook\",\n\t\t\t\tmetadata: {\n\t\t\t\t\tdescription: \"Handle Stripe webhook events (HMAC-SHA256 signature verified)\",\n\t\t\t\t},\n\t\t\t\tasync handler(request) {\n\t\t\t\t\treturn module.handleWebhook(request);\n\t\t\t\t},\n\t\t\t});\n\t\t},\n\t};\n}\n","/**\n * TOTP two-factor authentication for KavachOS.\n *\n * Implements RFC 6238 (TOTP) and RFC 4226 (HOTP) from scratch using\n * node:crypto — no external dependencies.\n *\n * Flow:\n * 1. `setup(userId)` — generate secret + backup codes (not yet active)\n * 2. `enable(userId, code)` — verify the code, flip enabled = true\n * 3. `verify(userId, code)` — called on each login after password check\n * 4. `disable(userId, code)` — verify then delete the record\n */\n\nimport { createHash, createHmac, randomBytes } from \"node:crypto\";\nimport { eq } from \"drizzle-orm\";\nimport type { Database } from \"../db/database.js\";\nimport { totpRecords } from \"../db/schema.js\";\n\n// ---------------------------------------------------------------------------\n// Public types\n// ---------------------------------------------------------------------------\n\nexport interface TotpConfig {\n\t/** App name shown in authenticator apps (default: \"KavachOS\") */\n\tappName?: string;\n\t/** TOTP period in seconds (default: 30) */\n\tperiod?: number;\n\t/** Number of backup codes to generate (default: 10) */\n\tbackupCodeCount?: number;\n\t/** Accept codes from adjacent time periods for clock drift (default: 1) */\n\twindow?: number;\n}\n\nexport interface TotpSetup {\n\t/** Base32-encoded secret for the authenticator app */\n\tsecret: string;\n\t/** otpauth:// URI for QR code generation */\n\turi: string;\n\t/** One-time backup codes (shown once, store hashed) */\n\tbackupCodes: string[];\n}\n\nexport interface TotpModule {\n\t/** Generate a new TOTP secret for a user (doesn't enable 2FA yet) */\n\tsetup: (userId: string) => Promise<TotpSetup>;\n\t/** Verify a TOTP code and enable 2FA for the user */\n\tenable: (userId: string, code: string) => Promise<{ enabled: boolean }>;\n\t/** Disable 2FA for a user */\n\tdisable: (userId: string, code: string) => Promise<{ disabled: boolean }>;\n\t/** Verify a TOTP code (for login) */\n\tverify: (userId: string, code: string) => Promise<{ valid: boolean; usedBackupCode?: boolean }>;\n\t/** Check if a user has 2FA enabled */\n\tisEnabled: (userId: string) => Promise<boolean>;\n\t/** Regenerate backup codes */\n\tregenerateBackupCodes: (userId: string, code: string) => Promise<{ backupCodes: string[] }>;\n\t/** Handle HTTP request */\n\thandleRequest: (request: Request) => Promise<Response | null>;\n}\n\n// ---------------------------------------------------------------------------\n// Internal types\n// ---------------------------------------------------------------------------\n\ninterface BackupCodeEntry {\n\thash: string;\n\tused: boolean;\n}\n\n// ---------------------------------------------------------------------------\n// Base32 helpers (RFC 4648)\n// ---------------------------------------------------------------------------\n\nconst BASE32_ALPHABET = \"ABCDEFGHIJKLMNOPQRSTUVWXYZ234567\";\n\nfunction base32Encode(bytes: Uint8Array): string {\n\tlet bits = 0;\n\tlet value = 0;\n\tlet output = \"\";\n\n\tfor (let i = 0; i < bytes.length; i++) {\n\t\tvalue = (value << 8) | (bytes[i] ?? 0);\n\t\tbits += 8;\n\n\t\twhile (bits >= 5) {\n\t\t\toutput += BASE32_ALPHABET[(value >>> (bits - 5)) & 31] ?? \"\";\n\t\t\tbits -= 5;\n\t\t}\n\t}\n\n\tif (bits > 0) {\n\t\toutput += BASE32_ALPHABET[(value << (5 - bits)) & 31] ?? \"\";\n\t}\n\n\treturn output;\n}\n\nfunction base32Decode(encoded: string): Uint8Array {\n\tconst str = encoded.toUpperCase().replace(/=+$/, \"\");\n\tlet bits = 0;\n\tlet value = 0;\n\tconst output: number[] = [];\n\n\tfor (let i = 0; i < str.length; i++) {\n\t\tconst ch = str[i] ?? \"\";\n\t\tconst idx = BASE32_ALPHABET.indexOf(ch);\n\t\tif (idx === -1) {\n\t\t\tthrow new Error(`Invalid base32 character: ${ch}`);\n\t\t}\n\t\tvalue = (value << 5) | idx;\n\t\tbits += 5;\n\n\t\tif (bits >= 8) {\n\t\t\toutput.push((value >>> (bits - 8)) & 255);\n\t\t\tbits -= 8;\n\t\t}\n\t}\n\n\treturn new Uint8Array(output);\n}\n\n// ---------------------------------------------------------------------------\n// TOTP core (RFC 6238 / RFC 4226)\n// ---------------------------------------------------------------------------\n\nfunction generateTotp(secret: Uint8Array, time: number, period: number): string {\n\tconst counter = Math.floor(time / period);\n\n\t// Convert counter to 8-byte big-endian buffer\n\tconst counterBuffer = new Uint8Array(8);\n\tlet remaining = counter;\n\tfor (let i = 7; i >= 0; i--) {\n\t\tcounterBuffer[i] = remaining & 0xff;\n\t\tremaining = Math.floor(remaining / 256);\n\t}\n\n\t// HMAC-SHA1(secret, counterBuffer)\n\tconst hmac = createHmac(\"sha1\", Buffer.from(secret));\n\thmac.update(Buffer.from(counterBuffer));\n\tconst digest = new Uint8Array(hmac.digest());\n\n\t// Dynamic truncation\n\tconst offset = (digest[19] ?? 0) & 0xf;\n\tconst code =\n\t\t((((digest[offset] ?? 0) & 0x7f) << 24) |\n\t\t\t(((digest[offset + 1] ?? 0) & 0xff) << 16) |\n\t\t\t(((digest[offset + 2] ?? 0) & 0xff) << 8) |\n\t\t\t((digest[offset + 3] ?? 0) & 0xff)) %\n\t\t1_000_000;\n\n\treturn code.toString().padStart(6, \"0\");\n}\n\nfunction verifyTotp(secret: Uint8Array, code: string, period: number, window: number): boolean {\n\tconst now = Math.floor(Date.now() / 1000);\n\n\tfor (let delta = -window; delta <= window; delta++) {\n\t\tconst expected = generateTotp(secret, now + delta * period, period);\n\t\tif (expected === code) return true;\n\t}\n\n\treturn false;\n}\n\n// ---------------------------------------------------------------------------\n// Secret generation\n// ---------------------------------------------------------------------------\n\nfunction generateSecret(): string {\n\tconst bytes = randomBytes(20);\n\treturn base32Encode(new Uint8Array(bytes));\n}\n\n// ---------------------------------------------------------------------------\n// Backup codes\n// ---------------------------------------------------------------------------\n\nconst BACKUP_CODE_CHARS = \"ABCDEFGHJKLMNPQRSTUVWXYZ23456789\"; // no 0/O/1/I confusion\n\nfunction generateBackupCode(): string {\n\tconst bytes = randomBytes(8);\n\tlet code = \"\";\n\tfor (let i = 0; i < 8; i++) {\n\t\tconst byte = bytes[i] ?? 0;\n\t\tcode += BACKUP_CODE_CHARS[byte % BACKUP_CODE_CHARS.length] ?? \"A\";\n\t}\n\treturn code;\n}\n\nfunction hashBackupCode(code: string): string {\n\treturn createHash(\"sha256\").update(code).digest(\"hex\");\n}\n\nfunction generateBackupCodes(count: number): { plain: string[]; hashed: BackupCodeEntry[] } {\n\tconst plain: string[] = [];\n\tconst hashed: BackupCodeEntry[] = [];\n\n\tfor (let i = 0; i < count; i++) {\n\t\tconst code = generateBackupCode();\n\t\tplain.push(code);\n\t\thashed.push({ hash: hashBackupCode(code), used: false });\n\t}\n\n\treturn { plain, hashed };\n}\n\n// ---------------------------------------------------------------------------\n// HTTP helpers\n// ---------------------------------------------------------------------------\n\nfunction jsonResponse(body: unknown, status = 200): Response {\n\treturn new Response(JSON.stringify(body), {\n\t\tstatus,\n\t\theaders: { \"Content-Type\": \"application/json\" },\n\t});\n}\n\nasync function parseBody(request: Request): Promise<Record<string, unknown>> {\n\ttry {\n\t\treturn (await request.json()) as Record<string, unknown>;\n\t} catch {\n\t\treturn {};\n\t}\n}\n\n// ---------------------------------------------------------------------------\n// Module factory\n// ---------------------------------------------------------------------------\n\nexport function createTotpModule(config: TotpConfig, db: Database): TotpModule {\n\tconst appName = config.appName ?? \"KavachOS\";\n\tconst period = config.period ?? 30;\n\tconst backupCodeCount = config.backupCodeCount ?? 10;\n\tconst window = config.window ?? 1;\n\n\t// ── setup ────────────────────────────────────────────────────────────────\n\n\tasync function setup(userId: string): Promise<TotpSetup> {\n\t\tconst secretStr = generateSecret();\n\t\tconst { plain, hashed } = generateBackupCodes(backupCodeCount);\n\n\t\tconst uri = `otpauth://totp/${encodeURIComponent(appName)}:${encodeURIComponent(userId)}?secret=${secretStr}&issuer=${encodeURIComponent(appName)}&algorithm=SHA1&digits=6&period=${period}`;\n\n\t\tconst now = new Date();\n\n\t\t// Upsert: replace any existing (pending) record for this user\n\t\tconst existing = await db.select().from(totpRecords).where(eq(totpRecords.userId, userId));\n\n\t\tif (existing.length > 0) {\n\t\t\tawait db\n\t\t\t\t.update(totpRecords)\n\t\t\t\t.set({\n\t\t\t\t\tsecret: secretStr,\n\t\t\t\t\tenabled: false,\n\t\t\t\t\tbackupCodes: hashed,\n\t\t\t\t\tupdatedAt: now,\n\t\t\t\t})\n\t\t\t\t.where(eq(totpRecords.userId, userId));\n\t\t} else {\n\t\t\tawait db.insert(totpRecords).values({\n\t\t\t\tuserId,\n\t\t\t\tsecret: secretStr,\n\t\t\t\tenabled: false,\n\t\t\t\tbackupCodes: hashed,\n\t\t\t\tcreatedAt: now,\n\t\t\t\tupdatedAt: now,\n\t\t\t});\n\t\t}\n\n\t\treturn { secret: secretStr, uri, backupCodes: plain };\n\t}\n\n\t// ── enable ───────────────────────────────────────────────────────────────\n\n\tasync function enable(userId: string, code: string): Promise<{ enabled: boolean }> {\n\t\tconst rows = await db.select().from(totpRecords).where(eq(totpRecords.userId, userId));\n\n\t\tconst record = rows[0];\n\t\tif (!record) {\n\t\t\treturn { enabled: false };\n\t\t}\n\n\t\tconst secretBytes = base32Decode(record.secret);\n\t\tconst valid = verifyTotp(secretBytes, code, period, window);\n\n\t\tif (!valid) {\n\t\t\treturn { enabled: false };\n\t\t}\n\n\t\tawait db\n\t\t\t.update(totpRecords)\n\t\t\t.set({ enabled: true, updatedAt: new Date() })\n\t\t\t.where(eq(totpRecords.userId, userId));\n\n\t\treturn { enabled: true };\n\t}\n\n\t// ── verify ───────────────────────────────────────────────────────────────\n\n\tasync function verify(\n\t\tuserId: string,\n\t\tcode: string,\n\t): Promise<{ valid: boolean; usedBackupCode?: boolean }> {\n\t\tconst rows = await db.select().from(totpRecords).where(eq(totpRecords.userId, userId));\n\n\t\tconst record = rows[0];\n\t\tif (!record || !record.enabled) {\n\t\t\treturn { valid: false };\n\t\t}\n\n\t\t// Try TOTP first\n\t\tconst secretBytes = base32Decode(record.secret);\n\t\tif (verifyTotp(secretBytes, code, period, window)) {\n\t\t\treturn { valid: true };\n\t\t}\n\n\t\t// Try backup codes\n\t\tconst codeHash = hashBackupCode(code.toUpperCase());\n\t\tconst backupCodes = record.backupCodes as BackupCodeEntry[];\n\t\tconst matchIndex = backupCodes.findIndex((b) => b.hash === codeHash && !b.used);\n\n\t\tif (matchIndex === -1) {\n\t\t\treturn { valid: false };\n\t\t}\n\n\t\t// Mark the backup code as used\n\t\tconst updated = backupCodes.map((b, i) => (i === matchIndex ? { ...b, used: true } : b));\n\n\t\tawait db\n\t\t\t.update(totpRecords)\n\t\t\t.set({ backupCodes: updated, updatedAt: new Date() })\n\t\t\t.where(eq(totpRecords.userId, userId));\n\n\t\treturn { valid: true, usedBackupCode: true };\n\t}\n\n\t// ── disable ──────────────────────────────────────────────────────────────\n\n\tasync function disable(userId: string, code: string): Promise<{ disabled: boolean }> {\n\t\tconst result = await verify(userId, code);\n\t\tif (!result.valid) {\n\t\t\treturn { disabled: false };\n\t\t}\n\n\t\tawait db.delete(totpRecords).where(eq(totpRecords.userId, userId));\n\t\treturn { disabled: true };\n\t}\n\n\t// ── isEnabled ────────────────────────────────────────────────────────────\n\n\tasync function isEnabled(userId: string): Promise<boolean> {\n\t\tconst rows = await db\n\t\t\t.select({ enabled: totpRecords.enabled })\n\t\t\t.from(totpRecords)\n\t\t\t.where(eq(totpRecords.userId, userId));\n\n\t\treturn rows[0]?.enabled === true;\n\t}\n\n\t// ── regenerateBackupCodes ────────────────────────────────────────────────\n\n\tasync function regenerateBackupCodes(\n\t\tuserId: string,\n\t\tcode: string,\n\t): Promise<{ backupCodes: string[] }> {\n\t\tconst result = await verify(userId, code);\n\t\tif (!result.valid) {\n\t\t\tthrow new Error(\"Invalid TOTP code — cannot regenerate backup codes\");\n\t\t}\n\n\t\tconst { plain, hashed } = generateBackupCodes(backupCodeCount);\n\n\t\tawait db\n\t\t\t.update(totpRecords)\n\t\t\t.set({ backupCodes: hashed, updatedAt: new Date() })\n\t\t\t.where(eq(totpRecords.userId, userId));\n\n\t\treturn { backupCodes: plain };\n\t}\n\n\t// ── handleRequest ────────────────────────────────────────────────────────\n\n\tasync function handleRequest(request: Request): Promise<Response | null> {\n\t\tconst url = new URL(request.url);\n\t\tconst path = url.pathname;\n\t\tconst method = request.method.toUpperCase();\n\n\t\tif (method !== \"POST\") return null;\n\n\t\tif (path === \"/auth/2fa/setup\") {\n\t\t\tconst body = await parseBody(request);\n\t\t\tconst userId = typeof body.userId === \"string\" ? body.userId : null;\n\t\t\tif (!userId) return jsonResponse({ error: \"userId required\" }, 400);\n\n\t\t\ttry {\n\t\t\t\tconst result = await setup(userId);\n\t\t\t\treturn jsonResponse(result);\n\t\t\t} catch (err) {\n\t\t\t\treturn jsonResponse({ error: err instanceof Error ? err.message : \"Setup failed\" }, 500);\n\t\t\t}\n\t\t}\n\n\t\tif (path === \"/auth/2fa/enable\") {\n\t\t\tconst body = await parseBody(request);\n\t\t\tconst userId = typeof body.userId === \"string\" ? body.userId : null;\n\t\t\tconst code = typeof body.code === \"string\" ? body.code : null;\n\t\t\tif (!userId || !code) return jsonResponse({ error: \"userId and code required\" }, 400);\n\n\t\t\tconst result = await enable(userId, code);\n\t\t\treturn jsonResponse(result);\n\t\t}\n\n\t\tif (path === \"/auth/2fa/verify\") {\n\t\t\tconst body = await parseBody(request);\n\t\t\tconst userId = typeof body.userId === \"string\" ? body.userId : null;\n\t\t\tconst code = typeof body.code === \"string\" ? body.code : null;\n\t\t\tif (!userId || !code) return jsonResponse({ error: \"userId and code required\" }, 400);\n\n\t\t\tconst result = await verify(userId, code);\n\t\t\treturn jsonResponse(result);\n\t\t}\n\n\t\tif (path === \"/auth/2fa/disable\") {\n\t\t\tconst body = await parseBody(request);\n\t\t\tconst userId = typeof body.userId === \"string\" ? body.userId : null;\n\t\t\tconst code = typeof body.code === \"string\" ? body.code : null;\n\t\t\tif (!userId || !code) return jsonResponse({ error: \"userId and code required\" }, 400);\n\n\t\t\tconst result = await disable(userId, code);\n\t\t\treturn jsonResponse(result);\n\t\t}\n\n\t\tif (path === \"/auth/2fa/backup-codes\") {\n\t\t\tconst body = await parseBody(request);\n\t\t\tconst userId = typeof body.userId === \"string\" ? body.userId : null;\n\t\t\tconst code = typeof body.code === \"string\" ? body.code : null;\n\t\t\tif (!userId || !code) return jsonResponse({ error: \"userId and code required\" }, 400);\n\n\t\t\ttry {\n\t\t\t\tconst result = await regenerateBackupCodes(userId, code);\n\t\t\t\treturn jsonResponse(result);\n\t\t\t} catch (err) {\n\t\t\t\treturn jsonResponse(\n\t\t\t\t\t{ error: err instanceof Error ? err.message : \"Failed to regenerate codes\" },\n\t\t\t\t\t400,\n\t\t\t\t);\n\t\t\t}\n\t\t}\n\n\t\treturn null;\n\t}\n\n\treturn {\n\t\tsetup,\n\t\tenable,\n\t\tdisable,\n\t\tverify,\n\t\tisEnabled,\n\t\tregenerateBackupCodes,\n\t\thandleRequest,\n\t};\n}\n","import type { KavachPlugin } from \"../plugin/types.js\";\nimport type { TotpConfig } from \"./totp.js\";\nimport { createTotpModule } from \"./totp.js\";\n\n// ---------------------------------------------------------------------------\n// Config\n// ---------------------------------------------------------------------------\n\nexport type TwoFactorConfig = TotpConfig;\n\n// ---------------------------------------------------------------------------\n// Helpers\n// ---------------------------------------------------------------------------\n\nfunction jsonResponse(body: unknown, status = 200): Response {\n\treturn new Response(JSON.stringify(body), {\n\t\tstatus,\n\t\theaders: { \"Content-Type\": \"application/json\" },\n\t});\n}\n\nasync function parseBody(request: Request): Promise<Record<string, unknown>> {\n\ttry {\n\t\treturn (await request.json()) as Record<string, unknown>;\n\t} catch {\n\t\treturn {};\n\t}\n}\n\n// ---------------------------------------------------------------------------\n// Plugin factory\n// ---------------------------------------------------------------------------\n\nexport function twoFactor(config?: TwoFactorConfig): KavachPlugin {\n\treturn {\n\t\tid: \"kavach-2fa\",\n\n\t\tasync init(ctx): Promise<undefined> {\n\t\t\tconst module = createTotpModule(config ?? {}, ctx.db);\n\n\t\t\t// POST /auth/2fa/enroll\n\t\t\t// Generates a TOTP secret and QR code URI for the authenticated user.\n\t\t\t// The user must call /auth/2fa/verify to activate 2FA after scanning.\n\t\t\tctx.addEndpoint({\n\t\t\t\tmethod: \"POST\",\n\t\t\t\tpath: \"/auth/2fa/enroll\",\n\t\t\t\tmetadata: {\n\t\t\t\t\trequireAuth: true,\n\t\t\t\t\tdescription: \"Generate a TOTP secret and QR code URI for enrollment\",\n\t\t\t\t},\n\t\t\t\tasync handler(request, endpointCtx) {\n\t\t\t\t\tconst user = await endpointCtx.getUser(request);\n\t\t\t\t\tif (!user) {\n\t\t\t\t\t\treturn jsonResponse({ error: \"Authentication required\" }, 401);\n\t\t\t\t\t}\n\n\t\t\t\t\ttry {\n\t\t\t\t\t\tconst setup = await module.setup(user.id);\n\t\t\t\t\t\treturn jsonResponse(setup);\n\t\t\t\t\t} catch (err) {\n\t\t\t\t\t\treturn jsonResponse(\n\t\t\t\t\t\t\t{ error: err instanceof Error ? err.message : \"Enrollment failed\" },\n\t\t\t\t\t\t\t500,\n\t\t\t\t\t\t);\n\t\t\t\t\t}\n\t\t\t\t},\n\t\t\t});\n\n\t\t\t// POST /auth/2fa/verify\n\t\t\t// Verifies a TOTP code. Activates 2FA on first use after enroll\n\t\t\t// (calls enable internally when not yet enabled), or validates during login.\n\t\t\tctx.addEndpoint({\n\t\t\t\tmethod: \"POST\",\n\t\t\t\tpath: \"/auth/2fa/verify\",\n\t\t\t\tmetadata: {\n\t\t\t\t\trequireAuth: true,\n\t\t\t\t\tdescription: \"Verify a TOTP code and enable 2FA if not yet active\",\n\t\t\t\t},\n\t\t\t\tasync handler(request, endpointCtx) {\n\t\t\t\t\tconst user = await endpointCtx.getUser(request);\n\t\t\t\t\tif (!user) {\n\t\t\t\t\t\treturn jsonResponse({ error: \"Authentication required\" }, 401);\n\t\t\t\t\t}\n\n\t\t\t\t\tconst body = await parseBody(request);\n\t\t\t\t\tconst code = typeof body.code === \"string\" ? body.code : null;\n\n\t\t\t\t\tif (!code) {\n\t\t\t\t\t\treturn jsonResponse({ error: \"Missing required field: code\" }, 400);\n\t\t\t\t\t}\n\n\t\t\t\t\t// If 2FA is not yet enabled, treat this verify call as the\n\t\t\t\t\t// confirmation step that activates it (post-enrollment flow).\n\t\t\t\t\tconst enabled = await module.isEnabled(user.id);\n\t\t\t\t\tif (!enabled) {\n\t\t\t\t\t\tconst result = await module.enable(user.id, code);\n\t\t\t\t\t\tif (!result.enabled) {\n\t\t\t\t\t\t\treturn jsonResponse({ error: \"Invalid TOTP code\" }, 400);\n\t\t\t\t\t\t}\n\t\t\t\t\t\treturn jsonResponse({ valid: true, activated: true });\n\t\t\t\t\t}\n\n\t\t\t\t\tconst result = await module.verify(user.id, code);\n\t\t\t\t\treturn jsonResponse(result);\n\t\t\t\t},\n\t\t\t});\n\n\t\t\t// POST /auth/2fa/disable\n\t\t\t// Disables 2FA. Requires a valid TOTP code or backup code as confirmation.\n\t\t\tctx.addEndpoint({\n\t\t\t\tmethod: \"POST\",\n\t\t\t\tpath: \"/auth/2fa/disable\",\n\t\t\t\tmetadata: {\n\t\t\t\t\trequireAuth: true,\n\t\t\t\t\tdescription: \"Disable 2FA — requires a valid TOTP or backup code\",\n\t\t\t\t},\n\t\t\t\tasync handler(request, endpointCtx) {\n\t\t\t\t\tconst user = await endpointCtx.getUser(request);\n\t\t\t\t\tif (!user) {\n\t\t\t\t\t\treturn jsonResponse({ error: \"Authentication required\" }, 401);\n\t\t\t\t\t}\n\n\t\t\t\t\tconst body = await parseBody(request);\n\t\t\t\t\tconst code = typeof body.code === \"string\" ? body.code : null;\n\n\t\t\t\t\tif (!code) {\n\t\t\t\t\t\treturn jsonResponse({ error: \"Missing required field: code\" }, 400);\n\t\t\t\t\t}\n\n\t\t\t\t\tconst result = await module.disable(user.id, code);\n\t\t\t\t\tif (!result.disabled) {\n\t\t\t\t\t\treturn jsonResponse({ error: \"Invalid TOTP code\" }, 400);\n\t\t\t\t\t}\n\n\t\t\t\t\treturn jsonResponse(result);\n\t\t\t\t},\n\t\t\t});\n\n\t\t\t// GET /auth/2fa/status\n\t\t\t// Returns whether 2FA is enabled for the authenticated user.\n\t\t\tctx.addEndpoint({\n\t\t\t\tmethod: \"GET\",\n\t\t\t\tpath: \"/auth/2fa/status\",\n\t\t\t\tmetadata: {\n\t\t\t\t\trequireAuth: true,\n\t\t\t\t\tdescription: \"Return whether 2FA is enabled for the authenticated user\",\n\t\t\t\t},\n\t\t\t\tasync handler(request, endpointCtx) {\n\t\t\t\t\tconst user = await endpointCtx.getUser(request);\n\t\t\t\t\tif (!user) {\n\t\t\t\t\t\treturn jsonResponse({ error: \"Authentication required\" }, 401);\n\t\t\t\t\t}\n\n\t\t\t\t\tconst enabled = await module.isEnabled(user.id);\n\t\t\t\t\treturn jsonResponse({ enabled });\n\t\t\t\t},\n\t\t\t});\n\n\t\t\t// POST /auth/2fa/backup-codes\n\t\t\t// Regenerates backup codes. Requires a valid TOTP code as confirmation.\n\t\t\tctx.addEndpoint({\n\t\t\t\tmethod: \"POST\",\n\t\t\t\tpath: \"/auth/2fa/backup-codes\",\n\t\t\t\tmetadata: {\n\t\t\t\t\trequireAuth: true,\n\t\t\t\t\tdescription: \"Regenerate backup codes — requires a valid TOTP code\",\n\t\t\t\t},\n\t\t\t\tasync handler(request, endpointCtx) {\n\t\t\t\t\tconst user = await endpointCtx.getUser(request);\n\t\t\t\t\tif (!user) {\n\t\t\t\t\t\treturn jsonResponse({ error: \"Authentication required\" }, 401);\n\t\t\t\t\t}\n\n\t\t\t\t\tconst body = await parseBody(request);\n\t\t\t\t\tconst code = typeof body.code === \"string\" ? body.code : null;\n\n\t\t\t\t\tif (!code) {\n\t\t\t\t\t\treturn jsonResponse({ error: \"Missing required field: code\" }, 400);\n\t\t\t\t\t}\n\n\t\t\t\t\ttry {\n\t\t\t\t\t\tconst result = await module.regenerateBackupCodes(user.id, code);\n\t\t\t\t\t\treturn jsonResponse(result);\n\t\t\t\t\t} catch (err) {\n\t\t\t\t\t\treturn jsonResponse(\n\t\t\t\t\t\t\t{ error: err instanceof Error ? err.message : \"Failed to regenerate backup codes\" },\n\t\t\t\t\t\t\t400,\n\t\t\t\t\t\t);\n\t\t\t\t\t}\n\t\t\t\t},\n\t\t\t});\n\t\t},\n\t};\n}\n","/**\n * Trusted device windows for 2FA in KavachOS.\n *\n * After a successful 2FA challenge, a device can be marked as trusted.\n * Subsequent logins from the same device skip 2FA until the trust window\n * expires (default 30 days) or trust is explicitly revoked.\n *\n * Fingerprints are HMAC-signed to prevent client-side spoofing.\n */\n\nimport { createHmac, randomBytes } from \"node:crypto\";\nimport { and, asc, eq, gt } from \"drizzle-orm\";\nimport type { Database } from \"../db/database.js\";\nimport { trustedDevices } from \"../db/schema.js\";\n\n// ---------------------------------------------------------------------------\n// Public types\n// ---------------------------------------------------------------------------\n\nexport interface TrustedDeviceConfig {\n\t/** How long to trust a device in seconds (default: 30 days). */\n\ttrustDurationSeconds?: number;\n\t/** Maximum number of trusted devices per user (default: 10). */\n\tmaxDevices?: number;\n\t/**\n\t * Secret used to HMAC-sign fingerprints, preventing client spoofing.\n\t * Should be a stable application secret (e.g. from env). If omitted a\n\t * random per-process key is used (fingerprints won't survive restarts).\n\t */\n\tsecret?: string;\n}\n\nexport interface TrustedDevice {\n\tid: string;\n\tfingerprint: string;\n\tlabel: string;\n\ttrustedAt: Date;\n\texpiresAt: Date;\n}\n\nexport interface TrustedDeviceModule {\n\t/**\n\t * Mark the device identified by `deviceFingerprint` as trusted for\n\t * `userId`. Returns a stable trust token (the record id) that can be\n\t * stored in a long-lived cookie.\n\t */\n\ttrustDevice(userId: string, deviceFingerprint: string): Promise<string>;\n\t/** Returns true if the device is currently trusted (not expired). */\n\tisTrusted(userId: string, deviceFingerprint: string): Promise<boolean>;\n\t/** Remove trust for a single device. */\n\trevokeDevice(userId: string, deviceFingerprint: string): Promise<void>;\n\t/** Remove trust for every device belonging to a user. */\n\trevokeAllDevices(userId: string): Promise<void>;\n\t/** List all active trusted devices for a user. */\n\tlistDevices(userId: string): Promise<TrustedDevice[]>;\n\t/**\n\t * Derive a stable, HMAC-protected fingerprint from request headers.\n\t * The same request will always produce the same fingerprint; changing\n\t * user-agent or accept-language invalidates the fingerprint.\n\t */\n\tgenerateFingerprint(request: Request): string;\n}\n\n// ---------------------------------------------------------------------------\n// Helpers\n// ---------------------------------------------------------------------------\n\nconst DEFAULT_TRUST_DURATION = 30 * 24 * 60 * 60; // 30 days in seconds\nconst DEFAULT_MAX_DEVICES = 10;\n\n/** Extract a human-readable label from a User-Agent string. */\nfunction labelFromUserAgent(ua: string): string {\n\tif (!ua) return \"Unknown device\";\n\n\t// Mobile OS\n\tif (/iPhone/.test(ua)) return \"iPhone\";\n\tif (/iPad/.test(ua)) return \"iPad\";\n\tif (/Android/.test(ua)) {\n\t\treturn /Mobile/.test(ua) ? \"Android phone\" : \"Android tablet\";\n\t}\n\n\t// Desktop OS\n\tif (/Windows NT/.test(ua)) return \"Windows\";\n\tif (/Macintosh/.test(ua)) return \"Mac\";\n\tif (/Linux/.test(ua)) return \"Linux\";\n\n\treturn \"Unknown device\";\n}\n\n/** Generate a URL-safe random id. */\nfunction generateId(): string {\n\treturn randomBytes(16).toString(\"hex\");\n}\n\n// ---------------------------------------------------------------------------\n// Module factory\n// ---------------------------------------------------------------------------\n\nexport function createTrustedDeviceModule(\n\tconfig: TrustedDeviceConfig,\n\tdb: Database,\n): TrustedDeviceModule {\n\tconst trustDurationSeconds = config.trustDurationSeconds ?? DEFAULT_TRUST_DURATION;\n\tconst maxDevices = config.maxDevices ?? DEFAULT_MAX_DEVICES;\n\t// Per-process fallback key so the module works without explicit config,\n\t// but fingerprints will differ across restarts (safe degradation).\n\tconst hmacSecret = config.secret ?? randomBytes(32).toString(\"hex\");\n\n\t// ── generateFingerprint ────────────────────────────────────────────────\n\n\tfunction generateFingerprint(request: Request): string {\n\t\tconst ua = request.headers.get(\"user-agent\") ?? \"\";\n\t\tconst lang = request.headers.get(\"accept-language\") ?? \"\";\n\t\tconst encoding = request.headers.get(\"accept-encoding\") ?? \"\";\n\t\tconst accept = request.headers.get(\"accept\") ?? \"\";\n\n\t\tconst payload = [ua, lang, encoding, accept].join(\"|\");\n\n\t\treturn createHmac(\"sha256\", hmacSecret).update(payload, \"utf8\").digest(\"hex\");\n\t}\n\n\t// ── trustDevice ───────────────────────────────────────────────────────\n\n\tasync function trustDevice(userId: string, deviceFingerprint: string): Promise<string> {\n\t\tconst now = new Date();\n\t\tconst expiresAt = new Date(now.getTime() + trustDurationSeconds * 1000);\n\n\t\t// Get existing devices for this user, oldest first\n\t\tconst existing = await db\n\t\t\t.select()\n\t\t\t.from(trustedDevices)\n\t\t\t.where(eq(trustedDevices.userId, userId))\n\t\t\t.orderBy(asc(trustedDevices.trustedAt));\n\n\t\t// Check if this fingerprint already has a record — refresh it\n\t\tconst existingRecord = existing.find((d) => d.fingerprint === deviceFingerprint);\n\t\tif (existingRecord) {\n\t\t\tawait db\n\t\t\t\t.update(trustedDevices)\n\t\t\t\t.set({ expiresAt, trustedAt: now })\n\t\t\t\t.where(eq(trustedDevices.id, existingRecord.id));\n\t\t\treturn existingRecord.id;\n\t\t}\n\n\t\t// Evict oldest devices when at capacity\n\t\tif (existing.length >= maxDevices) {\n\t\t\tconst toEvict = existing.slice(0, existing.length - maxDevices + 1);\n\t\t\tfor (const device of toEvict) {\n\t\t\t\tawait db.delete(trustedDevices).where(eq(trustedDevices.id, device.id));\n\t\t\t}\n\t\t}\n\n\t\t// Derive a user-agent label from the fingerprint's source material by\n\t\t// reconstructing it — we store the label separately at trust time.\n\t\t// Since we only have the fingerprint here, we store a generic label.\n\t\t// Callers who want a specific label should use a separate overload.\n\t\tconst id = generateId();\n\n\t\tawait db.insert(trustedDevices).values({\n\t\t\tid,\n\t\t\tuserId,\n\t\t\tfingerprint: deviceFingerprint,\n\t\t\tlabel: \"Trusted device\",\n\t\t\ttrustedAt: now,\n\t\t\texpiresAt,\n\t\t});\n\n\t\treturn id;\n\t}\n\n\t// ── isTrusted ─────────────────────────────────────────────────────────\n\n\tasync function isTrusted(userId: string, deviceFingerprint: string): Promise<boolean> {\n\t\tconst now = new Date();\n\n\t\tconst rows = await db\n\t\t\t.select({ id: trustedDevices.id })\n\t\t\t.from(trustedDevices)\n\t\t\t.where(\n\t\t\t\tand(\n\t\t\t\t\teq(trustedDevices.userId, userId),\n\t\t\t\t\teq(trustedDevices.fingerprint, deviceFingerprint),\n\t\t\t\t\tgt(trustedDevices.expiresAt, now),\n\t\t\t\t),\n\t\t\t);\n\n\t\treturn rows.length > 0;\n\t}\n\n\t// ── revokeDevice ──────────────────────────────────────────────────────\n\n\tasync function revokeDevice(userId: string, deviceFingerprint: string): Promise<void> {\n\t\tawait db\n\t\t\t.delete(trustedDevices)\n\t\t\t.where(\n\t\t\t\tand(eq(trustedDevices.userId, userId), eq(trustedDevices.fingerprint, deviceFingerprint)),\n\t\t\t);\n\t}\n\n\t// ── revokeAllDevices ──────────────────────────────────────────────────\n\n\tasync function revokeAllDevices(userId: string): Promise<void> {\n\t\tawait db.delete(trustedDevices).where(eq(trustedDevices.userId, userId));\n\t}\n\n\t// ── listDevices ───────────────────────────────────────────────────────\n\n\tasync function listDevices(userId: string): Promise<TrustedDevice[]> {\n\t\tconst now = new Date();\n\n\t\tconst rows = await db\n\t\t\t.select()\n\t\t\t.from(trustedDevices)\n\t\t\t.where(and(eq(trustedDevices.userId, userId), gt(trustedDevices.expiresAt, now)));\n\n\t\treturn rows.map((row) => ({\n\t\t\tid: row.id,\n\t\t\tfingerprint: row.fingerprint,\n\t\t\tlabel: row.label,\n\t\t\ttrustedAt: row.trustedAt,\n\t\t\texpiresAt: row.expiresAt,\n\t\t}));\n\t}\n\n\treturn {\n\t\ttrustDevice,\n\t\tisTrusted,\n\t\trevokeDevice,\n\t\trevokeAllDevices,\n\t\tlistDevices,\n\t\tgenerateFingerprint,\n\t};\n}\n\n// ---------------------------------------------------------------------------\n// Label helper — exported so adapters can pass a request to produce a label\n// ---------------------------------------------------------------------------\n\n/**\n * Derive a human-readable device label from a request's User-Agent header.\n * Useful when calling `trustDevice` so the stored label is descriptive.\n */\nexport function deviceLabelFromRequest(request: Request): string {\n\tconst ua = request.headers.get(\"user-agent\") ?? \"\";\n\treturn labelFromUserAgent(ua);\n}\n\n// Keep the internal helper available for tests without re-exporting\nexport { labelFromUserAgent as _labelFromUserAgent };\n","/**\n * Username + password authentication for KavachOS.\n *\n * Users register with a username and password instead of email. Usernames are\n * normalised to lowercase by default. Passwords are hashed with scrypt before\n * storage so a database breach does not expose credentials.\n *\n * @example\n * ```typescript\n * const kavach = await createKavach({\n * database: { provider: 'sqlite', url: 'kavach.db' },\n * auth: { session: { secret: process.env.SESSION_SECRET } },\n * username: {\n * password: { minLength: 8 },\n * },\n * });\n *\n * const response = await kavach.username?.handleRequest(request);\n * if (response) return response;\n * ```\n */\n\nimport { createHash, randomUUID, scryptSync, timingSafeEqual } from \"node:crypto\";\nimport { and, eq } from \"drizzle-orm\";\nimport type { Database } from \"../db/database.js\";\nimport { usernameAccounts, users } from \"../db/schema.js\";\nimport type { SessionManager } from \"../session/session.js\";\n\n// ---------------------------------------------------------------------------\n// Public types\n// ---------------------------------------------------------------------------\n\nexport interface UsernameAuthConfig {\n\t/** Minimum username length (default: 3) */\n\tminUsernameLength?: number;\n\t/** Maximum username length (default: 32) */\n\tmaxUsernameLength?: number;\n\t/** Allowed characters pattern (default: /^[a-zA-Z0-9_-]+$/) */\n\tallowedPattern?: RegExp;\n\t/** Whether usernames are case-sensitive (default: false — normalise to lowercase) */\n\tcaseSensitive?: boolean;\n\tpassword?: {\n\t\t/** Minimum password length (default: 8) */\n\t\tminLength?: number;\n\t\t/** Maximum password length (default: 128) */\n\t\tmaxLength?: number;\n\t};\n}\n\nexport interface UsernameAuthModule {\n\tsignUp: (input: { username: string; password: string; name?: string }) => Promise<{\n\t\tuser: { id: string; username: string; name: string | null };\n\t\tsession: { token: string; expiresAt: Date };\n\t}>;\n\tsignIn: (input: { username: string; password: string }) => Promise<{\n\t\tuser: { id: string; username: string };\n\t\tsession: { token: string; expiresAt: Date };\n\t}>;\n\tchangePassword: (\n\t\tuserId: string,\n\t\tcurrent: string,\n\t\tnewPassword: string,\n\t) => Promise<{ success: boolean }>;\n\tchangeUsername: (userId: string, newUsername: string) => Promise<{ success: boolean }>;\n\thandleRequest: (request: Request) => Promise<Response | null>;\n}\n\n// ---------------------------------------------------------------------------\n// Defaults\n// ---------------------------------------------------------------------------\n\nconst DEFAULT_MIN_USERNAME = 3;\nconst DEFAULT_MAX_USERNAME = 32;\nconst DEFAULT_ALLOWED_PATTERN = /^[a-zA-Z0-9_-]+$/;\nconst DEFAULT_MIN_PASSWORD = 8;\nconst DEFAULT_MAX_PASSWORD = 128;\nconst SCRYPT_KEYLEN = 64;\nconst SCRYPT_PARAMS = { N: 16384, r: 8, p: 1 };\n\n// ---------------------------------------------------------------------------\n// Helpers\n// ---------------------------------------------------------------------------\n\nfunction saltedHash(salt: string, password: string): Uint8Array {\n\treturn scryptSync(password, salt, SCRYPT_KEYLEN, SCRYPT_PARAMS);\n}\n\nfunction hashPassword(password: string): string {\n\tconst salt = createHash(\"sha256\").update(randomUUID()).digest(\"hex\").slice(0, 32);\n\tconst derived = saltedHash(salt, password);\n\treturn `${salt}:${Buffer.from(derived).toString(\"hex\")}`;\n}\n\nfunction verifyPassword(stored: string, candidate: string): boolean {\n\tconst colonIdx = stored.indexOf(\":\");\n\tif (colonIdx === -1) return false;\n\tconst salt = stored.slice(0, colonIdx);\n\tconst storedHash = stored.slice(colonIdx + 1);\n\tconst candidateHash = saltedHash(salt, candidate);\n\tconst storedBuf = Buffer.from(storedHash, \"hex\");\n\tif (candidateHash.byteLength !== storedBuf.byteLength) return false;\n\treturn timingSafeEqual(candidateHash, storedBuf);\n}\n\nfunction jsonResponse(body: unknown, status = 200): Response {\n\treturn new Response(JSON.stringify(body), {\n\t\tstatus,\n\t\theaders: { \"Content-Type\": \"application/json\" },\n\t});\n}\n\n// ---------------------------------------------------------------------------\n// Factory\n// ---------------------------------------------------------------------------\n\nexport function createUsernameAuthModule(\n\tconfig: UsernameAuthConfig,\n\tdb: Database,\n\tsessionManager: SessionManager,\n): UsernameAuthModule {\n\tconst minUsernameLen = config.minUsernameLength ?? DEFAULT_MIN_USERNAME;\n\tconst maxUsernameLen = config.maxUsernameLength ?? DEFAULT_MAX_USERNAME;\n\tconst allowedPattern = config.allowedPattern ?? DEFAULT_ALLOWED_PATTERN;\n\tconst caseSensitive = config.caseSensitive ?? false;\n\tconst minPasswordLen = config.password?.minLength ?? DEFAULT_MIN_PASSWORD;\n\tconst maxPasswordLen = config.password?.maxLength ?? DEFAULT_MAX_PASSWORD;\n\n\tfunction normalise(username: string): string {\n\t\treturn caseSensitive ? username : username.toLowerCase();\n\t}\n\n\tfunction validateUsername(username: string): string | null {\n\t\tif (username.length < minUsernameLen) {\n\t\t\treturn `Username must be at least ${minUsernameLen} characters`;\n\t\t}\n\t\tif (username.length > maxUsernameLen) {\n\t\t\treturn `Username must be at most ${maxUsernameLen} characters`;\n\t\t}\n\t\tif (!allowedPattern.test(username)) {\n\t\t\treturn \"Username contains invalid characters\";\n\t\t}\n\t\treturn null;\n\t}\n\n\tfunction validatePassword(password: string): string | null {\n\t\tif (password.length < minPasswordLen) {\n\t\t\treturn `Password must be at least ${minPasswordLen} characters`;\n\t\t}\n\t\tif (password.length > maxPasswordLen) {\n\t\t\treturn `Password must be at most ${maxPasswordLen} characters`;\n\t\t}\n\t\treturn null;\n\t}\n\n\t// ── public API ─────────────────────────────────────────────────────────\n\n\tasync function signUp(input: { username: string; password: string; name?: string }): Promise<{\n\t\tuser: { id: string; username: string; name: string | null };\n\t\tsession: { token: string; expiresAt: Date };\n\t}> {\n\t\tconst normalisedUsername = normalise(input.username.trim());\n\n\t\tconst usernameError = validateUsername(normalisedUsername);\n\t\tif (usernameError) throw new Error(usernameError);\n\n\t\tconst passwordError = validatePassword(input.password);\n\t\tif (passwordError) throw new Error(passwordError);\n\n\t\t// Check username uniqueness\n\t\tconst existing = await db\n\t\t\t.select({ id: usernameAccounts.userId })\n\t\t\t.from(usernameAccounts)\n\t\t\t.where(eq(usernameAccounts.username, normalisedUsername));\n\n\t\tif (existing[0]) throw new Error(\"Username already taken\");\n\n\t\tconst now = new Date();\n\t\tconst userId = randomUUID();\n\t\tconst passwordHash = hashPassword(input.password);\n\n\t\tawait db.insert(users).values({\n\t\t\tid: userId,\n\t\t\temail: `${normalisedUsername}@username.local`,\n\t\t\tname: input.name ?? null,\n\t\t\tcreatedAt: now,\n\t\t\tupdatedAt: now,\n\t\t});\n\n\t\tawait db.insert(usernameAccounts).values({\n\t\t\tid: randomUUID(),\n\t\t\tuserId,\n\t\t\tusername: normalisedUsername,\n\t\t\tpasswordHash,\n\t\t\tcreatedAt: now,\n\t\t\tupdatedAt: now,\n\t\t});\n\n\t\tconst { token, session } = await sessionManager.create(userId);\n\n\t\treturn {\n\t\t\tuser: { id: userId, username: normalisedUsername, name: input.name ?? null },\n\t\t\tsession: { token, expiresAt: session.expiresAt },\n\t\t};\n\t}\n\n\tasync function signIn(input: { username: string; password: string }): Promise<{\n\t\tuser: { id: string; username: string };\n\t\tsession: { token: string; expiresAt: Date };\n\t}> {\n\t\tconst normalisedUsername = normalise(input.username.trim());\n\n\t\tconst rows = await db\n\t\t\t.select()\n\t\t\t.from(usernameAccounts)\n\t\t\t.where(eq(usernameAccounts.username, normalisedUsername));\n\n\t\tconst account = rows[0];\n\t\tif (!account) throw new Error(\"Invalid username or password\");\n\n\t\tconst valid = verifyPassword(account.passwordHash, input.password);\n\t\tif (!valid) throw new Error(\"Invalid username or password\");\n\n\t\tconst { token, session } = await sessionManager.create(account.userId);\n\n\t\treturn {\n\t\t\tuser: { id: account.userId, username: normalisedUsername },\n\t\t\tsession: { token, expiresAt: session.expiresAt },\n\t\t};\n\t}\n\n\tasync function changePassword(\n\t\tuserId: string,\n\t\tcurrent: string,\n\t\tnewPassword: string,\n\t): Promise<{ success: boolean }> {\n\t\tconst rows = await db\n\t\t\t.select()\n\t\t\t.from(usernameAccounts)\n\t\t\t.where(eq(usernameAccounts.userId, userId));\n\n\t\tconst account = rows[0];\n\t\tif (!account) throw new Error(\"Account not found\");\n\n\t\tconst valid = verifyPassword(account.passwordHash, current);\n\t\tif (!valid) throw new Error(\"Current password is incorrect\");\n\n\t\tconst passwordError = validatePassword(newPassword);\n\t\tif (passwordError) throw new Error(passwordError);\n\n\t\tconst newHash = hashPassword(newPassword);\n\t\tawait db\n\t\t\t.update(usernameAccounts)\n\t\t\t.set({ passwordHash: newHash, updatedAt: new Date() })\n\t\t\t.where(eq(usernameAccounts.userId, userId));\n\n\t\treturn { success: true };\n\t}\n\n\tasync function changeUsername(\n\t\tuserId: string,\n\t\tnewUsername: string,\n\t): Promise<{ success: boolean }> {\n\t\tconst normalised = normalise(newUsername.trim());\n\n\t\tconst usernameError = validateUsername(normalised);\n\t\tif (usernameError) throw new Error(usernameError);\n\n\t\tconst existing = await db\n\t\t\t.select({ id: usernameAccounts.userId })\n\t\t\t.from(usernameAccounts)\n\t\t\t.where(and(eq(usernameAccounts.username, normalised)));\n\n\t\tif (existing[0] && existing[0].id !== userId) {\n\t\t\tthrow new Error(\"Username already taken\");\n\t\t}\n\n\t\tawait db\n\t\t\t.update(usernameAccounts)\n\t\t\t.set({ username: normalised, updatedAt: new Date() })\n\t\t\t.where(eq(usernameAccounts.userId, userId));\n\n\t\treturn { success: true };\n\t}\n\n\tconst HANDLED_PATHS = new Set([\n\t\t\"/auth/username/sign-up\",\n\t\t\"/auth/username/sign-in\",\n\t\t\"/auth/username/change-password\",\n\t\t\"/auth/username/change-username\",\n\t]);\n\n\tasync function handleRequest(request: Request): Promise<Response | null> {\n\t\tif (request.method !== \"POST\") return null;\n\n\t\tconst url = new URL(request.url);\n\t\tconst { pathname } = url;\n\n\t\tif (!HANDLED_PATHS.has(pathname)) return null;\n\n\t\tlet body: unknown;\n\t\ttry {\n\t\t\tbody = await request.json();\n\t\t} catch {\n\t\t\treturn jsonResponse({ error: \"Invalid JSON body\" }, 400);\n\t\t}\n\n\t\tconst b = body as Record<string, unknown>;\n\n\t\tif (pathname === \"/auth/username/sign-up\") {\n\t\t\tif (typeof b.username !== \"string\" || typeof b.password !== \"string\") {\n\t\t\t\treturn jsonResponse({ error: \"Missing required fields: username, password\" }, 400);\n\t\t\t}\n\t\t\ttry {\n\t\t\t\tconst result = await signUp({\n\t\t\t\t\tusername: b.username,\n\t\t\t\t\tpassword: b.password,\n\t\t\t\t\tname: typeof b.name === \"string\" ? b.name : undefined,\n\t\t\t\t});\n\t\t\t\treturn jsonResponse(result, 201);\n\t\t\t} catch (err) {\n\t\t\t\treturn jsonResponse({ error: err instanceof Error ? err.message : \"Sign-up failed\" }, 400);\n\t\t\t}\n\t\t}\n\n\t\tif (pathname === \"/auth/username/sign-in\") {\n\t\t\tif (typeof b.username !== \"string\" || typeof b.password !== \"string\") {\n\t\t\t\treturn jsonResponse({ error: \"Missing required fields: username, password\" }, 400);\n\t\t\t}\n\t\t\ttry {\n\t\t\t\tconst result = await signIn({ username: b.username, password: b.password });\n\t\t\t\treturn jsonResponse(result);\n\t\t\t} catch {\n\t\t\t\treturn jsonResponse({ error: \"Invalid username or password\" }, 401);\n\t\t\t}\n\t\t}\n\n\t\tif (pathname === \"/auth/username/change-password\") {\n\t\t\tif (\n\t\t\t\ttypeof b.userId !== \"string\" ||\n\t\t\t\ttypeof b.current !== \"string\" ||\n\t\t\t\ttypeof b.newPassword !== \"string\"\n\t\t\t) {\n\t\t\t\treturn jsonResponse(\n\t\t\t\t\t{ error: \"Missing required fields: userId, current, newPassword\" },\n\t\t\t\t\t400,\n\t\t\t\t);\n\t\t\t}\n\t\t\ttry {\n\t\t\t\tconst result = await changePassword(b.userId, b.current, b.newPassword);\n\t\t\t\treturn jsonResponse(result);\n\t\t\t} catch (err) {\n\t\t\t\treturn jsonResponse(\n\t\t\t\t\t{ error: err instanceof Error ? err.message : \"Change password failed\" },\n\t\t\t\t\t400,\n\t\t\t\t);\n\t\t\t}\n\t\t}\n\n\t\tif (pathname === \"/auth/username/change-username\") {\n\t\t\tif (typeof b.userId !== \"string\" || typeof b.newUsername !== \"string\") {\n\t\t\t\treturn jsonResponse({ error: \"Missing required fields: userId, newUsername\" }, 400);\n\t\t\t}\n\t\t\ttry {\n\t\t\t\tconst result = await changeUsername(b.userId, b.newUsername);\n\t\t\t\treturn jsonResponse(result);\n\t\t\t} catch (err) {\n\t\t\t\treturn jsonResponse(\n\t\t\t\t\t{ error: err instanceof Error ? err.message : \"Change username failed\" },\n\t\t\t\t\t400,\n\t\t\t\t);\n\t\t\t}\n\t\t}\n\n\t\treturn null;\n\t}\n\n\treturn { signUp, signIn, changePassword, changeUsername, handleRequest };\n}\n","/**\n * Webhook system for KavachOS.\n *\n * Fires signed HTTP POST requests to configured endpoints when auth events\n * occur. Payloads are signed with HMAC-SHA256 and sent with\n * `X-Kavach-Event`, `X-Kavach-Signature`, and `X-Kavach-Timestamp` headers.\n *\n * Delivery is fire-and-forget with exponential backoff retries (1s, 2s, 4s).\n * Failed deliveries after all retries are silently dropped so they never block\n * the auth operation that triggered them.\n *\n * @example\n * ```typescript\n * const kavach = await createKavach({\n * database: { provider: 'sqlite', url: 'kavach.db' },\n * webhooks: [{\n * url: 'https://my-service.example.com/webhooks/kavach',\n * secret: process.env.WEBHOOK_SECRET,\n * events: ['user.created', 'session.created'],\n * }],\n * });\n *\n * // Emit from anywhere in your app\n * kavach.webhooks?.emit('user.created', { userId: user.id });\n * ```\n */\n\nimport { createHmac } from \"node:crypto\";\n\n// ---------------------------------------------------------------------------\n// Public types\n// ---------------------------------------------------------------------------\n\nexport type WebhookEvent =\n\t| \"user.created\"\n\t| \"user.deleted\"\n\t| \"user.updated\"\n\t| \"session.created\"\n\t| \"session.revoked\"\n\t| \"agent.created\"\n\t| \"agent.revoked\"\n\t| \"agent.rotated\"\n\t| \"auth.sign-in\"\n\t| \"auth.sign-up\"\n\t| \"auth.password-reset\"\n\t| \"auth.email-verified\";\n\nexport interface WebhookConfig {\n\t/** Destination URL for the webhook POST request. */\n\turl: string;\n\t/** HMAC signing secret — keep this private. */\n\tsecret: string;\n\t/** Events this endpoint subscribes to. */\n\tevents: WebhookEvent[];\n\t/** Retry count (default: 3) */\n\tretries?: number;\n\t/** Request timeout in milliseconds (default: 10000) */\n\ttimeout?: number;\n}\n\nexport interface WebhookModule {\n\t/** Fire a webhook for an event. Non-blocking — retries happen in background. */\n\temit: (event: WebhookEvent, payload: Record<string, unknown>) => void;\n\t/** Register an additional webhook endpoint at runtime. */\n\taddEndpoint: (config: WebhookConfig) => void;\n\t/** Return a copy of all configured endpoints. */\n\tlistEndpoints: () => WebhookConfig[];\n}\n\n// ---------------------------------------------------------------------------\n// Helpers\n// ---------------------------------------------------------------------------\n\nfunction signPayload(secret: string, timestamp: string, body: string): string {\n\tconst data = `${timestamp}.${body}`;\n\treturn createHmac(\"sha256\", secret).update(data).digest(\"hex\");\n}\n\nasync function deliverOnce(\n\tendpoint: WebhookConfig,\n\tevent: WebhookEvent,\n\tbody: string,\n\ttimestamp: string,\n): Promise<boolean> {\n\tconst signature = signPayload(endpoint.secret, timestamp, body);\n\tconst timeout = endpoint.timeout ?? 10_000;\n\n\tconst controller = new AbortController();\n\tconst timer = setTimeout(() => controller.abort(), timeout);\n\n\ttry {\n\t\tconst response = await fetch(endpoint.url, {\n\t\t\tmethod: \"POST\",\n\t\t\theaders: {\n\t\t\t\t\"Content-Type\": \"application/json\",\n\t\t\t\t\"X-Kavach-Event\": event,\n\t\t\t\t\"X-Kavach-Signature\": `sha256=${signature}`,\n\t\t\t\t\"X-Kavach-Timestamp\": timestamp,\n\t\t\t},\n\t\t\tbody,\n\t\t\tsignal: controller.signal,\n\t\t});\n\t\treturn response.ok;\n\t} catch {\n\t\treturn false;\n\t} finally {\n\t\tclearTimeout(timer);\n\t}\n}\n\nasync function deliverWithRetry(\n\tendpoint: WebhookConfig,\n\tevent: WebhookEvent,\n\tbody: string,\n\ttimestamp: string,\n): Promise<void> {\n\tconst maxRetries = endpoint.retries ?? 3;\n\tlet attempt = 0;\n\n\twhile (attempt <= maxRetries) {\n\t\tconst success = await deliverOnce(endpoint, event, body, timestamp);\n\t\tif (success) return;\n\n\t\tattempt++;\n\t\tif (attempt <= maxRetries) {\n\t\t\t// Exponential backoff: 1s, 2s, 4s, …\n\t\t\tawait new Promise<void>((resolve) => setTimeout(resolve, 1000 * 2 ** (attempt - 1)));\n\t\t}\n\t}\n}\n\n// ---------------------------------------------------------------------------\n// Factory\n// ---------------------------------------------------------------------------\n\nexport function createWebhookModule(configs: WebhookConfig[]): WebhookModule {\n\tconst endpoints: WebhookConfig[] = [...configs];\n\n\tfunction emit(event: WebhookEvent, payload: Record<string, unknown>): void {\n\t\tconst timestamp = Math.floor(Date.now() / 1000).toString();\n\t\tconst body = JSON.stringify({ event, timestamp, data: payload });\n\n\t\tfor (const endpoint of endpoints) {\n\t\t\tif (!endpoint.events.includes(event)) continue;\n\t\t\t// Fire and forget — intentionally not awaited\n\t\t\tvoid deliverWithRetry(endpoint, event, body, timestamp);\n\t\t}\n\t}\n\n\tfunction addEndpoint(config: WebhookConfig): void {\n\t\tendpoints.push(config);\n\t}\n\n\tfunction listEndpoints(): WebhookConfig[] {\n\t\treturn [...endpoints];\n\t}\n\n\treturn { emit, addEndpoint, listEndpoints };\n}\n"]}
|