@holeauth/hono 0.0.2-alpha.0 → 0.1.0-alpha.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.js +2 -0
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
package/dist/index.js
CHANGED
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/index.ts","../src/dispatch.ts","../src/cookies.ts"],"sourcesContent":["import { Hono, type Context, type MiddlewareHandler } from 'hono';\nimport {\n defineHoleauth,\n type HoleauthConfig,\n type HoleauthInstance,\n type HoleauthPlugin,\n type PluginsApi,\n type SessionData,\n} from '@holeauth/core';\nimport { getSessionOrRefreshFromRequest } from '@holeauth/core/session';\nimport { cookieName } from '@holeauth/core/cookies';\nimport { createDispatcher, type DispatchOptions } from './dispatch.js';\nimport { parseCookies } from './cookies.js';\n\nexport { createDispatcher, type DispatchOptions } from './dispatch.js';\nexport * from './cookies.js';\nexport { getSessionOrRefreshFromRequest, type RequestRefreshResult } from '@holeauth/core/session';\n\nexport type HoleauthHonoVariables = {\n holeauthSession: SessionData | null;\n};\n\nexport type HonoHoleauth<\n Plugins extends readonly HoleauthPlugin<string, unknown>[] = [],\n> = HoleauthInstance &\n PluginsApi<Plugins> & {\n /** Mount with `app.route('/api/auth', auth.app)`. */\n app: Hono;\n };\n\n/* ──────────────────────────── handler ──────────────────────────── */\n\n/**\n * Build a Hono sub-app that handles all holeauth core + plugin routes.\n *\n * ```ts\n * const auth = createHonoAuth({ ... });\n * app.route('/api/auth', auth.app);\n * ```\n */\nexport function createHonoAuth<\n const Plugins extends readonly HoleauthPlugin<string, unknown>[] = [],\n>(\n config: Omit<HoleauthConfig, 'plugins'> & { plugins?: Plugins },\n opts: DispatchOptions = {},\n): HonoHoleauth<Plugins> {\n const base = defineHoleauth(config);\n const app = createHonoAuthApp(base, opts);\n return { ...base, app } as HonoHoleauth<Plugins>;\n}\n\n/** Build a Hono sub-app from an existing `HoleauthInstance`. */\nexport function createHonoAuthApp(auth: HoleauthInstance, opts: DispatchOptions = {}): Hono {\n const dispatch = createDispatcher(auth, opts);\n const app = new Hono();\n\n // Hono passes the raw Web Request through `c.req.raw`. The dispatcher uses\n // `new URL(req.url).pathname` so we must reconstruct a request whose path\n // includes the mount prefix (Hono strips it). The dispatcher itself strips\n // its configured basePath.\n app.all('*', async (c) => {\n const inner = c.req.raw;\n // The basePath is part of the original request URL via the mount point;\n // Hono exposes the matched route path stripped, so we re-derive the full\n // path from `c.req.url` (which is unchanged) — but we still need to keep\n // the original URL. Hono's `c.req.raw.url` is the full URL — pass through.\n const webRes = await dispatch(inner);\n return webRes;\n });\n\n return app;\n}\n\n/* ───────────────────────── session helpers ─────────────────────── */\n\n/**\n * Hono middleware that resolves `c.var.holeauthSession`. Use:\n *\n * ```ts\n * app.use('*', holeauthHonoMiddleware(auth));\n * app.get('/me', (c) => c.json({ session: c.get('holeauthSession') }));\n * ```\n */\nexport function holeauthHonoMiddleware(\n auth: HoleauthInstance,\n): MiddlewareHandler<{ Variables: HoleauthHonoVariables }> {\n return async (c, next) => {\n const session = await getSession(c, auth);\n c.set('holeauthSession', session);\n await next();\n };\n}\n\n/** Read the current session from a Hono context. */\nexport async function getSession(\n c: Context,\n auth: HoleauthInstance,\n): Promise<SessionData | null> {\n const cookieHeader = c.req.header('cookie') ?? null;\n const jar = parseCookies(cookieHeader);\n const token = jar[cookieName(auth.config, 'access')];\n if (!token) return null;\n return auth.getSession(token);\n}\n\n/* ─────────────────────── tRPC context factory ──────────────────── */\n\nexport interface HoleauthHonoContext {\n c: Context;\n req: Request;\n session: SessionData | null;\n /** True when the access token was silently rotated via the refresh token. */\n refreshed: boolean;\n auth: HoleauthInstance;\n}\n\n/**\n * Build a tRPC context factory for Hono — pair with `@hono/trpc-server`. The\n * returned function accepts the same shape passed by Hono's tRPC adapter.\n */\nexport function createHoleauthHonoContext(auth: HoleauthInstance) {\n return async function createContext(_opts: unknown, c: Context): Promise<HoleauthHonoContext> {\n const { session, refreshed, setCookieHeaders } = await getSessionOrRefreshFromRequest(c.req.raw, auth);\n for (const cookie of setCookieHeaders) {\n c.header('Set-Cookie', cookie, { append: true });\n }\n return { c, req: c.req.raw, session, refreshed, auth };\n };\n}\n\nexport type { HoleauthConfig } from '@holeauth/core';\n","import type { HoleauthConfig, HoleauthInstance, SignInResult, PluginRoute, PluginRouteContext } from '@holeauth/core';\nimport { HoleauthError, CsrfError } from '@holeauth/core/errors';\nimport { getRegistry } from '@holeauth/core';\nimport {\n readCookie,\n checkCsrf,\n writeAuthCookies,\n clearAuthCookies,\n writePending,\n parseCookies,\n setCookie,\n} from './cookies.js';\nimport {\n buildCookie,\n serializeCookie,\n deleteCookie,\n cookieName,\n} from '@holeauth/core/cookies';\n\nfunction json(body: unknown, init: ResponseInit = {}): Response {\n const headers = new Headers(init.headers);\n headers.set('content-type', 'application/json');\n return new Response(JSON.stringify(body), { ...init, headers });\n}\n\nfunction errorResponse(e: unknown): Response {\n if (e instanceof HoleauthError) {\n return json({ error: { code: e.code, message: e.message } }, { status: e.status });\n }\n // Duck-type fallback: `@holeauth/core` is built as multiple bundled\n // entrypoints (splitting: false), so a `HoleauthError` thrown from one\n // bundle (e.g. core/flows via dist/index.js) is not `instanceof` the\n // class re-imported from `@holeauth/core/errors` in this package.\n if (\n e instanceof Error &&\n e.name === 'HoleauthError' &&\n typeof (e as { code?: unknown }).code === 'string' &&\n typeof (e as { status?: unknown }).status === 'number'\n ) {\n const err = e as Error & { code: string; status: number };\n return json({ error: { code: err.code, message: err.message } }, { status: err.status });\n }\n // Log unexpected errors so they don't disappear into a generic 500.\n // eslint-disable-next-line no-console\n console.error('[holeauth] Unhandled error in request dispatch:', e);\n return json({ error: { code: 'INTERNAL', message: 'Internal error' } }, { status: 500 });\n}\n\nfunction getMeta(req: Request): { ip?: string; userAgent?: string } {\n return {\n ip:\n req.headers.get('x-forwarded-for')?.split(',')[0]?.trim() ??\n req.headers.get('x-real-ip') ??\n undefined,\n userAgent: req.headers.get('user-agent') ?? undefined,\n };\n}\n\nasync function parseBody(req: Request): Promise<Record<string, unknown>> {\n try { return (await req.json()) as Record<string, unknown>; } catch { return {}; }\n}\n\nfunction pathSegments(req: Request, basePath: string): string[] {\n const url = new URL(req.url);\n let p = url.pathname;\n if (p.startsWith(basePath)) p = p.slice(basePath.length);\n return p.split('/').filter(Boolean);\n}\n\nfunction writeTokens(cfg: HoleauthConfig, result: SignInResult): Response {\n const headers = new Headers({ 'content-type': 'application/json' });\n if (result.kind === 'ok') {\n writeAuthCookies(cfg, headers, result.tokens);\n setCookie(headers, serializeCookie(deleteCookie(cfg, 'pending')));\n return new Response(\n JSON.stringify({ ok: true, user: publicUser(result.user), csrfToken: result.tokens.csrfToken }),\n { status: 200, headers },\n );\n }\n writePending(cfg, headers, result.pendingToken);\n return new Response(\n JSON.stringify({\n ok: true,\n pending: true,\n pluginId: result.pluginId,\n userId: result.userId,\n data: result.data ?? null,\n }),\n { status: 200, headers },\n );\n}\n\nfunction publicUser(u: { id: string; email: string; name?: string | null; image?: string | null }) {\n return { id: u.id, email: u.email, name: u.name ?? null, image: u.image ?? null };\n}\n\n/* ───────────────────── Plugin route matching ───────────────────── */\n\nfunction matchPluginRoute(\n routes: readonly PluginRoute[],\n method: string,\n segs: string[],\n): { route: PluginRoute; params: Record<string, string> } | null {\n for (const r of routes) {\n if (r.method !== method) continue;\n const rSegs = r.path.split('/').filter(Boolean);\n if (rSegs.length !== segs.length) continue;\n const params: Record<string, string> = {};\n let ok = true;\n for (let i = 0; i < rSegs.length; i++) {\n const a = rSegs[i]!;\n const b = segs[i]!;\n if (a.startsWith(':')) {\n params[a.slice(1)] = decodeURIComponent(b);\n } else if (a !== b) {\n ok = false;\n break;\n }\n }\n if (ok) return { route: r, params };\n }\n return null;\n}\n\nasync function runPluginRoute(\n instance: HoleauthInstance,\n route: PluginRoute,\n req: Request,\n params: Record<string, string>,\n): Promise<Response> {\n const cfg = instance.config;\n const registry = getRegistry(instance);\n\n const jar = parseCookies(req.headers.get('cookie'));\n const responseHeaders = new Headers();\n const meta = getMeta(req);\n\n if (route.requireCsrf) {\n if (!checkCsrf(req, cfg)) throw new CsrfError();\n }\n\n const session = await (async () => {\n const at = readCookie(req, cfg, 'access');\n return at ? instance.getSession(at) : null;\n })();\n\n if (route.requireAuth && !session) {\n return json({ error: { code: 'UNAUTHENTICATED', message: 'authentication required' } }, { status: 401 });\n }\n\n const body = req.method === 'POST' ? await parseBody(req) : {};\n const ctx: PluginRouteContext = {\n req,\n body: { ...body, ...params },\n responseHeaders,\n cookies: { get: (name) => jar[name] },\n setCookie(spec) {\n const secure = (cfg.tokens?.cookieSecure ?? ((globalThis as { process?: { env?: { NODE_ENV?: string } } }).process?.env?.NODE_ENV === 'production'));\n const parts = [`${spec.name}=${encodeURIComponent(spec.value)}`];\n parts.push(`Path=${spec.path ?? '/'}`);\n if (spec.maxAge !== undefined) parts.push(`Max-Age=${spec.maxAge}`);\n if (spec.httpOnly ?? true) parts.push('HttpOnly');\n if (secure) parts.push('Secure');\n const ss = spec.sameSite ?? cfg.tokens?.sameSite ?? 'lax';\n parts.push(`SameSite=${ss.charAt(0).toUpperCase()}${ss.slice(1)}`);\n setCookie(responseHeaders, parts.join('; '));\n },\n async getSession() {\n return session;\n },\n meta,\n plugin: registry.ctx,\n };\n\n const res = await route.handler(ctx);\n // Merge any headers the plugin appended into the returned response.\n if (responseHeaders.has('Set-Cookie')) {\n const merged = new Headers(res.headers);\n responseHeaders.forEach((v, k) => {\n if (k.toLowerCase() === 'set-cookie') merged.append('Set-Cookie', v);\n else merged.set(k, v);\n });\n return new Response(res.body, { status: res.status, statusText: res.statusText, headers: merged });\n }\n return res;\n}\n\n/* ─────────────────────────── Dispatcher ─────────────────────────── */\n\nexport interface DispatchOptions {\n /** Used to strip the prefix from pathnames. Default '/api/auth'. */\n basePath?: string;\n /** Default post-signin redirect destination (SSO callback). */\n defaultRedirect?: string;\n}\n\n/**\n * Build the unified GET/POST dispatcher. Mounted under `/api/auth/[...holeauth]`.\n *\n * Core routes take precedence; plugin routes are matched only if no core\n * route accepts the request.\n */\nexport function createDispatcher(\n instance: HoleauthInstance,\n opts: DispatchOptions = {},\n): (req: Request) => Promise<Response> {\n const basePath = opts.basePath ?? '/api/auth';\n const cfg = instance.config;\n const registry = getRegistry(instance);\n\n return async function dispatch(req: Request): Promise<Response> {\n const segs = pathSegments(req, basePath);\n const method = req.method.toUpperCase();\n\n try {\n // ── GET /session ─────────────────────────────────────────\n if (method === 'GET' && segs[0] === 'session' && !segs[1]) {\n const at = readCookie(req, cfg, 'access');\n const session = at ? await instance.getSession(at) : null;\n return json({ session });\n }\n\n // ── GET /csrf ────────────────────────────────────────────\n if (method === 'GET' && segs[0] === 'csrf' && !segs[1]) {\n const existing = readCookie(req, cfg, 'csrf');\n return json({ csrfToken: existing ?? null });\n }\n\n // ── GET /invite/info?token=... ───────────────────────────\n if (method === 'GET' && segs[0] === 'invite' && segs[1] === 'info' && !segs[2]) {\n const url = new URL(req.url);\n const token = url.searchParams.get('token') ?? '';\n if (!token) return json({ error: { code: 'MISSING_TOKEN', message: 'token required' } }, { status: 400 });\n const info = await instance.getInviteInfo({ token });\n // Expose only fields intended for public pre-fill.\n return json({\n invite: {\n email: info.email,\n name: info.name ?? null,\n expiresAt: info.expiresAt,\n identifier: info.identifier,\n },\n });\n }\n\n // ── GET /invite/list ─────────────────────────────────────\n if (method === 'GET' && segs[0] === 'invite' && segs[1] === 'list' && !segs[2]) {\n const at = readCookie(req, cfg, 'access');\n const s = at ? await instance.getSession(at) : null;\n if (!s) return json({ error: { code: 'UNAUTHENTICATED' } }, { status: 401 });\n const invites = await instance.listInvites();\n return json({ invites });\n }\n\n // ── GET /authorize/:provider ─────────────────────────────\n if (method === 'GET' && segs[0] === 'authorize' && segs[1]) {\n const { url, state, codeVerifier } = await instance.sso.authorize(segs[1]);\n const headers = new Headers({ location: url });\n setCookie(headers, serializeCookie(buildCookie(cfg, {\n kind: 'oauthState', value: state, maxAge: 600, sameSite: 'lax',\n })));\n setCookie(headers, serializeCookie(buildCookie(cfg, {\n kind: 'oauthPkce', value: codeVerifier, maxAge: 600, sameSite: 'lax',\n })));\n return new Response(null, { status: 302, headers });\n }\n\n // ── GET /callback/:provider?code=&state= ─────────────────\n if (method === 'GET' && segs[0] === 'callback' && segs[1]) {\n const url = new URL(req.url);\n const code = url.searchParams.get('code') ?? '';\n const state = url.searchParams.get('state') ?? '';\n const jar = parseCookies(req.headers.get('cookie'));\n const storedState = jar[cookieName(cfg, 'oauthState')];\n const codeVerifier = jar[cookieName(cfg, 'oauthPkce')];\n if (!state || !storedState || state !== storedState || !codeVerifier) {\n return json({ error: { code: 'SSO_STATE_MISMATCH', message: 'state/pkce invalid' } }, { status: 400 });\n }\n const meta = getMeta(req);\n const { user, tokens } = await instance.sso.callback(segs[1], {\n code, state, codeVerifier, ip: meta.ip, userAgent: meta.userAgent,\n });\n const headers = new Headers({ location: opts.defaultRedirect ?? '/dashboard' });\n writeAuthCookies(cfg, headers, tokens);\n setCookie(headers, serializeCookie(deleteCookie(cfg, 'oauthState')));\n setCookie(headers, serializeCookie(deleteCookie(cfg, 'oauthPkce')));\n void user;\n return new Response(null, { status: 302, headers });\n }\n\n if (method === 'POST') {\n // POST /register\n if (segs[0] === 'register' && !segs[1]) {\n const body = await parseBody(req);\n const user = await instance.register({\n email: String(body.email ?? ''),\n password: String(body.password ?? ''),\n name: body.name ? String(body.name) : undefined,\n });\n return json({ ok: true, user: publicUser(user) });\n }\n\n // POST /signin (password)\n if (segs[0] === 'signin' && !segs[1]) {\n const body = await parseBody(req);\n const meta = getMeta(req);\n const result = await instance.signIn({\n email: String(body.email ?? ''),\n password: String(body.password ?? ''),\n ip: meta.ip, userAgent: meta.userAgent,\n });\n return writeTokens(cfg, result);\n }\n\n // POST /signout\n if (segs[0] === 'signout' && !segs[1]) {\n if (!checkCsrf(req, cfg)) throw new CsrfError();\n const at = readCookie(req, cfg, 'access');\n const rt = readCookie(req, cfg, 'refresh');\n await instance.signOut({ accessToken: at, refreshToken: rt });\n const headers = new Headers({ 'content-type': 'application/json' });\n clearAuthCookies(cfg, headers);\n return new Response(JSON.stringify({ ok: true }), { status: 200, headers });\n }\n\n // POST /refresh\n if (segs[0] === 'refresh' && !segs[1]) {\n const rt = readCookie(req, cfg, 'refresh');\n if (!rt) return json({ error: { code: 'NO_REFRESH', message: 'no refresh token' } }, { status: 401 });\n const meta = getMeta(req);\n const tokens = await instance.refresh({ refreshToken: rt, ip: meta.ip, userAgent: meta.userAgent });\n const headers = new Headers({ 'content-type': 'application/json' });\n writeAuthCookies(cfg, headers, tokens);\n return new Response(JSON.stringify({ ok: true, csrfToken: tokens.csrfToken }), { status: 200, headers });\n }\n\n // POST /password/change\n if (segs[0] === 'password' && segs[1] === 'change' && !segs[2]) {\n if (!checkCsrf(req, cfg)) throw new CsrfError();\n const at = readCookie(req, cfg, 'access');\n const s = at ? await instance.getSession(at) : null;\n if (!s) return json({ error: { code: 'UNAUTHENTICATED' } }, { status: 401 });\n const body = await parseBody(req);\n await instance.changePassword({\n userId: s.userId,\n currentPassword: String(body.currentPassword ?? ''),\n newPassword: String(body.newPassword ?? ''),\n revokeOtherSessions: body.revokeOtherSessions !== false,\n });\n return json({ ok: true });\n }\n\n // POST /password/reset/request\n if (segs[0] === 'password' && segs[1] === 'reset' && segs[2] === 'request' && !segs[3]) {\n const body = await parseBody(req);\n await instance.requestPasswordReset({ email: String(body.email ?? '') });\n // Do not echo token — consumer is expected to have delivered it out-of-band.\n return json({ ok: true });\n }\n\n // POST /password/reset/consume\n if (segs[0] === 'password' && segs[1] === 'reset' && segs[2] === 'consume' && !segs[3]) {\n const body = await parseBody(req);\n await instance.consumePasswordReset({\n email: String(body.email ?? ''),\n token: String(body.token ?? ''),\n newPassword: String(body.newPassword ?? ''),\n });\n return json({ ok: true });\n }\n\n // POST /invite/create (auth + CSRF)\n if (segs[0] === 'invite' && segs[1] === 'create' && !segs[2]) {\n if (!checkCsrf(req, cfg)) throw new CsrfError();\n const at = readCookie(req, cfg, 'access');\n const s = at ? await instance.getSession(at) : null;\n if (!s) return json({ error: { code: 'UNAUTHENTICATED' } }, { status: 401 });\n const body = await parseBody(req);\n const result = await instance.createInvite({\n email: String(body.email ?? ''),\n name: body.name != null ? String(body.name) : undefined,\n groupIds: Array.isArray(body.groupIds) ? (body.groupIds as unknown[]).map(String) : undefined,\n metadata: (body.metadata ?? null) as Record<string, unknown> | null,\n ttlSeconds: typeof body.ttlSeconds === 'number' ? body.ttlSeconds : undefined,\n invitedBy: s.userId,\n });\n return json({ ok: true, invite: result });\n }\n\n // POST /invite/consume (public)\n if (segs[0] === 'invite' && segs[1] === 'consume' && !segs[2]) {\n const body = await parseBody(req);\n const meta = getMeta(req);\n const result = await instance.consumeInvite({\n token: String(body.token ?? ''),\n password: String(body.password ?? ''),\n name: body.name != null ? String(body.name) : undefined,\n autoSignIn: body.autoSignIn !== false,\n ip: meta.ip,\n userAgent: meta.userAgent,\n });\n if (result.tokens) {\n const headers = new Headers({ 'content-type': 'application/json' });\n writeAuthCookies(cfg, headers, result.tokens);\n return new Response(\n JSON.stringify({\n ok: true,\n user: publicUser(result.user),\n csrfToken: result.tokens.csrfToken,\n groupIds: result.groupIds ?? [],\n }),\n { status: 200, headers },\n );\n }\n return json({ ok: true, user: publicUser(result.user), groupIds: result.groupIds ?? [] });\n }\n\n // POST /invite/revoke (auth + CSRF)\n if (segs[0] === 'invite' && segs[1] === 'revoke' && !segs[2]) {\n if (!checkCsrf(req, cfg)) throw new CsrfError();\n const at = readCookie(req, cfg, 'access');\n const s = at ? await instance.getSession(at) : null;\n if (!s) return json({ error: { code: 'UNAUTHENTICATED' } }, { status: 401 });\n const body = await parseBody(req);\n await instance.revokeInvite({ identifier: String(body.identifier ?? '') });\n return json({ ok: true });\n }\n }\n\n // ── Plugin routes ────────────────────────────────────────\n const match = matchPluginRoute(registry.routes, method, segs);\n if (match) {\n return runPluginRoute(instance, match.route, req, match.params);\n }\n\n return json({ error: { code: 'NOT_FOUND', message: 'route not found' } }, { status: 404 });\n } catch (e) {\n return errorResponse(e);\n }\n };\n}\n","import type { HoleauthConfig, IssuedTokens } from '@holeauth/core';\nimport {\n buildCookie,\n deleteCookie,\n serializeCookie,\n cookieName,\n verifyCsrf,\n CSRF_HEADER,\n} from '@holeauth/core/cookies';\n\n/** Append one Set-Cookie header entry. Headers.append() preserves multiple values. */\nexport function setCookie(headers: Headers, cookie: string): void {\n headers.append('Set-Cookie', cookie);\n}\n\n/**\n * Apply a freshly-issued token bundle to a Response. Writes access + refresh\n * (httpOnly) plus the JS-readable CSRF cookie.\n */\nexport function writeAuthCookies(cfg: HoleauthConfig, headers: Headers, tokens: IssuedTokens): void {\n const accessTtl = cfg.tokens?.accessTtl ?? 900;\n const refreshTtl = cfg.tokens?.refreshTtl ?? 2592000;\n\n setCookie(\n headers,\n serializeCookie(buildCookie(cfg, { kind: 'access', value: tokens.accessToken, maxAge: accessTtl })),\n );\n setCookie(\n headers,\n serializeCookie(buildCookie(cfg, { kind: 'refresh', value: tokens.refreshToken, maxAge: refreshTtl })),\n );\n setCookie(\n headers,\n serializeCookie(buildCookie(cfg, { kind: 'csrf', value: tokens.csrfToken, maxAge: refreshTtl, httpOnly: false })),\n );\n}\n\nexport function clearAuthCookies(cfg: HoleauthConfig, headers: Headers): void {\n setCookie(headers, serializeCookie(deleteCookie(cfg, 'access')));\n setCookie(headers, serializeCookie(deleteCookie(cfg, 'refresh')));\n setCookie(headers, serializeCookie(deleteCookie(cfg, 'csrf')));\n setCookie(headers, serializeCookie(deleteCookie(cfg, 'pending')));\n}\n\nexport function writePending(cfg: HoleauthConfig, headers: Headers, pendingToken: string): void {\n const ttl = cfg.tokens?.pendingTtl ?? 300;\n setCookie(\n headers,\n serializeCookie(buildCookie(cfg, { kind: 'pending', value: pendingToken, maxAge: ttl })),\n );\n}\n\n/** Parse a Cookie header into a map. Next gives us a cookies API but we also\n * work off raw Request here for edge compatibility. */\nexport function parseCookies(header: string | null): Record<string, string> {\n const out: Record<string, string> = {};\n if (!header) return out;\n for (const part of header.split(';')) {\n const i = part.indexOf('=');\n if (i < 0) continue;\n const k = part.slice(0, i).trim();\n const v = decodeURIComponent(part.slice(i + 1).trim());\n if (k) out[k] = v;\n }\n return out;\n}\n\nexport function readCookie(req: Request, cfg: HoleauthConfig, kind: Parameters<typeof cookieName>[1]): string | undefined {\n const jar = parseCookies(req.headers.get('cookie'));\n return jar[cookieName(cfg, kind)];\n}\n\n/** Returns true if the double-submit CSRF check passes. */\nexport function checkCsrf(req: Request, cfg: HoleauthConfig): boolean {\n const cookie = readCookie(req, cfg, 'csrf');\n const header = req.headers.get(CSRF_HEADER);\n return verifyCsrf(cookie, header ?? undefined);\n}\n"],"mappings":"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","names":["cookieName","buildCookie","serializeCookie","deleteCookie","cookieName","getSessionOrRefreshFromRequest","cookieName"]}
|
|
1
|
+
{"version":3,"sources":["../src/index.ts","../src/dispatch.ts","../src/cookies.ts"],"sourcesContent":["import { Hono, type Context, type MiddlewareHandler } from 'hono';\nimport {\n defineHoleauth,\n type HoleauthConfig,\n type HoleauthInstance,\n type HoleauthPlugin,\n type PluginsApi,\n type SessionData,\n} from '@holeauth/core';\nimport { getSessionOrRefreshFromRequest } from '@holeauth/core/session';\nimport { cookieName } from '@holeauth/core/cookies';\nimport { createDispatcher, type DispatchOptions } from './dispatch.js';\nimport { parseCookies } from './cookies.js';\n\nexport { createDispatcher, type DispatchOptions } from './dispatch.js';\nexport * from './cookies.js';\nexport { getSessionOrRefreshFromRequest, type RequestRefreshResult } from '@holeauth/core/session';\n\nexport type HoleauthHonoVariables = {\n holeauthSession: SessionData | null;\n};\n\nexport type HonoHoleauth<\n Plugins extends readonly HoleauthPlugin<string, unknown>[] = [],\n> = HoleauthInstance &\n PluginsApi<Plugins> & {\n /** Mount with `app.route('/api/auth', auth.app)`. */\n app: Hono;\n };\n\n/* ──────────────────────────── handler ──────────────────────────── */\n\n/**\n * Build a Hono sub-app that handles all holeauth core + plugin routes.\n *\n * ```ts\n * const auth = createHonoAuth({ ... });\n * app.route('/api/auth', auth.app);\n * ```\n */\nexport function createHonoAuth<\n const Plugins extends readonly HoleauthPlugin<string, unknown>[] = [],\n>(\n config: Omit<HoleauthConfig, 'plugins'> & { plugins?: Plugins },\n opts: DispatchOptions = {},\n): HonoHoleauth<Plugins> {\n const base = defineHoleauth(config);\n const app = createHonoAuthApp(base, opts);\n return { ...base, app } as HonoHoleauth<Plugins>;\n}\n\n/** Build a Hono sub-app from an existing `HoleauthInstance`. */\nexport function createHonoAuthApp(auth: HoleauthInstance, opts: DispatchOptions = {}): Hono {\n const dispatch = createDispatcher(auth, opts);\n const app = new Hono();\n\n // Hono passes the raw Web Request through `c.req.raw`. The dispatcher uses\n // `new URL(req.url).pathname` so we must reconstruct a request whose path\n // includes the mount prefix (Hono strips it). The dispatcher itself strips\n // its configured basePath.\n app.all('*', async (c) => {\n const inner = c.req.raw;\n // The basePath is part of the original request URL via the mount point;\n // Hono exposes the matched route path stripped, so we re-derive the full\n // path from `c.req.url` (which is unchanged) — but we still need to keep\n // the original URL. Hono's `c.req.raw.url` is the full URL — pass through.\n const webRes = await dispatch(inner);\n return webRes;\n });\n\n return app;\n}\n\n/* ───────────────────────── session helpers ─────────────────────── */\n\n/**\n * Hono middleware that resolves `c.var.holeauthSession`. Use:\n *\n * ```ts\n * app.use('*', holeauthHonoMiddleware(auth));\n * app.get('/me', (c) => c.json({ session: c.get('holeauthSession') }));\n * ```\n */\nexport function holeauthHonoMiddleware(\n auth: HoleauthInstance,\n): MiddlewareHandler<{ Variables: HoleauthHonoVariables }> {\n return async (c, next) => {\n const session = await getSession(c, auth);\n c.set('holeauthSession', session);\n await next();\n };\n}\n\n/** Read the current session from a Hono context. */\nexport async function getSession(\n c: Context,\n auth: HoleauthInstance,\n): Promise<SessionData | null> {\n const cookieHeader = c.req.header('cookie') ?? null;\n const jar = parseCookies(cookieHeader);\n const token = jar[cookieName(auth.config, 'access')];\n if (!token) return null;\n return auth.getSession(token);\n}\n\n/* ─────────────────────── tRPC context factory ──────────────────── */\n\nexport interface HoleauthHonoContext {\n c: Context;\n req: Request;\n session: SessionData | null;\n /** True when the access token was silently rotated via the refresh token. */\n refreshed: boolean;\n auth: HoleauthInstance;\n}\n\n/**\n * Build a tRPC context factory for Hono — pair with `@hono/trpc-server`. The\n * returned function accepts the same shape passed by Hono's tRPC adapter.\n */\nexport function createHoleauthHonoContext(auth: HoleauthInstance) {\n return async function createContext(_opts: unknown, c: Context): Promise<HoleauthHonoContext> {\n const { session, refreshed, setCookieHeaders } = await getSessionOrRefreshFromRequest(c.req.raw, auth);\n for (const cookie of setCookieHeaders) {\n c.header('Set-Cookie', cookie, { append: true });\n }\n return { c, req: c.req.raw, session, refreshed, auth };\n };\n}\n\nexport type { HoleauthConfig } from '@holeauth/core';\n","import type { HoleauthConfig, HoleauthInstance, SignInResult, PluginRoute, PluginRouteContext } from '@holeauth/core';\nimport { HoleauthError, CsrfError } from '@holeauth/core/errors';\nimport { getRegistry } from '@holeauth/core';\nimport {\n readCookie,\n checkCsrf,\n writeAuthCookies,\n clearAuthCookies,\n writePending,\n parseCookies,\n setCookie,\n} from './cookies.js';\nimport {\n buildCookie,\n serializeCookie,\n deleteCookie,\n cookieName,\n} from '@holeauth/core/cookies';\n\nfunction json(body: unknown, init: ResponseInit = {}): Response {\n const headers = new Headers(init.headers);\n headers.set('content-type', 'application/json');\n return new Response(JSON.stringify(body), { ...init, headers });\n}\n\nfunction errorResponse(e: unknown): Response {\n if (e instanceof HoleauthError) {\n return json({ error: { code: e.code, message: e.message } }, { status: e.status });\n }\n // Duck-type fallback: `@holeauth/core` is built as multiple bundled\n // entrypoints (splitting: false), so a `HoleauthError` thrown from one\n // bundle (e.g. core/flows via dist/index.js) is not `instanceof` the\n // class re-imported from `@holeauth/core/errors` in this package.\n if (\n e instanceof Error &&\n e.name === 'HoleauthError' &&\n typeof (e as { code?: unknown }).code === 'string' &&\n typeof (e as { status?: unknown }).status === 'number'\n ) {\n const err = e as Error & { code: string; status: number };\n return json({ error: { code: err.code, message: err.message } }, { status: err.status });\n }\n // Log unexpected errors so they don't disappear into a generic 500.\n // eslint-disable-next-line no-console\n console.error('[holeauth] Unhandled error in request dispatch:', e);\n return json({ error: { code: 'INTERNAL', message: 'Internal error' } }, { status: 500 });\n}\n\nfunction getMeta(req: Request): { ip?: string; userAgent?: string } {\n return {\n ip:\n req.headers.get('x-forwarded-for')?.split(',')[0]?.trim() ??\n req.headers.get('x-real-ip') ??\n undefined,\n userAgent: req.headers.get('user-agent') ?? undefined,\n };\n}\n\nasync function parseBody(req: Request): Promise<Record<string, unknown>> {\n try { return (await req.json()) as Record<string, unknown>; } catch { return {}; }\n}\n\nfunction pathSegments(req: Request, basePath: string): string[] {\n const url = new URL(req.url);\n let p = url.pathname;\n if (p.startsWith(basePath)) p = p.slice(basePath.length);\n return p.split('/').filter(Boolean);\n}\n\nfunction writeTokens(cfg: HoleauthConfig, result: SignInResult): Response {\n const headers = new Headers({ 'content-type': 'application/json' });\n if (result.kind === 'ok') {\n writeAuthCookies(cfg, headers, result.tokens);\n setCookie(headers, serializeCookie(deleteCookie(cfg, 'pending')));\n return new Response(\n JSON.stringify({ ok: true, user: publicUser(result.user), csrfToken: result.tokens.csrfToken }),\n { status: 200, headers },\n );\n }\n writePending(cfg, headers, result.pendingToken);\n return new Response(\n JSON.stringify({\n ok: true,\n pending: true,\n pluginId: result.pluginId,\n pendingType: result.pluginId,\n pendingToken: result.pendingToken,\n userId: result.userId,\n data: result.data ?? null,\n }),\n { status: 200, headers },\n );\n}\n\nfunction publicUser(u: { id: string; email: string; name?: string | null; image?: string | null }) {\n return { id: u.id, email: u.email, name: u.name ?? null, image: u.image ?? null };\n}\n\n/* ───────────────────── Plugin route matching ───────────────────── */\n\nfunction matchPluginRoute(\n routes: readonly PluginRoute[],\n method: string,\n segs: string[],\n): { route: PluginRoute; params: Record<string, string> } | null {\n for (const r of routes) {\n if (r.method !== method) continue;\n const rSegs = r.path.split('/').filter(Boolean);\n if (rSegs.length !== segs.length) continue;\n const params: Record<string, string> = {};\n let ok = true;\n for (let i = 0; i < rSegs.length; i++) {\n const a = rSegs[i]!;\n const b = segs[i]!;\n if (a.startsWith(':')) {\n params[a.slice(1)] = decodeURIComponent(b);\n } else if (a !== b) {\n ok = false;\n break;\n }\n }\n if (ok) return { route: r, params };\n }\n return null;\n}\n\nasync function runPluginRoute(\n instance: HoleauthInstance,\n route: PluginRoute,\n req: Request,\n params: Record<string, string>,\n): Promise<Response> {\n const cfg = instance.config;\n const registry = getRegistry(instance);\n\n const jar = parseCookies(req.headers.get('cookie'));\n const responseHeaders = new Headers();\n const meta = getMeta(req);\n\n if (route.requireCsrf) {\n if (!checkCsrf(req, cfg)) throw new CsrfError();\n }\n\n const session = await (async () => {\n const at = readCookie(req, cfg, 'access');\n return at ? instance.getSession(at) : null;\n })();\n\n if (route.requireAuth && !session) {\n return json({ error: { code: 'UNAUTHENTICATED', message: 'authentication required' } }, { status: 401 });\n }\n\n const body = req.method === 'POST' ? await parseBody(req) : {};\n const ctx: PluginRouteContext = {\n req,\n body: { ...body, ...params },\n responseHeaders,\n cookies: { get: (name) => jar[name] },\n setCookie(spec) {\n const secure = (cfg.tokens?.cookieSecure ?? ((globalThis as { process?: { env?: { NODE_ENV?: string } } }).process?.env?.NODE_ENV === 'production'));\n const parts = [`${spec.name}=${encodeURIComponent(spec.value)}`];\n parts.push(`Path=${spec.path ?? '/'}`);\n if (spec.maxAge !== undefined) parts.push(`Max-Age=${spec.maxAge}`);\n if (spec.httpOnly ?? true) parts.push('HttpOnly');\n if (secure) parts.push('Secure');\n const ss = spec.sameSite ?? cfg.tokens?.sameSite ?? 'lax';\n parts.push(`SameSite=${ss.charAt(0).toUpperCase()}${ss.slice(1)}`);\n setCookie(responseHeaders, parts.join('; '));\n },\n async getSession() {\n return session;\n },\n meta,\n plugin: registry.ctx,\n };\n\n const res = await route.handler(ctx);\n // Merge any headers the plugin appended into the returned response.\n if (responseHeaders.has('Set-Cookie')) {\n const merged = new Headers(res.headers);\n responseHeaders.forEach((v, k) => {\n if (k.toLowerCase() === 'set-cookie') merged.append('Set-Cookie', v);\n else merged.set(k, v);\n });\n return new Response(res.body, { status: res.status, statusText: res.statusText, headers: merged });\n }\n return res;\n}\n\n/* ─────────────────────────── Dispatcher ─────────────────────────── */\n\nexport interface DispatchOptions {\n /** Used to strip the prefix from pathnames. Default '/api/auth'. */\n basePath?: string;\n /** Default post-signin redirect destination (SSO callback). */\n defaultRedirect?: string;\n}\n\n/**\n * Build the unified GET/POST dispatcher. Mounted under `/api/auth/[...holeauth]`.\n *\n * Core routes take precedence; plugin routes are matched only if no core\n * route accepts the request.\n */\nexport function createDispatcher(\n instance: HoleauthInstance,\n opts: DispatchOptions = {},\n): (req: Request) => Promise<Response> {\n const basePath = opts.basePath ?? '/api/auth';\n const cfg = instance.config;\n const registry = getRegistry(instance);\n\n return async function dispatch(req: Request): Promise<Response> {\n const segs = pathSegments(req, basePath);\n const method = req.method.toUpperCase();\n\n try {\n // ── GET /session ─────────────────────────────────────────\n if (method === 'GET' && segs[0] === 'session' && !segs[1]) {\n const at = readCookie(req, cfg, 'access');\n const session = at ? await instance.getSession(at) : null;\n return json({ session });\n }\n\n // ── GET /csrf ────────────────────────────────────────────\n if (method === 'GET' && segs[0] === 'csrf' && !segs[1]) {\n const existing = readCookie(req, cfg, 'csrf');\n return json({ csrfToken: existing ?? null });\n }\n\n // ── GET /invite/info?token=... ───────────────────────────\n if (method === 'GET' && segs[0] === 'invite' && segs[1] === 'info' && !segs[2]) {\n const url = new URL(req.url);\n const token = url.searchParams.get('token') ?? '';\n if (!token) return json({ error: { code: 'MISSING_TOKEN', message: 'token required' } }, { status: 400 });\n const info = await instance.getInviteInfo({ token });\n // Expose only fields intended for public pre-fill.\n return json({\n invite: {\n email: info.email,\n name: info.name ?? null,\n expiresAt: info.expiresAt,\n identifier: info.identifier,\n },\n });\n }\n\n // ── GET /invite/list ─────────────────────────────────────\n if (method === 'GET' && segs[0] === 'invite' && segs[1] === 'list' && !segs[2]) {\n const at = readCookie(req, cfg, 'access');\n const s = at ? await instance.getSession(at) : null;\n if (!s) return json({ error: { code: 'UNAUTHENTICATED' } }, { status: 401 });\n const invites = await instance.listInvites();\n return json({ invites });\n }\n\n // ── GET /authorize/:provider ─────────────────────────────\n if (method === 'GET' && segs[0] === 'authorize' && segs[1]) {\n const { url, state, codeVerifier } = await instance.sso.authorize(segs[1]);\n const headers = new Headers({ location: url });\n setCookie(headers, serializeCookie(buildCookie(cfg, {\n kind: 'oauthState', value: state, maxAge: 600, sameSite: 'lax',\n })));\n setCookie(headers, serializeCookie(buildCookie(cfg, {\n kind: 'oauthPkce', value: codeVerifier, maxAge: 600, sameSite: 'lax',\n })));\n return new Response(null, { status: 302, headers });\n }\n\n // ── GET /callback/:provider?code=&state= ─────────────────\n if (method === 'GET' && segs[0] === 'callback' && segs[1]) {\n const url = new URL(req.url);\n const code = url.searchParams.get('code') ?? '';\n const state = url.searchParams.get('state') ?? '';\n const jar = parseCookies(req.headers.get('cookie'));\n const storedState = jar[cookieName(cfg, 'oauthState')];\n const codeVerifier = jar[cookieName(cfg, 'oauthPkce')];\n if (!state || !storedState || state !== storedState || !codeVerifier) {\n return json({ error: { code: 'SSO_STATE_MISMATCH', message: 'state/pkce invalid' } }, { status: 400 });\n }\n const meta = getMeta(req);\n const { user, tokens } = await instance.sso.callback(segs[1], {\n code, state, codeVerifier, ip: meta.ip, userAgent: meta.userAgent,\n });\n const headers = new Headers({ location: opts.defaultRedirect ?? '/dashboard' });\n writeAuthCookies(cfg, headers, tokens);\n setCookie(headers, serializeCookie(deleteCookie(cfg, 'oauthState')));\n setCookie(headers, serializeCookie(deleteCookie(cfg, 'oauthPkce')));\n void user;\n return new Response(null, { status: 302, headers });\n }\n\n if (method === 'POST') {\n // POST /register\n if (segs[0] === 'register' && !segs[1]) {\n const body = await parseBody(req);\n const user = await instance.register({\n email: String(body.email ?? ''),\n password: String(body.password ?? ''),\n name: body.name ? String(body.name) : undefined,\n });\n return json({ ok: true, user: publicUser(user) });\n }\n\n // POST /signin (password)\n if (segs[0] === 'signin' && !segs[1]) {\n const body = await parseBody(req);\n const meta = getMeta(req);\n const result = await instance.signIn({\n email: String(body.email ?? ''),\n password: String(body.password ?? ''),\n ip: meta.ip, userAgent: meta.userAgent,\n });\n return writeTokens(cfg, result);\n }\n\n // POST /signout\n if (segs[0] === 'signout' && !segs[1]) {\n if (!checkCsrf(req, cfg)) throw new CsrfError();\n const at = readCookie(req, cfg, 'access');\n const rt = readCookie(req, cfg, 'refresh');\n await instance.signOut({ accessToken: at, refreshToken: rt });\n const headers = new Headers({ 'content-type': 'application/json' });\n clearAuthCookies(cfg, headers);\n return new Response(JSON.stringify({ ok: true }), { status: 200, headers });\n }\n\n // POST /refresh\n if (segs[0] === 'refresh' && !segs[1]) {\n const rt = readCookie(req, cfg, 'refresh');\n if (!rt) return json({ error: { code: 'NO_REFRESH', message: 'no refresh token' } }, { status: 401 });\n const meta = getMeta(req);\n const tokens = await instance.refresh({ refreshToken: rt, ip: meta.ip, userAgent: meta.userAgent });\n const headers = new Headers({ 'content-type': 'application/json' });\n writeAuthCookies(cfg, headers, tokens);\n return new Response(JSON.stringify({ ok: true, csrfToken: tokens.csrfToken }), { status: 200, headers });\n }\n\n // POST /password/change\n if (segs[0] === 'password' && segs[1] === 'change' && !segs[2]) {\n if (!checkCsrf(req, cfg)) throw new CsrfError();\n const at = readCookie(req, cfg, 'access');\n const s = at ? await instance.getSession(at) : null;\n if (!s) return json({ error: { code: 'UNAUTHENTICATED' } }, { status: 401 });\n const body = await parseBody(req);\n await instance.changePassword({\n userId: s.userId,\n currentPassword: String(body.currentPassword ?? ''),\n newPassword: String(body.newPassword ?? ''),\n revokeOtherSessions: body.revokeOtherSessions !== false,\n });\n return json({ ok: true });\n }\n\n // POST /password/reset/request\n if (segs[0] === 'password' && segs[1] === 'reset' && segs[2] === 'request' && !segs[3]) {\n const body = await parseBody(req);\n await instance.requestPasswordReset({ email: String(body.email ?? '') });\n // Do not echo token — consumer is expected to have delivered it out-of-band.\n return json({ ok: true });\n }\n\n // POST /password/reset/consume\n if (segs[0] === 'password' && segs[1] === 'reset' && segs[2] === 'consume' && !segs[3]) {\n const body = await parseBody(req);\n await instance.consumePasswordReset({\n email: String(body.email ?? ''),\n token: String(body.token ?? ''),\n newPassword: String(body.newPassword ?? ''),\n });\n return json({ ok: true });\n }\n\n // POST /invite/create (auth + CSRF)\n if (segs[0] === 'invite' && segs[1] === 'create' && !segs[2]) {\n if (!checkCsrf(req, cfg)) throw new CsrfError();\n const at = readCookie(req, cfg, 'access');\n const s = at ? await instance.getSession(at) : null;\n if (!s) return json({ error: { code: 'UNAUTHENTICATED' } }, { status: 401 });\n const body = await parseBody(req);\n const result = await instance.createInvite({\n email: String(body.email ?? ''),\n name: body.name != null ? String(body.name) : undefined,\n groupIds: Array.isArray(body.groupIds) ? (body.groupIds as unknown[]).map(String) : undefined,\n metadata: (body.metadata ?? null) as Record<string, unknown> | null,\n ttlSeconds: typeof body.ttlSeconds === 'number' ? body.ttlSeconds : undefined,\n invitedBy: s.userId,\n });\n return json({ ok: true, invite: result });\n }\n\n // POST /invite/consume (public)\n if (segs[0] === 'invite' && segs[1] === 'consume' && !segs[2]) {\n const body = await parseBody(req);\n const meta = getMeta(req);\n const result = await instance.consumeInvite({\n token: String(body.token ?? ''),\n password: String(body.password ?? ''),\n name: body.name != null ? String(body.name) : undefined,\n autoSignIn: body.autoSignIn !== false,\n ip: meta.ip,\n userAgent: meta.userAgent,\n });\n if (result.tokens) {\n const headers = new Headers({ 'content-type': 'application/json' });\n writeAuthCookies(cfg, headers, result.tokens);\n return new Response(\n JSON.stringify({\n ok: true,\n user: publicUser(result.user),\n csrfToken: result.tokens.csrfToken,\n groupIds: result.groupIds ?? [],\n }),\n { status: 200, headers },\n );\n }\n return json({ ok: true, user: publicUser(result.user), groupIds: result.groupIds ?? [] });\n }\n\n // POST /invite/revoke (auth + CSRF)\n if (segs[0] === 'invite' && segs[1] === 'revoke' && !segs[2]) {\n if (!checkCsrf(req, cfg)) throw new CsrfError();\n const at = readCookie(req, cfg, 'access');\n const s = at ? await instance.getSession(at) : null;\n if (!s) return json({ error: { code: 'UNAUTHENTICATED' } }, { status: 401 });\n const body = await parseBody(req);\n await instance.revokeInvite({ identifier: String(body.identifier ?? '') });\n return json({ ok: true });\n }\n }\n\n // ── Plugin routes ────────────────────────────────────────\n const match = matchPluginRoute(registry.routes, method, segs);\n if (match) {\n return runPluginRoute(instance, match.route, req, match.params);\n }\n\n return json({ error: { code: 'NOT_FOUND', message: 'route not found' } }, { status: 404 });\n } catch (e) {\n return errorResponse(e);\n }\n };\n}\n","import type { HoleauthConfig, IssuedTokens } from '@holeauth/core';\nimport {\n buildCookie,\n deleteCookie,\n serializeCookie,\n cookieName,\n verifyCsrf,\n CSRF_HEADER,\n} from '@holeauth/core/cookies';\n\n/** Append one Set-Cookie header entry. Headers.append() preserves multiple values. */\nexport function setCookie(headers: Headers, cookie: string): void {\n headers.append('Set-Cookie', cookie);\n}\n\n/**\n * Apply a freshly-issued token bundle to a Response. Writes access + refresh\n * (httpOnly) plus the JS-readable CSRF cookie.\n */\nexport function writeAuthCookies(cfg: HoleauthConfig, headers: Headers, tokens: IssuedTokens): void {\n const accessTtl = cfg.tokens?.accessTtl ?? 900;\n const refreshTtl = cfg.tokens?.refreshTtl ?? 2592000;\n\n setCookie(\n headers,\n serializeCookie(buildCookie(cfg, { kind: 'access', value: tokens.accessToken, maxAge: accessTtl })),\n );\n setCookie(\n headers,\n serializeCookie(buildCookie(cfg, { kind: 'refresh', value: tokens.refreshToken, maxAge: refreshTtl })),\n );\n setCookie(\n headers,\n serializeCookie(buildCookie(cfg, { kind: 'csrf', value: tokens.csrfToken, maxAge: refreshTtl, httpOnly: false })),\n );\n}\n\nexport function clearAuthCookies(cfg: HoleauthConfig, headers: Headers): void {\n setCookie(headers, serializeCookie(deleteCookie(cfg, 'access')));\n setCookie(headers, serializeCookie(deleteCookie(cfg, 'refresh')));\n setCookie(headers, serializeCookie(deleteCookie(cfg, 'csrf')));\n setCookie(headers, serializeCookie(deleteCookie(cfg, 'pending')));\n}\n\nexport function writePending(cfg: HoleauthConfig, headers: Headers, pendingToken: string): void {\n const ttl = cfg.tokens?.pendingTtl ?? 300;\n setCookie(\n headers,\n serializeCookie(buildCookie(cfg, { kind: 'pending', value: pendingToken, maxAge: ttl })),\n );\n}\n\n/** Parse a Cookie header into a map. Next gives us a cookies API but we also\n * work off raw Request here for edge compatibility. */\nexport function parseCookies(header: string | null): Record<string, string> {\n const out: Record<string, string> = {};\n if (!header) return out;\n for (const part of header.split(';')) {\n const i = part.indexOf('=');\n if (i < 0) continue;\n const k = part.slice(0, i).trim();\n const v = decodeURIComponent(part.slice(i + 1).trim());\n if (k) out[k] = v;\n }\n return out;\n}\n\nexport function readCookie(req: Request, cfg: HoleauthConfig, kind: Parameters<typeof cookieName>[1]): string | undefined {\n const jar = parseCookies(req.headers.get('cookie'));\n return jar[cookieName(cfg, kind)];\n}\n\n/** Returns true if the double-submit CSRF check passes. */\nexport function checkCsrf(req: Request, cfg: HoleauthConfig): boolean {\n const cookie = readCookie(req, cfg, 'csrf');\n const header = req.headers.get(CSRF_HEADER);\n return verifyCsrf(cookie, header ?? undefined);\n}\n"],"mappings":";AAAA,SAAS,YAAkD;AAC3D;AAAA,EACE;AAAA,OAMK;AACP,SAAS,sCAAsC;AAC/C,SAAS,cAAAA,mBAAkB;;;ACT3B,SAAS,eAAe,iBAAiB;AACzC,SAAS,mBAAmB;;;ACD5B;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OACK;AAGA,SAAS,UAAU,SAAkB,QAAsB;AAChE,UAAQ,OAAO,cAAc,MAAM;AACrC;AAMO,SAAS,iBAAiB,KAAqB,SAAkB,QAA4B;AAClG,QAAM,YAAY,IAAI,QAAQ,aAAa;AAC3C,QAAM,aAAa,IAAI,QAAQ,cAAc;AAE7C;AAAA,IACE;AAAA,IACA,gBAAgB,YAAY,KAAK,EAAE,MAAM,UAAU,OAAO,OAAO,aAAa,QAAQ,UAAU,CAAC,CAAC;AAAA,EACpG;AACA;AAAA,IACE;AAAA,IACA,gBAAgB,YAAY,KAAK,EAAE,MAAM,WAAW,OAAO,OAAO,cAAc,QAAQ,WAAW,CAAC,CAAC;AAAA,EACvG;AACA;AAAA,IACE;AAAA,IACA,gBAAgB,YAAY,KAAK,EAAE,MAAM,QAAQ,OAAO,OAAO,WAAW,QAAQ,YAAY,UAAU,MAAM,CAAC,CAAC;AAAA,EAClH;AACF;AAEO,SAAS,iBAAiB,KAAqB,SAAwB;AAC5E,YAAU,SAAS,gBAAgB,aAAa,KAAK,QAAQ,CAAC,CAAC;AAC/D,YAAU,SAAS,gBAAgB,aAAa,KAAK,SAAS,CAAC,CAAC;AAChE,YAAU,SAAS,gBAAgB,aAAa,KAAK,MAAM,CAAC,CAAC;AAC7D,YAAU,SAAS,gBAAgB,aAAa,KAAK,SAAS,CAAC,CAAC;AAClE;AAEO,SAAS,aAAa,KAAqB,SAAkB,cAA4B;AAC9F,QAAM,MAAM,IAAI,QAAQ,cAAc;AACtC;AAAA,IACE;AAAA,IACA,gBAAgB,YAAY,KAAK,EAAE,MAAM,WAAW,OAAO,cAAc,QAAQ,IAAI,CAAC,CAAC;AAAA,EACzF;AACF;AAIO,SAAS,aAAa,QAA+C;AAC1E,QAAM,MAA8B,CAAC;AACrC,MAAI,CAAC,OAAQ,QAAO;AACpB,aAAW,QAAQ,OAAO,MAAM,GAAG,GAAG;AACpC,UAAM,IAAI,KAAK,QAAQ,GAAG;AAC1B,QAAI,IAAI,EAAG;AACX,UAAM,IAAI,KAAK,MAAM,GAAG,CAAC,EAAE,KAAK;AAChC,UAAM,IAAI,mBAAmB,KAAK,MAAM,IAAI,CAAC,EAAE,KAAK,CAAC;AACrD,QAAI,EAAG,KAAI,CAAC,IAAI;AAAA,EAClB;AACA,SAAO;AACT;AAEO,SAAS,WAAW,KAAc,KAAqB,MAA4D;AACxH,QAAM,MAAM,aAAa,IAAI,QAAQ,IAAI,QAAQ,CAAC;AAClD,SAAO,IAAI,WAAW,KAAK,IAAI,CAAC;AAClC;AAGO,SAAS,UAAU,KAAc,KAA8B;AACpE,QAAM,SAAS,WAAW,KAAK,KAAK,MAAM;AAC1C,QAAM,SAAS,IAAI,QAAQ,IAAI,WAAW;AAC1C,SAAO,WAAW,QAAQ,UAAU,MAAS;AAC/C;;;ADjEA;AAAA,EACE,eAAAC;AAAA,EACA,mBAAAC;AAAA,EACA,gBAAAC;AAAA,EACA,cAAAC;AAAA,OACK;AAEP,SAAS,KAAK,MAAe,OAAqB,CAAC,GAAa;AAC9D,QAAM,UAAU,IAAI,QAAQ,KAAK,OAAO;AACxC,UAAQ,IAAI,gBAAgB,kBAAkB;AAC9C,SAAO,IAAI,SAAS,KAAK,UAAU,IAAI,GAAG,EAAE,GAAG,MAAM,QAAQ,CAAC;AAChE;AAEA,SAAS,cAAc,GAAsB;AAC3C,MAAI,aAAa,eAAe;AAC9B,WAAO,KAAK,EAAE,OAAO,EAAE,MAAM,EAAE,MAAM,SAAS,EAAE,QAAQ,EAAE,GAAG,EAAE,QAAQ,EAAE,OAAO,CAAC;AAAA,EACnF;AAKA,MACE,aAAa,SACb,EAAE,SAAS,mBACX,OAAQ,EAAyB,SAAS,YAC1C,OAAQ,EAA2B,WAAW,UAC9C;AACA,UAAM,MAAM;AACZ,WAAO,KAAK,EAAE,OAAO,EAAE,MAAM,IAAI,MAAM,SAAS,IAAI,QAAQ,EAAE,GAAG,EAAE,QAAQ,IAAI,OAAO,CAAC;AAAA,EACzF;AAGA,UAAQ,MAAM,mDAAmD,CAAC;AAClE,SAAO,KAAK,EAAE,OAAO,EAAE,MAAM,YAAY,SAAS,iBAAiB,EAAE,GAAG,EAAE,QAAQ,IAAI,CAAC;AACzF;AAEA,SAAS,QAAQ,KAAmD;AAClE,SAAO;AAAA,IACL,IACE,IAAI,QAAQ,IAAI,iBAAiB,GAAG,MAAM,GAAG,EAAE,CAAC,GAAG,KAAK,KACxD,IAAI,QAAQ,IAAI,WAAW,KAC3B;AAAA,IACF,WAAW,IAAI,QAAQ,IAAI,YAAY,KAAK;AAAA,EAC9C;AACF;AAEA,eAAe,UAAU,KAAgD;AACvE,MAAI;AAAE,WAAQ,MAAM,IAAI,KAAK;AAAA,EAA+B,QAAQ;AAAE,WAAO,CAAC;AAAA,EAAG;AACnF;AAEA,SAAS,aAAa,KAAc,UAA4B;AAC9D,QAAM,MAAM,IAAI,IAAI,IAAI,GAAG;AAC3B,MAAI,IAAI,IAAI;AACZ,MAAI,EAAE,WAAW,QAAQ,EAAG,KAAI,EAAE,MAAM,SAAS,MAAM;AACvD,SAAO,EAAE,MAAM,GAAG,EAAE,OAAO,OAAO;AACpC;AAEA,SAAS,YAAY,KAAqB,QAAgC;AACxE,QAAM,UAAU,IAAI,QAAQ,EAAE,gBAAgB,mBAAmB,CAAC;AAClE,MAAI,OAAO,SAAS,MAAM;AACxB,qBAAiB,KAAK,SAAS,OAAO,MAAM;AAC5C,cAAU,SAASF,iBAAgBC,cAAa,KAAK,SAAS,CAAC,CAAC;AAChE,WAAO,IAAI;AAAA,MACT,KAAK,UAAU,EAAE,IAAI,MAAM,MAAM,WAAW,OAAO,IAAI,GAAG,WAAW,OAAO,OAAO,UAAU,CAAC;AAAA,MAC9F,EAAE,QAAQ,KAAK,QAAQ;AAAA,IACzB;AAAA,EACF;AACA,eAAa,KAAK,SAAS,OAAO,YAAY;AAC9C,SAAO,IAAI;AAAA,IACT,KAAK,UAAU;AAAA,MACb,IAAI;AAAA,MACJ,SAAS;AAAA,MACT,UAAU,OAAO;AAAA,MACjB,aAAa,OAAO;AAAA,MACpB,cAAc,OAAO;AAAA,MACrB,QAAQ,OAAO;AAAA,MACf,MAAM,OAAO,QAAQ;AAAA,IACvB,CAAC;AAAA,IACD,EAAE,QAAQ,KAAK,QAAQ;AAAA,EACzB;AACF;AAEA,SAAS,WAAW,GAA+E;AACjG,SAAO,EAAE,IAAI,EAAE,IAAI,OAAO,EAAE,OAAO,MAAM,EAAE,QAAQ,MAAM,OAAO,EAAE,SAAS,KAAK;AAClF;AAIA,SAAS,iBACP,QACA,QACA,MAC+D;AAC/D,aAAW,KAAK,QAAQ;AACtB,QAAI,EAAE,WAAW,OAAQ;AACzB,UAAM,QAAQ,EAAE,KAAK,MAAM,GAAG,EAAE,OAAO,OAAO;AAC9C,QAAI,MAAM,WAAW,KAAK,OAAQ;AAClC,UAAM,SAAiC,CAAC;AACxC,QAAI,KAAK;AACT,aAAS,IAAI,GAAG,IAAI,MAAM,QAAQ,KAAK;AACrC,YAAM,IAAI,MAAM,CAAC;AACjB,YAAM,IAAI,KAAK,CAAC;AAChB,UAAI,EAAE,WAAW,GAAG,GAAG;AACrB,eAAO,EAAE,MAAM,CAAC,CAAC,IAAI,mBAAmB,CAAC;AAAA,MAC3C,WAAW,MAAM,GAAG;AAClB,aAAK;AACL;AAAA,MACF;AAAA,IACF;AACA,QAAI,GAAI,QAAO,EAAE,OAAO,GAAG,OAAO;AAAA,EACpC;AACA,SAAO;AACT;AAEA,eAAe,eACb,UACA,OACA,KACA,QACmB;AACnB,QAAM,MAAM,SAAS;AACrB,QAAM,WAAW,YAAY,QAAQ;AAErC,QAAM,MAAM,aAAa,IAAI,QAAQ,IAAI,QAAQ,CAAC;AAClD,QAAM,kBAAkB,IAAI,QAAQ;AACpC,QAAM,OAAO,QAAQ,GAAG;AAExB,MAAI,MAAM,aAAa;AACrB,QAAI,CAAC,UAAU,KAAK,GAAG,EAAG,OAAM,IAAI,UAAU;AAAA,EAChD;AAEA,QAAM,UAAU,OAAO,YAAY;AACjC,UAAM,KAAK,WAAW,KAAK,KAAK,QAAQ;AACxC,WAAO,KAAK,SAAS,WAAW,EAAE,IAAI;AAAA,EACxC,GAAG;AAEH,MAAI,MAAM,eAAe,CAAC,SAAS;AACjC,WAAO,KAAK,EAAE,OAAO,EAAE,MAAM,mBAAmB,SAAS,0BAA0B,EAAE,GAAG,EAAE,QAAQ,IAAI,CAAC;AAAA,EACzG;AAEA,QAAM,OAAO,IAAI,WAAW,SAAS,MAAM,UAAU,GAAG,IAAI,CAAC;AAC7D,QAAM,MAA0B;AAAA,IAC9B;AAAA,IACA,MAAM,EAAE,GAAG,MAAM,GAAG,OAAO;AAAA,IAC3B;AAAA,IACA,SAAS,EAAE,KAAK,CAAC,SAAS,IAAI,IAAI,EAAE;AAAA,IACpC,UAAU,MAAM;AACd,YAAM,SAAU,IAAI,QAAQ,gBAAkB,WAA6D,SAAS,KAAK,aAAa;AACtI,YAAM,QAAQ,CAAC,GAAG,KAAK,IAAI,IAAI,mBAAmB,KAAK,KAAK,CAAC,EAAE;AAC/D,YAAM,KAAK,QAAQ,KAAK,QAAQ,GAAG,EAAE;AACrC,UAAI,KAAK,WAAW,OAAW,OAAM,KAAK,WAAW,KAAK,MAAM,EAAE;AAClE,UAAI,KAAK,YAAY,KAAM,OAAM,KAAK,UAAU;AAChD,UAAI,OAAQ,OAAM,KAAK,QAAQ;AAC/B,YAAM,KAAK,KAAK,YAAY,IAAI,QAAQ,YAAY;AACpD,YAAM,KAAK,YAAY,GAAG,OAAO,CAAC,EAAE,YAAY,CAAC,GAAG,GAAG,MAAM,CAAC,CAAC,EAAE;AACjE,gBAAU,iBAAiB,MAAM,KAAK,IAAI,CAAC;AAAA,IAC7C;AAAA,IACA,MAAM,aAAa;AACjB,aAAO;AAAA,IACT;AAAA,IACA;AAAA,IACA,QAAQ,SAAS;AAAA,EACnB;AAEA,QAAM,MAAM,MAAM,MAAM,QAAQ,GAAG;AAEnC,MAAI,gBAAgB,IAAI,YAAY,GAAG;AACrC,UAAM,SAAS,IAAI,QAAQ,IAAI,OAAO;AACtC,oBAAgB,QAAQ,CAAC,GAAG,MAAM;AAChC,UAAI,EAAE,YAAY,MAAM,aAAc,QAAO,OAAO,cAAc,CAAC;AAAA,UAC9D,QAAO,IAAI,GAAG,CAAC;AAAA,IACtB,CAAC;AACD,WAAO,IAAI,SAAS,IAAI,MAAM,EAAE,QAAQ,IAAI,QAAQ,YAAY,IAAI,YAAY,SAAS,OAAO,CAAC;AAAA,EACnG;AACA,SAAO;AACT;AAiBO,SAAS,iBACd,UACA,OAAwB,CAAC,GACY;AACrC,QAAM,WAAW,KAAK,YAAY;AAClC,QAAM,MAAM,SAAS;AACrB,QAAM,WAAW,YAAY,QAAQ;AAErC,SAAO,eAAe,SAAS,KAAiC;AAC9D,UAAM,OAAO,aAAa,KAAK,QAAQ;AACvC,UAAM,SAAS,IAAI,OAAO,YAAY;AAEtC,QAAI;AAEF,UAAI,WAAW,SAAS,KAAK,CAAC,MAAM,aAAa,CAAC,KAAK,CAAC,GAAG;AACzD,cAAM,KAAK,WAAW,KAAK,KAAK,QAAQ;AACxC,cAAM,UAAU,KAAK,MAAM,SAAS,WAAW,EAAE,IAAI;AACrD,eAAO,KAAK,EAAE,QAAQ,CAAC;AAAA,MACzB;AAGA,UAAI,WAAW,SAAS,KAAK,CAAC,MAAM,UAAU,CAAC,KAAK,CAAC,GAAG;AACtD,cAAM,WAAW,WAAW,KAAK,KAAK,MAAM;AAC5C,eAAO,KAAK,EAAE,WAAW,YAAY,KAAK,CAAC;AAAA,MAC7C;AAGA,UAAI,WAAW,SAAS,KAAK,CAAC,MAAM,YAAY,KAAK,CAAC,MAAM,UAAU,CAAC,KAAK,CAAC,GAAG;AAC9E,cAAM,MAAM,IAAI,IAAI,IAAI,GAAG;AAC3B,cAAM,QAAQ,IAAI,aAAa,IAAI,OAAO,KAAK;AAC/C,YAAI,CAAC,MAAO,QAAO,KAAK,EAAE,OAAO,EAAE,MAAM,iBAAiB,SAAS,iBAAiB,EAAE,GAAG,EAAE,QAAQ,IAAI,CAAC;AACxG,cAAM,OAAO,MAAM,SAAS,cAAc,EAAE,MAAM,CAAC;AAEnD,eAAO,KAAK;AAAA,UACV,QAAQ;AAAA,YACN,OAAO,KAAK;AAAA,YACZ,MAAM,KAAK,QAAQ;AAAA,YACnB,WAAW,KAAK;AAAA,YAChB,YAAY,KAAK;AAAA,UACnB;AAAA,QACF,CAAC;AAAA,MACH;AAGA,UAAI,WAAW,SAAS,KAAK,CAAC,MAAM,YAAY,KAAK,CAAC,MAAM,UAAU,CAAC,KAAK,CAAC,GAAG;AAC9E,cAAM,KAAK,WAAW,KAAK,KAAK,QAAQ;AACxC,cAAM,IAAI,KAAK,MAAM,SAAS,WAAW,EAAE,IAAI;AAC/C,YAAI,CAAC,EAAG,QAAO,KAAK,EAAE,OAAO,EAAE,MAAM,kBAAkB,EAAE,GAAG,EAAE,QAAQ,IAAI,CAAC;AAC3E,cAAM,UAAU,MAAM,SAAS,YAAY;AAC3C,eAAO,KAAK,EAAE,QAAQ,CAAC;AAAA,MACzB;AAGA,UAAI,WAAW,SAAS,KAAK,CAAC,MAAM,eAAe,KAAK,CAAC,GAAG;AAC1D,cAAM,EAAE,KAAK,OAAO,aAAa,IAAI,MAAM,SAAS,IAAI,UAAU,KAAK,CAAC,CAAC;AACzE,cAAM,UAAU,IAAI,QAAQ,EAAE,UAAU,IAAI,CAAC;AAC7C,kBAAU,SAASD,iBAAgBD,aAAY,KAAK;AAAA,UAClD,MAAM;AAAA,UAAc,OAAO;AAAA,UAAO,QAAQ;AAAA,UAAK,UAAU;AAAA,QAC3D,CAAC,CAAC,CAAC;AACH,kBAAU,SAASC,iBAAgBD,aAAY,KAAK;AAAA,UAClD,MAAM;AAAA,UAAa,OAAO;AAAA,UAAc,QAAQ;AAAA,UAAK,UAAU;AAAA,QACjE,CAAC,CAAC,CAAC;AACH,eAAO,IAAI,SAAS,MAAM,EAAE,QAAQ,KAAK,QAAQ,CAAC;AAAA,MACpD;AAGA,UAAI,WAAW,SAAS,KAAK,CAAC,MAAM,cAAc,KAAK,CAAC,GAAG;AACzD,cAAM,MAAM,IAAI,IAAI,IAAI,GAAG;AAC3B,cAAM,OAAO,IAAI,aAAa,IAAI,MAAM,KAAK;AAC7C,cAAM,QAAQ,IAAI,aAAa,IAAI,OAAO,KAAK;AAC/C,cAAM,MAAM,aAAa,IAAI,QAAQ,IAAI,QAAQ,CAAC;AAClD,cAAM,cAAc,IAAIG,YAAW,KAAK,YAAY,CAAC;AACrD,cAAM,eAAe,IAAIA,YAAW,KAAK,WAAW,CAAC;AACrD,YAAI,CAAC,SAAS,CAAC,eAAe,UAAU,eAAe,CAAC,cAAc;AACpE,iBAAO,KAAK,EAAE,OAAO,EAAE,MAAM,sBAAsB,SAAS,qBAAqB,EAAE,GAAG,EAAE,QAAQ,IAAI,CAAC;AAAA,QACvG;AACA,cAAM,OAAO,QAAQ,GAAG;AACxB,cAAM,EAAE,MAAM,OAAO,IAAI,MAAM,SAAS,IAAI,SAAS,KAAK,CAAC,GAAG;AAAA,UAC5D;AAAA,UAAM;AAAA,UAAO;AAAA,UAAc,IAAI,KAAK;AAAA,UAAI,WAAW,KAAK;AAAA,QAC1D,CAAC;AACD,cAAM,UAAU,IAAI,QAAQ,EAAE,UAAU,KAAK,mBAAmB,aAAa,CAAC;AAC9E,yBAAiB,KAAK,SAAS,MAAM;AACrC,kBAAU,SAASF,iBAAgBC,cAAa,KAAK,YAAY,CAAC,CAAC;AACnE,kBAAU,SAASD,iBAAgBC,cAAa,KAAK,WAAW,CAAC,CAAC;AAClE,aAAK;AACL,eAAO,IAAI,SAAS,MAAM,EAAE,QAAQ,KAAK,QAAQ,CAAC;AAAA,MACpD;AAEA,UAAI,WAAW,QAAQ;AAErB,YAAI,KAAK,CAAC,MAAM,cAAc,CAAC,KAAK,CAAC,GAAG;AACtC,gBAAM,OAAO,MAAM,UAAU,GAAG;AAChC,gBAAM,OAAO,MAAM,SAAS,SAAS;AAAA,YACnC,OAAO,OAAO,KAAK,SAAS,EAAE;AAAA,YAC9B,UAAU,OAAO,KAAK,YAAY,EAAE;AAAA,YACpC,MAAM,KAAK,OAAO,OAAO,KAAK,IAAI,IAAI;AAAA,UACxC,CAAC;AACD,iBAAO,KAAK,EAAE,IAAI,MAAM,MAAM,WAAW,IAAI,EAAE,CAAC;AAAA,QAClD;AAGA,YAAI,KAAK,CAAC,MAAM,YAAY,CAAC,KAAK,CAAC,GAAG;AACpC,gBAAM,OAAO,MAAM,UAAU,GAAG;AAChC,gBAAM,OAAO,QAAQ,GAAG;AACxB,gBAAM,SAAS,MAAM,SAAS,OAAO;AAAA,YACnC,OAAO,OAAO,KAAK,SAAS,EAAE;AAAA,YAC9B,UAAU,OAAO,KAAK,YAAY,EAAE;AAAA,YACpC,IAAI,KAAK;AAAA,YAAI,WAAW,KAAK;AAAA,UAC/B,CAAC;AACD,iBAAO,YAAY,KAAK,MAAM;AAAA,QAChC;AAGA,YAAI,KAAK,CAAC,MAAM,aAAa,CAAC,KAAK,CAAC,GAAG;AACrC,cAAI,CAAC,UAAU,KAAK,GAAG,EAAG,OAAM,IAAI,UAAU;AAC9C,gBAAM,KAAK,WAAW,KAAK,KAAK,QAAQ;AACxC,gBAAM,KAAK,WAAW,KAAK,KAAK,SAAS;AACzC,gBAAM,SAAS,QAAQ,EAAE,aAAa,IAAI,cAAc,GAAG,CAAC;AAC5D,gBAAM,UAAU,IAAI,QAAQ,EAAE,gBAAgB,mBAAmB,CAAC;AAClE,2BAAiB,KAAK,OAAO;AAC7B,iBAAO,IAAI,SAAS,KAAK,UAAU,EAAE,IAAI,KAAK,CAAC,GAAG,EAAE,QAAQ,KAAK,QAAQ,CAAC;AAAA,QAC5E;AAGA,YAAI,KAAK,CAAC,MAAM,aAAa,CAAC,KAAK,CAAC,GAAG;AACrC,gBAAM,KAAK,WAAW,KAAK,KAAK,SAAS;AACzC,cAAI,CAAC,GAAI,QAAO,KAAK,EAAE,OAAO,EAAE,MAAM,cAAc,SAAS,mBAAmB,EAAE,GAAG,EAAE,QAAQ,IAAI,CAAC;AACpG,gBAAM,OAAO,QAAQ,GAAG;AACxB,gBAAM,SAAS,MAAM,SAAS,QAAQ,EAAE,cAAc,IAAI,IAAI,KAAK,IAAI,WAAW,KAAK,UAAU,CAAC;AAClG,gBAAM,UAAU,IAAI,QAAQ,EAAE,gBAAgB,mBAAmB,CAAC;AAClE,2BAAiB,KAAK,SAAS,MAAM;AACrC,iBAAO,IAAI,SAAS,KAAK,UAAU,EAAE,IAAI,MAAM,WAAW,OAAO,UAAU,CAAC,GAAG,EAAE,QAAQ,KAAK,QAAQ,CAAC;AAAA,QACzG;AAGA,YAAI,KAAK,CAAC,MAAM,cAAc,KAAK,CAAC,MAAM,YAAY,CAAC,KAAK,CAAC,GAAG;AAC9D,cAAI,CAAC,UAAU,KAAK,GAAG,EAAG,OAAM,IAAI,UAAU;AAC9C,gBAAM,KAAK,WAAW,KAAK,KAAK,QAAQ;AACxC,gBAAM,IAAI,KAAK,MAAM,SAAS,WAAW,EAAE,IAAI;AAC/C,cAAI,CAAC,EAAG,QAAO,KAAK,EAAE,OAAO,EAAE,MAAM,kBAAkB,EAAE,GAAG,EAAE,QAAQ,IAAI,CAAC;AAC3E,gBAAM,OAAO,MAAM,UAAU,GAAG;AAChC,gBAAM,SAAS,eAAe;AAAA,YAC5B,QAAQ,EAAE;AAAA,YACV,iBAAiB,OAAO,KAAK,mBAAmB,EAAE;AAAA,YAClD,aAAa,OAAO,KAAK,eAAe,EAAE;AAAA,YAC1C,qBAAqB,KAAK,wBAAwB;AAAA,UACpD,CAAC;AACD,iBAAO,KAAK,EAAE,IAAI,KAAK,CAAC;AAAA,QAC1B;AAGA,YAAI,KAAK,CAAC,MAAM,cAAc,KAAK,CAAC,MAAM,WAAW,KAAK,CAAC,MAAM,aAAa,CAAC,KAAK,CAAC,GAAG;AACtF,gBAAM,OAAO,MAAM,UAAU,GAAG;AAChC,gBAAM,SAAS,qBAAqB,EAAE,OAAO,OAAO,KAAK,SAAS,EAAE,EAAE,CAAC;AAEvE,iBAAO,KAAK,EAAE,IAAI,KAAK,CAAC;AAAA,QAC1B;AAGA,YAAI,KAAK,CAAC,MAAM,cAAc,KAAK,CAAC,MAAM,WAAW,KAAK,CAAC,MAAM,aAAa,CAAC,KAAK,CAAC,GAAG;AACtF,gBAAM,OAAO,MAAM,UAAU,GAAG;AAChC,gBAAM,SAAS,qBAAqB;AAAA,YAClC,OAAO,OAAO,KAAK,SAAS,EAAE;AAAA,YAC9B,OAAO,OAAO,KAAK,SAAS,EAAE;AAAA,YAC9B,aAAa,OAAO,KAAK,eAAe,EAAE;AAAA,UAC5C,CAAC;AACD,iBAAO,KAAK,EAAE,IAAI,KAAK,CAAC;AAAA,QAC1B;AAGA,YAAI,KAAK,CAAC,MAAM,YAAY,KAAK,CAAC,MAAM,YAAY,CAAC,KAAK,CAAC,GAAG;AAC5D,cAAI,CAAC,UAAU,KAAK,GAAG,EAAG,OAAM,IAAI,UAAU;AAC9C,gBAAM,KAAK,WAAW,KAAK,KAAK,QAAQ;AACxC,gBAAM,IAAI,KAAK,MAAM,SAAS,WAAW,EAAE,IAAI;AAC/C,cAAI,CAAC,EAAG,QAAO,KAAK,EAAE,OAAO,EAAE,MAAM,kBAAkB,EAAE,GAAG,EAAE,QAAQ,IAAI,CAAC;AAC3E,gBAAM,OAAO,MAAM,UAAU,GAAG;AAChC,gBAAM,SAAS,MAAM,SAAS,aAAa;AAAA,YACzC,OAAO,OAAO,KAAK,SAAS,EAAE;AAAA,YAC9B,MAAM,KAAK,QAAQ,OAAO,OAAO,KAAK,IAAI,IAAI;AAAA,YAC9C,UAAU,MAAM,QAAQ,KAAK,QAAQ,IAAK,KAAK,SAAuB,IAAI,MAAM,IAAI;AAAA,YACpF,UAAW,KAAK,YAAY;AAAA,YAC5B,YAAY,OAAO,KAAK,eAAe,WAAW,KAAK,aAAa;AAAA,YACpE,WAAW,EAAE;AAAA,UACf,CAAC;AACD,iBAAO,KAAK,EAAE,IAAI,MAAM,QAAQ,OAAO,CAAC;AAAA,QAC1C;AAGA,YAAI,KAAK,CAAC,MAAM,YAAY,KAAK,CAAC,MAAM,aAAa,CAAC,KAAK,CAAC,GAAG;AAC7D,gBAAM,OAAO,MAAM,UAAU,GAAG;AAChC,gBAAM,OAAO,QAAQ,GAAG;AACxB,gBAAM,SAAS,MAAM,SAAS,cAAc;AAAA,YAC1C,OAAO,OAAO,KAAK,SAAS,EAAE;AAAA,YAC9B,UAAU,OAAO,KAAK,YAAY,EAAE;AAAA,YACpC,MAAM,KAAK,QAAQ,OAAO,OAAO,KAAK,IAAI,IAAI;AAAA,YAC9C,YAAY,KAAK,eAAe;AAAA,YAChC,IAAI,KAAK;AAAA,YACT,WAAW,KAAK;AAAA,UAClB,CAAC;AACD,cAAI,OAAO,QAAQ;AACjB,kBAAM,UAAU,IAAI,QAAQ,EAAE,gBAAgB,mBAAmB,CAAC;AAClE,6BAAiB,KAAK,SAAS,OAAO,MAAM;AAC5C,mBAAO,IAAI;AAAA,cACT,KAAK,UAAU;AAAA,gBACb,IAAI;AAAA,gBACJ,MAAM,WAAW,OAAO,IAAI;AAAA,gBAC5B,WAAW,OAAO,OAAO;AAAA,gBACzB,UAAU,OAAO,YAAY,CAAC;AAAA,cAChC,CAAC;AAAA,cACD,EAAE,QAAQ,KAAK,QAAQ;AAAA,YACzB;AAAA,UACF;AACA,iBAAO,KAAK,EAAE,IAAI,MAAM,MAAM,WAAW,OAAO,IAAI,GAAG,UAAU,OAAO,YAAY,CAAC,EAAE,CAAC;AAAA,QAC1F;AAGA,YAAI,KAAK,CAAC,MAAM,YAAY,KAAK,CAAC,MAAM,YAAY,CAAC,KAAK,CAAC,GAAG;AAC5D,cAAI,CAAC,UAAU,KAAK,GAAG,EAAG,OAAM,IAAI,UAAU;AAC9C,gBAAM,KAAK,WAAW,KAAK,KAAK,QAAQ;AACxC,gBAAM,IAAI,KAAK,MAAM,SAAS,WAAW,EAAE,IAAI;AAC/C,cAAI,CAAC,EAAG,QAAO,KAAK,EAAE,OAAO,EAAE,MAAM,kBAAkB,EAAE,GAAG,EAAE,QAAQ,IAAI,CAAC;AAC3E,gBAAM,OAAO,MAAM,UAAU,GAAG;AAChC,gBAAM,SAAS,aAAa,EAAE,YAAY,OAAO,KAAK,cAAc,EAAE,EAAE,CAAC;AACzE,iBAAO,KAAK,EAAE,IAAI,KAAK,CAAC;AAAA,QAC1B;AAAA,MACF;AAGA,YAAM,QAAQ,iBAAiB,SAAS,QAAQ,QAAQ,IAAI;AAC5D,UAAI,OAAO;AACT,eAAO,eAAe,UAAU,MAAM,OAAO,KAAK,MAAM,MAAM;AAAA,MAChE;AAEA,aAAO,KAAK,EAAE,OAAO,EAAE,MAAM,aAAa,SAAS,kBAAkB,EAAE,GAAG,EAAE,QAAQ,IAAI,CAAC;AAAA,IAC3F,SAAS,GAAG;AACV,aAAO,cAAc,CAAC;AAAA,IACxB;AAAA,EACF;AACF;;;AD1aA,SAAS,kCAAAE,uCAAiE;AAwBnE,SAAS,eAGd,QACA,OAAwB,CAAC,GACF;AACvB,QAAM,OAAO,eAAe,MAAM;AAClC,QAAM,MAAM,kBAAkB,MAAM,IAAI;AACxC,SAAO,EAAE,GAAG,MAAM,IAAI;AACxB;AAGO,SAAS,kBAAkB,MAAwB,OAAwB,CAAC,GAAS;AAC1F,QAAM,WAAW,iBAAiB,MAAM,IAAI;AAC5C,QAAM,MAAM,IAAI,KAAK;AAMrB,MAAI,IAAI,KAAK,OAAO,MAAM;AACxB,UAAM,QAAQ,EAAE,IAAI;AAKpB,UAAM,SAAS,MAAM,SAAS,KAAK;AACnC,WAAO;AAAA,EACT,CAAC;AAED,SAAO;AACT;AAYO,SAAS,uBACd,MACyD;AACzD,SAAO,OAAO,GAAG,SAAS;AACxB,UAAM,UAAU,MAAM,WAAW,GAAG,IAAI;AACxC,MAAE,IAAI,mBAAmB,OAAO;AAChC,UAAM,KAAK;AAAA,EACb;AACF;AAGA,eAAsB,WACpB,GACA,MAC6B;AAC7B,QAAM,eAAe,EAAE,IAAI,OAAO,QAAQ,KAAK;AAC/C,QAAM,MAAM,aAAa,YAAY;AACrC,QAAM,QAAQ,IAAIC,YAAW,KAAK,QAAQ,QAAQ,CAAC;AACnD,MAAI,CAAC,MAAO,QAAO;AACnB,SAAO,KAAK,WAAW,KAAK;AAC9B;AAiBO,SAAS,0BAA0B,MAAwB;AAChE,SAAO,eAAe,cAAc,OAAgB,GAA0C;AAC5F,UAAM,EAAE,SAAS,WAAW,iBAAiB,IAAI,MAAM,+BAA+B,EAAE,IAAI,KAAK,IAAI;AACrG,eAAW,UAAU,kBAAkB;AACrC,QAAE,OAAO,cAAc,QAAQ,EAAE,QAAQ,KAAK,CAAC;AAAA,IACjD;AACA,WAAO,EAAE,GAAG,KAAK,EAAE,IAAI,KAAK,SAAS,WAAW,KAAK;AAAA,EACvD;AACF;","names":["cookieName","buildCookie","serializeCookie","deleteCookie","cookieName","getSessionOrRefreshFromRequest","cookieName"]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@holeauth/hono",
|
|
3
|
-
"version": "0.0
|
|
3
|
+
"version": "0.1.0-alpha.1",
|
|
4
4
|
"description": "Hono bindings for holeauth.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"author": "Robert Kratz",
|
|
@@ -36,7 +36,7 @@
|
|
|
36
36
|
"provenance": true
|
|
37
37
|
},
|
|
38
38
|
"dependencies": {
|
|
39
|
-
"@holeauth/core": "0.0
|
|
39
|
+
"@holeauth/core": "1.0.0-alpha.1"
|
|
40
40
|
},
|
|
41
41
|
"peerDependencies": {
|
|
42
42
|
"hono": "^4"
|