@ghostly-solutions/auth 0.1.1 → 0.2.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/LICENSE +13 -0
- package/README.md +200 -71
- package/dist/{auth-client-CAHMjodm.d.ts → auth-client-Cdkp07ii.d.ts} +14 -6
- package/dist/{auth-sdk-error-DKM7PyKC.d.ts → auth-sdk-error-D3gsfK9d.d.ts} +0 -3
- package/dist/extension.d.ts +49 -0
- package/dist/extension.js +634 -0
- package/dist/extension.js.map +1 -0
- package/dist/index.d.ts +13 -19
- package/dist/index.js +106 -119
- package/dist/index.js.map +1 -1
- package/dist/next.d.ts +4 -27
- package/dist/next.js +125 -383
- package/dist/next.js.map +1 -1
- package/dist/react.d.ts +4 -20
- package/dist/react.js +129 -176
- package/dist/react.js.map +1 -1
- package/docs/api-reference.md +66 -89
- package/docs/architecture.md +28 -46
- package/docs/development-and-ci.md +15 -19
- package/docs/index.md +1 -15
- package/docs/integration-guide.md +54 -80
- package/docs/overview.md +27 -28
- package/package.json +15 -2
|
@@ -0,0 +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/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/runtime.ts","../src/core/return-to-storage.ts","../src/core/session-store.ts","../src/adapters/extension/auth-client.ts","../src/adapters/extension/chrome-auth-client.ts"],"names":[],"mappings":"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","file":"extension.js","sourcesContent":["const authApiPrefix = \"/oauth\";\n\nexport const authEndpoints = {\n authorize: `${authApiPrefix}/authorize`,\n extensionToken: `${authApiPrefix}/extension/token`,\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 { 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 { resolveApiEndpoint } from \"../../core/api-origin\";\nimport type { BroadcastSync } from \"../../core/broadcast-sync\";\nimport { createBroadcastSync } from \"../../core/broadcast-sync\";\nimport { isObjectRecord, isStringValue } from \"../../core/object-guards\";\nimport { resolveReturnToPath } from \"../../core/return-to-storage\";\nimport { isGhostlySession } from \"../../core/session-parser\";\nimport { SessionStore } from \"../../core/session-store\";\nimport { AuthSdkError } from \"../../errors/auth-sdk-error\";\nimport type {\n AuthClient,\n AuthInitOptions,\n AuthInitResult,\n LoginOptions,\n SessionListener,\n SessionRequestOptions,\n} from \"../../types/auth-client\";\nimport { authErrorCode } from \"../../types/auth-error-code\";\nimport type { GhostlySession } from \"../../types/ghostly-session\";\n\ninterface LaunchWebAuthFlowPayload {\n authorizeUrl: string;\n}\n\ninterface OpenAuthorizePagePayload {\n authorizeUrl: string;\n}\n\ninterface RequestOptions {\n expectedStatus?: number;\n method: \"GET\" | \"POST\";\n path: string;\n}\n\ntype PersistAccessToken = (token: ExtensionStoredAccessToken | null) => Promise<void> | void;\ntype ResolveSessionId = () => Promise<string | null>;\ntype RestoreAccessToken =\n | (() => Promise<ExtensionStoredAccessToken | null>)\n | (() => ExtensionStoredAccessToken | null);\n\nexport interface ExtensionAccessToken {\n accessToken: string;\n application: string;\n expiresAt: string | null;\n session: GhostlySession | null;\n tokenType: string;\n}\n\nexport interface ExtensionAccessTokenRequestOptions {\n forceRefresh?: boolean;\n}\n\nexport interface ExtensionStoredAccessToken extends ExtensionAccessToken {}\n\nexport interface ExtensionAuthClientOptions {\n apiOrigin: string;\n application?: string;\n clearSessionId?: () => Promise<void> | void;\n launchWebAuthFlow?: (payload: LaunchWebAuthFlowPayload) => Promise<void>;\n openAuthorizePage?: (payload: OpenAuthorizePagePayload) => Promise<void>;\n persistAccessToken?: PersistAccessToken;\n resolveSessionId?: ResolveSessionId;\n restoreAccessToken?: RestoreAccessToken;\n}\n\nexport interface ExtensionAuthClient extends AuthClient {\n getAccessToken(\n options?: ExtensionAccessTokenRequestOptions,\n ): Promise<ExtensionAccessToken | null>;\n loginWithTabFlow(options?: LoginOptions): Promise<void>;\n loginWithWebAuthFlow(options?: LoginOptions): Promise<void>;\n}\n\nconst extensionSessionHeader = \"X-Ghostly-Session-Id\";\nconst includeCredentials: RequestCredentials = \"include\";\nconst noStoreCache: RequestCache = \"no-store\";\nconst tokenFreshnessLeewayMs = 60_000;\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 buildApiErrorMessage(method: RequestOptions[\"method\"], path: string): string {\n return `Auth API request failed: ${method} ${path}`;\n}\n\nfunction buildNetworkErrorMessage(method: RequestOptions[\"method\"], path: string): string {\n return `Auth API network failure: ${method} ${path}`;\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 toInitResult(session: GhostlySession | null): AuthInitResult {\n return {\n session,\n status: session ? \"authenticated\" : \"unauthenticated\",\n };\n}\n\nfunction parseSessionPayload(payload: unknown, path: string): GhostlySession | null {\n if (payload === null) {\n return null;\n }\n if (!isGhostlySession(payload)) {\n throw createInvalidSessionPayloadError(path);\n }\n return payload;\n}\n\nfunction isExtensionAccessToken(value: unknown): value is ExtensionAccessToken {\n if (!isObjectRecord(value)) {\n return false;\n }\n\n return (\n isStringValue(value.accessToken) &&\n isStringValue(value.application) &&\n (value.expiresAt === null || isStringValue(value.expiresAt)) &&\n (value.session === null || isGhostlySession(value.session)) &&\n isStringValue(value.tokenType)\n );\n}\n\nfunction isStoredTokenFresh(\n token: ExtensionStoredAccessToken | null,\n): token is ExtensionStoredAccessToken {\n if (!token || !token.accessToken.trim()) {\n return false;\n }\n\n if (!token.expiresAt) {\n return true;\n }\n\n const expiresAt = Date.parse(token.expiresAt);\n if (Number.isNaN(expiresAt)) {\n return false;\n }\n\n return expiresAt - Date.now() > tokenFreshnessLeewayMs;\n}\n\nfunction buildAuthorizeUrl(apiOrigin: string, returnTo: string, application?: string): string {\n const authorizeEndpoint = resolveApiEndpoint(authEndpoints.authorize, apiOrigin);\n const authorizeUrl = new URL(authorizeEndpoint, window.location.origin);\n authorizeUrl.searchParams.set(\"return_to\", returnTo);\n if (application?.trim()) {\n authorizeUrl.searchParams.set(\"app\", application.trim());\n }\n return authorizeUrl.toString();\n}\n\nfunction parseErrorPayload(payload: unknown): { details: unknown; message: string | null } {\n if (!isObjectRecord(payload)) {\n return {\n details: null,\n message: null,\n };\n }\n\n return {\n details: \"details\" in payload ? payload.details : null,\n message: isStringValue(payload.message)\n ? payload.message\n : isStringValue(payload.error)\n ? payload.error\n : null,\n };\n}\n\nfunction createRequest(\n options: ExtensionAuthClientOptions,\n): <TResponse>(requestOptions: RequestOptions) => Promise<TResponse> {\n const resolveEndpoint = (path: string): string => resolveApiEndpoint(path, options.apiOrigin);\n\n return async function request<TResponse>(requestOptions: RequestOptions): Promise<TResponse> {\n const expectedStatus = requestOptions.expectedStatus ?? httpStatus.ok;\n const headers = new Headers();\n const sessionId = (await options.resolveSessionId?.())?.trim() || \"\";\n\n if (sessionId) {\n headers.set(extensionSessionHeader, sessionId);\n }\n\n let response: Response;\n try {\n response = await fetch(resolveEndpoint(requestOptions.path), {\n cache: noStoreCache,\n credentials: includeCredentials,\n headers,\n method: requestOptions.method,\n });\n } catch (error) {\n throw new AuthSdkError({\n code: authErrorCode.networkError,\n details: error,\n message: buildNetworkErrorMessage(requestOptions.method, requestOptions.path),\n status: null,\n });\n }\n\n if (response.status !== expectedStatus) {\n let parsedPayload: unknown = null;\n try {\n parsedPayload = await response.json();\n } catch {\n parsedPayload = null;\n }\n\n const parsed = parseErrorPayload(parsedPayload);\n throw new AuthSdkError({\n code:\n response.status === httpStatus.unauthorized\n ? authErrorCode.unauthorized\n : authErrorCode.apiError,\n details: parsed.details,\n message: parsed.message ?? buildApiErrorMessage(requestOptions.method, requestOptions.path),\n status: response.status,\n });\n }\n\n if (response.status === httpStatus.noContent) {\n return null as TResponse;\n }\n\n return (await response.json()) as TResponse;\n };\n}\n\nfunction createLoadSession(\n request: <TResponse>(requestOptions: RequestOptions) => Promise<TResponse>,\n): () => Promise<GhostlySession | null> {\n return async () => {\n const payload = await request<unknown>({\n method: \"GET\",\n path: authEndpoints.session,\n });\n return parseSessionPayload(payload, authEndpoints.session);\n };\n}\n\nfunction createInit(\n sessionStore: SessionStore,\n loadSession: () => Promise<GhostlySession | null>,\n publishSession: (session: GhostlySession | null) => void,\n): (initOptions?: AuthInitOptions) => Promise<AuthInitResult> {\n let initPromise: Promise<AuthInitResult> | null = null;\n\n return 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 publishSession(session);\n return toInitResult(session);\n })();\n\n try {\n return await initPromise;\n } finally {\n initPromise = null;\n }\n };\n}\n\nfunction createRefresh(\n request: <TResponse>(requestOptions: RequestOptions) => Promise<TResponse>,\n sessionStore: SessionStore,\n publishSession: (session: GhostlySession | null) => void,\n): () => Promise<GhostlySession | null> {\n return async () => {\n const payload = await request<unknown>({\n method: \"POST\",\n path: authEndpoints.refresh,\n });\n const session = parseSessionPayload(payload, authEndpoints.refresh);\n sessionStore.setSession(session);\n publishSession(session);\n return session;\n };\n}\n\nfunction createGetAccessToken(\n request: <TResponse>(requestOptions: RequestOptions) => Promise<TResponse>,\n sessionStore: SessionStore,\n publishSession: (session: GhostlySession | null) => void,\n persistAccessToken?: PersistAccessToken,\n restoreAccessToken?: RestoreAccessToken,\n): (requestOptions?: ExtensionAccessTokenRequestOptions) => Promise<ExtensionAccessToken | null> {\n return async (requestOptions?: ExtensionAccessTokenRequestOptions) => {\n const forceRefresh = requestOptions?.forceRefresh ?? false;\n const stored = (await restoreAccessToken?.()) ?? null;\n if (!forceRefresh && isStoredTokenFresh(stored)) {\n if (stored.session) {\n sessionStore.setSession(stored.session);\n }\n return stored;\n }\n\n const payload = await request<unknown>({\n method: \"GET\",\n path: authEndpoints.extensionToken,\n });\n\n if (!isExtensionAccessToken(payload)) {\n throw new AuthSdkError({\n code: authErrorCode.apiError,\n details: null,\n message: `Auth API response has invalid extension token shape: ${authEndpoints.extensionToken}`,\n status: null,\n });\n }\n\n const nextToken: ExtensionStoredAccessToken = {\n accessToken: payload.accessToken,\n application: payload.application,\n expiresAt: payload.expiresAt,\n session: payload.session,\n tokenType: payload.tokenType,\n };\n\n sessionStore.setSession(nextToken.session);\n publishSession(nextToken.session);\n await persistAccessToken?.(nextToken);\n return nextToken;\n };\n}\n\nfunction createLogout(\n request: <TResponse>(requestOptions: RequestOptions) => Promise<TResponse>,\n sessionStore: SessionStore,\n publishSession: (session: GhostlySession | null) => void,\n options: ExtensionAuthClientOptions,\n): () => Promise<void> {\n return async () => {\n await request<null>({\n expectedStatus: httpStatus.noContent,\n method: \"POST\",\n path: authEndpoints.logout,\n });\n await options.clearSessionId?.();\n sessionStore.setSession(null);\n publishSession(null);\n await options.persistAccessToken?.(null);\n };\n}\n\nexport function createExtensionAuthClient(\n options: ExtensionAuthClientOptions,\n): ExtensionAuthClient {\n const sessionStore = new SessionStore();\n const broadcastSync = createSafeBroadcastSync((session) => {\n sessionStore.setSession(session);\n });\n const publishSession = broadcastSync.publishSession.bind(broadcastSync);\n const request = createRequest(options);\n const loadSession = createLoadSession(request);\n const init = createInit(sessionStore, loadSession, publishSession);\n const refresh = createRefresh(request, sessionStore, publishSession);\n const getAccessToken = createGetAccessToken(\n request,\n sessionStore,\n publishSession,\n options.persistAccessToken,\n options.restoreAccessToken,\n );\n const logout = createLogout(request, sessionStore, publishSession, options);\n\n const getSession = async (\n requestOptions?: SessionRequestOptions,\n ): Promise<GhostlySession | null> => {\n const result = await init({\n forceRefresh: requestOptions?.forceRefresh ?? false,\n });\n return result.session;\n };\n\n const requireSession = async (): Promise<GhostlySession> => {\n const session = await getSession();\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 loginWithTabFlow = async (loginOptions?: LoginOptions): Promise<void> => {\n if (!options.openAuthorizePage) {\n throw new Error(\"Extension auth client requires openAuthorizePage for tab login flow.\");\n }\n\n const returnTo = resolveReturnToPath(loginOptions?.returnTo);\n const authorizeUrl = buildAuthorizeUrl(\n options.apiOrigin,\n returnTo,\n loginOptions?.application ?? options.application,\n );\n\n await options.openAuthorizePage({\n authorizeUrl,\n });\n };\n\n const loginWithWebAuthFlow = async (loginOptions?: LoginOptions): Promise<void> => {\n if (!options.launchWebAuthFlow) {\n throw new Error(\"Extension auth client requires launchWebAuthFlow for web auth flow.\");\n }\n\n const returnTo = resolveReturnToPath(loginOptions?.returnTo);\n const authorizeUrl = buildAuthorizeUrl(\n options.apiOrigin,\n returnTo,\n loginOptions?.application ?? options.application,\n );\n\n await options.launchWebAuthFlow({\n authorizeUrl,\n });\n await refresh();\n };\n\n return {\n init,\n getSession,\n login(loginOptions?: LoginOptions) {\n if (options.openAuthorizePage) {\n void loginWithTabFlow(loginOptions);\n return;\n }\n\n void loginWithWebAuthFlow(loginOptions);\n },\n logout,\n refresh,\n requireSession,\n subscribe(listener: SessionListener) {\n return sessionStore.subscribe(listener);\n },\n getAccessToken,\n loginWithTabFlow,\n loginWithWebAuthFlow,\n };\n}\n","import {\n createExtensionAuthClient,\n type ExtensionAuthClient,\n type ExtensionAuthClientOptions,\n type ExtensionStoredAccessToken,\n} from \"./auth-client\";\n\ninterface ChromeCookiesApi {\n get(details: { name: string; url: string }): Promise<{ value?: string } | null>;\n remove(details: { name: string; url: string }): Promise<unknown>;\n}\n\ninterface ChromeStorageAreaApi {\n get(keys: string[]): Promise<Record<string, unknown>>;\n remove(keys: string[]): Promise<void>;\n set(items: Record<string, unknown>): Promise<void>;\n}\n\ninterface ChromeTabsApi {\n create(details: { active?: boolean; url: string }): Promise<unknown>;\n}\n\ninterface ChromeRuntimeLike {\n cookies?: ChromeCookiesApi;\n storage?: {\n local?: ChromeStorageAreaApi;\n };\n tabs?: ChromeTabsApi;\n}\n\nexport interface ChromeExtensionAuthClientOptions\n extends Omit<\n ExtensionAuthClientOptions,\n | \"clearSessionId\"\n | \"openAuthorizePage\"\n | \"persistAccessToken\"\n | \"resolveSessionId\"\n | \"restoreAccessToken\"\n > {\n accessTokenStorageKey?: string;\n sessionCookieName?: string;\n sessionStorageKey?: string;\n tokenExpiresAtStorageKey?: string;\n}\n\nconst defaultSessionCookieName = \"gs_auth_session\";\nconst defaultAccessTokenStorageKey = \"authToken\";\nconst defaultTokenExpiresAtStorageKey = \"authTokenExpiresAt\";\nconst defaultSessionStorageKey = \"authSession\";\n\nfunction getChromeRuntime(): ChromeRuntimeLike {\n return (globalThis as { chrome?: ChromeRuntimeLike }).chrome ?? {};\n}\n\nexport function createChromeExtensionAuthClient(\n options: ChromeExtensionAuthClientOptions,\n): ExtensionAuthClient {\n const sessionCookieName = options.sessionCookieName?.trim() || defaultSessionCookieName;\n const accessTokenStorageKey =\n options.accessTokenStorageKey?.trim() || defaultAccessTokenStorageKey;\n const tokenExpiresAtStorageKey =\n options.tokenExpiresAtStorageKey?.trim() || defaultTokenExpiresAtStorageKey;\n const sessionStorageKey = options.sessionStorageKey?.trim() || defaultSessionStorageKey;\n\n const resolveSessionId = async (): Promise<string | null> => {\n const cookies = getChromeRuntime().cookies;\n if (!cookies) {\n return null;\n }\n\n const cookie = await cookies.get({\n name: sessionCookieName,\n url: `${options.apiOrigin}/`,\n });\n return cookie?.value?.trim() || null;\n };\n\n const clearSessionId = async (): Promise<void> => {\n const cookies = getChromeRuntime().cookies;\n if (!cookies) {\n return;\n }\n await cookies.remove({\n name: sessionCookieName,\n url: `${options.apiOrigin}/`,\n });\n };\n\n const persistAccessToken = async (token: ExtensionStoredAccessToken | null): Promise<void> => {\n const storage = getChromeRuntime().storage?.local;\n if (!storage) {\n return;\n }\n\n if (!token) {\n await storage.remove([accessTokenStorageKey, tokenExpiresAtStorageKey, sessionStorageKey]);\n return;\n }\n\n await storage.set({\n [accessTokenStorageKey]: token.accessToken,\n [tokenExpiresAtStorageKey]: token.expiresAt || null,\n [sessionStorageKey]: token.session || null,\n });\n };\n\n const restoreAccessToken = async (): Promise<ExtensionStoredAccessToken | null> => {\n const storage = getChromeRuntime().storage?.local;\n if (!storage) {\n return null;\n }\n\n const stored = await storage.get([\n accessTokenStorageKey,\n tokenExpiresAtStorageKey,\n sessionStorageKey,\n ]);\n\n const rawAccessToken = stored[accessTokenStorageKey];\n if (typeof rawAccessToken !== \"string\" || rawAccessToken.trim() === \"\") {\n return null;\n }\n\n return {\n accessToken: rawAccessToken,\n application: options.application?.trim() || \"\",\n expiresAt:\n typeof stored[tokenExpiresAtStorageKey] === \"string\"\n ? stored[tokenExpiresAtStorageKey]\n : null,\n session: (stored[sessionStorageKey] as ExtensionStoredAccessToken[\"session\"]) ?? null,\n tokenType: \"Bearer\",\n };\n };\n\n const openAuthorizePage = async ({ authorizeUrl }: { authorizeUrl: string }): Promise<void> => {\n const tabs = getChromeRuntime().tabs;\n if (!tabs) {\n throw new Error(\"Chrome tabs API is unavailable.\");\n }\n await tabs.create({ active: true, url: authorizeUrl });\n };\n\n return createExtensionAuthClient({\n ...options,\n clearSessionId,\n openAuthorizePage,\n persistAccessToken,\n resolveSessionId,\n restoreAccessToken,\n });\n}\n"]}
|
package/dist/index.d.ts
CHANGED
|
@@ -1,34 +1,28 @@
|
|
|
1
|
-
import { A as AuthClient, G as GhostlySession } from './auth-client-
|
|
2
|
-
export {
|
|
3
|
-
export { A as AuthErrorCode, a as AuthSdkError, b as AuthSdkErrorPayload, c as authErrorCode } from './auth-sdk-error-
|
|
1
|
+
import { a as AuthClientOptions, A as AuthClient, G as GhostlySession } from './auth-client-Cdkp07ii.js';
|
|
2
|
+
export { b as AuthInitOptions, c as AuthInitResult, L as LoginOptions, S as SessionListener, d as SessionRequestOptions } from './auth-client-Cdkp07ii.js';
|
|
3
|
+
export { A as AuthErrorCode, a as AuthSdkError, b as AuthSdkErrorPayload, c as authErrorCode } from './auth-sdk-error-D3gsfK9d.js';
|
|
4
4
|
|
|
5
5
|
declare const authEndpoints: {
|
|
6
|
-
readonly
|
|
7
|
-
readonly
|
|
8
|
-
readonly
|
|
9
|
-
readonly
|
|
6
|
+
readonly authorize: "/oauth/authorize";
|
|
7
|
+
readonly extensionToken: "/oauth/extension/token";
|
|
8
|
+
readonly providerCallback: "/oauth/callback/provider";
|
|
9
|
+
readonly session: "/oauth/session";
|
|
10
|
+
readonly refresh: "/oauth/refresh";
|
|
11
|
+
readonly logout: "/oauth/logout";
|
|
10
12
|
};
|
|
11
13
|
|
|
12
|
-
declare const authQueryKeys: {
|
|
13
|
-
readonly token: "token";
|
|
14
|
-
};
|
|
15
14
|
declare const authRoutes: {
|
|
16
15
|
readonly root: "/";
|
|
17
|
-
readonly callback: "/auth/callback";
|
|
18
16
|
};
|
|
19
17
|
|
|
20
|
-
declare function createAuthClient(): AuthClient;
|
|
18
|
+
declare function createAuthClient(options?: AuthClientOptions): AuthClient;
|
|
21
19
|
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
}
|
|
25
|
-
interface KeycloakValidateResponse {
|
|
26
|
-
session: GhostlySession;
|
|
27
|
-
}
|
|
20
|
+
type OauthSessionResponse = GhostlySession | null;
|
|
21
|
+
type OauthRefreshResponse = GhostlySession | null;
|
|
28
22
|
interface AuthErrorPayload {
|
|
29
23
|
code: string;
|
|
30
24
|
details: unknown;
|
|
31
25
|
message: string;
|
|
32
26
|
}
|
|
33
27
|
|
|
34
|
-
export { AuthClient, type AuthErrorPayload, GhostlySession, type
|
|
28
|
+
export { AuthClient, AuthClientOptions, type AuthErrorPayload, GhostlySession, type OauthRefreshResponse, type OauthSessionResponse, authEndpoints, authRoutes, createAuthClient };
|
package/dist/index.js
CHANGED
|
@@ -1,33 +1,27 @@
|
|
|
1
1
|
// src/constants/auth-endpoints.ts
|
|
2
|
-
var authApiPrefix = "/
|
|
2
|
+
var authApiPrefix = "/oauth";
|
|
3
3
|
var authEndpoints = {
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
4
|
+
authorize: `${authApiPrefix}/authorize`,
|
|
5
|
+
extensionToken: `${authApiPrefix}/extension/token`,
|
|
6
|
+
providerCallback: `${authApiPrefix}/callback/provider`,
|
|
7
|
+
session: `${authApiPrefix}/session`,
|
|
8
|
+
refresh: `${authApiPrefix}/refresh`,
|
|
7
9
|
logout: `${authApiPrefix}/logout`
|
|
8
10
|
};
|
|
9
11
|
|
|
10
12
|
// src/constants/auth-keys.ts
|
|
11
|
-
var authQueryKeys = {
|
|
12
|
-
token: "token"
|
|
13
|
-
};
|
|
14
|
-
var authStorageKeys = {
|
|
15
|
-
returnTo: "ghostly-auth:return-to"
|
|
16
|
-
};
|
|
17
13
|
var authBroadcast = {
|
|
18
14
|
channelName: "ghostly-auth-channel",
|
|
19
15
|
sessionUpdatedEvent: "session-updated"
|
|
20
16
|
};
|
|
21
17
|
var authRoutes = {
|
|
22
|
-
root: "/"
|
|
23
|
-
callback: "/auth/callback"
|
|
18
|
+
root: "/"
|
|
24
19
|
};
|
|
25
20
|
|
|
26
21
|
// src/constants/http-status.ts
|
|
27
22
|
var httpStatus = {
|
|
28
23
|
ok: 200,
|
|
29
24
|
noContent: 204,
|
|
30
|
-
badRequest: 400,
|
|
31
25
|
unauthorized: 401
|
|
32
26
|
};
|
|
33
27
|
|
|
@@ -47,9 +41,6 @@ var AuthSdkError = class extends Error {
|
|
|
47
41
|
|
|
48
42
|
// src/types/auth-error-code.ts
|
|
49
43
|
var authErrorCode = {
|
|
50
|
-
callbackMissingToken: "callback_missing_token",
|
|
51
|
-
callbackInvalidToken: "callback_invalid_token",
|
|
52
|
-
callbackValidationFailed: "callback_validation_failed",
|
|
53
44
|
unauthorized: "unauthorized",
|
|
54
45
|
networkError: "network_error",
|
|
55
46
|
apiError: "api_error",
|
|
@@ -57,6 +48,46 @@ var authErrorCode = {
|
|
|
57
48
|
serverOriginResolutionFailed: "server_origin_resolution_failed"
|
|
58
49
|
};
|
|
59
50
|
|
|
51
|
+
// src/core/api-origin.ts
|
|
52
|
+
var slash = "/";
|
|
53
|
+
function normalizeApiOrigin(apiOrigin) {
|
|
54
|
+
const trimmed = apiOrigin.trim();
|
|
55
|
+
if (!trimmed) {
|
|
56
|
+
throw new AuthSdkError({
|
|
57
|
+
code: authErrorCode.apiError,
|
|
58
|
+
details: null,
|
|
59
|
+
message: "Auth API origin must be a non-empty absolute URL.",
|
|
60
|
+
status: null
|
|
61
|
+
});
|
|
62
|
+
}
|
|
63
|
+
let parsed;
|
|
64
|
+
try {
|
|
65
|
+
parsed = new URL(trimmed);
|
|
66
|
+
} catch (error) {
|
|
67
|
+
throw new AuthSdkError({
|
|
68
|
+
code: authErrorCode.apiError,
|
|
69
|
+
details: error,
|
|
70
|
+
message: "Auth API origin must be a valid absolute URL.",
|
|
71
|
+
status: null
|
|
72
|
+
});
|
|
73
|
+
}
|
|
74
|
+
if (parsed.pathname !== slash || parsed.search || parsed.hash) {
|
|
75
|
+
throw new AuthSdkError({
|
|
76
|
+
code: authErrorCode.apiError,
|
|
77
|
+
details: null,
|
|
78
|
+
message: "Auth API origin must not include path, query, or hash.",
|
|
79
|
+
status: null
|
|
80
|
+
});
|
|
81
|
+
}
|
|
82
|
+
return parsed.origin;
|
|
83
|
+
}
|
|
84
|
+
function resolveApiEndpoint(path, apiOrigin) {
|
|
85
|
+
if (!apiOrigin) {
|
|
86
|
+
return path;
|
|
87
|
+
}
|
|
88
|
+
return `${normalizeApiOrigin(apiOrigin)}${path}`;
|
|
89
|
+
}
|
|
90
|
+
|
|
60
91
|
// src/core/object-guards.ts
|
|
61
92
|
function isObjectRecord(value) {
|
|
62
93
|
return typeof value === "object" && value !== null;
|
|
@@ -125,19 +156,6 @@ function createBroadcastSync(options) {
|
|
|
125
156
|
};
|
|
126
157
|
}
|
|
127
158
|
|
|
128
|
-
// src/core/callback-url.ts
|
|
129
|
-
function readCallbackToken(url) {
|
|
130
|
-
return url.searchParams.get(authQueryKeys.token);
|
|
131
|
-
}
|
|
132
|
-
function removeCallbackToken(url) {
|
|
133
|
-
const nextUrl = new URL(url.toString());
|
|
134
|
-
nextUrl.searchParams.delete(authQueryKeys.token);
|
|
135
|
-
return nextUrl;
|
|
136
|
-
}
|
|
137
|
-
function replaceBrowserHistory(url) {
|
|
138
|
-
window.history.replaceState(null, "", url.toString());
|
|
139
|
-
}
|
|
140
|
-
|
|
141
159
|
// src/core/http-client.ts
|
|
142
160
|
var jsonContentType = "application/json";
|
|
143
161
|
var jsonHeaderName = "content-type";
|
|
@@ -233,9 +251,8 @@ function getJson(path) {
|
|
|
233
251
|
path
|
|
234
252
|
});
|
|
235
253
|
}
|
|
236
|
-
function
|
|
254
|
+
function postJsonWithoutBody(path) {
|
|
237
255
|
return request({
|
|
238
|
-
body,
|
|
239
256
|
method: "POST",
|
|
240
257
|
path
|
|
241
258
|
});
|
|
@@ -282,18 +299,10 @@ function sanitizeReturnTo(value) {
|
|
|
282
299
|
function getCurrentBrowserPath() {
|
|
283
300
|
return `${window.location.pathname}${window.location.search}${window.location.hash}`;
|
|
284
301
|
}
|
|
285
|
-
function
|
|
302
|
+
function resolveReturnToPath(returnTo) {
|
|
286
303
|
assertBrowserRuntime();
|
|
287
304
|
const fallbackPath = getCurrentBrowserPath();
|
|
288
|
-
|
|
289
|
-
window.sessionStorage.setItem(authStorageKeys.returnTo, sanitized);
|
|
290
|
-
return sanitized;
|
|
291
|
-
}
|
|
292
|
-
function consumeReturnToPath() {
|
|
293
|
-
assertBrowserRuntime();
|
|
294
|
-
const value = window.sessionStorage.getItem(authStorageKeys.returnTo);
|
|
295
|
-
window.sessionStorage.removeItem(authStorageKeys.returnTo);
|
|
296
|
-
return sanitizeReturnTo(value);
|
|
305
|
+
return sanitizeReturnTo(returnTo ?? fallbackPath);
|
|
297
306
|
}
|
|
298
307
|
|
|
299
308
|
// src/core/session-store.ts
|
|
@@ -326,10 +335,6 @@ var SessionStore = class {
|
|
|
326
335
|
};
|
|
327
336
|
|
|
328
337
|
// src/core/auth-client.ts
|
|
329
|
-
function createPendingRedirectPromise() {
|
|
330
|
-
return new Promise(() => {
|
|
331
|
-
});
|
|
332
|
-
}
|
|
333
338
|
function createInvalidSessionPayloadError(path) {
|
|
334
339
|
return new AuthSdkError({
|
|
335
340
|
code: authErrorCode.apiError,
|
|
@@ -344,29 +349,11 @@ function toValidatedSession(payload, path) {
|
|
|
344
349
|
}
|
|
345
350
|
return payload;
|
|
346
351
|
}
|
|
347
|
-
function
|
|
348
|
-
if (
|
|
349
|
-
|
|
350
|
-
return new AuthSdkError({
|
|
351
|
-
code: authErrorCode.callbackInvalidToken,
|
|
352
|
-
details: error.details,
|
|
353
|
-
message: "Callback JWT is invalid or expired.",
|
|
354
|
-
status: error.status
|
|
355
|
-
});
|
|
356
|
-
}
|
|
357
|
-
return new AuthSdkError({
|
|
358
|
-
code: authErrorCode.callbackValidationFailed,
|
|
359
|
-
details: error.details,
|
|
360
|
-
message: "Keycloak callback validation failed.",
|
|
361
|
-
status: error.status
|
|
362
|
-
});
|
|
352
|
+
function toSessionPayload(payload, path) {
|
|
353
|
+
if (payload === null) {
|
|
354
|
+
return null;
|
|
363
355
|
}
|
|
364
|
-
return
|
|
365
|
-
code: authErrorCode.callbackValidationFailed,
|
|
366
|
-
details: error,
|
|
367
|
-
message: "Keycloak callback validation failed.",
|
|
368
|
-
status: null
|
|
369
|
-
});
|
|
356
|
+
return toValidatedSession(payload, path);
|
|
370
357
|
}
|
|
371
358
|
function createNoopBroadcastSync() {
|
|
372
359
|
return {
|
|
@@ -388,25 +375,53 @@ function createSafeBroadcastSync(onSessionUpdated) {
|
|
|
388
375
|
throw error;
|
|
389
376
|
}
|
|
390
377
|
}
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
}
|
|
396
|
-
return toValidatedSession(payload, authEndpoints.session);
|
|
378
|
+
function toInitResult(session) {
|
|
379
|
+
return {
|
|
380
|
+
session,
|
|
381
|
+
status: session ? "authenticated" : "unauthenticated"
|
|
382
|
+
};
|
|
397
383
|
}
|
|
398
|
-
function createAuthClient() {
|
|
399
|
-
|
|
384
|
+
function createAuthClient(options = {}) {
|
|
385
|
+
let initPromise = null;
|
|
386
|
+
const defaultApplication = options.application?.trim() || "";
|
|
400
387
|
const sessionStore = new SessionStore();
|
|
401
388
|
const broadcastSync = createSafeBroadcastSync((session) => {
|
|
402
389
|
sessionStore.setSession(session);
|
|
403
390
|
});
|
|
404
|
-
const
|
|
405
|
-
|
|
391
|
+
const resolveEndpoint = (path) => resolveApiEndpoint(path, options.apiOrigin);
|
|
392
|
+
const loadSession = async () => {
|
|
393
|
+
const payload = await getJson(resolveEndpoint(authEndpoints.session));
|
|
394
|
+
return toSessionPayload(payload, authEndpoints.session);
|
|
395
|
+
};
|
|
396
|
+
const init = async (initOptions) => {
|
|
397
|
+
const forceRefresh = initOptions?.forceRefresh ?? false;
|
|
406
398
|
if (sessionStore.hasResolvedSession() && !forceRefresh) {
|
|
407
|
-
return sessionStore.getSessionIfResolved();
|
|
399
|
+
return toInitResult(sessionStore.getSessionIfResolved());
|
|
408
400
|
}
|
|
409
|
-
|
|
401
|
+
if (initPromise) {
|
|
402
|
+
return initPromise;
|
|
403
|
+
}
|
|
404
|
+
initPromise = (async () => {
|
|
405
|
+
const session = await loadSession();
|
|
406
|
+
sessionStore.setSession(session);
|
|
407
|
+
broadcastSync.publishSession(session);
|
|
408
|
+
return toInitResult(session);
|
|
409
|
+
})();
|
|
410
|
+
try {
|
|
411
|
+
return await initPromise;
|
|
412
|
+
} finally {
|
|
413
|
+
initPromise = null;
|
|
414
|
+
}
|
|
415
|
+
};
|
|
416
|
+
const getSession = async (requestOptions) => {
|
|
417
|
+
const result = await init({
|
|
418
|
+
forceRefresh: requestOptions?.forceRefresh ?? false
|
|
419
|
+
});
|
|
420
|
+
return result.session;
|
|
421
|
+
};
|
|
422
|
+
const refresh = async () => {
|
|
423
|
+
const payload = await postJsonWithoutBody(resolveEndpoint(authEndpoints.refresh));
|
|
424
|
+
const session = toSessionPayload(payload, authEndpoints.refresh);
|
|
410
425
|
sessionStore.setSession(session);
|
|
411
426
|
broadcastSync.publishSession(session);
|
|
412
427
|
return session;
|
|
@@ -423,61 +438,33 @@ function createAuthClient() {
|
|
|
423
438
|
status: httpStatus.unauthorized
|
|
424
439
|
});
|
|
425
440
|
};
|
|
426
|
-
const login = (
|
|
427
|
-
|
|
428
|
-
window.location.
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
if (!token) {
|
|
434
|
-
throw new AuthSdkError({
|
|
435
|
-
code: authErrorCode.callbackMissingToken,
|
|
436
|
-
details: null,
|
|
437
|
-
message: "Missing callback token query parameter.",
|
|
438
|
-
status: httpStatus.badRequest
|
|
439
|
-
});
|
|
441
|
+
const login = (loginOptions) => {
|
|
442
|
+
const returnTo = resolveReturnToPath(loginOptions?.returnTo);
|
|
443
|
+
const authorizeUrl = new URL(resolveEndpoint(authEndpoints.authorize), window.location.origin);
|
|
444
|
+
authorizeUrl.searchParams.set("return_to", returnTo);
|
|
445
|
+
const application = loginOptions?.application?.trim() || defaultApplication;
|
|
446
|
+
if (application) {
|
|
447
|
+
authorizeUrl.searchParams.set("app", application);
|
|
440
448
|
}
|
|
441
|
-
|
|
442
|
-
replaceBrowserHistory(cleanedUrl);
|
|
443
|
-
try {
|
|
444
|
-
const payload = await postJson(
|
|
445
|
-
authEndpoints.validateKeycloakToken,
|
|
446
|
-
{ token }
|
|
447
|
-
);
|
|
448
|
-
const session = toValidatedSession(payload.session, authEndpoints.validateKeycloakToken);
|
|
449
|
-
sessionStore.setSession(session);
|
|
450
|
-
broadcastSync.publishSession(session);
|
|
451
|
-
return {
|
|
452
|
-
redirectTo: consumeReturnToPath(),
|
|
453
|
-
session
|
|
454
|
-
};
|
|
455
|
-
} catch (error) {
|
|
456
|
-
throw toCallbackFailure(error);
|
|
457
|
-
}
|
|
458
|
-
};
|
|
459
|
-
const completeCallbackRedirect = async () => {
|
|
460
|
-
const result = await processCallback();
|
|
461
|
-
window.location.replace(result.redirectTo);
|
|
462
|
-
return createPendingRedirectPromise();
|
|
449
|
+
window.location.assign(authorizeUrl.toString());
|
|
463
450
|
};
|
|
464
451
|
const logout = async () => {
|
|
465
|
-
await postEmpty(authEndpoints.logout);
|
|
452
|
+
await postEmpty(resolveEndpoint(authEndpoints.logout));
|
|
466
453
|
sessionStore.setSession(null);
|
|
467
454
|
broadcastSync.publishSession(null);
|
|
468
455
|
};
|
|
469
456
|
const subscribe = sessionStore.subscribe.bind(sessionStore);
|
|
470
457
|
return {
|
|
471
|
-
|
|
458
|
+
init,
|
|
472
459
|
getSession,
|
|
473
460
|
login,
|
|
474
461
|
logout,
|
|
475
|
-
|
|
462
|
+
refresh,
|
|
476
463
|
requireSession,
|
|
477
464
|
subscribe
|
|
478
465
|
};
|
|
479
466
|
}
|
|
480
467
|
|
|
481
|
-
export { AuthSdkError, authEndpoints, authErrorCode,
|
|
468
|
+
export { AuthSdkError, authEndpoints, authErrorCode, authRoutes, createAuthClient };
|
|
482
469
|
//# sourceMappingURL=index.js.map
|
|
483
470
|
//# sourceMappingURL=index.js.map
|