@insforge/sdk 1.4.1 → 1.4.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +122 -9
- package/SDK-REFERENCE.md +29 -19
- package/dist/{client-DoWwzWnh.d.ts → client-BR9o-WUm.d.ts} +2 -1
- package/dist/{client-hYdj36T6.d.mts → client-C-qBRoea.d.mts} +2 -1
- package/dist/index.d.mts +4 -4
- package/dist/index.d.ts +4 -4
- package/dist/index.js +20 -6
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +20 -6
- package/dist/index.mjs.map +1 -1
- package/dist/{middleware-BxJ0PzUT.d.mts → middleware-K59XjpUX.d.mts} +2 -2
- package/dist/{middleware-DLZiheYP.d.ts → middleware-Tu_RlUAt.d.ts} +2 -2
- package/dist/ssr/middleware.d.mts +2 -2
- package/dist/ssr/middleware.d.ts +2 -2
- package/dist/ssr/middleware.js.map +1 -1
- package/dist/ssr/middleware.mjs.map +1 -1
- package/dist/ssr.d.mts +46 -6
- package/dist/ssr.d.ts +46 -6
- package/dist/ssr.js +129 -7
- package/dist/ssr.js.map +1 -1
- package/dist/ssr.mjs +128 -7
- package/dist/ssr.mjs.map +1 -1
- package/dist/{types-NjykhyRq.d.mts → types-Dk-44JJf.d.mts} +12 -0
- package/dist/{types-NjykhyRq.d.ts → types-Dk-44JJf.d.ts} +12 -0
- package/package.json +1 -1
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { I as InsForgeConfig, d as InsForgeError } from './types-
|
|
1
|
+
import { I as InsForgeConfig, d as InsForgeError } from './types-Dk-44JJf.mjs';
|
|
2
2
|
|
|
3
3
|
declare const DEFAULT_ACCESS_TOKEN_COOKIE = "insforge_access_token";
|
|
4
4
|
declare const DEFAULT_REFRESH_TOKEN_COOKIE = "insforge_refresh_token";
|
|
@@ -64,4 +64,4 @@ interface UpdateSessionResult {
|
|
|
64
64
|
}
|
|
65
65
|
declare function updateSession(options: UpdateSessionOptions): Promise<UpdateSessionResult>;
|
|
66
66
|
|
|
67
|
-
export { type AuthCookieSettings as A, type CookieStore as C, DEFAULT_ACCESS_TOKEN_COOKIE as D, type UpdateSessionOptions as U, type
|
|
67
|
+
export { type AuthCookieSettings as A, type CookieStore as C, DEFAULT_ACCESS_TOKEN_COOKIE as D, type UpdateSessionOptions as U, type CookieWriter as a, type UpdateSessionResult as b, DEFAULT_REFRESH_TOKEN_COOKIE as c, accessTokenCookieOptions as d, clearAuthCookies as e, getRefreshTokenCookieName as f, getAccessTokenCookieName as g, type AuthCookieNames as h, type AuthCookieOptions as i, type CookieOptions as j, type CookieReader as k, refreshTokenCookieOptions as r, setAuthCookies as s, updateSession as u };
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { I as InsForgeConfig, d as InsForgeError } from './types-
|
|
1
|
+
import { I as InsForgeConfig, d as InsForgeError } from './types-Dk-44JJf.js';
|
|
2
2
|
|
|
3
3
|
declare const DEFAULT_ACCESS_TOKEN_COOKIE = "insforge_access_token";
|
|
4
4
|
declare const DEFAULT_REFRESH_TOKEN_COOKIE = "insforge_refresh_token";
|
|
@@ -64,4 +64,4 @@ interface UpdateSessionResult {
|
|
|
64
64
|
}
|
|
65
65
|
declare function updateSession(options: UpdateSessionOptions): Promise<UpdateSessionResult>;
|
|
66
66
|
|
|
67
|
-
export { type AuthCookieSettings as A, type CookieStore as C, DEFAULT_ACCESS_TOKEN_COOKIE as D, type UpdateSessionOptions as U, type
|
|
67
|
+
export { type AuthCookieSettings as A, type CookieStore as C, DEFAULT_ACCESS_TOKEN_COOKIE as D, type UpdateSessionOptions as U, type CookieWriter as a, type UpdateSessionResult as b, DEFAULT_REFRESH_TOKEN_COOKIE as c, accessTokenCookieOptions as d, clearAuthCookies as e, getRefreshTokenCookieName as f, getAccessTokenCookieName as g, type AuthCookieNames as h, type AuthCookieOptions as i, type CookieOptions as j, type CookieReader as k, refreshTokenCookieOptions as r, setAuthCookies as s, updateSession as u };
|
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
export {
|
|
2
|
-
import '../types-
|
|
1
|
+
export { h as AuthCookieNames, i as AuthCookieOptions, A as AuthCookieSettings, j as CookieOptions, k as CookieReader, C as CookieStore, a as CookieWriter, D as DEFAULT_ACCESS_TOKEN_COOKIE, c as DEFAULT_REFRESH_TOKEN_COOKIE, U as UpdateSessionOptions, b as UpdateSessionResult, e as clearAuthCookies, g as getAccessTokenCookieName, f as getRefreshTokenCookieName, s as setAuthCookies, u as updateSession } from '../middleware-K59XjpUX.mjs';
|
|
2
|
+
import '../types-Dk-44JJf.mjs';
|
|
3
3
|
import '@insforge/shared-schemas';
|
package/dist/ssr/middleware.d.ts
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
export {
|
|
2
|
-
import '../types-
|
|
1
|
+
export { h as AuthCookieNames, i as AuthCookieOptions, A as AuthCookieSettings, j as CookieOptions, k as CookieReader, C as CookieStore, a as CookieWriter, D as DEFAULT_ACCESS_TOKEN_COOKIE, c as DEFAULT_REFRESH_TOKEN_COOKIE, U as UpdateSessionOptions, b as UpdateSessionResult, e as clearAuthCookies, g as getAccessTokenCookieName, f as getRefreshTokenCookieName, s as setAuthCookies, u as updateSession } from '../middleware-Tu_RlUAt.js';
|
|
2
|
+
import '../types-Dk-44JJf.js';
|
|
3
3
|
import '@insforge/shared-schemas';
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/ssr/middleware.ts","../../src/lib/jwt.ts","../../src/ssr/cookies.ts","../../src/types.ts","../../src/ssr/refresh.ts","../../src/ssr/update-session.ts"],"sourcesContent":["export {\n updateSession,\n type UpdateSessionOptions,\n type UpdateSessionResult,\n} from './update-session';\nexport {\n DEFAULT_ACCESS_TOKEN_COOKIE,\n DEFAULT_REFRESH_TOKEN_COOKIE,\n clearAuthCookies,\n getAccessTokenCookieName,\n getRefreshTokenCookieName,\n setAuthCookies,\n type AuthCookieNames,\n type AuthCookieOptions,\n type AuthCookieSettings,\n type CookieOptions,\n type CookieReader,\n type CookieStore,\n type CookieWriter,\n} from './cookies';\n","function decodeBase64Url(input: string): string {\n const normalized = input.replace(/-/g, '+').replace(/_/g, '/');\n const padded = normalized.padEnd(\n normalized.length + ((4 - (normalized.length % 4)) % 4),\n '=',\n );\n\n const binary = atob(padded);\n const bytes = Uint8Array.from(binary, (char) => char.charCodeAt(0));\n return new TextDecoder().decode(bytes);\n}\n\nexport function getJwtExpiration(token: string | null | undefined): Date | null {\n if (!token) return null;\n\n const [, payload] = token.split('.');\n if (!payload) return null;\n\n try {\n const parsed = JSON.parse(decodeBase64Url(payload)) as { exp?: unknown };\n if (typeof parsed.exp !== 'number' || !Number.isFinite(parsed.exp)) {\n return null;\n }\n return new Date(parsed.exp * 1000);\n } catch {\n return null;\n }\n}\n\nexport function isJwtExpiredOrExpiring(\n token: string | null | undefined,\n leewaySeconds = 60,\n): boolean {\n if (!token) return false;\n const expires = getJwtExpiration(token);\n if (!expires) return true;\n\n return expires.getTime() <= Date.now() + leewaySeconds * 1000;\n}\n","import { getJwtExpiration } from '../lib/jwt';\n\nexport const DEFAULT_ACCESS_TOKEN_COOKIE = 'insforge_access_token';\nexport const DEFAULT_REFRESH_TOKEN_COOKIE = 'insforge_refresh_token';\n\nexport interface AuthCookieNames {\n accessToken?: string;\n refreshToken?: string;\n}\n\nexport interface CookieOptions {\n domain?: string;\n path?: string;\n expires?: Date;\n maxAge?: number;\n httpOnly?: boolean;\n secure?: boolean;\n sameSite?: 'lax' | 'strict' | 'none';\n}\n\nexport interface AuthCookieOptions {\n accessToken?: CookieOptions;\n refreshToken?: CookieOptions;\n}\n\nexport type CookieStoreValue =\n | string\n | { value?: string | null }\n | undefined\n | null;\n\nexport interface CookieReader {\n get(name: string): CookieStoreValue;\n}\n\nexport interface CookieWriter {\n set?(name: string, value: string, options?: CookieOptions): unknown;\n set?(options: { name: string; value: string } & CookieOptions): unknown;\n delete?(name: string): unknown;\n delete?(options: { name: string } & CookieOptions): unknown;\n}\n\nexport interface CookieStore extends CookieReader, CookieWriter {}\n\nexport interface AuthCookieSettings {\n names?: AuthCookieNames;\n options?: AuthCookieOptions;\n}\n\nconst EXPIRED_DATE = new Date(0);\n\nexport function getAccessTokenCookieName(names?: AuthCookieNames): string {\n return names?.accessToken ?? DEFAULT_ACCESS_TOKEN_COOKIE;\n}\n\nexport function getRefreshTokenCookieName(names?: AuthCookieNames): string {\n return names?.refreshToken ?? DEFAULT_REFRESH_TOKEN_COOKIE;\n}\n\nexport function getCookieValue(\n cookies: CookieReader | undefined,\n name: string,\n): string | null {\n if (!cookies) return null;\n\n const value = cookies.get(name);\n if (typeof value === 'string') return value || null;\n if (value && typeof value.value === 'string') return value.value || null;\n return null;\n}\n\nexport function getCookieValueFromHeader(\n cookieHeader: string | null | undefined,\n name: string,\n): string | null {\n if (!cookieHeader) return null;\n\n const parts = cookieHeader.split(';');\n for (const part of parts) {\n const [rawName, ...rawValue] = part.trim().split('=');\n if (rawName !== name) continue;\n try {\n return decodeURIComponent(rawValue.join('='));\n } catch {\n return rawValue.join('=');\n }\n }\n return null;\n}\n\nexport function getBrowserCookie(name: string): string | null {\n if (typeof document === 'undefined') return null;\n return getCookieValueFromHeader(document.cookie, name);\n}\n\nfunction defaultCookieOptions(): CookieOptions {\n const secure =\n typeof process !== 'undefined'\n ? process.env.NODE_ENV === 'production'\n : typeof location !== 'undefined' && location.protocol === 'https:';\n\n return {\n path: '/',\n sameSite: 'lax',\n secure,\n };\n}\n\nexport function accessTokenCookieOptions(\n token: string,\n overrides?: CookieOptions,\n): CookieOptions {\n return {\n ...defaultCookieOptions(),\n httpOnly: false,\n expires: getJwtExpiration(token) ?? undefined,\n ...overrides,\n };\n}\n\nexport function refreshTokenCookieOptions(\n token: string,\n overrides?: CookieOptions,\n): CookieOptions {\n return {\n ...defaultCookieOptions(),\n httpOnly: true,\n expires: getJwtExpiration(token) ?? undefined,\n ...overrides,\n };\n}\n\nexport function expiredCookieOptions(overrides?: CookieOptions): CookieOptions {\n const { expires: _expires, maxAge: _maxAge, ...safeOverrides } = overrides ?? {};\n return {\n ...defaultCookieOptions(),\n ...safeOverrides,\n expires: EXPIRED_DATE,\n maxAge: 0,\n };\n}\n\nexport function setCookie(\n cookies: CookieWriter | undefined,\n name: string,\n value: string,\n options?: CookieOptions,\n): void {\n if (!cookies?.set) return;\n cookies.set(name, value, options);\n}\n\nexport function deleteCookie(\n cookies: CookieWriter | undefined,\n name: string,\n options?: CookieOptions,\n): void {\n if (!cookies) return;\n if (cookies.set) {\n cookies.set(name, '', expiredCookieOptions(options));\n return;\n }\n cookies.delete?.(name);\n}\n\nexport function serializeCookie(\n name: string,\n value: string,\n options: CookieOptions = {},\n): string {\n const parts = [`${encodeURIComponent(name)}=${encodeURIComponent(value)}`];\n\n if (options.maxAge !== undefined) parts.push(`Max-Age=${options.maxAge}`);\n if (options.domain) parts.push(`Domain=${options.domain}`);\n if (options.path) parts.push(`Path=${options.path}`);\n if (options.expires) parts.push(`Expires=${options.expires.toUTCString()}`);\n if (options.httpOnly) parts.push('HttpOnly');\n if (options.secure) parts.push('Secure');\n if (options.sameSite) {\n const sameSite =\n options.sameSite.charAt(0).toUpperCase() + options.sameSite.slice(1);\n parts.push(`SameSite=${sameSite}`);\n }\n\n return parts.join('; ');\n}\n\nexport function appendSetCookie(\n headers: Headers,\n name: string,\n value: string,\n options?: CookieOptions,\n): void {\n headers.append('Set-Cookie', serializeCookie(name, value, options));\n}\n\nexport function setAuthCookies(\n cookies: CookieWriter | undefined,\n tokens: {\n accessToken: string;\n refreshToken?: string | null;\n },\n settings: AuthCookieSettings = {},\n): void {\n const accessName = getAccessTokenCookieName(settings.names);\n const refreshName = getRefreshTokenCookieName(settings.names);\n const accessOptions = accessTokenCookieOptions(\n tokens.accessToken,\n settings.options?.accessToken,\n );\n\n setCookie(cookies, accessName, tokens.accessToken, accessOptions);\n if (tokens.refreshToken) {\n setCookie(\n cookies,\n refreshName,\n tokens.refreshToken,\n refreshTokenCookieOptions(\n tokens.refreshToken,\n settings.options?.refreshToken,\n ),\n );\n }\n}\n\nexport function clearAuthCookies(\n cookies: CookieWriter | undefined,\n settings: AuthCookieSettings = {},\n): void {\n const accessName = getAccessTokenCookieName(settings.names);\n const refreshName = getRefreshTokenCookieName(settings.names);\n const accessOptions = expiredCookieOptions(settings.options?.accessToken);\n const refreshOptions = expiredCookieOptions(settings.options?.refreshToken);\n\n deleteCookie(cookies, accessName, accessOptions);\n deleteCookie(cookies, refreshName, refreshOptions);\n}\n\nexport function setAuthCookieHeaders(\n headers: Headers,\n tokens: {\n accessToken: string;\n refreshToken?: string | null;\n },\n settings: AuthCookieSettings = {},\n): void {\n const accessName = getAccessTokenCookieName(settings.names);\n const refreshName = getRefreshTokenCookieName(settings.names);\n\n appendSetCookie(\n headers,\n accessName,\n tokens.accessToken,\n accessTokenCookieOptions(tokens.accessToken, settings.options?.accessToken),\n );\n if (tokens.refreshToken) {\n appendSetCookie(\n headers,\n refreshName,\n tokens.refreshToken,\n refreshTokenCookieOptions(\n tokens.refreshToken,\n settings.options?.refreshToken,\n ),\n );\n }\n}\n\nexport function clearAuthCookieHeaders(\n headers: Headers,\n settings: AuthCookieSettings = {},\n): void {\n appendSetCookie(\n headers,\n getAccessTokenCookieName(settings.names),\n '',\n expiredCookieOptions(settings.options?.accessToken),\n );\n appendSetCookie(\n headers,\n getRefreshTokenCookieName(settings.names),\n '',\n expiredCookieOptions(settings.options?.refreshToken),\n );\n}\n","/**\n * InsForge SDK Types - only SDK-specific types here\n * Use @insforge/shared-schemas directly for API types\n */\n\nimport type { ErrorCode, UserSchema } from '@insforge/shared-schemas';\n\nexport type InsForgeErrorCode = ErrorCode | (string & {});\n\nexport interface InsForgeConfig {\n /**\n * The base URL of the InsForge backend API\n * @default \"http://localhost:7130\"\n */\n baseUrl?: string;\n\n /**\n * Anonymous API key (optional)\n * Used for public/unauthenticated requests when no user token is set\n */\n anonKey?: string;\n\n /**\n * Static access token (optional)\n * Seeds the client with a fixed bearer token used for all authenticated\n * requests — e.g. a user JWT inside an edge function, or a server-signed\n * JWT from an external auth provider. Disables automatic token refresh\n * and implies server mode unless `isServerMode` is set explicitly.\n */\n accessToken?: string;\n\n /**\n * @deprecated Use `accessToken` instead. Same behavior; `accessToken`\n * takes precedence when both are provided.\n */\n edgeFunctionToken?: string;\n\n /**\n * Direct URL to Deno Subhosting functions (optional)\n * When provided, SDK will try this URL first for function invocations.\n * Falls back to proxy URL if subhosting returns 404.\n * @example \"https://{appKey}.functions.insforge.app\"\n */\n functionsUrl?: string;\n\n /**\n * Custom fetch implementation (useful for Node.js environments)\n */\n fetch?: typeof fetch;\n\n /**\n * Enable server-side auth mode (SSR/Node runtime)\n * In this mode auth endpoints use `client_type=mobile` and refresh_token body flow.\n *\n * @deprecated Use `createServerClient()`, `createBrowserClient()`, and\n * `updateSession()` from `@insforge/sdk/ssr` for SSR apps.\n * @default false\n */\n isServerMode?: boolean;\n\n /**\n * Custom headers to include with every request\n */\n headers?: Record<string, string>;\n\n /**\n * Enable debug logging for HTTP requests and responses.\n * When true, request/response details are logged to the console.\n * Can also be a custom log function for advanced use cases.\n * @default false\n */\n debug?: boolean | ((message: string, ...args: any[]) => void);\n\n /**\n * Request timeout in milliseconds.\n * Requests that exceed this duration will be aborted.\n * Set to 0 to disable timeout.\n * @default 30000\n */\n timeout?: number;\n\n /**\n * Maximum number of retry attempts for failed requests.\n * Retries are triggered on network errors and server errors (5xx).\n * Client errors (4xx) are never retried.\n * Set to 0 to disable retries.\n * @default 3\n */\n retryCount?: number;\n\n /**\n * Initial delay in milliseconds before the first retry.\n * The delay doubles with each subsequent attempt (exponential backoff)\n * with ±15% jitter to prevent thundering herd.\n * @default 500\n */\n retryDelay?: number;\n}\n\nexport type InsForgeAdminConfig = Omit<\n InsForgeConfig,\n 'anonKey' | 'accessToken' | 'edgeFunctionToken' | 'isServerMode'\n> & {\n /**\n * Project admin API key. Keep this server-side only.\n */\n apiKey: string;\n};\n\nexport interface AuthSession {\n user: UserSchema;\n accessToken: string;\n expiresAt?: Date;\n}\n\nexport interface AuthRefreshResponse {\n user: UserSchema;\n accessToken: string;\n csrfToken?: string;\n refreshToken?: string;\n}\n\nexport interface ApiError {\n error: InsForgeErrorCode;\n message: string;\n statusCode: number;\n nextActions?: string;\n}\n\nexport class InsForgeError extends Error {\n public statusCode: number;\n public error: InsForgeErrorCode;\n public nextActions?: string;\n\n constructor(\n message: string,\n statusCode: number,\n error: InsForgeErrorCode,\n nextActions?: string,\n ) {\n super(message);\n this.name = 'InsForgeError';\n this.statusCode = statusCode;\n this.error = error;\n this.nextActions = nextActions;\n }\n\n static fromApiError(apiError: ApiError): InsForgeError {\n return new InsForgeError(\n apiError.message,\n apiError.statusCode,\n apiError.error,\n apiError.nextActions,\n );\n }\n}\n","import {\n InsForgeError,\n type AuthRefreshResponse,\n type InsForgeConfig,\n} from '../types';\nimport { ERROR_CODES } from '@insforge/shared-schemas';\nimport {\n clearAuthCookieHeaders,\n getCookieValue,\n getCookieValueFromHeader,\n getRefreshTokenCookieName,\n setAuthCookieHeaders,\n type AuthCookieSettings,\n type CookieStore,\n} from './cookies';\n\nexport interface RefreshAuthOptions\n extends Omit<\n InsForgeConfig,\n 'accessToken' | 'edgeFunctionToken' | 'isServerMode' | 'auth'\n >,\n AuthCookieSettings {\n request?: Request;\n cookies?: Pick<CookieStore, 'get'>;\n refreshToken?: string;\n}\n\nexport interface RefreshAuthResult {\n response: Response;\n data: AuthRefreshResponse | null;\n accessToken: string | null;\n refreshToken: string | null;\n error: InsForgeError | null;\n}\n\nexport type RefreshAuthRouteHandler = (request: Request) => Promise<Response>;\n\nfunction jsonResponse(\n body: unknown,\n init: ResponseInit = {},\n headers = new Headers(init.headers),\n): Response {\n headers.set('Content-Type', 'application/json');\n return new Response(JSON.stringify(body), {\n ...init,\n headers,\n });\n}\n\nfunction normalizeError(error: unknown): InsForgeError {\n if (error instanceof InsForgeError) return error;\n\n if (error && typeof error === 'object') {\n const body = error as {\n error?: unknown;\n message?: unknown;\n statusCode?: unknown;\n };\n return new InsForgeError(\n typeof body.message === 'string'\n ? body.message\n : 'Failed to refresh auth session',\n typeof body.statusCode === 'number' ? body.statusCode : 500,\n typeof body.error === 'string'\n ? body.error\n : ERROR_CODES.UNKNOWN_ERROR,\n );\n }\n\n return new InsForgeError(\n error instanceof Error ? error.message : 'Failed to refresh auth session',\n 500,\n ERROR_CODES.UNKNOWN_ERROR,\n );\n}\n\nasync function readJson(response: Response): Promise<unknown> {\n const contentType = response.headers.get('content-type');\n if (!contentType?.includes('json')) return null;\n return response.json();\n}\n\nfunction readRefreshToken(options: RefreshAuthOptions): string | null {\n if (options.refreshToken) return options.refreshToken;\n\n const refreshCookieName = getRefreshTokenCookieName(options.names);\n const cookieValue = getCookieValue(options.cookies, refreshCookieName);\n if (cookieValue) return cookieValue;\n\n return getCookieValueFromHeader(\n options.request?.headers.get('cookie'),\n refreshCookieName,\n );\n}\n\nexport async function refreshAuth(\n options: RefreshAuthOptions = {},\n): Promise<RefreshAuthResult> {\n const headers = new Headers();\n const refreshToken = readRefreshToken(options);\n\n if (!refreshToken) {\n clearAuthCookieHeaders(headers, options);\n const error = new InsForgeError(\n 'Refresh token cookie is missing',\n 401,\n ERROR_CODES.AUTH_UNAUTHORIZED,\n );\n return {\n response: jsonResponse(\n {\n error: error.error,\n message: error.message,\n statusCode: error.statusCode,\n },\n { status: error.statusCode },\n headers,\n ),\n data: null,\n accessToken: null,\n refreshToken: null,\n error,\n };\n }\n\n let { baseUrl, anonKey } = options;\n try {\n baseUrl ||= process.env.NEXT_PUBLIC_INSFORGE_URL;\n anonKey ||= process.env.NEXT_PUBLIC_INSFORGE_ANON_KEY;\n } catch {\n // process may be unavailable outside Next.js/browser-bundled envs.\n }\n if (!baseUrl || !anonKey) {\n throw new Error(\n 'Missing InsForge baseUrl or anonKey. Pass baseUrl and anonKey to refreshAuth() or set NEXT_PUBLIC_INSFORGE_URL and NEXT_PUBLIC_INSFORGE_ANON_KEY.',\n );\n }\n\n const fetchImpl =\n options.fetch ??\n (globalThis.fetch\n ? globalThis.fetch.bind(globalThis)\n : (undefined as typeof fetch | undefined));\n if (!fetchImpl) {\n throw new Error(\n 'Fetch is not available. Please provide a fetch implementation.',\n );\n }\n\n const requestHeaders = new Headers(options.headers);\n requestHeaders.set('Authorization', `Bearer ${anonKey}`);\n requestHeaders.set('Content-Type', 'application/json');\n requestHeaders.set('Accept', 'application/json');\n\n let data: AuthRefreshResponse | null = null;\n let error: InsForgeError | null = null;\n\n try {\n const response = await fetchImpl(\n new URL('/api/auth/refresh?client_type=mobile', baseUrl).toString(),\n {\n method: 'POST',\n headers: requestHeaders,\n body: JSON.stringify({ refresh_token: refreshToken }),\n },\n );\n const body = await readJson(response);\n if (!response.ok) {\n error = normalizeError(\n body ?? {\n message: 'Failed to refresh auth session',\n statusCode: response.status,\n error: ERROR_CODES.UNKNOWN_ERROR,\n },\n );\n } else {\n data = body as AuthRefreshResponse;\n }\n } catch (caught) {\n error = normalizeError(caught);\n }\n\n if (error || !data?.accessToken) {\n clearAuthCookieHeaders(headers, options);\n const normalized = normalizeError(error);\n return {\n response: jsonResponse(\n {\n error: normalized.error,\n message: normalized.message,\n statusCode: normalized.statusCode,\n },\n { status: normalized.statusCode || 500 },\n headers,\n ),\n data: null,\n accessToken: null,\n refreshToken: null,\n error: normalized,\n };\n }\n\n const nextRefreshToken = data.refreshToken ?? refreshToken;\n setAuthCookieHeaders(\n headers,\n {\n accessToken: data.accessToken,\n refreshToken: nextRefreshToken,\n },\n options,\n );\n\n const responseBody: AuthRefreshResponse = {\n accessToken: data.accessToken,\n user: data.user,\n csrfToken: data.csrfToken,\n };\n\n return {\n response: jsonResponse(responseBody, { status: 200 }, headers),\n data: responseBody,\n accessToken: data.accessToken,\n refreshToken: nextRefreshToken,\n error: null,\n };\n}\n\nexport function createRefreshAuthRouter(\n options: Omit<RefreshAuthOptions, 'request'> = {},\n): { POST: RefreshAuthRouteHandler } {\n return {\n POST: async (request: Request) =>\n (await refreshAuth({ ...options, request })).response,\n };\n}\n","import { isJwtExpiredOrExpiring } from '../lib/jwt';\nimport type { InsForgeConfig, InsForgeError } from '../types';\nimport {\n clearAuthCookies,\n getAccessTokenCookieName,\n getCookieValue,\n getRefreshTokenCookieName,\n setAuthCookies,\n type AuthCookieSettings,\n type CookieStore,\n} from './cookies';\nimport { refreshAuth } from './refresh';\n\nexport interface UpdateSessionOptions\n extends Omit<\n InsForgeConfig,\n 'accessToken' | 'edgeFunctionToken' | 'isServerMode' | 'auth'\n >,\n AuthCookieSettings {\n requestCookies: CookieStore;\n responseCookies: CookieStore;\n refreshLeewaySeconds?: number;\n}\n\nexport interface UpdateSessionResult {\n refreshed: boolean;\n accessToken: string | null;\n error: InsForgeError | null;\n}\n\nexport async function updateSession(\n options: UpdateSessionOptions,\n): Promise<UpdateSessionResult> {\n const accessCookieName = getAccessTokenCookieName(options.names);\n const refreshCookieName = getRefreshTokenCookieName(options.names);\n const accessToken = getCookieValue(\n options.requestCookies,\n accessCookieName,\n );\n\n if (\n accessToken &&\n !isJwtExpiredOrExpiring(accessToken, options.refreshLeewaySeconds)\n ) {\n return {\n refreshed: false,\n accessToken,\n error: null,\n };\n }\n\n const refreshToken = getCookieValue(\n options.requestCookies,\n refreshCookieName,\n );\n if (!refreshToken) {\n if (accessToken) {\n clearAuthCookies(options.requestCookies, options);\n clearAuthCookies(options.responseCookies, options);\n }\n return {\n refreshed: false,\n accessToken: null,\n error: null,\n };\n }\n\n const result = await refreshAuth({\n ...options,\n refreshToken,\n });\n\n if (result.error || !result.accessToken) {\n clearAuthCookies(options.requestCookies, options);\n clearAuthCookies(options.responseCookies, options);\n return {\n refreshed: false,\n accessToken: null,\n error: result.error,\n };\n }\n\n const tokens = {\n accessToken: result.accessToken,\n refreshToken: result.refreshToken ?? refreshToken,\n };\n setAuthCookies(options.requestCookies, tokens, options);\n setAuthCookies(options.responseCookies, tokens, options);\n\n return {\n refreshed: true,\n accessToken: result.accessToken,\n error: null,\n };\n}\n"],"mappings":"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","names":["error"]}
|
|
1
|
+
{"version":3,"sources":["../../src/ssr/middleware.ts","../../src/lib/jwt.ts","../../src/ssr/cookies.ts","../../src/types.ts","../../src/ssr/refresh.ts","../../src/ssr/update-session.ts"],"sourcesContent":["export {\n updateSession,\n type UpdateSessionOptions,\n type UpdateSessionResult,\n} from './update-session';\nexport {\n DEFAULT_ACCESS_TOKEN_COOKIE,\n DEFAULT_REFRESH_TOKEN_COOKIE,\n clearAuthCookies,\n getAccessTokenCookieName,\n getRefreshTokenCookieName,\n setAuthCookies,\n type AuthCookieNames,\n type AuthCookieOptions,\n type AuthCookieSettings,\n type CookieOptions,\n type CookieReader,\n type CookieStore,\n type CookieWriter,\n} from './cookies';\n","function decodeBase64Url(input: string): string {\n const normalized = input.replace(/-/g, '+').replace(/_/g, '/');\n const padded = normalized.padEnd(\n normalized.length + ((4 - (normalized.length % 4)) % 4),\n '=',\n );\n\n const binary = atob(padded);\n const bytes = Uint8Array.from(binary, (char) => char.charCodeAt(0));\n return new TextDecoder().decode(bytes);\n}\n\nexport function getJwtExpiration(token: string | null | undefined): Date | null {\n if (!token) return null;\n\n const [, payload] = token.split('.');\n if (!payload) return null;\n\n try {\n const parsed = JSON.parse(decodeBase64Url(payload)) as { exp?: unknown };\n if (typeof parsed.exp !== 'number' || !Number.isFinite(parsed.exp)) {\n return null;\n }\n return new Date(parsed.exp * 1000);\n } catch {\n return null;\n }\n}\n\nexport function isJwtExpiredOrExpiring(\n token: string | null | undefined,\n leewaySeconds = 60,\n): boolean {\n if (!token) return false;\n const expires = getJwtExpiration(token);\n if (!expires) return true;\n\n return expires.getTime() <= Date.now() + leewaySeconds * 1000;\n}\n","import { getJwtExpiration } from '../lib/jwt';\n\nexport const DEFAULT_ACCESS_TOKEN_COOKIE = 'insforge_access_token';\nexport const DEFAULT_REFRESH_TOKEN_COOKIE = 'insforge_refresh_token';\n\nexport interface AuthCookieNames {\n accessToken?: string;\n refreshToken?: string;\n}\n\nexport interface CookieOptions {\n domain?: string;\n path?: string;\n expires?: Date;\n maxAge?: number;\n httpOnly?: boolean;\n secure?: boolean;\n sameSite?: 'lax' | 'strict' | 'none';\n}\n\nexport interface AuthCookieOptions {\n accessToken?: CookieOptions;\n refreshToken?: CookieOptions;\n}\n\nexport type CookieStoreValue =\n | string\n | { value?: string | null }\n | undefined\n | null;\n\nexport interface CookieReader {\n get(name: string): CookieStoreValue;\n}\n\nexport interface CookieWriter {\n set?(name: string, value: string, options?: CookieOptions): unknown;\n set?(options: { name: string; value: string } & CookieOptions): unknown;\n delete?(name: string): unknown;\n delete?(options: { name: string } & CookieOptions): unknown;\n}\n\nexport interface CookieStore extends CookieReader, CookieWriter {}\n\nexport interface AuthCookieSettings {\n names?: AuthCookieNames;\n options?: AuthCookieOptions;\n}\n\nconst EXPIRED_DATE = new Date(0);\n\nexport function getAccessTokenCookieName(names?: AuthCookieNames): string {\n return names?.accessToken ?? DEFAULT_ACCESS_TOKEN_COOKIE;\n}\n\nexport function getRefreshTokenCookieName(names?: AuthCookieNames): string {\n return names?.refreshToken ?? DEFAULT_REFRESH_TOKEN_COOKIE;\n}\n\nexport function getCookieValue(\n cookies: CookieReader | undefined,\n name: string,\n): string | null {\n if (!cookies) return null;\n\n const value = cookies.get(name);\n if (typeof value === 'string') return value || null;\n if (value && typeof value.value === 'string') return value.value || null;\n return null;\n}\n\nexport function getCookieValueFromHeader(\n cookieHeader: string | null | undefined,\n name: string,\n): string | null {\n if (!cookieHeader) return null;\n\n const parts = cookieHeader.split(';');\n for (const part of parts) {\n const [rawName, ...rawValue] = part.trim().split('=');\n if (rawName !== name) continue;\n try {\n return decodeURIComponent(rawValue.join('='));\n } catch {\n return rawValue.join('=');\n }\n }\n return null;\n}\n\nexport function getBrowserCookie(name: string): string | null {\n if (typeof document === 'undefined') return null;\n return getCookieValueFromHeader(document.cookie, name);\n}\n\nfunction defaultCookieOptions(): CookieOptions {\n const secure =\n typeof process !== 'undefined'\n ? process.env.NODE_ENV === 'production'\n : typeof location !== 'undefined' && location.protocol === 'https:';\n\n return {\n path: '/',\n sameSite: 'lax',\n secure,\n };\n}\n\nexport function accessTokenCookieOptions(\n token: string,\n overrides?: CookieOptions,\n): CookieOptions {\n return {\n ...defaultCookieOptions(),\n httpOnly: false,\n expires: getJwtExpiration(token) ?? undefined,\n ...overrides,\n };\n}\n\nexport function refreshTokenCookieOptions(\n token: string,\n overrides?: CookieOptions,\n): CookieOptions {\n return {\n ...defaultCookieOptions(),\n httpOnly: true,\n expires: getJwtExpiration(token) ?? undefined,\n ...overrides,\n };\n}\n\nexport function expiredCookieOptions(overrides?: CookieOptions): CookieOptions {\n const { expires: _expires, maxAge: _maxAge, ...safeOverrides } = overrides ?? {};\n return {\n ...defaultCookieOptions(),\n ...safeOverrides,\n expires: EXPIRED_DATE,\n maxAge: 0,\n };\n}\n\nexport function setCookie(\n cookies: CookieWriter | undefined,\n name: string,\n value: string,\n options?: CookieOptions,\n): void {\n if (!cookies?.set) return;\n cookies.set(name, value, options);\n}\n\nexport function deleteCookie(\n cookies: CookieWriter | undefined,\n name: string,\n options?: CookieOptions,\n): void {\n if (!cookies) return;\n if (cookies.set) {\n cookies.set(name, '', expiredCookieOptions(options));\n return;\n }\n cookies.delete?.(name);\n}\n\nexport function serializeCookie(\n name: string,\n value: string,\n options: CookieOptions = {},\n): string {\n const parts = [`${encodeURIComponent(name)}=${encodeURIComponent(value)}`];\n\n if (options.maxAge !== undefined) parts.push(`Max-Age=${options.maxAge}`);\n if (options.domain) parts.push(`Domain=${options.domain}`);\n if (options.path) parts.push(`Path=${options.path}`);\n if (options.expires) parts.push(`Expires=${options.expires.toUTCString()}`);\n if (options.httpOnly) parts.push('HttpOnly');\n if (options.secure) parts.push('Secure');\n if (options.sameSite) {\n const sameSite =\n options.sameSite.charAt(0).toUpperCase() + options.sameSite.slice(1);\n parts.push(`SameSite=${sameSite}`);\n }\n\n return parts.join('; ');\n}\n\nexport function appendSetCookie(\n headers: Headers,\n name: string,\n value: string,\n options?: CookieOptions,\n): void {\n headers.append('Set-Cookie', serializeCookie(name, value, options));\n}\n\nexport function setAuthCookies(\n cookies: CookieWriter | undefined,\n tokens: {\n accessToken: string;\n refreshToken?: string | null;\n },\n settings: AuthCookieSettings = {},\n): void {\n const accessName = getAccessTokenCookieName(settings.names);\n const refreshName = getRefreshTokenCookieName(settings.names);\n const accessOptions = accessTokenCookieOptions(\n tokens.accessToken,\n settings.options?.accessToken,\n );\n\n setCookie(cookies, accessName, tokens.accessToken, accessOptions);\n if (tokens.refreshToken) {\n setCookie(\n cookies,\n refreshName,\n tokens.refreshToken,\n refreshTokenCookieOptions(\n tokens.refreshToken,\n settings.options?.refreshToken,\n ),\n );\n }\n}\n\nexport function clearAuthCookies(\n cookies: CookieWriter | undefined,\n settings: AuthCookieSettings = {},\n): void {\n const accessName = getAccessTokenCookieName(settings.names);\n const refreshName = getRefreshTokenCookieName(settings.names);\n const accessOptions = expiredCookieOptions(settings.options?.accessToken);\n const refreshOptions = expiredCookieOptions(settings.options?.refreshToken);\n\n deleteCookie(cookies, accessName, accessOptions);\n deleteCookie(cookies, refreshName, refreshOptions);\n}\n\nexport function setAuthCookieHeaders(\n headers: Headers,\n tokens: {\n accessToken: string;\n refreshToken?: string | null;\n },\n settings: AuthCookieSettings = {},\n): void {\n const accessName = getAccessTokenCookieName(settings.names);\n const refreshName = getRefreshTokenCookieName(settings.names);\n\n appendSetCookie(\n headers,\n accessName,\n tokens.accessToken,\n accessTokenCookieOptions(tokens.accessToken, settings.options?.accessToken),\n );\n if (tokens.refreshToken) {\n appendSetCookie(\n headers,\n refreshName,\n tokens.refreshToken,\n refreshTokenCookieOptions(\n tokens.refreshToken,\n settings.options?.refreshToken,\n ),\n );\n }\n}\n\nexport function clearAuthCookieHeaders(\n headers: Headers,\n settings: AuthCookieSettings = {},\n): void {\n appendSetCookie(\n headers,\n getAccessTokenCookieName(settings.names),\n '',\n expiredCookieOptions(settings.options?.accessToken),\n );\n appendSetCookie(\n headers,\n getRefreshTokenCookieName(settings.names),\n '',\n expiredCookieOptions(settings.options?.refreshToken),\n );\n}\n","/**\n * InsForge SDK Types - only SDK-specific types here\n * Use @insforge/shared-schemas directly for API types\n */\n\nimport type { ErrorCode, UserSchema } from '@insforge/shared-schemas';\n\nexport type InsForgeErrorCode = ErrorCode | (string & {});\n\nexport interface InsForgeConfig {\n /**\n * The base URL of the InsForge backend API\n * @default \"http://localhost:7130\"\n */\n baseUrl?: string;\n\n /**\n * Anonymous API key (optional)\n * Used for public/unauthenticated requests when no user token is set\n */\n anonKey?: string;\n\n /**\n * Static access token (optional)\n * Seeds the client with a fixed bearer token used for all authenticated\n * requests — e.g. a user JWT inside an edge function, or a server-signed\n * JWT from an external auth provider. Disables automatic token refresh\n * and implies server mode unless `isServerMode` is set explicitly.\n */\n accessToken?: string;\n\n /**\n * @deprecated Use `accessToken` instead. Same behavior; `accessToken`\n * takes precedence when both are provided.\n */\n edgeFunctionToken?: string;\n\n /**\n * Direct URL to Deno Subhosting functions (optional)\n * When provided, SDK will try this URL first for function invocations.\n * Falls back to proxy URL if subhosting returns 404.\n * @example \"https://{appKey}.functions.insforge.app\"\n */\n functionsUrl?: string;\n\n /**\n * Custom fetch implementation (useful for Node.js environments)\n */\n fetch?: typeof fetch;\n\n /**\n * Enable server-side auth mode (SSR/Node runtime)\n * In this mode auth endpoints use `client_type=mobile` and refresh_token body flow.\n *\n * @deprecated Use `createServerClient()`, `createBrowserClient()`, and\n * `updateSession()` from `@insforge/sdk/ssr` for SSR apps.\n * @default false\n */\n isServerMode?: boolean;\n\n /**\n * Advanced auth module options.\n */\n auth?: {\n /**\n * Detect and exchange OAuth callback parameters on browser client\n * initialization. SSR browser clients disable this so auth mutations can\n * stay server-owned.\n * @default true\n */\n detectOAuthCallback?: boolean;\n };\n\n /**\n * Custom headers to include with every request\n */\n headers?: Record<string, string>;\n\n /**\n * Enable debug logging for HTTP requests and responses.\n * When true, request/response details are logged to the console.\n * Can also be a custom log function for advanced use cases.\n * @default false\n */\n debug?: boolean | ((message: string, ...args: any[]) => void);\n\n /**\n * Request timeout in milliseconds.\n * Requests that exceed this duration will be aborted.\n * Set to 0 to disable timeout.\n * @default 30000\n */\n timeout?: number;\n\n /**\n * Maximum number of retry attempts for failed requests.\n * Retries are triggered on network errors and server errors (5xx).\n * Client errors (4xx) are never retried.\n * Set to 0 to disable retries.\n * @default 3\n */\n retryCount?: number;\n\n /**\n * Initial delay in milliseconds before the first retry.\n * The delay doubles with each subsequent attempt (exponential backoff)\n * with ±15% jitter to prevent thundering herd.\n * @default 500\n */\n retryDelay?: number;\n}\n\nexport type InsForgeAdminConfig = Omit<\n InsForgeConfig,\n 'anonKey' | 'accessToken' | 'edgeFunctionToken' | 'isServerMode'\n> & {\n /**\n * Project admin API key. Keep this server-side only.\n */\n apiKey: string;\n};\n\nexport interface AuthSession {\n user: UserSchema;\n accessToken: string;\n expiresAt?: Date;\n}\n\nexport interface AuthRefreshResponse {\n user: UserSchema;\n accessToken: string;\n csrfToken?: string;\n refreshToken?: string;\n}\n\nexport interface ApiError {\n error: InsForgeErrorCode;\n message: string;\n statusCode: number;\n nextActions?: string;\n}\n\nexport class InsForgeError extends Error {\n public statusCode: number;\n public error: InsForgeErrorCode;\n public nextActions?: string;\n\n constructor(\n message: string,\n statusCode: number,\n error: InsForgeErrorCode,\n nextActions?: string,\n ) {\n super(message);\n this.name = 'InsForgeError';\n this.statusCode = statusCode;\n this.error = error;\n this.nextActions = nextActions;\n }\n\n static fromApiError(apiError: ApiError): InsForgeError {\n return new InsForgeError(\n apiError.message,\n apiError.statusCode,\n apiError.error,\n apiError.nextActions,\n );\n }\n}\n","import {\n InsForgeError,\n type AuthRefreshResponse,\n type InsForgeConfig,\n} from '../types';\nimport { ERROR_CODES } from '@insforge/shared-schemas';\nimport {\n clearAuthCookieHeaders,\n getCookieValue,\n getCookieValueFromHeader,\n getRefreshTokenCookieName,\n setAuthCookieHeaders,\n type AuthCookieSettings,\n type CookieStore,\n} from './cookies';\n\nexport interface RefreshAuthOptions\n extends Omit<\n InsForgeConfig,\n 'accessToken' | 'edgeFunctionToken' | 'isServerMode' | 'auth'\n >,\n AuthCookieSettings {\n request?: Request;\n cookies?: Pick<CookieStore, 'get'>;\n refreshToken?: string;\n}\n\nexport interface RefreshAuthResult {\n response: Response;\n data: AuthRefreshResponse | null;\n accessToken: string | null;\n refreshToken: string | null;\n error: InsForgeError | null;\n}\n\nexport type RefreshAuthRouteHandler = (request: Request) => Promise<Response>;\n\nfunction jsonResponse(\n body: unknown,\n init: ResponseInit = {},\n headers = new Headers(init.headers),\n): Response {\n headers.set('Content-Type', 'application/json');\n return new Response(JSON.stringify(body), {\n ...init,\n headers,\n });\n}\n\nfunction normalizeError(error: unknown): InsForgeError {\n if (error instanceof InsForgeError) return error;\n\n if (error && typeof error === 'object') {\n const body = error as {\n error?: unknown;\n message?: unknown;\n statusCode?: unknown;\n };\n return new InsForgeError(\n typeof body.message === 'string'\n ? body.message\n : 'Failed to refresh auth session',\n typeof body.statusCode === 'number' ? body.statusCode : 500,\n typeof body.error === 'string'\n ? body.error\n : ERROR_CODES.UNKNOWN_ERROR,\n );\n }\n\n return new InsForgeError(\n error instanceof Error ? error.message : 'Failed to refresh auth session',\n 500,\n ERROR_CODES.UNKNOWN_ERROR,\n );\n}\n\nasync function readJson(response: Response): Promise<unknown> {\n const contentType = response.headers.get('content-type');\n if (!contentType?.includes('json')) return null;\n return response.json();\n}\n\nfunction readRefreshToken(options: RefreshAuthOptions): string | null {\n if (options.refreshToken) return options.refreshToken;\n\n const refreshCookieName = getRefreshTokenCookieName(options.names);\n const cookieValue = getCookieValue(options.cookies, refreshCookieName);\n if (cookieValue) return cookieValue;\n\n return getCookieValueFromHeader(\n options.request?.headers.get('cookie'),\n refreshCookieName,\n );\n}\n\nexport async function refreshAuth(\n options: RefreshAuthOptions = {},\n): Promise<RefreshAuthResult> {\n const headers = new Headers();\n const refreshToken = readRefreshToken(options);\n\n if (!refreshToken) {\n clearAuthCookieHeaders(headers, options);\n const error = new InsForgeError(\n 'Refresh token cookie is missing',\n 401,\n ERROR_CODES.AUTH_UNAUTHORIZED,\n );\n return {\n response: jsonResponse(\n {\n error: error.error,\n message: error.message,\n statusCode: error.statusCode,\n },\n { status: error.statusCode },\n headers,\n ),\n data: null,\n accessToken: null,\n refreshToken: null,\n error,\n };\n }\n\n let { baseUrl, anonKey } = options;\n try {\n baseUrl ||= process.env.NEXT_PUBLIC_INSFORGE_URL;\n anonKey ||= process.env.NEXT_PUBLIC_INSFORGE_ANON_KEY;\n } catch {\n // process may be unavailable outside Next.js/browser-bundled envs.\n }\n if (!baseUrl || !anonKey) {\n throw new Error(\n 'Missing InsForge baseUrl or anonKey. Pass baseUrl and anonKey to refreshAuth() or set NEXT_PUBLIC_INSFORGE_URL and NEXT_PUBLIC_INSFORGE_ANON_KEY.',\n );\n }\n\n const fetchImpl =\n options.fetch ??\n (globalThis.fetch\n ? globalThis.fetch.bind(globalThis)\n : (undefined as typeof fetch | undefined));\n if (!fetchImpl) {\n throw new Error(\n 'Fetch is not available. Please provide a fetch implementation.',\n );\n }\n\n const requestHeaders = new Headers(options.headers);\n requestHeaders.set('Authorization', `Bearer ${anonKey}`);\n requestHeaders.set('Content-Type', 'application/json');\n requestHeaders.set('Accept', 'application/json');\n\n let data: AuthRefreshResponse | null = null;\n let error: InsForgeError | null = null;\n\n try {\n const response = await fetchImpl(\n new URL('/api/auth/refresh?client_type=mobile', baseUrl).toString(),\n {\n method: 'POST',\n headers: requestHeaders,\n body: JSON.stringify({ refresh_token: refreshToken }),\n },\n );\n const body = await readJson(response);\n if (!response.ok) {\n error = normalizeError(\n body ?? {\n message: 'Failed to refresh auth session',\n statusCode: response.status,\n error: ERROR_CODES.UNKNOWN_ERROR,\n },\n );\n } else {\n data = body as AuthRefreshResponse;\n }\n } catch (caught) {\n error = normalizeError(caught);\n }\n\n if (error || !data?.accessToken) {\n clearAuthCookieHeaders(headers, options);\n const normalized = normalizeError(error);\n return {\n response: jsonResponse(\n {\n error: normalized.error,\n message: normalized.message,\n statusCode: normalized.statusCode,\n },\n { status: normalized.statusCode || 500 },\n headers,\n ),\n data: null,\n accessToken: null,\n refreshToken: null,\n error: normalized,\n };\n }\n\n const nextRefreshToken = data.refreshToken ?? refreshToken;\n setAuthCookieHeaders(\n headers,\n {\n accessToken: data.accessToken,\n refreshToken: nextRefreshToken,\n },\n options,\n );\n\n const responseBody: AuthRefreshResponse = {\n accessToken: data.accessToken,\n user: data.user,\n csrfToken: data.csrfToken,\n };\n\n return {\n response: jsonResponse(responseBody, { status: 200 }, headers),\n data: responseBody,\n accessToken: data.accessToken,\n refreshToken: nextRefreshToken,\n error: null,\n };\n}\n\nexport function createRefreshAuthRouter(\n options: Omit<RefreshAuthOptions, 'request'> = {},\n): { POST: RefreshAuthRouteHandler } {\n return {\n POST: async (request: Request) =>\n (await refreshAuth({ ...options, request })).response,\n };\n}\n","import { isJwtExpiredOrExpiring } from '../lib/jwt';\nimport type { InsForgeConfig, InsForgeError } from '../types';\nimport {\n clearAuthCookies,\n getAccessTokenCookieName,\n getCookieValue,\n getRefreshTokenCookieName,\n setAuthCookies,\n type AuthCookieSettings,\n type CookieStore,\n} from './cookies';\nimport { refreshAuth } from './refresh';\n\nexport interface UpdateSessionOptions\n extends Omit<\n InsForgeConfig,\n 'accessToken' | 'edgeFunctionToken' | 'isServerMode' | 'auth'\n >,\n AuthCookieSettings {\n requestCookies: CookieStore;\n responseCookies: CookieStore;\n refreshLeewaySeconds?: number;\n}\n\nexport interface UpdateSessionResult {\n refreshed: boolean;\n accessToken: string | null;\n error: InsForgeError | null;\n}\n\nexport async function updateSession(\n options: UpdateSessionOptions,\n): Promise<UpdateSessionResult> {\n const accessCookieName = getAccessTokenCookieName(options.names);\n const refreshCookieName = getRefreshTokenCookieName(options.names);\n const accessToken = getCookieValue(\n options.requestCookies,\n accessCookieName,\n );\n\n if (\n accessToken &&\n !isJwtExpiredOrExpiring(accessToken, options.refreshLeewaySeconds)\n ) {\n return {\n refreshed: false,\n accessToken,\n error: null,\n };\n }\n\n const refreshToken = getCookieValue(\n options.requestCookies,\n refreshCookieName,\n );\n if (!refreshToken) {\n if (accessToken) {\n clearAuthCookies(options.requestCookies, options);\n clearAuthCookies(options.responseCookies, options);\n }\n return {\n refreshed: false,\n accessToken: null,\n error: null,\n };\n }\n\n const result = await refreshAuth({\n ...options,\n refreshToken,\n });\n\n if (result.error || !result.accessToken) {\n clearAuthCookies(options.requestCookies, options);\n clearAuthCookies(options.responseCookies, options);\n return {\n refreshed: false,\n accessToken: null,\n error: result.error,\n };\n }\n\n const tokens = {\n accessToken: result.accessToken,\n refreshToken: result.refreshToken ?? refreshToken,\n };\n setAuthCookies(options.requestCookies, tokens, options);\n setAuthCookies(options.responseCookies, tokens, options);\n\n return {\n refreshed: true,\n accessToken: result.accessToken,\n error: null,\n };\n}\n"],"mappings":"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","names":["error"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/lib/jwt.ts","../../src/ssr/cookies.ts","../../src/types.ts","../../src/ssr/refresh.ts","../../src/ssr/update-session.ts"],"sourcesContent":["function decodeBase64Url(input: string): string {\n const normalized = input.replace(/-/g, '+').replace(/_/g, '/');\n const padded = normalized.padEnd(\n normalized.length + ((4 - (normalized.length % 4)) % 4),\n '=',\n );\n\n const binary = atob(padded);\n const bytes = Uint8Array.from(binary, (char) => char.charCodeAt(0));\n return new TextDecoder().decode(bytes);\n}\n\nexport function getJwtExpiration(token: string | null | undefined): Date | null {\n if (!token) return null;\n\n const [, payload] = token.split('.');\n if (!payload) return null;\n\n try {\n const parsed = JSON.parse(decodeBase64Url(payload)) as { exp?: unknown };\n if (typeof parsed.exp !== 'number' || !Number.isFinite(parsed.exp)) {\n return null;\n }\n return new Date(parsed.exp * 1000);\n } catch {\n return null;\n }\n}\n\nexport function isJwtExpiredOrExpiring(\n token: string | null | undefined,\n leewaySeconds = 60,\n): boolean {\n if (!token) return false;\n const expires = getJwtExpiration(token);\n if (!expires) return true;\n\n return expires.getTime() <= Date.now() + leewaySeconds * 1000;\n}\n","import { getJwtExpiration } from '../lib/jwt';\n\nexport const DEFAULT_ACCESS_TOKEN_COOKIE = 'insforge_access_token';\nexport const DEFAULT_REFRESH_TOKEN_COOKIE = 'insforge_refresh_token';\n\nexport interface AuthCookieNames {\n accessToken?: string;\n refreshToken?: string;\n}\n\nexport interface CookieOptions {\n domain?: string;\n path?: string;\n expires?: Date;\n maxAge?: number;\n httpOnly?: boolean;\n secure?: boolean;\n sameSite?: 'lax' | 'strict' | 'none';\n}\n\nexport interface AuthCookieOptions {\n accessToken?: CookieOptions;\n refreshToken?: CookieOptions;\n}\n\nexport type CookieStoreValue =\n | string\n | { value?: string | null }\n | undefined\n | null;\n\nexport interface CookieReader {\n get(name: string): CookieStoreValue;\n}\n\nexport interface CookieWriter {\n set?(name: string, value: string, options?: CookieOptions): unknown;\n set?(options: { name: string; value: string } & CookieOptions): unknown;\n delete?(name: string): unknown;\n delete?(options: { name: string } & CookieOptions): unknown;\n}\n\nexport interface CookieStore extends CookieReader, CookieWriter {}\n\nexport interface AuthCookieSettings {\n names?: AuthCookieNames;\n options?: AuthCookieOptions;\n}\n\nconst EXPIRED_DATE = new Date(0);\n\nexport function getAccessTokenCookieName(names?: AuthCookieNames): string {\n return names?.accessToken ?? DEFAULT_ACCESS_TOKEN_COOKIE;\n}\n\nexport function getRefreshTokenCookieName(names?: AuthCookieNames): string {\n return names?.refreshToken ?? DEFAULT_REFRESH_TOKEN_COOKIE;\n}\n\nexport function getCookieValue(\n cookies: CookieReader | undefined,\n name: string,\n): string | null {\n if (!cookies) return null;\n\n const value = cookies.get(name);\n if (typeof value === 'string') return value || null;\n if (value && typeof value.value === 'string') return value.value || null;\n return null;\n}\n\nexport function getCookieValueFromHeader(\n cookieHeader: string | null | undefined,\n name: string,\n): string | null {\n if (!cookieHeader) return null;\n\n const parts = cookieHeader.split(';');\n for (const part of parts) {\n const [rawName, ...rawValue] = part.trim().split('=');\n if (rawName !== name) continue;\n try {\n return decodeURIComponent(rawValue.join('='));\n } catch {\n return rawValue.join('=');\n }\n }\n return null;\n}\n\nexport function getBrowserCookie(name: string): string | null {\n if (typeof document === 'undefined') return null;\n return getCookieValueFromHeader(document.cookie, name);\n}\n\nfunction defaultCookieOptions(): CookieOptions {\n const secure =\n typeof process !== 'undefined'\n ? process.env.NODE_ENV === 'production'\n : typeof location !== 'undefined' && location.protocol === 'https:';\n\n return {\n path: '/',\n sameSite: 'lax',\n secure,\n };\n}\n\nexport function accessTokenCookieOptions(\n token: string,\n overrides?: CookieOptions,\n): CookieOptions {\n return {\n ...defaultCookieOptions(),\n httpOnly: false,\n expires: getJwtExpiration(token) ?? undefined,\n ...overrides,\n };\n}\n\nexport function refreshTokenCookieOptions(\n token: string,\n overrides?: CookieOptions,\n): CookieOptions {\n return {\n ...defaultCookieOptions(),\n httpOnly: true,\n expires: getJwtExpiration(token) ?? undefined,\n ...overrides,\n };\n}\n\nexport function expiredCookieOptions(overrides?: CookieOptions): CookieOptions {\n const { expires: _expires, maxAge: _maxAge, ...safeOverrides } = overrides ?? {};\n return {\n ...defaultCookieOptions(),\n ...safeOverrides,\n expires: EXPIRED_DATE,\n maxAge: 0,\n };\n}\n\nexport function setCookie(\n cookies: CookieWriter | undefined,\n name: string,\n value: string,\n options?: CookieOptions,\n): void {\n if (!cookies?.set) return;\n cookies.set(name, value, options);\n}\n\nexport function deleteCookie(\n cookies: CookieWriter | undefined,\n name: string,\n options?: CookieOptions,\n): void {\n if (!cookies) return;\n if (cookies.set) {\n cookies.set(name, '', expiredCookieOptions(options));\n return;\n }\n cookies.delete?.(name);\n}\n\nexport function serializeCookie(\n name: string,\n value: string,\n options: CookieOptions = {},\n): string {\n const parts = [`${encodeURIComponent(name)}=${encodeURIComponent(value)}`];\n\n if (options.maxAge !== undefined) parts.push(`Max-Age=${options.maxAge}`);\n if (options.domain) parts.push(`Domain=${options.domain}`);\n if (options.path) parts.push(`Path=${options.path}`);\n if (options.expires) parts.push(`Expires=${options.expires.toUTCString()}`);\n if (options.httpOnly) parts.push('HttpOnly');\n if (options.secure) parts.push('Secure');\n if (options.sameSite) {\n const sameSite =\n options.sameSite.charAt(0).toUpperCase() + options.sameSite.slice(1);\n parts.push(`SameSite=${sameSite}`);\n }\n\n return parts.join('; ');\n}\n\nexport function appendSetCookie(\n headers: Headers,\n name: string,\n value: string,\n options?: CookieOptions,\n): void {\n headers.append('Set-Cookie', serializeCookie(name, value, options));\n}\n\nexport function setAuthCookies(\n cookies: CookieWriter | undefined,\n tokens: {\n accessToken: string;\n refreshToken?: string | null;\n },\n settings: AuthCookieSettings = {},\n): void {\n const accessName = getAccessTokenCookieName(settings.names);\n const refreshName = getRefreshTokenCookieName(settings.names);\n const accessOptions = accessTokenCookieOptions(\n tokens.accessToken,\n settings.options?.accessToken,\n );\n\n setCookie(cookies, accessName, tokens.accessToken, accessOptions);\n if (tokens.refreshToken) {\n setCookie(\n cookies,\n refreshName,\n tokens.refreshToken,\n refreshTokenCookieOptions(\n tokens.refreshToken,\n settings.options?.refreshToken,\n ),\n );\n }\n}\n\nexport function clearAuthCookies(\n cookies: CookieWriter | undefined,\n settings: AuthCookieSettings = {},\n): void {\n const accessName = getAccessTokenCookieName(settings.names);\n const refreshName = getRefreshTokenCookieName(settings.names);\n const accessOptions = expiredCookieOptions(settings.options?.accessToken);\n const refreshOptions = expiredCookieOptions(settings.options?.refreshToken);\n\n deleteCookie(cookies, accessName, accessOptions);\n deleteCookie(cookies, refreshName, refreshOptions);\n}\n\nexport function setAuthCookieHeaders(\n headers: Headers,\n tokens: {\n accessToken: string;\n refreshToken?: string | null;\n },\n settings: AuthCookieSettings = {},\n): void {\n const accessName = getAccessTokenCookieName(settings.names);\n const refreshName = getRefreshTokenCookieName(settings.names);\n\n appendSetCookie(\n headers,\n accessName,\n tokens.accessToken,\n accessTokenCookieOptions(tokens.accessToken, settings.options?.accessToken),\n );\n if (tokens.refreshToken) {\n appendSetCookie(\n headers,\n refreshName,\n tokens.refreshToken,\n refreshTokenCookieOptions(\n tokens.refreshToken,\n settings.options?.refreshToken,\n ),\n );\n }\n}\n\nexport function clearAuthCookieHeaders(\n headers: Headers,\n settings: AuthCookieSettings = {},\n): void {\n appendSetCookie(\n headers,\n getAccessTokenCookieName(settings.names),\n '',\n expiredCookieOptions(settings.options?.accessToken),\n );\n appendSetCookie(\n headers,\n getRefreshTokenCookieName(settings.names),\n '',\n expiredCookieOptions(settings.options?.refreshToken),\n );\n}\n","/**\n * InsForge SDK Types - only SDK-specific types here\n * Use @insforge/shared-schemas directly for API types\n */\n\nimport type { ErrorCode, UserSchema } from '@insforge/shared-schemas';\n\nexport type InsForgeErrorCode = ErrorCode | (string & {});\n\nexport interface InsForgeConfig {\n /**\n * The base URL of the InsForge backend API\n * @default \"http://localhost:7130\"\n */\n baseUrl?: string;\n\n /**\n * Anonymous API key (optional)\n * Used for public/unauthenticated requests when no user token is set\n */\n anonKey?: string;\n\n /**\n * Static access token (optional)\n * Seeds the client with a fixed bearer token used for all authenticated\n * requests — e.g. a user JWT inside an edge function, or a server-signed\n * JWT from an external auth provider. Disables automatic token refresh\n * and implies server mode unless `isServerMode` is set explicitly.\n */\n accessToken?: string;\n\n /**\n * @deprecated Use `accessToken` instead. Same behavior; `accessToken`\n * takes precedence when both are provided.\n */\n edgeFunctionToken?: string;\n\n /**\n * Direct URL to Deno Subhosting functions (optional)\n * When provided, SDK will try this URL first for function invocations.\n * Falls back to proxy URL if subhosting returns 404.\n * @example \"https://{appKey}.functions.insforge.app\"\n */\n functionsUrl?: string;\n\n /**\n * Custom fetch implementation (useful for Node.js environments)\n */\n fetch?: typeof fetch;\n\n /**\n * Enable server-side auth mode (SSR/Node runtime)\n * In this mode auth endpoints use `client_type=mobile` and refresh_token body flow.\n *\n * @deprecated Use `createServerClient()`, `createBrowserClient()`, and\n * `updateSession()` from `@insforge/sdk/ssr` for SSR apps.\n * @default false\n */\n isServerMode?: boolean;\n\n /**\n * Custom headers to include with every request\n */\n headers?: Record<string, string>;\n\n /**\n * Enable debug logging for HTTP requests and responses.\n * When true, request/response details are logged to the console.\n * Can also be a custom log function for advanced use cases.\n * @default false\n */\n debug?: boolean | ((message: string, ...args: any[]) => void);\n\n /**\n * Request timeout in milliseconds.\n * Requests that exceed this duration will be aborted.\n * Set to 0 to disable timeout.\n * @default 30000\n */\n timeout?: number;\n\n /**\n * Maximum number of retry attempts for failed requests.\n * Retries are triggered on network errors and server errors (5xx).\n * Client errors (4xx) are never retried.\n * Set to 0 to disable retries.\n * @default 3\n */\n retryCount?: number;\n\n /**\n * Initial delay in milliseconds before the first retry.\n * The delay doubles with each subsequent attempt (exponential backoff)\n * with ±15% jitter to prevent thundering herd.\n * @default 500\n */\n retryDelay?: number;\n}\n\nexport type InsForgeAdminConfig = Omit<\n InsForgeConfig,\n 'anonKey' | 'accessToken' | 'edgeFunctionToken' | 'isServerMode'\n> & {\n /**\n * Project admin API key. Keep this server-side only.\n */\n apiKey: string;\n};\n\nexport interface AuthSession {\n user: UserSchema;\n accessToken: string;\n expiresAt?: Date;\n}\n\nexport interface AuthRefreshResponse {\n user: UserSchema;\n accessToken: string;\n csrfToken?: string;\n refreshToken?: string;\n}\n\nexport interface ApiError {\n error: InsForgeErrorCode;\n message: string;\n statusCode: number;\n nextActions?: string;\n}\n\nexport class InsForgeError extends Error {\n public statusCode: number;\n public error: InsForgeErrorCode;\n public nextActions?: string;\n\n constructor(\n message: string,\n statusCode: number,\n error: InsForgeErrorCode,\n nextActions?: string,\n ) {\n super(message);\n this.name = 'InsForgeError';\n this.statusCode = statusCode;\n this.error = error;\n this.nextActions = nextActions;\n }\n\n static fromApiError(apiError: ApiError): InsForgeError {\n return new InsForgeError(\n apiError.message,\n apiError.statusCode,\n apiError.error,\n apiError.nextActions,\n );\n }\n}\n","import {\n InsForgeError,\n type AuthRefreshResponse,\n type InsForgeConfig,\n} from '../types';\nimport { ERROR_CODES } from '@insforge/shared-schemas';\nimport {\n clearAuthCookieHeaders,\n getCookieValue,\n getCookieValueFromHeader,\n getRefreshTokenCookieName,\n setAuthCookieHeaders,\n type AuthCookieSettings,\n type CookieStore,\n} from './cookies';\n\nexport interface RefreshAuthOptions\n extends Omit<\n InsForgeConfig,\n 'accessToken' | 'edgeFunctionToken' | 'isServerMode' | 'auth'\n >,\n AuthCookieSettings {\n request?: Request;\n cookies?: Pick<CookieStore, 'get'>;\n refreshToken?: string;\n}\n\nexport interface RefreshAuthResult {\n response: Response;\n data: AuthRefreshResponse | null;\n accessToken: string | null;\n refreshToken: string | null;\n error: InsForgeError | null;\n}\n\nexport type RefreshAuthRouteHandler = (request: Request) => Promise<Response>;\n\nfunction jsonResponse(\n body: unknown,\n init: ResponseInit = {},\n headers = new Headers(init.headers),\n): Response {\n headers.set('Content-Type', 'application/json');\n return new Response(JSON.stringify(body), {\n ...init,\n headers,\n });\n}\n\nfunction normalizeError(error: unknown): InsForgeError {\n if (error instanceof InsForgeError) return error;\n\n if (error && typeof error === 'object') {\n const body = error as {\n error?: unknown;\n message?: unknown;\n statusCode?: unknown;\n };\n return new InsForgeError(\n typeof body.message === 'string'\n ? body.message\n : 'Failed to refresh auth session',\n typeof body.statusCode === 'number' ? body.statusCode : 500,\n typeof body.error === 'string'\n ? body.error\n : ERROR_CODES.UNKNOWN_ERROR,\n );\n }\n\n return new InsForgeError(\n error instanceof Error ? error.message : 'Failed to refresh auth session',\n 500,\n ERROR_CODES.UNKNOWN_ERROR,\n );\n}\n\nasync function readJson(response: Response): Promise<unknown> {\n const contentType = response.headers.get('content-type');\n if (!contentType?.includes('json')) return null;\n return response.json();\n}\n\nfunction readRefreshToken(options: RefreshAuthOptions): string | null {\n if (options.refreshToken) return options.refreshToken;\n\n const refreshCookieName = getRefreshTokenCookieName(options.names);\n const cookieValue = getCookieValue(options.cookies, refreshCookieName);\n if (cookieValue) return cookieValue;\n\n return getCookieValueFromHeader(\n options.request?.headers.get('cookie'),\n refreshCookieName,\n );\n}\n\nexport async function refreshAuth(\n options: RefreshAuthOptions = {},\n): Promise<RefreshAuthResult> {\n const headers = new Headers();\n const refreshToken = readRefreshToken(options);\n\n if (!refreshToken) {\n clearAuthCookieHeaders(headers, options);\n const error = new InsForgeError(\n 'Refresh token cookie is missing',\n 401,\n ERROR_CODES.AUTH_UNAUTHORIZED,\n );\n return {\n response: jsonResponse(\n {\n error: error.error,\n message: error.message,\n statusCode: error.statusCode,\n },\n { status: error.statusCode },\n headers,\n ),\n data: null,\n accessToken: null,\n refreshToken: null,\n error,\n };\n }\n\n let { baseUrl, anonKey } = options;\n try {\n baseUrl ||= process.env.NEXT_PUBLIC_INSFORGE_URL;\n anonKey ||= process.env.NEXT_PUBLIC_INSFORGE_ANON_KEY;\n } catch {\n // process may be unavailable outside Next.js/browser-bundled envs.\n }\n if (!baseUrl || !anonKey) {\n throw new Error(\n 'Missing InsForge baseUrl or anonKey. Pass baseUrl and anonKey to refreshAuth() or set NEXT_PUBLIC_INSFORGE_URL and NEXT_PUBLIC_INSFORGE_ANON_KEY.',\n );\n }\n\n const fetchImpl =\n options.fetch ??\n (globalThis.fetch\n ? globalThis.fetch.bind(globalThis)\n : (undefined as typeof fetch | undefined));\n if (!fetchImpl) {\n throw new Error(\n 'Fetch is not available. Please provide a fetch implementation.',\n );\n }\n\n const requestHeaders = new Headers(options.headers);\n requestHeaders.set('Authorization', `Bearer ${anonKey}`);\n requestHeaders.set('Content-Type', 'application/json');\n requestHeaders.set('Accept', 'application/json');\n\n let data: AuthRefreshResponse | null = null;\n let error: InsForgeError | null = null;\n\n try {\n const response = await fetchImpl(\n new URL('/api/auth/refresh?client_type=mobile', baseUrl).toString(),\n {\n method: 'POST',\n headers: requestHeaders,\n body: JSON.stringify({ refresh_token: refreshToken }),\n },\n );\n const body = await readJson(response);\n if (!response.ok) {\n error = normalizeError(\n body ?? {\n message: 'Failed to refresh auth session',\n statusCode: response.status,\n error: ERROR_CODES.UNKNOWN_ERROR,\n },\n );\n } else {\n data = body as AuthRefreshResponse;\n }\n } catch (caught) {\n error = normalizeError(caught);\n }\n\n if (error || !data?.accessToken) {\n clearAuthCookieHeaders(headers, options);\n const normalized = normalizeError(error);\n return {\n response: jsonResponse(\n {\n error: normalized.error,\n message: normalized.message,\n statusCode: normalized.statusCode,\n },\n { status: normalized.statusCode || 500 },\n headers,\n ),\n data: null,\n accessToken: null,\n refreshToken: null,\n error: normalized,\n };\n }\n\n const nextRefreshToken = data.refreshToken ?? refreshToken;\n setAuthCookieHeaders(\n headers,\n {\n accessToken: data.accessToken,\n refreshToken: nextRefreshToken,\n },\n options,\n );\n\n const responseBody: AuthRefreshResponse = {\n accessToken: data.accessToken,\n user: data.user,\n csrfToken: data.csrfToken,\n };\n\n return {\n response: jsonResponse(responseBody, { status: 200 }, headers),\n data: responseBody,\n accessToken: data.accessToken,\n refreshToken: nextRefreshToken,\n error: null,\n };\n}\n\nexport function createRefreshAuthRouter(\n options: Omit<RefreshAuthOptions, 'request'> = {},\n): { POST: RefreshAuthRouteHandler } {\n return {\n POST: async (request: Request) =>\n (await refreshAuth({ ...options, request })).response,\n };\n}\n","import { isJwtExpiredOrExpiring } from '../lib/jwt';\nimport type { InsForgeConfig, InsForgeError } from '../types';\nimport {\n clearAuthCookies,\n getAccessTokenCookieName,\n getCookieValue,\n getRefreshTokenCookieName,\n setAuthCookies,\n type AuthCookieSettings,\n type CookieStore,\n} from './cookies';\nimport { refreshAuth } from './refresh';\n\nexport interface UpdateSessionOptions\n extends Omit<\n InsForgeConfig,\n 'accessToken' | 'edgeFunctionToken' | 'isServerMode' | 'auth'\n >,\n AuthCookieSettings {\n requestCookies: CookieStore;\n responseCookies: CookieStore;\n refreshLeewaySeconds?: number;\n}\n\nexport interface UpdateSessionResult {\n refreshed: boolean;\n accessToken: string | null;\n error: InsForgeError | null;\n}\n\nexport async function updateSession(\n options: UpdateSessionOptions,\n): Promise<UpdateSessionResult> {\n const accessCookieName = getAccessTokenCookieName(options.names);\n const refreshCookieName = getRefreshTokenCookieName(options.names);\n const accessToken = getCookieValue(\n options.requestCookies,\n accessCookieName,\n );\n\n if (\n accessToken &&\n !isJwtExpiredOrExpiring(accessToken, options.refreshLeewaySeconds)\n ) {\n return {\n refreshed: false,\n accessToken,\n error: null,\n };\n }\n\n const refreshToken = getCookieValue(\n options.requestCookies,\n refreshCookieName,\n );\n if (!refreshToken) {\n if (accessToken) {\n clearAuthCookies(options.requestCookies, options);\n clearAuthCookies(options.responseCookies, options);\n }\n return {\n refreshed: false,\n accessToken: null,\n error: null,\n };\n }\n\n const result = await refreshAuth({\n ...options,\n refreshToken,\n });\n\n if (result.error || !result.accessToken) {\n clearAuthCookies(options.requestCookies, options);\n clearAuthCookies(options.responseCookies, options);\n return {\n refreshed: false,\n accessToken: null,\n error: result.error,\n };\n }\n\n const tokens = {\n accessToken: result.accessToken,\n refreshToken: result.refreshToken ?? refreshToken,\n };\n setAuthCookies(options.requestCookies, tokens, options);\n setAuthCookies(options.responseCookies, tokens, options);\n\n return {\n refreshed: true,\n accessToken: result.accessToken,\n error: null,\n };\n}\n"],"mappings":"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","names":["error"]}
|
|
1
|
+
{"version":3,"sources":["../../src/lib/jwt.ts","../../src/ssr/cookies.ts","../../src/types.ts","../../src/ssr/refresh.ts","../../src/ssr/update-session.ts"],"sourcesContent":["function decodeBase64Url(input: string): string {\n const normalized = input.replace(/-/g, '+').replace(/_/g, '/');\n const padded = normalized.padEnd(\n normalized.length + ((4 - (normalized.length % 4)) % 4),\n '=',\n );\n\n const binary = atob(padded);\n const bytes = Uint8Array.from(binary, (char) => char.charCodeAt(0));\n return new TextDecoder().decode(bytes);\n}\n\nexport function getJwtExpiration(token: string | null | undefined): Date | null {\n if (!token) return null;\n\n const [, payload] = token.split('.');\n if (!payload) return null;\n\n try {\n const parsed = JSON.parse(decodeBase64Url(payload)) as { exp?: unknown };\n if (typeof parsed.exp !== 'number' || !Number.isFinite(parsed.exp)) {\n return null;\n }\n return new Date(parsed.exp * 1000);\n } catch {\n return null;\n }\n}\n\nexport function isJwtExpiredOrExpiring(\n token: string | null | undefined,\n leewaySeconds = 60,\n): boolean {\n if (!token) return false;\n const expires = getJwtExpiration(token);\n if (!expires) return true;\n\n return expires.getTime() <= Date.now() + leewaySeconds * 1000;\n}\n","import { getJwtExpiration } from '../lib/jwt';\n\nexport const DEFAULT_ACCESS_TOKEN_COOKIE = 'insforge_access_token';\nexport const DEFAULT_REFRESH_TOKEN_COOKIE = 'insforge_refresh_token';\n\nexport interface AuthCookieNames {\n accessToken?: string;\n refreshToken?: string;\n}\n\nexport interface CookieOptions {\n domain?: string;\n path?: string;\n expires?: Date;\n maxAge?: number;\n httpOnly?: boolean;\n secure?: boolean;\n sameSite?: 'lax' | 'strict' | 'none';\n}\n\nexport interface AuthCookieOptions {\n accessToken?: CookieOptions;\n refreshToken?: CookieOptions;\n}\n\nexport type CookieStoreValue =\n | string\n | { value?: string | null }\n | undefined\n | null;\n\nexport interface CookieReader {\n get(name: string): CookieStoreValue;\n}\n\nexport interface CookieWriter {\n set?(name: string, value: string, options?: CookieOptions): unknown;\n set?(options: { name: string; value: string } & CookieOptions): unknown;\n delete?(name: string): unknown;\n delete?(options: { name: string } & CookieOptions): unknown;\n}\n\nexport interface CookieStore extends CookieReader, CookieWriter {}\n\nexport interface AuthCookieSettings {\n names?: AuthCookieNames;\n options?: AuthCookieOptions;\n}\n\nconst EXPIRED_DATE = new Date(0);\n\nexport function getAccessTokenCookieName(names?: AuthCookieNames): string {\n return names?.accessToken ?? DEFAULT_ACCESS_TOKEN_COOKIE;\n}\n\nexport function getRefreshTokenCookieName(names?: AuthCookieNames): string {\n return names?.refreshToken ?? DEFAULT_REFRESH_TOKEN_COOKIE;\n}\n\nexport function getCookieValue(\n cookies: CookieReader | undefined,\n name: string,\n): string | null {\n if (!cookies) return null;\n\n const value = cookies.get(name);\n if (typeof value === 'string') return value || null;\n if (value && typeof value.value === 'string') return value.value || null;\n return null;\n}\n\nexport function getCookieValueFromHeader(\n cookieHeader: string | null | undefined,\n name: string,\n): string | null {\n if (!cookieHeader) return null;\n\n const parts = cookieHeader.split(';');\n for (const part of parts) {\n const [rawName, ...rawValue] = part.trim().split('=');\n if (rawName !== name) continue;\n try {\n return decodeURIComponent(rawValue.join('='));\n } catch {\n return rawValue.join('=');\n }\n }\n return null;\n}\n\nexport function getBrowserCookie(name: string): string | null {\n if (typeof document === 'undefined') return null;\n return getCookieValueFromHeader(document.cookie, name);\n}\n\nfunction defaultCookieOptions(): CookieOptions {\n const secure =\n typeof process !== 'undefined'\n ? process.env.NODE_ENV === 'production'\n : typeof location !== 'undefined' && location.protocol === 'https:';\n\n return {\n path: '/',\n sameSite: 'lax',\n secure,\n };\n}\n\nexport function accessTokenCookieOptions(\n token: string,\n overrides?: CookieOptions,\n): CookieOptions {\n return {\n ...defaultCookieOptions(),\n httpOnly: false,\n expires: getJwtExpiration(token) ?? undefined,\n ...overrides,\n };\n}\n\nexport function refreshTokenCookieOptions(\n token: string,\n overrides?: CookieOptions,\n): CookieOptions {\n return {\n ...defaultCookieOptions(),\n httpOnly: true,\n expires: getJwtExpiration(token) ?? undefined,\n ...overrides,\n };\n}\n\nexport function expiredCookieOptions(overrides?: CookieOptions): CookieOptions {\n const { expires: _expires, maxAge: _maxAge, ...safeOverrides } = overrides ?? {};\n return {\n ...defaultCookieOptions(),\n ...safeOverrides,\n expires: EXPIRED_DATE,\n maxAge: 0,\n };\n}\n\nexport function setCookie(\n cookies: CookieWriter | undefined,\n name: string,\n value: string,\n options?: CookieOptions,\n): void {\n if (!cookies?.set) return;\n cookies.set(name, value, options);\n}\n\nexport function deleteCookie(\n cookies: CookieWriter | undefined,\n name: string,\n options?: CookieOptions,\n): void {\n if (!cookies) return;\n if (cookies.set) {\n cookies.set(name, '', expiredCookieOptions(options));\n return;\n }\n cookies.delete?.(name);\n}\n\nexport function serializeCookie(\n name: string,\n value: string,\n options: CookieOptions = {},\n): string {\n const parts = [`${encodeURIComponent(name)}=${encodeURIComponent(value)}`];\n\n if (options.maxAge !== undefined) parts.push(`Max-Age=${options.maxAge}`);\n if (options.domain) parts.push(`Domain=${options.domain}`);\n if (options.path) parts.push(`Path=${options.path}`);\n if (options.expires) parts.push(`Expires=${options.expires.toUTCString()}`);\n if (options.httpOnly) parts.push('HttpOnly');\n if (options.secure) parts.push('Secure');\n if (options.sameSite) {\n const sameSite =\n options.sameSite.charAt(0).toUpperCase() + options.sameSite.slice(1);\n parts.push(`SameSite=${sameSite}`);\n }\n\n return parts.join('; ');\n}\n\nexport function appendSetCookie(\n headers: Headers,\n name: string,\n value: string,\n options?: CookieOptions,\n): void {\n headers.append('Set-Cookie', serializeCookie(name, value, options));\n}\n\nexport function setAuthCookies(\n cookies: CookieWriter | undefined,\n tokens: {\n accessToken: string;\n refreshToken?: string | null;\n },\n settings: AuthCookieSettings = {},\n): void {\n const accessName = getAccessTokenCookieName(settings.names);\n const refreshName = getRefreshTokenCookieName(settings.names);\n const accessOptions = accessTokenCookieOptions(\n tokens.accessToken,\n settings.options?.accessToken,\n );\n\n setCookie(cookies, accessName, tokens.accessToken, accessOptions);\n if (tokens.refreshToken) {\n setCookie(\n cookies,\n refreshName,\n tokens.refreshToken,\n refreshTokenCookieOptions(\n tokens.refreshToken,\n settings.options?.refreshToken,\n ),\n );\n }\n}\n\nexport function clearAuthCookies(\n cookies: CookieWriter | undefined,\n settings: AuthCookieSettings = {},\n): void {\n const accessName = getAccessTokenCookieName(settings.names);\n const refreshName = getRefreshTokenCookieName(settings.names);\n const accessOptions = expiredCookieOptions(settings.options?.accessToken);\n const refreshOptions = expiredCookieOptions(settings.options?.refreshToken);\n\n deleteCookie(cookies, accessName, accessOptions);\n deleteCookie(cookies, refreshName, refreshOptions);\n}\n\nexport function setAuthCookieHeaders(\n headers: Headers,\n tokens: {\n accessToken: string;\n refreshToken?: string | null;\n },\n settings: AuthCookieSettings = {},\n): void {\n const accessName = getAccessTokenCookieName(settings.names);\n const refreshName = getRefreshTokenCookieName(settings.names);\n\n appendSetCookie(\n headers,\n accessName,\n tokens.accessToken,\n accessTokenCookieOptions(tokens.accessToken, settings.options?.accessToken),\n );\n if (tokens.refreshToken) {\n appendSetCookie(\n headers,\n refreshName,\n tokens.refreshToken,\n refreshTokenCookieOptions(\n tokens.refreshToken,\n settings.options?.refreshToken,\n ),\n );\n }\n}\n\nexport function clearAuthCookieHeaders(\n headers: Headers,\n settings: AuthCookieSettings = {},\n): void {\n appendSetCookie(\n headers,\n getAccessTokenCookieName(settings.names),\n '',\n expiredCookieOptions(settings.options?.accessToken),\n );\n appendSetCookie(\n headers,\n getRefreshTokenCookieName(settings.names),\n '',\n expiredCookieOptions(settings.options?.refreshToken),\n );\n}\n","/**\n * InsForge SDK Types - only SDK-specific types here\n * Use @insforge/shared-schemas directly for API types\n */\n\nimport type { ErrorCode, UserSchema } from '@insforge/shared-schemas';\n\nexport type InsForgeErrorCode = ErrorCode | (string & {});\n\nexport interface InsForgeConfig {\n /**\n * The base URL of the InsForge backend API\n * @default \"http://localhost:7130\"\n */\n baseUrl?: string;\n\n /**\n * Anonymous API key (optional)\n * Used for public/unauthenticated requests when no user token is set\n */\n anonKey?: string;\n\n /**\n * Static access token (optional)\n * Seeds the client with a fixed bearer token used for all authenticated\n * requests — e.g. a user JWT inside an edge function, or a server-signed\n * JWT from an external auth provider. Disables automatic token refresh\n * and implies server mode unless `isServerMode` is set explicitly.\n */\n accessToken?: string;\n\n /**\n * @deprecated Use `accessToken` instead. Same behavior; `accessToken`\n * takes precedence when both are provided.\n */\n edgeFunctionToken?: string;\n\n /**\n * Direct URL to Deno Subhosting functions (optional)\n * When provided, SDK will try this URL first for function invocations.\n * Falls back to proxy URL if subhosting returns 404.\n * @example \"https://{appKey}.functions.insforge.app\"\n */\n functionsUrl?: string;\n\n /**\n * Custom fetch implementation (useful for Node.js environments)\n */\n fetch?: typeof fetch;\n\n /**\n * Enable server-side auth mode (SSR/Node runtime)\n * In this mode auth endpoints use `client_type=mobile` and refresh_token body flow.\n *\n * @deprecated Use `createServerClient()`, `createBrowserClient()`, and\n * `updateSession()` from `@insforge/sdk/ssr` for SSR apps.\n * @default false\n */\n isServerMode?: boolean;\n\n /**\n * Advanced auth module options.\n */\n auth?: {\n /**\n * Detect and exchange OAuth callback parameters on browser client\n * initialization. SSR browser clients disable this so auth mutations can\n * stay server-owned.\n * @default true\n */\n detectOAuthCallback?: boolean;\n };\n\n /**\n * Custom headers to include with every request\n */\n headers?: Record<string, string>;\n\n /**\n * Enable debug logging for HTTP requests and responses.\n * When true, request/response details are logged to the console.\n * Can also be a custom log function for advanced use cases.\n * @default false\n */\n debug?: boolean | ((message: string, ...args: any[]) => void);\n\n /**\n * Request timeout in milliseconds.\n * Requests that exceed this duration will be aborted.\n * Set to 0 to disable timeout.\n * @default 30000\n */\n timeout?: number;\n\n /**\n * Maximum number of retry attempts for failed requests.\n * Retries are triggered on network errors and server errors (5xx).\n * Client errors (4xx) are never retried.\n * Set to 0 to disable retries.\n * @default 3\n */\n retryCount?: number;\n\n /**\n * Initial delay in milliseconds before the first retry.\n * The delay doubles with each subsequent attempt (exponential backoff)\n * with ±15% jitter to prevent thundering herd.\n * @default 500\n */\n retryDelay?: number;\n}\n\nexport type InsForgeAdminConfig = Omit<\n InsForgeConfig,\n 'anonKey' | 'accessToken' | 'edgeFunctionToken' | 'isServerMode'\n> & {\n /**\n * Project admin API key. Keep this server-side only.\n */\n apiKey: string;\n};\n\nexport interface AuthSession {\n user: UserSchema;\n accessToken: string;\n expiresAt?: Date;\n}\n\nexport interface AuthRefreshResponse {\n user: UserSchema;\n accessToken: string;\n csrfToken?: string;\n refreshToken?: string;\n}\n\nexport interface ApiError {\n error: InsForgeErrorCode;\n message: string;\n statusCode: number;\n nextActions?: string;\n}\n\nexport class InsForgeError extends Error {\n public statusCode: number;\n public error: InsForgeErrorCode;\n public nextActions?: string;\n\n constructor(\n message: string,\n statusCode: number,\n error: InsForgeErrorCode,\n nextActions?: string,\n ) {\n super(message);\n this.name = 'InsForgeError';\n this.statusCode = statusCode;\n this.error = error;\n this.nextActions = nextActions;\n }\n\n static fromApiError(apiError: ApiError): InsForgeError {\n return new InsForgeError(\n apiError.message,\n apiError.statusCode,\n apiError.error,\n apiError.nextActions,\n );\n }\n}\n","import {\n InsForgeError,\n type AuthRefreshResponse,\n type InsForgeConfig,\n} from '../types';\nimport { ERROR_CODES } from '@insforge/shared-schemas';\nimport {\n clearAuthCookieHeaders,\n getCookieValue,\n getCookieValueFromHeader,\n getRefreshTokenCookieName,\n setAuthCookieHeaders,\n type AuthCookieSettings,\n type CookieStore,\n} from './cookies';\n\nexport interface RefreshAuthOptions\n extends Omit<\n InsForgeConfig,\n 'accessToken' | 'edgeFunctionToken' | 'isServerMode' | 'auth'\n >,\n AuthCookieSettings {\n request?: Request;\n cookies?: Pick<CookieStore, 'get'>;\n refreshToken?: string;\n}\n\nexport interface RefreshAuthResult {\n response: Response;\n data: AuthRefreshResponse | null;\n accessToken: string | null;\n refreshToken: string | null;\n error: InsForgeError | null;\n}\n\nexport type RefreshAuthRouteHandler = (request: Request) => Promise<Response>;\n\nfunction jsonResponse(\n body: unknown,\n init: ResponseInit = {},\n headers = new Headers(init.headers),\n): Response {\n headers.set('Content-Type', 'application/json');\n return new Response(JSON.stringify(body), {\n ...init,\n headers,\n });\n}\n\nfunction normalizeError(error: unknown): InsForgeError {\n if (error instanceof InsForgeError) return error;\n\n if (error && typeof error === 'object') {\n const body = error as {\n error?: unknown;\n message?: unknown;\n statusCode?: unknown;\n };\n return new InsForgeError(\n typeof body.message === 'string'\n ? body.message\n : 'Failed to refresh auth session',\n typeof body.statusCode === 'number' ? body.statusCode : 500,\n typeof body.error === 'string'\n ? body.error\n : ERROR_CODES.UNKNOWN_ERROR,\n );\n }\n\n return new InsForgeError(\n error instanceof Error ? error.message : 'Failed to refresh auth session',\n 500,\n ERROR_CODES.UNKNOWN_ERROR,\n );\n}\n\nasync function readJson(response: Response): Promise<unknown> {\n const contentType = response.headers.get('content-type');\n if (!contentType?.includes('json')) return null;\n return response.json();\n}\n\nfunction readRefreshToken(options: RefreshAuthOptions): string | null {\n if (options.refreshToken) return options.refreshToken;\n\n const refreshCookieName = getRefreshTokenCookieName(options.names);\n const cookieValue = getCookieValue(options.cookies, refreshCookieName);\n if (cookieValue) return cookieValue;\n\n return getCookieValueFromHeader(\n options.request?.headers.get('cookie'),\n refreshCookieName,\n );\n}\n\nexport async function refreshAuth(\n options: RefreshAuthOptions = {},\n): Promise<RefreshAuthResult> {\n const headers = new Headers();\n const refreshToken = readRefreshToken(options);\n\n if (!refreshToken) {\n clearAuthCookieHeaders(headers, options);\n const error = new InsForgeError(\n 'Refresh token cookie is missing',\n 401,\n ERROR_CODES.AUTH_UNAUTHORIZED,\n );\n return {\n response: jsonResponse(\n {\n error: error.error,\n message: error.message,\n statusCode: error.statusCode,\n },\n { status: error.statusCode },\n headers,\n ),\n data: null,\n accessToken: null,\n refreshToken: null,\n error,\n };\n }\n\n let { baseUrl, anonKey } = options;\n try {\n baseUrl ||= process.env.NEXT_PUBLIC_INSFORGE_URL;\n anonKey ||= process.env.NEXT_PUBLIC_INSFORGE_ANON_KEY;\n } catch {\n // process may be unavailable outside Next.js/browser-bundled envs.\n }\n if (!baseUrl || !anonKey) {\n throw new Error(\n 'Missing InsForge baseUrl or anonKey. Pass baseUrl and anonKey to refreshAuth() or set NEXT_PUBLIC_INSFORGE_URL and NEXT_PUBLIC_INSFORGE_ANON_KEY.',\n );\n }\n\n const fetchImpl =\n options.fetch ??\n (globalThis.fetch\n ? globalThis.fetch.bind(globalThis)\n : (undefined as typeof fetch | undefined));\n if (!fetchImpl) {\n throw new Error(\n 'Fetch is not available. Please provide a fetch implementation.',\n );\n }\n\n const requestHeaders = new Headers(options.headers);\n requestHeaders.set('Authorization', `Bearer ${anonKey}`);\n requestHeaders.set('Content-Type', 'application/json');\n requestHeaders.set('Accept', 'application/json');\n\n let data: AuthRefreshResponse | null = null;\n let error: InsForgeError | null = null;\n\n try {\n const response = await fetchImpl(\n new URL('/api/auth/refresh?client_type=mobile', baseUrl).toString(),\n {\n method: 'POST',\n headers: requestHeaders,\n body: JSON.stringify({ refresh_token: refreshToken }),\n },\n );\n const body = await readJson(response);\n if (!response.ok) {\n error = normalizeError(\n body ?? {\n message: 'Failed to refresh auth session',\n statusCode: response.status,\n error: ERROR_CODES.UNKNOWN_ERROR,\n },\n );\n } else {\n data = body as AuthRefreshResponse;\n }\n } catch (caught) {\n error = normalizeError(caught);\n }\n\n if (error || !data?.accessToken) {\n clearAuthCookieHeaders(headers, options);\n const normalized = normalizeError(error);\n return {\n response: jsonResponse(\n {\n error: normalized.error,\n message: normalized.message,\n statusCode: normalized.statusCode,\n },\n { status: normalized.statusCode || 500 },\n headers,\n ),\n data: null,\n accessToken: null,\n refreshToken: null,\n error: normalized,\n };\n }\n\n const nextRefreshToken = data.refreshToken ?? refreshToken;\n setAuthCookieHeaders(\n headers,\n {\n accessToken: data.accessToken,\n refreshToken: nextRefreshToken,\n },\n options,\n );\n\n const responseBody: AuthRefreshResponse = {\n accessToken: data.accessToken,\n user: data.user,\n csrfToken: data.csrfToken,\n };\n\n return {\n response: jsonResponse(responseBody, { status: 200 }, headers),\n data: responseBody,\n accessToken: data.accessToken,\n refreshToken: nextRefreshToken,\n error: null,\n };\n}\n\nexport function createRefreshAuthRouter(\n options: Omit<RefreshAuthOptions, 'request'> = {},\n): { POST: RefreshAuthRouteHandler } {\n return {\n POST: async (request: Request) =>\n (await refreshAuth({ ...options, request })).response,\n };\n}\n","import { isJwtExpiredOrExpiring } from '../lib/jwt';\nimport type { InsForgeConfig, InsForgeError } from '../types';\nimport {\n clearAuthCookies,\n getAccessTokenCookieName,\n getCookieValue,\n getRefreshTokenCookieName,\n setAuthCookies,\n type AuthCookieSettings,\n type CookieStore,\n} from './cookies';\nimport { refreshAuth } from './refresh';\n\nexport interface UpdateSessionOptions\n extends Omit<\n InsForgeConfig,\n 'accessToken' | 'edgeFunctionToken' | 'isServerMode' | 'auth'\n >,\n AuthCookieSettings {\n requestCookies: CookieStore;\n responseCookies: CookieStore;\n refreshLeewaySeconds?: number;\n}\n\nexport interface UpdateSessionResult {\n refreshed: boolean;\n accessToken: string | null;\n error: InsForgeError | null;\n}\n\nexport async function updateSession(\n options: UpdateSessionOptions,\n): Promise<UpdateSessionResult> {\n const accessCookieName = getAccessTokenCookieName(options.names);\n const refreshCookieName = getRefreshTokenCookieName(options.names);\n const accessToken = getCookieValue(\n options.requestCookies,\n accessCookieName,\n );\n\n if (\n accessToken &&\n !isJwtExpiredOrExpiring(accessToken, options.refreshLeewaySeconds)\n ) {\n return {\n refreshed: false,\n accessToken,\n error: null,\n };\n }\n\n const refreshToken = getCookieValue(\n options.requestCookies,\n refreshCookieName,\n );\n if (!refreshToken) {\n if (accessToken) {\n clearAuthCookies(options.requestCookies, options);\n clearAuthCookies(options.responseCookies, options);\n }\n return {\n refreshed: false,\n accessToken: null,\n error: null,\n };\n }\n\n const result = await refreshAuth({\n ...options,\n refreshToken,\n });\n\n if (result.error || !result.accessToken) {\n clearAuthCookies(options.requestCookies, options);\n clearAuthCookies(options.responseCookies, options);\n return {\n refreshed: false,\n accessToken: null,\n error: result.error,\n };\n }\n\n const tokens = {\n accessToken: result.accessToken,\n refreshToken: result.refreshToken ?? refreshToken,\n };\n setAuthCookies(options.requestCookies, tokens, options);\n setAuthCookies(options.responseCookies, tokens, options);\n\n return {\n refreshed: true,\n accessToken: result.accessToken,\n error: null,\n };\n}\n"],"mappings":"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","names":["error"]}
|
package/dist/ssr.d.mts
CHANGED
|
@@ -1,15 +1,19 @@
|
|
|
1
|
-
import { I as InsForgeClient } from './client-
|
|
2
|
-
import { I as InsForgeConfig, e as AuthRefreshResponse, d as InsForgeError } from './types-
|
|
3
|
-
import { A as AuthCookieSettings, C as CookieStore } from './middleware-
|
|
4
|
-
export {
|
|
1
|
+
import { I as InsForgeClient } from './client-C-qBRoea.mjs';
|
|
2
|
+
import { I as InsForgeConfig, e as AuthRefreshResponse, d as InsForgeError } from './types-Dk-44JJf.mjs';
|
|
3
|
+
import { A as AuthCookieSettings, C as CookieStore, a as CookieWriter } from './middleware-K59XjpUX.mjs';
|
|
4
|
+
export { h as AuthCookieNames, i as AuthCookieOptions, j as CookieOptions, k as CookieReader, D as DEFAULT_ACCESS_TOKEN_COOKIE, c as DEFAULT_REFRESH_TOKEN_COOKIE, U as UpdateSessionOptions, b as UpdateSessionResult, d as accessTokenCookieOptions, e as clearAuthCookies, g as getAccessTokenCookieName, f as getRefreshTokenCookieName, r as refreshTokenCookieOptions, s as setAuthCookies, u as updateSession } from './middleware-K59XjpUX.mjs';
|
|
5
5
|
import '@insforge/shared-schemas';
|
|
6
6
|
import '@supabase/postgrest-js';
|
|
7
7
|
|
|
8
|
+
type BrowserAuth = Pick<InsForgeClient['auth'], 'getCurrentUser' | 'getProfile' | 'getPublicAuthConfig'>;
|
|
9
|
+
type BrowserInsForgeClient = Omit<InsForgeClient, 'auth'> & {
|
|
10
|
+
readonly auth: BrowserAuth;
|
|
11
|
+
};
|
|
8
12
|
interface CreateBrowserClientOptions extends Omit<InsForgeConfig, 'accessToken' | 'edgeFunctionToken' | 'isServerMode' | 'auth'>, AuthCookieSettings {
|
|
9
13
|
refreshUrl?: string;
|
|
10
14
|
refreshLeewaySeconds?: number;
|
|
11
15
|
}
|
|
12
|
-
declare function createBrowserClient(options?: CreateBrowserClientOptions):
|
|
16
|
+
declare function createBrowserClient(options?: CreateBrowserClientOptions): BrowserInsForgeClient;
|
|
13
17
|
|
|
14
18
|
interface CreateServerClientOptions extends Omit<InsForgeConfig, 'accessToken' | 'edgeFunctionToken' | 'isServerMode' | 'auth'>, AuthCookieSettings {
|
|
15
19
|
cookies?: Pick<CookieStore, 'get'>;
|
|
@@ -35,4 +39,40 @@ declare function createRefreshAuthRouter(options?: Omit<RefreshAuthOptions, 'req
|
|
|
35
39
|
POST: RefreshAuthRouteHandler;
|
|
36
40
|
};
|
|
37
41
|
|
|
38
|
-
|
|
42
|
+
interface CreateAuthActionsOptions extends Omit<InsForgeConfig, 'accessToken' | 'edgeFunctionToken' | 'isServerMode' | 'auth'>, AuthCookieSettings {
|
|
43
|
+
/**
|
|
44
|
+
* Read/write cookie store. Use this in Next.js Server Actions:
|
|
45
|
+
* `createAuthActions({ cookies: await cookies() })`.
|
|
46
|
+
*/
|
|
47
|
+
cookies?: CookieStore;
|
|
48
|
+
/**
|
|
49
|
+
* Request cookie reader. Use with `responseCookies` in Route Handlers where
|
|
50
|
+
* request and response cookies are separate objects.
|
|
51
|
+
*/
|
|
52
|
+
requestCookies?: Pick<CookieStore, 'get'>;
|
|
53
|
+
/**
|
|
54
|
+
* Response cookie writer. Use with `requestCookies` in Route Handlers.
|
|
55
|
+
*/
|
|
56
|
+
responseCookies?: CookieWriter;
|
|
57
|
+
}
|
|
58
|
+
type AuthTokenKeys = 'accessToken' | 'refreshToken' | 'csrfToken';
|
|
59
|
+
type SafeAuthData<T> = Omit<NonNullable<T>, AuthTokenKeys>;
|
|
60
|
+
type AuthResultData<TMethod extends (...args: any[]) => Promise<any>> = Awaited<ReturnType<TMethod>> extends {
|
|
61
|
+
data: infer TData;
|
|
62
|
+
} ? TData : never;
|
|
63
|
+
type SafeAuthAction<TMethod extends (...args: any[]) => Promise<any>> = (...args: Parameters<TMethod>) => Promise<{
|
|
64
|
+
data: SafeAuthData<AuthResultData<TMethod>> | null;
|
|
65
|
+
error: InsForgeError | null;
|
|
66
|
+
}>;
|
|
67
|
+
interface AuthActions {
|
|
68
|
+
signUp: SafeAuthAction<InsForgeClient['auth']['signUp']>;
|
|
69
|
+
signInWithPassword: SafeAuthAction<InsForgeClient['auth']['signInWithPassword']>;
|
|
70
|
+
signInWithOAuth: InsForgeClient['auth']['signInWithOAuth'];
|
|
71
|
+
signInWithIdToken: SafeAuthAction<InsForgeClient['auth']['signInWithIdToken']>;
|
|
72
|
+
exchangeOAuthCode: SafeAuthAction<InsForgeClient['auth']['exchangeOAuthCode']>;
|
|
73
|
+
verifyEmail: SafeAuthAction<InsForgeClient['auth']['verifyEmail']>;
|
|
74
|
+
signOut: InsForgeClient['auth']['signOut'];
|
|
75
|
+
}
|
|
76
|
+
declare function createAuthActions(options?: CreateAuthActionsOptions): AuthActions;
|
|
77
|
+
|
|
78
|
+
export { type AuthActions, AuthCookieSettings, CookieStore, CookieWriter, type CreateAuthActionsOptions, type CreateBrowserClientOptions, type CreateServerClientOptions, type RefreshAuthOptions, type RefreshAuthResult, type RefreshAuthRouteHandler, createAuthActions, createBrowserClient, createRefreshAuthRouter, createServerClient, refreshAuth };
|
package/dist/ssr.d.ts
CHANGED
|
@@ -1,15 +1,19 @@
|
|
|
1
|
-
import { I as InsForgeClient } from './client-
|
|
2
|
-
import { I as InsForgeConfig, e as AuthRefreshResponse, d as InsForgeError } from './types-
|
|
3
|
-
import { A as AuthCookieSettings, C as CookieStore } from './middleware-
|
|
4
|
-
export {
|
|
1
|
+
import { I as InsForgeClient } from './client-BR9o-WUm.js';
|
|
2
|
+
import { I as InsForgeConfig, e as AuthRefreshResponse, d as InsForgeError } from './types-Dk-44JJf.js';
|
|
3
|
+
import { A as AuthCookieSettings, C as CookieStore, a as CookieWriter } from './middleware-Tu_RlUAt.js';
|
|
4
|
+
export { h as AuthCookieNames, i as AuthCookieOptions, j as CookieOptions, k as CookieReader, D as DEFAULT_ACCESS_TOKEN_COOKIE, c as DEFAULT_REFRESH_TOKEN_COOKIE, U as UpdateSessionOptions, b as UpdateSessionResult, d as accessTokenCookieOptions, e as clearAuthCookies, g as getAccessTokenCookieName, f as getRefreshTokenCookieName, r as refreshTokenCookieOptions, s as setAuthCookies, u as updateSession } from './middleware-Tu_RlUAt.js';
|
|
5
5
|
import '@insforge/shared-schemas';
|
|
6
6
|
import '@supabase/postgrest-js';
|
|
7
7
|
|
|
8
|
+
type BrowserAuth = Pick<InsForgeClient['auth'], 'getCurrentUser' | 'getProfile' | 'getPublicAuthConfig'>;
|
|
9
|
+
type BrowserInsForgeClient = Omit<InsForgeClient, 'auth'> & {
|
|
10
|
+
readonly auth: BrowserAuth;
|
|
11
|
+
};
|
|
8
12
|
interface CreateBrowserClientOptions extends Omit<InsForgeConfig, 'accessToken' | 'edgeFunctionToken' | 'isServerMode' | 'auth'>, AuthCookieSettings {
|
|
9
13
|
refreshUrl?: string;
|
|
10
14
|
refreshLeewaySeconds?: number;
|
|
11
15
|
}
|
|
12
|
-
declare function createBrowserClient(options?: CreateBrowserClientOptions):
|
|
16
|
+
declare function createBrowserClient(options?: CreateBrowserClientOptions): BrowserInsForgeClient;
|
|
13
17
|
|
|
14
18
|
interface CreateServerClientOptions extends Omit<InsForgeConfig, 'accessToken' | 'edgeFunctionToken' | 'isServerMode' | 'auth'>, AuthCookieSettings {
|
|
15
19
|
cookies?: Pick<CookieStore, 'get'>;
|
|
@@ -35,4 +39,40 @@ declare function createRefreshAuthRouter(options?: Omit<RefreshAuthOptions, 'req
|
|
|
35
39
|
POST: RefreshAuthRouteHandler;
|
|
36
40
|
};
|
|
37
41
|
|
|
38
|
-
|
|
42
|
+
interface CreateAuthActionsOptions extends Omit<InsForgeConfig, 'accessToken' | 'edgeFunctionToken' | 'isServerMode' | 'auth'>, AuthCookieSettings {
|
|
43
|
+
/**
|
|
44
|
+
* Read/write cookie store. Use this in Next.js Server Actions:
|
|
45
|
+
* `createAuthActions({ cookies: await cookies() })`.
|
|
46
|
+
*/
|
|
47
|
+
cookies?: CookieStore;
|
|
48
|
+
/**
|
|
49
|
+
* Request cookie reader. Use with `responseCookies` in Route Handlers where
|
|
50
|
+
* request and response cookies are separate objects.
|
|
51
|
+
*/
|
|
52
|
+
requestCookies?: Pick<CookieStore, 'get'>;
|
|
53
|
+
/**
|
|
54
|
+
* Response cookie writer. Use with `requestCookies` in Route Handlers.
|
|
55
|
+
*/
|
|
56
|
+
responseCookies?: CookieWriter;
|
|
57
|
+
}
|
|
58
|
+
type AuthTokenKeys = 'accessToken' | 'refreshToken' | 'csrfToken';
|
|
59
|
+
type SafeAuthData<T> = Omit<NonNullable<T>, AuthTokenKeys>;
|
|
60
|
+
type AuthResultData<TMethod extends (...args: any[]) => Promise<any>> = Awaited<ReturnType<TMethod>> extends {
|
|
61
|
+
data: infer TData;
|
|
62
|
+
} ? TData : never;
|
|
63
|
+
type SafeAuthAction<TMethod extends (...args: any[]) => Promise<any>> = (...args: Parameters<TMethod>) => Promise<{
|
|
64
|
+
data: SafeAuthData<AuthResultData<TMethod>> | null;
|
|
65
|
+
error: InsForgeError | null;
|
|
66
|
+
}>;
|
|
67
|
+
interface AuthActions {
|
|
68
|
+
signUp: SafeAuthAction<InsForgeClient['auth']['signUp']>;
|
|
69
|
+
signInWithPassword: SafeAuthAction<InsForgeClient['auth']['signInWithPassword']>;
|
|
70
|
+
signInWithOAuth: InsForgeClient['auth']['signInWithOAuth'];
|
|
71
|
+
signInWithIdToken: SafeAuthAction<InsForgeClient['auth']['signInWithIdToken']>;
|
|
72
|
+
exchangeOAuthCode: SafeAuthAction<InsForgeClient['auth']['exchangeOAuthCode']>;
|
|
73
|
+
verifyEmail: SafeAuthAction<InsForgeClient['auth']['verifyEmail']>;
|
|
74
|
+
signOut: InsForgeClient['auth']['signOut'];
|
|
75
|
+
}
|
|
76
|
+
declare function createAuthActions(options?: CreateAuthActionsOptions): AuthActions;
|
|
77
|
+
|
|
78
|
+
export { type AuthActions, AuthCookieSettings, CookieStore, CookieWriter, type CreateAuthActionsOptions, type CreateBrowserClientOptions, type CreateServerClientOptions, type RefreshAuthOptions, type RefreshAuthResult, type RefreshAuthRouteHandler, createAuthActions, createBrowserClient, createRefreshAuthRouter, createServerClient, refreshAuth };
|