@ghostly-solutions/auth 0.1.0 → 0.2.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/react.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/constants/auth-endpoints.ts","../src/constants/http-status.ts","../src/errors/auth-sdk-error.ts","../src/types/auth-error-code.ts","../src/constants/auth-keys.ts","../src/core/object-guards.ts","../src/core/session-parser.ts","../src/core/broadcast-sync.ts","../src/core/callback-url.ts","../src/core/http-client.ts","../src/core/runtime.ts","../src/core/return-to-storage.ts","../src/core/session-store.ts","../src/core/auth-client.ts","../src/adapters/react/auth-callback-handler.tsx","../src/adapters/react/auth-context.tsx","../src/adapters/react/auth-provider.tsx","../src/adapters/react/use-auth.ts","../src/adapters/react/auth-session-gate.tsx"],"names":["useMemo","useState","useEffect","jsx","Fragment"],"mappings":"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","file":"react.js","sourcesContent":["const authApiPrefix = \"/v1/auth\";\n\nexport const authEndpoints = {\n loginStart: `${authApiPrefix}/keycloak/login`,\n validateKeycloakToken: `${authApiPrefix}/keycloak/validate`,\n session: `${authApiPrefix}/me`,\n logout: `${authApiPrefix}/logout`,\n} as const;\n","export const httpStatus = {\n ok: 200,\n found: 302,\n noContent: 204,\n badRequest: 400,\n unauthorized: 401,\n} as const;\n","import type { AuthErrorCode } from \"../types/auth-error-code\";\n\nexport interface AuthSdkErrorPayload {\n code: AuthErrorCode;\n details: unknown;\n message: string;\n status: number | null;\n}\n\nexport class AuthSdkError extends Error {\n readonly code: AuthErrorCode;\n readonly details: unknown;\n readonly status: number | null;\n\n constructor(payload: AuthSdkErrorPayload) {\n super(payload.message);\n this.name = \"AuthSdkError\";\n this.code = payload.code;\n this.details = payload.details;\n this.status = payload.status;\n }\n}\n","export const authErrorCode = {\n callbackMissingToken: \"callback_missing_token\",\n callbackInvalidToken: \"callback_invalid_token\",\n callbackValidationFailed: \"callback_validation_failed\",\n unauthorized: \"unauthorized\",\n networkError: \"network_error\",\n apiError: \"api_error\",\n broadcastChannelUnsupported: \"broadcast_channel_unsupported\",\n serverOriginResolutionFailed: \"server_origin_resolution_failed\",\n} as const;\n\nexport type AuthErrorCode = (typeof authErrorCode)[keyof typeof authErrorCode];\n","export const authQueryKeys = {\n token: \"token\",\n} as const;\n\nexport const authStorageKeys = {\n returnTo: \"ghostly-auth:return-to\",\n} as const;\n\nexport const authBroadcast = {\n channelName: \"ghostly-auth-channel\",\n sessionUpdatedEvent: \"session-updated\",\n} as const;\n\nexport const authRoutes = {\n root: \"/\",\n callback: \"/auth/callback\",\n} as const;\n","export function isObjectRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === \"object\" && value !== null;\n}\n\nexport function isStringValue(value: unknown): value is string {\n return typeof value === \"string\";\n}\n","import type { GhostlySession } from \"../types/ghostly-session\";\nimport { isObjectRecord, isStringValue } from \"./object-guards\";\n\nexport function isStringArray(value: unknown): value is string[] {\n return Array.isArray(value) && value.every((entry) => isStringValue(entry));\n}\n\nexport function isGhostlySession(value: unknown): value is GhostlySession {\n if (!isObjectRecord(value)) {\n return false;\n }\n\n return (\n isStringValue(value.id) &&\n isStringValue(value.username) &&\n (value.firstName === null || isStringValue(value.firstName)) &&\n (value.lastName === null || isStringValue(value.lastName)) &&\n isStringValue(value.email) &&\n isStringValue(value.role) &&\n isStringArray(value.permissions)\n );\n}\n","import { authBroadcast } from \"../constants/auth-keys\";\nimport { AuthSdkError } from \"../errors/auth-sdk-error\";\nimport { authErrorCode } from \"../types/auth-error-code\";\nimport type { GhostlySession } from \"../types/ghostly-session\";\nimport { isObjectRecord, isStringValue } from \"./object-guards\";\nimport { isGhostlySession } from \"./session-parser\";\n\ninterface SessionUpdatedMessage {\n session: GhostlySession | null;\n type: typeof authBroadcast.sessionUpdatedEvent;\n}\n\nexport interface BroadcastSync {\n close(): void;\n publishSession(session: GhostlySession | null): void;\n}\n\ninterface CreateBroadcastSyncOptions {\n onSessionUpdated: (session: GhostlySession | null) => void;\n}\n\nfunction isSessionUpdatedMessage(value: unknown): value is SessionUpdatedMessage {\n if (!isObjectRecord(value)) {\n return false;\n }\n\n if (!isStringValue(value.type)) {\n return false;\n }\n\n if (value.type !== authBroadcast.sessionUpdatedEvent) {\n return false;\n }\n\n return value.session === null || isGhostlySession(value.session);\n}\n\nfunction createUnsupportedBroadcastChannelError(): AuthSdkError {\n return new AuthSdkError({\n code: authErrorCode.broadcastChannelUnsupported,\n details: null,\n message: \"BroadcastChannel is unavailable in this runtime.\",\n status: null,\n });\n}\n\nexport function createBroadcastSync(options: CreateBroadcastSyncOptions): BroadcastSync {\n if (typeof BroadcastChannel === \"undefined\") {\n throw createUnsupportedBroadcastChannelError();\n }\n\n const channel = new BroadcastChannel(authBroadcast.channelName);\n\n const onMessage: EventListener = (event) => {\n const messageEvent = event as MessageEvent<unknown>;\n\n if (!isSessionUpdatedMessage(messageEvent.data)) {\n return;\n }\n\n options.onSessionUpdated(messageEvent.data.session);\n };\n\n channel.addEventListener(\"message\", onMessage);\n\n return {\n close() {\n channel.removeEventListener(\"message\", onMessage);\n channel.close();\n },\n publishSession(session) {\n const payload: SessionUpdatedMessage = {\n session,\n type: authBroadcast.sessionUpdatedEvent,\n };\n\n channel.postMessage(payload);\n },\n };\n}\n","import { authQueryKeys } from \"../constants/auth-keys\";\n\nexport function readCallbackToken(url: URL): string | null {\n return url.searchParams.get(authQueryKeys.token);\n}\n\nexport function removeCallbackToken(url: URL): URL {\n const nextUrl = new URL(url.toString());\n nextUrl.searchParams.delete(authQueryKeys.token);\n return nextUrl;\n}\n\nexport function replaceBrowserHistory(url: URL): void {\n window.history.replaceState(null, \"\", url.toString());\n}\n","import { httpStatus } from \"../constants/http-status\";\nimport { AuthSdkError } from \"../errors/auth-sdk-error\";\nimport { authErrorCode } from \"../types/auth-error-code\";\nimport { isObjectRecord, isStringValue } from \"./object-guards\";\n\nconst jsonContentType = \"application/json\";\nconst jsonHeaderName = \"content-type\";\nconst includeCredentials: RequestCredentials = \"include\";\nconst noStoreCache: RequestCache = \"no-store\";\n\ninterface RequestOptions<TBody> {\n body?: TBody;\n expectedStatus?: number;\n method: \"GET\" | \"POST\";\n path: string;\n}\n\ninterface ParsedErrorPayload {\n code: string | null;\n details: unknown;\n message: string | null;\n}\n\nfunction toTypedValue<TValue>(value: unknown): TValue {\n return value as TValue;\n}\n\nfunction mapHttpStatusToAuthErrorCode(status: number) {\n if (status === httpStatus.unauthorized) {\n return authErrorCode.unauthorized;\n }\n\n return authErrorCode.apiError;\n}\n\nasync function parseJsonPayload(response: Response): Promise<unknown> {\n try {\n return await response.json();\n } catch {\n return null;\n }\n}\n\nasync function parseErrorPayload(response: Response): Promise<ParsedErrorPayload> {\n const payload = await parseJsonPayload(response);\n\n if (!isObjectRecord(payload)) {\n return {\n code: null,\n details: null,\n message: null,\n };\n }\n\n const maybeCode = payload.code;\n const maybeMessage = payload.message;\n\n return {\n code: isStringValue(maybeCode) ? maybeCode : null,\n details: \"details\" in payload ? payload.details : null,\n message: isStringValue(maybeMessage) ? maybeMessage : null,\n };\n}\n\nfunction buildApiErrorMessage(method: RequestOptions<unknown>[\"method\"], path: string): string {\n return `Auth API request failed: ${method} ${path}`;\n}\n\nfunction buildNetworkErrorMessage(method: RequestOptions<unknown>[\"method\"], path: string): string {\n return `Auth API network failure: ${method} ${path}`;\n}\n\nasync function request<TResponse, TBody = undefined>(\n options: RequestOptions<TBody>,\n): Promise<TResponse> {\n const expectedStatus = options.expectedStatus ?? httpStatus.ok;\n const headers = new Headers();\n const hasBody = typeof options.body !== \"undefined\";\n\n if (hasBody) {\n headers.set(jsonHeaderName, jsonContentType);\n }\n\n const requestInit: RequestInit = {\n cache: noStoreCache,\n credentials: includeCredentials,\n headers,\n method: options.method,\n };\n\n if (hasBody) {\n requestInit.body = JSON.stringify(options.body);\n }\n\n let response: Response;\n\n try {\n response = await fetch(options.path, requestInit);\n } catch (error) {\n throw new AuthSdkError({\n code: authErrorCode.networkError,\n details: error,\n message: buildNetworkErrorMessage(options.method, options.path),\n status: null,\n });\n }\n\n if (response.status !== expectedStatus) {\n const parsed = await parseErrorPayload(response);\n\n throw new AuthSdkError({\n code: mapHttpStatusToAuthErrorCode(response.status),\n details: {\n apiCode: parsed.code,\n apiDetails: parsed.details,\n },\n message: parsed.message ?? buildApiErrorMessage(options.method, options.path),\n status: response.status,\n });\n }\n\n if (response.status === httpStatus.noContent) {\n return toTypedValue<TResponse>(null);\n }\n\n const payload = await parseJsonPayload(response);\n return toTypedValue<TResponse>(payload);\n}\n\nexport function getJson<TResponse>(path: string): Promise<TResponse> {\n return request<TResponse>({\n method: \"GET\",\n path,\n });\n}\n\nexport function postJson<TResponse, TBody>(path: string, body: TBody): Promise<TResponse> {\n return request<TResponse, TBody>({\n body,\n method: \"POST\",\n path,\n });\n}\n\nexport function postEmpty(path: string): Promise<null> {\n return request<null>({\n expectedStatus: httpStatus.noContent,\n method: \"POST\",\n path,\n });\n}\n","import { AuthSdkError } from \"../errors/auth-sdk-error\";\nimport { authErrorCode } from \"../types/auth-error-code\";\n\nconst browserRuntimeErrorMessage = \"Browser runtime is required for this auth operation.\";\n\nexport function isBrowserRuntime(): boolean {\n return typeof window !== \"undefined\";\n}\n\nexport function assertBrowserRuntime(): void {\n if (isBrowserRuntime()) {\n return;\n }\n\n throw new AuthSdkError({\n code: authErrorCode.apiError,\n details: null,\n message: browserRuntimeErrorMessage,\n status: null,\n });\n}\n","import { authRoutes, authStorageKeys } from \"../constants/auth-keys\";\nimport { assertBrowserRuntime } from \"./runtime\";\n\nfunction sanitizeReturnTo(value: string | null | undefined): string {\n if (!value) {\n return authRoutes.root;\n }\n\n if (!value.startsWith(authRoutes.root)) {\n return authRoutes.root;\n }\n\n const protocolRelativePrefix = \"//\";\n\n if (value.startsWith(protocolRelativePrefix)) {\n return authRoutes.root;\n }\n\n return value;\n}\n\nfunction getCurrentBrowserPath(): string {\n return `${window.location.pathname}${window.location.search}${window.location.hash}`;\n}\n\nexport function saveReturnToPath(returnTo: string | undefined): string {\n assertBrowserRuntime();\n\n const fallbackPath = getCurrentBrowserPath();\n const sanitized = sanitizeReturnTo(returnTo ?? fallbackPath);\n window.sessionStorage.setItem(authStorageKeys.returnTo, sanitized);\n return sanitized;\n}\n\nexport function consumeReturnToPath(): string {\n assertBrowserRuntime();\n\n const value = window.sessionStorage.getItem(authStorageKeys.returnTo);\n window.sessionStorage.removeItem(authStorageKeys.returnTo);\n return sanitizeReturnTo(value);\n}\n","import type { SessionListener } from \"../types/auth-client\";\nimport type { GhostlySession } from \"../types/ghostly-session\";\n\ntype SessionResolveState = \"pending\" | \"resolved\";\n\nexport class SessionStore {\n private listeners = new Set<SessionListener>();\n private resolvedSession: GhostlySession | null = null;\n private resolveState: SessionResolveState = \"pending\";\n\n getSessionIfResolved(): GhostlySession | null {\n if (this.resolveState === \"pending\") {\n return null;\n }\n\n return this.resolvedSession;\n }\n\n hasResolvedSession(): boolean {\n return this.resolveState === \"resolved\";\n }\n\n setSession(session: GhostlySession | null): void {\n this.resolveState = \"resolved\";\n this.resolvedSession = session;\n\n for (const listener of this.listeners) {\n listener(session);\n }\n }\n\n subscribe(listener: SessionListener): () => void {\n this.listeners.add(listener);\n\n return () => {\n this.listeners.delete(listener);\n };\n }\n}\n","import { authEndpoints } from \"../constants/auth-endpoints\";\nimport { httpStatus } from \"../constants/http-status\";\nimport { AuthSdkError } from \"../errors/auth-sdk-error\";\nimport type {\n AuthClient,\n LoginOptions,\n ProcessCallbackResult,\n SessionRequestOptions,\n} from \"../types/auth-client\";\nimport { authErrorCode } from \"../types/auth-error-code\";\nimport type { GhostlySession } from \"../types/ghostly-session\";\nimport type { BroadcastSync } from \"./broadcast-sync\";\nimport { createBroadcastSync } from \"./broadcast-sync\";\nimport { readCallbackToken, removeCallbackToken, replaceBrowserHistory } from \"./callback-url\";\nimport { getJson, postEmpty, postJson } from \"./http-client\";\nimport { consumeReturnToPath, saveReturnToPath } from \"./return-to-storage\";\nimport { assertBrowserRuntime } from \"./runtime\";\nimport { isGhostlySession } from \"./session-parser\";\nimport { SessionStore } from \"./session-store\";\n\ninterface ValidateTokenRequest {\n token: string;\n}\n\ninterface ValidateTokenResponse {\n session: unknown;\n}\n\nfunction createPendingRedirectPromise<TValue>(): Promise<TValue> {\n return new Promise(() => {\n // Location redirect never resolves within current runtime execution.\n });\n}\n\nfunction createInvalidSessionPayloadError(path: string): AuthSdkError {\n return new AuthSdkError({\n code: authErrorCode.apiError,\n details: null,\n message: `Auth API response has invalid session shape: ${path}`,\n status: null,\n });\n}\n\nfunction toValidatedSession(payload: unknown, path: string): GhostlySession {\n if (!isGhostlySession(payload)) {\n throw createInvalidSessionPayloadError(path);\n }\n\n return payload;\n}\n\nfunction toCallbackFailure(error: unknown): AuthSdkError {\n if (error instanceof AuthSdkError) {\n if (error.status === httpStatus.unauthorized) {\n return new AuthSdkError({\n code: authErrorCode.callbackInvalidToken,\n details: error.details,\n message: \"Callback JWT is invalid or expired.\",\n status: error.status,\n });\n }\n\n return new AuthSdkError({\n code: authErrorCode.callbackValidationFailed,\n details: error.details,\n message: \"Keycloak callback validation failed.\",\n status: error.status,\n });\n }\n\n return new AuthSdkError({\n code: authErrorCode.callbackValidationFailed,\n details: error,\n message: \"Keycloak callback validation failed.\",\n status: null,\n });\n}\n\nfunction createNoopBroadcastSync(): BroadcastSync {\n return {\n close() {},\n publishSession() {},\n };\n}\n\nfunction createSafeBroadcastSync(\n onSessionUpdated: (session: GhostlySession | null) => void,\n): BroadcastSync {\n try {\n return createBroadcastSync({\n onSessionUpdated,\n });\n } catch (error) {\n if (error instanceof AuthSdkError && error.code === authErrorCode.broadcastChannelUnsupported) {\n return createNoopBroadcastSync();\n }\n\n throw error;\n }\n}\n\nasync function fetchCurrentSessionFromApi(): Promise<GhostlySession | null> {\n const payload = await getJson<unknown>(authEndpoints.session);\n\n if (payload === null) {\n return null;\n }\n\n return toValidatedSession(payload, authEndpoints.session);\n}\n\nexport function createAuthClient(): AuthClient {\n assertBrowserRuntime();\n\n const sessionStore = new SessionStore();\n const broadcastSync = createSafeBroadcastSync((session) => {\n sessionStore.setSession(session);\n });\n\n const getSession = async (options?: SessionRequestOptions): Promise<GhostlySession | null> => {\n const forceRefresh = options?.forceRefresh ?? false;\n\n if (sessionStore.hasResolvedSession() && !forceRefresh) {\n return sessionStore.getSessionIfResolved();\n }\n\n const session = await fetchCurrentSessionFromApi();\n sessionStore.setSession(session);\n broadcastSync.publishSession(session);\n\n return session;\n };\n\n const requireSession = async (): Promise<GhostlySession> => {\n const session = await getSession();\n\n if (session) {\n return session;\n }\n\n throw new AuthSdkError({\n code: authErrorCode.unauthorized,\n details: null,\n message: \"Authenticated session is required.\",\n status: httpStatus.unauthorized,\n });\n };\n\n const login = (options?: LoginOptions): void => {\n saveReturnToPath(options?.returnTo);\n window.location.assign(authEndpoints.loginStart);\n };\n\n const processCallback = async (): Promise<ProcessCallbackResult> => {\n const currentUrl = new URL(window.location.href);\n const token = readCallbackToken(currentUrl);\n\n if (!token) {\n throw new AuthSdkError({\n code: authErrorCode.callbackMissingToken,\n details: null,\n message: \"Missing callback token query parameter.\",\n status: httpStatus.badRequest,\n });\n }\n\n const cleanedUrl = removeCallbackToken(currentUrl);\n replaceBrowserHistory(cleanedUrl);\n\n try {\n const payload = await postJson<ValidateTokenResponse, ValidateTokenRequest>(\n authEndpoints.validateKeycloakToken,\n { token },\n );\n\n const session = toValidatedSession(payload.session, authEndpoints.validateKeycloakToken);\n sessionStore.setSession(session);\n broadcastSync.publishSession(session);\n\n return {\n redirectTo: consumeReturnToPath(),\n session,\n };\n } catch (error) {\n throw toCallbackFailure(error);\n }\n };\n\n const completeCallbackRedirect = async (): Promise<never> => {\n const result = await processCallback();\n window.location.replace(result.redirectTo);\n return createPendingRedirectPromise<never>();\n };\n\n const logout = async (): Promise<void> => {\n await postEmpty(authEndpoints.logout);\n sessionStore.setSession(null);\n broadcastSync.publishSession(null);\n };\n\n const subscribe = sessionStore.subscribe.bind(sessionStore);\n\n return {\n completeCallbackRedirect,\n getSession,\n login,\n logout,\n processCallback,\n requireSession,\n subscribe,\n };\n}\n","\"use client\";\n\nimport type { ReactNode } from \"react\";\nimport { useEffect, useMemo, useState } from \"react\";\nimport { createAuthClient } from \"../../core/auth-client\";\nimport { AuthSdkError } from \"../../errors/auth-sdk-error\";\nimport type { AuthClient } from \"../../types/auth-client\";\n\nexport type AuthCallbackStatus = \"processing\" | \"failed\";\n\nexport interface UseAuthCallbackRedirectOptions {\n client?: AuthClient;\n}\n\nexport interface UseAuthCallbackRedirectResult {\n error: AuthSdkError | null;\n status: AuthCallbackStatus;\n}\n\nfunction normalizeAuthError(error: unknown): AuthSdkError {\n if (error instanceof AuthSdkError) {\n return error;\n }\n\n return new AuthSdkError({\n code: \"callback_validation_failed\",\n details: error,\n message: \"Auth callback redirect failed.\",\n status: null,\n });\n}\n\nexport function useAuthCallbackRedirect(\n options: UseAuthCallbackRedirectOptions = {},\n): UseAuthCallbackRedirectResult {\n const client = useMemo(() => options.client ?? createAuthClient(), [options.client]);\n const [error, setError] = useState<AuthSdkError | null>(null);\n\n useEffect(() => {\n let isActive = true;\n\n void client.completeCallbackRedirect().catch((caughtError) => {\n if (!isActive) {\n return;\n }\n\n setError(normalizeAuthError(caughtError));\n });\n\n return () => {\n isActive = false;\n };\n }, [client]);\n\n if (error) {\n return {\n error,\n status: \"failed\",\n };\n }\n\n return {\n error: null,\n status: \"processing\",\n };\n}\n\nexport interface AuthCallbackHandlerProps {\n client?: AuthClient;\n processing: ReactNode;\n renderError: (error: AuthSdkError) => ReactNode;\n}\n\nexport function AuthCallbackHandler(props: AuthCallbackHandlerProps) {\n const state = useAuthCallbackRedirect({\n client: props.client,\n });\n\n if (state.status === \"failed\" && state.error) {\n return props.renderError(state.error);\n }\n\n return <>{props.processing}</>;\n}\n","\"use client\";\n\nimport { createContext } from \"react\";\nimport type { AuthSdkError } from \"../../errors/auth-sdk-error\";\nimport type { LoginOptions } from \"../../types/auth-client\";\nimport type { GhostlySession } from \"../../types/ghostly-session\";\n\nexport interface AuthContextValue {\n error: AuthSdkError | null;\n isLoading: boolean;\n login: (options?: LoginOptions) => void;\n logout: () => Promise<void>;\n refresh: () => Promise<GhostlySession | null>;\n session: GhostlySession | null;\n}\n\nexport const AuthContext = createContext<AuthContextValue | null>(null);\n","\"use client\";\n\nimport { type ReactNode, useCallback, useEffect, useMemo, useState } from \"react\";\nimport { createAuthClient } from \"../../core/auth-client\";\nimport { AuthSdkError } from \"../../errors/auth-sdk-error\";\nimport type { AuthClient, LoginOptions } from \"../../types/auth-client\";\nimport type { GhostlySession } from \"../../types/ghostly-session\";\nimport { AuthContext } from \"./auth-context\";\n\nconst initialLoadingState = true;\n\nfunction toAuthError(error: unknown): AuthSdkError {\n if (error instanceof AuthSdkError) {\n return error;\n }\n\n return new AuthSdkError({\n code: \"api_error\",\n details: error,\n message: \"Unexpected auth adapter error.\",\n status: null,\n });\n}\n\nfunction createDeferredAuthClient(): AuthClient {\n let authClient: AuthClient | null = null;\n\n const resolveClient = (): AuthClient => {\n authClient ??= createAuthClient();\n return authClient;\n };\n\n return {\n completeCallbackRedirect() {\n return resolveClient().completeCallbackRedirect();\n },\n getSession(options) {\n return resolveClient().getSession(options);\n },\n login(options?: LoginOptions) {\n resolveClient().login(options);\n },\n logout() {\n return resolveClient().logout();\n },\n processCallback() {\n return resolveClient().processCallback();\n },\n requireSession() {\n return resolveClient().requireSession();\n },\n subscribe(listener) {\n if (typeof window === \"undefined\") {\n return () => {};\n }\n\n return resolveClient().subscribe(listener);\n },\n };\n}\n\nexport interface AuthProviderProps {\n children: ReactNode;\n client?: AuthClient;\n}\n\nexport function AuthProvider(props: AuthProviderProps) {\n const authClient = useMemo(() => props.client ?? createDeferredAuthClient(), [props.client]);\n const [session, setSession] = useState<GhostlySession | null>(null);\n const [error, setError] = useState<AuthSdkError | null>(null);\n const [isLoading, setIsLoading] = useState<boolean>(initialLoadingState);\n\n useEffect(() => {\n let isActive = true;\n\n const unsubscribe = authClient.subscribe((nextSession) => {\n if (!isActive) {\n return;\n }\n\n setSession(nextSession);\n setIsLoading(false);\n });\n\n void authClient\n .getSession()\n .then((nextSession) => {\n if (!isActive) {\n return;\n }\n\n setSession(nextSession);\n })\n .catch((caughtError: unknown) => {\n if (!isActive) {\n return;\n }\n\n setError(toAuthError(caughtError));\n })\n .finally(() => {\n if (!isActive) {\n return;\n }\n\n setIsLoading(false);\n });\n\n return () => {\n isActive = false;\n unsubscribe();\n };\n }, [authClient]);\n\n const login = useCallback(\n (options?: LoginOptions) => {\n setError(null);\n authClient.login(options);\n },\n [authClient],\n );\n\n const logout = useCallback(async () => {\n setError(null);\n\n try {\n await authClient.logout();\n setSession(null);\n } catch (caughtError) {\n const normalizedError = toAuthError(caughtError);\n setError(normalizedError);\n throw normalizedError;\n }\n }, [authClient]);\n\n const refresh = useCallback(async () => {\n setError(null);\n\n try {\n const nextSession = await authClient.getSession({ forceRefresh: true });\n setSession(nextSession);\n return nextSession;\n } catch (caughtError) {\n const normalizedError = toAuthError(caughtError);\n setError(normalizedError);\n throw normalizedError;\n }\n }, [authClient]);\n\n const contextValue = useMemo(\n () => ({\n error,\n isLoading,\n login,\n logout,\n refresh,\n session,\n }),\n [error, isLoading, login, logout, refresh, session],\n );\n\n return <AuthContext.Provider value={contextValue}>{props.children}</AuthContext.Provider>;\n}\n","\"use client\";\n\nimport { useContext } from \"react\";\nimport { AuthContext } from \"./auth-context\";\n\nconst missingProviderErrorMessage = \"useAuth must be used inside AuthProvider.\";\n\nexport function useAuth() {\n const context = useContext(AuthContext);\n\n if (context) {\n return context;\n }\n\n throw new Error(missingProviderErrorMessage);\n}\n","\"use client\";\n\nimport type { ReactNode } from \"react\";\nimport type { LoginOptions } from \"../../types/auth-client\";\nimport type { GhostlySession } from \"../../types/ghostly-session\";\nimport { useAuth } from \"./use-auth\";\n\ninterface UnauthorizedRenderProps {\n login: (options?: LoginOptions) => void;\n}\n\nexport interface AuthSessionGateProps {\n authorized: (session: GhostlySession) => ReactNode;\n loading?: ReactNode;\n unauthorized: ReactNode | ((props: UnauthorizedRenderProps) => ReactNode);\n}\n\nfunction resolveUnauthorizedContent(\n input: AuthSessionGateProps[\"unauthorized\"],\n props: UnauthorizedRenderProps,\n): ReactNode {\n if (typeof input === \"function\") {\n return input(props);\n }\n\n return input;\n}\n\nexport function AuthSessionGate(props: AuthSessionGateProps) {\n const auth = useAuth();\n\n if (auth.isLoading) {\n return <>{props.loading ?? null}</>;\n }\n\n if (!auth.session) {\n return (\n <>\n {resolveUnauthorizedContent(props.unauthorized, {\n login: auth.login,\n })}\n </>\n );\n }\n\n return <>{props.authorized(auth.session)}</>;\n}\n"]}
1
+ {"version":3,"sources":["../src/constants/auth-endpoints.ts","../src/constants/http-status.ts","../src/errors/auth-sdk-error.ts","../src/types/auth-error-code.ts","../src/core/api-origin.ts","../src/constants/auth-keys.ts","../src/core/object-guards.ts","../src/core/session-parser.ts","../src/core/broadcast-sync.ts","../src/core/http-client.ts","../src/core/runtime.ts","../src/core/return-to-storage.ts","../src/core/session-store.ts","../src/core/auth-client.ts","../src/adapters/react/auth-context.tsx","../src/adapters/react/auth-provider.tsx","../src/adapters/react/use-auth.ts","../src/adapters/react/auth-session-gate.tsx"],"names":["jsx"],"mappings":"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","file":"react.js","sourcesContent":["const authApiPrefix = \"/oauth\";\n\nexport const authEndpoints = {\n authorize: `${authApiPrefix}/authorize`,\n providerCallback: `${authApiPrefix}/callback/provider`,\n session: `${authApiPrefix}/session`,\n refresh: `${authApiPrefix}/refresh`,\n logout: `${authApiPrefix}/logout`,\n} as const;\n","export const httpStatus = {\n ok: 200,\n found: 302,\n noContent: 204,\n badRequest: 400,\n unauthorized: 401,\n} as const;\n","import type { AuthErrorCode } from \"../types/auth-error-code\";\n\nexport interface AuthSdkErrorPayload {\n code: AuthErrorCode;\n details: unknown;\n message: string;\n status: number | null;\n}\n\nexport class AuthSdkError extends Error {\n readonly code: AuthErrorCode;\n readonly details: unknown;\n readonly status: number | null;\n\n constructor(payload: AuthSdkErrorPayload) {\n super(payload.message);\n this.name = \"AuthSdkError\";\n this.code = payload.code;\n this.details = payload.details;\n this.status = payload.status;\n }\n}\n","export const authErrorCode = {\n unauthorized: \"unauthorized\",\n networkError: \"network_error\",\n apiError: \"api_error\",\n broadcastChannelUnsupported: \"broadcast_channel_unsupported\",\n serverOriginResolutionFailed: \"server_origin_resolution_failed\",\n} as const;\n\nexport type AuthErrorCode = (typeof authErrorCode)[keyof typeof authErrorCode];\n","import { AuthSdkError } from \"../errors/auth-sdk-error\";\nimport { authErrorCode } from \"../types/auth-error-code\";\n\nconst slash = \"/\";\n\nfunction normalizeApiOrigin(apiOrigin: string): string {\n const trimmed = apiOrigin.trim();\n\n if (!trimmed) {\n throw new AuthSdkError({\n code: authErrorCode.apiError,\n details: null,\n message: \"Auth API origin must be a non-empty absolute URL.\",\n status: null,\n });\n }\n\n let parsed: URL;\n\n try {\n parsed = new URL(trimmed);\n } catch (error) {\n throw new AuthSdkError({\n code: authErrorCode.apiError,\n details: error,\n message: \"Auth API origin must be a valid absolute URL.\",\n status: null,\n });\n }\n\n if (parsed.pathname !== slash || parsed.search || parsed.hash) {\n throw new AuthSdkError({\n code: authErrorCode.apiError,\n details: null,\n message: \"Auth API origin must not include path, query, or hash.\",\n status: null,\n });\n }\n\n return parsed.origin;\n}\n\nexport function resolveApiEndpoint(path: string, apiOrigin?: string): string {\n if (!apiOrigin) {\n return path;\n }\n\n return `${normalizeApiOrigin(apiOrigin)}${path}`;\n}\n","export const authBroadcast = {\n channelName: \"ghostly-auth-channel\",\n sessionUpdatedEvent: \"session-updated\",\n} as const;\n\nexport const authRoutes = {\n root: \"/\",\n} as const;\n","export function isObjectRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === \"object\" && value !== null;\n}\n\nexport function isStringValue(value: unknown): value is string {\n return typeof value === \"string\";\n}\n","import type { GhostlySession } from \"../types/ghostly-session\";\nimport { isObjectRecord, isStringValue } from \"./object-guards\";\n\nexport function isStringArray(value: unknown): value is string[] {\n return Array.isArray(value) && value.every((entry) => isStringValue(entry));\n}\n\nexport function isGhostlySession(value: unknown): value is GhostlySession {\n if (!isObjectRecord(value)) {\n return false;\n }\n\n return (\n isStringValue(value.id) &&\n isStringValue(value.username) &&\n (value.firstName === null || isStringValue(value.firstName)) &&\n (value.lastName === null || isStringValue(value.lastName)) &&\n isStringValue(value.email) &&\n isStringValue(value.role) &&\n isStringArray(value.permissions)\n );\n}\n","import { authBroadcast } from \"../constants/auth-keys\";\nimport { AuthSdkError } from \"../errors/auth-sdk-error\";\nimport { authErrorCode } from \"../types/auth-error-code\";\nimport type { GhostlySession } from \"../types/ghostly-session\";\nimport { isObjectRecord, isStringValue } from \"./object-guards\";\nimport { isGhostlySession } from \"./session-parser\";\n\ninterface SessionUpdatedMessage {\n session: GhostlySession | null;\n type: typeof authBroadcast.sessionUpdatedEvent;\n}\n\nexport interface BroadcastSync {\n close(): void;\n publishSession(session: GhostlySession | null): void;\n}\n\ninterface CreateBroadcastSyncOptions {\n onSessionUpdated: (session: GhostlySession | null) => void;\n}\n\nfunction isSessionUpdatedMessage(value: unknown): value is SessionUpdatedMessage {\n if (!isObjectRecord(value)) {\n return false;\n }\n\n if (!isStringValue(value.type)) {\n return false;\n }\n\n if (value.type !== authBroadcast.sessionUpdatedEvent) {\n return false;\n }\n\n return value.session === null || isGhostlySession(value.session);\n}\n\nfunction createUnsupportedBroadcastChannelError(): AuthSdkError {\n return new AuthSdkError({\n code: authErrorCode.broadcastChannelUnsupported,\n details: null,\n message: \"BroadcastChannel is unavailable in this runtime.\",\n status: null,\n });\n}\n\nexport function createBroadcastSync(options: CreateBroadcastSyncOptions): BroadcastSync {\n if (typeof BroadcastChannel === \"undefined\") {\n throw createUnsupportedBroadcastChannelError();\n }\n\n const channel = new BroadcastChannel(authBroadcast.channelName);\n\n const onMessage: EventListener = (event) => {\n const messageEvent = event as MessageEvent<unknown>;\n\n if (!isSessionUpdatedMessage(messageEvent.data)) {\n return;\n }\n\n options.onSessionUpdated(messageEvent.data.session);\n };\n\n channel.addEventListener(\"message\", onMessage);\n\n return {\n close() {\n channel.removeEventListener(\"message\", onMessage);\n channel.close();\n },\n publishSession(session) {\n const payload: SessionUpdatedMessage = {\n session,\n type: authBroadcast.sessionUpdatedEvent,\n };\n\n channel.postMessage(payload);\n },\n };\n}\n","import { httpStatus } from \"../constants/http-status\";\nimport { AuthSdkError } from \"../errors/auth-sdk-error\";\nimport { authErrorCode } from \"../types/auth-error-code\";\nimport { isObjectRecord, isStringValue } from \"./object-guards\";\n\nconst jsonContentType = \"application/json\";\nconst jsonHeaderName = \"content-type\";\nconst includeCredentials: RequestCredentials = \"include\";\nconst noStoreCache: RequestCache = \"no-store\";\n\ninterface RequestOptions<TBody> {\n body?: TBody;\n expectedStatus?: number;\n method: \"GET\" | \"POST\";\n path: string;\n}\n\ninterface ParsedErrorPayload {\n code: string | null;\n details: unknown;\n message: string | null;\n}\n\nfunction toTypedValue<TValue>(value: unknown): TValue {\n return value as TValue;\n}\n\nfunction mapHttpStatusToAuthErrorCode(status: number) {\n if (status === httpStatus.unauthorized) {\n return authErrorCode.unauthorized;\n }\n\n return authErrorCode.apiError;\n}\n\nasync function parseJsonPayload(response: Response): Promise<unknown> {\n try {\n return await response.json();\n } catch {\n return null;\n }\n}\n\nasync function parseErrorPayload(response: Response): Promise<ParsedErrorPayload> {\n const payload = await parseJsonPayload(response);\n\n if (!isObjectRecord(payload)) {\n return {\n code: null,\n details: null,\n message: null,\n };\n }\n\n const maybeCode = payload.code;\n const maybeMessage = payload.message;\n\n return {\n code: isStringValue(maybeCode) ? maybeCode : null,\n details: \"details\" in payload ? payload.details : null,\n message: isStringValue(maybeMessage) ? maybeMessage : null,\n };\n}\n\nfunction buildApiErrorMessage(method: RequestOptions<unknown>[\"method\"], path: string): string {\n return `Auth API request failed: ${method} ${path}`;\n}\n\nfunction buildNetworkErrorMessage(method: RequestOptions<unknown>[\"method\"], path: string): string {\n return `Auth API network failure: ${method} ${path}`;\n}\n\nasync function request<TResponse, TBody = undefined>(\n options: RequestOptions<TBody>,\n): Promise<TResponse> {\n const expectedStatus = options.expectedStatus ?? httpStatus.ok;\n const headers = new Headers();\n const hasBody = typeof options.body !== \"undefined\";\n\n if (hasBody) {\n headers.set(jsonHeaderName, jsonContentType);\n }\n\n const requestInit: RequestInit = {\n cache: noStoreCache,\n credentials: includeCredentials,\n headers,\n method: options.method,\n };\n\n if (hasBody) {\n requestInit.body = JSON.stringify(options.body);\n }\n\n let response: Response;\n\n try {\n response = await fetch(options.path, requestInit);\n } catch (error) {\n throw new AuthSdkError({\n code: authErrorCode.networkError,\n details: error,\n message: buildNetworkErrorMessage(options.method, options.path),\n status: null,\n });\n }\n\n if (response.status !== expectedStatus) {\n const parsed = await parseErrorPayload(response);\n\n throw new AuthSdkError({\n code: mapHttpStatusToAuthErrorCode(response.status),\n details: {\n apiCode: parsed.code,\n apiDetails: parsed.details,\n },\n message: parsed.message ?? buildApiErrorMessage(options.method, options.path),\n status: response.status,\n });\n }\n\n if (response.status === httpStatus.noContent) {\n return toTypedValue<TResponse>(null);\n }\n\n const payload = await parseJsonPayload(response);\n return toTypedValue<TResponse>(payload);\n}\n\nexport function getJson<TResponse>(path: string): Promise<TResponse> {\n return request<TResponse>({\n method: \"GET\",\n path,\n });\n}\n\nexport function postJson<TResponse, TBody>(path: string, body: TBody): Promise<TResponse> {\n return request<TResponse, TBody>({\n body,\n method: \"POST\",\n path,\n });\n}\n\nexport function postJsonWithoutBody<TResponse>(path: string): Promise<TResponse> {\n return request<TResponse>({\n method: \"POST\",\n path,\n });\n}\n\nexport function postEmpty(path: string): Promise<null> {\n return request<null>({\n expectedStatus: httpStatus.noContent,\n method: \"POST\",\n path,\n });\n}\n","import { AuthSdkError } from \"../errors/auth-sdk-error\";\nimport { authErrorCode } from \"../types/auth-error-code\";\n\nconst browserRuntimeErrorMessage = \"Browser runtime is required for this auth operation.\";\n\nexport function isBrowserRuntime(): boolean {\n return typeof window !== \"undefined\";\n}\n\nexport function assertBrowserRuntime(): void {\n if (isBrowserRuntime()) {\n return;\n }\n\n throw new AuthSdkError({\n code: authErrorCode.apiError,\n details: null,\n message: browserRuntimeErrorMessage,\n status: null,\n });\n}\n","import { authRoutes } from \"../constants/auth-keys\";\nimport { assertBrowserRuntime } from \"./runtime\";\n\nfunction sanitizeReturnTo(value: string | null | undefined): string {\n if (!value) {\n return authRoutes.root;\n }\n\n if (!value.startsWith(authRoutes.root)) {\n return authRoutes.root;\n }\n\n const protocolRelativePrefix = \"//\";\n\n if (value.startsWith(protocolRelativePrefix)) {\n return authRoutes.root;\n }\n\n return value;\n}\n\nfunction getCurrentBrowserPath(): string {\n return `${window.location.pathname}${window.location.search}${window.location.hash}`;\n}\n\nexport function resolveReturnToPath(returnTo: string | undefined): string {\n assertBrowserRuntime();\n\n const fallbackPath = getCurrentBrowserPath();\n return sanitizeReturnTo(returnTo ?? fallbackPath);\n}\n","import type { SessionListener } from \"../types/auth-client\";\nimport type { GhostlySession } from \"../types/ghostly-session\";\n\ntype SessionResolveState = \"pending\" | \"resolved\";\n\nexport class SessionStore {\n private listeners = new Set<SessionListener>();\n private resolvedSession: GhostlySession | null = null;\n private resolveState: SessionResolveState = \"pending\";\n\n getSessionIfResolved(): GhostlySession | null {\n if (this.resolveState === \"pending\") {\n return null;\n }\n\n return this.resolvedSession;\n }\n\n hasResolvedSession(): boolean {\n return this.resolveState === \"resolved\";\n }\n\n setSession(session: GhostlySession | null): void {\n this.resolveState = \"resolved\";\n this.resolvedSession = session;\n\n for (const listener of this.listeners) {\n listener(session);\n }\n }\n\n subscribe(listener: SessionListener): () => void {\n this.listeners.add(listener);\n\n return () => {\n this.listeners.delete(listener);\n };\n }\n}\n","import { authEndpoints } from \"../constants/auth-endpoints\";\nimport { httpStatus } from \"../constants/http-status\";\nimport { AuthSdkError } from \"../errors/auth-sdk-error\";\nimport type {\n AuthClient,\n AuthClientOptions,\n AuthInitOptions,\n AuthInitResult,\n LoginOptions,\n SessionRequestOptions,\n} from \"../types/auth-client\";\nimport { authErrorCode } from \"../types/auth-error-code\";\nimport type { GhostlySession } from \"../types/ghostly-session\";\nimport { resolveApiEndpoint } from \"./api-origin\";\nimport type { BroadcastSync } from \"./broadcast-sync\";\nimport { createBroadcastSync } from \"./broadcast-sync\";\nimport { getJson, postEmpty, postJsonWithoutBody } from \"./http-client\";\nimport { resolveReturnToPath } from \"./return-to-storage\";\nimport { isGhostlySession } from \"./session-parser\";\nimport { SessionStore } from \"./session-store\";\n\nfunction createInvalidSessionPayloadError(path: string): AuthSdkError {\n return new AuthSdkError({\n code: authErrorCode.apiError,\n details: null,\n message: `Auth API response has invalid session shape: ${path}`,\n status: null,\n });\n}\n\nfunction toValidatedSession(payload: unknown, path: string): GhostlySession {\n if (!isGhostlySession(payload)) {\n throw createInvalidSessionPayloadError(path);\n }\n\n return payload;\n}\n\nfunction toSessionPayload(payload: unknown, path: string): GhostlySession | null {\n if (payload === null) {\n return null;\n }\n\n return toValidatedSession(payload, path);\n}\n\nfunction createNoopBroadcastSync(): BroadcastSync {\n return {\n close() {},\n publishSession() {},\n };\n}\n\nfunction createSafeBroadcastSync(\n onSessionUpdated: (session: GhostlySession | null) => void,\n): BroadcastSync {\n try {\n return createBroadcastSync({\n onSessionUpdated,\n });\n } catch (error) {\n if (error instanceof AuthSdkError && error.code === authErrorCode.broadcastChannelUnsupported) {\n return createNoopBroadcastSync();\n }\n\n throw error;\n }\n}\n\nfunction toInitResult(session: GhostlySession | null): AuthInitResult {\n return {\n session,\n status: session ? \"authenticated\" : \"unauthenticated\",\n };\n}\n\nexport function createAuthClient(options: AuthClientOptions = {}): AuthClient {\n let initPromise: Promise<AuthInitResult> | null = null;\n const defaultApplication = options.application?.trim() || \"\";\n\n const sessionStore = new SessionStore();\n const broadcastSync = createSafeBroadcastSync((session) => {\n sessionStore.setSession(session);\n });\n\n const resolveEndpoint = (path: string): string => resolveApiEndpoint(path, options.apiOrigin);\n\n const loadSession = async (): Promise<GhostlySession | null> => {\n const payload = await getJson<unknown>(resolveEndpoint(authEndpoints.session));\n return toSessionPayload(payload, authEndpoints.session);\n };\n\n const init = async (initOptions?: AuthInitOptions): Promise<AuthInitResult> => {\n const forceRefresh = initOptions?.forceRefresh ?? false;\n\n if (sessionStore.hasResolvedSession() && !forceRefresh) {\n return toInitResult(sessionStore.getSessionIfResolved());\n }\n\n if (initPromise) {\n return initPromise;\n }\n\n initPromise = (async () => {\n const session = await loadSession();\n sessionStore.setSession(session);\n broadcastSync.publishSession(session);\n return toInitResult(session);\n })();\n\n try {\n return await initPromise;\n } finally {\n initPromise = null;\n }\n };\n\n const getSession = async (\n requestOptions?: SessionRequestOptions,\n ): Promise<GhostlySession | null> => {\n const result = await init({\n forceRefresh: requestOptions?.forceRefresh ?? false,\n });\n\n return result.session;\n };\n\n const refresh = async (): Promise<GhostlySession | null> => {\n const payload = await postJsonWithoutBody<unknown>(resolveEndpoint(authEndpoints.refresh));\n const session = toSessionPayload(payload, authEndpoints.refresh);\n sessionStore.setSession(session);\n broadcastSync.publishSession(session);\n return session;\n };\n\n const requireSession = async (): Promise<GhostlySession> => {\n const session = await getSession();\n\n if (session) {\n return session;\n }\n\n throw new AuthSdkError({\n code: authErrorCode.unauthorized,\n details: null,\n message: \"Authenticated session is required.\",\n status: httpStatus.unauthorized,\n });\n };\n\n const login = (loginOptions?: LoginOptions): void => {\n const returnTo = resolveReturnToPath(loginOptions?.returnTo);\n const authorizeUrl = new URL(resolveEndpoint(authEndpoints.authorize), window.location.origin);\n authorizeUrl.searchParams.set(\"return_to\", returnTo);\n const application = loginOptions?.application?.trim() || defaultApplication;\n if (application) {\n authorizeUrl.searchParams.set(\"app\", application);\n }\n window.location.assign(authorizeUrl.toString());\n };\n\n const logout = async (): Promise<void> => {\n await postEmpty(resolveEndpoint(authEndpoints.logout));\n sessionStore.setSession(null);\n broadcastSync.publishSession(null);\n };\n\n const subscribe = sessionStore.subscribe.bind(sessionStore);\n\n return {\n init,\n getSession,\n login,\n logout,\n refresh,\n requireSession,\n subscribe,\n };\n}\n","\"use client\";\n\nimport { createContext } from \"react\";\nimport type { AuthSdkError } from \"../../errors/auth-sdk-error\";\nimport type { LoginOptions } from \"../../types/auth-client\";\nimport type { GhostlySession } from \"../../types/ghostly-session\";\n\nexport interface AuthContextValue {\n error: AuthSdkError | null;\n isLoading: boolean;\n login: (options?: LoginOptions) => void;\n logout: () => Promise<void>;\n refresh: () => Promise<GhostlySession | null>;\n session: GhostlySession | null;\n}\n\nexport const AuthContext = createContext<AuthContextValue | null>(null);\n","\"use client\";\n\nimport { type ReactNode, useCallback, useEffect, useMemo, useState } from \"react\";\nimport { createAuthClient } from \"../../core/auth-client\";\nimport { AuthSdkError } from \"../../errors/auth-sdk-error\";\nimport type { AuthClient, LoginOptions } from \"../../types/auth-client\";\nimport type { GhostlySession } from \"../../types/ghostly-session\";\nimport { AuthContext } from \"./auth-context\";\n\nconst initialLoadingState = true;\n\nfunction toAuthError(error: unknown): AuthSdkError {\n if (error instanceof AuthSdkError) {\n return error;\n }\n\n return new AuthSdkError({\n code: \"api_error\",\n details: error,\n message: \"Unexpected auth adapter error.\",\n status: null,\n });\n}\n\nfunction createDeferredAuthClient(): AuthClient {\n let authClient: AuthClient | null = null;\n\n const resolveClient = (): AuthClient => {\n authClient ??= createAuthClient();\n return authClient;\n };\n\n return {\n init(options) {\n return resolveClient().init(options);\n },\n getSession(options) {\n return resolveClient().getSession(options);\n },\n login(options?: LoginOptions) {\n resolveClient().login(options);\n },\n logout() {\n return resolveClient().logout();\n },\n refresh() {\n return resolveClient().refresh();\n },\n requireSession() {\n return resolveClient().requireSession();\n },\n subscribe(listener) {\n if (typeof window === \"undefined\") {\n return () => {};\n }\n\n return resolveClient().subscribe(listener);\n },\n };\n}\n\nexport interface AuthProviderProps {\n children: ReactNode;\n client?: AuthClient;\n initialSession?: GhostlySession | null;\n}\n\nexport function AuthProvider(props: AuthProviderProps) {\n const authClient = useMemo(() => props.client ?? createDeferredAuthClient(), [props.client]);\n const [session, setSession] = useState<GhostlySession | null>(props.initialSession ?? null);\n const [error, setError] = useState<AuthSdkError | null>(null);\n const [isLoading, setIsLoading] = useState<boolean>(\n props.initialSession === undefined ? initialLoadingState : false,\n );\n\n useEffect(() => {\n let isActive = true;\n const requiresBootstrap = props.initialSession === undefined;\n\n if (!requiresBootstrap) {\n setSession(props.initialSession ?? null);\n setIsLoading(false);\n }\n\n const unsubscribe = authClient.subscribe((nextSession) => {\n if (!isActive) {\n return;\n }\n\n setSession(nextSession);\n });\n\n if (!requiresBootstrap) {\n return () => {\n isActive = false;\n unsubscribe();\n };\n }\n\n void authClient\n .init()\n .then((result) => {\n if (!isActive) {\n return;\n }\n\n setSession(result.session);\n })\n .catch((caughtError: unknown) => {\n if (!isActive) {\n return;\n }\n\n setError(toAuthError(caughtError));\n })\n .finally(() => {\n if (!isActive) {\n return;\n }\n\n setIsLoading(false);\n });\n\n return () => {\n isActive = false;\n unsubscribe();\n };\n }, [authClient, props.initialSession]);\n\n const login = useCallback(\n (options?: LoginOptions) => {\n setError(null);\n authClient.login(options);\n },\n [authClient],\n );\n\n const logout = useCallback(async () => {\n setError(null);\n\n try {\n await authClient.logout();\n setSession(null);\n } catch (caughtError) {\n const normalizedError = toAuthError(caughtError);\n setError(normalizedError);\n throw normalizedError;\n }\n }, [authClient]);\n\n const refresh = useCallback(async () => {\n setError(null);\n\n try {\n const nextSession = await authClient.refresh();\n setSession(nextSession);\n return nextSession;\n } catch (caughtError) {\n const normalizedError = toAuthError(caughtError);\n setError(normalizedError);\n throw normalizedError;\n }\n }, [authClient]);\n\n const contextValue = useMemo(\n () => ({\n error,\n isLoading,\n login,\n logout,\n refresh,\n session,\n }),\n [error, isLoading, login, logout, refresh, session],\n );\n\n return <AuthContext.Provider value={contextValue}>{props.children}</AuthContext.Provider>;\n}\n","\"use client\";\n\nimport { useContext } from \"react\";\nimport { AuthContext } from \"./auth-context\";\n\nconst missingProviderErrorMessage = \"useAuth must be used inside AuthProvider.\";\n\nexport function useAuth() {\n const context = useContext(AuthContext);\n\n if (context) {\n return context;\n }\n\n throw new Error(missingProviderErrorMessage);\n}\n","\"use client\";\n\nimport type { ReactNode } from \"react\";\nimport type { LoginOptions } from \"../../types/auth-client\";\nimport type { GhostlySession } from \"../../types/ghostly-session\";\nimport { useAuth } from \"./use-auth\";\n\ninterface UnauthorizedRenderProps {\n login: (options?: LoginOptions) => void;\n}\n\nexport interface AuthSessionGateProps {\n authorized: (session: GhostlySession) => ReactNode;\n loading?: ReactNode;\n unauthorized: ReactNode | ((props: UnauthorizedRenderProps) => ReactNode);\n}\n\nfunction resolveUnauthorizedContent(\n input: AuthSessionGateProps[\"unauthorized\"],\n props: UnauthorizedRenderProps,\n): ReactNode {\n if (typeof input === \"function\") {\n return input(props);\n }\n\n return input;\n}\n\nexport function AuthSessionGate(props: AuthSessionGateProps) {\n const auth = useAuth();\n\n if (auth.isLoading) {\n return <>{props.loading ?? null}</>;\n }\n\n if (!auth.session) {\n return (\n <>\n {resolveUnauthorizedContent(props.unauthorized, {\n login: auth.login,\n })}\n </>\n );\n }\n\n return <>{props.authorized(auth.session)}</>;\n}\n"]}
@@ -15,131 +15,107 @@ export interface GhostlySession {
15
15
  ```
16
16
 
17
17
  ```ts
18
- export interface KeycloakValidateRequest {
19
- token: string;
18
+ export interface AuthClientOptions {
19
+ apiOrigin?: string;
20
+ application?: string;
20
21
  }
21
22
 
22
- export interface KeycloakValidateResponse {
23
- session: GhostlySession;
23
+ export interface AuthInitOptions {
24
+ forceRefresh?: boolean;
24
25
  }
25
26
 
26
- export interface AuthErrorPayload {
27
- code: string;
28
- message: string;
29
- details: unknown;
27
+ export interface AuthInitResult {
28
+ session: GhostlySession | null;
29
+ status: "authenticated" | "unauthenticated";
30
30
  }
31
- ```
32
31
 
33
- ```ts
34
- export const authErrorCode = {
35
- callbackMissingToken: "callback_missing_token",
36
- callbackInvalidToken: "callback_invalid_token",
37
- callbackValidationFailed: "callback_validation_failed",
38
- unauthorized: "unauthorized",
39
- networkError: "network_error",
40
- apiError: "api_error",
41
- broadcastChannelUnsupported: "broadcast_channel_unsupported",
42
- serverOriginResolutionFailed: "server_origin_resolution_failed",
43
- } as const;
44
- ```
45
-
46
- ```ts
47
- export class AuthSdkError extends Error {
48
- readonly code: AuthErrorCode;
49
- readonly status: number | null;
50
- readonly details: unknown;
32
+ export interface LoginOptions {
33
+ returnTo?: string;
34
+ application?: string;
51
35
  }
52
36
  ```
53
37
 
54
- ## Core Client
55
-
56
38
  ```ts
57
39
  export interface AuthClient {
58
- login(options?: { returnTo?: string }): void;
59
- processCallback(): Promise<{ session: GhostlySession; redirectTo: string }>;
60
- completeCallbackRedirect(): Promise<never>;
40
+ init(options?: AuthInitOptions): Promise<AuthInitResult>;
61
41
  getSession(options?: { forceRefresh?: boolean }): Promise<GhostlySession | null>;
62
- requireSession(): Promise<GhostlySession>;
42
+ login(options?: LoginOptions): void;
43
+ refresh(): Promise<GhostlySession | null>;
63
44
  logout(): Promise<void>;
45
+ requireSession(): Promise<GhostlySession>;
64
46
  subscribe(listener: (session: GhostlySession | null) => void): () => void;
65
47
  }
66
48
  ```
67
49
 
68
- ### `createAuthClient()`
69
-
70
- Creates a browser runtime client. Throws `AuthSdkError` when browser requirements are not met.
71
-
72
- ### `login(options?)`
73
-
74
- - Stores `returnTo` in `sessionStorage`.
75
- - Redirects to `GET /v1/auth/keycloak/login`.
76
-
77
- ### `processCallback()`
50
+ ## Core Entry (`@ghostly-solutions/auth`)
78
51
 
79
- - Reads `token` from callback URL query.
80
- - Removes token from URL using `history.replaceState`.
81
- - Sends `POST /v1/auth/keycloak/validate` with `{ token }`.
82
- - Returns `{ session, redirectTo }`.
52
+ - `createAuthClient(options?)`
53
+ - `authEndpoints`
54
+ - `authRoutes`
55
+ - `authErrorCode`
56
+ - `AuthSdkError`
83
57
 
84
- ### `completeCallbackRedirect()`
58
+ `createAuthClient()` must run in browser runtime.
85
59
 
86
- Processes callback and performs `location.replace(redirectTo)`.
60
+ ## React Entry (`@ghostly-solutions/auth/react`)
87
61
 
88
- ### `getSession(options?)`
89
-
90
- - Lazy by default: returns cached resolved session.
91
- - With `forceRefresh: true`: re-fetches `GET /v1/auth/me`.
92
-
93
- ### `requireSession()`
94
-
95
- Returns session or throws `AuthSdkError` with `code = "unauthorized"`.
96
-
97
- ### `logout()`
98
-
99
- Calls `POST /v1/auth/logout`, clears session state, and broadcasts update.
100
-
101
- ### `subscribe(listener)`
62
+ - `AuthProvider`
63
+ - `AuthSessionGate`
64
+ - `useAuth`
102
65
 
103
- Subscribes to in-memory session updates for the current tab.
66
+ `AuthProvider` props:
104
67
 
105
- ## React Adapter
68
+ - `children: ReactNode`
69
+ - `client?: AuthClient`
70
+ - `initialSession?: GhostlySession | null`
106
71
 
107
- Entry: `@ghostly-solutions/auth/react`
72
+ `initialSession` semantics:
108
73
 
109
- - `AuthProvider`
110
- - `useAuth`
111
- - `AuthCallbackHandler`
112
- - `useAuthCallbackRedirect`
113
- - `AuthSessionGate`
74
+ - `undefined` => provider bootstraps with `init()` and keeps `isLoading=true` until resolved.
75
+ - `null` => provider starts as resolved unauthenticated (`isLoading=false`).
76
+ - `GhostlySession` => provider starts as resolved authenticated (`isLoading=false`).
114
77
 
115
78
  `useAuth()` returns:
116
79
 
117
- - `session: GhostlySession | null`
118
- - `isLoading: boolean`
119
- - `error: AuthSdkError | null`
120
- - `login(options?)`
80
+ - `session`
81
+ - `isLoading`
82
+ - `error`
83
+ - `login()`
121
84
  - `logout()`
122
85
  - `refresh()`
123
86
 
124
- `useAuthCallbackRedirect()` returns:
125
-
126
- - `status: "processing" | "failed"`
127
- - `error: AuthSdkError | null`
128
-
129
- ## Next Adapter
130
-
131
- Entry: `@ghostly-solutions/auth/next`
87
+ ## Next Entry (`@ghostly-solutions/auth/next`)
132
88
 
133
89
  - `getServerSession(options)`
134
90
  - `requireServerSession(options)`
135
- - `ensureClientAuthenticated(client?)`
136
91
  - `getNextServerSession(options?)`
92
+ - `tryGetNextServerSession(options?)`
137
93
  - `requireNextServerSession(options?)`
138
- - `createNextAuthRouteHandlers(options)`
94
+ - `ensureClientAuthenticated(client?)`
95
+
96
+ ## Extension Entry (`@ghostly-solutions/auth/extension`)
97
+
98
+ - `createExtensionAuthClient(options)`
99
+ - `ExtensionAuthClient.loginWithWebAuthFlow(options?)`
139
100
 
140
- `getServerSession` requires incoming request `Headers` to resolve origin and forward auth headers.
101
+ `ExtensionAuthClient` extends `AuthClient`.
141
102
 
142
- `createNextAuthRouteHandlers` supports:
103
+ ## Errors
143
104
 
144
- - `mode: "mock"`: built-in cookie/session mock contract for `/v1/auth/*`
145
- - `mode: "proxy"`: pass-through to external auth gateway (`proxy.baseUrl`)
105
+ ```ts
106
+ export const authErrorCode = {
107
+ unauthorized: "unauthorized",
108
+ networkError: "network_error",
109
+ apiError: "api_error",
110
+ broadcastChannelUnsupported: "broadcast_channel_unsupported",
111
+ serverOriginResolutionFailed: "server_origin_resolution_failed",
112
+ } as const;
113
+ ```
114
+
115
+ ```ts
116
+ export class AuthSdkError extends Error {
117
+ readonly code: AuthErrorCode;
118
+ readonly status: number | null;
119
+ readonly details: unknown;
120
+ }
121
+ ```
@@ -1,62 +1,44 @@
1
1
  # Architecture
2
2
 
3
- ## Layer Map
3
+ ## Layers
4
4
 
5
- - `src/constants`: fixed external contract values (routes, keys, status constants).
6
- - `src/types`: public and internal type contracts.
7
- - `src/errors`: canonical SDK error model.
8
- - `src/core`: runtime-independent auth behavior and state management.
9
- - `src/adapters/react`: React provider and hook adapter.
10
- - `src/adapters/next`: Next.js server/client integration helpers.
5
+ - `src/constants`: fixed routes and protocol constants.
6
+ - `src/types`: public contracts.
7
+ - `src/errors`: typed SDK errors.
8
+ - `src/core`: browser auth client, state store, transport, broadcast sync.
9
+ - `src/adapters/react`: provider/hook/session gate.
10
+ - `src/adapters/next`: server helpers for Next runtime.
11
+ - `src/adapters/extension`: extension-specific login orchestration.
11
12
 
12
- ## Core Runtime Model
13
+ ## Session Model
13
14
 
14
- ### Session State
15
+ - Session is stored server-side.
16
+ - Browser keeps only `HttpOnly` cookie.
17
+ - SDK keeps in-memory snapshot of `GhostlySession | null`.
18
+ - `BroadcastChannel` syncs updates across tabs.
15
19
 
16
- `SessionStore` keeps the resolved session state in memory.
20
+ ## Request Model
17
21
 
18
- - Initial state: pending.
19
- - Resolved state: `GhostlySession | null`.
20
- - Updates notify subscribers.
21
-
22
- ### HTTP Layer
23
-
24
- `http-client.ts` standardizes API calls:
22
+ Transport defaults:
25
23
 
26
24
  - `credentials: "include"`
27
25
  - `cache: "no-store"`
28
- - normalized error mapping to `AuthSdkError`
29
-
30
- ### Callback Processing
31
-
32
- `auth-client.ts` callback sequence:
33
-
34
- 1. Parse `token` from URL.
35
- 2. Remove `token` from browser URL immediately.
36
- 3. Validate token via API.
37
- 4. Save session in memory.
38
- 5. Resolve `returnTo` and return result.
39
-
40
- ### Cross-tab Sync
41
-
42
- `broadcast-sync.ts` sends `session-updated` events through `BroadcastChannel`.
43
-
44
- - Login/session refresh and logout publish updates.
45
- - Other tabs update in-memory state in reaction to events.
46
26
 
47
- ## Security Decisions
27
+ SDK calls:
48
28
 
49
- - No JS-level token persistence.
50
- - Callback token is removed from URL before API validation response handling.
51
- - `returnTo` is sanitized to internal absolute paths only.
52
- - Unauthorized state is explicit and typed.
29
+ - `GET /oauth/session` in `init()` and `getSession({ forceRefresh: true })`
30
+ - `POST /oauth/refresh` in `refresh()`
31
+ - `POST /oauth/logout` in `logout()`
53
32
 
54
- ## Packaging
33
+ ## Redirect Model
55
34
 
56
- The package exposes three entrypoints:
35
+ - `login()` builds `GET /oauth/authorize?return_to=...` and may append logical `app`.
36
+ - `return_to` is sanitized to in-app absolute path (`/path`).
37
+ - OAuth callback processing is server-side; SDK does not process callback token URLs.
57
38
 
58
- - `@ghostly-solutions/auth`
59
- - `@ghostly-solutions/auth/react`
60
- - `@ghostly-solutions/auth/next`
39
+ ## Security Notes
61
40
 
62
- Build output is generated to `dist/` via `tsup` with ESM and declarations.
41
+ - No token persistence in local/session storage.
42
+ - No callback token in browser URL contract.
43
+ - Unauthorized state is explicit (`null` session or typed error).
44
+ - IdP client selection belongs to the auth gateway, not to the SDK.
@@ -5,7 +5,7 @@
5
5
  - Node.js 22+
6
6
  - npm 11+
7
7
 
8
- Bun is optional for local convenience and is not part of CI requirements.
8
+ Bun can be used locally as an optional runner.
9
9
 
10
10
  ## Local Commands
11
11
 
@@ -17,37 +17,33 @@ npm run build
17
17
  npm run check
18
18
  ```
19
19
 
20
- ## Optional Bun Commands
21
-
22
- Optional Bun aliases are defined in `bun.json`.
23
-
24
- Examples:
20
+ Optional Bun shortcuts:
25
21
 
26
22
  ```bash
27
23
  bun run lint
24
+ bun run typecheck
28
25
  bun run test
29
26
  bun run build
30
27
  ```
31
28
 
32
- These are convenience-only wrappers around the npm-first toolchain.
33
-
34
- ## CI (`.gitlab-ci.yml`)
35
-
36
- Pipeline stages:
29
+ ## CI
37
30
 
38
- 1. `validate`: lint and typecheck.
39
- 2. `test`: unit test run.
40
- 3. `build`: package build and `npm pack --dry-run` verification.
31
+ `.gitlab-ci.yml` runs:
41
32
 
42
- Key CI characteristics:
33
+ 1. `lint`
34
+ 2. `typecheck`
35
+ 3. `test`
36
+ 4. `build` + `npm pack --dry-run`
43
37
 
44
- - Uses `node:22-bookworm`.
45
- - Uses `npm ci` with lockfile-based cache.
46
- - Produces `dist/` as build artifact.
38
+ CI image: `node:22-bookworm`.
47
39
 
48
40
  ## Release Checklist
49
41
 
50
42
  1. `npm run check`
51
43
  2. `npm run build`
52
44
  3. `npm pack --dry-run`
53
- 4. Verify `dist/` contains `index`, `react`, and `next` outputs with `.d.ts` files.
45
+ 4. Verify exports in package tarball:
46
+ - `@ghostly-solutions/auth`
47
+ - `@ghostly-solutions/auth/react`
48
+ - `@ghostly-solutions/auth/next`
49
+ - `@ghostly-solutions/auth/extension`
package/docs/index.md CHANGED
@@ -1,22 +1,8 @@
1
1
  # Ghostly Auth SDK Documentation
2
2
 
3
- ## Documents
4
-
5
3
  - [Overview](./overview.md)
6
4
  - [API Reference](./api-reference.md)
7
5
  - [Integration Guide](./integration-guide.md)
8
6
  - [Architecture](./architecture.md)
9
7
  - [Development and CI](./development-and-ci.md)
10
- - [Interactive Demo](../demo/README.md)
11
-
12
- ## Scope
13
-
14
- This SDK provides a fixed authentication flow for Ghostly Solutions products:
15
-
16
- 1. Redirect user to Ghostly API login start endpoint.
17
- 2. Receive JWT on a dedicated callback page.
18
- 3. Validate JWT through Ghostly API.
19
- 4. Resolve and expose a typed session.
20
- 5. Keep tabs synchronized and support logout.
21
-
22
- The SDK intentionally avoids runtime endpoint configuration and fallback logic.
8
+ - [Demo](../demo/README.md)