@syndew/oluso-sdk 0.0.0-stage → 0.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.
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/client.ts","../../src/journey/conditions.ts","../../src/journey/styles.ts","../../src/journey/webauthn.ts","../../src/journey/render.ts","../../src/auth/storage.ts","../../src/auth/client.ts"],"sourcesContent":["import type {\n OlusoConfig,\n JourneyInfo,\n SubmissionResult,\n JourneySession,\n StepResult,\n OlusoEvent,\n OlusoEventListener,\n OlusoEventType,\n} from './types';\n\n/**\n * Oluso SDK Client\n *\n * @example\n * ```typescript\n * const oluso = new OlusoClient({\n * serverUrl: 'https://auth.oluso.io',\n * tenant: 'acme',\n * });\n *\n * // Get journey info (form fields, etc.)\n * const journey = await oluso.getJourney('waitlist');\n *\n * // Submit data\n * const result = await oluso.submit('waitlist', {\n * email: 'user@example.com',\n * name: 'John Doe',\n * });\n * ```\n */\nexport class OlusoClient {\n private config: Required<Pick<OlusoConfig, 'serverUrl'>> & OlusoConfig;\n private fetchFn: typeof fetch;\n private listeners: Map<OlusoEventType | '*', Set<OlusoEventListener>> = new Map();\n\n constructor(config: OlusoConfig) {\n if (!config.serverUrl) {\n throw new Error('serverUrl is required');\n }\n\n this.config = {\n ...config,\n serverUrl: config.serverUrl.replace(/\\/$/, ''), // Remove trailing slash\n };\n this.fetchFn = config.fetch || globalThis.fetch.bind(globalThis);\n }\n\n /**\n * Get journey information including form fields. Journeys are named by slug.\n */\n async getJourney(slug: string): Promise<JourneyInfo> {\n const response = await this.request<JourneyInfo>(`/api/public/journeys/${encodeURIComponent(slug)}`);\n return response;\n }\n\n /**\n * Submit data to a data collection journey (waitlist, contact, survey, etc.)\n */\n async submit(\n slug: string,\n data: Record<string, unknown>,\n options?: {\n /** Client-side metadata */\n metadata?: Record<string, string>;\n /** Honeypot field for spam detection */\n honeypot?: string;\n }\n ): Promise<SubmissionResult> {\n try {\n const result = await this.request<SubmissionResult>(`/api/public/journeys/${encodeURIComponent(slug)}/submit`, {\n method: 'POST',\n body: {\n data,\n metadata: {\n ...options?.metadata,\n referrer: typeof document !== 'undefined' ? document.referrer : undefined,\n userAgent: typeof navigator !== 'undefined' ? navigator.userAgent : undefined,\n },\n honeypot: options?.honeypot,\n },\n });\n\n this.emit({\n type: 'submission:success',\n slug,\n data: result,\n });\n\n return result;\n } catch (error) {\n this.emit({\n type: 'submission:error',\n slug,\n error: error instanceof Error ? error : new Error(String(error)),\n });\n throw error;\n }\n }\n\n /**\n * Start a multi-step journey and run its first step. Without data the session's `step`\n * is the first step to render; with data, that is the first step's input.\n */\n async startJourney(slug: string, data?: Record<string, unknown>): Promise<JourneySession> {\n const session = await this.request<JourneySession>(\n `/api/public/journeys/${encodeURIComponent(slug)}/start`,\n { method: 'POST', body: { data } }\n );\n\n this.emit({\n type: 'journey:started',\n slug: session.slug,\n sessionId: session.sessionId,\n data: session,\n });\n\n return session;\n }\n\n /**\n * Start a sign-in (or any authentication) journey for a public client. When the session completes it carries an\n * authorization code, redeemed at the token endpoint with the PKCE verifier and redirect_uri \"postmessage\". Use\n * this when your app keeps its own tokens; OlusoAuth.mountSignIn does the whole round trip for you.\n */\n async startAuthJourney(slug: string, auth: { clientId: string; codeChallenge: string; scope?: string }, data?: Record<string, unknown>): Promise<JourneySession> {\n const session = await this.request<JourneySession>(\n `/api/public/journeys/${encodeURIComponent(slug)}/start`,\n {\n method: 'POST',\n body: { data, clientId: auth.clientId, codeChallenge: auth.codeChallenge, codeChallengeMethod: 'S256', scope: auth.scope },\n }\n );\n\n this.emit({ type: 'journey:started', slug: session.slug, sessionId: session.sessionId, data: session });\n return session;\n }\n\n /**\n * Submit input (or an action such as \"resend\") for the session's current step.\n * The result is the session afterwards: the next step to render, or the completion.\n */\n async submitStep(\n sessionId: string,\n data?: Record<string, unknown>,\n action?: string\n ): Promise<StepResult> {\n const result = await this.request<StepResult>(\n `/api/public/journeys/sessions/${encodeURIComponent(sessionId)}/step`,\n { method: 'POST', body: { data, action } }\n );\n\n this.emit({\n type: result.completed ? 'journey:completed' : result.success ? 'journey:step' : 'journey:error',\n slug: result.slug,\n sessionId,\n data: result,\n });\n\n return result;\n }\n\n /**\n * Submit the current step the way a form posts it: every field, files under their field's name, and the\n * clicked button's name and value. Use this for steps with file fields; `action` is a step action such as \"init\".\n */\n async submitStepForm(sessionId: string, form: FormData, action?: string): Promise<StepResult> {\n if (action) form.set('__journey_action', action);\n const result = await this.request<StepResult>(\n `/api/public/journeys/sessions/${encodeURIComponent(sessionId)}/step`,\n { method: 'POST', body: form }\n );\n\n this.emit({\n type: result.completed ? 'journey:completed' : result.success ? 'journey:step' : 'journey:error',\n slug: result.slug,\n sessionId,\n data: result,\n });\n\n return result;\n }\n\n /** The server this client talks to */\n get serverUrl(): string {\n return this.config.serverUrl;\n }\n\n /**\n * Get where a multi-step session stands (status, current step), without running it\n */\n async getSession(sessionId: string): Promise<JourneySession> {\n return this.request<JourneySession>(`/api/public/journeys/sessions/${encodeURIComponent(sessionId)}`);\n }\n\n /**\n * URL of the hosted journey page (/journey/start/{slug}) to redirect to\n */\n getJourneyUrl(slug: string, options?: {\n redirectUri?: string;\n state?: string;\n }): string {\n const params = new URLSearchParams();\n if (this.config.tenant) params.set('tenant', this.config.tenant);\n\n if (options?.redirectUri) {\n params.set('redirect_uri', options.redirectUri);\n }\n if (options?.state) {\n params.set('state', options.state);\n }\n\n return `${this.config.serverUrl}/journey/start/${encodeURIComponent(slug)}?${params}`;\n }\n\n /**\n * URL of the hosted journey page (/journey/start/{slug}) for an iframe\n */\n getEmbedUrl(slug: string, options?: {\n theme?: 'light' | 'dark';\n hideHeader?: boolean;\n }): string {\n const params = new URLSearchParams({ embed: 'true' });\n if (this.config.tenant) params.set('tenant', this.config.tenant);\n\n if (options?.theme) {\n params.set('theme', options.theme);\n }\n if (options?.hideHeader) {\n params.set('hideHeader', 'true');\n }\n\n return `${this.config.serverUrl}/journey/start/${encodeURIComponent(slug)}?${params}`;\n }\n\n /**\n * Subscribe to SDK events\n */\n on(event: OlusoEventType | '*', listener: OlusoEventListener): () => void {\n if (!this.listeners.has(event)) {\n this.listeners.set(event, new Set());\n }\n this.listeners.get(event)!.add(listener);\n\n // Return unsubscribe function\n return () => {\n this.listeners.get(event)?.delete(listener);\n };\n }\n\n /**\n * Unsubscribe from SDK events\n */\n off(event: OlusoEventType | '*', listener: OlusoEventListener): void {\n this.listeners.get(event)?.delete(listener);\n }\n\n private emit(event: OlusoEvent): void {\n // Emit to specific listeners\n this.listeners.get(event.type)?.forEach((listener) => listener(event));\n // Emit to wildcard listeners\n this.listeners.get('*')?.forEach((listener) => listener(event));\n }\n\n private async request<T>(\n path: string,\n options?: {\n method?: 'GET' | 'POST' | 'PUT' | 'DELETE';\n body?: unknown;\n }\n ): Promise<T> {\n const url = `${this.config.serverUrl}${path}`;\n const method = options?.method || 'GET';\n const isForm = typeof FormData !== 'undefined' && options?.body instanceof FormData;\n const headers: Record<string, string> = {};\n if (this.config.tenant) {\n headers['X-Tenant-ID'] = this.config.tenant;\n }\n // A form sets its own multipart boundary.\n if (!isForm) {\n headers['Content-Type'] = 'application/json';\n }\n\n if (this.config.apiKey) {\n headers['X-API-Key'] = this.config.apiKey;\n }\n\n if (this.config.headers) {\n Object.assign(headers, await this.config.headers({ method, url }));\n }\n\n const response = await this.fetchFn(url, {\n method,\n headers,\n body: options?.body === undefined ? undefined : isForm ? (options.body as FormData) : JSON.stringify(options.body),\n credentials: 'include', // Include cookies for session management\n });\n\n if (!response.ok) {\n const error = await response.json().catch(() => ({ message: response.statusText }));\n throw new OlusoError(\n error.message || `Request failed: ${response.status}`,\n response.status,\n error.code,\n error.errors\n );\n }\n\n return response.json();\n }\n}\n\n/**\n * Custom error class for SDK errors\n */\nexport class OlusoError extends Error {\n constructor(\n message: string,\n public readonly status: number,\n public readonly code?: string,\n public readonly fieldErrors?: Record<string, string>\n ) {\n super(message);\n this.name = 'OlusoError';\n }\n}\n","import type { JourneyFormCondition } from '../types';\n\nconst ALIASES: Record<string, string> = {\n eq: 'eq', equals: 'eq', '==': 'eq', '=': 'eq',\n ne: 'ne', neq: 'ne', notequals: 'ne', '!=': 'ne',\n gt: 'gt', '>': 'gt', greaterthan: 'gt',\n gte: 'gte', '>=': 'gte', greaterthanorequals: 'gte',\n lt: 'lt', '<': 'lt', lessthan: 'lt',\n lte: 'lte', '<=': 'lte', lessthanorequals: 'lte',\n contains: 'contains', notcontains: 'not_contains', '!contains': 'not_contains',\n startswith: 'starts_with', endswith: 'ends_with',\n exists: 'exists', notnull: 'exists', isset: 'exists',\n notexists: 'not_exists', null: 'not_exists', isnotset: 'not_exists',\n empty: 'empty', notempty: 'not_empty',\n in: 'in', notin: 'not_in', '!in': 'not_in',\n regex: 'regex', matches: 'regex',\n true: 'true', false: 'false',\n};\n\n/** The canonical operator, as the server names it; undefined for one no condition supports. */\nexport function normalizeOperator(op: string | undefined): string | undefined {\n if (!op) return undefined;\n return ALIASES[op.trim().toLowerCase().replace(/_/g, '')];\n}\n\nconst same = (a: string, b: string) => a.localeCompare(b, undefined, { sensitivity: 'accent' }) === 0;\n\nfunction order(actual: string, expected: string | undefined): number | undefined {\n if (expected === undefined) return undefined;\n const a = Number(actual);\n const e = Number(expected);\n if (actual.trim() !== '' && expected.trim() !== '' && !Number.isNaN(a) && !Number.isNaN(e)) return a === e ? 0 : a < e ? -1 : 1;\n const ad = Date.parse(actual);\n const ed = Date.parse(expected);\n if (!Number.isNaN(ad) && !Number.isNaN(ed)) return ad === ed ? 0 : ad < ed ? -1 : 1;\n return actual.localeCompare(expected, undefined, { sensitivity: 'accent' });\n}\n\nfunction compare(actual: string, op: string, expected: string | undefined): boolean {\n const lower = actual.toLowerCase();\n const want = (expected ?? '').toLowerCase();\n switch (op) {\n case 'eq': return same(actual, expected ?? '');\n case 'ne': return !same(actual, expected ?? '');\n case 'gt': { const o = order(actual, expected); return o !== undefined && o > 0; }\n case 'gte': { const o = order(actual, expected); return o !== undefined && o >= 0; }\n case 'lt': { const o = order(actual, expected); return o !== undefined && o < 0; }\n case 'lte': { const o = order(actual, expected); return o !== undefined && o <= 0; }\n case 'contains': return lower.includes(want);\n case 'not_contains': return !lower.includes(want);\n case 'starts_with': return lower.startsWith(want);\n case 'ends_with': return lower.endsWith(want);\n case 'regex':\n if (!expected) return false;\n try { return new RegExp(expected, 'i').test(actual); } catch { return false; }\n default: return false;\n }\n}\n\nfunction expectedList(expected: string | undefined): string[] {\n if (!expected || !expected.trim()) return [];\n const trimmed = expected.trim();\n if (trimmed.startsWith('[')) {\n try {\n const parsed = JSON.parse(trimmed);\n if (Array.isArray(parsed)) return parsed.map(String);\n } catch {\n return [];\n }\n }\n return trimmed.split(',').map((v) => v.trim()).filter(Boolean);\n}\n\nconst truthy = (v: string) => v.toLowerCase() !== 'false' && v !== '0';\n\n/**\n * Whether a field's current values meet a showWhen condition, with the server's semantics: positive operators pass\n * when any value matches, negative ones when none does.\n */\nexport function conditionMet(condition: JourneyFormCondition, values: string[]): boolean {\n const op = normalizeOperator(condition.operator);\n const present = values.filter((v) => v !== '');\n const members = () => present.flatMap((v) => v.split(',').map((p) => p.trim()).filter(Boolean));\n switch (op) {\n case 'exists':\n case 'not_empty': return present.length > 0;\n case 'not_exists':\n case 'empty': return present.length === 0;\n case 'ne': return !present.some((v) => compare(v, 'eq', condition.value));\n case 'not_contains': return !present.some((v) => compare(v, 'contains', condition.value));\n case 'in': { const list = expectedList(condition.value); return members().some((m) => list.some((e) => same(m, e))); }\n case 'not_in': { const list = expectedList(condition.value); return !members().some((m) => list.some((e) => same(m, e))); }\n case 'true': return present.some(truthy);\n case 'false': return !present.some(truthy);\n case undefined: return false;\n default: return present.some((v) => compare(v, op, condition.value));\n }\n}\n","/** Default look for rendered journeys. Override the custom properties on `.oluso-journey`, or pass `unstyled`. */\nexport const JOURNEY_STYLES = `\n.oluso-journey {\n --oluso-accent: #4f46e5;\n --oluso-accent-contrast: #ffffff;\n --oluso-fg: #111827;\n --oluso-muted: #6b7280;\n --oluso-bg: #ffffff;\n --oluso-field-bg: #ffffff;\n --oluso-border: #d1d5db;\n --oluso-danger: #b91c1c;\n --oluso-danger-bg: #fef2f2;\n --oluso-notice-bg: #eff6ff;\n --oluso-notice: #1d4ed8;\n --oluso-radius: 8px;\n --oluso-gap: 14px;\n --oluso-font: inherit;\n font-family: var(--oluso-font);\n color: var(--oluso-fg);\n font-size: 15px;\n line-height: 1.5;\n}\n.oluso-journey[data-theme=\"dark\"] {\n --oluso-fg: #f3f4f6;\n --oluso-muted: #9ca3af;\n --oluso-bg: #111827;\n --oluso-field-bg: #1f2937;\n --oluso-border: #374151;\n --oluso-danger: #fca5a5;\n --oluso-danger-bg: rgba(185, 28, 28, 0.15);\n --oluso-notice-bg: rgba(59, 130, 246, 0.15);\n --oluso-notice: #93c5fd;\n}\n@media (prefers-color-scheme: dark) {\n .oluso-journey[data-theme=\"auto\"] {\n --oluso-fg: #f3f4f6;\n --oluso-muted: #9ca3af;\n --oluso-bg: #111827;\n --oluso-field-bg: #1f2937;\n --oluso-border: #374151;\n --oluso-danger: #fca5a5;\n --oluso-danger-bg: rgba(185, 28, 28, 0.15);\n --oluso-notice-bg: rgba(59, 130, 246, 0.15);\n --oluso-notice: #93c5fd;\n }\n}\n.oluso-journey *, .oluso-journey *::before, .oluso-journey *::after { box-sizing: border-box; }\n.oluso-journey__form { display: flex; flex-direction: column; gap: var(--oluso-gap); margin: 0; }\n.oluso-journey__title { font-size: 1.25em; font-weight: 600; margin: 0; }\n.oluso-journey__description { color: var(--oluso-muted); margin: 0; white-space: pre-line; }\n.oluso-journey__alert { border-radius: var(--oluso-radius); padding: 10px 12px; margin: 0; }\n.oluso-journey__alert--error { background: var(--oluso-danger-bg); color: var(--oluso-danger); }\n.oluso-journey__alert--notice { background: var(--oluso-notice-bg); color: var(--oluso-notice); }\n.oluso-journey__group { display: flex; flex-direction: column; gap: var(--oluso-gap); border: 0; margin: 0; padding: 0; }\n.oluso-journey__field { display: flex; flex-direction: column; gap: 6px; }\n.oluso-journey__field[hidden] { display: none; }\n.oluso-journey__label { font-weight: 500; }\n.oluso-journey__required { color: var(--oluso-danger); margin-left: 2px; }\n.oluso-journey__input, .oluso-journey__select, .oluso-journey__textarea {\n width: 100%; font: inherit; color: var(--oluso-fg); background: var(--oluso-field-bg);\n border: 1px solid var(--oluso-border); border-radius: var(--oluso-radius); padding: 9px 11px; min-height: 40px;\n}\n.oluso-journey__input:focus, .oluso-journey__select:focus, .oluso-journey__textarea:focus {\n outline: 2px solid var(--oluso-accent); outline-offset: 1px; border-color: transparent;\n}\n.oluso-journey__input[aria-invalid=\"true\"], .oluso-journey__select[aria-invalid=\"true\"], .oluso-journey__textarea[aria-invalid=\"true\"] {\n border-color: var(--oluso-danger);\n}\n.oluso-journey__input--otp { letter-spacing: 0.4em; font-variant-numeric: tabular-nums; text-align: center; font-size: 1.2em; }\n.oluso-journey__phone { display: flex; gap: 8px; }\n.oluso-journey__phone .oluso-journey__select { width: auto; max-width: 45%; }\n.oluso-journey__choices { display: flex; flex-direction: column; gap: 8px; }\n.oluso-journey__choice { display: flex; gap: 10px; align-items: flex-start; cursor: pointer; }\n.oluso-journey__choice input { margin-top: 3px; accent-color: var(--oluso-accent); }\n.oluso-journey__choice-description { display: block; color: var(--oluso-muted); font-size: 0.9em; }\n.oluso-journey__help, .oluso-journey__hint { color: var(--oluso-muted); font-size: 0.875em; margin: 0; }\n.oluso-journey__error { color: var(--oluso-danger); font-size: 0.875em; margin: 0; }\n.oluso-journey__content { margin: 0; white-space: pre-line; }\n.oluso-journey__actions { display: flex; flex-wrap: wrap; gap: 8px; align-items: center; }\n.oluso-journey__button {\n font: inherit; font-weight: 500; border-radius: var(--oluso-radius); padding: 9px 16px; min-height: 40px; cursor: pointer;\n border: 1px solid var(--oluso-border); background: var(--oluso-field-bg); color: var(--oluso-fg);\n}\n.oluso-journey__button--primary { background: var(--oluso-accent); color: var(--oluso-accent-contrast); border-color: var(--oluso-accent); }\n.oluso-journey__button--primary:only-child, .oluso-journey__actions--stacked .oluso-journey__button--primary { flex: 1 1 auto; }\n.oluso-journey__button--link { background: none; border: 0; color: var(--oluso-accent); padding: 4px 0; min-height: 0; }\n.oluso-journey__button--cancel { background: none; }\n.oluso-journey__button:disabled { opacity: 0.6; cursor: progress; }\n.oluso-journey__enter { position: absolute; left: -10000px; width: 1px; height: 1px; overflow: hidden; }\n.oluso-journey__action-line { display: flex; flex-wrap: wrap; gap: 6px; align-items: baseline; margin: 0; }\n.oluso-journey__links { display: flex; flex-wrap: wrap; gap: 12px; font-size: 0.9em; }\n.oluso-journey__links a { color: var(--oluso-accent); }\n.oluso-journey__qr { display: flex; flex-direction: column; align-items: center; gap: 8px; }\n.oluso-journey__qr img { width: 180px; height: 180px; background: #fff; padding: 8px; border-radius: var(--oluso-radius); }\n.oluso-journey__code { font-family: ui-monospace, SFMono-Regular, Menlo, monospace; word-break: break-all; }\n.oluso-journey__codes { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 6px; margin: 0; padding: 0; list-style: none; }\n.oluso-journey__codes li { font-family: ui-monospace, SFMono-Regular, Menlo, monospace; padding: 6px 8px; border: 1px solid var(--oluso-border); border-radius: 6px; text-align: center; }\n.oluso-journey__status { color: var(--oluso-muted); text-align: center; padding: 16px 0; }\n.oluso-journey__done { text-align: center; padding: 8px 0; }\n`;\n\nlet injected = false;\n\nexport function injectJourneyStyles(): void {\n if (injected || typeof document === 'undefined') return;\n const style = document.createElement('style');\n style.setAttribute('data-oluso-journey', '');\n style.textContent = JOURNEY_STYLES;\n document.head.appendChild(style);\n injected = true;\n}\n","/** WebAuthn for journey steps: options arrive and results leave as base64url, the way the server reads them. */\n\nexport function base64UrlToBuffer(value: string): ArrayBuffer {\n const base64 = value.replace(/-/g, '+').replace(/_/g, '/');\n const padded = base64 + '='.repeat((4 - (base64.length % 4)) % 4);\n const binary = atob(padded);\n const bytes = new Uint8Array(binary.length);\n for (let i = 0; i < binary.length; i++) bytes[i] = binary.charCodeAt(i);\n return bytes.buffer;\n}\n\nexport function bufferToBase64Url(buffer: ArrayBuffer | null | undefined): string | null {\n if (!buffer) return null;\n const bytes = new Uint8Array(buffer);\n let binary = '';\n for (let i = 0; i < bytes.length; i++) binary += String.fromCharCode(bytes[i]);\n return btoa(binary).replace(/\\+/g, '-').replace(/\\//g, '_').replace(/=+$/, '');\n}\n\ntype Json = Record<string, unknown>;\n\nfunction credentialDescriptors(list: unknown): PublicKeyCredentialDescriptor[] | undefined {\n if (!Array.isArray(list)) return undefined;\n return list.map((c: Json) => ({\n type: (c.type as PublicKeyCredentialType) ?? 'public-key',\n id: base64UrlToBuffer(String(c.id)),\n transports: c.transports as AuthenticatorTransport[] | undefined,\n }));\n}\n\nexport function requestOptions(publicKey: Json): PublicKeyCredentialRequestOptions {\n return {\n ...(publicKey as object),\n challenge: base64UrlToBuffer(String(publicKey.challenge)),\n allowCredentials: credentialDescriptors(publicKey.allowCredentials),\n } as PublicKeyCredentialRequestOptions;\n}\n\nexport function creationOptions(publicKey: Json): PublicKeyCredentialCreationOptions {\n const user = (publicKey.user ?? {}) as Json;\n return {\n ...(publicKey as object),\n challenge: base64UrlToBuffer(String(publicKey.challenge)),\n user: { ...(user as object), id: base64UrlToBuffer(String(user.id)) },\n excludeCredentials: credentialDescriptors(publicKey.excludeCredentials),\n } as PublicKeyCredentialCreationOptions;\n}\n\n/** A passkey sign-in, as the JSON the server reads. */\nexport async function getAssertion(publicKey: Json): Promise<string> {\n const credential = (await navigator.credentials.get({ publicKey: requestOptions(publicKey) })) as PublicKeyCredential | null;\n if (!credential) throw new Error('No passkey was chosen');\n const response = credential.response as AuthenticatorAssertionResponse;\n return JSON.stringify({\n id: credential.id,\n rawId: bufferToBase64Url(credential.rawId),\n type: credential.type,\n response: {\n clientDataJSON: bufferToBase64Url(response.clientDataJSON),\n authenticatorData: bufferToBase64Url(response.authenticatorData),\n signature: bufferToBase64Url(response.signature),\n userHandle: bufferToBase64Url(response.userHandle),\n },\n authenticatorAttachment: credential.authenticatorAttachment ?? null,\n });\n}\n\n/** A new passkey, as the JSON the server reads. */\nexport async function createCredential(publicKey: Json): Promise<string> {\n const credential = (await navigator.credentials.create({ publicKey: creationOptions(publicKey) })) as PublicKeyCredential | null;\n if (!credential) throw new Error('No passkey was created');\n const response = credential.response as AuthenticatorAttestationResponse;\n return JSON.stringify({\n id: credential.id,\n rawId: bufferToBase64Url(credential.rawId),\n type: credential.type,\n response: {\n clientDataJSON: bufferToBase64Url(response.clientDataJSON),\n attestationObject: bufferToBase64Url(response.attestationObject),\n transports: typeof response.getTransports === 'function' ? response.getTransports() : undefined,\n },\n authenticatorAttachment: credential.authenticatorAttachment ?? null,\n });\n}\n","import type { OlusoClient } from '../client';\nimport type {\n JourneyFormAction,\n JourneyFormField,\n JourneyFormWidget,\n JourneySession,\n JourneyStepForm,\n} from '../types';\nimport { conditionMet } from './conditions';\nimport { injectJourneyStyles } from './styles';\nimport { createCredential, getAssertion } from './webauthn';\n\n/** Text the renderer shows itself; everything about a step comes from the server in the person's language. */\nexport interface JourneyLabels {\n loading: string;\n completed: string;\n failed: string;\n expired: string;\n restart: string;\n takePhoto: string;\n copy: string;\n copied: string;\n passkey: string;\n retry: string;\n waiting: string;\n unavailable: string;\n}\n\nconst DEFAULT_LABELS: JourneyLabels = {\n loading: 'Loading…',\n completed: 'All done. Thank you.',\n failed: 'Something went wrong. Please try again.',\n expired: 'This session has expired. Please start again.',\n restart: 'Start again',\n takePhoto: 'Take a photo',\n copy: 'Copy',\n copied: 'Copied',\n passkey: 'Use your passkey',\n retry: 'Try again',\n waiting: 'Waiting…',\n unavailable: 'This step can’t be shown here.',\n};\n\nexport interface MountJourneyOptions {\n client: OlusoClient;\n /** Start this journey (a waitlist, a contact form, a survey, a sign-up). */\n slug?: string;\n /** Input for the first step. */\n data?: Record<string, unknown>;\n /** Continue a session started elsewhere, e.g. one your backend started for the signed-in user. */\n session?: JourneySession;\n /** Start the session yourself, e.g. a sign-in journey with PKCE. */\n start?: () => Promise<JourneySession>;\n /** After every step the server returns. */\n onStep?: (session: JourneySession) => void;\n /** When the journey completes. */\n onComplete?: (session: JourneySession) => void | Promise<void>;\n /** When the journey fails, expires or a request fails. */\n onError?: (error: Error, session?: JourneySession) => void;\n /** When a step continues elsewhere (an external identity provider, a checkout). Defaults to navigating there. */\n onRedirect?: (url: string, session: JourneySession) => void;\n /** Show the completion message when done (default true). */\n showCompletion?: boolean;\n theme?: 'light' | 'dark' | 'auto';\n /** Skip the default styles; style `.oluso-journey__*` yourself. */\n unstyled?: boolean;\n labels?: Partial<JourneyLabels>;\n}\n\nexport interface JourneyMount {\n /** The session as it stands. */\n readonly session: JourneySession | undefined;\n /** Start again from the first step (only for journeys started by slug or `start`). */\n restart(): Promise<void>;\n destroy(): void;\n}\n\ntype Element = HTMLElement;\n\nfunction el<K extends keyof HTMLElementTagNameMap>(tag: K, className?: string, text?: string): HTMLElementTagNameMap[K] {\n const node = document.createElement(tag);\n if (className) node.className = className;\n if (text !== undefined) node.textContent = text;\n return node;\n}\n\nlet uid = 0;\n\n/**\n * Renders any journey into `container` and runs it step by step: forms, sign-in, verification codes, passkeys,\n * captcha, consent, file uploads. Steps the server describes are drawn natively; a step that only has hosted markup\n * is shown as that markup.\n */\nexport function mountJourney(container: Element, options: MountJourneyOptions): JourneyMount {\n const labels: JourneyLabels = { ...DEFAULT_LABELS, ...options.labels };\n const client = options.client;\n const id = `oluso-j${++uid}`;\n let session: JourneySession | undefined;\n let destroyed = false;\n let timers: number[] = [];\n\n if (!options.unstyled) injectJourneyStyles();\n const root = el('div', 'oluso-journey');\n root.setAttribute('data-theme', options.theme ?? 'auto');\n container.appendChild(root);\n\n const clearTimers = () => {\n timers.forEach((t) => window.clearInterval(t));\n timers = [];\n };\n\n const status = (text: string) => {\n root.replaceChildren(el('p', 'oluso-journey__status', text));\n };\n\n const fail = (error: unknown) => {\n const err = error instanceof Error ? error : new Error(String(error));\n options.onError?.(err, session);\n return err;\n };\n\n const canRestart = () => Boolean(options.slug || options.start);\n\n const begin = async () => {\n clearTimers();\n status(labels.loading);\n try {\n const started = options.start\n ? await options.start()\n : options.slug\n ? await client.startJourney(options.slug, options.data)\n : options.session;\n if (!started) throw new Error('mountJourney needs a slug, a session or a start function');\n await show(started);\n } catch (error) {\n showProblem(fail(error).message);\n }\n };\n\n const show = async (next: JourneySession) => {\n if (destroyed) return;\n clearTimers();\n session = next;\n options.onStep?.(next);\n\n if (next.completed) {\n if (next.redirectUrl) {\n await options.onComplete?.(next);\n redirect(next.redirectUrl, next);\n return;\n }\n if (options.showCompletion !== false) {\n const done = el('div', 'oluso-journey__done');\n done.appendChild(el('p', 'oluso-journey__content', next.message || labels.completed));\n root.replaceChildren(done);\n } else {\n root.replaceChildren();\n }\n await options.onComplete?.(next);\n return;\n }\n\n if (next.status !== 'in_progress') {\n const message = next.status === 'expired' ? labels.expired : next.errorDescription || labels.failed;\n fail(new Error(message));\n showProblem(message);\n return;\n }\n\n if (next.redirectUrl) {\n redirect(next.redirectUrl, next);\n return;\n }\n\n if (next.step?.form) {\n renderForm(next.step.form);\n } else if (next.step?.html) {\n renderHtml(next.step.html);\n } else {\n showProblem(labels.unavailable);\n }\n };\n\n const redirect = (url: string, current: JourneySession) => {\n if (options.onRedirect) options.onRedirect(url, current);\n else window.location.assign(url);\n };\n\n const showProblem = (message: string) => {\n const box = el('div', 'oluso-journey__form');\n box.appendChild(el('p', 'oluso-journey__alert oluso-journey__alert--error', message));\n if (canRestart()) {\n const again = el('button', 'oluso-journey__button oluso-journey__button--primary', labels.restart);\n again.type = 'button';\n again.addEventListener('click', () => void begin());\n const row = el('div', 'oluso-journey__actions');\n row.appendChild(again);\n box.appendChild(row);\n }\n root.replaceChildren(box);\n };\n\n const post = async (form: FormData, action?: string) => {\n if (!session) return;\n const next = await client.submitStepForm(session.sessionId, form, action);\n await show(next);\n };\n\n const submitting = (form: HTMLFormElement, busy: boolean) => {\n form.setAttribute('aria-busy', String(busy));\n form.querySelectorAll('button').forEach((b) => ((b as HTMLButtonElement).disabled = busy));\n };\n\n const send = async (form: HTMLFormElement, action: JourneyFormAction | undefined, extra?: Record<string, string>) => {\n const data = action?.postsFields === false ? new FormData() : new FormData(form);\n if (action?.name) data.append(action.name, action.value ?? '');\n if (action?.values) for (const [k, v] of Object.entries(action.values)) data.append(k, v);\n if (extra) for (const [k, v] of Object.entries(extra)) data.set(k, v);\n submitting(form, true);\n try {\n await post(data);\n } catch (error) {\n submitting(form, false);\n const message = fail(error).message;\n let alert = form.querySelector<HTMLElement>('[data-oluso-request-error]');\n if (!alert) {\n alert = el('p', 'oluso-journey__alert oluso-journey__alert--error');\n alert.setAttribute('data-oluso-request-error', '');\n alert.setAttribute('role', 'alert');\n form.prepend(alert);\n }\n alert.textContent = message;\n }\n };\n\n const renderForm = (step: JourneyStepForm) => {\n const form = el('form', 'oluso-journey__form');\n\n if (step.title) form.appendChild(el('h2', 'oluso-journey__title', step.title));\n if (step.description) form.appendChild(el('p', 'oluso-journey__description', step.description));\n if (step.error) {\n const alert = el('p', 'oluso-journey__alert oluso-journey__alert--error', step.error);\n alert.setAttribute('role', 'alert');\n form.appendChild(alert);\n }\n if (step.notice) {\n const notice = el('p', 'oluso-journey__alert oluso-journey__alert--notice', step.notice);\n notice.setAttribute('role', 'status');\n form.appendChild(notice);\n }\n\n const wrappers: Array<{ field: JourneyFormField; wrapper: Element }> = [];\n for (const field of step.fields) {\n const rendered = renderField(field);\n if (!rendered) continue;\n form.appendChild(rendered);\n if (field.showWhen || field.showWhenAll?.length) wrappers.push({ field, wrapper: rendered });\n }\n\n if (step.widget) {\n const widget = renderWidget(step.widget, form);\n if (widget) form.appendChild(widget);\n }\n\n if (step.links.length > 0) {\n const links = el('div', 'oluso-journey__links');\n for (const link of step.links) {\n const a = el('a', undefined, link.label);\n a.href = link.url;\n a.target = '_blank';\n a.rel = 'noopener noreferrer';\n links.appendChild(a);\n }\n form.appendChild(links);\n }\n\n if (step.actions.length > 0) {\n const row = el('div', 'oluso-journey__actions');\n // Enter submits the first submit button in the form, so the primary action goes first, out of sight.\n const primary = step.actions.findIndex((a) => a.kind === 'primary');\n if (primary >= 0) {\n const enter = el('button', 'oluso-journey__enter');\n enter.type = 'submit';\n enter.tabIndex = -1;\n enter.setAttribute('aria-hidden', 'true');\n enter.dataset.olusoAction = String(primary);\n form.prepend(enter);\n }\n const described: Element[] = [];\n step.actions.forEach((action, index) => {\n const button = el('button', `oluso-journey__button oluso-journey__button--${action.kind}`, action.label);\n button.type = 'submit';\n button.formNoValidate = action.skipValidation || action.postsFields === false;\n button.dataset.olusoAction = String(index);\n if (action.description) {\n // A described button (a resend link with its prompt, a method with its explanation) gets a line of its own.\n const line = el('p', 'oluso-journey__action-line');\n line.appendChild(el('span', 'oluso-journey__help', action.description));\n line.appendChild(button);\n described.push(line);\n } else {\n row.appendChild(button);\n }\n });\n if (row.childElementCount > 0) form.appendChild(row);\n described.forEach((line) => form.appendChild(line));\n }\n\n const applyConditions = () => {\n for (const { field, wrapper } of wrappers) {\n const conditions = [...(field.showWhen ? [field.showWhen] : []), ...(field.showWhenAll ?? [])];\n const shown = conditions.every((c) => conditionMet(c, currentValues(form.elements.namedItem(c.field))));\n wrapper.hidden = !shown;\n wrapper.querySelectorAll('input, select, textarea').forEach((input) => {\n (input as HTMLInputElement).disabled = !shown || (input as HTMLElement).dataset.olusoReadonly === 'true';\n });\n }\n };\n form.addEventListener('input', (event) => {\n applyConditions();\n const target = event.target as HTMLElement;\n const wrapper = target.closest('.oluso-journey__field');\n wrapper?.querySelectorAll('[aria-invalid=\"true\"]').forEach((n) => n.removeAttribute('aria-invalid'));\n wrapper?.querySelector('.oluso-journey__error')?.remove();\n });\n form.addEventListener('change', applyConditions);\n applyConditions();\n\n form.addEventListener('submit', (event) => {\n event.preventDefault();\n const submitter = (event as SubmitEvent).submitter as HTMLButtonElement | null;\n const index = submitter?.dataset.olusoAction;\n const action = index !== undefined ? step.actions[Number(index)] : step.actions.find((a) => a.kind === 'primary');\n if (action?.confirm && submitter && submitter.dataset.olusoConfirming !== 'true') {\n // Ask inline: the question replaces the button's label until it is clicked again.\n submitter.dataset.olusoConfirming = 'true';\n submitter.textContent = action.confirm;\n submitter.setAttribute('aria-live', 'polite');\n return;\n }\n void send(form, action);\n });\n\n root.replaceChildren(form);\n const focus = form.querySelector<HTMLElement>('[autofocus]')\n ?? form.querySelector<HTMLElement>('input:not([type=hidden]):not([disabled]), select, textarea');\n focus?.focus({ preventScroll: true });\n };\n\n const renderField = (field: JourneyFormField): Element | null => {\n const fieldId = `${id}-${field.name}`;\n\n if (field.type === 'hidden') {\n const input = el('input');\n input.type = 'hidden';\n input.name = field.name;\n input.value = field.value ?? '';\n return input;\n }\n\n const wrapper = el('div', 'oluso-journey__field');\n if (field.group) wrapper.dataset.group = field.group;\n\n if (field.type === 'content') {\n if (field.label) wrapper.appendChild(el('p', 'oluso-journey__label', field.label));\n wrapper.appendChild(el('p', 'oluso-journey__content', field.value ?? ''));\n return wrapper;\n }\n\n const label = () => {\n if (!field.label) return;\n const l = el('label', 'oluso-journey__label', field.label);\n l.htmlFor = fieldId;\n if (field.required) {\n const marker = el('span', 'oluso-journey__required', '*');\n marker.setAttribute('aria-hidden', 'true');\n l.appendChild(marker);\n }\n wrapper.appendChild(l);\n };\n\n const describedBy: string[] = [];\n const common = (input: HTMLInputElement | HTMLSelectElement | HTMLTextAreaElement) => {\n input.id = fieldId;\n input.name = field.name;\n input.required = field.required;\n if (field.readOnly) {\n if (input instanceof HTMLSelectElement) input.disabled = true;\n else input.readOnly = true;\n input.dataset.olusoReadonly = String(input instanceof HTMLSelectElement);\n }\n if (field.autofocus) input.autofocus = true;\n if (field.autocomplete) input.setAttribute('autocomplete', field.autocomplete);\n if (field.error) input.setAttribute('aria-invalid', 'true');\n };\n\n switch (field.type) {\n case 'textarea': {\n label();\n const input = el('textarea', 'oluso-journey__textarea');\n common(input);\n input.value = field.value ?? '';\n if (field.placeholder) input.placeholder = field.placeholder;\n if (field.rows) input.rows = field.rows;\n if (field.minLength) input.minLength = field.minLength;\n if (field.maxLength) input.maxLength = field.maxLength;\n wrapper.appendChild(input);\n break;\n }\n case 'select': {\n label();\n const input = el('select', 'oluso-journey__select');\n common(input);\n const blank = el('option', undefined, field.placeholder ?? '');\n blank.value = '';\n input.appendChild(blank);\n for (const option of field.options ?? []) {\n const o = el('option', undefined, option.label);\n o.value = option.value;\n o.disabled = option.disabled;\n o.selected = option.value === field.value;\n input.appendChild(o);\n }\n wrapper.appendChild(input);\n break;\n }\n case 'radio': {\n const group = el('fieldset', 'oluso-journey__group');\n if (field.label) {\n const legend = el('legend', 'oluso-journey__label', field.label);\n if (field.required) legend.appendChild(el('span', 'oluso-journey__required', '*'));\n group.appendChild(legend);\n }\n const choices = el('div', 'oluso-journey__choices');\n (field.options ?? []).forEach((option, i) => {\n const choice = el('label', 'oluso-journey__choice');\n const input = el('input');\n input.type = 'radio';\n input.name = field.name;\n input.value = option.value;\n input.id = `${fieldId}-${i}`;\n input.required = field.required;\n input.disabled = option.disabled || field.readOnly;\n input.checked = option.value === field.value;\n const text = el('span', undefined, option.label);\n if (option.description) text.appendChild(el('span', 'oluso-journey__choice-description', option.description));\n choice.append(input, text);\n choices.appendChild(choice);\n });\n group.appendChild(choices);\n wrapper.appendChild(group);\n break;\n }\n case 'checkbox': {\n // A checkbox with a placeholder shows its label above and the placeholder beside the box, as the hosted form does.\n if (field.placeholder) label();\n const choice = el('label', 'oluso-journey__choice');\n const input = el('input');\n input.type = 'checkbox';\n input.value = 'true';\n common(input);\n input.checked = field.value === 'true';\n if (field.readOnly) {\n // Read-only still posts its value (a required consent scope), so it can't be disabled.\n input.setAttribute('aria-readonly', 'true');\n input.addEventListener('click', (e) => e.preventDefault());\n }\n const text = el('span', undefined, field.placeholder ?? field.label ?? '');\n if (!field.placeholder && field.required) text.appendChild(el('span', 'oluso-journey__required', '*'));\n choice.append(input, text);\n wrapper.appendChild(choice);\n break;\n }\n case 'file': {\n label();\n const input = el('input', 'oluso-journey__input');\n input.type = 'file';\n common(input);\n input.readOnly = false;\n input.disabled = field.readOnly;\n if (field.accept) input.accept = field.accept;\n input.multiple = (field.maxFiles ?? 1) > 1;\n input.required = field.required && !field.capture;\n wrapper.appendChild(input);\n if (field.capture && !field.readOnly) {\n const cameraLabel = el('label', 'oluso-journey__hint', labels.takePhoto);\n cameraLabel.htmlFor = `${fieldId}-camera`;\n const camera = el('input', 'oluso-journey__input');\n camera.type = 'file';\n camera.id = `${fieldId}-camera`;\n camera.name = field.name;\n camera.accept = 'image/*';\n camera.setAttribute('capture', field.capture);\n wrapper.append(cameraLabel, camera);\n }\n break;\n }\n case 'tel': {\n label();\n if (field.countries && field.countries.length > 0) {\n const row = el('div', 'oluso-journey__phone');\n const country = el('select', 'oluso-journey__select');\n country.name = `${field.name}__country`;\n country.setAttribute('aria-label', field.label ?? field.name);\n country.disabled = field.readOnly;\n for (const c of field.countries) {\n const o = el('option', undefined, `${c.flag ? c.flag + ' ' : ''}${c.name} (${c.dialCode})`);\n o.value = c.code;\n o.selected = c.code === field.country;\n country.appendChild(o);\n }\n const input = el('input', 'oluso-journey__input');\n input.type = 'tel';\n input.inputMode = 'tel';\n common(input);\n input.value = field.value ?? '';\n if (field.placeholder) input.placeholder = field.placeholder;\n row.append(country, input);\n wrapper.appendChild(row);\n } else {\n const input = textInput(field, 'tel');\n common(input);\n wrapper.appendChild(input);\n }\n break;\n }\n case 'otp': {\n label();\n const input = el('input', 'oluso-journey__input oluso-journey__input--otp');\n input.type = 'text';\n input.inputMode = 'numeric';\n common(input);\n input.setAttribute('autocomplete', field.autocomplete ?? 'one-time-code');\n if (field.maxLength) {\n input.maxLength = field.maxLength;\n input.minLength = field.minLength ?? field.maxLength;\n }\n input.pattern = field.pattern ?? '[0-9]*';\n input.value = field.value ?? '';\n wrapper.appendChild(input);\n break;\n }\n default: {\n label();\n const known = ['text', 'email', 'password', 'number', 'date', 'url', 'tel'];\n const input = textInput(field, known.includes(field.type) ? field.type : 'text');\n common(input);\n wrapper.appendChild(input);\n }\n }\n\n if (field.description) {\n const help = el('p', 'oluso-journey__help', field.description);\n help.id = `${fieldId}-help`;\n describedBy.push(help.id);\n wrapper.appendChild(help);\n }\n if (field.hint) {\n const hint = el('p', 'oluso-journey__hint', field.hint);\n hint.id = `${fieldId}-hint`;\n describedBy.push(hint.id);\n wrapper.appendChild(hint);\n }\n if (field.error) {\n const error = el('p', 'oluso-journey__error', field.error);\n error.id = `${fieldId}-error`;\n describedBy.push(error.id);\n wrapper.appendChild(error);\n }\n if (describedBy.length > 0) {\n Array.from(wrapper.querySelectorAll('[id]')).find((n) => n.id === fieldId)?.setAttribute('aria-describedby', describedBy.join(' '));\n }\n return wrapper;\n };\n\n const textInput = (field: JourneyFormField, type: string) => {\n const input = el('input', 'oluso-journey__input');\n input.type = type;\n input.value = field.value ?? '';\n if (field.placeholder) input.placeholder = field.placeholder;\n if (field.pattern) input.pattern = field.pattern;\n if (field.patternError) {\n input.title = field.patternError;\n input.addEventListener('invalid', () => {\n if (input.validity.patternMismatch) input.setCustomValidity(field.patternError!);\n });\n input.addEventListener('input', () => input.setCustomValidity(''));\n }\n if (field.minLength) input.minLength = field.minLength;\n if (field.maxLength) input.maxLength = field.maxLength;\n if (field.min) input.min = field.min;\n if (field.max) input.max = field.max;\n if (type === 'number') input.step = 'any';\n return input;\n };\n\n const renderWidget = (widget: JourneyFormWidget, form: HTMLFormElement): Element | null => {\n const data = (widget.data ?? {}) as Record<string, unknown>;\n const box = el('div', 'oluso-journey__widget');\n\n const result = (value: string) => {\n if (!widget.resultField) return;\n let input = Array.from(form.querySelectorAll<HTMLInputElement>('input[type=hidden]')).find((n) => n.name === widget.resultField) ?? null;\n if (!input) {\n input = el('input');\n input.type = 'hidden';\n input.name = widget.resultField;\n form.appendChild(input);\n }\n input.value = value;\n };\n\n switch (widget.type) {\n case 'webauthn_get':\n case 'webauthn_create': {\n const run = el('button', 'oluso-journey__button oluso-journey__button--primary', widget.submit?.label ?? labels.passkey);\n run.type = 'button';\n const go = async () => {\n run.disabled = true;\n try {\n const options = await webAuthnOptions(data);\n const publicKey = options.publicKey;\n let extra = options.extra;\n const credential = widget.type === 'webauthn_get' ? await getAssertion(publicKey) : await createCredential(publicKey);\n result(credential);\n const naming = data.credentialName as { field?: string; platform?: string; crossPlatform?: string; other?: string } | undefined;\n if (naming?.field) {\n const attachment = (JSON.parse(credential) as { authenticatorAttachment?: string | null }).authenticatorAttachment;\n const name = attachment === 'platform' ? naming.platform : attachment === 'cross-platform' ? naming.crossPlatform : naming.other;\n (extra ??= {})[naming.field] = name ?? '';\n }\n await send(form, widget.submit, extra);\n } catch (error) {\n run.disabled = false;\n run.textContent = labels.retry;\n options.onError?.(error instanceof Error ? error : new Error(String(error)), session);\n }\n };\n run.addEventListener('click', () => void go());\n box.appendChild(run);\n if (typeof PublicKeyCredential !== 'undefined') queueMicrotask(() => void go());\n return box;\n }\n case 'verification_connect': {\n // A verification provider's own widget runs in the page; its outcome comes back as the step's callback.\n const options = (data.options ?? {}) as Record<string, unknown>;\n const reference = typeof data.referenceOption === 'string' ? options[data.referenceOption] : undefined;\n const field = typeof data.referenceField === 'string' ? data.referenceField : 'reference_id';\n const callback = async (withReference: boolean) => {\n const values = new FormData();\n if (withReference) values.set(field, reference == null ? '' : String(reference));\n submitting(form, true);\n try {\n await post(values, 'callback');\n } catch (error) {\n submitting(form, false);\n fail(error);\n }\n };\n const start = async () => {\n await loadScript(String(data.scriptUrl));\n const Ctor = (window as unknown as Record<string, unknown>)[typeof data.global === 'string' ? data.global : 'Connect'] as\n | (new (o: Record<string, unknown>) => { setup?: () => void; open: () => void })\n | undefined;\n if (!Ctor) throw new Error('The verification widget could not be loaded');\n const connect = new Ctor({\n ...options,\n onSuccess: () => void callback(true),\n onError: () => void callback(false),\n onClose: () => undefined,\n });\n connect.setup?.();\n connect.open();\n return connect;\n };\n let instance: Promise<{ open: () => void }> | undefined;\n const open = () => {\n if (instance) {\n void instance.then((c) => c.open());\n return;\n }\n instance = start();\n instance.catch((error) => {\n instance = undefined;\n fail(error);\n });\n };\n if (widget.submit) {\n const button = el('button', `oluso-journey__button oluso-journey__button--${widget.submit.kind}`, widget.submit.label);\n button.type = 'button';\n button.addEventListener('click', open);\n box.appendChild(button);\n }\n open();\n return box;\n }\n case 'captcha': {\n const target = el('div', 'oluso-journey__captcha');\n box.appendChild(target);\n void renderCaptcha(target, data, (token) => {\n result(token);\n if (widget.submit) void send(form, widget.submit);\n }).catch((error) => options.onError?.(error instanceof Error ? error : new Error(String(error)), session));\n return box;\n }\n case 'qr': {\n const qr = el('div', 'oluso-journey__qr');\n if (typeof data.image === 'string') {\n const img = el('img');\n img.src = data.image;\n img.alt = '';\n qr.appendChild(img);\n }\n if (typeof data.secret === 'string') {\n if (typeof data.secretLabel === 'string') qr.appendChild(el('span', 'oluso-journey__help', data.secretLabel));\n qr.appendChild(el('code', 'oluso-journey__code', data.secret));\n }\n else if (typeof data.value === 'string' && typeof data.image !== 'string') qr.appendChild(el('code', 'oluso-journey__code', data.value));\n box.appendChild(qr);\n return box;\n }\n case 'codes': {\n const codes = Array.isArray(data.codes) ? data.codes.map(String) : [];\n const list = el('ul', 'oluso-journey__codes');\n codes.forEach((c) => list.appendChild(el('li', undefined, c)));\n const copy = el('button', 'oluso-journey__button', labels.copy);\n copy.type = 'button';\n copy.addEventListener('click', () => {\n void navigator.clipboard?.writeText(codes.join('\\n')).then(() => (copy.textContent = labels.copied));\n });\n box.append(list, copy);\n return box;\n }\n case 'poll': {\n const seconds = Math.max(2, Number(data.intervalSeconds) || 5);\n const stopAt = Number(data.maxSeconds) > 0 ? Date.now() + Number(data.maxSeconds) * 1000 : Infinity;\n const rendered = session?.currentStep;\n timers.push(window.setInterval(() => {\n if (Date.now() > stopAt) {\n clearTimers();\n return;\n }\n if (!session || document.hidden) return;\n void client.getSession(session.sessionId).then(async (now) => {\n if (now.status !== 'in_progress' || now.currentStep !== rendered) {\n clearTimers();\n await post(new FormData(), 'init');\n }\n }).catch(() => undefined);\n }, seconds * 1000));\n return null;\n }\n default:\n return null;\n }\n };\n\n const webAuthnOptions = async (data: Record<string, unknown>) => {\n if (data.publicKey) return { publicKey: data.publicKey as Record<string, unknown>, extra: undefined };\n const url = String(data.optionsUrl);\n const absolute = /^https?:/i.test(url) ? url : `${client.serverUrl}${url.startsWith('/') ? '' : '/'}${url}`;\n const method = String(data.optionsMethod ?? 'POST').toUpperCase();\n const response = await fetch(absolute, {\n method,\n headers: { 'Content-Type': 'application/json' },\n body: method === 'GET' ? undefined : JSON.stringify(data.optionsBody ?? {}),\n credentials: 'include',\n });\n if (!response.ok) throw new Error(labels.failed);\n const json = (await response.json()) as Record<string, unknown>;\n const extra: Record<string, string> = {};\n if (typeof data.idProperty === 'string' && typeof data.idField === 'string' && json[data.idProperty] != null) {\n extra[data.idField] = String(json[data.idProperty]);\n }\n return { publicKey: (json.options ?? json) as Record<string, unknown>, extra };\n };\n\n const renderHtml = (html: string) => {\n const wrapper = el('div', 'oluso-journey__html');\n wrapper.innerHTML = html;\n wrapper.querySelectorAll('script').forEach((s) => s.remove());\n wrapper.addEventListener('submit', (event) => {\n const form = event.target as HTMLFormElement;\n event.preventDefault();\n const submitter = (event as SubmitEvent).submitter as HTMLButtonElement | null;\n const data = new FormData(form);\n if (submitter?.name) data.append(submitter.name, submitter.value);\n data.delete('__RequestVerificationToken');\n submitting(form, true);\n post(data).catch((error) => {\n submitting(form, false);\n fail(error);\n });\n });\n root.replaceChildren(wrapper);\n };\n\n void (options.session ? show(options.session) : begin());\n\n return {\n get session() {\n return session;\n },\n restart: begin,\n destroy() {\n destroyed = true;\n clearTimers();\n root.remove();\n },\n };\n}\n\nfunction currentValues(item: unknown): string[] {\n if (!item) return [];\n const inputs = item instanceof RadioNodeList ? Array.from(item) : [item];\n return inputs.flatMap((node) => {\n const input = node as HTMLInputElement;\n if (input.disabled) return [];\n if (input.type === 'checkbox' || input.type === 'radio') return input.checked ? [input.value] : [];\n if (input instanceof HTMLSelectElement && input.multiple) return Array.from(input.selectedOptions).map((o) => o.value);\n return [input.value];\n });\n}\n\nconst loadedScripts = new Map<string, Promise<void>>();\n\nfunction loadScript(src: string): Promise<void> {\n let loading = loadedScripts.get(src);\n if (!loading) {\n loading = new Promise<void>((resolve, reject) => {\n const tag = document.createElement('script');\n tag.src = src;\n tag.async = true;\n tag.onload = () => resolve();\n tag.onerror = () => {\n loadedScripts.delete(src);\n reject(new Error('A script the step needs could not be loaded'));\n };\n document.head.appendChild(tag);\n });\n loadedScripts.set(src, loading);\n }\n return loading;\n}\n\nconst CAPTCHA_SCRIPTS: Record<string, { src: string; global: string }> = {\n recaptcha: { src: 'https://www.google.com/recaptcha/api.js?render=explicit&onload=', global: 'grecaptcha' },\n hcaptcha: { src: 'https://js.hcaptcha.com/1/api.js?render=explicit&onload=', global: 'hcaptcha' },\n turnstile: { src: 'https://challenges.cloudflare.com/turnstile/v0/api.js?render=explicit&onload=', global: 'turnstile' },\n};\n\ntype CaptchaApi = {\n render: (el: HTMLElement, options: Record<string, unknown>) => unknown;\n ready?: (cb: () => void) => void;\n execute?: (siteKey: string, options: { action: string }) => Promise<string>;\n};\n\nasync function renderCaptcha(target: HTMLElement, data: Record<string, unknown>, done: (token: string) => void): Promise<void> {\n const provider = String(data.provider ?? 'recaptcha').toLowerCase();\n const script = CAPTCHA_SCRIPTS[provider];\n if (!script) throw new Error(`Captcha provider '${provider}' isn't supported`);\n const w = window as unknown as Record<string, unknown>;\n if (!w[script.global]) {\n const callback = `__olusoCaptcha${Date.now()}`;\n await new Promise<void>((resolve, reject) => {\n w[callback] = () => resolve();\n const tag = document.createElement('script');\n tag.src = script.src + callback + (data.language ? `&hl=${encodeURIComponent(String(data.language))}` : '');\n tag.async = true;\n tag.onerror = () => reject(new Error('The captcha could not be loaded'));\n document.head.appendChild(tag);\n });\n }\n const api = w[script.global] as CaptchaApi;\n const siteKey = String(data.siteKey ?? '');\n if (provider === 'recaptcha' && data.version === 'v3' && api.execute) {\n api.ready?.(() => void api.execute!(siteKey, { action: String(data.action ?? 'submit') }).then(done));\n return;\n }\n api.render(target, {\n sitekey: siteKey,\n theme: data.theme,\n size: data.size,\n action: data.action,\n callback: (token: string) => done(token),\n });\n}\n","import type { TokenSet } from './types';\n\n/**\n * Token storage abstraction\n */\nexport interface TokenStorage {\n getTokens(): TokenSet | null;\n setTokens(tokens: TokenSet): void;\n clear(): void;\n}\n\nconst STORAGE_KEY = 'oluso_auth_tokens';\n\nexport class MemoryStorage implements TokenStorage {\n private tokens: TokenSet | null = null;\n\n getTokens(): TokenSet | null {\n if (this.tokens && Date.now() / 1000 >= this.tokens.expiresAt) {\n this.tokens = null;\n }\n return this.tokens;\n }\n\n setTokens(tokens: TokenSet): void {\n this.tokens = tokens;\n }\n\n clear(): void {\n this.tokens = null;\n }\n}\n\nexport class BrowserStorage implements TokenStorage {\n private store: Storage;\n\n constructor(type: 'localStorage' | 'sessionStorage') {\n this.store = type === 'localStorage' ? localStorage : sessionStorage;\n }\n\n getTokens(): TokenSet | null {\n try {\n const raw = this.store.getItem(STORAGE_KEY);\n if (!raw) return null;\n\n const tokens: TokenSet = JSON.parse(raw);\n if (Date.now() / 1000 >= tokens.expiresAt) {\n this.clear();\n return null;\n }\n return tokens;\n } catch {\n return null;\n }\n }\n\n setTokens(tokens: TokenSet): void {\n this.store.setItem(STORAGE_KEY, JSON.stringify(tokens));\n }\n\n clear(): void {\n this.store.removeItem(STORAGE_KEY);\n }\n}\n\nexport function createStorage(type: 'memory' | 'localStorage' | 'sessionStorage'): TokenStorage {\n if (type === 'memory') return new MemoryStorage();\n return new BrowserStorage(type);\n}\n","import type { OlusoAuthConfig, OidcEndpoints, OlusoUser, TokenSet, AuthResult, JourneyStepData, PasskeyOptions, FedCmOptions, WebAuthnAssertionOptions, MountSignInOptions } from './types';\nimport { OlusoClient } from '../client';\nimport { mountJourney, type JourneyMount } from '../journey/render';\nimport type { JourneySession } from '../types';\nimport { createStorage, type TokenStorage } from './storage';\n\n/**\n * Oluso Auth Client\n *\n * Handles authentication via OIDC (redirect), the hosted journey in a modal, or the\n * journey run step by step from your own UI (inline). Inline journeys complete with an\n * authorization code bound to this client's PKCE verifier, redeemed for tokens here.\n *\n * @example\n * ```typescript\n * const auth = new OlusoAuth({\n * serverUrl: 'https://auth.yoursite.com',\n * tenant: 'acme',\n * clientId: 'my-spa-client',\n * });\n *\n * // Inline auth (no redirect)\n * const result = await auth.signIn({ username: 'user@example.com', password: '...' });\n * if (result.success) {\n * console.log('Logged in as', result.user.name);\n * }\n *\n * // Check roles\n * if (auth.hasRole('admin')) { ... }\n * ```\n */\nexport class OlusoAuth {\n private config: Required<Pick<OlusoAuthConfig, 'serverUrl' | 'tenant' | 'clientId'>> & OlusoAuthConfig;\n private storage: TokenStorage;\n private user: OlusoUser | null = null;\n private resolvedEndpoints: OidcEndpoints | null = null;\n private discoveryPromise: Promise<OidcEndpoints> | null = null;\n /** PKCE verifiers of inline journeys still in progress, by session */\n private readonly journeyVerifiers = new Map<string, string>();\n\n constructor(config: OlusoAuthConfig) {\n if (!config.serverUrl || !config.tenant || !config.clientId) {\n throw new Error('serverUrl, tenant, and clientId are required');\n }\n\n this.config = {\n scopes: 'openid profile email',\n signInJourney: 'signin',\n signUpJourney: 'signup',\n passwordResetJourney: 'password-reset',\n storage: 'memory',\n ...config,\n serverUrl: config.serverUrl.replace(/\\/$/, ''),\n };\n\n this.storage = createStorage(this.config.storage!);\n\n // Restore user from stored tokens\n const tokens = this.storage.getTokens();\n if (tokens) {\n this.user = this.parseIdToken(tokens.idToken);\n }\n }\n\n // =========================================================================\n // Journey Auth (inline or modal)\n // =========================================================================\n\n /**\n * Sign in.\n * - With data: run the sign-in journey inline with these inputs (programmatic, first-party\n * only). If another step follows (e.g. MFA), the result has requiresStep, sessionId and\n * the step to render; continue with continueStep().\n * - Without data: open the hosted journey in a secure iframe modal (safe for any site)\n */\n async signIn(data?: Record<string, unknown>): Promise<AuthResult> {\n if (data) {\n return this.executeJourney(this.config.signInJourney!, data);\n }\n return this.openAuthModal('signin');\n }\n\n /**\n * Sign up.\n * - With data: run the sign-up journey inline (programmatic, first-party only)\n * - Without data: open the hosted journey in a secure iframe modal\n */\n async signUp(data?: Record<string, unknown>): Promise<AuthResult> {\n if (data) {\n return this.executeJourney(this.config.signUpJourney!, data);\n }\n return this.openAuthModal('signup');\n }\n\n /**\n * Sign in with a passkey (WebAuthn).\n * No form or iframe needed — the browser shows a native biometric/key prompt.\n * Works with discoverable credentials (usernameless) or username-based flow.\n *\n * @example\n * ```typescript\n * // Discoverable credential (passkey autofill or prompt)\n * const result = await auth.signInWithPasskey();\n *\n * // Username-based (shows credentials for specific user)\n * const result = await auth.signInWithPasskey({ username: 'user@example.com' });\n *\n * // Conditional mediation (passkey suggestions in input fields)\n * const result = await auth.signInWithPasskey({ conditional: true });\n * ```\n */\n async signInWithPasskey(options?: PasskeyOptions): Promise<AuthResult> {\n if (!window.PublicKeyCredential) {\n return { success: false, error: 'WebAuthn is not supported in this browser' };\n }\n\n const { verifier, challenge } = await this.generatePkce();\n\n // 1. Get assertion options from server. The sign-in request (scope, PKCE challenge) goes along so the\n // server can refuse it before the user is prompted for a passkey.\n const optionsUrl = `${this.config.serverUrl}/connect/webauthn/assertion-options`;\n const optionsResponse = await fetch(optionsUrl, {\n method: 'POST',\n headers: this.buildHeaders(),\n body: JSON.stringify({\n clientId: this.config.clientId,\n username: options?.username,\n scope: this.config.scopes,\n codeChallenge: challenge,\n codeChallengeMethod: 'S256',\n }),\n });\n\n if (!optionsResponse.ok) {\n const err = await optionsResponse.json().catch(() => ({ error_description: 'Failed to get passkey options' }));\n return { success: false, error: err.error_description || err.error };\n }\n\n const assertionOptions: WebAuthnAssertionOptions = await optionsResponse.json();\n\n // 2. Call navigator.credentials.get() with the options\n const publicKeyOptions: PublicKeyCredentialRequestOptions = {\n challenge: this.base64UrlDecode(assertionOptions.challenge),\n timeout: assertionOptions.timeout,\n rpId: assertionOptions.rpId,\n userVerification: (assertionOptions.userVerification || 'preferred') as UserVerificationRequirement,\n allowCredentials: assertionOptions.allowCredentials?.map(c => ({\n type: c.type as PublicKeyCredentialType,\n id: this.base64UrlDecode(c.id),\n transports: c.transports as AuthenticatorTransport[] | undefined,\n })),\n };\n\n let credential: PublicKeyCredential | null;\n try {\n const getOptions: CredentialRequestOptions = {\n publicKey: publicKeyOptions,\n signal: options?.signal,\n };\n\n // Conditional mediation (passkey autofill)\n if (options?.conditional) {\n (getOptions as Record<string, unknown>).mediation = 'conditional';\n }\n\n credential = await navigator.credentials.get(getOptions) as PublicKeyCredential | null;\n } catch (err: unknown) {\n const message = err instanceof Error ? err.message : 'Passkey request failed';\n if (err instanceof DOMException && err.name === 'AbortError') {\n return { success: false, error: 'cancelled' };\n }\n if (err instanceof DOMException && err.name === 'NotAllowedError') {\n return { success: false, error: 'cancelled' };\n }\n return { success: false, error: message };\n }\n\n if (!credential) {\n return { success: false, error: 'No credential returned' };\n }\n\n // 3. Send assertion response to server\n const assertionResponse = credential.response as AuthenticatorAssertionResponse;\n const responsePayload = JSON.stringify({\n id: credential.id,\n rawId: this.base64UrlEncode(new Uint8Array(credential.rawId)),\n type: credential.type,\n response: {\n clientDataJSON: this.base64UrlEncode(new Uint8Array(assertionResponse.clientDataJSON)),\n authenticatorData: this.base64UrlEncode(new Uint8Array(assertionResponse.authenticatorData)),\n signature: this.base64UrlEncode(new Uint8Array(assertionResponse.signature)),\n userHandle: assertionResponse.userHandle\n ? this.base64UrlEncode(new Uint8Array(assertionResponse.userHandle))\n : null,\n },\n });\n\n const verifyUrl = `${this.config.serverUrl}/connect/webauthn/assertion`;\n const verifyResponse = await fetch(verifyUrl, {\n method: 'POST',\n headers: this.buildHeaders(),\n body: JSON.stringify({\n clientId: this.config.clientId,\n assertionId: assertionOptions.assertionId,\n assertionResponse: responsePayload,\n codeChallenge: challenge,\n codeChallengeMethod: 'S256',\n scope: this.config.scopes,\n }),\n });\n\n if (!verifyResponse.ok) {\n const err = await verifyResponse.json().catch(() => ({ error_description: 'Passkey verification failed' }));\n return { success: false, error: err.error_description || err.error };\n }\n\n const { code } = await verifyResponse.json();\n\n // 4. Exchange auth code for tokens\n return this.exchangeCodeForTokens(code, verifier, 'postmessage');\n }\n\n /**\n * Sign in with FedCM (Federated Credential Management).\n * Opens a browser-native account picker — no redirect or popup needed.\n * Requires the user to be already authenticated on the Oluso server (has session cookie).\n *\n * Browser support: Chrome/Edge 132+ (the provider `params` that carry the PKCE challenge).\n * The page origin must be registered for the client (CORS origin or redirect URI).\n *\n * @example\n * ```typescript\n * const result = await auth.signInWithFedCM();\n * if (result.success) {\n * console.log('Signed in as', result.user.name);\n * }\n * ```\n */\n async signInWithFedCM(options?: FedCmOptions): Promise<AuthResult> {\n // Check FedCM support\n if (!('IdentityCredential' in window)) {\n return { success: false, error: 'FedCM is not supported in this browser' };\n }\n\n // PKCE: the challenge (and scope) reach the ID assertion endpoint through the provider's `params`,\n // which bind the code to this page; the verifier redeems it.\n const { verifier, challenge } = await this.generatePkce();\n\n try {\n const credential = await navigator.credentials.get({\n identity: {\n providers: [{\n configURL: `${this.config.serverUrl}/fedcm/config.json`,\n clientId: this.config.clientId,\n nonce: options?.nonce,\n loginHint: options?.loginHint,\n params: {\n code_challenge: challenge,\n code_challenge_method: 'S256',\n scope: this.config.scopes,\n },\n }],\n },\n mediation: options?.autoReauth ? 'optional' : 'required',\n } as CredentialRequestOptions) as { token?: string } | null;\n\n if (!credential?.token) {\n return { success: false, error: 'No credential returned from FedCM' };\n }\n\n // The FedCM token is an auth code — exchange it for real tokens\n return this.exchangeCodeForTokens(credential.token, verifier, 'fedcm');\n } catch (err: unknown) {\n if (err instanceof DOMException && err.name === 'AbortError') {\n return { success: false, error: 'cancelled' };\n }\n if (err instanceof DOMException && err.name === 'NetworkError') {\n return { success: false, error: 'FedCM network error — user may not be signed in to the identity provider' };\n }\n const message = err instanceof Error ? err.message : 'FedCM request failed';\n return { success: false, error: message };\n }\n }\n\n /**\n * Render the sign-in journey into `container` and sign in without leaving the page, e.g. in a modal when the\n * session has expired. Every step the journey has (password, MFA, passkey, consent) is shown; when it completes,\n * the code is redeemed and `onSignedIn` gets the result.\n */\n mountSignIn(container: HTMLElement, options: MountSignInOptions = {}): JourneyMount {\n const client = new OlusoClient({ serverUrl: this.config.serverUrl, tenant: this.config.tenant, apiKey: this.config.apiKey });\n let verifier = '';\n return mountJourney(container, {\n client,\n theme: options.theme,\n unstyled: options.unstyled,\n labels: options.labels,\n showCompletion: false,\n onError: options.onError,\n onRedirect: options.onRedirect,\n start: async () => {\n const pkce = await this.generatePkce();\n verifier = pkce.verifier;\n return client.startAuthJourney(\n options.journey ?? this.config.signInJourney!,\n { clientId: this.config.clientId, codeChallenge: pkce.challenge, scope: this.config.scopes });\n },\n onComplete: async (session) => {\n const result = session.code\n ? await this.exchangeCodeForTokens(session.code, verifier, 'postmessage')\n : { success: false, error: session.errorDescription || session.error || 'Authentication failed', code: session.error };\n options.onSignedIn?.(result);\n },\n });\n }\n\n /**\n * Continue an inline journey with the input for its current step (e.g. an MFA code)\n */\n async continueStep(sessionId: string, data: Record<string, unknown>): Promise<AuthResult> {\n const verifier = this.journeyVerifiers.get(sessionId);\n if (!verifier) {\n return { success: false, error: 'This journey was not started by this client', code: 'invalid_session' };\n }\n\n const url = `${this.config.serverUrl}/api/public/journeys/sessions/${encodeURIComponent(sessionId)}/step`;\n const response = await fetch(url, {\n method: 'POST',\n headers: this.buildHeaders(),\n body: JSON.stringify({ data }),\n credentials: 'include',\n });\n\n if (!response.ok) {\n const error = await response.json().catch(() => ({ message: 'Step failed' }));\n return { success: false, error: error.error_description || error.message, code: error.error || error.code };\n }\n\n return this.handleJourneyResult(await response.json(), verifier);\n }\n\n /**\n * Get the fields/config of a data-collection journey (for rendering in UI)\n */\n async getJourneyStep(journeySlug: string): Promise<JourneyStepData | null> {\n const url = `${this.config.serverUrl}/api/public/journeys/${encodeURIComponent(journeySlug)}`;\n\n const response = await fetch(url, {\n headers: this.buildHeaders(),\n credentials: 'include',\n });\n\n if (!response.ok) return null;\n\n const journey = await response.json();\n return {\n step: 'initial',\n fields: journey.fields || [],\n title: journey.ui?.title || journey.name,\n description: journey.description,\n };\n }\n\n // =========================================================================\n // OIDC Redirect Flow\n // =========================================================================\n\n /**\n * Redirect to the Oluso login page (standard OIDC Authorization Code + PKCE)\n */\n async loginWithRedirect(options?: { prompt?: 'login' | 'consent' | 'none'; state?: string }): Promise<void> {\n const { verifier, challenge } = await this.generatePkce();\n\n // Store verifier for callback\n sessionStorage.setItem('oluso_pkce_verifier', verifier);\n if (options?.state) {\n sessionStorage.setItem('oluso_auth_state', options.state);\n }\n\n const endpoints = await this.getEndpoints();\n\n const params = new URLSearchParams({\n response_type: 'code',\n client_id: this.config.clientId,\n redirect_uri: this.config.redirectUri || window.location.origin + '/callback',\n scope: this.config.scopes!,\n code_challenge: challenge,\n code_challenge_method: 'S256',\n tenant: this.config.tenant,\n });\n\n if (options?.prompt) params.set('prompt', options.prompt);\n if (options?.state) params.set('state', options.state);\n\n window.location.href = `${endpoints.authorization}?${params}`;\n }\n\n /**\n * Handle the OIDC callback (exchange code for tokens)\n */\n async handleCallback(callbackUrl?: string): Promise<AuthResult> {\n const url = new URL(callbackUrl || window.location.href);\n const code = url.searchParams.get('code');\n const error = url.searchParams.get('error');\n\n if (error) {\n return { success: false, error: url.searchParams.get('error_description') || error, code: error };\n }\n\n if (!code) {\n return { success: false, error: 'No authorization code in callback' };\n }\n\n const verifier = sessionStorage.getItem('oluso_pkce_verifier');\n sessionStorage.removeItem('oluso_pkce_verifier');\n\n if (!verifier) {\n return { success: false, error: 'PKCE verifier not found' };\n }\n\n return this.exchangeCodeForTokens(code, verifier, this.config.redirectUri || window.location.origin + '/callback');\n }\n\n // =========================================================================\n // Token & User Management\n // =========================================================================\n\n /**\n * Get the current user (null if not authenticated)\n */\n getUser(): OlusoUser | null {\n return this.user;\n }\n\n /**\n * Check if user is authenticated (has valid tokens)\n */\n isAuthenticated(): boolean {\n return this.user !== null && this.storage.getTokens() !== null;\n }\n\n /**\n * Get the current access token (for API calls)\n */\n getAccessToken(): string | null {\n return this.storage.getTokens()?.accessToken ?? null;\n }\n\n /**\n * Check if user has a specific role\n */\n hasRole(role: string): boolean {\n return this.user?.roles.includes(role) ?? false;\n }\n\n /**\n * Check if user has any of the specified roles\n */\n hasAnyRole(...roles: string[]): boolean {\n return roles.some(r => this.hasRole(r));\n }\n\n /**\n * Check if user has a specific permission\n */\n hasPermission(permission: string): boolean {\n return this.user?.permissions.includes(permission) ?? false;\n }\n\n /**\n * Refresh the access token using the refresh token\n */\n async refreshToken(): Promise<boolean> {\n const tokens = this.storage.getTokens();\n if (!tokens?.refreshToken) return false;\n\n const endpoints = await this.getEndpoints();\n const response = await fetch(endpoints.token!, {\n method: 'POST',\n headers: { 'Content-Type': 'application/x-www-form-urlencoded' },\n body: new URLSearchParams({\n grant_type: 'refresh_token',\n client_id: this.config.clientId,\n refresh_token: tokens.refreshToken,\n }),\n });\n\n if (!response.ok) {\n this.logout();\n return false;\n }\n\n const tokenData = await response.json();\n this.processTokenResponse(tokenData);\n return true;\n }\n\n /**\n * Log out — clear tokens and optionally redirect to end session.\n * If redirect is true, uses discovered or configured end_session_endpoint.\n */\n logout(options?: { redirect?: boolean; postLogoutRedirectUri?: string }): void {\n const tokens = this.storage.getTokens();\n this.storage.clear();\n this.user = null;\n this.config.onAuthStateChange?.(null);\n\n if (options?.redirect && tokens?.idToken) {\n // If we have a resolved endpoint, redirect immediately; otherwise discover first\n if (this.resolvedEndpoints?.endSession || this.config.endpoints?.endSession) {\n const params = new URLSearchParams({\n id_token_hint: tokens.idToken,\n post_logout_redirect_uri: options.postLogoutRedirectUri || window.location.origin,\n });\n window.location.href = `${this.resolvedEndpoints?.endSession || this.config.endpoints?.endSession}?${params}`;\n } else {\n // Fallback: discover then redirect\n this.getEndpoints().then(endpoints => {\n const params = new URLSearchParams({\n id_token_hint: tokens.idToken!,\n post_logout_redirect_uri: options!.postLogoutRedirectUri || window.location.origin,\n });\n window.location.href = `${endpoints.endSession}?${params}`;\n });\n }\n }\n }\n\n /**\n * Fetch the user's profile from the userinfo endpoint\n */\n async fetchUserInfo(): Promise<OlusoUser | null> {\n const token = this.getAccessToken();\n if (!token) return null;\n\n const endpoints = await this.getEndpoints();\n const response = await fetch(endpoints.userinfo!, {\n headers: { Authorization: `Bearer ${token}` },\n });\n\n if (!response.ok) return null;\n\n const claims = await response.json();\n this.user = this.claimsToUser(claims);\n this.config.onAuthStateChange?.(this.user);\n return this.user;\n }\n\n // =========================================================================\n // Private Helpers\n // =========================================================================\n\n /**\n * Opens a secure iframe modal for authentication.\n * Credentials are entered inside the iframe (auth server origin).\n * Returns tokens via postMessage + PKCE code exchange.\n */\n private async openAuthModal(mode: 'signin' | 'signup'): Promise<AuthResult> {\n const { verifier, challenge } = await this.generatePkce();\n\n const journeySlug = mode === 'signin'\n ? this.config.signInJourney!\n : this.config.signUpJourney!;\n\n const params = new URLSearchParams({\n journey: journeySlug,\n client_id: this.config.clientId,\n origin: window.location.origin,\n code_challenge: challenge,\n code_challenge_method: 'S256',\n scope: this.config.scopes!,\n });\n\n const iframeSrc = `${this.config.serverUrl}/embed/auth?${params}`;\n\n return new Promise<AuthResult>((resolve) => {\n // Create overlay + modal\n const overlay = document.createElement('div');\n overlay.style.cssText = 'position:fixed;inset:0;background:rgba(0,0,0,0.6);backdrop-filter:blur(4px);z-index:99999;display:flex;align-items:center;justify-content:center;padding:24px;';\n\n const modal = document.createElement('div');\n modal.style.cssText = 'background:#fff;border-radius:16px;width:100%;max-width:420px;max-height:90vh;overflow:hidden;box-shadow:0 25px 50px -12px rgba(0,0,0,0.25);';\n\n const header = document.createElement('div');\n header.style.cssText = 'display:flex;justify-content:flex-end;padding:12px 16px 0;';\n const closeBtn = document.createElement('button');\n closeBtn.innerHTML = '&times;';\n closeBtn.style.cssText = 'background:none;border:none;cursor:pointer;color:#9ca3af;font-size:20px;padding:4px;border-radius:6px;';\n header.appendChild(closeBtn);\n\n const iframe = document.createElement('iframe');\n iframe.src = iframeSrc;\n // Journey steps may capture documents with the camera (e.g. business verification).\n iframe.allow = 'camera; microphone';\n iframe.style.cssText = 'border:none;width:100%;min-height:300px;';\n\n const branding = document.createElement('div');\n branding.style.cssText = 'display:none;text-align:center;padding:10px 0;font-size:11px;color:#9ca3af;border-top:1px solid #e5e7eb;font-family:-apple-system,BlinkMacSystemFont,sans-serif;';\n branding.innerHTML = 'Powered by <a href=\"https://oluso.io\" target=\"_blank\" rel=\"noopener\" style=\"color:#9ca3af;text-decoration:none;\">Oluso</a>';\n\n modal.appendChild(header);\n modal.appendChild(iframe);\n modal.appendChild(branding);\n overlay.appendChild(modal);\n document.body.appendChild(overlay);\n document.body.style.overflow = 'hidden';\n\n const cleanup = () => {\n window.removeEventListener('message', messageHandler);\n document.removeEventListener('keydown', escHandler);\n document.body.style.overflow = '';\n overlay.remove();\n };\n\n const cancel = () => {\n cleanup();\n resolve({ success: false, error: 'cancelled' });\n };\n\n closeBtn.addEventListener('click', cancel);\n overlay.addEventListener('click', (e) => { if (e.target === overlay) cancel(); });\n\n const escHandler = (e: KeyboardEvent) => { if (e.key === 'Escape') cancel(); };\n document.addEventListener('keydown', escHandler);\n\n const messageHandler = async (event: MessageEvent) => {\n const serverOrigin = new URL(this.config.serverUrl).origin;\n if (event.origin !== serverOrigin) return;\n\n const data = event.data;\n if (!data || typeof data !== 'object') return;\n\n if (data.type === 'oluso:auth:code') {\n cleanup();\n const result = await this.exchangeCodeForTokens(data.code, verifier, 'postmessage');\n resolve(result);\n } else if (data.type === 'oluso:auth:error') {\n cleanup();\n resolve({ success: false, error: data.error });\n } else if (data.type === 'oluso:auth:ready') {\n branding.style.display = data.hideBranding ? 'none' : 'block';\n } else if (data.type === 'oluso:auth:resize' && typeof data.height === 'number') {\n iframe.style.height = `${data.height}px`;\n }\n };\n\n window.addEventListener('message', messageHandler);\n });\n }\n\n /**\n * Get OIDC endpoints — uses manual overrides, falls back to discovery.\n */\n private async getEndpoints(): Promise<Required<OidcEndpoints>> {\n // Manual overrides take priority\n if (this.config.endpoints?.authorization && this.config.endpoints?.token) {\n const base = this.config.serverUrl;\n return {\n authorization: this.config.endpoints.authorization,\n token: this.config.endpoints.token,\n userinfo: this.config.endpoints.userinfo || `${base}/connect/userinfo`,\n endSession: this.config.endpoints.endSession || `${base}/connect/endsession`,\n jwks: this.config.endpoints.jwks || `${base}/.well-known/openid-configuration/jwks`,\n };\n }\n\n // Use cached discovery\n if (this.resolvedEndpoints) {\n return this.resolvedEndpoints as Required<OidcEndpoints>;\n }\n\n // Discover from well-known\n if (!this.discoveryPromise) {\n this.discoveryPromise = this.discoverEndpoints();\n }\n\n this.resolvedEndpoints = await this.discoveryPromise;\n return this.resolvedEndpoints as Required<OidcEndpoints>;\n }\n\n private async discoverEndpoints(): Promise<OidcEndpoints> {\n const base = this.config.serverUrl;\n const wellKnownUrl = `${base}/.well-known/openid-configuration`;\n\n try {\n const response = await fetch(wellKnownUrl);\n if (!response.ok) {\n return this.defaultEndpoints();\n }\n\n const doc = await response.json();\n return {\n authorization: doc.authorization_endpoint || `${base}/connect/authorize`,\n token: doc.token_endpoint || `${base}/connect/token`,\n userinfo: doc.userinfo_endpoint || `${base}/connect/userinfo`,\n endSession: doc.end_session_endpoint || `${base}/connect/endsession`,\n jwks: doc.jwks_uri || `${base}/.well-known/openid-configuration/jwks`,\n };\n } catch {\n return this.defaultEndpoints();\n }\n }\n\n private defaultEndpoints(): OidcEndpoints {\n const base = this.config.serverUrl;\n return {\n authorization: `${base}/connect/authorize`,\n token: `${base}/connect/token`,\n userinfo: `${base}/connect/userinfo`,\n endSession: `${base}/connect/endsession`,\n jwks: `${base}/.well-known/openid-configuration/jwks`,\n };\n }\n\n private async executeJourney(journeySlug: string, data: Record<string, unknown>): Promise<AuthResult> {\n const { verifier, challenge } = await this.generatePkce();\n const url = `${this.config.serverUrl}/api/public/journeys/${encodeURIComponent(journeySlug)}/start`;\n\n const response = await fetch(url, {\n method: 'POST',\n headers: this.buildHeaders(),\n body: JSON.stringify({\n data,\n clientId: this.config.clientId,\n codeChallenge: challenge,\n codeChallengeMethod: 'S256',\n scope: this.config.scopes,\n }),\n credentials: 'include',\n });\n\n if (!response.ok) {\n const error = await response.json().catch(() => ({ message: 'Auth failed' }));\n return { success: false, error: error.error_description || error.message, code: error.error || error.code };\n }\n\n return this.handleJourneyResult(await response.json(), verifier);\n }\n\n /**\n * Completed: redeem the code with the journey's verifier. In progress: hand back the step\n * to render (an error from the step's last input, e.g. a wrong password, rides along).\n */\n private async handleJourneyResult(session: JourneySession, verifier: string): Promise<AuthResult> {\n if (session.completed && session.code) {\n this.journeyVerifiers.delete(session.sessionId);\n return this.exchangeCodeForTokens(session.code, verifier, 'postmessage');\n }\n\n if (session.status === 'in_progress') {\n this.journeyVerifiers.set(session.sessionId, verifier);\n const stepError = session.step?.model?.errorMessage ?? session.step?.model?.formError;\n return {\n success: false,\n requiresStep: session.step?.type ?? session.currentStep,\n sessionId: session.sessionId,\n step: session.step,\n redirectUrl: session.redirectUrl,\n error: typeof stepError === 'string' ? stepError : undefined,\n };\n }\n\n this.journeyVerifiers.delete(session.sessionId);\n return {\n success: false,\n error: session.errorDescription || session.error || 'Authentication failed',\n code: session.error,\n };\n }\n\n private processTokenResponse(tokenData: Record<string, unknown>): AuthResult {\n const tokens: TokenSet = {\n accessToken: tokenData.access_token as string,\n idToken: tokenData.id_token as string | undefined,\n refreshToken: tokenData.refresh_token as string | undefined,\n expiresAt: Math.floor(Date.now() / 1000) + (tokenData.expires_in as number || 3600),\n tokenType: (tokenData.token_type as string) || 'Bearer',\n scope: tokenData.scope as string | undefined,\n };\n\n this.storage.setTokens(tokens);\n this.user = this.parseIdToken(tokens.idToken);\n this.config.onAuthStateChange?.(this.user);\n\n return { success: true, user: this.user!, tokens };\n }\n\n private parseIdToken(idToken?: string): OlusoUser | null {\n if (!idToken) return null;\n\n try {\n const parts = idToken.split('.');\n if (parts.length !== 3) return null;\n\n const payload = JSON.parse(atob(parts[1].replace(/-/g, '+').replace(/_/g, '/')));\n return this.claimsToUser(payload);\n } catch {\n return null;\n }\n }\n\n private claimsToUser(claims: Record<string, unknown>): OlusoUser {\n return {\n sub: claims.sub as string,\n name: (claims.name || claims.preferred_username) as string | undefined,\n email: claims.email as string | undefined,\n emailVerified: claims.email_verified as boolean | undefined,\n roles: this.parseArrayClaim(claims.role || claims.roles),\n permissions: this.parseArrayClaim(claims.permission || claims.permissions),\n tenantId: claims.tenant_id as string | undefined,\n claims,\n };\n }\n\n private parseArrayClaim(claim: unknown): string[] {\n if (!claim) return [];\n if (Array.isArray(claim)) return claim.map(String);\n if (typeof claim === 'string') return [claim];\n return [];\n }\n\n private buildHeaders(): Record<string, string> {\n const headers: Record<string, string> = {\n 'Content-Type': 'application/json',\n 'X-Tenant-ID': this.config.tenant,\n };\n if (this.config.apiKey) {\n headers['X-API-Key'] = this.config.apiKey;\n }\n return headers;\n }\n\n private async generatePkce(): Promise<{ verifier: string; challenge: string }> {\n const array = new Uint8Array(32);\n crypto.getRandomValues(array);\n const verifier = this.base64UrlEncode(array);\n\n const encoder = new TextEncoder();\n const digest = await crypto.subtle.digest('SHA-256', encoder.encode(verifier));\n const challenge = this.base64UrlEncode(new Uint8Array(digest));\n\n return { verifier, challenge };\n }\n\n private base64UrlEncode(buffer: Uint8Array): string {\n let binary = '';\n for (let i = 0; i < buffer.length; i++) {\n binary += String.fromCharCode(buffer[i]);\n }\n return btoa(binary).replace(/\\+/g, '-').replace(/\\//g, '_').replace(/=+$/, '');\n }\n\n private base64UrlDecode(str: string): ArrayBuffer {\n const base64 = str.replace(/-/g, '+').replace(/_/g, '/');\n const padding = '='.repeat((4 - base64.length % 4) % 4);\n const binary = atob(base64 + padding);\n const bytes = new Uint8Array(binary.length);\n for (let i = 0; i < binary.length; i++) {\n bytes[i] = binary.charCodeAt(i);\n }\n return bytes.buffer;\n }\n\n /**\n * Exchange an authorization code for tokens via the token endpoint.\n * Used by passkey, FedCM, and modal auth flows.\n */\n private async exchangeCodeForTokens(code: string, verifier: string, redirectUri: string): Promise<AuthResult> {\n const endpoints = await this.getEndpoints();\n const response = await fetch(endpoints.token!, {\n method: 'POST',\n headers: { 'Content-Type': 'application/x-www-form-urlencoded' },\n body: new URLSearchParams({\n grant_type: 'authorization_code',\n client_id: this.config.clientId,\n code,\n redirect_uri: redirectUri,\n code_verifier: verifier,\n }),\n });\n\n if (!response.ok) {\n const err = await response.json().catch(() => ({ error_description: 'Token exchange failed' }));\n return { success: false, error: err.error_description || err.error };\n }\n\n const tokenData = await response.json();\n return this.processTokenResponse(tokenData);\n }\n}\n"],"mappings":"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","names":["options"]}