import { BoardSdk } from './index.js'; import './_spec-EgN7VmAI.js'; import './search-Dx1TiAZk.js'; import './board-CsEAgsKh.js'; import './jobs-ub3gywNQ.js'; import './seo-BbG2Ujyo.js'; import './blog-BIjFcNcm.js'; /** * Session cookie codec — pure (no framework imports, no node imports) so it * stays hermetically testable and platform-neutral: helpers speak cookie * STRINGS (`Set-Cookie` values / `Cookie` headers), never framework response * objects. The session is the SDK bearer pair plus the access-token expiry; * it lives in ONE httpOnly cookie owned by the host app (the SDK never sees * storage on the server — ). */ interface BoardSession { accessToken: string; refreshToken: string; /** Access-token expiry, epoch ms (from board_auth_session). */ expiresAt: number; } declare const SESSION_COOKIE_NAME = "__Host-cavuno_board_session"; /** * The session cookie name, optionally board-scoped. One origin can serve * multiple boards (the hosted platform scopes its grant cookie per account * for this reason) — a multi-board host MUST pass its board identifier so * sessions cannot clobber each other; single-board apps omit it. */ declare function sessionCookieName(board?: string): string; declare function serializeSessionCookie(session: BoardSession, options?: { board?: string; }): string; declare function clearSessionCookie(options?: { board?: string; }): string; declare function parseSessionCookie(cookieHeader: string | null, options?: { board?: string; }): BoardSession | null; declare function isExpiringSoon(session: BoardSession, now: number, windowMs?: number): boolean; declare const BOARD_ACCESS_COOKIE_NAME = "__Host-cavuno_board_access"; /** * The grant cookie name, optionally board-scoped — hosted scopes its grant * cookie per account (`board_access_`) because one app instance * can gate multiple boards. Multi-board hosts MUST pass their board * identifier; single-board apps omit it. */ declare function grantCookieName(board?: string): string; declare function serializeGrantCookie(token: string, options?: { board?: string; }): string; declare function clearGrantCookie(options?: { board?: string; }): string; declare function parseGrantCookie(cookieHeader: string | null, options?: { board?: string; }): string | null; /** * Open-redirect guards — pure URL-safety logic (no cookies involved), * transcribed from the hosted board's `validate-redirect-path.ts` and * tested against it input-for-input. */ /** * Guard a `?redirect=` / `?next=` param: a same-origin absolute path only * ('/', not '//', no scheme), else `defaultPath` — hosted's * `getSafeRedirectPath(path, defaultPath = '/')` shape (the two-arg form is * live on the employer sign-up page, which falls back to * '/account/connect'). */ declare function safeRedirectPath(path: string | undefined | null, defaultPath?: string): string; /** * The current page path (from the request `Referer`) for the /password * redirect-back, guarded by `safeRedirectPath`. Pure — the framework-owned * header read happens in the host app's middleware and the value is passed * in here, so this stays platform-neutral. */ declare function currentPathFromReferer(referer: string | null): string; /** * Keep `.cavuno.app` working after a custom-domain cutover by * 308-redirecting to the board's canonical custom domain. * * Pass `primaryDomain` from the public board context. When it is set, a * request to a `*.cavuno.app` serving host redirects in one hop while * preserving the path and query. A board without a custom domain keeps * serving from its cavuno.app hostname. */ /** * True when the request host is a cavuno.app board-serving host * (slug or board-hash subdomain), not the apex and not a preview host * we deliberately leave alone. */ declare function isCavunoAppServingHost(hostname: string): boolean; /** * When a custom-domain board is hit on its cavuno.app fallback origin, * return the one-hop 308 Location to the canonical custom domain. * Domainless boards (no primaryDomain) return null — serve in place. */ declare function getCavunoAppCanonicalRedirectUrl(params: { currentHost: string | null; /** * From `board.context().primaryDomain` — the board's active primary * custom domain hostname, or null when domainless. */ primaryDomain: string | null | undefined; /** Full request URL or path+query; path+query is preserved on the hop. */ requestUrl?: string | null; defaultPath?: string; }): string | null; /** * Single-flight session refresh — dedupes concurrent refreshes for the same * session WITHIN one process/isolate (the rotation race, , * mitigated at the one layer a client library can reach). * * Refresh tokens are single-use: two concurrent refreshes for the same * session burn the pair — the loser 401s and the user is signed out * mid-session. This helper keys an in-flight slot per refreshToken so every * concurrent caller awaits the SAME rotation; sequential calls after settle * start a fresh one. * * Scope honestly stated: the dedupe is PER PROCESS/ISOLATE (an in-memory * map). Two simultaneous requests served by different instances can still * race the token; the proactive `isExpiringSoon` window keeps that rare, it * does not eliminate it. Pair with `storage: 'nostore'` on the shared * server client — `auth.refresh` persists the rotated pair into * `client.storage`, and any persistent shared storage would bleed one * user's tokens into another's requests. * * Returns the rotated `BoardSession` (persist it back to the cookie), or * `null` on a 401 — the token is burned or revoked: clear the cookie and * continue signed out, never retry. Other errors (network, 5xx, 429) * rethrow untouched. * * @example * const refreshSession = createSessionRefresher(board); * // in the session middleware: * if (isExpiringSoon(session, Date.now())) { * const next = await refreshSession(session); * setCookie(next ? serializeSessionCookie(next) : clearSessionCookie()); * } */ declare function createSessionRefresher(board: Pick): (session: BoardSession) => Promise; export { BOARD_ACCESS_COOKIE_NAME, type BoardSession, SESSION_COOKIE_NAME, clearGrantCookie, clearSessionCookie, createSessionRefresher, currentPathFromReferer, getCavunoAppCanonicalRedirectUrl, grantCookieName, isCavunoAppServingHost, isExpiringSoon, parseGrantCookie, parseSessionCookie, safeRedirectPath, serializeGrantCookie, serializeSessionCookie, sessionCookieName };