@rttnd/gau 0.7.4 → 1.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/chunk-GVRQST3R.js +1 -0
- package/dist/chunk-GVRQST3R.js.map +1 -0
- package/dist/chunk-IDBFAEA3.js +1 -0
- package/dist/chunk-IDBFAEA3.js.map +1 -0
- package/dist/src/client/solid/index.jsx +97 -16
- package/dist/src/client/svelte/index.svelte.js +1 -1
- package/dist/src/client/svelte/index.svelte.js.map +1 -1
- package/dist/src/client/token.d.ts +4 -0
- package/dist/src/client/token.d.ts.map +1 -1
- package/dist/src/client/vanilla/index.js +1 -1
- package/dist/src/core/cookies.d.ts +1 -0
- package/dist/src/core/cookies.d.ts.map +1 -1
- package/dist/src/core/handler.d.ts.map +1 -1
- package/dist/src/core/handlers/callback.d.ts.map +1 -1
- package/dist/src/core/handlers/index.d.ts +1 -0
- package/dist/src/core/handlers/index.d.ts.map +1 -1
- package/dist/src/core/handlers/index.js +1 -1
- package/dist/src/core/handlers/token.d.ts +3 -0
- package/dist/src/core/handlers/token.d.ts.map +1 -0
- package/dist/src/core/handlers/utils.d.ts.map +1 -1
- package/dist/src/core/index.js +1 -1
- package/dist/src/index.js +1 -1
- package/dist/src/jwt/index.js +1 -1
- package/dist/src/runtimes/index.js +1 -1
- package/dist/src/runtimes/tauri/index.d.ts +1 -1
- package/dist/src/runtimes/tauri/index.d.ts.map +1 -1
- package/dist/src/runtimes/tauri/index.js +1 -1
- package/dist/src/solidstart/index.js +1 -1
- package/dist/src/sveltekit/index.js +1 -1
- package/package.json +2 -7
- package/dist/chunk-H457ZXFC.js +0 -1
- package/dist/chunk-H457ZXFC.js.map +0 -1
- package/dist/chunk-LWY5YOPO.js +0 -1
- package/dist/chunk-LWY5YOPO.js.map +0 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../../src/client/token.ts","../../../../src/runtimes/tauri/index.ts","../../../../src/client/svelte/index.svelte.ts","../../../../src/core/cookies.ts","../../../../src/jwt/jwt.ts","../../../../src/oauth/utils.ts","../../../../src/core/index.ts","../../../../src/client/vanilla/index.ts"],"sourcesContent":["import { BROWSER } from 'esm-env'\n\nexport function storeSessionToken(token: string) {\n if (!BROWSER)\n return\n try {\n localStorage.setItem('gau-token', token)\n document.cookie = `__gau-session-token=${token}; path=/; max-age=31536000; samesite=lax; secure`\n }\n catch {}\n}\n\nexport function getSessionToken(): string | null {\n if (!BROWSER)\n return null\n return localStorage.getItem('gau-token')\n}\n\nexport function clearSessionToken() {\n if (!BROWSER)\n return\n try {\n localStorage.removeItem('gau-token')\n document.cookie = `__gau-session-token=; path=/; max-age=0`\n }\n catch {}\n}\n","import type { ProfileName, ProviderIds } from '../../core'\nimport { BROWSER } from 'esm-env'\nimport { getSessionToken } from '../../client/token'\n\nexport function isTauri(): boolean {\n return BROWSER && '__TAURI_INTERNALS__' in globalThis\n}\n\nexport async function signInWithTauri<const TAuth = unknown, P extends ProviderIds<TAuth> = ProviderIds<TAuth>, PR extends (ProfileName<TAuth, P> | string) | undefined = undefined>(\n provider: P,\n baseUrl: string,\n scheme: string = 'gau',\n redirectOverride?: string,\n profile?: PR,\n) {\n if (!isTauri())\n return\n\n const { platform } = await import('@tauri-apps/plugin-os')\n const { openUrl } = await import('@tauri-apps/plugin-opener')\n\n const currentPlatform = platform() // platform is NO LONGER an async function\n let redirectTo: string\n\n if (redirectOverride)\n redirectTo = redirectOverride\n else if (currentPlatform === 'android' || currentPlatform === 'ios')\n redirectTo = new URL(baseUrl).origin\n else\n redirectTo = `${scheme}://oauth/callback`\n\n const params = new URLSearchParams()\n params.set('redirectTo', redirectTo)\n if (profile)\n params.set('profile', String(profile))\n const authUrl = `${baseUrl}/${provider}?${params.toString()}`\n await openUrl(authUrl)\n}\n\nexport async function setupTauriListener(\n handler: (url: string) => Promise<void>,\n): Promise<(() => void) | void> {\n if (!isTauri())\n return\n\n const { listen } = await import('@tauri-apps/api/event')\n try {\n const unlisten = await listen<string>('deep-link', async (event) => {\n await handler(event.payload)\n })\n return unlisten\n }\n catch (err) {\n console.error(err)\n }\n}\n\nexport function handleTauriDeepLink(url: string, baseUrl: string, scheme: string, onToken: (token: string) => void) {\n const parsed = new URL(url)\n if (parsed.protocol !== `${scheme}:` && parsed.origin !== new URL(baseUrl).origin)\n return\n\n const params = new URLSearchParams(parsed.hash.substring(1))\n const token = params.get('token')\n if (token)\n onToken(token)\n}\n\nexport async function linkAccountWithTauri<const TAuth = unknown, P extends ProviderIds<TAuth> = ProviderIds<TAuth>, PR extends (ProfileName<TAuth, P> | string) | undefined = undefined>(\n provider: P,\n baseUrl: string,\n scheme: string = 'gau',\n redirectOverride?: string,\n profile?: PR,\n) {\n if (!isTauri())\n return\n\n const { platform } = await import('@tauri-apps/plugin-os')\n const { openUrl } = await import('@tauri-apps/plugin-opener')\n\n const currentPlatform = platform()\n let redirectTo: string\n\n if (redirectOverride)\n redirectTo = redirectOverride\n else if (currentPlatform === 'android' || currentPlatform === 'ios')\n redirectTo = new URL(baseUrl).origin\n else\n redirectTo = `${scheme}://oauth/callback`\n\n const token = getSessionToken()\n if (!token) {\n console.error('No session token found, cannot link account.')\n return\n }\n\n const params = new URLSearchParams()\n params.set('redirectTo', redirectTo)\n params.set('token', token)\n if (profile)\n params.set('profile', String(profile))\n const linkUrl = `${baseUrl}/link/${provider}?${params.toString()}`\n await openUrl(linkUrl)\n}\n\nexport async function startAuthBridge(\n baseUrl: string,\n scheme: string,\n onToken: (token: string) => Promise<void> | void,\n): Promise<(() => void) | void> {\n if (!isTauri())\n return\n\n const unlisten = await setupTauriListener(async (url) => {\n handleTauriDeepLink(url, baseUrl, scheme, onToken)\n })\n return unlisten\n}\n","import type { GauSession, ProfileName, ProviderIds } from '../../core'\n// @ts-expect-error svelte-kit\nimport { replaceState } from '$app/navigation'\nimport { BROWSER } from 'esm-env'\nimport { getContext, onMount, setContext } from 'svelte'\nimport { NULL_SESSION } from '../../core'\nimport { isTauri } from '../../runtimes/tauri'\nimport { createAuthClient } from '../vanilla'\n\ninterface AuthContextValue<TAuth = unknown> {\n session: GauSession<ProviderIds<TAuth>>\n isLoading: boolean\n signIn: <P extends ProviderIds<TAuth>>(provider: P, options?: { redirectTo?: string, profile?: ProfileName<TAuth, P> }) => Promise<void>\n linkAccount: <P extends ProviderIds<TAuth>>(provider: P, options?: { redirectTo?: string, profile?: ProfileName<TAuth, P> }) => Promise<void>\n unlinkAccount: (provider: ProviderIds<TAuth>) => Promise<void>\n signOut: () => Promise<void>\n refresh: () => Promise<void>\n}\n\nconst AUTH_CONTEXT_KEY = Symbol('gau-auth')\n\nexport function createSvelteAuth<const TAuth = unknown>({\n baseUrl = '/api/auth',\n scheme = 'gau',\n redirectTo: defaultRedirectTo,\n}: {\n baseUrl?: string\n scheme?: string\n redirectTo?: string\n} = {}) {\n type CurrentSession = GauSession<ProviderIds<TAuth>>\n\n const client = createAuthClient<TAuth>({\n baseUrl,\n })\n\n const fetchSession = async (): Promise<CurrentSession> => {\n if (!BROWSER)\n return { ...NULL_SESSION, providers: [] }\n return client.refreshSession()\n }\n\n let session: CurrentSession = $state({ ...NULL_SESSION, providers: [] })\n let isLoading = $state(true)\n\n async function replaceUrlSafe(url: string) {\n try {\n replaceState(url, {})\n }\n catch {\n if (BROWSER)\n window.history.replaceState(null, '', url)\n }\n }\n\n async function signIn<P extends ProviderIds<TAuth>>(provider: P, { redirectTo, profile }: { redirectTo?: string, profile?: ProfileName<TAuth, P> } = {}) {\n const inTauri = isTauri()\n let finalRedirectTo = redirectTo ?? defaultRedirectTo\n\n if (inTauri) {\n const { signInWithTauri } = await import('../../runtimes/tauri')\n await signInWithTauri<TAuth, P, typeof profile>(provider, baseUrl, scheme, finalRedirectTo, profile)\n return\n }\n\n if (!finalRedirectTo && BROWSER)\n finalRedirectTo = window.location.origin\n\n const url = await client.signIn<P, typeof profile>(provider, { redirectTo: finalRedirectTo, profile })\n if (BROWSER)\n window.location.href = url\n }\n\n async function linkAccount<P extends ProviderIds<TAuth>>(provider: P, { redirectTo, profile }: { redirectTo?: string, profile?: ProfileName<TAuth, P> } = {}) {\n if (isTauri()) {\n const { linkAccountWithTauri } = await import('../../runtimes/tauri')\n await linkAccountWithTauri<TAuth, P, typeof profile>(provider, baseUrl, scheme, redirectTo, profile)\n return\n }\n\n let finalRedirectTo = redirectTo ?? defaultRedirectTo\n if (!finalRedirectTo && BROWSER)\n finalRedirectTo = window.location.href\n\n const url = await client.linkAccount<P, typeof profile>(provider, { redirectTo: finalRedirectTo, profile })\n if (BROWSER)\n window.location.href = url\n }\n\n async function unlinkAccount(provider: ProviderIds<TAuth>) {\n const ok = await client.unlinkAccount(provider)\n if (ok)\n session = await fetchSession()\n else\n console.error('Failed to unlink account')\n }\n\n async function signOut() {\n await client.signOut()\n session = await fetchSession()\n }\n\n onMount(() => {\n if (!BROWSER)\n return\n\n void (async () => {\n const handled = await client.handleRedirectCallback(async url => replaceUrlSafe(url))\n if (!handled)\n session = await fetchSession()\n\n isLoading = false\n })()\n\n let cleanup: (() => void) | void\n let disposed = false\n\n if (!isTauri())\n return\n\n void (async () => {\n const { startAuthBridge } = await import('../../runtimes/tauri')\n const unlisten = await startAuthBridge(baseUrl, scheme, async (token) => {\n await client.applySessionToken(token)\n session = await fetchSession()\n })\n if (disposed)\n unlisten?.()\n else\n cleanup = unlisten\n })()\n\n return () => {\n disposed = true\n cleanup?.()\n }\n })\n\n const contextValue: AuthContextValue<TAuth> = {\n get session() {\n return session\n },\n get isLoading() {\n return isLoading\n },\n signIn,\n linkAccount,\n unlinkAccount,\n signOut,\n refresh: async () => { session = await fetchSession() },\n }\n\n setContext(AUTH_CONTEXT_KEY, contextValue)\n}\n\nexport function useAuth<const TAuth = unknown>(): AuthContextValue<TAuth> {\n const context = getContext<AuthContextValue<TAuth>>(AUTH_CONTEXT_KEY)\n if (!context)\n throw new Error('useAuth must be used within an AuthProvider')\n\n return context\n}\n","import type { SerializeOptions } from 'cookie'\nimport { parse, serialize } from 'cookie'\n\nexport const DEFAULT_COOKIE_SERIALIZE_OPTIONS: SerializeOptions = {\n path: '/',\n sameSite: 'lax',\n secure: true,\n httpOnly: true,\n}\n\nexport type Cookie = [string, string, SerializeOptions]\n\nexport function parseCookies(cookieHeader: string | null | undefined): Map<string, string> {\n const cookies = new Map<string, string>()\n if (cookieHeader) {\n const parsed = parse(cookieHeader)\n for (const name in parsed)\n cookies.set(name, parsed[name]!)\n }\n return cookies\n}\n\nexport class Cookies {\n #new: Cookie[] = []\n\n constructor(\n private readonly requestCookies: Map<string, string>,\n private readonly defaultOptions: SerializeOptions,\n ) {}\n\n get(name: string): string | undefined {\n return this.requestCookies.get(name)\n }\n\n set(name: string, value: string, options?: SerializeOptions): void {\n const combinedOptions = { ...this.defaultOptions, ...options }\n this.#new.push([name, value, combinedOptions])\n }\n\n delete(name: string, options?: Omit<SerializeOptions, 'expires' | 'maxAge'>): void {\n this.set(name, '', { ...options, expires: new Date(0), maxAge: 0 })\n }\n\n toHeaders(): Headers {\n const headers = new Headers()\n for (const [name, value, options] of this.#new)\n headers.append('Set-Cookie', serialize(name, value, options))\n\n return headers\n }\n}\n\nexport const CSRF_COOKIE_NAME = '__gau-csrf-token'\nexport const SESSION_COOKIE_NAME = '__gau-session-token'\nexport const SESSION_STRATEGY_COOKIE_NAME = '__gau-session-strategy'\nexport const LINKING_TOKEN_COOKIE_NAME = '__gau-linking-token'\nexport const PKCE_COOKIE_NAME = '__gau-pkce-code-verifier'\nexport const CALLBACK_URI_COOKIE_NAME = '__gau-callback-uri'\nexport const PROVIDER_OPTIONS_COOKIE_NAME = '__gau-provider-options'\n\nexport const CSRF_MAX_AGE = 60 * 10 // 10 minutes\n","/// <reference types=\"node\" />\nimport {\n createJWTSignatureMessage,\n encodeJWT,\n JWSRegisteredHeaders,\n JWTRegisteredClaims,\n parseJWT,\n} from '@oslojs/jwt'\nimport { AuthError } from '../core/index'\nimport { constantTimeEqual, deriveKeysFromSecret, rawToDer } from './utils'\n\nexport type SupportedAlgorithm = 'ES256' | 'HS256'\n\ninterface CommonSignOptions {\n /** Time-to-live in seconds (exp claim). If omitted the token will not expire. */\n ttl?: number\n}\n\nexport type SignOptions\n = | ({ algorithm?: 'ES256', privateKey?: CryptoKey, secret?: string }\n & CommonSignOptions & { iss?: string, aud?: string | string[], sub?: string })\n | ({ algorithm: 'HS256', secret?: string | Uint8Array, privateKey?: never }\n & CommonSignOptions & { iss?: string, aud?: string | string[], sub?: string })\n\n/**\n * Create a signed JWT.\n * Defaults to ES256 when a privateKey is supplied. Falls back to HS256 when a secret is supplied.\n */\nexport async function sign<T extends Record<string, unknown>>(payload: T, options: SignOptions = {}): Promise<string> {\n let { algorithm = 'ES256', ttl, iss, aud, sub, privateKey, secret } = options\n\n if (algorithm === 'ES256') {\n if (!privateKey) {\n if (typeof secret !== 'string')\n throw new AuthError('Missing secret for ES256 signing. It must be a base64url-encoded string.');\n\n ({ privateKey } = await deriveKeysFromSecret(secret))\n }\n }\n else if (algorithm === 'HS256' && !secret) {\n throw new AuthError('Missing secret for HS256 signing')\n }\n\n const now = Math.floor(Date.now() / 1000)\n\n const jwtPayload: Record<string, unknown> = { iat: now, iss, aud, sub, ...payload }\n\n if (ttl != null && ttl > 0)\n jwtPayload.exp = now + ttl\n\n const isHS256 = algorithm === 'HS256'\n const alg: SupportedAlgorithm = isHS256 ? 'HS256' : 'ES256'\n\n const headerJSON = JSON.stringify({ alg, typ: 'JWT' })\n const payloadJSON = JSON.stringify(jwtPayload)\n\n const signatureMessage = createJWTSignatureMessage(headerJSON, payloadJSON)\n\n let signature: Uint8Array\n\n if (isHS256) {\n // HS256 (HMAC-SHA256)\n const secretBytes = typeof secret === 'string'\n ? new TextEncoder().encode(secret)\n : secret\n\n const cryptoKey = await crypto.subtle.importKey(\n 'raw',\n secretBytes as BufferSource,\n { name: 'HMAC', hash: 'SHA-256' },\n false,\n ['sign'],\n )\n\n signature = new Uint8Array(await crypto.subtle.sign('HMAC', cryptoKey, signatureMessage as BufferSource))\n }\n else {\n // ES256 (ECDSA-SHA256)\n // Runtimes like Bun's return the raw (r||s) signature directly, not DER-encoded.\n signature = new Uint8Array(\n await crypto.subtle.sign(\n { name: 'ECDSA', hash: 'SHA-256' },\n privateKey!,\n signatureMessage as BufferSource,\n ),\n )\n }\n\n return encodeJWT(headerJSON, payloadJSON, signature)\n}\n\nexport type VerifyOptions\n = | { algorithm?: 'ES256', publicKey?: CryptoKey, secret?: string, iss?: string, aud?: string | string[] }\n | { algorithm: 'HS256', secret?: string | Uint8Array, publicKey?: never, iss?: string, aud?: string | string[] }\n\n/**\n * Verify a JWT and return its payload when the signature is valid.\n * The algorithm is inferred from options – ES256 by default.\n * Throws when verification fails or the token is expired.\n */\nexport async function verify<T = Record<string, unknown>>(token: string, options: VerifyOptions): Promise<T> {\n let { algorithm = 'ES256', publicKey, secret, iss, aud } = options\n\n if (algorithm === 'ES256') {\n if (!publicKey) {\n if (typeof secret !== 'string')\n throw new AuthError('Missing secret for ES256 verification. Must be a base64url-encoded string.');\n\n ({ publicKey } = await deriveKeysFromSecret(secret))\n }\n }\n\n if (algorithm === 'HS256' && !secret)\n throw new AuthError('Missing secret for HS256 verification')\n\n const [header, payload, signature, signatureMessage] = parseJWT(token)\n\n const headerParams = new JWSRegisteredHeaders(header)\n const headerAlg = headerParams.algorithm()\n\n let validSignature = false\n\n // HS256 verification path\n if (algorithm === 'HS256') {\n if (headerAlg !== 'HS256')\n throw new Error(`JWT algorithm is \"${headerAlg}\", but verifier was configured for \"HS256\"`)\n\n const secretBytes = typeof secret === 'string'\n ? new TextEncoder().encode(secret)\n : secret\n\n const cryptoKey = await crypto.subtle.importKey(\n 'raw',\n secretBytes as BufferSource,\n { name: 'HMAC', hash: 'SHA-256' },\n false,\n ['sign'],\n )\n\n const expectedSig = new Uint8Array(await crypto.subtle.sign('HMAC', cryptoKey, signatureMessage as BufferSource))\n validSignature = constantTimeEqual(expectedSig, new Uint8Array(signature))\n }\n // ES256 verification path (default)\n else {\n if (headerAlg !== 'ES256')\n throw new AuthError(`JWT algorithm is \"${headerAlg}\", but verifier was configured for \"ES256\"`)\n\n const signatureBytes = new Uint8Array(signature)\n\n // Runtimes like Node.js return DER-encoded signatures. Others (Bun) return raw (r||s).\n // We try DER first, as it's more common in Node environments.\n validSignature = await crypto.subtle.verify(\n { name: 'ECDSA', hash: 'SHA-256' },\n publicKey!,\n signatureBytes as BufferSource,\n signatureMessage as BufferSource,\n )\n\n if (!validSignature && signatureBytes.length === 64) {\n // If DER verification fails and the signature is 64 bytes, it might be a raw signature.\n // Convert it to DER and try again.\n try {\n const derSig = rawToDer(signatureBytes)\n validSignature = await crypto.subtle.verify(\n { name: 'ECDSA', hash: 'SHA-256' },\n publicKey!,\n derSig as BufferSource,\n signatureMessage as BufferSource,\n )\n }\n catch {\n // rawToDer can throw if the signature is not 64 bytes, but we already checked.\n // This catch is for other unexpected errors.\n validSignature = false\n }\n }\n }\n\n if (!validSignature)\n throw new AuthError('Invalid JWT signature')\n\n const claims = new JWTRegisteredClaims(payload)\n if (claims.hasExpiration() && !claims.verifyExpiration())\n throw new AuthError('JWT expired')\n if (claims.hasNotBefore() && !claims.verifyNotBefore())\n throw new AuthError('JWT not yet valid')\n if (iss && (payload as any).iss !== iss)\n throw new AuthError('Invalid JWT issuer')\n\n if (aud) {\n const expectedAudience = Array.isArray(aud) ? aud : [aud]\n const tokenAudience = (payload as any).aud\n ? (Array.isArray((payload as any).aud) ? (payload as any).aud : [(payload as any).aud])\n : []\n\n if (!expectedAudience.some(audValue => tokenAudience.includes(audValue)))\n throw new AuthError('Invalid JWT audience')\n }\n\n return payload as T\n}\n","import { generateCodeVerifier, generateState } from 'arctic'\n\nexport function createOAuthUris() {\n const state = generateState()\n const codeVerifier = generateCodeVerifier()\n\n return {\n state,\n codeVerifier,\n }\n}\n","export interface User {\n id: string\n name?: string | null\n email?: string | null\n emailVerified?: boolean | null\n image?: string | null\n role?: string | null\n isAdmin?: boolean\n}\n\nexport interface Session {\n id: string\n sub: string\n [key: string]: unknown\n}\n\nexport interface GauSession<TProviders extends string = string> {\n user: User | null\n session: Session | null\n accounts?: Account[] | null\n providers?: TProviders[]\n}\n\nexport const NULL_SESSION = {\n user: null,\n session: null,\n accounts: null,\n} as const\n\nexport interface NewUser extends Omit<User, 'id' | 'accounts' | 'isAdmin'> {\n id?: string\n}\n\nexport interface Account {\n userId: string\n provider: string\n providerAccountId: string\n type?: string // e.g. \"oauth\"\n accessToken?: string | null\n refreshToken?: string | null\n expiresAt?: number | null // epoch seconds\n idToken?: string | null\n scope?: string | null\n tokenType?: string | null\n sessionState?: string | null\n}\n\nexport interface NewAccount extends Account {}\n\nexport interface Adapter {\n getUser: (id: string) => Promise<User | null>\n getUserByEmail: (email: string) => Promise<User | null>\n getUserByAccount: (provider: string, providerAccountId: string) => Promise<User | null>\n getAccounts: (userId: string) => Promise<Account[]>\n getUserAndAccounts: (userId: string) => Promise<{ user: User, accounts: Account[] } | null>\n createUser: (data: NewUser) => Promise<User>\n linkAccount: (data: NewAccount) => Promise<void>\n unlinkAccount: (provider: string, providerAccountId: string) => Promise<void>\n updateAccount?: (data: Partial<Account> & { userId: string, provider: string, providerAccountId: string }) => Promise<void>\n updateUser: (data: Partial<User> & { id: string }) => Promise<User>\n deleteUser: (id: string) => Promise<void>\n}\n\nexport class AuthError extends Error {\n override readonly cause?: unknown\n constructor(message: string, cause?: unknown) {\n super(message)\n this.name = 'AuthError'\n this.cause = cause\n }\n}\n\nexport function json<T>(data: T, init: ResponseInit = {}): Response {\n const headers = new Headers(init.headers)\n if (!headers.has('Content-Type'))\n headers.set('Content-Type', 'application/json; charset=utf-8')\n return new Response(JSON.stringify(data), { ...init, headers })\n}\n\nexport function redirect(url: string, status: 302 | 303 = 302): Response {\n return new Response(null, {\n status,\n headers: {\n Location: url,\n },\n })\n}\n\nexport * from './cookies'\nexport * from './createAuth'\nexport * from './handler'\n","import type { GauSession, ProfileName, ProviderIds } from '../../core'\nimport { isTauri } from '../../runtimes/tauri/index'\nimport { clearSessionToken, getSessionToken, storeSessionToken } from '../token'\n\nexport interface AuthClientOptions {\n baseUrl: string\n scheme?: string\n}\n\ntype SessionListener<TAuth = unknown> = (session: GauSession<ProviderIds<TAuth>>) => void\n\nfunction buildQuery(params: Record<string, string | undefined | null>): string {\n const q = new URLSearchParams()\n for (const [k, v] of Object.entries(params)) {\n if (v != null && v !== '')\n q.set(k, String(v))\n }\n const s = q.toString()\n return s ? `?${s}` : ''\n}\n\nexport function createAuthClient<const TAuth = unknown>({ baseUrl, scheme = 'gau' }: AuthClientOptions) {\n let currentSession: GauSession<ProviderIds<TAuth>> = { user: null, session: null, accounts: null, providers: [] }\n const listeners = new Set<SessionListener<TAuth>>()\n\n const notify = () => {\n for (const l of listeners)\n l(currentSession)\n }\n\n async function fetchSession(): Promise<GauSession<ProviderIds<TAuth>>> {\n const token = getSessionToken()\n const headers = token ? { Authorization: `Bearer ${token}` } : undefined\n const res = await fetch(`${baseUrl}/session`, token ? { headers } : { credentials: 'include' })\n const contentType = res.headers.get('content-type')\n if (contentType?.includes('application/json'))\n return await res.json()\n return { user: null, session: null, accounts: null, providers: [] }\n }\n\n async function refreshSession(): Promise<GauSession<ProviderIds<TAuth>>> {\n const next = await fetchSession()\n currentSession = next\n notify()\n return next\n }\n\n async function applySessionToken(token: string): Promise<void> {\n try {\n storeSessionToken(token)\n }\n finally {\n await refreshSession()\n }\n }\n\n function onSessionChange(listener: SessionListener<TAuth>): () => void {\n listeners.add(listener)\n return () => listeners.delete(listener)\n }\n\n async function handleRedirectCallback(replaceUrl?: (url: string) => void): Promise<boolean> {\n if (typeof window === 'undefined')\n return false\n\n if (window.location.hash === '#_=_') {\n const cleanUrl = window.location.pathname + window.location.search\n if (replaceUrl)\n replaceUrl(cleanUrl)\n else\n window.history.replaceState(null, '', cleanUrl)\n return false\n }\n\n const hash = window.location.hash?.substring(1) ?? ''\n if (!hash)\n return false\n\n const params = new URLSearchParams(hash)\n const token = params.get('token')\n if (!token)\n return false\n\n await applySessionToken(token)\n\n const cleanUrl = window.location.pathname + window.location.search\n if (replaceUrl)\n replaceUrl(cleanUrl)\n else\n window.history.replaceState(null, '', cleanUrl)\n\n return true\n }\n\n function makeProviderUrl<P extends ProviderIds<TAuth>, PR extends (ProfileName<TAuth, P> | string) | undefined>(provider: P, params?: { redirectTo?: string, profile?: PR }): string {\n const q = buildQuery({\n redirectTo: params?.redirectTo,\n profile: params?.profile != null ? String(params.profile) : undefined,\n })\n return `${baseUrl}/${provider}${q}`\n }\n\n function makeLinkUrl<P extends ProviderIds<TAuth>, PR extends (ProfileName<TAuth, P> | string) | undefined>(provider: P, params: { redirectTo?: string, profile?: PR, redirect?: 'false' | 'true' }): string {\n const q = buildQuery({\n redirectTo: params.redirectTo,\n profile: params.profile != null ? String(params.profile) : undefined,\n redirect: params.redirect,\n })\n return `${baseUrl}/link/${provider}${q}`\n }\n\n async function signIn<P extends ProviderIds<TAuth>, PR extends (ProfileName<TAuth, P> | string) | undefined>(provider: P, options?: { redirectTo?: string, profile?: PR }): Promise<string> {\n const url = makeProviderUrl<P, PR>(provider, options)\n\n if (isTauri()) {\n const { signInWithTauri } = await import('../../runtimes/tauri/index')\n await signInWithTauri<TAuth, P, PR>(provider, baseUrl, scheme, options?.redirectTo, options?.profile)\n }\n\n return url\n }\n\n async function linkAccount<P extends ProviderIds<TAuth>, PR extends (ProfileName<TAuth, P> | string) | undefined>(provider: P, options?: { redirectTo?: string, profile?: PR }): Promise<string> {\n if (isTauri()) {\n const { linkAccountWithTauri } = await import('../../runtimes/tauri/index')\n await linkAccountWithTauri<TAuth, P, PR>(provider, baseUrl, scheme, options?.redirectTo, options?.profile)\n return makeLinkUrl<P, PR>(provider, { redirectTo: options?.redirectTo, profile: options?.profile, redirect: 'false' })\n }\n\n const linkUrl = makeLinkUrl<P, PR>(provider, { redirectTo: options?.redirectTo, profile: options?.profile, redirect: 'false' })\n const token = getSessionToken()\n const fetchOptions: RequestInit = token ? { headers: { Authorization: `Bearer ${token}` } } : { credentials: 'include' }\n const res: Response = await fetch(linkUrl, fetchOptions)\n if (res.redirected)\n return res.url\n try {\n const data = await res.json()\n if (data?.url)\n return data.url\n }\n catch {}\n return linkUrl\n }\n\n async function unlinkAccount<P extends ProviderIds<TAuth>>(provider: P): Promise<boolean> {\n const token = getSessionToken()\n const fetchOptions: RequestInit = token ? { headers: { Authorization: `Bearer ${token}` } } : { credentials: 'include' }\n const res = await fetch(`${baseUrl}/unlink/${provider}`, { method: 'POST', ...fetchOptions })\n if (res.ok) {\n await refreshSession()\n return true\n }\n return false\n }\n\n async function signOut(): Promise<void> {\n clearSessionToken()\n const token = getSessionToken()\n const headers = token ? { Authorization: `Bearer ${token}` } : undefined\n await fetch(`${baseUrl}/signout`, token ? { method: 'POST', headers } : { method: 'POST', credentials: 'include' })\n await refreshSession()\n }\n\n async function startTauriBridge(): Promise<(() => void) | void> {\n if (!isTauri())\n return\n\n const { startAuthBridge } = await import('../../runtimes/tauri/index')\n const cleanup = await startAuthBridge(baseUrl, scheme, async (token) => {\n await applySessionToken(token)\n })\n return cleanup\n }\n\n return {\n get session() {\n return currentSession\n },\n fetchSession,\n refreshSession,\n applySessionToken,\n handleRedirectCallback,\n onSessionChange,\n signIn,\n linkAccount,\n unlinkAccount,\n signOut,\n startTauriBridge,\n }\n}\n"],"mappings":"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","names":["BROWSER","BROWSER","cleanUrl","signInWithTauri","linkAccountWithTauri","startAuthBridge","BROWSER","signInWithTauri","linkAccountWithTauri","startAuthBridge"]}
|
|
1
|
+
{"version":3,"sources":["../../../../src/client/token.ts","../../../../src/runtimes/tauri/index.ts","../../../../src/client/svelte/index.svelte.ts","../../../../src/core/cookies.ts","../../../../src/jwt/jwt.ts","../../../../src/oauth/utils.ts","../../../../src/core/index.ts","../../../../src/client/vanilla/index.ts"],"sourcesContent":["import { BROWSER } from 'esm-env'\n\nexport function storeSessionToken(token: string) {\n if (!BROWSER)\n return\n try {\n localStorage.setItem('gau-token', token)\n document.cookie = `__gau-session-token=${token}; path=/; max-age=31536000; samesite=lax; secure`\n }\n catch {}\n}\n\nexport function getSessionToken(): string | null {\n if (!BROWSER)\n return null\n return localStorage.getItem('gau-token')\n}\n\nexport function clearSessionToken() {\n if (!BROWSER)\n return\n try {\n localStorage.removeItem('gau-token')\n document.cookie = `__gau-session-token=; path=/; max-age=0`\n }\n catch {}\n}\n\nexport async function generatePKCE() {\n if (!BROWSER || !window.crypto || !window.crypto.subtle)\n throw new Error('PKCE relies on window.crypto, which is not available in this environment.')\n\n function base64UrlEncode(array: Uint8Array): string {\n return btoa(String.fromCharCode(...array))\n .replace(/\\+/g, '-')\n .replace(/\\//g, '_')\n .replace(/=+$/, '')\n }\n\n const verifierLength = 43\n const randomValues = new Uint8Array(verifierLength)\n window.crypto.getRandomValues(randomValues)\n const codeVerifier = base64UrlEncode(randomValues)\n\n const encoder = new TextEncoder()\n const data = encoder.encode(codeVerifier)\n const hash = await window.crypto.subtle.digest('SHA-256', data)\n const codeChallenge = base64UrlEncode(new Uint8Array(hash))\n\n return { codeVerifier, codeChallenge }\n}\n","import type { ProfileName, ProviderIds } from '../../core'\nimport { BROWSER } from 'esm-env'\nimport { generatePKCE, getSessionToken } from '../../client/token'\n\nexport function isTauri(): boolean {\n return BROWSER && '__TAURI_INTERNALS__' in globalThis\n}\n\nfunction resolveOrigin(baseUrl: string): string | null {\n try {\n return new URL(baseUrl).origin\n }\n catch {\n if (BROWSER && typeof window !== 'undefined') {\n try {\n return new URL(baseUrl, window.location.origin).origin\n }\n catch {\n return null\n }\n }\n return null\n }\n}\n\nexport async function signInWithTauri<const TAuth = unknown, P extends ProviderIds<TAuth> = ProviderIds<TAuth>, PR extends (ProfileName<TAuth, P> | string) | undefined = undefined>(\n provider: P,\n baseUrl: string,\n scheme: string = 'gau',\n redirectOverride?: string,\n profile?: PR,\n) {\n if (!isTauri())\n return\n\n const { openUrl } = await import('@tauri-apps/plugin-opener')\n\n function resolveAbsoluteBase(base: string): string {\n try {\n const u = new URL(base)\n return u.toString().replace(/\\/$/, '')\n }\n catch {\n if (BROWSER && typeof window !== 'undefined') {\n try {\n const u = new URL(base, window.location.origin)\n return u.toString().replace(/\\/$/, '')\n }\n catch {\n return base\n }\n }\n return base\n }\n }\n\n let redirectTo: string\n\n if (redirectOverride)\n redirectTo = redirectOverride\n else\n redirectTo = `${scheme}://oauth/callback`\n\n const { codeVerifier, codeChallenge } = await generatePKCE()\n localStorage.setItem('gau-pkce-verifier', codeVerifier)\n\n const params = new URLSearchParams()\n params.set('redirectTo', redirectTo)\n if (profile)\n params.set('profile', String(profile))\n params.set('code_challenge', codeChallenge)\n const resolvedBase = resolveAbsoluteBase(baseUrl)\n const authUrl = `${resolvedBase}/${provider}?${params.toString()}`\n await openUrl(authUrl)\n}\n\nexport async function setupTauriListener(\n handler: (url: string) => Promise<void>,\n): Promise<(() => void) | void> {\n if (!isTauri())\n return\n\n const { listen } = await import('@tauri-apps/api/event')\n try {\n const unlisten = await listen<string>('deep-link', async (event) => {\n await handler(event.payload)\n })\n return unlisten\n }\n catch (err) {\n console.error(err)\n }\n}\n\nexport async function handleTauriDeepLink(url: string, baseUrl: string, scheme: string, onToken: (token: string) => void) {\n const parsed = new URL(url)\n const baseOrigin = resolveOrigin(baseUrl)\n if (parsed.protocol !== `${scheme}:` && (!baseOrigin || parsed.origin !== baseOrigin))\n return\n\n const queryParams = new URLSearchParams(parsed.search)\n const code = queryParams.get('code')\n if (code) {\n const verifier = localStorage.getItem('gau-pkce-verifier')\n if (!verifier) {\n console.error('No PKCE verifier found')\n return\n }\n localStorage.removeItem('gau-pkce-verifier')\n\n try {\n const res = await fetch(`${baseUrl}/token`, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({ code, codeVerifier: verifier }),\n })\n if (res.ok) {\n const data = await res.json()\n if (data.token)\n onToken(data.token)\n }\n else {\n console.error('Failed to exchange code for token')\n }\n }\n catch (e) {\n console.error('Error exchanging code for token:', e)\n }\n }\n}\n\nexport async function linkAccountWithTauri<const TAuth = unknown, P extends ProviderIds<TAuth> = ProviderIds<TAuth>, PR extends (ProfileName<TAuth, P> | string) | undefined = undefined>(\n provider: P,\n baseUrl: string,\n scheme: string = 'gau',\n redirectOverride?: string,\n profile?: PR,\n) {\n if (!isTauri())\n return\n\n const { openUrl } = await import('@tauri-apps/plugin-opener')\n\n let redirectTo: string\n\n if (redirectOverride)\n redirectTo = redirectOverride\n else\n redirectTo = `${scheme}://oauth/callback`\n\n const token = getSessionToken()\n if (!token) {\n console.error('No session token found, cannot link account.')\n return\n }\n\n const params = new URLSearchParams()\n params.set('redirectTo', redirectTo)\n params.set('token', token)\n if (profile)\n params.set('profile', String(profile))\n const resolvedBase = (() => {\n try {\n const u = new URL(baseUrl)\n return u.toString().replace(/\\/$/, '')\n }\n catch {\n if (BROWSER && typeof window !== 'undefined') {\n try {\n const u = new URL(baseUrl, window.location.origin)\n return u.toString().replace(/\\/$/, '')\n }\n catch {\n return baseUrl\n }\n }\n return baseUrl\n }\n })()\n const linkUrl = `${resolvedBase}/link/${provider}?${params.toString()}`\n await openUrl(linkUrl)\n}\n\nexport async function startAuthBridge(\n baseUrl: string,\n scheme: string,\n onToken: (token: string) => Promise<void> | void,\n): Promise<(() => void) | void> {\n if (!isTauri())\n return\n\n const unlisten = await setupTauriListener(async (url) => {\n handleTauriDeepLink(url, baseUrl, scheme, onToken)\n })\n return unlisten\n}\n","import type { GauSession, ProfileName, ProviderIds } from '../../core'\n// @ts-expect-error svelte-kit\nimport { replaceState } from '$app/navigation'\nimport { BROWSER } from 'esm-env'\nimport { getContext, onMount, setContext } from 'svelte'\nimport { NULL_SESSION } from '../../core'\nimport { isTauri } from '../../runtimes/tauri'\nimport { createAuthClient } from '../vanilla'\n\ninterface AuthContextValue<TAuth = unknown> {\n session: GauSession<ProviderIds<TAuth>>\n isLoading: boolean\n signIn: <P extends ProviderIds<TAuth>>(provider: P, options?: { redirectTo?: string, profile?: ProfileName<TAuth, P> }) => Promise<void>\n linkAccount: <P extends ProviderIds<TAuth>>(provider: P, options?: { redirectTo?: string, profile?: ProfileName<TAuth, P> }) => Promise<void>\n unlinkAccount: (provider: ProviderIds<TAuth>) => Promise<void>\n signOut: () => Promise<void>\n refresh: () => Promise<void>\n}\n\nconst AUTH_CONTEXT_KEY = Symbol('gau-auth')\n\nexport function createSvelteAuth<const TAuth = unknown>({\n baseUrl = '/api/auth',\n scheme = 'gau',\n redirectTo: defaultRedirectTo,\n}: {\n baseUrl?: string\n scheme?: string\n redirectTo?: string\n} = {}) {\n type CurrentSession = GauSession<ProviderIds<TAuth>>\n\n const client = createAuthClient<TAuth>({\n baseUrl,\n })\n\n const fetchSession = async (): Promise<CurrentSession> => {\n if (!BROWSER)\n return { ...NULL_SESSION, providers: [] }\n return client.refreshSession()\n }\n\n let session: CurrentSession = $state({ ...NULL_SESSION, providers: [] })\n let isLoading = $state(true)\n\n async function replaceUrlSafe(url: string) {\n try {\n replaceState(url, {})\n }\n catch {\n if (BROWSER)\n window.history.replaceState(null, '', url)\n }\n }\n\n async function signIn<P extends ProviderIds<TAuth>>(provider: P, { redirectTo, profile }: { redirectTo?: string, profile?: ProfileName<TAuth, P> } = {}) {\n const inTauri = isTauri()\n let finalRedirectTo = redirectTo ?? defaultRedirectTo\n\n if (inTauri) {\n const { signInWithTauri } = await import('../../runtimes/tauri')\n await signInWithTauri<TAuth, P, typeof profile>(provider, baseUrl, scheme, finalRedirectTo, profile)\n return\n }\n\n if (!finalRedirectTo && BROWSER)\n finalRedirectTo = window.location.origin\n\n const url = await client.signIn<P, typeof profile>(provider, { redirectTo: finalRedirectTo, profile })\n if (BROWSER)\n window.location.href = url\n }\n\n async function linkAccount<P extends ProviderIds<TAuth>>(provider: P, { redirectTo, profile }: { redirectTo?: string, profile?: ProfileName<TAuth, P> } = {}) {\n if (isTauri()) {\n const { linkAccountWithTauri } = await import('../../runtimes/tauri')\n await linkAccountWithTauri<TAuth, P, typeof profile>(provider, baseUrl, scheme, redirectTo, profile)\n return\n }\n\n let finalRedirectTo = redirectTo ?? defaultRedirectTo\n if (!finalRedirectTo && BROWSER)\n finalRedirectTo = window.location.href\n\n const url = await client.linkAccount<P, typeof profile>(provider, { redirectTo: finalRedirectTo, profile })\n if (BROWSER)\n window.location.href = url\n }\n\n async function unlinkAccount(provider: ProviderIds<TAuth>) {\n const ok = await client.unlinkAccount(provider)\n if (ok)\n session = await fetchSession()\n else\n console.error('Failed to unlink account')\n }\n\n async function signOut() {\n await client.signOut()\n session = await fetchSession()\n }\n\n onMount(() => {\n if (!BROWSER)\n return\n\n void (async () => {\n const handled = await client.handleRedirectCallback(async url => replaceUrlSafe(url))\n if (!handled)\n session = await fetchSession()\n\n isLoading = false\n })()\n\n let cleanup: (() => void) | void\n let disposed = false\n\n if (!isTauri())\n return\n\n void (async () => {\n const { startAuthBridge } = await import('../../runtimes/tauri')\n const unlisten = await startAuthBridge(baseUrl, scheme, async (token) => {\n await client.applySessionToken(token)\n session = await fetchSession()\n })\n if (disposed)\n unlisten?.()\n else\n cleanup = unlisten\n })()\n\n return () => {\n disposed = true\n cleanup?.()\n }\n })\n\n const contextValue: AuthContextValue<TAuth> = {\n get session() {\n return session\n },\n get isLoading() {\n return isLoading\n },\n signIn,\n linkAccount,\n unlinkAccount,\n signOut,\n refresh: async () => { session = await fetchSession() },\n }\n\n setContext(AUTH_CONTEXT_KEY, contextValue)\n}\n\nexport function useAuth<const TAuth = unknown>(): AuthContextValue<TAuth> {\n const context = getContext<AuthContextValue<TAuth>>(AUTH_CONTEXT_KEY)\n if (!context)\n throw new Error('useAuth must be used within an AuthProvider')\n\n return context\n}\n","import type { SerializeOptions } from 'cookie'\nimport { parse, serialize } from 'cookie'\n\nexport const DEFAULT_COOKIE_SERIALIZE_OPTIONS: SerializeOptions = {\n path: '/',\n sameSite: 'lax',\n secure: true,\n httpOnly: true,\n}\n\nexport type Cookie = [string, string, SerializeOptions]\n\nexport function parseCookies(cookieHeader: string | null | undefined): Map<string, string> {\n const cookies = new Map<string, string>()\n if (cookieHeader) {\n const parsed = parse(cookieHeader)\n for (const name in parsed)\n cookies.set(name, parsed[name]!)\n }\n return cookies\n}\n\nexport class Cookies {\n #new: Cookie[] = []\n\n constructor(\n private readonly requestCookies: Map<string, string>,\n private readonly defaultOptions: SerializeOptions,\n ) {}\n\n get(name: string): string | undefined {\n return this.requestCookies.get(name)\n }\n\n set(name: string, value: string, options?: SerializeOptions): void {\n const combinedOptions = { ...this.defaultOptions, ...options }\n this.#new.push([name, value, combinedOptions])\n }\n\n delete(name: string, options?: Omit<SerializeOptions, 'expires' | 'maxAge'>): void {\n this.set(name, '', { ...options, expires: new Date(0), maxAge: 0 })\n }\n\n toHeaders(): Headers {\n const headers = new Headers()\n for (const [name, value, options] of this.#new)\n headers.append('Set-Cookie', serialize(name, value, options))\n\n return headers\n }\n}\n\nexport const CSRF_COOKIE_NAME = '__gau-csrf-token'\nexport const SESSION_COOKIE_NAME = '__gau-session-token'\nexport const SESSION_STRATEGY_COOKIE_NAME = '__gau-session-strategy'\nexport const LINKING_TOKEN_COOKIE_NAME = '__gau-linking-token'\nexport const PKCE_COOKIE_NAME = '__gau-pkce-code-verifier'\nexport const CALLBACK_URI_COOKIE_NAME = '__gau-callback-uri'\nexport const PROVIDER_OPTIONS_COOKIE_NAME = '__gau-provider-options'\nexport const CLIENT_CHALLENGE_COOKIE_NAME = '__gau-client-challenge'\n\nexport const CSRF_MAX_AGE = 60 * 10 // 10 minutes\n","/// <reference types=\"node\" />\nimport {\n createJWTSignatureMessage,\n encodeJWT,\n JWSRegisteredHeaders,\n JWTRegisteredClaims,\n parseJWT,\n} from '@oslojs/jwt'\nimport { AuthError } from '../core/index'\nimport { constantTimeEqual, deriveKeysFromSecret, rawToDer } from './utils'\n\nexport type SupportedAlgorithm = 'ES256' | 'HS256'\n\ninterface CommonSignOptions {\n /** Time-to-live in seconds (exp claim). If omitted the token will not expire. */\n ttl?: number\n}\n\nexport type SignOptions\n = | ({ algorithm?: 'ES256', privateKey?: CryptoKey, secret?: string }\n & CommonSignOptions & { iss?: string, aud?: string | string[], sub?: string })\n | ({ algorithm: 'HS256', secret?: string | Uint8Array, privateKey?: never }\n & CommonSignOptions & { iss?: string, aud?: string | string[], sub?: string })\n\n/**\n * Create a signed JWT.\n * Defaults to ES256 when a privateKey is supplied. Falls back to HS256 when a secret is supplied.\n */\nexport async function sign<T extends Record<string, unknown>>(payload: T, options: SignOptions = {}): Promise<string> {\n let { algorithm = 'ES256', ttl, iss, aud, sub, privateKey, secret } = options\n\n if (algorithm === 'ES256') {\n if (!privateKey) {\n if (typeof secret !== 'string')\n throw new AuthError('Missing secret for ES256 signing. It must be a base64url-encoded string.');\n\n ({ privateKey } = await deriveKeysFromSecret(secret))\n }\n }\n else if (algorithm === 'HS256' && !secret) {\n throw new AuthError('Missing secret for HS256 signing')\n }\n\n const now = Math.floor(Date.now() / 1000)\n\n const jwtPayload: Record<string, unknown> = { iat: now, iss, aud, sub, ...payload }\n\n if (ttl != null && ttl > 0)\n jwtPayload.exp = now + ttl\n\n const isHS256 = algorithm === 'HS256'\n const alg: SupportedAlgorithm = isHS256 ? 'HS256' : 'ES256'\n\n const headerJSON = JSON.stringify({ alg, typ: 'JWT' })\n const payloadJSON = JSON.stringify(jwtPayload)\n\n const signatureMessage = createJWTSignatureMessage(headerJSON, payloadJSON)\n\n let signature: Uint8Array\n\n if (isHS256) {\n // HS256 (HMAC-SHA256)\n const secretBytes = typeof secret === 'string'\n ? new TextEncoder().encode(secret)\n : secret\n\n const cryptoKey = await crypto.subtle.importKey(\n 'raw',\n secretBytes as BufferSource,\n { name: 'HMAC', hash: 'SHA-256' },\n false,\n ['sign'],\n )\n\n signature = new Uint8Array(await crypto.subtle.sign('HMAC', cryptoKey, signatureMessage as BufferSource))\n }\n else {\n // ES256 (ECDSA-SHA256)\n // Runtimes like Bun's return the raw (r||s) signature directly, not DER-encoded.\n signature = new Uint8Array(\n await crypto.subtle.sign(\n { name: 'ECDSA', hash: 'SHA-256' },\n privateKey!,\n signatureMessage as BufferSource,\n ),\n )\n }\n\n return encodeJWT(headerJSON, payloadJSON, signature)\n}\n\nexport type VerifyOptions\n = | { algorithm?: 'ES256', publicKey?: CryptoKey, secret?: string, iss?: string, aud?: string | string[] }\n | { algorithm: 'HS256', secret?: string | Uint8Array, publicKey?: never, iss?: string, aud?: string | string[] }\n\n/**\n * Verify a JWT and return its payload when the signature is valid.\n * The algorithm is inferred from options – ES256 by default.\n * Throws when verification fails or the token is expired.\n */\nexport async function verify<T = Record<string, unknown>>(token: string, options: VerifyOptions): Promise<T> {\n let { algorithm = 'ES256', publicKey, secret, iss, aud } = options\n\n if (algorithm === 'ES256') {\n if (!publicKey) {\n if (typeof secret !== 'string')\n throw new AuthError('Missing secret for ES256 verification. Must be a base64url-encoded string.');\n\n ({ publicKey } = await deriveKeysFromSecret(secret))\n }\n }\n\n if (algorithm === 'HS256' && !secret)\n throw new AuthError('Missing secret for HS256 verification')\n\n const [header, payload, signature, signatureMessage] = parseJWT(token)\n\n const headerParams = new JWSRegisteredHeaders(header)\n const headerAlg = headerParams.algorithm()\n\n let validSignature = false\n\n // HS256 verification path\n if (algorithm === 'HS256') {\n if (headerAlg !== 'HS256')\n throw new Error(`JWT algorithm is \"${headerAlg}\", but verifier was configured for \"HS256\"`)\n\n const secretBytes = typeof secret === 'string'\n ? new TextEncoder().encode(secret)\n : secret\n\n const cryptoKey = await crypto.subtle.importKey(\n 'raw',\n secretBytes as BufferSource,\n { name: 'HMAC', hash: 'SHA-256' },\n false,\n ['sign'],\n )\n\n const expectedSig = new Uint8Array(await crypto.subtle.sign('HMAC', cryptoKey, signatureMessage as BufferSource))\n validSignature = constantTimeEqual(expectedSig, new Uint8Array(signature))\n }\n // ES256 verification path (default)\n else {\n if (headerAlg !== 'ES256')\n throw new AuthError(`JWT algorithm is \"${headerAlg}\", but verifier was configured for \"ES256\"`)\n\n const signatureBytes = new Uint8Array(signature)\n\n // Runtimes like Node.js return DER-encoded signatures. Others (Bun) return raw (r||s).\n // We try DER first, as it's more common in Node environments.\n validSignature = await crypto.subtle.verify(\n { name: 'ECDSA', hash: 'SHA-256' },\n publicKey!,\n signatureBytes as BufferSource,\n signatureMessage as BufferSource,\n )\n\n if (!validSignature && signatureBytes.length === 64) {\n // If DER verification fails and the signature is 64 bytes, it might be a raw signature.\n // Convert it to DER and try again.\n try {\n const derSig = rawToDer(signatureBytes)\n validSignature = await crypto.subtle.verify(\n { name: 'ECDSA', hash: 'SHA-256' },\n publicKey!,\n derSig as BufferSource,\n signatureMessage as BufferSource,\n )\n }\n catch {\n // rawToDer can throw if the signature is not 64 bytes, but we already checked.\n // This catch is for other unexpected errors.\n validSignature = false\n }\n }\n }\n\n if (!validSignature)\n throw new AuthError('Invalid JWT signature')\n\n const claims = new JWTRegisteredClaims(payload)\n if (claims.hasExpiration() && !claims.verifyExpiration())\n throw new AuthError('JWT expired')\n if (claims.hasNotBefore() && !claims.verifyNotBefore())\n throw new AuthError('JWT not yet valid')\n if (iss && (payload as any).iss !== iss)\n throw new AuthError('Invalid JWT issuer')\n\n if (aud) {\n const expectedAudience = Array.isArray(aud) ? aud : [aud]\n const tokenAudience = (payload as any).aud\n ? (Array.isArray((payload as any).aud) ? (payload as any).aud : [(payload as any).aud])\n : []\n\n if (!expectedAudience.some(audValue => tokenAudience.includes(audValue)))\n throw new AuthError('Invalid JWT audience')\n }\n\n return payload as T\n}\n","import { generateCodeVerifier, generateState } from 'arctic'\n\nexport function createOAuthUris() {\n const state = generateState()\n const codeVerifier = generateCodeVerifier()\n\n return {\n state,\n codeVerifier,\n }\n}\n","export interface User {\n id: string\n name?: string | null\n email?: string | null\n emailVerified?: boolean | null\n image?: string | null\n role?: string | null\n isAdmin?: boolean\n}\n\nexport interface Session {\n id: string\n sub: string\n [key: string]: unknown\n}\n\nexport interface GauSession<TProviders extends string = string> {\n user: User | null\n session: Session | null\n accounts?: Account[] | null\n providers?: TProviders[]\n}\n\nexport const NULL_SESSION = {\n user: null,\n session: null,\n accounts: null,\n} as const\n\nexport interface NewUser extends Omit<User, 'id' | 'accounts' | 'isAdmin'> {\n id?: string\n}\n\nexport interface Account {\n userId: string\n provider: string\n providerAccountId: string\n type?: string // e.g. \"oauth\"\n accessToken?: string | null\n refreshToken?: string | null\n expiresAt?: number | null // epoch seconds\n idToken?: string | null\n scope?: string | null\n tokenType?: string | null\n sessionState?: string | null\n}\n\nexport interface NewAccount extends Account {}\n\nexport interface Adapter {\n getUser: (id: string) => Promise<User | null>\n getUserByEmail: (email: string) => Promise<User | null>\n getUserByAccount: (provider: string, providerAccountId: string) => Promise<User | null>\n getAccounts: (userId: string) => Promise<Account[]>\n getUserAndAccounts: (userId: string) => Promise<{ user: User, accounts: Account[] } | null>\n createUser: (data: NewUser) => Promise<User>\n linkAccount: (data: NewAccount) => Promise<void>\n unlinkAccount: (provider: string, providerAccountId: string) => Promise<void>\n updateAccount?: (data: Partial<Account> & { userId: string, provider: string, providerAccountId: string }) => Promise<void>\n updateUser: (data: Partial<User> & { id: string }) => Promise<User>\n deleteUser: (id: string) => Promise<void>\n}\n\nexport class AuthError extends Error {\n override readonly cause?: unknown\n constructor(message: string, cause?: unknown) {\n super(message)\n this.name = 'AuthError'\n this.cause = cause\n }\n}\n\nexport function json<T>(data: T, init: ResponseInit = {}): Response {\n const headers = new Headers(init.headers)\n if (!headers.has('Content-Type'))\n headers.set('Content-Type', 'application/json; charset=utf-8')\n return new Response(JSON.stringify(data), { ...init, headers })\n}\n\nexport function redirect(url: string, status: 302 | 303 = 302): Response {\n return new Response(null, {\n status,\n headers: {\n Location: url,\n },\n })\n}\n\nexport * from './cookies'\nexport * from './createAuth'\nexport * from './handler'\n","import type { GauSession, ProfileName, ProviderIds } from '../../core'\nimport { isTauri } from '../../runtimes/tauri/index'\nimport { clearSessionToken, getSessionToken, storeSessionToken } from '../token'\n\nexport interface AuthClientOptions {\n baseUrl: string\n scheme?: string\n}\n\ntype SessionListener<TAuth = unknown> = (session: GauSession<ProviderIds<TAuth>>) => void\n\nfunction buildQuery(params: Record<string, string | undefined | null>): string {\n const q = new URLSearchParams()\n for (const [k, v] of Object.entries(params)) {\n if (v != null && v !== '')\n q.set(k, String(v))\n }\n const s = q.toString()\n return s ? `?${s}` : ''\n}\n\nexport function createAuthClient<const TAuth = unknown>({ baseUrl, scheme = 'gau' }: AuthClientOptions) {\n let currentSession: GauSession<ProviderIds<TAuth>> = { user: null, session: null, accounts: null, providers: [] }\n const listeners = new Set<SessionListener<TAuth>>()\n\n const notify = () => {\n for (const l of listeners)\n l(currentSession)\n }\n\n async function fetchSession(): Promise<GauSession<ProviderIds<TAuth>>> {\n const token = getSessionToken()\n const headers = token ? { Authorization: `Bearer ${token}` } : undefined\n const res = await fetch(`${baseUrl}/session`, token ? { headers } : { credentials: 'include' })\n const contentType = res.headers.get('content-type')\n if (contentType?.includes('application/json'))\n return await res.json()\n return { user: null, session: null, accounts: null, providers: [] }\n }\n\n async function refreshSession(): Promise<GauSession<ProviderIds<TAuth>>> {\n const next = await fetchSession()\n currentSession = next\n notify()\n return next\n }\n\n async function applySessionToken(token: string): Promise<void> {\n try {\n storeSessionToken(token)\n }\n finally {\n await refreshSession()\n }\n }\n\n function onSessionChange(listener: SessionListener<TAuth>): () => void {\n listeners.add(listener)\n return () => listeners.delete(listener)\n }\n\n async function handleRedirectCallback(replaceUrl?: (url: string) => void): Promise<boolean> {\n if (typeof window === 'undefined')\n return false\n\n if (window.location.hash === '#_=_') {\n const cleanUrl = window.location.pathname + window.location.search\n if (replaceUrl)\n replaceUrl(cleanUrl)\n else\n window.history.replaceState(null, '', cleanUrl)\n return false\n }\n\n const hash = window.location.hash?.substring(1) ?? ''\n if (!hash)\n return false\n\n const params = new URLSearchParams(hash)\n const token = params.get('token')\n if (!token)\n return false\n\n await applySessionToken(token)\n\n const cleanUrl = window.location.pathname + window.location.search\n if (replaceUrl)\n replaceUrl(cleanUrl)\n else\n window.history.replaceState(null, '', cleanUrl)\n\n return true\n }\n\n function makeProviderUrl<P extends ProviderIds<TAuth>, PR extends (ProfileName<TAuth, P> | string) | undefined>(provider: P, params?: { redirectTo?: string, profile?: PR }): string {\n const q = buildQuery({\n redirectTo: params?.redirectTo,\n profile: params?.profile != null ? String(params.profile) : undefined,\n })\n return `${baseUrl}/${provider}${q}`\n }\n\n function makeLinkUrl<P extends ProviderIds<TAuth>, PR extends (ProfileName<TAuth, P> | string) | undefined>(provider: P, params: { redirectTo?: string, profile?: PR, redirect?: 'false' | 'true' }): string {\n const q = buildQuery({\n redirectTo: params.redirectTo,\n profile: params.profile != null ? String(params.profile) : undefined,\n redirect: params.redirect,\n })\n return `${baseUrl}/link/${provider}${q}`\n }\n\n async function signIn<P extends ProviderIds<TAuth>, PR extends (ProfileName<TAuth, P> | string) | undefined>(provider: P, options?: { redirectTo?: string, profile?: PR }): Promise<string> {\n const url = makeProviderUrl<P, PR>(provider, options)\n\n if (isTauri()) {\n const { signInWithTauri } = await import('../../runtimes/tauri/index')\n await signInWithTauri<TAuth, P, PR>(provider, baseUrl, scheme, options?.redirectTo, options?.profile)\n }\n\n return url\n }\n\n async function linkAccount<P extends ProviderIds<TAuth>, PR extends (ProfileName<TAuth, P> | string) | undefined>(provider: P, options?: { redirectTo?: string, profile?: PR }): Promise<string> {\n if (isTauri()) {\n const { linkAccountWithTauri } = await import('../../runtimes/tauri/index')\n await linkAccountWithTauri<TAuth, P, PR>(provider, baseUrl, scheme, options?.redirectTo, options?.profile)\n return makeLinkUrl<P, PR>(provider, { redirectTo: options?.redirectTo, profile: options?.profile, redirect: 'false' })\n }\n\n const linkUrl = makeLinkUrl<P, PR>(provider, { redirectTo: options?.redirectTo, profile: options?.profile, redirect: 'false' })\n const token = getSessionToken()\n const fetchOptions: RequestInit = token ? { headers: { Authorization: `Bearer ${token}` } } : { credentials: 'include' }\n const res: Response = await fetch(linkUrl, fetchOptions)\n if (res.redirected)\n return res.url\n try {\n const data = await res.json()\n if (data?.url)\n return data.url\n }\n catch {}\n return linkUrl\n }\n\n async function unlinkAccount<P extends ProviderIds<TAuth>>(provider: P): Promise<boolean> {\n const token = getSessionToken()\n const fetchOptions: RequestInit = token ? { headers: { Authorization: `Bearer ${token}` } } : { credentials: 'include' }\n const res = await fetch(`${baseUrl}/unlink/${provider}`, { method: 'POST', ...fetchOptions })\n if (res.ok) {\n await refreshSession()\n return true\n }\n return false\n }\n\n async function signOut(): Promise<void> {\n clearSessionToken()\n const token = getSessionToken()\n const headers = token ? { Authorization: `Bearer ${token}` } : undefined\n await fetch(`${baseUrl}/signout`, token ? { method: 'POST', headers } : { method: 'POST', credentials: 'include' })\n await refreshSession()\n }\n\n async function startTauriBridge(): Promise<(() => void) | void> {\n if (!isTauri())\n return\n\n const { startAuthBridge } = await import('../../runtimes/tauri/index')\n const cleanup = await startAuthBridge(baseUrl, scheme, async (token) => {\n await applySessionToken(token)\n })\n return cleanup\n }\n\n return {\n get session() {\n return currentSession\n },\n fetchSession,\n refreshSession,\n applySessionToken,\n handleRedirectCallback,\n onSessionChange,\n signIn,\n linkAccount,\n unlinkAccount,\n signOut,\n startTauriBridge,\n }\n}\n"],"mappings":"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","names":["BROWSER","BROWSER","cleanUrl","signInWithTauri","linkAccountWithTauri","startAuthBridge","BROWSER","signInWithTauri","linkAccountWithTauri","startAuthBridge"]}
|
|
@@ -1,4 +1,8 @@
|
|
|
1
1
|
export declare function storeSessionToken(token: string): void;
|
|
2
2
|
export declare function getSessionToken(): string | null;
|
|
3
3
|
export declare function clearSessionToken(): void;
|
|
4
|
+
export declare function generatePKCE(): Promise<{
|
|
5
|
+
codeVerifier: string;
|
|
6
|
+
codeChallenge: string;
|
|
7
|
+
}>;
|
|
4
8
|
//# sourceMappingURL=token.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"token.d.ts","sourceRoot":"","sources":["../../../src/client/token.ts"],"names":[],"mappings":"AAEA,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,MAAM,QAQ9C;AAED,wBAAgB,eAAe,IAAI,MAAM,GAAG,IAAI,CAI/C;AAED,wBAAgB,iBAAiB,SAQhC"}
|
|
1
|
+
{"version":3,"file":"token.d.ts","sourceRoot":"","sources":["../../../src/client/token.ts"],"names":[],"mappings":"AAEA,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,MAAM,QAQ9C;AAED,wBAAgB,eAAe,IAAI,MAAM,GAAG,IAAI,CAI/C;AAED,wBAAgB,iBAAiB,SAQhC;AAED,wBAAsB,YAAY;;;GAsBjC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{clearSessionToken as n,getSessionToken as t,isTauri as e,storeSessionToken as r}from"../../../chunk-
|
|
1
|
+
import{clearSessionToken as n,getSessionToken as t,isTauri as e,storeSessionToken as r}from"../../../chunk-GVRQST3R.js";function i(n){const t=new URLSearchParams;for(const[e,r]of Object.entries(n))null!=r&&""!==r&&t.set(e,String(r));const e=t.toString();return e?`?${e}`:""}function o({baseUrl:o,scheme:a="gau"}){let c={user:null,session:null,accounts:null,providers:[]};const s=new Set;async function u(){const n=t(),e=n?{Authorization:`Bearer ${n}`}:void 0,r=await fetch(`${o}/session`,n?{headers:e}:{credentials:"include"}),i=r.headers.get("content-type");return i?.includes("application/json")?await r.json():{user:null,session:null,accounts:null,providers:[]}}async function l(){const n=await u();return c=n,(()=>{for(const n of s)n(c)})(),n}async function d(n){try{r(n)}finally{await l()}}function f(n,t){const e=i({redirectTo:t.redirectTo,profile:null!=t.profile?String(t.profile):void 0,redirect:t.redirect});return`${o}/link/${n}${e}`}return{get session(){return c},fetchSession:u,refreshSession:l,applySessionToken:d,handleRedirectCallback:async function(n){if("undefined"==typeof window)return!1;if("#_=_"===window.location.hash){const t=window.location.pathname+window.location.search;return n?n(t):window.history.replaceState(null,"",t),!1}const t=window.location.hash?.substring(1)??"";if(!t)return!1;const e=new URLSearchParams(t).get("token");if(!e)return!1;await d(e);const r=window.location.pathname+window.location.search;return n?n(r):window.history.replaceState(null,"",r),!0},onSessionChange:function(n){return s.add(n),()=>s.delete(n)},signIn:async function(n,t){const r=function(n,t){const e=i({redirectTo:t?.redirectTo,profile:null!=t?.profile?String(t.profile):void 0});return`${o}/${n}${e}`}(n,t);if(e()){const{signInWithTauri:e}=await import("../../runtimes/tauri/index.js");await e(n,o,a,t?.redirectTo,t?.profile)}return r},linkAccount:async function(n,r){if(e()){const{linkAccountWithTauri:t}=await import("../../runtimes/tauri/index.js");return await t(n,o,a,r?.redirectTo,r?.profile),f(n,{redirectTo:r?.redirectTo,profile:r?.profile,redirect:"false"})}const i=f(n,{redirectTo:r?.redirectTo,profile:r?.profile,redirect:"false"}),c=t(),s=c?{headers:{Authorization:`Bearer ${c}`}}:{credentials:"include"},u=await fetch(i,s);if(u.redirected)return u.url;try{const n=await u.json();if(n?.url)return n.url}catch{}return i},unlinkAccount:async function(n){const e=t(),r=e?{headers:{Authorization:`Bearer ${e}`}}:{credentials:"include"};return!!(await fetch(`${o}/unlink/${n}`,{method:"POST",...r})).ok&&(await l(),!0)},signOut:async function(){n();const e=t(),r=e?{Authorization:`Bearer ${e}`}:void 0;await fetch(`${o}/signout`,e?{method:"POST",headers:r}:{method:"POST",credentials:"include"}),await l()},startTauriBridge:async function(){if(!e())return;const{startAuthBridge:n}=await import("../../runtimes/tauri/index.js");return await n(o,a,async n=>{await d(n)})}}}export{o as createAuthClient};//# sourceMappingURL=index.js.map
|
|
@@ -19,5 +19,6 @@ export declare const LINKING_TOKEN_COOKIE_NAME = "__gau-linking-token";
|
|
|
19
19
|
export declare const PKCE_COOKIE_NAME = "__gau-pkce-code-verifier";
|
|
20
20
|
export declare const CALLBACK_URI_COOKIE_NAME = "__gau-callback-uri";
|
|
21
21
|
export declare const PROVIDER_OPTIONS_COOKIE_NAME = "__gau-provider-options";
|
|
22
|
+
export declare const CLIENT_CHALLENGE_COOKIE_NAME = "__gau-client-challenge";
|
|
22
23
|
export declare const CSRF_MAX_AGE: number;
|
|
23
24
|
//# sourceMappingURL=cookies.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cookies.d.ts","sourceRoot":"","sources":["../../../src/core/cookies.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,QAAQ,CAAA;AAG9C,eAAO,MAAM,gCAAgC,EAAE,gBAK9C,CAAA;AAED,MAAM,MAAM,MAAM,GAAG,CAAC,MAAM,EAAE,MAAM,EAAE,gBAAgB,CAAC,CAAA;AAEvD,wBAAgB,YAAY,CAAC,YAAY,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,GAAG,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAQzF;AAED,qBAAa,OAAO;;IAIhB,OAAO,CAAC,QAAQ,CAAC,cAAc;IAC/B,OAAO,CAAC,QAAQ,CAAC,cAAc;IAFjC,YACmB,cAAc,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,EACnC,cAAc,EAAE,gBAAgB,EAC/C;IAEJ,GAAG,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAEpC;IAED,GAAG,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,gBAAgB,GAAG,IAAI,CAGjE;IAED,MAAM,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,IAAI,CAAC,gBAAgB,EAAE,SAAS,GAAG,QAAQ,CAAC,GAAG,IAAI,CAEjF;IAED,SAAS,IAAI,OAAO,CAMnB;CACF;AAED,eAAO,MAAM,gBAAgB,qBAAqB,CAAA;AAClD,eAAO,MAAM,mBAAmB,wBAAwB,CAAA;AACxD,eAAO,MAAM,4BAA4B,2BAA2B,CAAA;AACpE,eAAO,MAAM,yBAAyB,wBAAwB,CAAA;AAC9D,eAAO,MAAM,gBAAgB,6BAA6B,CAAA;AAC1D,eAAO,MAAM,wBAAwB,uBAAuB,CAAA;AAC5D,eAAO,MAAM,4BAA4B,2BAA2B,CAAA;AAEpE,eAAO,MAAM,YAAY,QAAU,CAAA"}
|
|
1
|
+
{"version":3,"file":"cookies.d.ts","sourceRoot":"","sources":["../../../src/core/cookies.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,QAAQ,CAAA;AAG9C,eAAO,MAAM,gCAAgC,EAAE,gBAK9C,CAAA;AAED,MAAM,MAAM,MAAM,GAAG,CAAC,MAAM,EAAE,MAAM,EAAE,gBAAgB,CAAC,CAAA;AAEvD,wBAAgB,YAAY,CAAC,YAAY,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,GAAG,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAQzF;AAED,qBAAa,OAAO;;IAIhB,OAAO,CAAC,QAAQ,CAAC,cAAc;IAC/B,OAAO,CAAC,QAAQ,CAAC,cAAc;IAFjC,YACmB,cAAc,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,EACnC,cAAc,EAAE,gBAAgB,EAC/C;IAEJ,GAAG,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAEpC;IAED,GAAG,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,gBAAgB,GAAG,IAAI,CAGjE;IAED,MAAM,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,IAAI,CAAC,gBAAgB,EAAE,SAAS,GAAG,QAAQ,CAAC,GAAG,IAAI,CAEjF;IAED,SAAS,IAAI,OAAO,CAMnB;CACF;AAED,eAAO,MAAM,gBAAgB,qBAAqB,CAAA;AAClD,eAAO,MAAM,mBAAmB,wBAAwB,CAAA;AACxD,eAAO,MAAM,4BAA4B,2BAA2B,CAAA;AACpE,eAAO,MAAM,yBAAyB,wBAAwB,CAAA;AAC9D,eAAO,MAAM,gBAAgB,6BAA6B,CAAA;AAC1D,eAAO,MAAM,wBAAwB,uBAAuB,CAAA;AAC5D,eAAO,MAAM,4BAA4B,2BAA2B,CAAA;AACpE,eAAO,MAAM,4BAA4B,2BAA2B,CAAA;AAEpE,eAAO,MAAM,YAAY,QAAU,CAAA"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"handler.d.ts","sourceRoot":"","sources":["../../../src/core/handler.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,cAAc,CAAA;
|
|
1
|
+
{"version":3,"file":"handler.d.ts","sourceRoot":"","sources":["../../../src/core/handler.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,cAAc,CAAA;AAexC,wBAAgB,aAAa,CAAC,IAAI,EAAE,IAAI,GAAG,CAAC,OAAO,EAAE,OAAO,KAAK,OAAO,CAAC,QAAQ,CAAC,CAiEjF"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"callback.d.ts","sourceRoot":"","sources":["../../../../src/core/handlers/callback.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,eAAe,CAAA;
|
|
1
|
+
{"version":3,"file":"callback.d.ts","sourceRoot":"","sources":["../../../../src/core/handlers/callback.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,eAAe,CAAA;AAgBzC,wBAAsB,cAAc,CAAC,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,IAAI,EAAE,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,QAAQ,CAAC,CA4iBxG"}
|
|
@@ -3,5 +3,6 @@ export { applyCors, handlePreflight } from './cors';
|
|
|
3
3
|
export { handleLink, handleUnlink } from './link';
|
|
4
4
|
export { handleSignIn, handleSignOut } from './login';
|
|
5
5
|
export { handleSession } from './session';
|
|
6
|
+
export { handleToken } from './token';
|
|
6
7
|
export { verifyRequestOrigin } from './utils';
|
|
7
8
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/core/handlers/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,YAAY,CAAA;AAC3C,OAAO,EAAE,SAAS,EAAE,eAAe,EAAE,MAAM,QAAQ,CAAA;AACnD,OAAO,EAAE,UAAU,EAAE,YAAY,EAAE,MAAM,QAAQ,CAAA;AACjD,OAAO,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,SAAS,CAAA;AACrD,OAAO,EAAE,aAAa,EAAE,MAAM,WAAW,CAAA;AACzC,OAAO,EAAE,mBAAmB,EAAE,MAAM,SAAS,CAAA"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/core/handlers/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,YAAY,CAAA;AAC3C,OAAO,EAAE,SAAS,EAAE,eAAe,EAAE,MAAM,QAAQ,CAAA;AACnD,OAAO,EAAE,UAAU,EAAE,YAAY,EAAE,MAAM,QAAQ,CAAA;AACjD,OAAO,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,SAAS,CAAA;AACrD,OAAO,EAAE,aAAa,EAAE,MAAM,WAAW,CAAA;AACzC,OAAO,EAAE,WAAW,EAAE,MAAM,SAAS,CAAA;AACrC,OAAO,EAAE,mBAAmB,EAAE,MAAM,SAAS,CAAA"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{applyCors as o,handleCallback as r,handleLink as m,handlePreflight as p,handleSession as t,handleSignIn as
|
|
1
|
+
import{applyCors as o,handleCallback as r,handleLink as m,handlePreflight as p,handleSession as t,handleSignIn as A,handleSignOut as c,handleToken as e,handleUnlink as f,verifyRequestOrigin as h}from"../../../chunk-IDBFAEA3.js";export{o as applyCors,r as handleCallback,m as handleLink,p as handlePreflight,t as handleSession,A as handleSignIn,c as handleSignOut,e as handleToken,f as handleUnlink,h as verifyRequestOrigin};//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"token.d.ts","sourceRoot":"","sources":["../../../../src/core/handlers/token.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,eAAe,CAAA;AAGzC,wBAAsB,WAAW,CAAC,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,IAAI,GAAG,OAAO,CAAC,QAAQ,CAAC,CAsCjF"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../../../../src/core/handlers/utils.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,eAAe,CAAA;
|
|
1
|
+
{"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../../../../src/core/handlers/utils.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,eAAe,CAAA;AAezC,wBAAgB,mBAAmB,CAAC,OAAO,EAAE,OAAO,EAAE,UAAU,EAAE,KAAK,GAAG,MAAM,EAAE,EAAE,WAAW,EAAE,OAAO,GAAG,OAAO,CA+BjH;AAED,wBAAsB,oBAAoB,CACxC,OAAO,EAAE,OAAO,EAChB,IAAI,EAAE,IAAI,EACV,UAAU,EAAE,MAAM,EAClB,YAAY,EAAE,MAAM,GAAG,IAAI,GAC1B,OAAO,CAAC,QAAQ,CAAC,CAiInB"}
|
package/dist/src/core/index.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{AuthError as o,CALLBACK_URI_COOKIE_NAME as r,
|
|
1
|
+
import{AuthError as o,CALLBACK_URI_COOKIE_NAME as r,CLIENT_CHALLENGE_COOKIE_NAME as m,CSRF_COOKIE_NAME as p,CSRF_MAX_AGE as t,Cookies as A,DEFAULT_COOKIE_SERIALIZE_OPTIONS as c,LINKING_TOKEN_COOKIE_NAME as e,NULL_SESSION as f,PKCE_COOKIE_NAME as h,PROVIDER_OPTIONS_COOKIE_NAME as i,SESSION_COOKIE_NAME as j,SESSION_STRATEGY_COOKIE_NAME as k,createAuth as n,createHandler as s,json as u,parseCookies as x,redirect as B}from"../../chunk-IDBFAEA3.js";export{o as AuthError,r as CALLBACK_URI_COOKIE_NAME,m as CLIENT_CHALLENGE_COOKIE_NAME,p as CSRF_COOKIE_NAME,t as CSRF_MAX_AGE,A as Cookies,c as DEFAULT_COOKIE_SERIALIZE_OPTIONS,e as LINKING_TOKEN_COOKIE_NAME,f as NULL_SESSION,h as PKCE_COOKIE_NAME,i as PROVIDER_OPTIONS_COOKIE_NAME,j as SESSION_COOKIE_NAME,k as SESSION_STRATEGY_COOKIE_NAME,n as createAuth,s as createHandler,u as json,x as parseCookies,B as redirect};//# sourceMappingURL=index.js.map
|
package/dist/src/index.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{AuthError as o,CALLBACK_URI_COOKIE_NAME as r,
|
|
1
|
+
import{AuthError as o,CALLBACK_URI_COOKIE_NAME as r,CLIENT_CHALLENGE_COOKIE_NAME as m,CSRF_COOKIE_NAME as p,CSRF_MAX_AGE as t,Cookies as A,DEFAULT_COOKIE_SERIALIZE_OPTIONS as c,LINKING_TOKEN_COOKIE_NAME as e,NULL_SESSION as f,PKCE_COOKIE_NAME as h,PROVIDER_OPTIONS_COOKIE_NAME as i,SESSION_COOKIE_NAME as j,SESSION_STRATEGY_COOKIE_NAME as k,createAuth as n,createHandler as s,json as u,parseCookies as x,redirect as B}from"../chunk-IDBFAEA3.js";export{o as AuthError,r as CALLBACK_URI_COOKIE_NAME,m as CLIENT_CHALLENGE_COOKIE_NAME,p as CSRF_COOKIE_NAME,t as CSRF_MAX_AGE,A as Cookies,c as DEFAULT_COOKIE_SERIALIZE_OPTIONS,e as LINKING_TOKEN_COOKIE_NAME,f as NULL_SESSION,h as PKCE_COOKIE_NAME,i as PROVIDER_OPTIONS_COOKIE_NAME,j as SESSION_COOKIE_NAME,k as SESSION_STRATEGY_COOKIE_NAME,n as createAuth,s as createHandler,u as json,x as parseCookies,B as redirect};//# sourceMappingURL=index.js.map
|
package/dist/src/jwt/index.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{sign as o,verify as r}from"../../chunk-
|
|
1
|
+
import{sign as o,verify as r}from"../../chunk-IDBFAEA3.js";export{o as sign,r as verify};//# sourceMappingURL=index.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{handleTauriDeepLink as o,isTauri as r,linkAccountWithTauri as m,setupTauriListener as p,signInWithTauri as t,startAuthBridge as
|
|
1
|
+
import{handleTauriDeepLink as o,isTauri as r,linkAccountWithTauri as m,setupTauriListener as p,signInWithTauri as t,startAuthBridge as R}from"../../chunk-GVRQST3R.js";export{o as handleTauriDeepLink,r as isTauri,m as linkAccountWithTauri,p as setupTauriListener,t as signInWithTauri,R as startAuthBridge};//# sourceMappingURL=index.js.map
|
|
@@ -2,7 +2,7 @@ import type { ProfileName, ProviderIds } from '../../core';
|
|
|
2
2
|
export declare function isTauri(): boolean;
|
|
3
3
|
export declare function signInWithTauri<const TAuth = unknown, P extends ProviderIds<TAuth> = ProviderIds<TAuth>, PR extends (ProfileName<TAuth, P> | string) | undefined = undefined>(provider: P, baseUrl: string, scheme?: string, redirectOverride?: string, profile?: PR): Promise<void>;
|
|
4
4
|
export declare function setupTauriListener(handler: (url: string) => Promise<void>): Promise<(() => void) | void>;
|
|
5
|
-
export declare function handleTauriDeepLink(url: string, baseUrl: string, scheme: string, onToken: (token: string) => void): void
|
|
5
|
+
export declare function handleTauriDeepLink(url: string, baseUrl: string, scheme: string, onToken: (token: string) => void): Promise<void>;
|
|
6
6
|
export declare function linkAccountWithTauri<const TAuth = unknown, P extends ProviderIds<TAuth> = ProviderIds<TAuth>, PR extends (ProfileName<TAuth, P> | string) | undefined = undefined>(provider: P, baseUrl: string, scheme?: string, redirectOverride?: string, profile?: PR): Promise<void>;
|
|
7
7
|
export declare function startAuthBridge(baseUrl: string, scheme: string, onToken: (token: string) => Promise<void> | void): Promise<(() => void) | void>;
|
|
8
8
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/runtimes/tauri/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,WAAW,EAAE,MAAM,YAAY,CAAA;AAI1D,wBAAgB,OAAO,IAAI,OAAO,CAEjC;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/runtimes/tauri/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,WAAW,EAAE,MAAM,YAAY,CAAA;AAI1D,wBAAgB,OAAO,IAAI,OAAO,CAEjC;AAmBD,wBAAsB,eAAe,CAAC,KAAK,CAAC,KAAK,GAAG,OAAO,EAAE,CAAC,SAAS,WAAW,CAAC,KAAK,CAAC,GAAG,WAAW,CAAC,KAAK,CAAC,EAAE,EAAE,SAAS,CAAC,WAAW,CAAC,KAAK,EAAE,CAAC,CAAC,GAAG,MAAM,CAAC,GAAG,SAAS,GAAG,SAAS,EACjL,QAAQ,EAAE,CAAC,EACX,OAAO,EAAE,MAAM,EACf,MAAM,GAAE,MAAc,EACtB,gBAAgB,CAAC,EAAE,MAAM,EACzB,OAAO,CAAC,EAAE,EAAE,iBA4Cb;AAED,wBAAsB,kBAAkB,CACtC,OAAO,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,GACtC,OAAO,CAAC,CAAC,MAAM,IAAI,CAAC,GAAG,IAAI,CAAC,CAc9B;AAED,wBAAsB,mBAAmB,CAAC,GAAG,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,iBAmCvH;AAED,wBAAsB,oBAAoB,CAAC,KAAK,CAAC,KAAK,GAAG,OAAO,EAAE,CAAC,SAAS,WAAW,CAAC,KAAK,CAAC,GAAG,WAAW,CAAC,KAAK,CAAC,EAAE,EAAE,SAAS,CAAC,WAAW,CAAC,KAAK,EAAE,CAAC,CAAC,GAAG,MAAM,CAAC,GAAG,SAAS,GAAG,SAAS,EACtL,QAAQ,EAAE,CAAC,EACX,OAAO,EAAE,MAAM,EACf,MAAM,GAAE,MAAc,EACtB,gBAAgB,CAAC,EAAE,MAAM,EACzB,OAAO,CAAC,EAAE,EAAE,iBA6Cb;AAED,wBAAsB,eAAe,CACnC,OAAO,EAAE,MAAM,EACf,MAAM,EAAE,MAAM,EACd,OAAO,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI,GAC/C,OAAO,CAAC,CAAC,MAAM,IAAI,CAAC,GAAG,IAAI,CAAC,CAQ9B"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{handleTauriDeepLink as o,isTauri as r,linkAccountWithTauri as m,setupTauriListener as p,signInWithTauri as t,startAuthBridge as
|
|
1
|
+
import{handleTauriDeepLink as o,isTauri as r,linkAccountWithTauri as m,setupTauriListener as p,signInWithTauri as t,startAuthBridge as R}from"../../../chunk-GVRQST3R.js";export{o as handleTauriDeepLink,r as isTauri,m as linkAccountWithTauri,p as setupTauriListener,t as signInWithTauri,R as startAuthBridge};//# sourceMappingURL=index.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{NULL_SESSION as e,SESSION_COOKIE_NAME as r,createAuth as t,createHandler as n,parseCookies as o}from"../../chunk-
|
|
1
|
+
import{NULL_SESSION as e,SESSION_COOKIE_NAME as r,createAuth as t,createHandler as n,parseCookies as o}from"../../chunk-IDBFAEA3.js";import s from"process";function i(e){const r="providerMap"in e&&"signJWT"in e?e:t(e);r.development="development"===s.env.NODE_ENV;const o=n(r),i=e=>o(e.request);return{GET:i,POST:i,OPTIONS:i}}function a(t){return async function(n){let s=o(n.headers.get("Cookie")).get(r);if(!s){const e=n.headers.get("Authorization");e?.startsWith("Bearer ")&&(s=e.substring(7))}const i=Array.from(t.providerMap.keys());if(!s)return{...e,providers:i};try{const r=await t.validateSession(s);return r?{...r,providers:i}:{...e,providers:i}}catch{return{...e,providers:i}}}}function c(e,r){const n=a("providerMap"in r&&"signJWT"in r?r:t(r));return async r=>{const t=new URL(r.request.url);if("boolean"==typeof e?e:e.includes(t.pathname)){const e=await n(r.request);return void(r.locals.getSession=async()=>e)}r.locals.getSession=()=>n(r.request)}}export{i as SolidAuth,c as authMiddleware,a as createSolidStartGetSession};//# sourceMappingURL=index.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{NULL_SESSION as e,SESSION_COOKIE_NAME as r,createAuth as t,createHandler as s,parseCookies as n}from"../../chunk-
|
|
1
|
+
import{NULL_SESSION as e,SESSION_COOKIE_NAME as r,createAuth as t,createHandler as s,parseCookies as n}from"../../chunk-IDBFAEA3.js";function o(o){const i="providerMap"in o&&"signJWT"in o?o:t(o);(async()=>{try{i.development=(await import("$app/environment")).dev}catch{i.development=!1}})();const a=s(i),c=e=>a(e.request);return{GET:c,POST:c,OPTIONS:c,handle:async({event:t,resolve:s})=>(t.locals.getSession=async()=>{let s=n(t.request.headers.get("Cookie")).get(r);if(!s){const e=t.request.headers.get("Authorization");e?.startsWith("Bearer ")&&(s=e.substring(7))}const o=Array.from(i.providerMap.keys());if(!s)return{...e,providers:o};try{const r=await i.validateSession(s);return r?{...r,providers:o}:{...e,providers:o}}catch{return{...e,providers:o}}},s(t))}}export{o as SvelteKitAuth};//# sourceMappingURL=index.js.map
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@rttnd/gau",
|
|
3
3
|
"type": "module",
|
|
4
|
-
"version": "
|
|
4
|
+
"version": "1.1.0",
|
|
5
5
|
"packageManager": "bun@1.3.0",
|
|
6
6
|
"description": "gau is a delightful auth library",
|
|
7
7
|
"license": "MIT",
|
|
@@ -115,11 +115,10 @@
|
|
|
115
115
|
"@sveltejs/kit": "^2.25.1",
|
|
116
116
|
"@tauri-apps/api": "^2.6.0",
|
|
117
117
|
"@tauri-apps/plugin-opener": "^2.3.0",
|
|
118
|
-
"@tauri-apps/plugin-os": "^2.3.0",
|
|
119
118
|
"@tauri-apps/plugin-shell": "^2.3.0",
|
|
120
119
|
"drizzle-orm": "^0.44.3",
|
|
121
120
|
"solid-js": "^1.9.7",
|
|
122
|
-
"svelte": "^5.
|
|
121
|
+
"svelte": "^5.41.1",
|
|
123
122
|
"typescript": "^5.8.3"
|
|
124
123
|
},
|
|
125
124
|
"peerDependenciesMeta": {
|
|
@@ -135,9 +134,6 @@
|
|
|
135
134
|
"@tauri-apps/plugin-opener": {
|
|
136
135
|
"optional": true
|
|
137
136
|
},
|
|
138
|
-
"@tauri-apps/plugin-os": {
|
|
139
|
-
"optional": true
|
|
140
|
-
},
|
|
141
137
|
"@tauri-apps/plugin-shell": {
|
|
142
138
|
"optional": true
|
|
143
139
|
},
|
|
@@ -168,7 +164,6 @@
|
|
|
168
164
|
"@sveltejs/kit": "^2.47.2",
|
|
169
165
|
"@tauri-apps/api": "^2.6.0",
|
|
170
166
|
"@tauri-apps/plugin-opener": "^2.3.0",
|
|
171
|
-
"@tauri-apps/plugin-os": "^2.3.0",
|
|
172
167
|
"@types/better-sqlite3": "^7.6.13",
|
|
173
168
|
"@types/bun": "^1.3.0",
|
|
174
169
|
"@types/node": "^24.9.1",
|
package/dist/chunk-H457ZXFC.js
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import{BROWSER as t}from"esm-env";import{BROWSER as n}from"esm-env";function o(t){if(n)try{localStorage.setItem("gau-token",t),document.cookie=`__gau-session-token=${t}; path=/; max-age=31536000; samesite=lax; secure`}catch{}}function a(){return n?localStorage.getItem("gau-token"):null}function e(){if(n)try{localStorage.removeItem("gau-token"),document.cookie="__gau-session-token=; path=/; max-age=0"}catch{}}function r(){return t&&"__TAURI_INTERNALS__"in globalThis}async function i(t,n,o="gau",a,e){if(!r())return;const{platform:i}=await import("@tauri-apps/plugin-os"),{openUrl:s}=await import("@tauri-apps/plugin-opener"),c=i();let u;u=a||("android"===c||"ios"===c?new URL(n).origin:`${o}://oauth/callback`);const p=new URLSearchParams;p.set("redirectTo",u),e&&p.set("profile",String(e));const l=`${n}/${t}?${p.toString()}`;await s(l)}async function s(t){if(!r())return;const{listen:n}=await import("@tauri-apps/api/event");try{return await n("deep-link",async n=>{await t(n.payload)})}catch(t){console.error(t)}}function c(t,n,o,a){const e=new URL(t);if(e.protocol!==`${o}:`&&e.origin!==new URL(n).origin)return;const r=new URLSearchParams(e.hash.substring(1)).get("token");r&&a(r)}async function u(t,n,o="gau",e,i){if(!r())return;const{platform:s}=await import("@tauri-apps/plugin-os"),{openUrl:c}=await import("@tauri-apps/plugin-opener"),u=s();let p;p=e||("android"===u||"ios"===u?new URL(n).origin:`${o}://oauth/callback`);const l=a();if(!l)return void console.error("No session token found, cannot link account.");const g=new URLSearchParams;g.set("redirectTo",p),g.set("token",l),i&&g.set("profile",String(i));const m=`${n}/link/${t}?${g.toString()}`;await c(m)}async function p(t,n,o){if(!r())return;return await s(async a=>{c(a,t,n,o)})}export{o as storeSessionToken,a as getSessionToken,e as clearSessionToken,r as isTauri,i as signInWithTauri,s as setupTauriListener,c as handleTauriDeepLink,u as linkAccountWithTauri,p as startAuthBridge};//# sourceMappingURL=chunk-H457ZXFC.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/runtimes/tauri/index.ts","../src/client/token.ts"],"sourcesContent":["import type { ProfileName, ProviderIds } from '../../core'\nimport { BROWSER } from 'esm-env'\nimport { getSessionToken } from '../../client/token'\n\nexport function isTauri(): boolean {\n return BROWSER && '__TAURI_INTERNALS__' in globalThis\n}\n\nexport async function signInWithTauri<const TAuth = unknown, P extends ProviderIds<TAuth> = ProviderIds<TAuth>, PR extends (ProfileName<TAuth, P> | string) | undefined = undefined>(\n provider: P,\n baseUrl: string,\n scheme: string = 'gau',\n redirectOverride?: string,\n profile?: PR,\n) {\n if (!isTauri())\n return\n\n const { platform } = await import('@tauri-apps/plugin-os')\n const { openUrl } = await import('@tauri-apps/plugin-opener')\n\n const currentPlatform = platform() // platform is NO LONGER an async function\n let redirectTo: string\n\n if (redirectOverride)\n redirectTo = redirectOverride\n else if (currentPlatform === 'android' || currentPlatform === 'ios')\n redirectTo = new URL(baseUrl).origin\n else\n redirectTo = `${scheme}://oauth/callback`\n\n const params = new URLSearchParams()\n params.set('redirectTo', redirectTo)\n if (profile)\n params.set('profile', String(profile))\n const authUrl = `${baseUrl}/${provider}?${params.toString()}`\n await openUrl(authUrl)\n}\n\nexport async function setupTauriListener(\n handler: (url: string) => Promise<void>,\n): Promise<(() => void) | void> {\n if (!isTauri())\n return\n\n const { listen } = await import('@tauri-apps/api/event')\n try {\n const unlisten = await listen<string>('deep-link', async (event) => {\n await handler(event.payload)\n })\n return unlisten\n }\n catch (err) {\n console.error(err)\n }\n}\n\nexport function handleTauriDeepLink(url: string, baseUrl: string, scheme: string, onToken: (token: string) => void) {\n const parsed = new URL(url)\n if (parsed.protocol !== `${scheme}:` && parsed.origin !== new URL(baseUrl).origin)\n return\n\n const params = new URLSearchParams(parsed.hash.substring(1))\n const token = params.get('token')\n if (token)\n onToken(token)\n}\n\nexport async function linkAccountWithTauri<const TAuth = unknown, P extends ProviderIds<TAuth> = ProviderIds<TAuth>, PR extends (ProfileName<TAuth, P> | string) | undefined = undefined>(\n provider: P,\n baseUrl: string,\n scheme: string = 'gau',\n redirectOverride?: string,\n profile?: PR,\n) {\n if (!isTauri())\n return\n\n const { platform } = await import('@tauri-apps/plugin-os')\n const { openUrl } = await import('@tauri-apps/plugin-opener')\n\n const currentPlatform = platform()\n let redirectTo: string\n\n if (redirectOverride)\n redirectTo = redirectOverride\n else if (currentPlatform === 'android' || currentPlatform === 'ios')\n redirectTo = new URL(baseUrl).origin\n else\n redirectTo = `${scheme}://oauth/callback`\n\n const token = getSessionToken()\n if (!token) {\n console.error('No session token found, cannot link account.')\n return\n }\n\n const params = new URLSearchParams()\n params.set('redirectTo', redirectTo)\n params.set('token', token)\n if (profile)\n params.set('profile', String(profile))\n const linkUrl = `${baseUrl}/link/${provider}?${params.toString()}`\n await openUrl(linkUrl)\n}\n\nexport async function startAuthBridge(\n baseUrl: string,\n scheme: string,\n onToken: (token: string) => Promise<void> | void,\n): Promise<(() => void) | void> {\n if (!isTauri())\n return\n\n const unlisten = await setupTauriListener(async (url) => {\n handleTauriDeepLink(url, baseUrl, scheme, onToken)\n })\n return unlisten\n}\n","import { BROWSER } from 'esm-env'\n\nexport function storeSessionToken(token: string) {\n if (!BROWSER)\n return\n try {\n localStorage.setItem('gau-token', token)\n document.cookie = `__gau-session-token=${token}; path=/; max-age=31536000; samesite=lax; secure`\n }\n catch {}\n}\n\nexport function getSessionToken(): string | null {\n if (!BROWSER)\n return null\n return localStorage.getItem('gau-token')\n}\n\nexport function clearSessionToken() {\n if (!BROWSER)\n return\n try {\n localStorage.removeItem('gau-token')\n document.cookie = `__gau-session-token=; path=/; max-age=0`\n }\n catch {}\n}\n"],"mappings":"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","names":["BROWSER","BROWSER"]}
|
package/dist/chunk-LWY5YOPO.js
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import{createJWTSignatureMessage as e,encodeJWT as t,JWSRegisteredHeaders as r,JWTRegisteredClaims as n,parseJWT as o}from"@oslojs/jwt";import{parse as s,serialize as i}from"cookie";var a={path:"/",sameSite:"lax",secure:!0,httpOnly:!0};function l(e){const t=new Map;if(e){const r=s(e);for(const e in r)t.set(e,r[e])}return t}var c=class{constructor(e,t){this.requestCookies=e,this.defaultOptions=t}#e=[];get(e){return this.requestCookies.get(e)}set(e,t,r){const n={...this.defaultOptions,...r};this.#e.push([e,t,n])}delete(e,t){this.set(e,"",{...t,expires:new Date(0),maxAge:0})}toHeaders(){const e=new Headers;for(const[t,r,n]of this.#e)e.append("Set-Cookie",i(t,r,n));return e}},u="__gau-csrf-token",d="__gau-session-token",f="__gau-session-strategy",h="__gau-linking-token",p="__gau-pkce-code-verifier",g="__gau-callback-uri",w="__gau-provider-options",m=600;function y({adapter:e,providers:t,basePath:r="/api/auth",jwt:n={},session:o={},cookies:s={},onOAuthExchange:i,mapExternalProfile:l,onBeforeLinkAccount:c,onAfterLinkAccount:u,trustHosts:d=[],autoLink:f="verifiedEmail",allowDifferentEmails:h=!0,updateUserInfoOnLink:p=!1,roles:g={},cors:w=!0,profiles:m}){const{algorithm:y="ES256",secret:k,iss:v,aud:A,ttl:S=86400}=n,T={...a,...s},E=o.strategy??"auto";if("ES256"===y&&void 0!==k&&"string"!=typeof k)throw new R("For ES256, the secret option must be a string.");const U=new Map(t.map(e=>[e.id,e])),b=!1!==w&&{allowedOrigins:(!0===w?"all":w.allowedOrigins)??"all",allowCredentials:(!0===w||w.allowCredentials)??!0,allowedHeaders:(!0===w?void 0:w.allowedHeaders)??["Content-Type","Authorization","Cookie"],allowedMethods:(!0===w?void 0:w.allowedMethods)??["GET","POST","OPTIONS"],exposeHeaders:!0===w?void 0:w.exposeHeaders,maxAge:!0===w?void 0:w.maxAge},x=m??{},C={defaultRole:g.defaultRole??"user",resolveOnCreate:g.resolveOnCreate,adminRoles:g.adminRoles??["admin"],adminUserIds:g.adminUserIds??[]};async function H(e,t={}){return N(e,function(e={}){const t={ttl:e.ttl,iss:e.iss??v,aud:e.aud??A,sub:e.sub};if("HS256"===y)return{algorithm:y,secret:e.secret??k,...t};{if(void 0!==e.secret&&"string"!=typeof e.secret)throw new R("For ES256, the secret option must be a string.");const r=e.secret??k;return{algorithm:y,privateKey:e.privateKey,secret:r,...t}}}(t))}async function O(e,t={}){const r=function(e={}){const t={iss:e.iss??v,aud:e.aud??A};if("HS256"===y)return{algorithm:y,secret:e.secret??k,...t};{if(void 0!==e.secret&&"string"!=typeof e.secret)throw new R("For ES256, the secret option must be a string.");const r=e.secret??k;return{algorithm:y,publicKey:e.publicKey,secret:r,...t}}}(t);try{return await B(e,r)}catch{return null}}return{...e,providerMap:U,basePath:r,cookieOptions:T,jwt:{ttl:S},onOAuthExchange:i,mapExternalProfile:l,onBeforeLinkAccount:c,onAfterLinkAccount:u,signJWT:H,verifyJWT:O,createSession:async function(e,t={},r=S){return H({sub:e,...t},{ttl:r})},validateSession:async function(t){const r=await O(t);if(!r)return null;const n=await e.getUserAndAccounts(r.sub);if(!n)return null;const{user:o,accounts:s}=n,i=Boolean(o&&(o.role&&C.adminRoles.includes(o.role)||C.adminUserIds.length>0&&C.adminUserIds.includes(o.id)));return{user:o?{...o,isAdmin:i}:null,session:{id:t,...r},accounts:s}},getAccessToken:async function(t,r){const n=U.get(r);if(!n)return null;const o=(await e.getAccounts(t)).find(e=>e.provider===r);if(!o||!o.accessToken)return null;const s=Math.floor(Date.now()/1e3);if(!("number"==typeof o.expiresAt&&o.expiresAt<=s))return{accessToken:o.accessToken,expiresAt:o.expiresAt??null};if(!o.refreshToken||!n.refreshAccessToken)return null;try{const r=await n.refreshAccessToken(o.refreshToken,{}),s={userId:t,provider:o.provider,providerAccountId:o.providerAccountId,accessToken:r.accessToken??o.accessToken,refreshToken:r.refreshToken??o.refreshToken,expiresAt:r.expiresAt??null,idToken:r.idToken??o.idToken??null,tokenType:r.tokenType??o.tokenType??null,scope:r.scope??o.scope??null};return await(e.updateAccount?.(s)),{accessToken:s.accessToken,expiresAt:s.expiresAt}}catch{return null}},trustHosts:d,autoLink:f,allowDifferentEmails:h,profiles:x,updateUserInfoOnLink:p,sessionStrategy:E,development:!1,roles:C,cors:b}}async function k(e,t){if(e&&"function"==typeof e.onAfterLinkAccount)try{await e.onAfterLinkAccount(t)}catch(e){console.error("onAfterLinkAccount hook error:",e)}}async function v(e,t,r){const n=t.providerMap.get(r);if(!n)return j({error:"Provider not found"},{status:400});const o=new URL(e.url),s=o.searchParams.get("code"),i=o.searchParams.get("state");if(!s||!i)return j({error:"Missing code or state"},{status:400});const a=l(e.headers.get("Cookie")),f=new c(a,t.cookieOptions);let m,y="/";if(i.includes(".")){const[e,t]=i.split(".");m=e;try{y=atob(t??"")||"/"}catch{y="/"}}else m=i;const v=f.get(u);if(!v||v!==m)return j({error:"Invalid CSRF token"},{status:403});const A=f.get(p);if(!A)return j({error:"Missing PKCE code verifier"},{status:400});const S=f.get(g),T=f.get(w);let E;if(T)try{const e=atob(T),t=JSON.parse(e);E=t?.overrides}catch{}const U=f.get(h);U&&f.delete(h);const b=!!U;if(b){if(!await t.validateSession(U)){f.delete(u),f.delete(p),S&&f.delete(g),f.delete(w);const e=V(y);return f.toHeaders().forEach((t,r)=>e.headers.append(r,t)),e}}const{user:x,tokens:C}=await n.validateCallback(s,A,S??void 0,E);{const n=b?await t.validateSession(U):null,o=await async function(e,t){if(!e||"function"!=typeof e.onOAuthExchange)return{handled:!1};try{const r=await e.onOAuthExchange(t);return r&&"object"==typeof r?r:{handled:!1}}catch(e){return console.error("onOAuthExchange hook error:",e),{handled:!1}}}(t,{request:e,providerId:r,state:i,code:s,codeVerifier:A,callbackUri:S,redirectTo:y,cookies:f,providerUser:x,tokens:C,isLinking:b,sessionUserId:n?.user?.id});if(o.handled){f.delete(u),f.delete(p),S&&f.delete(g),f.delete(w);const e=o.response;return f.toHeaders().forEach((t,r)=>e.headers.append(r,t)),e}}const H=await async function(e,t){if(!e||"function"!=typeof e.mapExternalProfile)return t.providerUser;try{const r=await e.mapExternalProfile(t);return r?{...t.providerUser,...r}:t.providerUser}catch(e){return console.error("mapExternalProfile hook error:",e),t.providerUser}}(t,{request:e,providerId:r,providerUser:x,tokens:C,isLinking:b});if(!b&&!0===t.providerMap.get(r)?.linkOnly){f.delete(u),f.delete(p),S&&f.delete(g),f.delete(w);const e=j({error:"Sign-in with this provider is disabled. Please link it to an existing account."},{status:400});return f.toHeaders().forEach((t,r)=>e.headers.append(r,t)),e}let O=null;const I=await t.getUserByAccount(r,H.id);if(b){if(O=(await t.validateSession(U)).user,!O)return j({error:"User not found"},{status:404});if(I&&I.id!==O.id)return j({error:"Account already linked to another user"},{status:409});if(!1===t.allowDifferentEmails){const e=O.email,t=H.email;if(e&&t&&e!==t)return j({error:"Email mismatch between existing account and provider"},{status:400})}if(O){const e={id:O.id};let r=!1;if(t.updateUserInfoOnLink?(H.name&&H.name!==O.name&&(e.name=H.name,r=!0),H.avatar&&H.avatar!==O.image&&(e.image=H.avatar,r=!0)):(!O.name&&H.name&&(e.name=H.name,r=!0),!O.image&&H.avatar&&(e.image=H.avatar,r=!0)),O.email&&H.email&&O.email===H.email&&!0===H.emailVerified&&(!O.emailVerified||t.updateUserInfoOnLink)&&(e.emailVerified=!0,r=!0),r)try{O=await t.updateUser(e)}catch(e){console.error("Failed to update user info on link:",e)}}}else O=I;if(!O){const n=t.autoLink??"verifiedEmail";if(H.email&&("always"===n||"verifiedEmail"===n&&!0===H.emailVerified)){const e=await t.getUserByEmail(H.email);e&&(O=H.emailVerified&&!e.emailVerified?await t.updateUser({id:e.id,emailVerified:!0}):e)}if(!O)try{if(H.email&&!0===H.emailVerified&&!1===t.autoLink){if(await t.getUserByEmail(H.email))return j({error:"An account with this email already exists. Sign in with the existing method or link the provider."},{status:409})}let n;try{n=t.roles.resolveOnCreate?.({providerId:r,profile:H,request:e})}catch(e){console.error("roles.resolveOnCreate threw:",e)}const o=!0===H.emailVerified?H.email:null;O=await t.createUser({name:H.name,email:o,image:H.avatar,emailVerified:H.emailVerified,role:n??t.roles.defaultRole})}catch(e){return console.error("Failed to create user:",e),j({error:"Failed to create user"},{status:500})}}if(O&&H.email){const{email:e,emailVerified:r}=O,{email:n,emailVerified:o}=H,s={id:O.id};let i=!1;if(e||!0!==o?e!==n||!0!==o||r||(s.emailVerified=!0,i=!0):(s.email=n,s.emailVerified=!0,i=!0),i)try{O=await t.updateUser(s)}catch(e){console.error("Failed to update user after sign-in:",e)}}if(I)try{const n=(await t.getAccounts(O.id)).find(e=>e.provider===r&&e.providerAccountId===H.id);if(n&&t.updateAccount){let o,s,i,a;try{o=C.refreshToken()}catch{o=n.refreshToken??null}try{const e=C.accessTokenExpiresAt();e&&(s=Math.floor(e.getTime()/1e3))}catch{s=n.expiresAt??void 0}try{i=C.idToken()}catch{i=n.idToken??null}try{a=C.scopes()?.join(" ")??n.scope??null}catch{a=n.scope??null}await t.updateAccount({userId:O.id,provider:r,providerAccountId:H.id,accessToken:C.accessToken()??n.accessToken??void 0,refreshToken:o,expiresAt:s??n.expiresAt??void 0,tokenType:C.tokenType?.()??n.tokenType??null,scope:a,idToken:i}),await k(t,{request:e,providerId:r,userId:O.id,providerUser:H,tokens:C,action:"update"})}}catch(e){console.error("Failed to update account tokens on sign-in:",e)}else{let n,o,s;try{n=C.refreshToken()}catch{n=null}try{const e=C.accessTokenExpiresAt();e&&(o=Math.floor(e.getTime()/1e3))}catch{}try{s=C.idToken()}catch{s=null}{const n=await async function(e,t){if(!e||"function"!=typeof e.onBeforeLinkAccount)return{allow:!0};try{return await e.onBeforeLinkAccount(t)||{allow:!0}}catch(e){return console.error("onBeforeLinkAccount hook error:",e),{allow:!0}}}(t,{request:e,providerId:r,userId:O.id,providerUser:H,tokens:C});if(!1===n.allow){const e=n.response??j({error:"Linking not allowed"},{status:403});return f.toHeaders().forEach((t,r)=>e.headers.append(r,t)),e}}try{let i;try{i=C.scopes()?.join(" ")??null}catch{i=null}await t.linkAccount({userId:O.id,provider:r,providerAccountId:H.id,accessToken:C.accessToken(),refreshToken:n,expiresAt:o,tokenType:C.tokenType?.()??null,scope:i,idToken:s}),await k(t,{request:e,providerId:r,userId:O.id,providerUser:H,tokens:C,action:"link"})}catch(e){return console.error("Error linking account:",e),j({error:"Failed to link account"},{status:500})}}const L=await t.createSession(O.id),P=new URL(e.url),M=new URL(y,e.url),R="token"===t.sessionStrategy,F="cookie"===t.sessionStrategy,N="gau:"===M.protocol,B=P.host!==M.host;if(R||!F&&(N||B)){const e=new URL(M);e.hash=`token=${L}`;const t=`<!DOCTYPE html>\n<html lang="en">\n<head>\n <meta charset="utf-8" />\n <title>Authentication Complete</title>\n <style>\n body {\n font-family: ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, "Noto Sans", sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji";\n background-color: #09090b;\n color: #fafafa;\n display: flex;\n justify-content: center;\n align-items: center;\n height: 100vh;\n margin: 0;\n text-align: center;\n }\n .card {\n background-color: #18181b;\n border: 1px solid #27272a;\n border-radius: 0.75rem;\n padding: 2rem;\n max-width: 320px;\n }\n h1 {\n font-size: 1.25rem;\n font-weight: 600;\n margin: 0 0 0.5rem;\n }\n p {\n margin: 0;\n color: #a1a1aa;\n }\n </style>\n <script>\n window.onload = function() {\n const url = ${JSON.stringify(e.toString())};\n window.location.href = url;\n setTimeout(window.close, 500);\n };\n <\/script>\n</head>\n<body>\n <div class="card">\n <h1>Authentication Successful</h1>\n <p>You can now close this window.</p>\n </div>\n</body>\n</html>`;f.delete(u),f.delete(p),S&&f.delete(g),f.delete(w);const r=new Response(t,{status:200,headers:{"Content-Type":"text/html; charset=utf-8"}});return f.toHeaders().forEach((e,t)=>{r.headers.append(t,e)}),r}f.set(d,L,{maxAge:t.jwt.ttl,sameSite:t.development?"lax":"none",secure:!t.development}),f.delete(u),f.delete(p),S&&f.delete(g),f.delete(w);let K;if("false"===o.searchParams.get("redirect")){const e=await t.getAccounts(O.id),r=Boolean(O.role&&t.roles.adminRoles.includes(O.role)||t.roles.adminUserIds.includes(O.id));K=j({user:{...O,isAdmin:r,accounts:e}})}else K=V(y);return f.toHeaders().forEach((e,t)=>{K.headers.append(t,e)}),K}function A(e,t){if(!1===t.cors)return!1;const r=t.cors;if("all"===r.allowedOrigins)return!0;if("trust"===r.allowedOrigins){if("all"===t.trustHosts)return!0;try{const r=new URL(e);return t.trustHosts.includes(r.host)||t.trustHosts.includes(r.hostname)}catch{return!1}}if(r.allowedOrigins.includes("*"))return!0;try{const t=new URL(e);return r.allowedOrigins.includes(e)||r.allowedOrigins.includes(t.origin)||r.allowedOrigins.includes(t.host)||r.allowedOrigins.includes(t.hostname)}catch{return r.allowedOrigins.includes(e)}}function S(e,t,r){if(!1===r.cors)return t;const n=e.headers.get("Origin")||e.headers.get("origin");if(!n)return t;if(!A(n,r))return t;const o=r.cors;t.headers.set("Vary","Origin");const s=o.allowCredentials,i="all"!==o.allowedOrigins||s?n:"*";return t.headers.set("Access-Control-Allow-Origin",i),s&&t.headers.set("Access-Control-Allow-Credentials","true"),t.headers.set("Access-Control-Allow-Headers",o.allowedHeaders.join(", ")),t.headers.set("Access-Control-Allow-Methods",o.allowedMethods.join(", ")),o.exposeHeaders?.length&&t.headers.set("Access-Control-Expose-Headers",o.exposeHeaders.join(", ")),t}function T(e,t){if(!1===t.cors)return new Response(null,{status:204});const r=e.headers.get("Origin")||e.headers.get("origin"),n=t.cors,o={};if(r&&A(r,t)){const e=n.allowCredentials,t="all"!==n.allowedOrigins||e?r:"*";o["Access-Control-Allow-Origin"]=t,e&&(o["Access-Control-Allow-Credentials"]="true")}return o["Access-Control-Allow-Headers"]=n.allowedHeaders.join(", "),o["Access-Control-Allow-Methods"]=n.allowedMethods.join(", "),null!=n.maxAge&&(o["Access-Control-Max-Age"]=String(n.maxAge)),n.exposeHeaders?.length&&(o["Access-Control-Expose-Headers"]=n.exposeHeaders.join(", ")),new Response(null,{status:204,headers:o})}import{generateCodeVerifier as E,generateState as U}from"arctic";function b(e,t,r){if("all"===t)return!0;const n=e.headers.get("origin");if(!n)return!1;let o;try{o=new URL(n).host}catch{return!1}if(r){if(o.startsWith("localhost")||o.startsWith("127.0.0.1"))return!0}const s=new URL(e.url),i=s.host;return n===`${s.protocol}//${i}`||t.includes(o)}async function x(e,t,r,n){const o=t.providerMap.get(r);if(!o)return j({error:"Provider not found"},{status:400});const{state:s,codeVerifier:i}={state:U(),codeVerifier:E()},a=new URL(e.url),d=a.searchParams.get("redirectTo"),f=a.searchParams.get("profile"),m=a.searchParams.get("prompt");if(d){let r;try{if(d.startsWith("//"))throw new Error("Protocol-relative URL not allowed");r=new URL(d,a.origin)}catch{return j({error:'Invalid "redirectTo" URL'},{status:400})}const n=r.host,o=n===new URL(e.url).host,s="all"===t.trustHosts||t.trustHosts.includes(n);if(("http:"===r.protocol||"https:"===r.protocol)&&!o&&!s)return j({error:"Untrusted redirect host"},{status:400})}const y=d?`${s}.${btoa(d)}`:s;let k,v,A,S,T=a.searchParams.get("callbackUri");if(!T&&o.requiresRedirectUri&&(T=`${a.origin}${t.basePath}/${r}/callback`),f){const e=(t.profiles?.[r]??{})[f];if(!e)return j({error:`Unknown profile "${f}" for provider "${r}"`},{status:400});e.redirectUri&&(T=e.redirectUri),e.scopes&&(k=e.scopes),e.params&&(v={...e.params??{}});const{tenant:o,prompt:s}=e;if(null==o&&null==s||(A={...A??{},tenant:o,prompt:s}),!n&&!0===e.linkOnly)return j({error:"This profile is link-only. Please link it to an existing account."},{status:400})}if(m&&(v={...v??{},prompt:m}),!n&&!0===o.linkOnly)return j({error:"Sign-in with this provider is disabled. Please link it to an existing account."},{status:400});try{S=await o.getAuthorizationUrl(y,i,{redirectUri:T??void 0,scopes:k,params:v,overrides:A})}catch(e){console.error("Error getting authorization URL:",e),S=null}if(!S)return j({error:"Could not create authorization URL"},{status:500});const b=l(e.headers.get("Cookie")),x=new c(b,t.cookieOptions),C={maxAge:600,sameSite:t.development?"lax":"none",secure:!t.development};x.set(u,s,C),x.set(p,i,C),n?x.set(h,n,C):x.delete(h,{sameSite:t.development?"lax":"none",secure:!t.development}),T&&x.set(g,T,C);const H=JSON.stringify({params:v??{},overrides:A??{}});x.set(w,btoa(H),C);if("false"===a.searchParams.get("redirect")){const e=j({url:S.toString()});return x.toHeaders().forEach((t,r)=>{e.headers.append(r,t)}),e}const O=V(S.toString());return x.toHeaders().forEach((e,t)=>{O.headers.append(t,e)}),O}async function C(e,t,r){const n=new URL(e.url);let o=l(e.headers.get("Cookie")).get(d);if(!o){const t=e.headers.get("Authorization");t?.startsWith("Bearer ")&&(o=t.substring(7))}if(o||(o=n.searchParams.get("token")??void 0),!o)return j({error:"Unauthorized"},{status:401});if(!await t.validateSession(o))return j({error:"Unauthorized"},{status:401});n.searchParams.delete("token");return x(new Request(n.toString(),e),t,r,o)}async function H(e,t,r){let n=l(e.headers.get("Cookie")).get(d);if(!n){const t=e.headers.get("Authorization");t?.startsWith("Bearer ")&&(n=t.substring(7))}if(!n)return j({error:"Unauthorized"},{status:401});const o=await t.validateSession(n);if(!o||!o.user)return j({error:"Unauthorized"},{status:401});const s=o.accounts??[];if(s.length<=1)return j({error:"Cannot unlink the last account"},{status:400});const i=s.find(e=>e.provider===r);if(!i)return j({error:`Provider "${r}" not linked to this account`},{status:400});await t.unlinkAccount(r,i.providerAccountId);if((await t.getAccounts(o.user.id)).length>0&&o.user.email)try{await t.updateUser({id:o.user.id,email:null,emailVerified:!1})}catch(e){console.error("Failed to clear stale email after unlinking:",e)}return j({message:"Account unlinked successfully"})}async function O(e,t,r){return x(e,t,r,null)}async function I(e,t){const r=l(e.headers.get("Cookie")),n=new c(r,t.cookieOptions);n.delete(d,{sameSite:t.development?"lax":"none",secure:!t.development}),n.delete(h,{sameSite:t.development?"lax":"none",secure:!t.development});const o=j({message:"Signed out"});return n.toHeaders().forEach((e,t)=>{o.headers.append(t,e)}),o}async function L(e,t){let r=l(e.headers.get("Cookie")).get(d);if(!r){const t=e.headers.get("Authorization");t?.startsWith("Bearer ")&&(r=t.substring(7))}const n=Array.from(t.providerMap.keys());if(!r)return j({...M,providers:n});try{const e=await t.validateSession(r);return e?j({...e,providers:n}):j({...M,providers:n},{status:401})}catch(e){return console.error("Error validating session:",e),j({error:"Failed to validate session"},{status:500})}}function P(e){const{basePath:t}=e;return async function(r){if("OPTIONS"===r.method)return T(r,e);const n=new URL(r.url);if(!n.pathname.startsWith(t))return S(r,j({error:"Not Found"},{status:404}),e);if("POST"===r.method&&!b(r,e.trustHosts,e.development)){if(e.development){const t=r.headers.get("origin")??"N/A";return S(r,j({error:"Forbidden",message:`Untrusted origin: '${t}'. Add this origin to 'trustHosts' in createAuth() or ensure you are using 'localhost' or '127.0.0.1' for development.`},{status:403}),e)}return S(r,j({error:"Forbidden"},{status:403}),e)}const o=n.pathname.substring(t.length).split("/").filter(Boolean),s=o[0];if(!s)return S(r,j({error:"Not Found"},{status:404}),e);let i;i="GET"===r.method?"session"===s?await L(r,e):2===o.length&&"link"===o[0]?await C(r,e,o[1]):2===o.length&&"callback"===o[1]?await v(r,e,s):1===o.length?await O(r,e,s):j({error:"Not Found"},{status:404}):"POST"===r.method?1===o.length&&"signout"===s?await I(r,e):2===o.length&&"unlink"===o[0]?await H(r,e,o[1]):j({error:"Not Found"},{status:404}):j({error:"Method Not Allowed"},{status:405});try{i.headers.set("Cache-Control","no-store, private"),i.headers.set("Pragma","no-cache"),i.headers.set("Expires","0")}catch{}return S(r,i,e)}}var M={user:null,session:null,accounts:null},R=class extends Error{cause;constructor(e,t){super(e),this.name="AuthError",this.cause=t}};function j(e,t={}){const r=new Headers(t.headers);return r.has("Content-Type")||r.set("Content-Type","application/json; charset=utf-8"),new Response(JSON.stringify(e),{...t,headers:r})}function V(e,t=302){return new Response(null,{status:t,headers:{Location:e}})}async function F(e){try{const t=function(e){const t=e.replace(/-/g,"+").replace(/_/g,"/"),r=(4-t.length%4)%4,n=t.padEnd(t.length+r,"=");try{const e=atob(n),t=e.length,r=new Uint8Array(t);for(let n=0;n<t;n++)r[n]=e.charCodeAt(n);return r}catch{throw new R("Invalid base64url string")}}(e),r=await crypto.subtle.importKey("pkcs8",t.slice(),{name:"ECDSA",namedCurve:"P-256"},!0,["sign"]),n=await crypto.subtle.exportKey("jwk",r);delete n.d,n.key_ops=["verify"];return{privateKey:r,publicKey:await crypto.subtle.importKey("jwk",n,{name:"ECDSA",namedCurve:"P-256"},!0,["verify"])}}catch(e){if(e instanceof R)throw e;throw new R("Invalid secret. Must be a base64url-encoded PKCS#8 private key for ES256. Use `bunx gau secret` to generate one.",e)}}async function N(r,n={}){let{algorithm:o="ES256",ttl:s,iss:i,aud:a,sub:l,privateKey:c,secret:u}=n;if("ES256"===o){if(!c){if("string"!=typeof u)throw new R("Missing secret for ES256 signing. It must be a base64url-encoded string.");({privateKey:c}=await F(u))}}else if("HS256"===o&&!u)throw new R("Missing secret for HS256 signing");const d=Math.floor(Date.now()/1e3),f={iat:d,iss:i,aud:a,sub:l,...r};null!=s&&s>0&&(f.exp=d+s);const h="HS256"===o,p=h?"HS256":"ES256",g=JSON.stringify({alg:p,typ:"JWT"}),w=JSON.stringify(f),m=e(g,w);let y;if(h){const e="string"==typeof u?(new TextEncoder).encode(u):u,t=await crypto.subtle.importKey("raw",e,{name:"HMAC",hash:"SHA-256"},!1,["sign"]);y=new Uint8Array(await crypto.subtle.sign("HMAC",t,m))}else y=new Uint8Array(await crypto.subtle.sign({name:"ECDSA",hash:"SHA-256"},c,m));return t(g,w,y)}async function B(e,t){let{algorithm:s="ES256",publicKey:i,secret:a,iss:l,aud:c}=t;if("ES256"===s&&!i){if("string"!=typeof a)throw new R("Missing secret for ES256 verification. Must be a base64url-encoded string.");({publicKey:i}=await F(a))}if("HS256"===s&&!a)throw new R("Missing secret for HS256 verification");const[u,d,f,h]=o(e),p=new r(u).algorithm();let g=!1;if("HS256"===s){if("HS256"!==p)throw new Error(`JWT algorithm is "${p}", but verifier was configured for "HS256"`);const e="string"==typeof a?(new TextEncoder).encode(a):a,t=await crypto.subtle.importKey("raw",e,{name:"HMAC",hash:"SHA-256"},!1,["sign"]);g=function(e,t){let r=e.length^t.length;const n=Math.max(e.length,t.length);for(let o=0;o<n;o++)r|=(e[o]??0)^(t[o]??0);return 0===r}(new Uint8Array(await crypto.subtle.sign("HMAC",t,h)),new Uint8Array(f))}else{if("ES256"!==p)throw new R(`JWT algorithm is "${p}", but verifier was configured for "ES256"`);const e=new Uint8Array(f);if(g=await crypto.subtle.verify({name:"ECDSA",hash:"SHA-256"},i,e,h),!g&&64===e.length)try{const t=function(e){if(64!==e.length)throw new Error("Invalid raw signature length");let t=e.slice(0,32),r=e.slice(32),n=0;for(;n<t.length-1&&0===t[n];)n++;t=t.slice(n);let o=0;for(;o<r.length-1&&0===r[o];)o++;if(r=r.slice(o),t.length>0&&128&t[0]){const e=new Uint8Array(t.length+1);e[0]=0,e.set(t,1),t=e}if(r.length>0&&128&r[0]){const e=new Uint8Array(r.length+1);e[0]=0,e.set(r,1),r=e}const s=t.length,i=r.length,a=2+s+2+i,l=new Uint8Array(2+a);return l[0]=48,l[1]=a,l[2]=2,l[3]=s,l.set(t,4),l[4+s]=2,l[5+s]=i,l.set(r,6+s),l}(e);g=await crypto.subtle.verify({name:"ECDSA",hash:"SHA-256"},i,t,h)}catch{g=!1}}if(!g)throw new R("Invalid JWT signature");const w=new n(d);if(w.hasExpiration()&&!w.verifyExpiration())throw new R("JWT expired");if(w.hasNotBefore()&&!w.verifyNotBefore())throw new R("JWT not yet valid");if(l&&d.iss!==l)throw new R("Invalid JWT issuer");if(c){const e=Array.isArray(c)?c:[c],t=d.aud?Array.isArray(d.aud)?d.aud:[d.aud]:[];if(!e.some(e=>t.includes(e)))throw new R("Invalid JWT audience")}return d}export{a as DEFAULT_COOKIE_SERIALIZE_OPTIONS,l as parseCookies,c as Cookies,u as CSRF_COOKIE_NAME,d as SESSION_COOKIE_NAME,f as SESSION_STRATEGY_COOKIE_NAME,h as LINKING_TOKEN_COOKIE_NAME,p as PKCE_COOKIE_NAME,g as CALLBACK_URI_COOKIE_NAME,w as PROVIDER_OPTIONS_COOKIE_NAME,m as CSRF_MAX_AGE,N as sign,B as verify,y as createAuth,v as handleCallback,S as applyCors,T as handlePreflight,b as verifyRequestOrigin,C as handleLink,H as handleUnlink,O as handleSignIn,I as handleSignOut,L as handleSession,P as createHandler,M as NULL_SESSION,R as AuthError,j as json,V as redirect};//# sourceMappingURL=chunk-LWY5YOPO.js.map
|