@strivacity/sdk-core 4.0.0-beta.0 → 4.0.0-beta.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.
Files changed (97) hide show
  1. package/README.md +228 -86
  2. package/dist/assets/oidc.cjs +1 -1
  3. package/dist/assets/oidc.cjs.map +1 -1
  4. package/dist/assets/oidc.mjs +1 -1
  5. package/dist/assets/oidc.mjs.map +1 -1
  6. package/dist/assets/server.cjs +1 -1
  7. package/dist/assets/server.cjs.map +1 -1
  8. package/dist/assets/server.mjs +1 -1
  9. package/dist/assets/server.mjs.map +1 -1
  10. package/dist/flows/base.cjs +1 -1
  11. package/dist/flows/base.cjs.map +1 -1
  12. package/dist/flows/base.d.ts +4 -2
  13. package/dist/flows/base.mjs +1 -1
  14. package/dist/flows/base.mjs.map +1 -1
  15. package/dist/flows/popup.cjs +1 -1
  16. package/dist/flows/popup.cjs.map +1 -1
  17. package/dist/flows/popup.mjs +1 -1
  18. package/dist/flows/popup.mjs.map +1 -1
  19. package/dist/index.cjs +1 -1
  20. package/dist/index.cjs.map +1 -1
  21. package/dist/index.d.ts +6 -2
  22. package/dist/index.mjs +1 -1
  23. package/dist/index.mjs.map +1 -1
  24. package/dist/server/base.cjs +1 -1
  25. package/dist/server/base.cjs.map +1 -1
  26. package/dist/server/base.d.ts +2 -4
  27. package/dist/server/base.mjs +1 -1
  28. package/dist/server/base.mjs.map +1 -1
  29. package/dist/server/index.cjs +1 -1
  30. package/dist/server/index.mjs +1 -1
  31. package/dist/storages/cache.cjs.map +1 -1
  32. package/dist/storages/cache.d.ts +1 -1
  33. package/dist/storages/cache.mjs.map +1 -1
  34. package/dist/storages/index.cjs +1 -1
  35. package/dist/storages/index.mjs +1 -1
  36. package/dist/storages/server.cjs +1 -1
  37. package/dist/storages/server.d.ts +29 -1
  38. package/dist/storages/server.mjs +1 -1
  39. package/dist/storages/worker.cjs.map +1 -1
  40. package/dist/storages/worker.d.ts +1 -1
  41. package/dist/storages/worker.mjs.map +1 -1
  42. package/dist/types/native.d.ts +67 -2
  43. package/dist/types/oidc.cjs.map +1 -1
  44. package/dist/types/oidc.d.ts +47 -6
  45. package/dist/types/oidc.mjs.map +1 -1
  46. package/dist/types/popup.d.ts +1 -1
  47. package/dist/types/server.d.ts +21 -9
  48. package/dist/utils/index.cjs +1 -1
  49. package/dist/utils/index.d.ts +1 -0
  50. package/dist/utils/index.mjs +1 -1
  51. package/dist/utils/native-login.cjs +2 -0
  52. package/dist/utils/native-login.cjs.map +1 -0
  53. package/dist/utils/native-login.d.ts +13 -0
  54. package/dist/utils/native-login.mjs +2 -0
  55. package/dist/utils/native-login.mjs.map +1 -0
  56. package/dist/utils/oidc.d.ts +3 -4
  57. package/dist/utils/path.cjs +2 -0
  58. package/dist/utils/path.cjs.map +1 -0
  59. package/dist/utils/path.d.ts +16 -0
  60. package/dist/utils/path.mjs +2 -0
  61. package/dist/utils/path.mjs.map +1 -0
  62. package/dist/utils/server.d.ts +5 -4
  63. package/dist/utils/session.cjs +1 -1
  64. package/dist/utils/session.cjs.map +1 -1
  65. package/dist/utils/session.d.ts +10 -1
  66. package/dist/utils/session.mjs +1 -1
  67. package/dist/utils/session.mjs.map +1 -1
  68. package/package.json +1 -1
  69. package/testing/tests/flows/base.spec.ts +0 -1030
  70. package/testing/tests/flows/embedded.spec.ts +0 -443
  71. package/testing/tests/flows/index.spec.ts +0 -8
  72. package/testing/tests/flows/native.spec.ts +0 -487
  73. package/testing/tests/flows/popup.spec.ts +0 -400
  74. package/testing/tests/flows/redirect.spec.ts +0 -369
  75. package/testing/tests/handlers/embedded.spec.ts +0 -199
  76. package/testing/tests/handlers/index.spec.ts +0 -8
  77. package/testing/tests/handlers/native.spec.ts +0 -283
  78. package/testing/tests/handlers/popup.spec.ts +0 -206
  79. package/testing/tests/handlers/redirect.spec.ts +0 -70
  80. package/testing/tests/index.spec.ts +0 -78
  81. package/testing/tests/server/base.spec.ts +0 -846
  82. package/testing/tests/server/index.spec.ts +0 -15
  83. package/testing/tests/storages/cache.spec.ts +0 -107
  84. package/testing/tests/storages/index.spec.ts +0 -22
  85. package/testing/tests/storages/indexeddb.spec.ts +0 -113
  86. package/testing/tests/storages/local.spec.ts +0 -46
  87. package/testing/tests/storages/memory.spec.ts +0 -51
  88. package/testing/tests/storages/server.spec.ts +0 -435
  89. package/testing/tests/storages/session.spec.ts +0 -46
  90. package/testing/tests/storages/worker.spec.ts +0 -106
  91. package/testing/tests/utils/common.spec.ts +0 -77
  92. package/testing/tests/utils/credentials.spec.ts +0 -195
  93. package/testing/tests/utils/dom.spec.ts +0 -37
  94. package/testing/tests/utils/index.spec.ts +0 -71
  95. package/testing/tests/utils/logging.spec.ts +0 -82
  96. package/testing/tests/utils/oidc.spec.ts +0 -744
  97. package/testing/tests/utils/server.spec.ts +0 -235
@@ -1 +1 @@
1
- {"version":3,"file":"base.mjs","names":[],"sources":["../../src/flows/base.ts"],"sourcesContent":["import type { EventFunctions, ExtraRequestArgs, FlowState, SDK, SDKOptions, SessionData } from '../types/oidc';\nimport { buildEndSessionUrl, exchangeCode, getDiscoveryDocument, refreshToken, revokeToken, verifyIdToken } from '../utils/oidc';\nimport { loadSession, serializeSession, isSessionExpired } from '../utils/session';\nimport { ConfigurationError, NetworkError, ProtocolError, ServerError } from '../utils/errors';\n\n/**\n * Creates a base flow for the Strivacity SDK, providing common functionality for managing authentication sessions.\n *\n * @param flowState - The initial state of the flow, including session data and initialization status.\n * @param options - The SDK options, including issuer, clientId, redirectUri, scopes, and storage configuration.\n * @template URLHandlerParams - The type of additional request arguments for URL handling.\n * @returns An object implementing the SDK interface, with methods for initializing the flow, managing sessions, and handling authentication events.\n */\nexport function createBaseFlow<URLHandlerParams extends ExtraRequestArgs = ExtraRequestArgs>(flowState: FlowState, options: SDKOptions) {\n\tconst promises: Record<'init' | 'refresh' | 'revoke' | 'logout', Promise<void> | null> & { tokenExchange: Map<string, Promise<void>> } = {\n\t\tinit: null,\n\t\trefresh: null,\n\t\trevoke: null,\n\t\tlogout: null,\n\t\ttokenExchange: new Map(),\n\t};\n\t// eslint-disable-next-line @typescript-eslint/no-explicit-any\n\tconst eventCallbacks: Record<keyof EventFunctions, Set<(...args: Array<any>) => Promise<void> | void>> = {\n\t\taccessTokenExpired: new Set(),\n\t\tinit: new Set(),\n\t\tloggedIn: new Set(),\n\t\tsessionUpdated: new Set(),\n\t\tsessionCleared: new Set(),\n\t\tloginInitiated: new Set(),\n\t\tflowInitiated: new Set(),\n\t\tlogoutInitiated: new Set(),\n\t\tsessionLoaded: new Set(),\n\t\ttokenRefreshed: new Set(),\n\t\ttokenRefreshFailed: new Set(),\n\t\ttokenRevoked: new Set(),\n\t\ttokenRevokeFailed: new Set(),\n\t};\n\n\tfunction dispatchEvent<T extends keyof EventFunctions>(eventName: T, args: Parameters<EventFunctions[T]>): void {\n\t\tfor (const fn of eventCallbacks[eventName]) {\n\t\t\tvoid fn(...args);\n\t\t}\n\t}\n\n\tfunction subscribeToEvent<T extends keyof EventFunctions>(\n\t\teventName: T,\n\t\tcallbackFn: (...params: Parameters<EventFunctions[T]>) => Promise<void> | void,\n\t): ReturnType<SDK<URLHandlerParams>['subscribeToEvent']> {\n\t\teventCallbacks[eventName].add(callbackFn);\n\t\treturn { dispose: () => eventCallbacks[eventName].delete(callbackFn) };\n\t}\n\n\tfunction subscribeToAllEvents(callbackFn: (...params: Array<unknown>) => Promise<void> | void): ReturnType<SDK<URLHandlerParams>['subscribeToAllEvents']> {\n\t\tfor (const eventName in eventCallbacks) {\n\t\t\teventCallbacks[eventName as keyof EventFunctions].add(callbackFn);\n\t\t}\n\n\t\treturn {\n\t\t\tdispose: () => {\n\t\t\t\tfor (const eventName in eventCallbacks) {\n\t\t\t\t\teventCallbacks[eventName as keyof EventFunctions].delete(callbackFn);\n\t\t\t\t}\n\t\t\t},\n\t\t};\n\t}\n\n\tasync function getSession(): Promise<SessionData | null> {\n\t\tawait init();\n\n\t\treturn flowState.session;\n\t}\n\n\tasync function updateSession(newData: SessionData): ReturnType<SDK<URLHandlerParams>['updateSession']> {\n\t\tawait init();\n\n\t\t// NOTE: only unverified callers (e.g. direct API use) need validating here\n\t\tif (newData.id_token && !newData.claims) {\n\t\t\tnewData.claims = await verifyIdToken({ idToken: newData.id_token, options });\n\t\t}\n\n\t\tif (!options.serverSessionUri) {\n\t\t\tawait options.storage.set(options.storageTokenName, serializeSession(newData));\n\t\t}\n\n\t\tflowState.session = newData;\n\n\t\tdispatchEvent('sessionUpdated', [\n\t\t\t{\n\t\t\t\tidToken: flowState.session.id_token,\n\t\t\t\taccessToken: flowState.session.access_token,\n\t\t\t\trefreshToken: flowState.session.refresh_token,\n\t\t\t\tclaims: flowState.session.claims,\n\t\t\t},\n\t\t]);\n\t}\n\n\tasync function cleanupSession(): ReturnType<SDK<URLHandlerParams>['cleanupSession']> {\n\t\tawait init();\n\n\t\tif (!options.serverSessionUri) {\n\t\t\tawait options.storage.delete(options.storageTokenName);\n\t\t}\n\n\t\tflowState.session = null;\n\n\t\tdispatchEvent('sessionCleared', []);\n\t}\n\n\tasync function checkAuthentication(\n\t\tparams: { autoRefresh: boolean } = { autoRefresh: options.autoRefresh },\n\t): ReturnType<SDK<URLHandlerParams>['checkAuthentication']> {\n\t\tif (flowState.session?.access_token && !isSessionExpired(flowState.session)) {\n\t\t\treturn true;\n\t\t}\n\n\t\tif (params?.autoRefresh && flowState.session?.refresh_token) {\n\t\t\ttry {\n\t\t\t\tawait refresh();\n\t\t\t} catch {\n\t\t\t\treturn false;\n\t\t\t}\n\t\t}\n\n\t\treturn !isSessionExpired(flowState.session);\n\t}\n\n\tasync function init(): ReturnType<SDK<URLHandlerParams>['init']> {\n\t\tif (flowState.initialized) {\n\t\t\treturn;\n\t\t}\n\n\t\tif (promises.init) {\n\t\t\treturn promises.init;\n\t\t}\n\n\t\tpromises.init = (async () => {\n\t\t\ttry {\n\t\t\t\tif (!options.issuer) {\n\t\t\t\t\tconst error = new ConfigurationError('Missing option: issuer');\n\t\t\t\t\toptions.logging?.error('Required option missing', error);\n\t\t\t\t\tthrow error;\n\t\t\t\t}\n\t\t\t\tif (!options.clientId) {\n\t\t\t\t\tconst error = new ConfigurationError('Missing option: clientId');\n\t\t\t\t\toptions.logging?.error('Required option missing', error);\n\t\t\t\t\tthrow error;\n\t\t\t\t}\n\t\t\t\tif (!options.redirectUri) {\n\t\t\t\t\tconst error = new ConfigurationError('Missing option: redirectUri');\n\t\t\t\t\toptions.logging?.error('Required option missing', error);\n\t\t\t\t\tthrow error;\n\t\t\t\t}\n\t\t\t\tif (options.scopes && !Array.isArray(options.scopes)) {\n\t\t\t\t\tconst error = new ConfigurationError('Invalid option: scopes');\n\t\t\t\t\toptions.logging?.error('Invalid option provided', error);\n\t\t\t\t\tthrow error;\n\t\t\t\t}\n\n\t\t\t\tif (!options.serverSessionUri) {\n\t\t\t\t\tflowState.session = loadSession(await options.storage.get(options.storageTokenName));\n\t\t\t\t}\n\n\t\t\t\tflowState.initialized = true;\n\n\t\t\t\tdispatchEvent('init', []);\n\t\t\t\toptions.logging?.debug('SDK initialized');\n\n\t\t\t\tif (!flowState.session && !options.serverSessionUri) {\n\t\t\t\t\toptions.logging?.debug('No session found in storage');\n\t\t\t\t}\n\n\t\t\t\tif (flowState.session?.access_token) {\n\t\t\t\t\tdispatchEvent('sessionLoaded', [\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tidToken: flowState.session.id_token,\n\t\t\t\t\t\t\taccessToken: flowState.session.access_token,\n\t\t\t\t\t\t\trefreshToken: flowState.session.refresh_token,\n\t\t\t\t\t\t\tclaims: flowState.session.claims,\n\t\t\t\t\t\t},\n\t\t\t\t\t]);\n\t\t\t\t\toptions.logging?.debug('Session loaded from storage');\n\t\t\t\t}\n\n\t\t\t\tif (flowState.session?.access_token && isSessionExpired(flowState.session)) {\n\t\t\t\t\tdispatchEvent('accessTokenExpired', [{ accessToken: flowState.session.access_token, refreshToken: flowState.session.refresh_token }]);\n\t\t\t\t\toptions.logging?.debug('Access token has expired');\n\t\t\t\t}\n\t\t\t} finally {\n\t\t\t\tpromises.init = null;\n\t\t\t}\n\t\t})();\n\n\t\treturn promises.init;\n\t}\n\n\tasync function tokenExchange(params: Parameters<SDK<URLHandlerParams>['tokenExchange']>[0] = {}): ReturnType<SDK<URLHandlerParams>['tokenExchange']> {\n\t\tawait init();\n\n\t\tconst exchangeKey = params.state ?? '';\n\t\tconst inFlight = promises.tokenExchange.get(exchangeKey);\n\n\t\tif (inFlight) {\n\t\t\treturn inFlight;\n\t\t}\n\n\t\tconst exchangePromise = (async () => {\n\t\t\toptions.logging?.debug('Exchanging authorization code for tokens');\n\n\t\t\ttry {\n\t\t\t\tconst session = await exchangeCode({ params, options });\n\n\t\t\t\tif (!session.access_token) {\n\t\t\t\t\tthrow new ProtocolError('Missing access_token');\n\t\t\t\t}\n\n\t\t\t\tawait updateSession(session);\n\n\t\t\t\toptions.logging?.debug('Token exchange successful');\n\n\t\t\t\tdispatchEvent('loggedIn', [\n\t\t\t\t\t{ idToken: session.id_token, accessToken: session.access_token, refreshToken: session.refresh_token, claims: session.claims },\n\t\t\t\t]);\n\n\t\t\t\tif (options.logging) {\n\t\t\t\t\toptions.logging.xEventId = undefined;\n\t\t\t\t\toptions.logging.info('Login successful');\n\t\t\t\t}\n\t\t\t} catch (error) {\n\t\t\t\toptions.logging?.error('Token exchange failed', error);\n\t\t\t\tthrow error;\n\t\t\t} finally {\n\t\t\t\tpromises.tokenExchange.delete(exchangeKey);\n\t\t\t}\n\t\t})();\n\n\t\tpromises.tokenExchange.set(exchangeKey, exchangePromise);\n\n\t\treturn exchangePromise;\n\t}\n\n\tasync function handleCallback(url?: string | URL): ReturnType<SDK<URLHandlerParams>['handleCallback']> {\n\t\tawait init();\n\n\t\tconst callbackUrl = url ?? globalThis.window?.location.href;\n\t\tconst params = (await options.callbackHandler(callbackUrl, options.responseMode)) as Record<string, string>;\n\n\t\tawait tokenExchange(params);\n\t}\n\n\tasync function refresh(): ReturnType<SDK<URLHandlerParams>['refresh']> {\n\t\tawait init();\n\n\t\tif (promises.refresh) {\n\t\t\treturn promises.refresh;\n\t\t}\n\n\t\tif (promises.revoke) {\n\t\t\ttry {\n\t\t\t\tawait promises.revoke;\n\t\t\t} catch {}\n\t\t}\n\n\t\tif (promises.logout) {\n\t\t\ttry {\n\t\t\t\tawait promises.logout;\n\t\t\t} catch {}\n\t\t}\n\n\t\toptions.logging?.debug('Attempting to refresh session');\n\n\t\tif (typeof flowState.session?.refresh_token !== 'string') {\n\t\t\toptions.logging?.debug('Refresh called without refresh token');\n\t\t\treturn;\n\t\t}\n\n\t\tpromises.refresh = (async () => {\n\t\t\ttry {\n\t\t\t\tconst session = await refreshToken({ refreshToken: flowState.session!.refresh_token!, options, expectedSub: flowState.session?.claims?.sub });\n\t\t\t\tawait updateSession(session);\n\n\t\t\t\tdispatchEvent('tokenRefreshed', [\n\t\t\t\t\t{\n\t\t\t\t\t\tidToken: flowState.session?.id_token,\n\t\t\t\t\t\taccessToken: flowState.session?.access_token,\n\t\t\t\t\t\trefreshToken: flowState.session?.refresh_token,\n\t\t\t\t\t\tclaims: flowState.session?.claims,\n\t\t\t\t\t},\n\t\t\t\t]);\n\t\t\t\toptions.logging?.debug('Session refresh successful');\n\t\t\t} catch (error) {\n\t\t\t\tconst failedRefreshToken = flowState.session?.refresh_token;\n\n\t\t\t\t// NOTE: Transient Network/Server failures must not destroy a session that could still be refreshed later.\n\t\t\t\tif (!(error instanceof NetworkError) && !(error instanceof ServerError)) {\n\t\t\t\t\tawait cleanupSession();\n\t\t\t\t}\n\n\t\t\t\tdispatchEvent('tokenRefreshFailed', [{ refreshToken: failedRefreshToken }]);\n\t\t\t\toptions.logging?.error('Session refresh failed', error);\n\n\t\t\t\tthrow error;\n\t\t\t} finally {\n\t\t\t\tpromises.refresh = null;\n\t\t\t}\n\t\t})();\n\n\t\treturn promises.refresh;\n\t}\n\n\tasync function revoke(): ReturnType<SDK<URLHandlerParams>['revoke']> {\n\t\tawait init();\n\n\t\tif (promises.revoke) {\n\t\t\treturn promises.revoke;\n\t\t}\n\n\t\tif (promises.refresh) {\n\t\t\ttry {\n\t\t\t\tawait promises.refresh;\n\t\t\t} catch {}\n\t\t}\n\n\t\tif (promises.logout) {\n\t\t\ttry {\n\t\t\t\tawait promises.logout;\n\t\t\t} catch {}\n\t\t}\n\n\t\tpromises.revoke = (async () => {\n\t\t\ttry {\n\t\t\t\tif (flowState.session?.refresh_token) {\n\t\t\t\t\toptions.logging?.debug('Attempting to revoke refresh token');\n\t\t\t\t} else if (flowState.session?.access_token) {\n\t\t\t\t\toptions.logging?.debug('Attempting to revoke access token');\n\t\t\t\t}\n\n\t\t\t\t// NOTE: Cleanup session before revocation\n\t\t\t\tconst currentSession = flowState.session;\n\t\t\t\tawait cleanupSession();\n\n\t\t\t\tif (!currentSession?.access_token && !currentSession?.refresh_token) {\n\t\t\t\t\toptions.logging?.debug('Revoke called without session');\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\tconst tokenTypeHint = currentSession.refresh_token ? 'refresh_token' : 'access_token';\n\t\t\t\tconst token = (tokenTypeHint === 'refresh_token' ? currentSession.refresh_token : currentSession.access_token)!;\n\n\t\t\t\ttry {\n\t\t\t\t\tawait revokeToken({ tokenTypeHint, token, options });\n\n\t\t\t\t\tif (tokenTypeHint === 'refresh_token') {\n\t\t\t\t\t\tdispatchEvent('tokenRevoked', [{ token: currentSession.refresh_token, tokenTypeHint: 'refresh_token' }]);\n\t\t\t\t\t\toptions.logging?.info('Refresh token successfully revoked');\n\t\t\t\t\t} else {\n\t\t\t\t\t\tdispatchEvent('tokenRevoked', [{ token: currentSession.access_token, tokenTypeHint: 'access_token' }]);\n\t\t\t\t\t\toptions.logging?.info('Access token successfully revoked');\n\t\t\t\t\t}\n\t\t\t\t} catch (error) {\n\t\t\t\t\tif (tokenTypeHint === 'refresh_token') {\n\t\t\t\t\t\tdispatchEvent('tokenRevokeFailed', [{ token: currentSession.refresh_token, tokenTypeHint: 'refresh_token' }]);\n\t\t\t\t\t} else {\n\t\t\t\t\t\tdispatchEvent('tokenRevokeFailed', [{ token: currentSession.access_token, tokenTypeHint: 'access_token' }]);\n\t\t\t\t\t}\n\n\t\t\t\t\toptions.logging?.error('Token revocation failed', error);\n\t\t\t\t\tthrow error;\n\t\t\t\t}\n\t\t\t} finally {\n\t\t\t\tpromises.revoke = null;\n\t\t\t}\n\t\t})();\n\n\t\treturn promises.revoke;\n\t}\n\n\tasync function logout(params?: Parameters<SDK<URLHandlerParams>['logout']>[0]): ReturnType<SDK<URLHandlerParams>['logout']> {\n\t\tawait init();\n\n\t\tif (promises.logout) {\n\t\t\treturn promises.logout;\n\t\t}\n\n\t\tif (promises.revoke) {\n\t\t\ttry {\n\t\t\t\tawait promises.revoke;\n\t\t\t} catch {}\n\t\t}\n\n\t\tif (promises.refresh) {\n\t\t\ttry {\n\t\t\t\tawait promises.refresh;\n\t\t\t} catch {}\n\t\t}\n\n\t\tpromises.logout = (async () => {\n\t\t\ttry {\n\t\t\t\toptions.logging?.debug('Attempting to logout');\n\n\t\t\t\t// NOTE: Cleanup session before logout\n\t\t\t\tconst currentSession = flowState.session;\n\t\t\t\tawait cleanupSession();\n\n\t\t\t\tdispatchEvent('logoutInitiated', [{ idToken: currentSession?.id_token, claims: currentSession?.claims }]);\n\t\t\t\toptions.logging?.debug('Logout initiated');\n\n\t\t\t\tif (!currentSession?.id_token) {\n\t\t\t\t\toptions.logging?.debug('Logout called without id token');\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\ttry {\n\t\t\t\t\tconst metadata = await getDiscoveryDocument(options);\n\t\t\t\t\tconst logoutUrl = buildEndSessionUrl({\n\t\t\t\t\t\turl: metadata.end_session_endpoint,\n\t\t\t\t\t\tidToken: currentSession.id_token,\n\t\t\t\t\t\tpostLogoutRedirectUri: params?.postLogoutRedirectUri,\n\t\t\t\t\t});\n\n\t\t\t\t\tawait options.urlHandler(logoutUrl, params);\n\t\t\t\t} catch (error) {\n\t\t\t\t\toptions.logging?.error('Unable to redirect to the end-session endpoint', error);\n\t\t\t\t}\n\t\t\t} finally {\n\t\t\t\tpromises.logout = null;\n\t\t\t}\n\t\t})();\n\n\t\treturn promises.logout;\n\t}\n\n\treturn {\n\t\tdispatchEvent,\n\t\tsubscribeToEvent,\n\t\tsubscribeToAllEvents,\n\t\tgetSession,\n\t\tupdateSession,\n\t\tcleanupSession,\n\t\tcheckAuthentication,\n\t\tinit,\n\t\ttokenExchange,\n\t\thandleCallback,\n\t\trefresh,\n\t\trevoke,\n\t\tlogout,\n\t};\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"base.mjs","names":[],"sources":["../../src/flows/base.ts"],"sourcesContent":["import type { EventFunctions, ExtraRequestArgs, FlowState, SDK, SDKOptions, SessionData } from '../types/oidc';\nimport { buildEndSessionUrl, exchangeCode, getDiscoveryDocument, refreshToken, revokeToken, verifyIdToken } from '../utils/oidc';\nimport { loadSession, serializeSession, isSessionExpired } from '../utils/session';\nimport { parseState } from '../utils/state';\nimport { appendReturnTo } from '../utils/path';\nimport { ConfigurationError, NetworkError, ProtocolError, ServerError } from '../utils/errors';\nimport { redirectUrlHandler } from '../handlers/redirect';\n\n/**\n * Creates a base flow for the Strivacity SDK, providing common functionality for managing authentication sessions.\n *\n * @param flowState - The initial state of the flow, including session data and initialization status.\n * @param options - The SDK options, including issuer, clientId, redirectUri, scopes, and storage configuration.\n * @template URLHandlerParams - The type of additional request arguments for URL handling.\n * @returns An object implementing the SDK interface, with methods for initializing the flow, managing sessions, and handling authentication events.\n */\nexport function createBaseFlow<URLHandlerParams extends ExtraRequestArgs = ExtraRequestArgs>(flowState: FlowState, options: SDKOptions) {\n\tconst promises: Record<'init' | 'refresh' | 'revoke' | 'logout', Promise<void> | null> & { tokenExchange: Map<string, Promise<void>> } = {\n\t\tinit: null,\n\t\trefresh: null,\n\t\trevoke: null,\n\t\tlogout: null,\n\t\ttokenExchange: new Map(),\n\t};\n\tlet localSessionLock: Promise<unknown> = Promise.resolve();\n\t// eslint-disable-next-line @typescript-eslint/no-explicit-any\n\tconst eventCallbacks: Record<keyof EventFunctions, Set<(...args: Array<any>) => Promise<void> | void>> = {\n\t\taccessTokenExpired: new Set(),\n\t\tinit: new Set(),\n\t\tloggedIn: new Set(),\n\t\tsessionUpdated: new Set(),\n\t\tsessionCleared: new Set(),\n\t\tloginInitiated: new Set(),\n\t\tflowInitiated: new Set(),\n\t\tlogoutInitiated: new Set(),\n\t\tsessionLoaded: new Set(),\n\t\ttokenRefreshed: new Set(),\n\t\ttokenRefreshFailed: new Set(),\n\t\ttokenRevoked: new Set(),\n\t\ttokenRevokeFailed: new Set(),\n\t};\n\n\tfunction dispatchEvent<T extends keyof EventFunctions>(eventName: T, args: Parameters<EventFunctions[T]>): void {\n\t\tfor (const fn of eventCallbacks[eventName]) {\n\t\t\tvoid fn(...args);\n\t\t}\n\t}\n\n\tfunction subscribeToEvent<T extends keyof EventFunctions>(\n\t\teventName: T,\n\t\tcallbackFn: (...params: Parameters<EventFunctions[T]>) => Promise<void> | void,\n\t): ReturnType<SDK<URLHandlerParams>['subscribeToEvent']> {\n\t\teventCallbacks[eventName].add(callbackFn);\n\t\treturn { dispose: () => eventCallbacks[eventName].delete(callbackFn) };\n\t}\n\n\tfunction subscribeToAllEvents(callbackFn: (...params: Array<unknown>) => Promise<void> | void): ReturnType<SDK<URLHandlerParams>['subscribeToAllEvents']> {\n\t\tfor (const eventName in eventCallbacks) {\n\t\t\teventCallbacks[eventName as keyof EventFunctions].add(callbackFn);\n\t\t}\n\n\t\treturn {\n\t\t\tdispose: () => {\n\t\t\t\tfor (const eventName in eventCallbacks) {\n\t\t\t\t\teventCallbacks[eventName as keyof EventFunctions].delete(callbackFn);\n\t\t\t\t}\n\t\t\t},\n\t\t};\n\t}\n\n\tfunction withSessionLock<T>(fn: () => Promise<T>): Promise<T> {\n\t\tconst locks = globalThis.window ? (globalThis.navigator as Navigator | undefined)?.locks : undefined;\n\n\t\tif (locks) {\n\t\t\treturn locks.request(`strivacity.session.${options.clientId}.${options.storageTokenName}`, fn);\n\t\t}\n\n\t\t// NOTE: in-process fallback of the session lock where the Web Locks API is not available\n\t\tconst result = localSessionLock.then(fn);\n\t\tlocalSessionLock = result.catch(() => {});\n\n\t\treturn result;\n\t}\n\n\tasync function getSession(): Promise<SessionData | null> {\n\t\tawait init();\n\n\t\treturn flowState.session;\n\t}\n\n\tasync function loadStoredSession(): Promise<SessionData | null> {\n\t\tif (options.serverSessionUri) {\n\t\t\treturn null;\n\t\t}\n\n\t\treturn loadSession(await options.storage.get(options.storageTokenName));\n\t}\n\n\tasync function updateSession(newData: SessionData): ReturnType<SDK<URLHandlerParams>['updateSession']> {\n\t\tawait init();\n\n\t\t// NOTE: only unverified callers (e.g. direct API use) need validating here\n\t\tif (newData.id_token && !newData.claims) {\n\t\t\tnewData.claims = await verifyIdToken({ idToken: newData.id_token, options });\n\t\t}\n\n\t\tif (!options.serverSessionUri) {\n\t\t\tawait options.storage.set(options.storageTokenName, serializeSession(newData));\n\t\t}\n\n\t\tflowState.session = newData;\n\n\t\tdispatchEvent('sessionUpdated', [\n\t\t\t{\n\t\t\t\tidToken: flowState.session.id_token,\n\t\t\t\taccessToken: flowState.session.access_token,\n\t\t\t\trefreshToken: flowState.session.refresh_token,\n\t\t\t\tclaims: flowState.session.claims,\n\t\t\t},\n\t\t]);\n\t}\n\n\tasync function cleanupSession(): ReturnType<SDK<URLHandlerParams>['cleanupSession']> {\n\t\tawait init();\n\n\t\tif (!options.serverSessionUri) {\n\t\t\tawait options.storage.delete(options.storageTokenName);\n\t\t}\n\n\t\tflowState.session = null;\n\n\t\tdispatchEvent('sessionCleared', []);\n\t}\n\n\tasync function checkAuthentication(\n\t\tparams: { autoRefresh: boolean } = { autoRefresh: options.autoRefresh },\n\t): ReturnType<SDK<URLHandlerParams>['checkAuthentication']> {\n\t\tawait init();\n\n\t\tif (flowState.session?.access_token && !isSessionExpired(flowState.session, options.refreshSkew)) {\n\t\t\treturn true;\n\t\t}\n\n\t\tif (params?.autoRefresh && flowState.session?.refresh_token && !options.serverSessionUri) {\n\t\t\ttry {\n\t\t\t\tawait refresh();\n\t\t\t} catch {\n\t\t\t\treturn false;\n\t\t\t}\n\t\t}\n\n\t\treturn !isSessionExpired(flowState.session);\n\t}\n\n\tasync function init(): ReturnType<SDK<URLHandlerParams>['init']> {\n\t\tif (flowState.initialized) {\n\t\t\treturn;\n\t\t}\n\n\t\tif (promises.init) {\n\t\t\treturn promises.init;\n\t\t}\n\n\t\tpromises.init = (async () => {\n\t\t\ttry {\n\t\t\t\tif (!options.issuer) {\n\t\t\t\t\tconst error = new ConfigurationError('Missing option: issuer');\n\t\t\t\t\toptions.logging?.error('Required option missing', error);\n\t\t\t\t\tthrow error;\n\t\t\t\t}\n\t\t\t\tif (!options.clientId) {\n\t\t\t\t\tconst error = new ConfigurationError('Missing option: clientId');\n\t\t\t\t\toptions.logging?.error('Required option missing', error);\n\t\t\t\t\tthrow error;\n\t\t\t\t}\n\t\t\t\tif (!options.redirectUri) {\n\t\t\t\t\tconst error = new ConfigurationError('Missing option: redirectUri');\n\t\t\t\t\toptions.logging?.error('Required option missing', error);\n\t\t\t\t\tthrow error;\n\t\t\t\t}\n\t\t\t\tif (options.scopes && !Array.isArray(options.scopes)) {\n\t\t\t\t\tconst error = new ConfigurationError('Invalid option: scopes');\n\t\t\t\t\toptions.logging?.error('Invalid option provided', error);\n\t\t\t\t\tthrow error;\n\t\t\t\t}\n\n\t\t\t\tif (!options.serverSessionUri) {\n\t\t\t\t\tflowState.session = loadSession(await options.storage.get(options.storageTokenName));\n\t\t\t\t}\n\n\t\t\t\tflowState.initialized = true;\n\n\t\t\t\tdispatchEvent('init', []);\n\t\t\t\toptions.logging?.debug('SDK initialized');\n\n\t\t\t\tif (!flowState.session && !options.serverSessionUri) {\n\t\t\t\t\toptions.logging?.debug('No session found in storage');\n\t\t\t\t}\n\n\t\t\t\tif (flowState.session?.access_token) {\n\t\t\t\t\tdispatchEvent('sessionLoaded', [\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tidToken: flowState.session.id_token,\n\t\t\t\t\t\t\taccessToken: flowState.session.access_token,\n\t\t\t\t\t\t\trefreshToken: flowState.session.refresh_token,\n\t\t\t\t\t\t\tclaims: flowState.session.claims,\n\t\t\t\t\t\t},\n\t\t\t\t\t]);\n\t\t\t\t\toptions.logging?.debug('Session loaded from storage');\n\t\t\t\t}\n\n\t\t\t\tif (flowState.session?.access_token && isSessionExpired(flowState.session)) {\n\t\t\t\t\tdispatchEvent('accessTokenExpired', [{ accessToken: flowState.session.access_token, refreshToken: flowState.session.refresh_token }]);\n\t\t\t\t\toptions.logging?.debug('Access token has expired');\n\t\t\t\t}\n\t\t\t} finally {\n\t\t\t\tpromises.init = null;\n\t\t\t}\n\t\t})();\n\n\t\treturn promises.init;\n\t}\n\n\tasync function tokenExchange(params: Parameters<SDK<URLHandlerParams>['tokenExchange']>[0] = {}): ReturnType<SDK<URLHandlerParams>['tokenExchange']> {\n\t\tawait init();\n\n\t\tconst exchangeKey = params.state ?? '';\n\t\tconst inFlight = promises.tokenExchange.get(exchangeKey);\n\n\t\tif (inFlight) {\n\t\t\treturn inFlight;\n\t\t}\n\n\t\tconst exchangePromise = (async () => {\n\t\t\toptions.logging?.debug('Exchanging authorization code for tokens');\n\n\t\t\ttry {\n\t\t\t\tconst session = await exchangeCode({ params, options });\n\n\t\t\t\tif (!session.access_token) {\n\t\t\t\t\tthrow new ProtocolError('Missing access_token');\n\t\t\t\t}\n\n\t\t\t\tawait updateSession(session);\n\n\t\t\t\toptions.logging?.debug('Token exchange successful');\n\n\t\t\t\tdispatchEvent('loggedIn', [\n\t\t\t\t\t{ idToken: session.id_token, accessToken: session.access_token, refreshToken: session.refresh_token, claims: session.claims },\n\t\t\t\t]);\n\n\t\t\t\tif (options.logging) {\n\t\t\t\t\toptions.logging.xEventId = undefined;\n\t\t\t\t\toptions.logging.info('Login successful');\n\t\t\t\t}\n\t\t\t} catch (error) {\n\t\t\t\toptions.logging?.error('Token exchange failed', error);\n\t\t\t\tthrow error;\n\t\t\t} finally {\n\t\t\t\tpromises.tokenExchange.delete(exchangeKey);\n\t\t\t}\n\t\t})();\n\n\t\tpromises.tokenExchange.set(exchangeKey, exchangePromise);\n\n\t\treturn exchangePromise;\n\t}\n\n\tasync function handleCallback(url?: string | URL): ReturnType<SDK<URLHandlerParams>['handleCallback']> {\n\t\tawait init();\n\n\t\tconst callbackUrl = url ?? globalThis.window?.location.href;\n\t\tconst params = (await options.callbackHandler(callbackUrl, options.responseMode)) as Record<string, string>;\n\t\t// NOTE: read before the exchange, which deletes the state\n\t\tconst serializedState = params.state ? await options.stateStorage.get(`sty.${params.state}`) : null;\n\t\tlet returnTo: unknown;\n\n\t\ttry {\n\t\t\treturnTo = serializedState ? parseState(serializedState).metadata?.returnTo : undefined;\n\t\t} catch {\n\t\t\t// NOTE: an unparsable state has no returnTo\n\t\t}\n\n\t\tawait tokenExchange(params);\n\n\t\treturn typeof returnTo === 'string' && returnTo ? { returnTo } : {};\n\t}\n\n\tasync function refresh(params?: { returnTo?: string }): ReturnType<SDK<URLHandlerParams>['refresh']> {\n\t\tawait init();\n\n\t\tif (promises.refresh) {\n\t\t\treturn promises.refresh;\n\t\t}\n\n\t\toptions.logging?.debug('Attempting to refresh session');\n\n\t\t// NOTE: with server-managed sessions the server owns the refresh token: let its refresh route rotate the cookie and come back\n\t\tif (options.serverSessionUri) {\n\t\t\tawait redirectUrlHandler(appendReturnTo(`${options.authUrlPrefix}/refresh`, params?.returnTo));\n\t\t\treturn;\n\t\t}\n\n\t\tif (typeof flowState.session?.refresh_token !== 'string') {\n\t\t\toptions.logging?.debug('Refresh called without refresh token');\n\t\t\treturn;\n\t\t}\n\n\t\tpromises.refresh = withSessionLock(async () => {\n\t\t\tconst stored = await loadStoredSession();\n\n\t\t\tif (!stored && !options.serverSessionUri) {\n\t\t\t\tif (flowState.session) {\n\t\t\t\t\toptions.logging?.debug('Session was cleared by another tab');\n\t\t\t\t\tflowState.session = null;\n\t\t\t\t\tdispatchEvent('sessionCleared', []);\n\t\t\t\t}\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tif (stored?.access_token && stored.access_token !== flowState.session?.access_token) {\n\t\t\t\toptions.logging?.debug('Using the session refreshed by another tab');\n\t\t\t\tflowState.session = stored;\n\n\t\t\t\tif (!isSessionExpired(stored, options.refreshSkew)) {\n\t\t\t\t\tdispatchEvent('tokenRefreshed', [\n\t\t\t\t\t\t{ idToken: stored.id_token, accessToken: stored.access_token, refreshToken: stored.refresh_token, claims: stored.claims },\n\t\t\t\t\t]);\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif (typeof flowState.session?.refresh_token !== 'string') {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\ttry {\n\t\t\t\tconst session = await refreshToken({ refreshToken: flowState.session.refresh_token, options, expectedSub: flowState.session?.claims?.sub });\n\t\t\t\tawait updateSession(session);\n\n\t\t\t\tdispatchEvent('tokenRefreshed', [\n\t\t\t\t\t{\n\t\t\t\t\t\tidToken: flowState.session?.id_token,\n\t\t\t\t\t\taccessToken: flowState.session?.access_token,\n\t\t\t\t\t\trefreshToken: flowState.session?.refresh_token,\n\t\t\t\t\t\tclaims: flowState.session?.claims,\n\t\t\t\t\t},\n\t\t\t\t]);\n\t\t\t\toptions.logging?.debug('Session refresh successful');\n\t\t\t} catch (error) {\n\t\t\t\tconst failedRefreshToken = flowState.session?.refresh_token;\n\n\t\t\t\t// NOTE: Transient Network/Server failures must not destroy a session that could still be refreshed later.\n\t\t\t\tif (!(error instanceof NetworkError) && !(error instanceof ServerError)) {\n\t\t\t\t\tawait cleanupSession();\n\t\t\t\t}\n\n\t\t\t\tdispatchEvent('tokenRefreshFailed', [{ refreshToken: failedRefreshToken }]);\n\t\t\t\toptions.logging?.error('Session refresh failed', error);\n\n\t\t\t\tthrow error;\n\t\t\t}\n\t\t}).finally(() => {\n\t\t\tpromises.refresh = null;\n\t\t});\n\n\t\treturn promises.refresh;\n\t}\n\n\tasync function revoke(): ReturnType<SDK<URLHandlerParams>['revoke']> {\n\t\tawait init();\n\n\t\tif (promises.revoke) {\n\t\t\treturn promises.revoke;\n\t\t}\n\n\t\tpromises.revoke = (async () => {\n\t\t\ttry {\n\t\t\t\tif (flowState.session?.refresh_token) {\n\t\t\t\t\toptions.logging?.debug('Attempting to revoke refresh token');\n\t\t\t\t} else if (flowState.session?.access_token) {\n\t\t\t\t\toptions.logging?.debug('Attempting to revoke access token');\n\t\t\t\t}\n\n\t\t\t\t// NOTE: Cleanup session before revocation\n\t\t\t\tconst currentSession = await withSessionLock(async () => {\n\t\t\t\t\tconst currentSession = (await loadStoredSession()) ?? flowState.session;\n\t\t\t\t\tawait cleanupSession();\n\n\t\t\t\t\treturn currentSession;\n\t\t\t\t});\n\n\t\t\t\tif (!currentSession?.access_token && !currentSession?.refresh_token) {\n\t\t\t\t\toptions.logging?.debug('Revoke called without session');\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\tconst tokenTypeHint = currentSession.refresh_token ? 'refresh_token' : 'access_token';\n\t\t\t\tconst token = (tokenTypeHint === 'refresh_token' ? currentSession.refresh_token : currentSession.access_token)!;\n\n\t\t\t\ttry {\n\t\t\t\t\tawait revokeToken({ tokenTypeHint, token, options });\n\n\t\t\t\t\tif (tokenTypeHint === 'refresh_token') {\n\t\t\t\t\t\tdispatchEvent('tokenRevoked', [{ token: currentSession.refresh_token, tokenTypeHint: 'refresh_token' }]);\n\t\t\t\t\t\toptions.logging?.info('Refresh token successfully revoked');\n\t\t\t\t\t} else {\n\t\t\t\t\t\tdispatchEvent('tokenRevoked', [{ token: currentSession.access_token, tokenTypeHint: 'access_token' }]);\n\t\t\t\t\t\toptions.logging?.info('Access token successfully revoked');\n\t\t\t\t\t}\n\t\t\t\t} catch (error) {\n\t\t\t\t\tif (tokenTypeHint === 'refresh_token') {\n\t\t\t\t\t\tdispatchEvent('tokenRevokeFailed', [{ token: currentSession.refresh_token, tokenTypeHint: 'refresh_token' }]);\n\t\t\t\t\t} else {\n\t\t\t\t\t\tdispatchEvent('tokenRevokeFailed', [{ token: currentSession.access_token, tokenTypeHint: 'access_token' }]);\n\t\t\t\t\t}\n\n\t\t\t\t\toptions.logging?.error('Token revocation failed', error);\n\t\t\t\t\tthrow error;\n\t\t\t\t}\n\t\t\t} finally {\n\t\t\t\tpromises.revoke = null;\n\t\t\t}\n\t\t})();\n\n\t\treturn promises.revoke;\n\t}\n\n\tasync function logout(\n\t\tparams?: Parameters<SDK<URLHandlerParams>['logout']>[0],\n\t\turlHandlerOverride?: typeof options.urlHandler,\n\t): ReturnType<SDK<URLHandlerParams>['logout']> {\n\t\tawait init();\n\n\t\tif (promises.logout) {\n\t\t\treturn promises.logout;\n\t\t}\n\n\t\tpromises.logout = (async () => {\n\t\t\ttry {\n\t\t\t\toptions.logging?.debug('Attempting to logout');\n\n\t\t\t\t// NOTE: Cleanup session before logout\n\t\t\t\tconst currentSession = await withSessionLock(async () => {\n\t\t\t\t\tconst currentSession = (await loadStoredSession()) ?? flowState.session;\n\t\t\t\t\tawait cleanupSession();\n\n\t\t\t\t\treturn currentSession;\n\t\t\t\t});\n\n\t\t\t\tdispatchEvent('logoutInitiated', [{ idToken: currentSession?.id_token, claims: currentSession?.claims }]);\n\t\t\t\toptions.logging?.debug('Logout initiated');\n\n\t\t\t\tif (!currentSession?.id_token) {\n\t\t\t\t\toptions.logging?.debug('Logout called without id token');\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\ttry {\n\t\t\t\t\tconst metadata = await getDiscoveryDocument(options);\n\t\t\t\t\tconst logoutUrl = buildEndSessionUrl({\n\t\t\t\t\t\turl: metadata.end_session_endpoint,\n\t\t\t\t\t\tidToken: currentSession.id_token,\n\t\t\t\t\t\tpostLogoutRedirectUri: params?.postLogoutRedirectUri,\n\t\t\t\t\t});\n\t\t\t\t\tconst urlHandler = urlHandlerOverride ?? options.urlHandler;\n\n\t\t\t\t\tawait urlHandler(logoutUrl, params);\n\t\t\t\t} catch (error) {\n\t\t\t\t\toptions.logging?.error('Unable to redirect to the end-session endpoint', error);\n\t\t\t\t}\n\t\t\t} finally {\n\t\t\t\tpromises.logout = null;\n\t\t\t}\n\t\t})();\n\n\t\treturn promises.logout;\n\t}\n\n\treturn {\n\t\tdispatchEvent,\n\t\tsubscribeToEvent,\n\t\tsubscribeToAllEvents,\n\t\tgetSession,\n\t\tupdateSession,\n\t\tcleanupSession,\n\t\tcheckAuthentication,\n\t\tinit,\n\t\ttokenExchange,\n\t\thandleCallback,\n\t\trefresh,\n\t\trevoke,\n\t\tlogout,\n\t};\n}\n"],"mappings":"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"}
@@ -1,2 +1,2 @@
1
- Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require("../utils/session.cjs"),t=require("../assets/oidc.cjs"),n=require("./base.cjs"),r=require("../handlers/popup.cjs");function i(i){i.urlHandler||=r.popupUrlHandler,i.callbackHandler||=r.popupCallbackHandler;let a=t.f(),o=t.m(i),s=n.createBaseFlow(a,o),{dispatchEvent:c,...l}=s;async function u(e={}){await s.init(),e??={},e.display=`popup`;let n=typeof o.serverSessionUri==`boolean`?void 0:o.serverSessionUri,r=await t.t({url:n,includeOAuthParams:!n,persistState:!n,params:e,options:o});s.dispatchEvent(`loginInitiated`,[]),o.logging?.debug(`Attempting to redirect for login`);let i=await o.urlHandler(r,e);o.serverSessionUri||await s.tokenExchange(i)}async function d(e={}){return await u({...e,prompt:`create`})}async function f(e,t){await s.init();let n=new URL(e??globalThis.window?.location.href);o.logging?.debug(`Attempting to redirect for entry`),await o.urlHandler(new URL(`/provider/entry?${n.searchParams.toString()}`,o.issuer),t)}let p={...l,get options(){return o},get initialized(){return a.initialized},get storage(){return o.storage},get httpClient(){return o.httpClient},get logging(){return o.logging},get shortAppId(){return a.shortAppId},set shortAppId(e){a.shortAppId=e},get sessionId(){return a.sessionId},set sessionId(e){a.sessionId=e},get session(){return a.session},set session(e){a.session=e},get language(){return a.language},set language(e){a.language=e},get isAuthenticated(){return s.checkAuthentication()},get isAuthenticatedSync(){return!!a.session&&!e.isSessionExpired(a.session)},get accessToken(){return a.session?.access_token??null},get accessTokenExpired(){return!a.session||e.isSessionExpired(a.session)},get accessTokenExpirationDate(){return a.session?.expires_at??null},get refreshToken(){return a.session?.refresh_token??null},get idToken(){return a.session?.id_token??null},get idTokenClaims(){return a.session?.claims??null},login:u,register:d,entry:f};return o.lazyLoad||p.init(),p}exports.createPopupFlow=i;
1
+ Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require("../utils/session.cjs"),t=require("../assets/oidc.cjs"),n=require("../handlers/redirect.cjs"),r=require("./base.cjs"),i=require("../handlers/popup.cjs");function a(a){a.urlHandler||=i.popupUrlHandler,a.callbackHandler||=i.popupCallbackHandler;let o=t.f(),s=t.m(a),c=r.createBaseFlow(o,s),{dispatchEvent:l,...u}=c;async function d(e={}){await c.init(),e??={},e.display=`popup`;let n=typeof s.serverSessionUri==`boolean`?void 0:s.serverSessionUri,r=await t.t({url:n,includeOAuthParams:!n,persistState:!n,params:e,options:s});c.dispatchEvent(`loginInitiated`,[]),s.logging?.debug(`Attempting to redirect for login`);let i=await s.urlHandler(r,e);s.serverSessionUri||await c.tokenExchange(i)}async function f(e={}){return await d({...e,prompt:`create`})}async function p(e){return await c.logout(e,n.redirectUrlHandler)}async function m(e,t){await c.init();let n=new URL(e??globalThis.window?.location.href);s.logging?.debug(`Attempting to redirect for entry`),await s.urlHandler(new URL(`/provider/entry?${n.searchParams.toString()}`,s.issuer),t)}let h={...u,get options(){return s},get initialized(){return o.initialized},get storage(){return s.storage},get httpClient(){return s.httpClient},get logging(){return s.logging},get shortAppId(){return o.shortAppId},set shortAppId(e){o.shortAppId=e},get sessionId(){return o.sessionId},set sessionId(e){o.sessionId=e},get session(){return o.session},set session(e){o.session=e},get language(){return o.language},set language(e){o.language=e},get isAuthenticated(){return c.checkAuthentication()},get isAuthenticatedSync(){return!!o.session&&!e.isSessionExpired(o.session)},get accessToken(){return o.session?.access_token??null},get accessTokenExpired(){return!o.session||e.isSessionExpired(o.session)},get accessTokenExpirationDate(){return o.session?.expires_at??null},get refreshToken(){return o.session?.refresh_token??null},get idToken(){return o.session?.id_token??null},get idTokenClaims(){return o.session?.claims??null},login:d,register:f,logout:p,entry:m};return s.lazyLoad||h.init(),h}exports.createPopupFlow=a;
2
2
  //# sourceMappingURL=popup.cjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"popup.cjs","names":[],"sources":["../../src/flows/popup.ts"],"sourcesContent":["import type { SDKInitConfig } from '../types/oidc';\nimport type { RedirectOptions } from '../types/redirect';\nimport type { PopupFlow } from '../types/popup';\nimport { getDefaultFlowState, getSDKOptions, buildAuthorizationUrl } from '../utils/oidc';\nimport { isSessionExpired } from '../utils/session';\nimport { popupCallbackHandler, popupUrlHandler } from '../handlers/popup';\nimport { createBaseFlow } from './base';\n\n/**\n * Creates a popup flow for the Strivacity SDK, providing functionality for managing authentication sessions in a popup context.\n *\n * @param initConfig - The initial configuration for the SDK, including issuer, clientId, redirectUri, and other options.\n * @returns An object implementing the PopupFlow interface, with methods for login, registration, and entry flows.\n */\nexport function createPopupFlow(initConfig: SDKInitConfig): PopupFlow {\n\tif (!initConfig.urlHandler) {\n\t\tinitConfig.urlHandler = popupUrlHandler;\n\t}\n\tif (!initConfig.callbackHandler) {\n\t\tinitConfig.callbackHandler = popupCallbackHandler;\n\t}\n\n\tconst flowState = getDefaultFlowState();\n\tconst options = getSDKOptions(initConfig);\n\tconst base = createBaseFlow(flowState, options);\n\t// eslint-disable-next-line @typescript-eslint/no-unused-vars\n\tconst { dispatchEvent: _, ...exposedBase } = base;\n\n\tasync function login(params: Parameters<PopupFlow['login']>[0] = {}): ReturnType<PopupFlow['login']> {\n\t\tawait base.init();\n\n\t\tparams ??= {};\n\t\tparams.display = 'popup';\n\n\t\tconst serverSessionUri = typeof options.serverSessionUri !== 'boolean' ? options.serverSessionUri : undefined;\n\t\tconst url = await buildAuthorizationUrl({\n\t\t\turl: serverSessionUri,\n\t\t\tincludeOAuthParams: !serverSessionUri,\n\t\t\tpersistState: !serverSessionUri,\n\t\t\tparams,\n\t\t\toptions,\n\t\t});\n\n\t\tbase.dispatchEvent('loginInitiated', []);\n\t\toptions.logging?.debug('Attempting to redirect for login');\n\n\t\tconst data = (await options.urlHandler(url, params)) as Record<string, string>;\n\n\t\tif (!options.serverSessionUri) {\n\t\t\tawait base.tokenExchange(data);\n\t\t}\n\t}\n\n\tasync function register(params: Parameters<PopupFlow['register']>[0] = {}): ReturnType<PopupFlow['register']> {\n\t\treturn await login({ ...params, prompt: 'create' });\n\t}\n\n\tasync function entry(url?: string | URL, params?: RedirectOptions): ReturnType<PopupFlow['entry']> {\n\t\tawait base.init();\n\n\t\tconst entryUrl = new URL(url ?? globalThis.window?.location.href);\n\n\t\toptions.logging?.debug('Attempting to redirect for entry');\n\n\t\tawait options.urlHandler(new URL(`/provider/entry?${entryUrl.searchParams.toString()}`, options.issuer), params);\n\t}\n\n\tconst flow = {\n\t\t...exposedBase,\n\t\tget options() {\n\t\t\treturn options;\n\t\t},\n\t\tget initialized() {\n\t\t\treturn flowState.initialized;\n\t\t},\n\t\tget storage() {\n\t\t\treturn options.storage;\n\t\t},\n\t\tget httpClient() {\n\t\t\treturn options.httpClient;\n\t\t},\n\t\tget logging() {\n\t\t\treturn options.logging;\n\t\t},\n\t\tget shortAppId() {\n\t\t\treturn flowState.shortAppId;\n\t\t},\n\t\tset shortAppId(shortAppId: string | null) {\n\t\t\tflowState.shortAppId = shortAppId;\n\t\t},\n\t\tget sessionId() {\n\t\t\treturn flowState.sessionId;\n\t\t},\n\t\tset sessionId(sessionId: string | null) {\n\t\t\tflowState.sessionId = sessionId;\n\t\t},\n\t\tget session() {\n\t\t\treturn flowState.session;\n\t\t},\n\t\tset session(session) {\n\t\t\tflowState.session = session;\n\t\t},\n\t\tget language() {\n\t\t\treturn flowState.language;\n\t\t},\n\t\tset language(lang) {\n\t\t\tflowState.language = lang;\n\t\t},\n\t\tget isAuthenticated() {\n\t\t\treturn base.checkAuthentication();\n\t\t},\n\t\tget isAuthenticatedSync() {\n\t\t\treturn !!flowState.session && !isSessionExpired(flowState.session);\n\t\t},\n\t\tget accessToken() {\n\t\t\treturn flowState.session?.access_token ?? null;\n\t\t},\n\t\tget accessTokenExpired() {\n\t\t\treturn !flowState.session || isSessionExpired(flowState.session);\n\t\t},\n\t\tget accessTokenExpirationDate() {\n\t\t\treturn flowState.session?.expires_at ?? null;\n\t\t},\n\t\tget refreshToken() {\n\t\t\treturn flowState.session?.refresh_token ?? null;\n\t\t},\n\t\tget idToken() {\n\t\t\treturn flowState.session?.id_token ?? null;\n\t\t},\n\t\tget idTokenClaims() {\n\t\t\treturn flowState.session?.claims ?? null;\n\t\t},\n\t\tlogin,\n\t\tregister,\n\t\tentry,\n\t} satisfies PopupFlow;\n\n\tif (!options.lazyLoad) {\n\t\tvoid flow.init();\n\t}\n\n\treturn flow;\n}\n"],"mappings":"sMAcA,SAAgB,EAAgB,EAAsC,CACrE,AACC,EAAW,aAAa,EAAA,gBAEzB,AACC,EAAW,kBAAkB,EAAA,qBAG9B,IAAM,EAAY,EAAA,EAAoB,EAChC,EAAU,EAAA,EAAc,CAAU,EAClC,EAAO,EAAA,eAAe,EAAW,CAAO,EAExC,CAAE,cAAe,EAAG,GAAG,GAAgB,EAE7C,eAAe,EAAM,EAA4C,CAAC,EAAmC,CACpG,MAAM,EAAK,KAAK,EAEhB,IAAW,CAAC,EACZ,EAAO,QAAU,QAEjB,IAAM,EAAmB,OAAO,EAAQ,kBAAqB,UAAuC,IAAA,GAA3B,EAAQ,iBAC3E,EAAM,MAAM,EAAA,EAAsB,CACvC,IAAK,EACL,mBAAoB,CAAC,EACrB,aAAc,CAAC,EACf,SACA,SACD,CAAC,EAED,EAAK,cAAc,iBAAkB,CAAC,CAAC,EACvC,EAAQ,SAAS,MAAM,kCAAkC,EAEzD,IAAM,EAAQ,MAAM,EAAQ,WAAW,EAAK,CAAM,EAE7C,EAAQ,kBACZ,MAAM,EAAK,cAAc,CAAI,CAE/B,CAEA,eAAe,EAAS,EAA+C,CAAC,EAAsC,CAC7G,OAAO,MAAM,EAAM,CAAE,GAAG,EAAQ,OAAQ,QAAS,CAAC,CACnD,CAEA,eAAe,EAAM,EAAoB,EAA0D,CAClG,MAAM,EAAK,KAAK,EAEhB,IAAM,EAAW,IAAI,IAAI,GAAO,WAAW,QAAQ,SAAS,IAAI,EAEhE,EAAQ,SAAS,MAAM,kCAAkC,EAEzD,MAAM,EAAQ,WAAW,IAAI,IAAI,mBAAmB,EAAS,aAAa,SAAS,IAAK,EAAQ,MAAM,EAAG,CAAM,CAChH,CAEA,IAAM,EAAO,CACZ,GAAG,EACH,IAAI,SAAU,CACb,OAAO,CACR,EACA,IAAI,aAAc,CACjB,OAAO,EAAU,WAClB,EACA,IAAI,SAAU,CACb,OAAO,EAAQ,OAChB,EACA,IAAI,YAAa,CAChB,OAAO,EAAQ,UAChB,EACA,IAAI,SAAU,CACb,OAAO,EAAQ,OAChB,EACA,IAAI,YAAa,CAChB,OAAO,EAAU,UAClB,EACA,IAAI,WAAW,EAA2B,CACzC,EAAU,WAAa,CACxB,EACA,IAAI,WAAY,CACf,OAAO,EAAU,SAClB,EACA,IAAI,UAAU,EAA0B,CACvC,EAAU,UAAY,CACvB,EACA,IAAI,SAAU,CACb,OAAO,EAAU,OAClB,EACA,IAAI,QAAQ,EAAS,CACpB,EAAU,QAAU,CACrB,EACA,IAAI,UAAW,CACd,OAAO,EAAU,QAClB,EACA,IAAI,SAAS,EAAM,CAClB,EAAU,SAAW,CACtB,EACA,IAAI,iBAAkB,CACrB,OAAO,EAAK,oBAAoB,CACjC,EACA,IAAI,qBAAsB,CACzB,MAAO,CAAC,CAAC,EAAU,SAAW,CAAC,EAAA,iBAAiB,EAAU,OAAO,CAClE,EACA,IAAI,aAAc,CACjB,OAAO,EAAU,SAAS,cAAgB,IAC3C,EACA,IAAI,oBAAqB,CACxB,MAAO,CAAC,EAAU,SAAW,EAAA,iBAAiB,EAAU,OAAO,CAChE,EACA,IAAI,2BAA4B,CAC/B,OAAO,EAAU,SAAS,YAAc,IACzC,EACA,IAAI,cAAe,CAClB,OAAO,EAAU,SAAS,eAAiB,IAC5C,EACA,IAAI,SAAU,CACb,OAAO,EAAU,SAAS,UAAY,IACvC,EACA,IAAI,eAAgB,CACnB,OAAO,EAAU,SAAS,QAAU,IACrC,EACA,QACA,WACA,OACD,EAMA,OAJK,EAAQ,UACZ,EAAU,KAAK,EAGT,CACR"}
1
+ {"version":3,"file":"popup.cjs","names":[],"sources":["../../src/flows/popup.ts"],"sourcesContent":["import type { SDKInitConfig } from '../types/oidc';\nimport type { RedirectOptions } from '../types/redirect';\nimport type { PopupFlow } from '../types/popup';\nimport { getDefaultFlowState, getSDKOptions, buildAuthorizationUrl } from '../utils/oidc';\nimport { isSessionExpired } from '../utils/session';\nimport { popupCallbackHandler, popupUrlHandler } from '../handlers/popup';\nimport { redirectUrlHandler } from '../handlers/redirect';\nimport { createBaseFlow } from './base';\n\n/**\n * Creates a popup flow for the Strivacity SDK, providing functionality for managing authentication sessions in a popup context.\n *\n * @param initConfig - The initial configuration for the SDK, including issuer, clientId, redirectUri, and other options.\n * @returns An object implementing the PopupFlow interface, with methods for login, registration, and entry flows.\n */\nexport function createPopupFlow(initConfig: SDKInitConfig): PopupFlow {\n\tif (!initConfig.urlHandler) {\n\t\tinitConfig.urlHandler = popupUrlHandler;\n\t}\n\tif (!initConfig.callbackHandler) {\n\t\tinitConfig.callbackHandler = popupCallbackHandler;\n\t}\n\n\tconst flowState = getDefaultFlowState();\n\tconst options = getSDKOptions(initConfig);\n\tconst base = createBaseFlow(flowState, options);\n\t// eslint-disable-next-line @typescript-eslint/no-unused-vars\n\tconst { dispatchEvent: _, ...exposedBase } = base;\n\n\tasync function login(params: Parameters<PopupFlow['login']>[0] = {}): ReturnType<PopupFlow['login']> {\n\t\tawait base.init();\n\n\t\tparams ??= {};\n\t\tparams.display = 'popup';\n\n\t\tconst serverSessionUri = typeof options.serverSessionUri !== 'boolean' ? options.serverSessionUri : undefined;\n\t\tconst url = await buildAuthorizationUrl({\n\t\t\turl: serverSessionUri,\n\t\t\tincludeOAuthParams: !serverSessionUri,\n\t\t\tpersistState: !serverSessionUri,\n\t\t\tparams,\n\t\t\toptions,\n\t\t});\n\n\t\tbase.dispatchEvent('loginInitiated', []);\n\t\toptions.logging?.debug('Attempting to redirect for login');\n\n\t\tconst data = (await options.urlHandler(url, params)) as Record<string, string>;\n\n\t\tif (!options.serverSessionUri) {\n\t\t\tawait base.tokenExchange(data);\n\t\t}\n\t}\n\n\tasync function register(params: Parameters<PopupFlow['register']>[0] = {}): ReturnType<PopupFlow['register']> {\n\t\treturn await login({ ...params, prompt: 'create' });\n\t}\n\n\tasync function logout(params?: Parameters<PopupFlow['logout']>[0]): ReturnType<PopupFlow['logout']> {\n\t\treturn await base.logout(params, redirectUrlHandler);\n\t}\n\n\tasync function entry(url?: string | URL, params?: RedirectOptions): ReturnType<PopupFlow['entry']> {\n\t\tawait base.init();\n\n\t\tconst entryUrl = new URL(url ?? globalThis.window?.location.href);\n\n\t\toptions.logging?.debug('Attempting to redirect for entry');\n\n\t\tawait options.urlHandler(new URL(`/provider/entry?${entryUrl.searchParams.toString()}`, options.issuer), params);\n\t}\n\n\tconst flow = {\n\t\t...exposedBase,\n\t\tget options() {\n\t\t\treturn options;\n\t\t},\n\t\tget initialized() {\n\t\t\treturn flowState.initialized;\n\t\t},\n\t\tget storage() {\n\t\t\treturn options.storage;\n\t\t},\n\t\tget httpClient() {\n\t\t\treturn options.httpClient;\n\t\t},\n\t\tget logging() {\n\t\t\treturn options.logging;\n\t\t},\n\t\tget shortAppId() {\n\t\t\treturn flowState.shortAppId;\n\t\t},\n\t\tset shortAppId(shortAppId: string | null) {\n\t\t\tflowState.shortAppId = shortAppId;\n\t\t},\n\t\tget sessionId() {\n\t\t\treturn flowState.sessionId;\n\t\t},\n\t\tset sessionId(sessionId: string | null) {\n\t\t\tflowState.sessionId = sessionId;\n\t\t},\n\t\tget session() {\n\t\t\treturn flowState.session;\n\t\t},\n\t\tset session(session) {\n\t\t\tflowState.session = session;\n\t\t},\n\t\tget language() {\n\t\t\treturn flowState.language;\n\t\t},\n\t\tset language(lang) {\n\t\t\tflowState.language = lang;\n\t\t},\n\t\tget isAuthenticated() {\n\t\t\treturn base.checkAuthentication();\n\t\t},\n\t\tget isAuthenticatedSync() {\n\t\t\treturn !!flowState.session && !isSessionExpired(flowState.session);\n\t\t},\n\t\tget accessToken() {\n\t\t\treturn flowState.session?.access_token ?? null;\n\t\t},\n\t\tget accessTokenExpired() {\n\t\t\treturn !flowState.session || isSessionExpired(flowState.session);\n\t\t},\n\t\tget accessTokenExpirationDate() {\n\t\t\treturn flowState.session?.expires_at ?? null;\n\t\t},\n\t\tget refreshToken() {\n\t\t\treturn flowState.session?.refresh_token ?? null;\n\t\t},\n\t\tget idToken() {\n\t\t\treturn flowState.session?.id_token ?? null;\n\t\t},\n\t\tget idTokenClaims() {\n\t\t\treturn flowState.session?.claims ?? null;\n\t\t},\n\t\tlogin,\n\t\tregister,\n\t\tlogout,\n\t\tentry,\n\t} satisfies PopupFlow;\n\n\tif (!options.lazyLoad) {\n\t\tvoid flow.init();\n\t}\n\n\treturn flow;\n}\n"],"mappings":"4OAeA,SAAgB,EAAgB,EAAsC,CACrE,AACC,EAAW,aAAa,EAAA,gBAEzB,AACC,EAAW,kBAAkB,EAAA,qBAG9B,IAAM,EAAY,EAAA,EAAoB,EAChC,EAAU,EAAA,EAAc,CAAU,EAClC,EAAO,EAAA,eAAe,EAAW,CAAO,EAExC,CAAE,cAAe,EAAG,GAAG,GAAgB,EAE7C,eAAe,EAAM,EAA4C,CAAC,EAAmC,CACpG,MAAM,EAAK,KAAK,EAEhB,IAAW,CAAC,EACZ,EAAO,QAAU,QAEjB,IAAM,EAAmB,OAAO,EAAQ,kBAAqB,UAAuC,IAAA,GAA3B,EAAQ,iBAC3E,EAAM,MAAM,EAAA,EAAsB,CACvC,IAAK,EACL,mBAAoB,CAAC,EACrB,aAAc,CAAC,EACf,SACA,SACD,CAAC,EAED,EAAK,cAAc,iBAAkB,CAAC,CAAC,EACvC,EAAQ,SAAS,MAAM,kCAAkC,EAEzD,IAAM,EAAQ,MAAM,EAAQ,WAAW,EAAK,CAAM,EAE7C,EAAQ,kBACZ,MAAM,EAAK,cAAc,CAAI,CAE/B,CAEA,eAAe,EAAS,EAA+C,CAAC,EAAsC,CAC7G,OAAO,MAAM,EAAM,CAAE,GAAG,EAAQ,OAAQ,QAAS,CAAC,CACnD,CAEA,eAAe,EAAO,EAA8E,CACnG,OAAO,MAAM,EAAK,OAAO,EAAQ,EAAA,kBAAkB,CACpD,CAEA,eAAe,EAAM,EAAoB,EAA0D,CAClG,MAAM,EAAK,KAAK,EAEhB,IAAM,EAAW,IAAI,IAAI,GAAO,WAAW,QAAQ,SAAS,IAAI,EAEhE,EAAQ,SAAS,MAAM,kCAAkC,EAEzD,MAAM,EAAQ,WAAW,IAAI,IAAI,mBAAmB,EAAS,aAAa,SAAS,IAAK,EAAQ,MAAM,EAAG,CAAM,CAChH,CAEA,IAAM,EAAO,CACZ,GAAG,EACH,IAAI,SAAU,CACb,OAAO,CACR,EACA,IAAI,aAAc,CACjB,OAAO,EAAU,WAClB,EACA,IAAI,SAAU,CACb,OAAO,EAAQ,OAChB,EACA,IAAI,YAAa,CAChB,OAAO,EAAQ,UAChB,EACA,IAAI,SAAU,CACb,OAAO,EAAQ,OAChB,EACA,IAAI,YAAa,CAChB,OAAO,EAAU,UAClB,EACA,IAAI,WAAW,EAA2B,CACzC,EAAU,WAAa,CACxB,EACA,IAAI,WAAY,CACf,OAAO,EAAU,SAClB,EACA,IAAI,UAAU,EAA0B,CACvC,EAAU,UAAY,CACvB,EACA,IAAI,SAAU,CACb,OAAO,EAAU,OAClB,EACA,IAAI,QAAQ,EAAS,CACpB,EAAU,QAAU,CACrB,EACA,IAAI,UAAW,CACd,OAAO,EAAU,QAClB,EACA,IAAI,SAAS,EAAM,CAClB,EAAU,SAAW,CACtB,EACA,IAAI,iBAAkB,CACrB,OAAO,EAAK,oBAAoB,CACjC,EACA,IAAI,qBAAsB,CACzB,MAAO,CAAC,CAAC,EAAU,SAAW,CAAC,EAAA,iBAAiB,EAAU,OAAO,CAClE,EACA,IAAI,aAAc,CACjB,OAAO,EAAU,SAAS,cAAgB,IAC3C,EACA,IAAI,oBAAqB,CACxB,MAAO,CAAC,EAAU,SAAW,EAAA,iBAAiB,EAAU,OAAO,CAChE,EACA,IAAI,2BAA4B,CAC/B,OAAO,EAAU,SAAS,YAAc,IACzC,EACA,IAAI,cAAe,CAClB,OAAO,EAAU,SAAS,eAAiB,IAC5C,EACA,IAAI,SAAU,CACb,OAAO,EAAU,SAAS,UAAY,IACvC,EACA,IAAI,eAAgB,CACnB,OAAO,EAAU,SAAS,QAAU,IACrC,EACA,QACA,WACA,SACA,OACD,EAMA,OAJK,EAAQ,UACZ,EAAU,KAAK,EAGT,CACR"}
@@ -1,2 +1,2 @@
1
- import{isSessionExpired as e}from"../utils/session.mjs";import{f as t,m as n,t as r}from"../assets/oidc.mjs";import{createBaseFlow as i}from"./base.mjs";import{popupCallbackHandler as a,popupUrlHandler as o}from"../handlers/popup.mjs";function s(s){s.urlHandler||=o,s.callbackHandler||=a;let c=t(),l=n(s),u=i(c,l),{dispatchEvent:d,...f}=u;async function p(e={}){await u.init(),e??={},e.display=`popup`;let t=typeof l.serverSessionUri==`boolean`?void 0:l.serverSessionUri,n=await r({url:t,includeOAuthParams:!t,persistState:!t,params:e,options:l});u.dispatchEvent(`loginInitiated`,[]),l.logging?.debug(`Attempting to redirect for login`);let i=await l.urlHandler(n,e);l.serverSessionUri||await u.tokenExchange(i)}async function m(e={}){return await p({...e,prompt:`create`})}async function h(e,t){await u.init();let n=new URL(e??globalThis.window?.location.href);l.logging?.debug(`Attempting to redirect for entry`),await l.urlHandler(new URL(`/provider/entry?${n.searchParams.toString()}`,l.issuer),t)}let g={...f,get options(){return l},get initialized(){return c.initialized},get storage(){return l.storage},get httpClient(){return l.httpClient},get logging(){return l.logging},get shortAppId(){return c.shortAppId},set shortAppId(e){c.shortAppId=e},get sessionId(){return c.sessionId},set sessionId(e){c.sessionId=e},get session(){return c.session},set session(e){c.session=e},get language(){return c.language},set language(e){c.language=e},get isAuthenticated(){return u.checkAuthentication()},get isAuthenticatedSync(){return!!c.session&&!e(c.session)},get accessToken(){return c.session?.access_token??null},get accessTokenExpired(){return!c.session||e(c.session)},get accessTokenExpirationDate(){return c.session?.expires_at??null},get refreshToken(){return c.session?.refresh_token??null},get idToken(){return c.session?.id_token??null},get idTokenClaims(){return c.session?.claims??null},login:p,register:m,entry:h};return l.lazyLoad||g.init(),g}export{s as createPopupFlow};
1
+ import{isSessionExpired as e}from"../utils/session.mjs";import{f as t,m as n,t as r}from"../assets/oidc.mjs";import{redirectUrlHandler as i}from"../handlers/redirect.mjs";import{createBaseFlow as a}from"./base.mjs";import{popupCallbackHandler as o,popupUrlHandler as s}from"../handlers/popup.mjs";function c(c){c.urlHandler||=s,c.callbackHandler||=o;let l=t(),u=n(c),d=a(l,u),{dispatchEvent:f,...p}=d;async function m(e={}){await d.init(),e??={},e.display=`popup`;let t=typeof u.serverSessionUri==`boolean`?void 0:u.serverSessionUri,n=await r({url:t,includeOAuthParams:!t,persistState:!t,params:e,options:u});d.dispatchEvent(`loginInitiated`,[]),u.logging?.debug(`Attempting to redirect for login`);let i=await u.urlHandler(n,e);u.serverSessionUri||await d.tokenExchange(i)}async function h(e={}){return await m({...e,prompt:`create`})}async function g(e){return await d.logout(e,i)}async function _(e,t){await d.init();let n=new URL(e??globalThis.window?.location.href);u.logging?.debug(`Attempting to redirect for entry`),await u.urlHandler(new URL(`/provider/entry?${n.searchParams.toString()}`,u.issuer),t)}let v={...p,get options(){return u},get initialized(){return l.initialized},get storage(){return u.storage},get httpClient(){return u.httpClient},get logging(){return u.logging},get shortAppId(){return l.shortAppId},set shortAppId(e){l.shortAppId=e},get sessionId(){return l.sessionId},set sessionId(e){l.sessionId=e},get session(){return l.session},set session(e){l.session=e},get language(){return l.language},set language(e){l.language=e},get isAuthenticated(){return d.checkAuthentication()},get isAuthenticatedSync(){return!!l.session&&!e(l.session)},get accessToken(){return l.session?.access_token??null},get accessTokenExpired(){return!l.session||e(l.session)},get accessTokenExpirationDate(){return l.session?.expires_at??null},get refreshToken(){return l.session?.refresh_token??null},get idToken(){return l.session?.id_token??null},get idTokenClaims(){return l.session?.claims??null},login:m,register:h,logout:g,entry:_};return u.lazyLoad||v.init(),v}export{c as createPopupFlow};
2
2
  //# sourceMappingURL=popup.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"popup.mjs","names":[],"sources":["../../src/flows/popup.ts"],"sourcesContent":["import type { SDKInitConfig } from '../types/oidc';\nimport type { RedirectOptions } from '../types/redirect';\nimport type { PopupFlow } from '../types/popup';\nimport { getDefaultFlowState, getSDKOptions, buildAuthorizationUrl } from '../utils/oidc';\nimport { isSessionExpired } from '../utils/session';\nimport { popupCallbackHandler, popupUrlHandler } from '../handlers/popup';\nimport { createBaseFlow } from './base';\n\n/**\n * Creates a popup flow for the Strivacity SDK, providing functionality for managing authentication sessions in a popup context.\n *\n * @param initConfig - The initial configuration for the SDK, including issuer, clientId, redirectUri, and other options.\n * @returns An object implementing the PopupFlow interface, with methods for login, registration, and entry flows.\n */\nexport function createPopupFlow(initConfig: SDKInitConfig): PopupFlow {\n\tif (!initConfig.urlHandler) {\n\t\tinitConfig.urlHandler = popupUrlHandler;\n\t}\n\tif (!initConfig.callbackHandler) {\n\t\tinitConfig.callbackHandler = popupCallbackHandler;\n\t}\n\n\tconst flowState = getDefaultFlowState();\n\tconst options = getSDKOptions(initConfig);\n\tconst base = createBaseFlow(flowState, options);\n\t// eslint-disable-next-line @typescript-eslint/no-unused-vars\n\tconst { dispatchEvent: _, ...exposedBase } = base;\n\n\tasync function login(params: Parameters<PopupFlow['login']>[0] = {}): ReturnType<PopupFlow['login']> {\n\t\tawait base.init();\n\n\t\tparams ??= {};\n\t\tparams.display = 'popup';\n\n\t\tconst serverSessionUri = typeof options.serverSessionUri !== 'boolean' ? options.serverSessionUri : undefined;\n\t\tconst url = await buildAuthorizationUrl({\n\t\t\turl: serverSessionUri,\n\t\t\tincludeOAuthParams: !serverSessionUri,\n\t\t\tpersistState: !serverSessionUri,\n\t\t\tparams,\n\t\t\toptions,\n\t\t});\n\n\t\tbase.dispatchEvent('loginInitiated', []);\n\t\toptions.logging?.debug('Attempting to redirect for login');\n\n\t\tconst data = (await options.urlHandler(url, params)) as Record<string, string>;\n\n\t\tif (!options.serverSessionUri) {\n\t\t\tawait base.tokenExchange(data);\n\t\t}\n\t}\n\n\tasync function register(params: Parameters<PopupFlow['register']>[0] = {}): ReturnType<PopupFlow['register']> {\n\t\treturn await login({ ...params, prompt: 'create' });\n\t}\n\n\tasync function entry(url?: string | URL, params?: RedirectOptions): ReturnType<PopupFlow['entry']> {\n\t\tawait base.init();\n\n\t\tconst entryUrl = new URL(url ?? globalThis.window?.location.href);\n\n\t\toptions.logging?.debug('Attempting to redirect for entry');\n\n\t\tawait options.urlHandler(new URL(`/provider/entry?${entryUrl.searchParams.toString()}`, options.issuer), params);\n\t}\n\n\tconst flow = {\n\t\t...exposedBase,\n\t\tget options() {\n\t\t\treturn options;\n\t\t},\n\t\tget initialized() {\n\t\t\treturn flowState.initialized;\n\t\t},\n\t\tget storage() {\n\t\t\treturn options.storage;\n\t\t},\n\t\tget httpClient() {\n\t\t\treturn options.httpClient;\n\t\t},\n\t\tget logging() {\n\t\t\treturn options.logging;\n\t\t},\n\t\tget shortAppId() {\n\t\t\treturn flowState.shortAppId;\n\t\t},\n\t\tset shortAppId(shortAppId: string | null) {\n\t\t\tflowState.shortAppId = shortAppId;\n\t\t},\n\t\tget sessionId() {\n\t\t\treturn flowState.sessionId;\n\t\t},\n\t\tset sessionId(sessionId: string | null) {\n\t\t\tflowState.sessionId = sessionId;\n\t\t},\n\t\tget session() {\n\t\t\treturn flowState.session;\n\t\t},\n\t\tset session(session) {\n\t\t\tflowState.session = session;\n\t\t},\n\t\tget language() {\n\t\t\treturn flowState.language;\n\t\t},\n\t\tset language(lang) {\n\t\t\tflowState.language = lang;\n\t\t},\n\t\tget isAuthenticated() {\n\t\t\treturn base.checkAuthentication();\n\t\t},\n\t\tget isAuthenticatedSync() {\n\t\t\treturn !!flowState.session && !isSessionExpired(flowState.session);\n\t\t},\n\t\tget accessToken() {\n\t\t\treturn flowState.session?.access_token ?? null;\n\t\t},\n\t\tget accessTokenExpired() {\n\t\t\treturn !flowState.session || isSessionExpired(flowState.session);\n\t\t},\n\t\tget accessTokenExpirationDate() {\n\t\t\treturn flowState.session?.expires_at ?? null;\n\t\t},\n\t\tget refreshToken() {\n\t\t\treturn flowState.session?.refresh_token ?? null;\n\t\t},\n\t\tget idToken() {\n\t\t\treturn flowState.session?.id_token ?? null;\n\t\t},\n\t\tget idTokenClaims() {\n\t\t\treturn flowState.session?.claims ?? null;\n\t\t},\n\t\tlogin,\n\t\tregister,\n\t\tentry,\n\t} satisfies PopupFlow;\n\n\tif (!options.lazyLoad) {\n\t\tvoid flow.init();\n\t}\n\n\treturn flow;\n}\n"],"mappings":"2OAcA,SAAgB,EAAgB,EAAsC,CACrE,AACC,EAAW,aAAa,EAEzB,AACC,EAAW,kBAAkB,EAG9B,IAAM,EAAY,EAAoB,EAChC,EAAU,EAAc,CAAU,EAClC,EAAO,EAAe,EAAW,CAAO,EAExC,CAAE,cAAe,EAAG,GAAG,GAAgB,EAE7C,eAAe,EAAM,EAA4C,CAAC,EAAmC,CACpG,MAAM,EAAK,KAAK,EAEhB,IAAW,CAAC,EACZ,EAAO,QAAU,QAEjB,IAAM,EAAmB,OAAO,EAAQ,kBAAqB,UAAuC,IAAA,GAA3B,EAAQ,iBAC3E,EAAM,MAAM,EAAsB,CACvC,IAAK,EACL,mBAAoB,CAAC,EACrB,aAAc,CAAC,EACf,SACA,SACD,CAAC,EAED,EAAK,cAAc,iBAAkB,CAAC,CAAC,EACvC,EAAQ,SAAS,MAAM,kCAAkC,EAEzD,IAAM,EAAQ,MAAM,EAAQ,WAAW,EAAK,CAAM,EAE7C,EAAQ,kBACZ,MAAM,EAAK,cAAc,CAAI,CAE/B,CAEA,eAAe,EAAS,EAA+C,CAAC,EAAsC,CAC7G,OAAO,MAAM,EAAM,CAAE,GAAG,EAAQ,OAAQ,QAAS,CAAC,CACnD,CAEA,eAAe,EAAM,EAAoB,EAA0D,CAClG,MAAM,EAAK,KAAK,EAEhB,IAAM,EAAW,IAAI,IAAI,GAAO,WAAW,QAAQ,SAAS,IAAI,EAEhE,EAAQ,SAAS,MAAM,kCAAkC,EAEzD,MAAM,EAAQ,WAAW,IAAI,IAAI,mBAAmB,EAAS,aAAa,SAAS,IAAK,EAAQ,MAAM,EAAG,CAAM,CAChH,CAEA,IAAM,EAAO,CACZ,GAAG,EACH,IAAI,SAAU,CACb,OAAO,CACR,EACA,IAAI,aAAc,CACjB,OAAO,EAAU,WAClB,EACA,IAAI,SAAU,CACb,OAAO,EAAQ,OAChB,EACA,IAAI,YAAa,CAChB,OAAO,EAAQ,UAChB,EACA,IAAI,SAAU,CACb,OAAO,EAAQ,OAChB,EACA,IAAI,YAAa,CAChB,OAAO,EAAU,UAClB,EACA,IAAI,WAAW,EAA2B,CACzC,EAAU,WAAa,CACxB,EACA,IAAI,WAAY,CACf,OAAO,EAAU,SAClB,EACA,IAAI,UAAU,EAA0B,CACvC,EAAU,UAAY,CACvB,EACA,IAAI,SAAU,CACb,OAAO,EAAU,OAClB,EACA,IAAI,QAAQ,EAAS,CACpB,EAAU,QAAU,CACrB,EACA,IAAI,UAAW,CACd,OAAO,EAAU,QAClB,EACA,IAAI,SAAS,EAAM,CAClB,EAAU,SAAW,CACtB,EACA,IAAI,iBAAkB,CACrB,OAAO,EAAK,oBAAoB,CACjC,EACA,IAAI,qBAAsB,CACzB,MAAO,CAAC,CAAC,EAAU,SAAW,CAAC,EAAiB,EAAU,OAAO,CAClE,EACA,IAAI,aAAc,CACjB,OAAO,EAAU,SAAS,cAAgB,IAC3C,EACA,IAAI,oBAAqB,CACxB,MAAO,CAAC,EAAU,SAAW,EAAiB,EAAU,OAAO,CAChE,EACA,IAAI,2BAA4B,CAC/B,OAAO,EAAU,SAAS,YAAc,IACzC,EACA,IAAI,cAAe,CAClB,OAAO,EAAU,SAAS,eAAiB,IAC5C,EACA,IAAI,SAAU,CACb,OAAO,EAAU,SAAS,UAAY,IACvC,EACA,IAAI,eAAgB,CACnB,OAAO,EAAU,SAAS,QAAU,IACrC,EACA,QACA,WACA,OACD,EAMA,OAJK,EAAQ,UACZ,EAAU,KAAK,EAGT,CACR"}
1
+ {"version":3,"file":"popup.mjs","names":[],"sources":["../../src/flows/popup.ts"],"sourcesContent":["import type { SDKInitConfig } from '../types/oidc';\nimport type { RedirectOptions } from '../types/redirect';\nimport type { PopupFlow } from '../types/popup';\nimport { getDefaultFlowState, getSDKOptions, buildAuthorizationUrl } from '../utils/oidc';\nimport { isSessionExpired } from '../utils/session';\nimport { popupCallbackHandler, popupUrlHandler } from '../handlers/popup';\nimport { redirectUrlHandler } from '../handlers/redirect';\nimport { createBaseFlow } from './base';\n\n/**\n * Creates a popup flow for the Strivacity SDK, providing functionality for managing authentication sessions in a popup context.\n *\n * @param initConfig - The initial configuration for the SDK, including issuer, clientId, redirectUri, and other options.\n * @returns An object implementing the PopupFlow interface, with methods for login, registration, and entry flows.\n */\nexport function createPopupFlow(initConfig: SDKInitConfig): PopupFlow {\n\tif (!initConfig.urlHandler) {\n\t\tinitConfig.urlHandler = popupUrlHandler;\n\t}\n\tif (!initConfig.callbackHandler) {\n\t\tinitConfig.callbackHandler = popupCallbackHandler;\n\t}\n\n\tconst flowState = getDefaultFlowState();\n\tconst options = getSDKOptions(initConfig);\n\tconst base = createBaseFlow(flowState, options);\n\t// eslint-disable-next-line @typescript-eslint/no-unused-vars\n\tconst { dispatchEvent: _, ...exposedBase } = base;\n\n\tasync function login(params: Parameters<PopupFlow['login']>[0] = {}): ReturnType<PopupFlow['login']> {\n\t\tawait base.init();\n\n\t\tparams ??= {};\n\t\tparams.display = 'popup';\n\n\t\tconst serverSessionUri = typeof options.serverSessionUri !== 'boolean' ? options.serverSessionUri : undefined;\n\t\tconst url = await buildAuthorizationUrl({\n\t\t\turl: serverSessionUri,\n\t\t\tincludeOAuthParams: !serverSessionUri,\n\t\t\tpersistState: !serverSessionUri,\n\t\t\tparams,\n\t\t\toptions,\n\t\t});\n\n\t\tbase.dispatchEvent('loginInitiated', []);\n\t\toptions.logging?.debug('Attempting to redirect for login');\n\n\t\tconst data = (await options.urlHandler(url, params)) as Record<string, string>;\n\n\t\tif (!options.serverSessionUri) {\n\t\t\tawait base.tokenExchange(data);\n\t\t}\n\t}\n\n\tasync function register(params: Parameters<PopupFlow['register']>[0] = {}): ReturnType<PopupFlow['register']> {\n\t\treturn await login({ ...params, prompt: 'create' });\n\t}\n\n\tasync function logout(params?: Parameters<PopupFlow['logout']>[0]): ReturnType<PopupFlow['logout']> {\n\t\treturn await base.logout(params, redirectUrlHandler);\n\t}\n\n\tasync function entry(url?: string | URL, params?: RedirectOptions): ReturnType<PopupFlow['entry']> {\n\t\tawait base.init();\n\n\t\tconst entryUrl = new URL(url ?? globalThis.window?.location.href);\n\n\t\toptions.logging?.debug('Attempting to redirect for entry');\n\n\t\tawait options.urlHandler(new URL(`/provider/entry?${entryUrl.searchParams.toString()}`, options.issuer), params);\n\t}\n\n\tconst flow = {\n\t\t...exposedBase,\n\t\tget options() {\n\t\t\treturn options;\n\t\t},\n\t\tget initialized() {\n\t\t\treturn flowState.initialized;\n\t\t},\n\t\tget storage() {\n\t\t\treturn options.storage;\n\t\t},\n\t\tget httpClient() {\n\t\t\treturn options.httpClient;\n\t\t},\n\t\tget logging() {\n\t\t\treturn options.logging;\n\t\t},\n\t\tget shortAppId() {\n\t\t\treturn flowState.shortAppId;\n\t\t},\n\t\tset shortAppId(shortAppId: string | null) {\n\t\t\tflowState.shortAppId = shortAppId;\n\t\t},\n\t\tget sessionId() {\n\t\t\treturn flowState.sessionId;\n\t\t},\n\t\tset sessionId(sessionId: string | null) {\n\t\t\tflowState.sessionId = sessionId;\n\t\t},\n\t\tget session() {\n\t\t\treturn flowState.session;\n\t\t},\n\t\tset session(session) {\n\t\t\tflowState.session = session;\n\t\t},\n\t\tget language() {\n\t\t\treturn flowState.language;\n\t\t},\n\t\tset language(lang) {\n\t\t\tflowState.language = lang;\n\t\t},\n\t\tget isAuthenticated() {\n\t\t\treturn base.checkAuthentication();\n\t\t},\n\t\tget isAuthenticatedSync() {\n\t\t\treturn !!flowState.session && !isSessionExpired(flowState.session);\n\t\t},\n\t\tget accessToken() {\n\t\t\treturn flowState.session?.access_token ?? null;\n\t\t},\n\t\tget accessTokenExpired() {\n\t\t\treturn !flowState.session || isSessionExpired(flowState.session);\n\t\t},\n\t\tget accessTokenExpirationDate() {\n\t\t\treturn flowState.session?.expires_at ?? null;\n\t\t},\n\t\tget refreshToken() {\n\t\t\treturn flowState.session?.refresh_token ?? null;\n\t\t},\n\t\tget idToken() {\n\t\t\treturn flowState.session?.id_token ?? null;\n\t\t},\n\t\tget idTokenClaims() {\n\t\t\treturn flowState.session?.claims ?? null;\n\t\t},\n\t\tlogin,\n\t\tregister,\n\t\tlogout,\n\t\tentry,\n\t} satisfies PopupFlow;\n\n\tif (!options.lazyLoad) {\n\t\tvoid flow.init();\n\t}\n\n\treturn flow;\n}\n"],"mappings":"ySAeA,SAAgB,EAAgB,EAAsC,CACrE,AACC,EAAW,aAAa,EAEzB,AACC,EAAW,kBAAkB,EAG9B,IAAM,EAAY,EAAoB,EAChC,EAAU,EAAc,CAAU,EAClC,EAAO,EAAe,EAAW,CAAO,EAExC,CAAE,cAAe,EAAG,GAAG,GAAgB,EAE7C,eAAe,EAAM,EAA4C,CAAC,EAAmC,CACpG,MAAM,EAAK,KAAK,EAEhB,IAAW,CAAC,EACZ,EAAO,QAAU,QAEjB,IAAM,EAAmB,OAAO,EAAQ,kBAAqB,UAAuC,IAAA,GAA3B,EAAQ,iBAC3E,EAAM,MAAM,EAAsB,CACvC,IAAK,EACL,mBAAoB,CAAC,EACrB,aAAc,CAAC,EACf,SACA,SACD,CAAC,EAED,EAAK,cAAc,iBAAkB,CAAC,CAAC,EACvC,EAAQ,SAAS,MAAM,kCAAkC,EAEzD,IAAM,EAAQ,MAAM,EAAQ,WAAW,EAAK,CAAM,EAE7C,EAAQ,kBACZ,MAAM,EAAK,cAAc,CAAI,CAE/B,CAEA,eAAe,EAAS,EAA+C,CAAC,EAAsC,CAC7G,OAAO,MAAM,EAAM,CAAE,GAAG,EAAQ,OAAQ,QAAS,CAAC,CACnD,CAEA,eAAe,EAAO,EAA8E,CACnG,OAAO,MAAM,EAAK,OAAO,EAAQ,CAAkB,CACpD,CAEA,eAAe,EAAM,EAAoB,EAA0D,CAClG,MAAM,EAAK,KAAK,EAEhB,IAAM,EAAW,IAAI,IAAI,GAAO,WAAW,QAAQ,SAAS,IAAI,EAEhE,EAAQ,SAAS,MAAM,kCAAkC,EAEzD,MAAM,EAAQ,WAAW,IAAI,IAAI,mBAAmB,EAAS,aAAa,SAAS,IAAK,EAAQ,MAAM,EAAG,CAAM,CAChH,CAEA,IAAM,EAAO,CACZ,GAAG,EACH,IAAI,SAAU,CACb,OAAO,CACR,EACA,IAAI,aAAc,CACjB,OAAO,EAAU,WAClB,EACA,IAAI,SAAU,CACb,OAAO,EAAQ,OAChB,EACA,IAAI,YAAa,CAChB,OAAO,EAAQ,UAChB,EACA,IAAI,SAAU,CACb,OAAO,EAAQ,OAChB,EACA,IAAI,YAAa,CAChB,OAAO,EAAU,UAClB,EACA,IAAI,WAAW,EAA2B,CACzC,EAAU,WAAa,CACxB,EACA,IAAI,WAAY,CACf,OAAO,EAAU,SAClB,EACA,IAAI,UAAU,EAA0B,CACvC,EAAU,UAAY,CACvB,EACA,IAAI,SAAU,CACb,OAAO,EAAU,OAClB,EACA,IAAI,QAAQ,EAAS,CACpB,EAAU,QAAU,CACrB,EACA,IAAI,UAAW,CACd,OAAO,EAAU,QAClB,EACA,IAAI,SAAS,EAAM,CAClB,EAAU,SAAW,CACtB,EACA,IAAI,iBAAkB,CACrB,OAAO,EAAK,oBAAoB,CACjC,EACA,IAAI,qBAAsB,CACzB,MAAO,CAAC,CAAC,EAAU,SAAW,CAAC,EAAiB,EAAU,OAAO,CAClE,EACA,IAAI,aAAc,CACjB,OAAO,EAAU,SAAS,cAAgB,IAC3C,EACA,IAAI,oBAAqB,CACxB,MAAO,CAAC,EAAU,SAAW,EAAiB,EAAU,OAAO,CAChE,EACA,IAAI,2BAA4B,CAC/B,OAAO,EAAU,SAAS,YAAc,IACzC,EACA,IAAI,cAAe,CAClB,OAAO,EAAU,SAAS,eAAiB,IAC5C,EACA,IAAI,SAAU,CACb,OAAO,EAAU,SAAS,UAAY,IACvC,EACA,IAAI,eAAgB,CACnB,OAAO,EAAU,SAAS,QAAU,IACrC,EACA,QACA,WACA,SACA,OACD,EAMA,OAJK,EAAQ,UACZ,EAAU,KAAK,EAGT,CACR"}
package/dist/index.cjs CHANGED
@@ -1,2 +1,2 @@
1
- Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require("./utils/errors.cjs"),t=require("./flows/redirect.cjs"),n=require("./flows/popup.cjs"),r=require("./flows/embedded.cjs"),i=require("./flows/native.cjs");function a(a){if(typeof a.factory==`function`)return a.factory(a);if(a.mode===`redirect`)return t.createRedirectFlow(a);if(a.mode===`popup`)return n.createPopupFlow(a);if(a.mode===`embedded`)return r.createEmbeddedFlow(a);if(a.mode===`native`)return i.createNativeFlow(a);throw new e.UnsupportedFlowError}exports.initFlow=a;
1
+ Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require("./utils/errors.cjs"),t=require("./flows/redirect.cjs"),n=require("./flows/popup.cjs"),r=require("./flows/embedded.cjs"),i=require("./flows/native.cjs");function a(a){if(typeof a.factory==`function`)return a.factory({...a,mode:a.mode??`redirect`});let o=a;if(o.mode===`redirect`)return t.createRedirectFlow(o);if(o.mode===`popup`)return n.createPopupFlow(o);if(o.mode===`embedded`)return r.createEmbeddedFlow(o);if(o.mode===`native`)return i.createNativeFlow(o);throw new e.UnsupportedFlowError}exports.initFlow=a;
2
2
  //# sourceMappingURL=index.cjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.cjs","names":[],"sources":["../src/index.ts"],"sourcesContent":["import type { SDKInitConfig, RedirectFlow, PopupFlow, EmbeddedFlow, NativeFlow } from './types';\nimport { UnsupportedFlowError } from './utils/errors';\nimport { createRedirectFlow } from './flows/redirect';\nimport { createPopupFlow } from './flows/popup';\nimport { createEmbeddedFlow } from './flows/embedded';\nimport { createNativeFlow } from './flows/native';\n\nexport type * from './types';\n\n/**\n * Initializes an authentication flow based on the specified mode.\n *\n * @template T - The type of the flow instance returned by the factory function.\n * @param {SDKInitConfig & { mode?: 'popup' | 'redirect' | 'embedded' | 'native' }} options - The configuration options for the SDK.\n * @returns T | PopupFlow | RedirectFlow | EmbeddedFlow | NativeFlow} - The initialized flow instance.\n * @throws {UnsupportedFlowError} If the specified mode is not supported.\n */\nexport function initFlow<T>(options: SDKInitConfig): T;\nexport function initFlow(options: SDKInitConfig & { mode: 'popup'; lazyLoad: true }): PopupFlow;\nexport function initFlow(options: SDKInitConfig & { mode: 'redirect'; lazyLoad: true }): RedirectFlow;\nexport function initFlow(options: SDKInitConfig & { mode: 'embedded'; lazyLoad: true }): EmbeddedFlow;\nexport function initFlow(options: SDKInitConfig & { mode: 'native'; lazyLoad: true }): NativeFlow;\nexport function initFlow(\n\toptions: SDKInitConfig & { mode?: 'popup' | 'redirect' | 'embedded' | 'native' },\n): Promise<PopupFlow | RedirectFlow | EmbeddedFlow | NativeFlow> | PopupFlow | RedirectFlow | EmbeddedFlow | NativeFlow | unknown {\n\tif (typeof options.factory === 'function') {\n\t\treturn options.factory(options);\n\t}\n\n\tif (options.mode === 'redirect') {\n\t\treturn createRedirectFlow(options);\n\t} else if (options.mode === 'popup') {\n\t\treturn createPopupFlow(options);\n\t} else if (options.mode === 'embedded') {\n\t\treturn createEmbeddedFlow(options);\n\t} else if (options.mode === 'native') {\n\t\treturn createNativeFlow(options);\n\t}\n\n\tthrow new UnsupportedFlowError();\n}\n"],"mappings":"4OAsBA,SAAgB,EACf,EACiI,CACjI,GAAI,OAAO,EAAQ,SAAY,WAC9B,OAAO,EAAQ,QAAQ,CAAO,EAG/B,GAAI,EAAQ,OAAS,WACpB,OAAO,EAAA,mBAAmB,CAAO,EAC3B,GAAI,EAAQ,OAAS,QAC3B,OAAO,EAAA,gBAAgB,CAAO,EACxB,GAAI,EAAQ,OAAS,WAC3B,OAAO,EAAA,mBAAmB,CAAO,EAC3B,GAAI,EAAQ,OAAS,SAC3B,OAAO,EAAA,iBAAiB,CAAO,EAGhC,MAAM,IAAI,EAAA,oBACX"}
1
+ {"version":3,"file":"index.cjs","names":[],"sources":["../src/index.ts"],"sourcesContent":["import type { SDKInitConfig, SDKOptions, RedirectFlow, PopupFlow, EmbeddedFlow, NativeFlow } from './types';\nimport { UnsupportedFlowError } from './utils/errors';\nimport { createRedirectFlow } from './flows/redirect';\nimport { createPopupFlow } from './flows/popup';\nimport { createEmbeddedFlow } from './flows/embedded';\nimport { createNativeFlow } from './flows/native';\n\nexport type * from './types';\n\n/**\n * Initializes an authentication flow based on the specified mode.\n *\n * @template T - The type of the flow instance returned by the factory function.\n * @param {SDKInitConfig} options - The configuration options for the SDK. `mode` is optional when `factory` is set (the factory receives `'redirect'` by default).\n * @returns T | PopupFlow | RedirectFlow | EmbeddedFlow | NativeFlow} - The initialized flow instance.\n * @throws {UnsupportedFlowError} If the specified mode is not supported.\n */\nexport function initFlow<T>(options: Omit<SDKInitConfig, 'mode' | 'factory'> & { mode?: SDKOptions['mode']; factory: (options: SDKInitConfig) => T }): T;\nexport function initFlow<T>(options: SDKInitConfig): T;\nexport function initFlow(options: SDKInitConfig & { mode: 'popup'; lazyLoad: true }): PopupFlow;\nexport function initFlow(options: SDKInitConfig & { mode: 'redirect'; lazyLoad: true }): RedirectFlow;\nexport function initFlow(options: SDKInitConfig & { mode: 'embedded'; lazyLoad: true }): EmbeddedFlow;\nexport function initFlow(options: SDKInitConfig & { mode: 'native'; lazyLoad: true }): NativeFlow;\nexport function initFlow(\n\toptions: Omit<SDKInitConfig, 'mode'> & { mode?: SDKOptions['mode'] },\n): Promise<PopupFlow | RedirectFlow | EmbeddedFlow | NativeFlow> | PopupFlow | RedirectFlow | EmbeddedFlow | NativeFlow | unknown {\n\tif (typeof options.factory === 'function') {\n\t\treturn options.factory({ ...options, mode: options.mode ?? 'redirect' });\n\t}\n\n\tconst config = options as SDKInitConfig;\n\n\tif (config.mode === 'redirect') {\n\t\treturn createRedirectFlow(config);\n\t} else if (config.mode === 'popup') {\n\t\treturn createPopupFlow(config);\n\t} else if (config.mode === 'embedded') {\n\t\treturn createEmbeddedFlow(config);\n\t} else if (config.mode === 'native') {\n\t\treturn createNativeFlow(config);\n\t}\n\n\tthrow new UnsupportedFlowError();\n}\n"],"mappings":"4OAuBA,SAAgB,EACf,EACiI,CACjI,GAAI,OAAO,EAAQ,SAAY,WAC9B,OAAO,EAAQ,QAAQ,CAAE,GAAG,EAAS,KAAM,EAAQ,MAAQ,UAAW,CAAC,EAGxE,IAAM,EAAS,EAEf,GAAI,EAAO,OAAS,WACnB,OAAO,EAAA,mBAAmB,CAAM,EAC1B,GAAI,EAAO,OAAS,QAC1B,OAAO,EAAA,gBAAgB,CAAM,EACvB,GAAI,EAAO,OAAS,WAC1B,OAAO,EAAA,mBAAmB,CAAM,EAC1B,GAAI,EAAO,OAAS,SAC1B,OAAO,EAAA,iBAAiB,CAAM,EAG/B,MAAM,IAAI,EAAA,oBACX"}
package/dist/index.d.ts CHANGED
@@ -1,13 +1,17 @@
1
- import { SDKInitConfig, RedirectFlow, PopupFlow, EmbeddedFlow, NativeFlow } from './types';
1
+ import { SDKInitConfig, SDKOptions, RedirectFlow, PopupFlow, EmbeddedFlow, NativeFlow } from './types';
2
2
  export type * from './types';
3
3
  /**
4
4
  * Initializes an authentication flow based on the specified mode.
5
5
  *
6
6
  * @template T - The type of the flow instance returned by the factory function.
7
- * @param {SDKInitConfig & { mode?: 'popup' | 'redirect' | 'embedded' | 'native' }} options - The configuration options for the SDK.
7
+ * @param {SDKInitConfig} options - The configuration options for the SDK. `mode` is optional when `factory` is set (the factory receives `'redirect'` by default).
8
8
  * @returns T | PopupFlow | RedirectFlow | EmbeddedFlow | NativeFlow} - The initialized flow instance.
9
9
  * @throws {UnsupportedFlowError} If the specified mode is not supported.
10
10
  */
11
+ export declare function initFlow<T>(options: Omit<SDKInitConfig, 'mode' | 'factory'> & {
12
+ mode?: SDKOptions['mode'];
13
+ factory: (options: SDKInitConfig) => T;
14
+ }): T;
11
15
  export declare function initFlow<T>(options: SDKInitConfig): T;
12
16
  export declare function initFlow(options: SDKInitConfig & {
13
17
  mode: 'popup';
package/dist/index.mjs CHANGED
@@ -1,2 +1,2 @@
1
- import{UnsupportedFlowError as e}from"./utils/errors.mjs";import{createRedirectFlow as t}from"./flows/redirect.mjs";import{createPopupFlow as n}from"./flows/popup.mjs";import{createEmbeddedFlow as r}from"./flows/embedded.mjs";import{createNativeFlow as i}from"./flows/native.mjs";function a(a){if(typeof a.factory==`function`)return a.factory(a);if(a.mode===`redirect`)return t(a);if(a.mode===`popup`)return n(a);if(a.mode===`embedded`)return r(a);if(a.mode===`native`)return i(a);throw new e}export{a as initFlow};
1
+ import{UnsupportedFlowError as e}from"./utils/errors.mjs";import{createRedirectFlow as t}from"./flows/redirect.mjs";import{createPopupFlow as n}from"./flows/popup.mjs";import{createEmbeddedFlow as r}from"./flows/embedded.mjs";import{createNativeFlow as i}from"./flows/native.mjs";function a(a){if(typeof a.factory==`function`)return a.factory({...a,mode:a.mode??`redirect`});let o=a;if(o.mode===`redirect`)return t(o);if(o.mode===`popup`)return n(o);if(o.mode===`embedded`)return r(o);if(o.mode===`native`)return i(o);throw new e}export{a as initFlow};
2
2
  //# sourceMappingURL=index.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.mjs","names":[],"sources":["../src/index.ts"],"sourcesContent":["import type { SDKInitConfig, RedirectFlow, PopupFlow, EmbeddedFlow, NativeFlow } from './types';\nimport { UnsupportedFlowError } from './utils/errors';\nimport { createRedirectFlow } from './flows/redirect';\nimport { createPopupFlow } from './flows/popup';\nimport { createEmbeddedFlow } from './flows/embedded';\nimport { createNativeFlow } from './flows/native';\n\nexport type * from './types';\n\n/**\n * Initializes an authentication flow based on the specified mode.\n *\n * @template T - The type of the flow instance returned by the factory function.\n * @param {SDKInitConfig & { mode?: 'popup' | 'redirect' | 'embedded' | 'native' }} options - The configuration options for the SDK.\n * @returns T | PopupFlow | RedirectFlow | EmbeddedFlow | NativeFlow} - The initialized flow instance.\n * @throws {UnsupportedFlowError} If the specified mode is not supported.\n */\nexport function initFlow<T>(options: SDKInitConfig): T;\nexport function initFlow(options: SDKInitConfig & { mode: 'popup'; lazyLoad: true }): PopupFlow;\nexport function initFlow(options: SDKInitConfig & { mode: 'redirect'; lazyLoad: true }): RedirectFlow;\nexport function initFlow(options: SDKInitConfig & { mode: 'embedded'; lazyLoad: true }): EmbeddedFlow;\nexport function initFlow(options: SDKInitConfig & { mode: 'native'; lazyLoad: true }): NativeFlow;\nexport function initFlow(\n\toptions: SDKInitConfig & { mode?: 'popup' | 'redirect' | 'embedded' | 'native' },\n): Promise<PopupFlow | RedirectFlow | EmbeddedFlow | NativeFlow> | PopupFlow | RedirectFlow | EmbeddedFlow | NativeFlow | unknown {\n\tif (typeof options.factory === 'function') {\n\t\treturn options.factory(options);\n\t}\n\n\tif (options.mode === 'redirect') {\n\t\treturn createRedirectFlow(options);\n\t} else if (options.mode === 'popup') {\n\t\treturn createPopupFlow(options);\n\t} else if (options.mode === 'embedded') {\n\t\treturn createEmbeddedFlow(options);\n\t} else if (options.mode === 'native') {\n\t\treturn createNativeFlow(options);\n\t}\n\n\tthrow new UnsupportedFlowError();\n}\n"],"mappings":"wRAsBA,SAAgB,EACf,EACiI,CACjI,GAAI,OAAO,EAAQ,SAAY,WAC9B,OAAO,EAAQ,QAAQ,CAAO,EAG/B,GAAI,EAAQ,OAAS,WACpB,OAAO,EAAmB,CAAO,EAC3B,GAAI,EAAQ,OAAS,QAC3B,OAAO,EAAgB,CAAO,EACxB,GAAI,EAAQ,OAAS,WAC3B,OAAO,EAAmB,CAAO,EAC3B,GAAI,EAAQ,OAAS,SAC3B,OAAO,EAAiB,CAAO,EAGhC,MAAM,IAAI,CACX"}
1
+ {"version":3,"file":"index.mjs","names":[],"sources":["../src/index.ts"],"sourcesContent":["import type { SDKInitConfig, SDKOptions, RedirectFlow, PopupFlow, EmbeddedFlow, NativeFlow } from './types';\nimport { UnsupportedFlowError } from './utils/errors';\nimport { createRedirectFlow } from './flows/redirect';\nimport { createPopupFlow } from './flows/popup';\nimport { createEmbeddedFlow } from './flows/embedded';\nimport { createNativeFlow } from './flows/native';\n\nexport type * from './types';\n\n/**\n * Initializes an authentication flow based on the specified mode.\n *\n * @template T - The type of the flow instance returned by the factory function.\n * @param {SDKInitConfig} options - The configuration options for the SDK. `mode` is optional when `factory` is set (the factory receives `'redirect'` by default).\n * @returns T | PopupFlow | RedirectFlow | EmbeddedFlow | NativeFlow} - The initialized flow instance.\n * @throws {UnsupportedFlowError} If the specified mode is not supported.\n */\nexport function initFlow<T>(options: Omit<SDKInitConfig, 'mode' | 'factory'> & { mode?: SDKOptions['mode']; factory: (options: SDKInitConfig) => T }): T;\nexport function initFlow<T>(options: SDKInitConfig): T;\nexport function initFlow(options: SDKInitConfig & { mode: 'popup'; lazyLoad: true }): PopupFlow;\nexport function initFlow(options: SDKInitConfig & { mode: 'redirect'; lazyLoad: true }): RedirectFlow;\nexport function initFlow(options: SDKInitConfig & { mode: 'embedded'; lazyLoad: true }): EmbeddedFlow;\nexport function initFlow(options: SDKInitConfig & { mode: 'native'; lazyLoad: true }): NativeFlow;\nexport function initFlow(\n\toptions: Omit<SDKInitConfig, 'mode'> & { mode?: SDKOptions['mode'] },\n): Promise<PopupFlow | RedirectFlow | EmbeddedFlow | NativeFlow> | PopupFlow | RedirectFlow | EmbeddedFlow | NativeFlow | unknown {\n\tif (typeof options.factory === 'function') {\n\t\treturn options.factory({ ...options, mode: options.mode ?? 'redirect' });\n\t}\n\n\tconst config = options as SDKInitConfig;\n\n\tif (config.mode === 'redirect') {\n\t\treturn createRedirectFlow(config);\n\t} else if (config.mode === 'popup') {\n\t\treturn createPopupFlow(config);\n\t} else if (config.mode === 'embedded') {\n\t\treturn createEmbeddedFlow(config);\n\t} else if (config.mode === 'native') {\n\t\treturn createNativeFlow(config);\n\t}\n\n\tthrow new UnsupportedFlowError();\n}\n"],"mappings":"wRAuBA,SAAgB,EACf,EACiI,CACjI,GAAI,OAAO,EAAQ,SAAY,WAC9B,OAAO,EAAQ,QAAQ,CAAE,GAAG,EAAS,KAAM,EAAQ,MAAQ,UAAW,CAAC,EAGxE,IAAM,EAAS,EAEf,GAAI,EAAO,OAAS,WACnB,OAAO,EAAmB,CAAM,EAC1B,GAAI,EAAO,OAAS,QAC1B,OAAO,EAAgB,CAAM,EACvB,GAAI,EAAO,OAAS,WAC1B,OAAO,EAAmB,CAAM,EAC1B,GAAI,EAAO,OAAS,SAC1B,OAAO,EAAiB,CAAM,EAG/B,MAAM,IAAI,CACX"}
@@ -1,2 +1,2 @@
1
- Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require("../utils/errors.cjs"),t=require("../utils/common.cjs"),n=require("../utils/session.cjs"),r=require("../assets/oidc.cjs"),i=require("../assets/server.cjs");var a=`strivacity-session-v1`,o=3900,s=new Set([`transfer-encoding`,`connection`,`keep-alive`,`content-encoding`]),c=`sty.returnTo`,l=120;function u(a,o){let s=i.o(a,o),l=new Map;function u(){if(!s.issuer){let t=new e.ConfigurationError(`Missing option: issuer`);throw s.logging?.error(`Required option missing`,t),t}if(!s.clientId){let t=new e.ConfigurationError(`Missing option: clientId`);throw s.logging?.error(`Required option missing`,t),t}if(!s.redirectUri){let t=new e.ConfigurationError(`Missing option: redirectUri`);throw s.logging?.error(`Required option missing`,t),t}if(s.scopes&&!Array.isArray(s.scopes)){let t=new e.ConfigurationError(`Invalid option: scopes`);throw s.logging?.error(`Invalid option provided`,t),t}}async function d(e,t=302,n){return a.redirect?await a.redirect(e,t,n):new Response(null,{status:t,headers:{location:e.toString()}})}async function f(t,n,r){let i=new URL(`/error`,t);return n instanceof e.OidcError?(i.searchParams.set(`type`,n.category.toLowerCase()),i.searchParams.set(`error`,n.error),n.errorDescription&&i.searchParams.set(`error_description`,n.errorDescription)):n instanceof Error&&`category`in n?(i.searchParams.set(`type`,n.category.toLowerCase()),i.searchParams.set(`error`,n.name),i.searchParams.set(`error_description`,n.message)):(i.searchParams.set(`type`,`unknown`),i.searchParams.set(`error`,`unknown_error`),i.searchParams.set(`error_description`,n instanceof Error?n.message:`Unknown error`)),d(i,302,r)}async function p(e){return n.loadSession(await s.storage.get(s.storageTokenName,e))}async function m(e,t){await s.storage.set(s.storageTokenName,n.serializeSession(e),t)}async function h(e){await s.storage.delete(s.storageTokenName,e)}async function g(t){s.logging?.debug(`Attempting to refresh session`);let n=await p(t);if(!n)throw new e.ProtocolError(`No session available to refresh`);if(typeof n.refresh_token!=`string`)throw new e.ConfigurationError(`No refresh token available`);try{let e=await r.h({refreshToken:n.refresh_token,options:s,expectedSub:n.claims?.sub});return await m(e,t),s.logging?.debug(`Session refresh successful`),e}catch(e){throw await h(t),s.logging?.error(`Session refresh failed`,e),e}}async function _(e){let t=await p(e);if(t?.refresh_token?s.logging?.debug(`Attempting to revoke refresh token`):s.logging?.debug(`Attempting to revoke access token`),await h(e),!t?.access_token&&!t?.refresh_token){s.logging?.debug(`Revoke called without session`);return}let n=t.refresh_token?`refresh_token`:`access_token`,i=n===`refresh_token`?t.refresh_token:t.access_token;try{await r.g({tokenTypeHint:n,token:i,options:s}),n===`refresh_token`?s.logging?.info(`Refresh token successfully revoked`):s.logging?.info(`Access token successfully revoked`)}catch(e){throw s.logging?.error(`Token revocation failed`,e),e}}async function v(e){s.logging?.debug(`Attempting entry request`);let{searchParams:t}=new URL(e);try{let e=new URL(`/provider/flow/entry`,s.issuer),n=await r.o({url:e,params:t,sdkMode:s.mode===`embedded`?`web-embedded`:`web`,options:s});return s.logging?.debug(`Entry request successful - ${JSON.stringify(n)}`),n}catch(e){throw s.logging?.error(`Entry request failed`,e),e}}async function y(t,n){s.logging?.debug(`Exchanging authorization code for tokens`);try{let i=await r.a({params:t,options:s});if(!i.access_token)throw new e.ProtocolError(`Missing access_token`);return await m(i,n),s.logging?.debug(`Token exchange successful`),s.logging&&(s.logging.xEventId=void 0,s.logging.info(`Login successful`)),i}catch(e){throw s.logging?.error(`Token exchange failed`,e),e}}async function b(e,t){s.logging?.debug(`Attempting to logout`);let n=await p(t);if(await h(t),s.logging?.debug(`Logout initiated`),!n?.id_token)return s.logging?.debug(`Logout called without id token`),new URL(e);let i=await r.p(s);return r.n({url:i.end_session_endpoint,idToken:n.id_token,postLogoutRedirectUri:new URL(e).toString()})}async function x(t,n={}){let o=await a.toRequest(t),l=new URL(o.url),{returnTo:u,...d}=Object.fromEntries(l.searchParams),f=i.d(u,l.origin),p=await r.t({params:{...d,...n},options:s});if(u&&!f)throw new e.ProtocolError(`Invalid returnTo URL: ${u}. Expected a URL with the same origin as the request: ${l.origin}`);[`embedded`,`native`].includes(s.mode)&&d.sdk&&p.searchParams.set(`sdk`,d.sdk);let m=await s.httpClient.request(p,{method:`GET`,credentials:`include`,redirect:`manual`});return s.logging?.debug(`Attempting to redirect for login`),f&&i.l(t,i.u(c,f)),i.a(t,i.c(m))}async function S(e){return x(e,{prompt:`create`})}async function C(t){let n=await a.toRequest(t),o=new URL(n.url),l=Object.fromEntries(o.searchParams);try{let a=await s.stateStorage.get(`sty.${l.state}`);if(!a)throw new e.ProtocolError(`State not found or expired. Please try logging in again.`);await y(l,t);let u=r.x(a),f=i.s(n.headers.get(`cookie`))[`sty.returnTo`]??s.postLoginRedirectUri;return i.l(t,i.u(c,``,{expires:new Date(0)})),u.metadata?.display===`popup`?i.a(t,new Response(`<!DOCTYPE html><html><body><script>window.opener?.postMessage({}, '*');window.close();<\/script></body></html>`,{headers:{"content-type":`text/html; charset=utf-8`}})):i.a(t,await d(new URL(f,o.origin),302,t))}catch(e){return i.a(t,await f(o.origin,e,t))}}async function w(t){let n=await a.toRequest(t),r=new URL(n.url),o=r.origin,s=r.searchParams.get(`returnTo`),c=i.d(s,o);if(s&&!c)throw new e.ProtocolError(`Invalid returnTo URL: ${s}. Expected a URL with the same origin as the request: ${r.origin}`);try{return await g(t),c?i.a(t,await d(new URL(c,o),302,t)):i.a(t,new Response(null,{status:204}))}catch(e){return i.a(t,await f(o,e,t))}}async function T(e){let t=await a.toRequest(e),n=new URL(t.url).origin;try{return await _(e),i.a(e,await d(new URL(s.postLogoutRedirectUri,n),302,e))}catch(t){return i.a(e,await f(n,t,e))}}async function E(e){let t=await a.toRequest(e),n=new URL(t.url).origin;try{let r=await v(t.url),a=new URL(s.loginUri,n);return a.searchParams.set(`session_id`,r.session_id),a.searchParams.set(`short_app_id`,r.short_app_id),a.searchParams.set(`language`,r.language),i.a(e,await d(a,302,e))}catch(t){return i.a(e,await f(n,t,e))}}async function D(e){let t=await a.toRequest(e),n=new URL(t.url).origin;try{let t=await b(new URL(s.postLogoutRedirectUri,n),e);return i.a(e,await d(t,302,e))}catch(t){return i.a(e,await f(n,t,e))}}async function O(e){if(typeof s.storage.deleteByLogoutToken!=`function`)return new Response(`Back-channel logout requires a storage with deleteByLogoutToken`,{status:501});let n=await a.toRequest(e),o;try{if((n.headers.get(`content-type`)??``).includes(`application/x-www-form-urlencoded`))o=(await n.formData()).get(`logout_token`);else return new Response(`Invalid content type: expected application/x-www-form-urlencoded`,{status:400})}catch{return new Response(`Failed to parse request body`,{status:400})}if(!o)return new Response(`Missing logout_token`,{status:400});let c=t.timestamp();for(let[e,t]of l)t<=c&&l.delete(e);if(l.has(o))return new Response(`Invalid logout_token: token already used`,{status:400});l.set(o,c+120);let u,d;try{d=await r.p(s),u=await r.y({token:o,jwksUri:d.jwks_uri,options:s})}catch(e){return new Response(`Invalid logout_token: ${e.message}`,{status:400})}if(u.iss!==d.issuer)return new Response(`Invalid logout_token: invalid iss claim`,{status:400});if(Array.isArray(u.aud)?!u.aud.includes(s.clientId):u.aud!==s.clientId)return new Response(`Invalid logout_token: invalid aud claim`,{status:400});if(typeof u.iat!=`number`||Math.abs(c-u.iat)>120)return new Response(`Invalid logout_token: invalid or stale iat claim`,{status:400});if(!u.jti)return new Response(`Invalid logout_token: missing jti claim`,{status:400});if(u.nonce!==void 0)return new Response(`Invalid logout_token: nonce claim must not be present`,{status:400});if(!u.events||!(`http://schemas.openid.net/event/backchannel-logout`in u.events))return new Response(`Invalid logout_token: missing ${i.t} in events`,{status:400});if(!u.sid&&!u.sub)return new Response(`Invalid logout_token: must contain sid or sub claim`,{status:400});let f={};u.sid&&(f.sid=u.sid),u.sub&&(f.sub=u.sub);try{await s.storage.deleteByLogoutToken(f)}catch(e){return new Response(`Failed to delete session: ${e.message}`,{status:500})}return new Response(null,{status:200})}async function k(e){let t=await a.toRequest(e),n=new URL(t.url);return t.method===`GET`&&n.pathname===`${s.authUrlPrefix}/login`?x(e):t.method===`GET`&&n.pathname===`${s.authUrlPrefix}/register`?S(e):t.method===`GET`&&n.pathname===`${s.authUrlPrefix}/callback`?C(e):t.method===`GET`&&n.pathname===`${s.authUrlPrefix}/refresh`?w(e):t.method===`GET`&&n.pathname===`${s.authUrlPrefix}/revoke`?T(e):t.method===`GET`&&n.pathname===`${s.authUrlPrefix}/entry`?E(e):t.method===`GET`&&n.pathname===`${s.authUrlPrefix}/logout`?D(e):t.method===`POST`&&n.pathname===`${s.authUrlPrefix}/backchannel-logout`?O(e):null}return u(),{get options(){return s},getSession:p,updateSession:m,refreshSession:g,revokeSession:_,getEntrySession:v,completeLogin:y,logout:b,handleLogin:x,handleRegister:S,handleCallback:C,handleRefresh:w,handleRevoke:T,handleEntry:E,handleLogout:D,handleBackChannelLogout:O,handler:k}}exports.BACKCHANNEL_LOGOUT_TOKEN_MAX_AGE_SECONDS=l,exports.COOKIE_CHUNK_SIZE=o,exports.COOKIE_CONTEXT=a,exports.DISALLOWED_PROXY_HEADERS=s,exports.RETURN_TO_COOKIE=c,exports.createBaseServerSDK=u;
1
+ Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require("../utils/errors.cjs"),t=require("../utils/common.cjs"),n=require("../utils/session.cjs"),r=require("../assets/oidc.cjs"),i=require("../assets/server.cjs");var a=120;function o(a,o){let s=i.o(a,o),c=new Map,l=new WeakMap;function u(){if(!s.issuer){let t=new e.ConfigurationError(`Missing option: issuer`);throw s.logging?.error(`Required option missing`,t),t}if(!s.clientId){let t=new e.ConfigurationError(`Missing option: clientId`);throw s.logging?.error(`Required option missing`,t),t}if(!s.redirectUri){let t=new e.ConfigurationError(`Missing option: redirectUri`);throw s.logging?.error(`Required option missing`,t),t}if(s.scopes&&!Array.isArray(s.scopes)){let t=new e.ConfigurationError(`Invalid option: scopes`);throw s.logging?.error(`Invalid option provided`,t),t}}async function d(e,t=302,n){return a.redirect?await a.redirect(e,t,n):new Response(null,{status:t,headers:{location:e.toString()}})}async function f(t,n,r){let i=new URL(`/error`,t);return n instanceof e.OidcError?(i.searchParams.set(`type`,n.category.toLowerCase()),i.searchParams.set(`error`,n.error),n.errorDescription&&i.searchParams.set(`error_description`,n.errorDescription)):n instanceof Error&&`category`in n?(i.searchParams.set(`type`,n.category.toLowerCase()),i.searchParams.set(`error`,n.name),i.searchParams.set(`error_description`,n.message)):(i.searchParams.set(`type`,`unknown`),i.searchParams.set(`error`,`unknown_error`),i.searchParams.set(`error_description`,n instanceof Error?n.message:`Unknown error`)),d(i,302,r)}async function p(e){return n.loadSession(await s.storage.get(s.storageTokenName,e))}async function m(e,t={}){if(!(t.autoRefresh??s.autoRefresh))return p(e);let r=typeof e==`object`&&e?e:null,i=r?l.get(r):void 0;if(i)return i;let a=await p(e);if(!a?.refresh_token||!n.isSessionExpired(a,s.refreshSkew))return a;let o=r?l.get(r):void 0;return o||(o=_(e).catch(()=>null),r&&l.set(r,o)),o}async function h(e,t){await s.storage.set(s.storageTokenName,n.serializeSession(e),t)}async function g(e){await s.storage.delete(s.storageTokenName,e)}async function _(t){s.logging?.debug(`Attempting to refresh session`);let n=await p(t);if(!n)throw new e.ProtocolError(`No session available to refresh`);if(typeof n.refresh_token!=`string`)throw new e.ConfigurationError(`No refresh token available`);try{let e=await r.h({refreshToken:n.refresh_token,options:s,expectedSub:n.claims?.sub});return await h(e,t),s.logging?.debug(`Session refresh successful`),e}catch(e){throw await g(t),s.logging?.error(`Session refresh failed`,e),e}}async function v(e){let t=await p(e);if(t?.refresh_token?s.logging?.debug(`Attempting to revoke refresh token`):s.logging?.debug(`Attempting to revoke access token`),await g(e),!t?.access_token&&!t?.refresh_token){s.logging?.debug(`Revoke called without session`);return}let n=t.refresh_token?`refresh_token`:`access_token`,i=n===`refresh_token`?t.refresh_token:t.access_token;try{await r.g({tokenTypeHint:n,token:i,options:s}),n===`refresh_token`?s.logging?.info(`Refresh token successfully revoked`):s.logging?.info(`Access token successfully revoked`)}catch(e){throw s.logging?.error(`Token revocation failed`,e),e}}async function y(e){s.logging?.debug(`Attempting entry request`);let{searchParams:t}=new URL(e);try{let e=new URL(`/provider/flow/entry`,s.issuer),n=await r.o({url:e,params:t,sdkMode:s.mode===`embedded`?`web-embedded`:`web`,options:s});return s.logging?.debug(`Entry request successful - ${JSON.stringify(n)}`),n}catch(e){throw s.logging?.error(`Entry request failed`,e),e}}async function b(t,n){s.logging?.debug(`Exchanging authorization code for tokens`);try{let i=await r.a({params:t,options:s});if(!i.access_token)throw new e.ProtocolError(`Missing access_token`);return await h(i,n),s.logging?.debug(`Token exchange successful`),s.logging&&(s.logging.xEventId=void 0,s.logging.info(`Login successful`)),i}catch(e){throw s.logging?.error(`Token exchange failed`,e),e}}async function x(e,t){s.logging?.debug(`Attempting to logout`);let n=await p(t);if(await g(t),s.logging?.debug(`Logout initiated`),!n?.id_token)return s.logging?.debug(`Logout called without id token`),new URL(e);let i=await r.p(s);return r.n({url:i.end_session_endpoint,idToken:n.id_token,postLogoutRedirectUri:new URL(e).toString()})}async function S(t,n={}){let o=await a.toRequest(t),c=new URL(o.url),{returnTo:l,prompt:u,display:d,login_hint:f,acr_values:p,ui_locales:m,audience:h,...g}=Object.fromEntries(c.searchParams),_=i.d(l,c.origin),v=await r.t({params:{prompt:u??g.prompt,display:d??g.display,loginHint:f??g.loginHint,acrValues:(p??g.acrValues)?.split(` `),uiLocales:(m??g.uiLocales)?.split(` `),audiences:(h??g.audiences)?.split(` `),...n},options:s});if(l&&!_)throw new e.ProtocolError(`Invalid returnTo URL: ${l}. Expected a URL with the same origin as the request: ${c.origin}`);[`embedded`,`native`].includes(s.mode)&&g.sdk&&v.searchParams.set(`sdk`,g.sdk);let y=await s.httpClient.request(v,{method:`GET`,credentials:`include`,redirect:`manual`});return s.logging?.debug(`Attempting to redirect for login`),_&&i.l(t,i.u(i.i,_)),i.a(t,i.c(y))}async function C(e){return S(e,{prompt:`create`})}async function w(t){let n=await a.toRequest(t),o=new URL(n.url),c=Object.fromEntries(o.searchParams);try{let a=await s.stateStorage.get(`sty.${c.state}`);if(!a)throw new e.ProtocolError(`State not found or expired. Please try logging in again.`);await b(c,t);let l=r.x(a),u=i.s(n.headers.get(`cookie`))[`sty.returnTo`]??s.postLoginRedirectUri;return i.l(t,i.u(i.i,``,{maxAge:0})),l.metadata?.display===`popup`?i.a(t,new Response(`<!DOCTYPE html><html><body><script>window.opener?.postMessage({}, '*');window.close();<\/script></body></html>`,{headers:{"content-type":`text/html; charset=utf-8`}})):i.a(t,await d(new URL(u,o.origin),302,t))}catch(e){return i.a(t,await f(o.origin,e,t))}}async function T(t){let n=await a.toRequest(t),r=new URL(n.url),o=r.origin,s=r.searchParams.get(`returnTo`),c=i.d(s,o);if(s&&!c)throw new e.ProtocolError(`Invalid returnTo URL: ${s}. Expected a URL with the same origin as the request: ${r.origin}`);try{return await _(t),c?i.a(t,await d(new URL(c,o),302,t)):i.a(t,new Response(null,{status:204}))}catch(e){return i.a(t,await f(o,e,t))}}async function E(e){let t=await a.toRequest(e),n=new URL(t.url).origin;try{return await v(e),i.a(e,await d(new URL(s.postLogoutRedirectUri,n),302,e))}catch(t){return i.a(e,await f(n,t,e))}}async function D(e){let t=await a.toRequest(e),n=new URL(t.url).origin;try{let r=await y(t.url),a=new URL(s.loginUri,n);return a.searchParams.set(`session_id`,r.session_id),a.searchParams.set(`short_app_id`,r.short_app_id),a.searchParams.set(`language`,r.language),i.a(e,await d(a,302,e))}catch(t){return i.a(e,await f(n,t,e))}}async function O(e){let t=await a.toRequest(e),n=new URL(t.url),r=n.origin,o=n.searchParams.get(`returnTo`),c=i.d(o,r);try{let t=await x(new URL(c??s.postLogoutRedirectUri,r),e);return i.a(e,await d(t,302,e))}catch(t){return i.a(e,await f(r,t,e))}}async function k(e){if(typeof s.storage.deleteByLogoutToken!=`function`)return new Response(`Back-channel logout requires a storage with deleteByLogoutToken`,{status:501});let n=await a.toRequest(e),o;try{if((n.headers.get(`content-type`)??``).includes(`application/x-www-form-urlencoded`))o=(await n.formData()).get(`logout_token`);else return new Response(`Invalid content type: expected application/x-www-form-urlencoded`,{status:400})}catch{return new Response(`Failed to parse request body`,{status:400})}if(!o)return new Response(`Missing logout_token`,{status:400});let l=t.timestamp();for(let[e,t]of c)t<=l&&c.delete(e);if(c.has(o))return new Response(`Invalid logout_token: token already used`,{status:400});c.set(o,l+120);let u,d;try{d=await r.p(s),u=await r.y({token:o,jwksUri:d.jwks_uri,options:s})}catch(e){return new Response(`Invalid logout_token: ${e.message}`,{status:400})}if(u.iss!==d.issuer)return new Response(`Invalid logout_token: invalid iss claim`,{status:400});if(Array.isArray(u.aud)?!u.aud.includes(s.clientId):u.aud!==s.clientId)return new Response(`Invalid logout_token: invalid aud claim`,{status:400});if(typeof u.iat!=`number`||Math.abs(l-u.iat)>120)return new Response(`Invalid logout_token: invalid or stale iat claim`,{status:400});if(!u.jti)return new Response(`Invalid logout_token: missing jti claim`,{status:400});if(u.nonce!==void 0)return new Response(`Invalid logout_token: nonce claim must not be present`,{status:400});if(!u.events||!(`http://schemas.openid.net/event/backchannel-logout`in u.events))return new Response(`Invalid logout_token: missing ${i.t} in events`,{status:400});if(!u.sid&&!u.sub)return new Response(`Invalid logout_token: must contain sid or sub claim`,{status:400});let f={};u.sid&&(f.sid=u.sid),u.sub&&(f.sub=u.sub);try{await s.storage.deleteByLogoutToken(f)}catch(e){return new Response(`Failed to delete session: ${e.message}`,{status:500})}return new Response(null,{status:200})}async function A(e){let t=await a.toRequest(e),n=new URL(t.url);return t.method===`GET`&&n.pathname===`${s.authUrlPrefix}/login`?S(e):t.method===`GET`&&n.pathname===`${s.authUrlPrefix}/register`?C(e):t.method===`GET`&&n.pathname===`${s.authUrlPrefix}/callback`?w(e):t.method===`GET`&&n.pathname===`${s.authUrlPrefix}/refresh`?T(e):t.method===`GET`&&n.pathname===`${s.authUrlPrefix}/revoke`?E(e):t.method===`GET`&&n.pathname===`${s.authUrlPrefix}/entry`?D(e):t.method===`GET`&&n.pathname===`${s.authUrlPrefix}/logout`?O(e):t.method===`POST`&&n.pathname===`${s.authUrlPrefix}/backchannel-logout`?k(e):null}return u(),{get options(){return s},getSession:m,updateSession:h,refreshSession:_,revokeSession:v,getEntrySession:y,completeLogin:b,logout:x,handleLogin:S,handleRegister:C,handleCallback:w,handleRefresh:T,handleRevoke:E,handleEntry:D,handleLogout:O,handleBackChannelLogout:k,handler:A}}exports.BACKCHANNEL_LOGOUT_TOKEN_MAX_AGE_SECONDS=a,exports.COOKIE_CHUNK_SIZE=i.f,exports.COOKIE_CONTEXT=i.p,exports.DISALLOWED_PROXY_HEADERS=i.r,exports.RETURN_TO_COOKIE=i.i,exports.createBaseServerSDK=o;
2
2
  //# sourceMappingURL=base.cjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"base.cjs","names":[],"sources":["../../src/server/base.ts"],"sourcesContent":["import type { SDKStorage } from '../types/common';\nimport type { SessionData, LogoutTokenClaims } from '../types/oidc';\nimport type { BaseServerSDK, ServerAdapter, ServerStorage, ServerSDKInitConfig } from '../types/server';\nimport {\n\tbuildEndSessionUrl,\n\tbuildAuthorizationUrl,\n\trevokeToken,\n\trefreshToken,\n\texchangeCode,\n\tverifyJwt,\n\tfetchFlowEntry,\n\tgetDiscoveryDocument,\n} from '../utils/oidc';\nimport { loadSession, serializeSession } from '../utils/session';\nimport { parseState } from '../utils/state';\nimport { timestamp } from '../utils/common';\nimport { ConfigurationError, OidcError, ProtocolError, type FailureCategory } from '../utils/errors';\nimport {\n\tpushSetCookie,\n\tflushSetCookies,\n\tparseCookieHeader,\n\tserializeCookie,\n\tproxyResponse,\n\ttoSafeRedirect,\n\tgetServerSDKOptions,\n\tBACKCHANNEL_LOGOUT_EVENT,\n} from '../utils/server';\n\nexport const COOKIE_CONTEXT = 'strivacity-session-v1';\nexport const COOKIE_CHUNK_SIZE = 3900;\nexport const DISALLOWED_PROXY_HEADERS = new Set(['transfer-encoding', 'connection', 'keep-alive', 'content-encoding']);\nexport const RETURN_TO_COOKIE = 'sty.returnTo';\nexport const BACKCHANNEL_LOGOUT_TOKEN_MAX_AGE_SECONDS = 120;\n\n/**\n * Creates the framework-agnostic Strivacity base server SDK.\n *\n * @param {ServerAdapter<TEvent>} adapter - The framework adapter converting `TEvent` to a standard `Request`.\n * @param {ServerSDKOptions<TEvent, Storage, StateStorage>} initConfig - The initial configuration for the server SDK.\n * @returns {BaseServerSDK<TEvent>} The initialized, framework-agnostic server SDK core.\n */\nexport function createBaseServerSDK<\n\tTEvent = unknown,\n\tStorage extends ServerStorage<TEvent> = ServerStorage<TEvent>,\n\tStateStorage extends SDKStorage = SDKStorage,\n>(adapter: ServerAdapter<TEvent>, initConfig: ServerSDKInitConfig<TEvent, Storage, StateStorage>): BaseServerSDK<TEvent> {\n\tconst options = getServerSDKOptions(adapter, initConfig);\n\tconst seenLogoutTokenIds = new Map<string, number>();\n\n\tfunction init() {\n\t\tif (!options.issuer) {\n\t\t\tconst error = new ConfigurationError('Missing option: issuer');\n\t\t\toptions.logging?.error('Required option missing', error);\n\t\t\tthrow error;\n\t\t}\n\t\tif (!options.clientId) {\n\t\t\tconst error = new ConfigurationError('Missing option: clientId');\n\t\t\toptions.logging?.error('Required option missing', error);\n\t\t\tthrow error;\n\t\t}\n\t\tif (!options.redirectUri) {\n\t\t\tconst error = new ConfigurationError('Missing option: redirectUri');\n\t\t\toptions.logging?.error('Required option missing', error);\n\t\t\tthrow error;\n\t\t}\n\t\tif (options.scopes && !Array.isArray(options.scopes)) {\n\t\t\tconst error = new ConfigurationError('Invalid option: scopes');\n\t\t\toptions.logging?.error('Invalid option provided', error);\n\t\t\tthrow error;\n\t\t}\n\t}\n\n\tasync function redirect(url: string | URL, status = 302, event?: TEvent): Promise<Response> {\n\t\tif (adapter.redirect) {\n\t\t\treturn await adapter.redirect(url, status, event);\n\t\t}\n\n\t\treturn new Response(null, { status, headers: { location: url.toString() } });\n\t}\n\n\tasync function errorRedirect(origin: string, error: unknown, event?: TEvent): Promise<Response> {\n\t\tconst url = new URL('/error', origin);\n\n\t\tif (error instanceof OidcError) {\n\t\t\turl.searchParams.set('type', error.category.toLowerCase());\n\t\t\turl.searchParams.set('error', error.error);\n\t\t\tif (error.errorDescription) {\n\t\t\t\turl.searchParams.set('error_description', error.errorDescription);\n\t\t\t}\n\t\t} else if (error instanceof Error && 'category' in error) {\n\t\t\turl.searchParams.set('type', (error as { category: FailureCategory }).category.toLowerCase());\n\t\t\turl.searchParams.set('error', error.name);\n\t\t\turl.searchParams.set('error_description', error.message);\n\t\t} else {\n\t\t\turl.searchParams.set('type', 'unknown');\n\t\t\turl.searchParams.set('error', 'unknown_error');\n\t\t\turl.searchParams.set('error_description', error instanceof Error ? error.message : 'Unknown error');\n\t\t}\n\n\t\treturn redirect(url, 302, event);\n\t}\n\n\tasync function getSession(event?: TEvent): Promise<SessionData | null> {\n\t\treturn loadSession(await options.storage.get(options.storageTokenName, event));\n\t}\n\n\tasync function updateSession(session: SessionData, event?: TEvent): Promise<void> {\n\t\tawait options.storage.set(options.storageTokenName, serializeSession(session), event);\n\t}\n\n\tasync function cleanupSession(event?: TEvent): Promise<void> {\n\t\tawait options.storage.delete(options.storageTokenName, event);\n\t}\n\n\tasync function refreshSession(event?: TEvent): Promise<SessionData> {\n\t\toptions.logging?.debug('Attempting to refresh session');\n\n\t\tconst currentSession = await getSession(event);\n\n\t\tif (!currentSession) {\n\t\t\tthrow new ProtocolError('No session available to refresh');\n\t\t}\n\n\t\tif (typeof currentSession.refresh_token !== 'string') {\n\t\t\tthrow new ConfigurationError('No refresh token available');\n\t\t}\n\n\t\ttry {\n\t\t\tconst newSession = await refreshToken({ refreshToken: currentSession.refresh_token, options, expectedSub: currentSession.claims?.sub });\n\t\t\tawait updateSession(newSession, event);\n\n\t\t\toptions.logging?.debug('Session refresh successful');\n\n\t\t\treturn newSession;\n\t\t} catch (error) {\n\t\t\tawait cleanupSession(event);\n\t\t\toptions.logging?.error('Session refresh failed', error as Error);\n\n\t\t\tthrow error;\n\t\t}\n\t}\n\n\tasync function revokeSession(event?: TEvent): Promise<void> {\n\t\tconst currentSession = await getSession(event);\n\n\t\tif (currentSession?.refresh_token) {\n\t\t\toptions.logging?.debug('Attempting to revoke refresh token');\n\t\t} else {\n\t\t\toptions.logging?.debug('Attempting to revoke access token');\n\t\t}\n\n\t\t// NOTE: Cleanup session before revocation\n\t\tawait cleanupSession(event);\n\n\t\tif (!currentSession?.access_token && !currentSession?.refresh_token) {\n\t\t\toptions.logging?.debug('Revoke called without session');\n\t\t\treturn;\n\t\t}\n\n\t\tconst tokenTypeHint = currentSession.refresh_token ? 'refresh_token' : 'access_token';\n\t\tconst token = (tokenTypeHint === 'refresh_token' ? currentSession.refresh_token : currentSession.access_token)!;\n\n\t\ttry {\n\t\t\tawait revokeToken({ tokenTypeHint, token, options });\n\n\t\t\tif (tokenTypeHint === 'refresh_token') {\n\t\t\t\toptions.logging?.info('Refresh token successfully revoked');\n\t\t\t} else {\n\t\t\t\toptions.logging?.info('Access token successfully revoked');\n\t\t\t}\n\t\t} catch (error) {\n\t\t\toptions.logging?.error('Token revocation failed', error as Error);\n\t\t\tthrow error;\n\t\t}\n\t}\n\n\tasync function getEntrySession(entryUrl: string | URL): Promise<Record<string, string>> {\n\t\toptions.logging?.debug('Attempting entry request');\n\n\t\tconst { searchParams: params } = new URL(entryUrl);\n\n\t\ttry {\n\t\t\tconst url = new URL('/provider/flow/entry', options.issuer);\n\t\t\tconst data = await fetchFlowEntry({\n\t\t\t\turl,\n\t\t\t\tparams,\n\t\t\t\tsdkMode: options.mode === 'embedded' ? 'web-embedded' : 'web',\n\t\t\t\toptions,\n\t\t\t});\n\n\t\t\toptions.logging?.debug(`Entry request successful - ${JSON.stringify(data)}`);\n\n\t\t\treturn data;\n\t\t} catch (error) {\n\t\t\toptions.logging?.error('Entry request failed', error as Error);\n\t\t\tthrow error;\n\t\t}\n\t}\n\n\tasync function completeLogin(params: Record<string, string>, event?: TEvent): Promise<SessionData> {\n\t\toptions.logging?.debug('Exchanging authorization code for tokens');\n\n\t\ttry {\n\t\t\tconst session = await exchangeCode({ params, options });\n\n\t\t\tif (!session.access_token) {\n\t\t\t\tthrow new ProtocolError('Missing access_token');\n\t\t\t}\n\n\t\t\tawait updateSession(session, event);\n\n\t\t\toptions.logging?.debug('Token exchange successful');\n\n\t\t\tif (options.logging) {\n\t\t\t\toptions.logging.xEventId = undefined;\n\t\t\t\toptions.logging.info('Login successful');\n\t\t\t}\n\n\t\t\treturn session;\n\t\t} catch (error) {\n\t\t\toptions.logging?.error('Token exchange failed', error as Error);\n\t\t\tthrow error;\n\t\t}\n\t}\n\n\tasync function logout(postLogoutRedirectUri: string | URL, event?: TEvent): Promise<URL> {\n\t\toptions.logging?.debug('Attempting to logout');\n\n\t\t// NOTE: Cleanup session before logout\n\t\tconst currentSession = await getSession(event);\n\t\tawait cleanupSession(event);\n\n\t\toptions.logging?.debug('Logout initiated');\n\n\t\tif (!currentSession?.id_token) {\n\t\t\toptions.logging?.debug('Logout called without id token');\n\t\t\treturn new URL(postLogoutRedirectUri);\n\t\t}\n\n\t\tconst metadata = await getDiscoveryDocument(options);\n\n\t\treturn buildEndSessionUrl({\n\t\t\turl: metadata.end_session_endpoint,\n\t\t\tidToken: currentSession.id_token,\n\t\t\tpostLogoutRedirectUri: new URL(postLogoutRedirectUri).toString(),\n\t\t});\n\t}\n\n\tasync function handleLogin(event: TEvent, extraParams: Record<string, unknown> = {}): Promise<Response> {\n\t\tconst request = await adapter.toRequest(event);\n\t\tconst requestUrl = new URL(request.url);\n\t\tconst { returnTo, ...params } = Object.fromEntries(requestUrl.searchParams);\n\t\tconst safeReturnTo = toSafeRedirect(returnTo, requestUrl.origin);\n\t\tconst url = await buildAuthorizationUrl({ params: { ...params, ...extraParams }, options });\n\n\t\tif (returnTo && !safeReturnTo) {\n\t\t\tthrow new ProtocolError(`Invalid returnTo URL: ${returnTo}. Expected a URL with the same origin as the request: ${requestUrl.origin}`);\n\t\t}\n\n\t\tif (['embedded', 'native'].includes(options.mode) && params.sdk) {\n\t\t\turl.searchParams.set('sdk', params.sdk);\n\t\t}\n\n\t\tconst startResponse = await options.httpClient.request<string>(url, {\n\t\t\tmethod: 'GET',\n\t\t\tcredentials: 'include',\n\t\t\tredirect: 'manual',\n\t\t});\n\n\t\toptions.logging?.debug('Attempting to redirect for login');\n\n\t\tif (safeReturnTo) {\n\t\t\tpushSetCookie(event, serializeCookie(RETURN_TO_COOKIE, safeReturnTo));\n\t\t}\n\n\t\treturn flushSetCookies(event, proxyResponse(startResponse));\n\t}\n\n\tasync function handleRegister(event: TEvent): Promise<Response> {\n\t\treturn handleLogin(event, { prompt: 'create' });\n\t}\n\n\tasync function handleCallback(event: TEvent): Promise<Response> {\n\t\tconst request = await adapter.toRequest(event);\n\t\tconst requestUrl = new URL(request.url);\n\t\tconst params = Object.fromEntries(requestUrl.searchParams);\n\n\t\ttry {\n\t\t\tconst serializedState = await options.stateStorage.get(`sty.${params.state}`);\n\n\t\t\tif (!serializedState) {\n\t\t\t\tthrow new ProtocolError('State not found or expired. Please try logging in again.');\n\t\t\t}\n\n\t\t\tawait completeLogin(params, event);\n\n\t\t\tconst state = parseState(serializedState);\n\t\t\tconst returnTo = parseCookieHeader(request.headers.get('cookie'))[RETURN_TO_COOKIE] ?? options.postLoginRedirectUri;\n\n\t\t\tpushSetCookie(event, serializeCookie(RETURN_TO_COOKIE, '', { expires: new Date(0) }));\n\n\t\t\tif (state.metadata?.display === 'popup') {\n\t\t\t\t// NOTE: If the login was initiated from a popup, we return a HTML page that will close the popup and notify the opener window.\n\t\t\t\treturn flushSetCookies(\n\t\t\t\t\tevent,\n\t\t\t\t\tnew Response(`<!DOCTYPE html><html><body><script>window.opener?.postMessage({}, '*');window.close();</script></body></html>`, {\n\t\t\t\t\t\theaders: { 'content-type': 'text/html; charset=utf-8' },\n\t\t\t\t\t}),\n\t\t\t\t);\n\t\t\t}\n\n\t\t\treturn flushSetCookies(event, await redirect(new URL(returnTo, requestUrl.origin), 302, event));\n\t\t} catch (error) {\n\t\t\treturn flushSetCookies(event, await errorRedirect(requestUrl.origin, error, event));\n\t\t}\n\t}\n\n\tasync function handleRefresh(event: TEvent): Promise<Response> {\n\t\tconst request = await adapter.toRequest(event);\n\t\tconst requestUrl = new URL(request.url);\n\t\tconst origin = requestUrl.origin;\n\t\tconst returnTo = requestUrl.searchParams.get('returnTo');\n\t\tconst safeReturnTo = toSafeRedirect(returnTo, origin);\n\n\t\tif (returnTo && !safeReturnTo) {\n\t\t\tthrow new ProtocolError(`Invalid returnTo URL: ${returnTo}. Expected a URL with the same origin as the request: ${requestUrl.origin}`);\n\t\t}\n\n\t\ttry {\n\t\t\tawait refreshSession(event);\n\n\t\t\tif (safeReturnTo) {\n\t\t\t\treturn flushSetCookies(event, await redirect(new URL(safeReturnTo, origin), 302, event));\n\t\t\t}\n\n\t\t\treturn flushSetCookies(event, new Response(null, { status: 204 }));\n\t\t} catch (error) {\n\t\t\treturn flushSetCookies(event, await errorRedirect(origin, error, event));\n\t\t}\n\t}\n\n\tasync function handleRevoke(event: TEvent): Promise<Response> {\n\t\tconst request = await adapter.toRequest(event);\n\t\tconst origin = new URL(request.url).origin;\n\n\t\ttry {\n\t\t\tawait revokeSession(event);\n\n\t\t\treturn flushSetCookies(event, await redirect(new URL(options.postLogoutRedirectUri, origin), 302, event));\n\t\t} catch (error) {\n\t\t\treturn flushSetCookies(event, await errorRedirect(origin, error, event));\n\t\t}\n\t}\n\n\tasync function handleEntry(event: TEvent): Promise<Response> {\n\t\tconst request = await adapter.toRequest(event);\n\t\tconst origin = new URL(request.url).origin;\n\n\t\ttry {\n\t\t\tconst data = await getEntrySession(request.url);\n\t\t\tconst uri = new URL(options.loginUri, origin);\n\t\t\turi.searchParams.set('session_id', data.session_id);\n\t\t\turi.searchParams.set('short_app_id', data.short_app_id);\n\t\t\turi.searchParams.set('language', data.language);\n\n\t\t\treturn flushSetCookies(event, await redirect(uri, 302, event));\n\t\t} catch (error) {\n\t\t\treturn flushSetCookies(event, await errorRedirect(origin, error, event));\n\t\t}\n\t}\n\n\tasync function handleLogout(event: TEvent): Promise<Response> {\n\t\tconst request = await adapter.toRequest(event);\n\t\tconst origin = new URL(request.url).origin;\n\n\t\ttry {\n\t\t\tconst logoutUrl = await logout(new URL(options.postLogoutRedirectUri, origin), event);\n\t\t\treturn flushSetCookies(event, await redirect(logoutUrl, 302, event));\n\t\t} catch (error) {\n\t\t\treturn flushSetCookies(event, await errorRedirect(origin, error, event));\n\t\t}\n\t}\n\n\tasync function handleBackChannelLogout(event: TEvent): Promise<Response> {\n\t\tif (typeof options.storage.deleteByLogoutToken !== 'function') {\n\t\t\treturn new Response('Back-channel logout requires a storage with deleteByLogoutToken', { status: 501 });\n\t\t}\n\n\t\tconst request = await adapter.toRequest(event);\n\t\tlet logoutToken: string | null;\n\n\t\ttry {\n\t\t\tconst contentType = request.headers.get('content-type') ?? '';\n\n\t\t\tif (contentType.includes('application/x-www-form-urlencoded')) {\n\t\t\t\tconst body = await request.formData();\n\t\t\t\tlogoutToken = body.get('logout_token') as string | null;\n\t\t\t} else {\n\t\t\t\treturn new Response('Invalid content type: expected application/x-www-form-urlencoded', { status: 400 });\n\t\t\t}\n\t\t} catch {\n\t\t\treturn new Response('Failed to parse request body', { status: 400 });\n\t\t}\n\n\t\tif (!logoutToken) {\n\t\t\treturn new Response('Missing logout_token', { status: 400 });\n\t\t}\n\n\t\tconst now = timestamp();\n\n\t\tfor (const [token, expiresAt] of seenLogoutTokenIds) {\n\t\t\tif (expiresAt <= now) {\n\t\t\t\tseenLogoutTokenIds.delete(token);\n\t\t\t}\n\t\t}\n\n\t\tif (seenLogoutTokenIds.has(logoutToken)) {\n\t\t\treturn new Response('Invalid logout_token: token already used', { status: 400 });\n\t\t}\n\n\t\tseenLogoutTokenIds.set(logoutToken, now + BACKCHANNEL_LOGOUT_TOKEN_MAX_AGE_SECONDS);\n\n\t\tlet claims;\n\t\tlet metadata;\n\n\t\ttry {\n\t\t\tmetadata = await getDiscoveryDocument(options);\n\t\t\tclaims = await verifyJwt<LogoutTokenClaims>({ token: logoutToken, jwksUri: metadata.jwks_uri, options });\n\t\t} catch (error) {\n\t\t\treturn new Response(`Invalid logout_token: ${error.message}`, { status: 400 });\n\t\t}\n\n\t\tif (claims.iss !== metadata.issuer) {\n\t\t\treturn new Response('Invalid logout_token: invalid iss claim', { status: 400 });\n\t\t}\n\n\t\tif (Array.isArray(claims.aud) ? !claims.aud.includes(options.clientId) : claims.aud !== options.clientId) {\n\t\t\treturn new Response('Invalid logout_token: invalid aud claim', { status: 400 });\n\t\t}\n\n\t\tif (typeof claims.iat !== 'number' || Math.abs(now - claims.iat) > BACKCHANNEL_LOGOUT_TOKEN_MAX_AGE_SECONDS) {\n\t\t\treturn new Response('Invalid logout_token: invalid or stale iat claim', { status: 400 });\n\t\t}\n\n\t\tif (!claims.jti) {\n\t\t\treturn new Response('Invalid logout_token: missing jti claim', { status: 400 });\n\t\t}\n\n\t\tif (claims.nonce !== undefined) {\n\t\t\treturn new Response('Invalid logout_token: nonce claim must not be present', { status: 400 });\n\t\t}\n\n\t\tif (!claims.events || !(BACKCHANNEL_LOGOUT_EVENT in claims.events)) {\n\t\t\treturn new Response(`Invalid logout_token: missing ${BACKCHANNEL_LOGOUT_EVENT} in events`, { status: 400 });\n\t\t}\n\n\t\tif (!claims.sid && !claims.sub) {\n\t\t\treturn new Response('Invalid logout_token: must contain sid or sub claim', { status: 400 });\n\t\t}\n\n\t\tconst token: LogoutTokenClaims = {} as never;\n\n\t\tif (claims.sid) {\n\t\t\ttoken.sid = claims.sid;\n\t\t}\n\t\tif (claims.sub) {\n\t\t\ttoken.sub = claims.sub;\n\t\t}\n\n\t\ttry {\n\t\t\tawait options.storage.deleteByLogoutToken(token);\n\t\t} catch (error) {\n\t\t\treturn new Response(`Failed to delete session: ${error.message}`, { status: 500 });\n\t\t}\n\n\t\treturn new Response(null, { status: 200 });\n\t}\n\n\tasync function handler(event: TEvent): Promise<Response | null> {\n\t\tconst request = await adapter.toRequest(event);\n\t\tconst requestUrl = new URL(request.url);\n\n\t\tif (request.method === 'GET' && requestUrl.pathname === `${options.authUrlPrefix}/login`) {\n\t\t\treturn handleLogin(event);\n\t\t}\n\t\tif (request.method === 'GET' && requestUrl.pathname === `${options.authUrlPrefix}/register`) {\n\t\t\treturn handleRegister(event);\n\t\t}\n\t\tif (request.method === 'GET' && requestUrl.pathname === `${options.authUrlPrefix}/callback`) {\n\t\t\treturn handleCallback(event);\n\t\t}\n\t\tif (request.method === 'GET' && requestUrl.pathname === `${options.authUrlPrefix}/refresh`) {\n\t\t\treturn handleRefresh(event);\n\t\t}\n\t\tif (request.method === 'GET' && requestUrl.pathname === `${options.authUrlPrefix}/revoke`) {\n\t\t\treturn handleRevoke(event);\n\t\t}\n\t\tif (request.method === 'GET' && requestUrl.pathname === `${options.authUrlPrefix}/entry`) {\n\t\t\treturn handleEntry(event);\n\t\t}\n\t\tif (request.method === 'GET' && requestUrl.pathname === `${options.authUrlPrefix}/logout`) {\n\t\t\treturn handleLogout(event);\n\t\t}\n\t\tif (request.method === 'POST' && requestUrl.pathname === `${options.authUrlPrefix}/backchannel-logout`) {\n\t\t\treturn handleBackChannelLogout(event);\n\t\t}\n\n\t\treturn null;\n\t}\n\n\t// endregion\n\n\tinit();\n\n\treturn {\n\t\tget options() {\n\t\t\treturn options;\n\t\t},\n\t\tgetSession,\n\t\tupdateSession,\n\t\trefreshSession,\n\t\trevokeSession,\n\t\tgetEntrySession,\n\t\tcompleteLogin,\n\t\tlogout,\n\t\thandleLogin,\n\t\thandleRegister,\n\t\thandleCallback,\n\t\thandleRefresh,\n\t\thandleRevoke,\n\t\thandleEntry,\n\t\thandleLogout,\n\t\thandleBackChannelLogout,\n\t\thandler,\n\t};\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"base.cjs","names":[],"sources":["../../src/server/base.ts"],"sourcesContent":["import type { SDKStorage } from '../types/common';\nimport type { SessionData, LogoutTokenClaims } from '../types/oidc';\nimport type { BaseServerSDK, ServerAdapter, ServerStorage, ServerSDKInitConfig } from '../types/server';\nimport {\n\tbuildEndSessionUrl,\n\tbuildAuthorizationUrl,\n\trevokeToken,\n\trefreshToken,\n\texchangeCode,\n\tverifyJwt,\n\tfetchFlowEntry,\n\tgetDiscoveryDocument,\n} from '../utils/oidc';\nimport { isSessionExpired, loadSession, serializeSession } from '../utils/session';\nimport { parseState } from '../utils/state';\nimport { timestamp } from '../utils/common';\nimport { ConfigurationError, OidcError, ProtocolError, type FailureCategory } from '../utils/errors';\nimport {\n\tpushSetCookie,\n\tflushSetCookies,\n\tparseCookieHeader,\n\tserializeCookie,\n\tproxyResponse,\n\ttoSafeRedirect,\n\tgetServerSDKOptions,\n\tBACKCHANNEL_LOGOUT_EVENT,\n\tRETURN_TO_COOKIE,\n} from '../utils/server';\n\nexport { COOKIE_CONTEXT, COOKIE_CHUNK_SIZE } from '../storages/server';\nexport { DISALLOWED_PROXY_HEADERS, RETURN_TO_COOKIE } from '../utils/server';\n\nexport const BACKCHANNEL_LOGOUT_TOKEN_MAX_AGE_SECONDS = 120;\n\n/**\n * Creates the framework-agnostic Strivacity base server SDK.\n *\n * @param {ServerAdapter<TEvent>} adapter - The framework adapter converting `TEvent` to a standard `Request`.\n * @param {ServerSDKOptions<TEvent, Storage, StateStorage>} initConfig - The initial configuration for the server SDK.\n * @returns {BaseServerSDK<TEvent>} The initialized, framework-agnostic server SDK core.\n */\nexport function createBaseServerSDK<\n\tTEvent = unknown,\n\tStorage extends ServerStorage<TEvent> = ServerStorage<TEvent>,\n\tStateStorage extends SDKStorage = SDKStorage,\n>(adapter: ServerAdapter<TEvent>, initConfig: ServerSDKInitConfig<TEvent, Storage, StateStorage>): BaseServerSDK<TEvent> {\n\tconst options = getServerSDKOptions(adapter, initConfig);\n\tconst seenLogoutTokenIds = new Map<string, number>();\n\tconst freshSessions = new WeakMap<object, Promise<SessionData | null>>();\n\n\tfunction init() {\n\t\tif (!options.issuer) {\n\t\t\tconst error = new ConfigurationError('Missing option: issuer');\n\t\t\toptions.logging?.error('Required option missing', error);\n\t\t\tthrow error;\n\t\t}\n\t\tif (!options.clientId) {\n\t\t\tconst error = new ConfigurationError('Missing option: clientId');\n\t\t\toptions.logging?.error('Required option missing', error);\n\t\t\tthrow error;\n\t\t}\n\t\tif (!options.redirectUri) {\n\t\t\tconst error = new ConfigurationError('Missing option: redirectUri');\n\t\t\toptions.logging?.error('Required option missing', error);\n\t\t\tthrow error;\n\t\t}\n\t\tif (options.scopes && !Array.isArray(options.scopes)) {\n\t\t\tconst error = new ConfigurationError('Invalid option: scopes');\n\t\t\toptions.logging?.error('Invalid option provided', error);\n\t\t\tthrow error;\n\t\t}\n\t}\n\n\tasync function redirect(url: string | URL, status = 302, event?: TEvent): Promise<Response> {\n\t\tif (adapter.redirect) {\n\t\t\treturn await adapter.redirect(url, status, event);\n\t\t}\n\n\t\treturn new Response(null, { status, headers: { location: url.toString() } });\n\t}\n\n\tasync function errorRedirect(origin: string, error: unknown, event?: TEvent): Promise<Response> {\n\t\tconst url = new URL('/error', origin);\n\n\t\tif (error instanceof OidcError) {\n\t\t\turl.searchParams.set('type', error.category.toLowerCase());\n\t\t\turl.searchParams.set('error', error.error);\n\t\t\tif (error.errorDescription) {\n\t\t\t\turl.searchParams.set('error_description', error.errorDescription);\n\t\t\t}\n\t\t} else if (error instanceof Error && 'category' in error) {\n\t\t\turl.searchParams.set('type', (error as { category: FailureCategory }).category.toLowerCase());\n\t\t\turl.searchParams.set('error', error.name);\n\t\t\turl.searchParams.set('error_description', error.message);\n\t\t} else {\n\t\t\turl.searchParams.set('type', 'unknown');\n\t\t\turl.searchParams.set('error', 'unknown_error');\n\t\t\turl.searchParams.set('error_description', error instanceof Error ? error.message : 'Unknown error');\n\t\t}\n\n\t\treturn redirect(url, 302, event);\n\t}\n\n\tasync function loadStoredSession(event?: TEvent): Promise<SessionData | null> {\n\t\treturn loadSession(await options.storage.get(options.storageTokenName, event));\n\t}\n\n\tasync function getSession(event?: TEvent, params: { autoRefresh?: boolean } = {}): Promise<SessionData | null> {\n\t\tif (!(params.autoRefresh ?? options.autoRefresh)) {\n\t\t\treturn loadStoredSession(event);\n\t\t}\n\n\t\tconst key = typeof event === 'object' && event !== null ? event : null;\n\t\tconst pending = key ? freshSessions.get(key) : undefined;\n\n\t\tif (pending) {\n\t\t\treturn pending;\n\t\t}\n\n\t\tconst session = await loadStoredSession(event);\n\n\t\tif (!session?.refresh_token || !isSessionExpired(session, options.refreshSkew)) {\n\t\t\treturn session;\n\t\t}\n\n\t\tlet refresh = key ? freshSessions.get(key) : undefined;\n\n\t\tif (!refresh) {\n\t\t\trefresh = refreshSession(event).catch(() => null);\n\n\t\t\tif (key) {\n\t\t\t\tfreshSessions.set(key, refresh);\n\t\t\t}\n\t\t}\n\n\t\treturn refresh;\n\t}\n\n\tasync function updateSession(session: SessionData, event?: TEvent): Promise<void> {\n\t\tawait options.storage.set(options.storageTokenName, serializeSession(session), event);\n\t}\n\n\tasync function cleanupSession(event?: TEvent): Promise<void> {\n\t\tawait options.storage.delete(options.storageTokenName, event);\n\t}\n\n\tasync function refreshSession(event?: TEvent): Promise<SessionData> {\n\t\toptions.logging?.debug('Attempting to refresh session');\n\n\t\tconst currentSession = await loadStoredSession(event);\n\n\t\tif (!currentSession) {\n\t\t\tthrow new ProtocolError('No session available to refresh');\n\t\t}\n\n\t\tif (typeof currentSession.refresh_token !== 'string') {\n\t\t\tthrow new ConfigurationError('No refresh token available');\n\t\t}\n\n\t\ttry {\n\t\t\tconst newSession = await refreshToken({ refreshToken: currentSession.refresh_token, options, expectedSub: currentSession.claims?.sub });\n\t\t\tawait updateSession(newSession, event);\n\n\t\t\toptions.logging?.debug('Session refresh successful');\n\n\t\t\treturn newSession;\n\t\t} catch (error) {\n\t\t\tawait cleanupSession(event);\n\t\t\toptions.logging?.error('Session refresh failed', error as Error);\n\n\t\t\tthrow error;\n\t\t}\n\t}\n\n\tasync function revokeSession(event?: TEvent): Promise<void> {\n\t\tconst currentSession = await loadStoredSession(event);\n\n\t\tif (currentSession?.refresh_token) {\n\t\t\toptions.logging?.debug('Attempting to revoke refresh token');\n\t\t} else {\n\t\t\toptions.logging?.debug('Attempting to revoke access token');\n\t\t}\n\n\t\t// NOTE: Cleanup session before revocation\n\t\tawait cleanupSession(event);\n\n\t\tif (!currentSession?.access_token && !currentSession?.refresh_token) {\n\t\t\toptions.logging?.debug('Revoke called without session');\n\t\t\treturn;\n\t\t}\n\n\t\tconst tokenTypeHint = currentSession.refresh_token ? 'refresh_token' : 'access_token';\n\t\tconst token = (tokenTypeHint === 'refresh_token' ? currentSession.refresh_token : currentSession.access_token)!;\n\n\t\ttry {\n\t\t\tawait revokeToken({ tokenTypeHint, token, options });\n\n\t\t\tif (tokenTypeHint === 'refresh_token') {\n\t\t\t\toptions.logging?.info('Refresh token successfully revoked');\n\t\t\t} else {\n\t\t\t\toptions.logging?.info('Access token successfully revoked');\n\t\t\t}\n\t\t} catch (error) {\n\t\t\toptions.logging?.error('Token revocation failed', error as Error);\n\t\t\tthrow error;\n\t\t}\n\t}\n\n\tasync function getEntrySession(entryUrl: string | URL): Promise<Record<string, string>> {\n\t\toptions.logging?.debug('Attempting entry request');\n\n\t\tconst { searchParams: params } = new URL(entryUrl);\n\n\t\ttry {\n\t\t\tconst url = new URL('/provider/flow/entry', options.issuer);\n\t\t\tconst data = await fetchFlowEntry({\n\t\t\t\turl,\n\t\t\t\tparams,\n\t\t\t\tsdkMode: options.mode === 'embedded' ? 'web-embedded' : 'web',\n\t\t\t\toptions,\n\t\t\t});\n\n\t\t\toptions.logging?.debug(`Entry request successful - ${JSON.stringify(data)}`);\n\n\t\t\treturn data;\n\t\t} catch (error) {\n\t\t\toptions.logging?.error('Entry request failed', error as Error);\n\t\t\tthrow error;\n\t\t}\n\t}\n\n\tasync function completeLogin(params: Record<string, string>, event?: TEvent): Promise<SessionData> {\n\t\toptions.logging?.debug('Exchanging authorization code for tokens');\n\n\t\ttry {\n\t\t\tconst session = await exchangeCode({ params, options });\n\n\t\t\tif (!session.access_token) {\n\t\t\t\tthrow new ProtocolError('Missing access_token');\n\t\t\t}\n\n\t\t\tawait updateSession(session, event);\n\n\t\t\toptions.logging?.debug('Token exchange successful');\n\n\t\t\tif (options.logging) {\n\t\t\t\toptions.logging.xEventId = undefined;\n\t\t\t\toptions.logging.info('Login successful');\n\t\t\t}\n\n\t\t\treturn session;\n\t\t} catch (error) {\n\t\t\toptions.logging?.error('Token exchange failed', error as Error);\n\t\t\tthrow error;\n\t\t}\n\t}\n\n\tasync function logout(postLogoutRedirectUri: string | URL, event?: TEvent): Promise<URL> {\n\t\toptions.logging?.debug('Attempting to logout');\n\n\t\t// NOTE: Cleanup session before logout\n\t\tconst currentSession = await loadStoredSession(event);\n\t\tawait cleanupSession(event);\n\n\t\toptions.logging?.debug('Logout initiated');\n\n\t\tif (!currentSession?.id_token) {\n\t\t\toptions.logging?.debug('Logout called without id token');\n\t\t\treturn new URL(postLogoutRedirectUri);\n\t\t}\n\n\t\tconst metadata = await getDiscoveryDocument(options);\n\n\t\treturn buildEndSessionUrl({\n\t\t\turl: metadata.end_session_endpoint,\n\t\t\tidToken: currentSession.id_token,\n\t\t\tpostLogoutRedirectUri: new URL(postLogoutRedirectUri).toString(),\n\t\t});\n\t}\n\n\tasync function handleLogin(event: TEvent, extraParams: Record<string, unknown> = {}): Promise<Response> {\n\t\tconst request = await adapter.toRequest(event);\n\t\tconst requestUrl = new URL(request.url);\n\t\tconst { returnTo, prompt, display, login_hint, acr_values, ui_locales, audience, ...params } = Object.fromEntries(requestUrl.searchParams);\n\t\tconst safeReturnTo = toSafeRedirect(returnTo, requestUrl.origin);\n\t\tconst url = await buildAuthorizationUrl({\n\t\t\tparams: {\n\t\t\t\tprompt: prompt ?? params.prompt,\n\t\t\t\tdisplay: display ?? params.display,\n\t\t\t\tloginHint: login_hint ?? params.loginHint,\n\t\t\t\tacrValues: (acr_values ?? params.acrValues)?.split(' '),\n\t\t\t\tuiLocales: (ui_locales ?? params.uiLocales)?.split(' '),\n\t\t\t\taudiences: (audience ?? params.audiences)?.split(' '),\n\t\t\t\t...extraParams,\n\t\t\t},\n\t\t\toptions,\n\t\t});\n\n\t\tif (returnTo && !safeReturnTo) {\n\t\t\tthrow new ProtocolError(`Invalid returnTo URL: ${returnTo}. Expected a URL with the same origin as the request: ${requestUrl.origin}`);\n\t\t}\n\n\t\tif (['embedded', 'native'].includes(options.mode) && params.sdk) {\n\t\t\turl.searchParams.set('sdk', params.sdk);\n\t\t}\n\n\t\tconst startResponse = await options.httpClient.request<string>(url, {\n\t\t\tmethod: 'GET',\n\t\t\tcredentials: 'include',\n\t\t\tredirect: 'manual',\n\t\t});\n\n\t\toptions.logging?.debug('Attempting to redirect for login');\n\n\t\tif (safeReturnTo) {\n\t\t\tpushSetCookie(event, serializeCookie(RETURN_TO_COOKIE, safeReturnTo));\n\t\t}\n\n\t\treturn flushSetCookies(event, proxyResponse(startResponse));\n\t}\n\n\tasync function handleRegister(event: TEvent): Promise<Response> {\n\t\treturn handleLogin(event, { prompt: 'create' });\n\t}\n\n\tasync function handleCallback(event: TEvent): Promise<Response> {\n\t\tconst request = await adapter.toRequest(event);\n\t\tconst requestUrl = new URL(request.url);\n\t\tconst params = Object.fromEntries(requestUrl.searchParams);\n\n\t\ttry {\n\t\t\tconst serializedState = await options.stateStorage.get(`sty.${params.state}`);\n\n\t\t\tif (!serializedState) {\n\t\t\t\tthrow new ProtocolError('State not found or expired. Please try logging in again.');\n\t\t\t}\n\n\t\t\tawait completeLogin(params, event);\n\n\t\t\tconst state = parseState(serializedState);\n\t\t\tconst returnTo = parseCookieHeader(request.headers.get('cookie'))[RETURN_TO_COOKIE] ?? options.postLoginRedirectUri;\n\n\t\t\tpushSetCookie(event, serializeCookie(RETURN_TO_COOKIE, '', { maxAge: 0 }));\n\n\t\t\tif (state.metadata?.display === 'popup') {\n\t\t\t\t// NOTE: If the login was initiated from a popup, we return a HTML page that will close the popup and notify the opener window.\n\t\t\t\treturn flushSetCookies(\n\t\t\t\t\tevent,\n\t\t\t\t\tnew Response(`<!DOCTYPE html><html><body><script>window.opener?.postMessage({}, '*');window.close();</script></body></html>`, {\n\t\t\t\t\t\theaders: { 'content-type': 'text/html; charset=utf-8' },\n\t\t\t\t\t}),\n\t\t\t\t);\n\t\t\t}\n\n\t\t\treturn flushSetCookies(event, await redirect(new URL(returnTo, requestUrl.origin), 302, event));\n\t\t} catch (error) {\n\t\t\treturn flushSetCookies(event, await errorRedirect(requestUrl.origin, error, event));\n\t\t}\n\t}\n\n\tasync function handleRefresh(event: TEvent): Promise<Response> {\n\t\tconst request = await adapter.toRequest(event);\n\t\tconst requestUrl = new URL(request.url);\n\t\tconst origin = requestUrl.origin;\n\t\tconst returnTo = requestUrl.searchParams.get('returnTo');\n\t\tconst safeReturnTo = toSafeRedirect(returnTo, origin);\n\n\t\tif (returnTo && !safeReturnTo) {\n\t\t\tthrow new ProtocolError(`Invalid returnTo URL: ${returnTo}. Expected a URL with the same origin as the request: ${requestUrl.origin}`);\n\t\t}\n\n\t\ttry {\n\t\t\tawait refreshSession(event);\n\n\t\t\tif (safeReturnTo) {\n\t\t\t\treturn flushSetCookies(event, await redirect(new URL(safeReturnTo, origin), 302, event));\n\t\t\t}\n\n\t\t\treturn flushSetCookies(event, new Response(null, { status: 204 }));\n\t\t} catch (error) {\n\t\t\treturn flushSetCookies(event, await errorRedirect(origin, error, event));\n\t\t}\n\t}\n\n\tasync function handleRevoke(event: TEvent): Promise<Response> {\n\t\tconst request = await adapter.toRequest(event);\n\t\tconst origin = new URL(request.url).origin;\n\n\t\ttry {\n\t\t\tawait revokeSession(event);\n\n\t\t\treturn flushSetCookies(event, await redirect(new URL(options.postLogoutRedirectUri, origin), 302, event));\n\t\t} catch (error) {\n\t\t\treturn flushSetCookies(event, await errorRedirect(origin, error, event));\n\t\t}\n\t}\n\n\tasync function handleEntry(event: TEvent): Promise<Response> {\n\t\tconst request = await adapter.toRequest(event);\n\t\tconst origin = new URL(request.url).origin;\n\n\t\ttry {\n\t\t\tconst data = await getEntrySession(request.url);\n\t\t\tconst uri = new URL(options.loginUri, origin);\n\t\t\turi.searchParams.set('session_id', data.session_id);\n\t\t\turi.searchParams.set('short_app_id', data.short_app_id);\n\t\t\turi.searchParams.set('language', data.language);\n\n\t\t\treturn flushSetCookies(event, await redirect(uri, 302, event));\n\t\t} catch (error) {\n\t\t\treturn flushSetCookies(event, await errorRedirect(origin, error, event));\n\t\t}\n\t}\n\n\tasync function handleLogout(event: TEvent): Promise<Response> {\n\t\tconst request = await adapter.toRequest(event);\n\t\tconst requestUrl = new URL(request.url);\n\t\tconst origin = requestUrl.origin;\n\t\tconst returnTo = requestUrl.searchParams.get('returnTo');\n\t\tconst safeReturnTo = toSafeRedirect(returnTo, origin);\n\n\t\ttry {\n\t\t\tconst logoutUrl = await logout(new URL(safeReturnTo ?? options.postLogoutRedirectUri, origin), event);\n\t\t\treturn flushSetCookies(event, await redirect(logoutUrl, 302, event));\n\t\t} catch (error) {\n\t\t\treturn flushSetCookies(event, await errorRedirect(origin, error, event));\n\t\t}\n\t}\n\n\tasync function handleBackChannelLogout(event: TEvent): Promise<Response> {\n\t\tif (typeof options.storage.deleteByLogoutToken !== 'function') {\n\t\t\treturn new Response('Back-channel logout requires a storage with deleteByLogoutToken', { status: 501 });\n\t\t}\n\n\t\tconst request = await adapter.toRequest(event);\n\t\tlet logoutToken: string | null;\n\n\t\ttry {\n\t\t\tconst contentType = request.headers.get('content-type') ?? '';\n\n\t\t\tif (contentType.includes('application/x-www-form-urlencoded')) {\n\t\t\t\tconst body = await request.formData();\n\t\t\t\tlogoutToken = body.get('logout_token') as string | null;\n\t\t\t} else {\n\t\t\t\treturn new Response('Invalid content type: expected application/x-www-form-urlencoded', { status: 400 });\n\t\t\t}\n\t\t} catch {\n\t\t\treturn new Response('Failed to parse request body', { status: 400 });\n\t\t}\n\n\t\tif (!logoutToken) {\n\t\t\treturn new Response('Missing logout_token', { status: 400 });\n\t\t}\n\n\t\tconst now = timestamp();\n\n\t\tfor (const [token, expiresAt] of seenLogoutTokenIds) {\n\t\t\tif (expiresAt <= now) {\n\t\t\t\tseenLogoutTokenIds.delete(token);\n\t\t\t}\n\t\t}\n\n\t\tif (seenLogoutTokenIds.has(logoutToken)) {\n\t\t\treturn new Response('Invalid logout_token: token already used', { status: 400 });\n\t\t}\n\n\t\tseenLogoutTokenIds.set(logoutToken, now + BACKCHANNEL_LOGOUT_TOKEN_MAX_AGE_SECONDS);\n\n\t\tlet claims;\n\t\tlet metadata;\n\n\t\ttry {\n\t\t\tmetadata = await getDiscoveryDocument(options);\n\t\t\tclaims = await verifyJwt<LogoutTokenClaims>({ token: logoutToken, jwksUri: metadata.jwks_uri, options });\n\t\t} catch (error) {\n\t\t\treturn new Response(`Invalid logout_token: ${error.message}`, { status: 400 });\n\t\t}\n\n\t\tif (claims.iss !== metadata.issuer) {\n\t\t\treturn new Response('Invalid logout_token: invalid iss claim', { status: 400 });\n\t\t}\n\n\t\tif (Array.isArray(claims.aud) ? !claims.aud.includes(options.clientId) : claims.aud !== options.clientId) {\n\t\t\treturn new Response('Invalid logout_token: invalid aud claim', { status: 400 });\n\t\t}\n\n\t\tif (typeof claims.iat !== 'number' || Math.abs(now - claims.iat) > BACKCHANNEL_LOGOUT_TOKEN_MAX_AGE_SECONDS) {\n\t\t\treturn new Response('Invalid logout_token: invalid or stale iat claim', { status: 400 });\n\t\t}\n\n\t\tif (!claims.jti) {\n\t\t\treturn new Response('Invalid logout_token: missing jti claim', { status: 400 });\n\t\t}\n\n\t\tif (claims.nonce !== undefined) {\n\t\t\treturn new Response('Invalid logout_token: nonce claim must not be present', { status: 400 });\n\t\t}\n\n\t\tif (!claims.events || !(BACKCHANNEL_LOGOUT_EVENT in claims.events)) {\n\t\t\treturn new Response(`Invalid logout_token: missing ${BACKCHANNEL_LOGOUT_EVENT} in events`, { status: 400 });\n\t\t}\n\n\t\tif (!claims.sid && !claims.sub) {\n\t\t\treturn new Response('Invalid logout_token: must contain sid or sub claim', { status: 400 });\n\t\t}\n\n\t\tconst token: LogoutTokenClaims = {} as never;\n\n\t\tif (claims.sid) {\n\t\t\ttoken.sid = claims.sid;\n\t\t}\n\t\tif (claims.sub) {\n\t\t\ttoken.sub = claims.sub;\n\t\t}\n\n\t\ttry {\n\t\t\tawait options.storage.deleteByLogoutToken(token);\n\t\t} catch (error) {\n\t\t\treturn new Response(`Failed to delete session: ${error.message}`, { status: 500 });\n\t\t}\n\n\t\treturn new Response(null, { status: 200 });\n\t}\n\n\tasync function handler(event: TEvent): Promise<Response | null> {\n\t\tconst request = await adapter.toRequest(event);\n\t\tconst requestUrl = new URL(request.url);\n\n\t\tif (request.method === 'GET' && requestUrl.pathname === `${options.authUrlPrefix}/login`) {\n\t\t\treturn handleLogin(event);\n\t\t}\n\t\tif (request.method === 'GET' && requestUrl.pathname === `${options.authUrlPrefix}/register`) {\n\t\t\treturn handleRegister(event);\n\t\t}\n\t\tif (request.method === 'GET' && requestUrl.pathname === `${options.authUrlPrefix}/callback`) {\n\t\t\treturn handleCallback(event);\n\t\t}\n\t\tif (request.method === 'GET' && requestUrl.pathname === `${options.authUrlPrefix}/refresh`) {\n\t\t\treturn handleRefresh(event);\n\t\t}\n\t\tif (request.method === 'GET' && requestUrl.pathname === `${options.authUrlPrefix}/revoke`) {\n\t\t\treturn handleRevoke(event);\n\t\t}\n\t\tif (request.method === 'GET' && requestUrl.pathname === `${options.authUrlPrefix}/entry`) {\n\t\t\treturn handleEntry(event);\n\t\t}\n\t\tif (request.method === 'GET' && requestUrl.pathname === `${options.authUrlPrefix}/logout`) {\n\t\t\treturn handleLogout(event);\n\t\t}\n\t\tif (request.method === 'POST' && requestUrl.pathname === `${options.authUrlPrefix}/backchannel-logout`) {\n\t\t\treturn handleBackChannelLogout(event);\n\t\t}\n\n\t\treturn null;\n\t}\n\n\t// endregion\n\n\tinit();\n\n\treturn {\n\t\tget options() {\n\t\t\treturn options;\n\t\t},\n\t\tgetSession,\n\t\tupdateSession,\n\t\trefreshSession,\n\t\trevokeSession,\n\t\tgetEntrySession,\n\t\tcompleteLogin,\n\t\tlogout,\n\t\thandleLogin,\n\t\thandleRegister,\n\t\thandleCallback,\n\t\thandleRefresh,\n\t\thandleRevoke,\n\t\thandleEntry,\n\t\thandleLogout,\n\t\thandleBackChannelLogout,\n\t\thandler,\n\t};\n}\n"],"mappings":"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"}
@@ -1,9 +1,7 @@
1
1
  import { SDKStorage } from '../types/common';
2
2
  import { BaseServerSDK, ServerAdapter, ServerStorage, ServerSDKInitConfig } from '../types/server';
3
- export declare const COOKIE_CONTEXT = "strivacity-session-v1";
4
- export declare const COOKIE_CHUNK_SIZE = 3900;
5
- export declare const DISALLOWED_PROXY_HEADERS: Set<string>;
6
- export declare const RETURN_TO_COOKIE = "sty.returnTo";
3
+ export { COOKIE_CONTEXT, COOKIE_CHUNK_SIZE } from '../storages/server';
4
+ export { DISALLOWED_PROXY_HEADERS, RETURN_TO_COOKIE } from '../utils/server';
7
5
  export declare const BACKCHANNEL_LOGOUT_TOKEN_MAX_AGE_SECONDS = 120;
8
6
  /**
9
7
  * Creates the framework-agnostic Strivacity base server SDK.
@@ -1,2 +1,2 @@
1
- import{ConfigurationError as e,OidcError as t,ProtocolError as n}from"../utils/errors.mjs";import{timestamp as r}from"../utils/common.mjs";import{loadSession as i,serializeSession as a}from"../utils/session.mjs";import{a as o,g as s,h as c,n as l,o as u,p as d,t as f,x as p,y as m}from"../assets/oidc.mjs";import{a as h,c as g,d as _,l as v,o as y,s as b,t as x,u as S}from"../assets/server.mjs";var C=`strivacity-session-v1`,w=3900,T=new Set([`transfer-encoding`,`connection`,`keep-alive`,`content-encoding`]),E=`sty.returnTo`,D=120;function O(C,w){let T=y(C,w),D=new Map;function O(){if(!T.issuer){let t=new e(`Missing option: issuer`);throw T.logging?.error(`Required option missing`,t),t}if(!T.clientId){let t=new e(`Missing option: clientId`);throw T.logging?.error(`Required option missing`,t),t}if(!T.redirectUri){let t=new e(`Missing option: redirectUri`);throw T.logging?.error(`Required option missing`,t),t}if(T.scopes&&!Array.isArray(T.scopes)){let t=new e(`Invalid option: scopes`);throw T.logging?.error(`Invalid option provided`,t),t}}async function k(e,t=302,n){return C.redirect?await C.redirect(e,t,n):new Response(null,{status:t,headers:{location:e.toString()}})}async function A(e,n,r){let i=new URL(`/error`,e);return n instanceof t?(i.searchParams.set(`type`,n.category.toLowerCase()),i.searchParams.set(`error`,n.error),n.errorDescription&&i.searchParams.set(`error_description`,n.errorDescription)):n instanceof Error&&`category`in n?(i.searchParams.set(`type`,n.category.toLowerCase()),i.searchParams.set(`error`,n.name),i.searchParams.set(`error_description`,n.message)):(i.searchParams.set(`type`,`unknown`),i.searchParams.set(`error`,`unknown_error`),i.searchParams.set(`error_description`,n instanceof Error?n.message:`Unknown error`)),k(i,302,r)}async function j(e){return i(await T.storage.get(T.storageTokenName,e))}async function M(e,t){await T.storage.set(T.storageTokenName,a(e),t)}async function N(e){await T.storage.delete(T.storageTokenName,e)}async function P(t){T.logging?.debug(`Attempting to refresh session`);let r=await j(t);if(!r)throw new n(`No session available to refresh`);if(typeof r.refresh_token!=`string`)throw new e(`No refresh token available`);try{let e=await c({refreshToken:r.refresh_token,options:T,expectedSub:r.claims?.sub});return await M(e,t),T.logging?.debug(`Session refresh successful`),e}catch(e){throw await N(t),T.logging?.error(`Session refresh failed`,e),e}}async function F(e){let t=await j(e);if(t?.refresh_token?T.logging?.debug(`Attempting to revoke refresh token`):T.logging?.debug(`Attempting to revoke access token`),await N(e),!t?.access_token&&!t?.refresh_token){T.logging?.debug(`Revoke called without session`);return}let n=t.refresh_token?`refresh_token`:`access_token`,r=n===`refresh_token`?t.refresh_token:t.access_token;try{await s({tokenTypeHint:n,token:r,options:T}),n===`refresh_token`?T.logging?.info(`Refresh token successfully revoked`):T.logging?.info(`Access token successfully revoked`)}catch(e){throw T.logging?.error(`Token revocation failed`,e),e}}async function I(e){T.logging?.debug(`Attempting entry request`);let{searchParams:t}=new URL(e);try{let e=new URL(`/provider/flow/entry`,T.issuer),n=await u({url:e,params:t,sdkMode:T.mode===`embedded`?`web-embedded`:`web`,options:T});return T.logging?.debug(`Entry request successful - ${JSON.stringify(n)}`),n}catch(e){throw T.logging?.error(`Entry request failed`,e),e}}async function L(e,t){T.logging?.debug(`Exchanging authorization code for tokens`);try{let r=await o({params:e,options:T});if(!r.access_token)throw new n(`Missing access_token`);return await M(r,t),T.logging?.debug(`Token exchange successful`),T.logging&&(T.logging.xEventId=void 0,T.logging.info(`Login successful`)),r}catch(e){throw T.logging?.error(`Token exchange failed`,e),e}}async function R(e,t){T.logging?.debug(`Attempting to logout`);let n=await j(t);if(await N(t),T.logging?.debug(`Logout initiated`),!n?.id_token)return T.logging?.debug(`Logout called without id token`),new URL(e);let r=await d(T);return l({url:r.end_session_endpoint,idToken:n.id_token,postLogoutRedirectUri:new URL(e).toString()})}async function z(e,t={}){let r=await C.toRequest(e),i=new URL(r.url),{returnTo:a,...o}=Object.fromEntries(i.searchParams),s=_(a,i.origin),c=await f({params:{...o,...t},options:T});if(a&&!s)throw new n(`Invalid returnTo URL: ${a}. Expected a URL with the same origin as the request: ${i.origin}`);[`embedded`,`native`].includes(T.mode)&&o.sdk&&c.searchParams.set(`sdk`,o.sdk);let l=await T.httpClient.request(c,{method:`GET`,credentials:`include`,redirect:`manual`});return T.logging?.debug(`Attempting to redirect for login`),s&&v(e,S(E,s)),h(e,g(l))}async function B(e){return z(e,{prompt:`create`})}async function V(e){let t=await C.toRequest(e),r=new URL(t.url),i=Object.fromEntries(r.searchParams);try{let a=await T.stateStorage.get(`sty.${i.state}`);if(!a)throw new n(`State not found or expired. Please try logging in again.`);await L(i,e);let o=p(a),s=b(t.headers.get(`cookie`))[`sty.returnTo`]??T.postLoginRedirectUri;return v(e,S(E,``,{expires:new Date(0)})),o.metadata?.display===`popup`?h(e,new Response(`<!DOCTYPE html><html><body><script>window.opener?.postMessage({}, '*');window.close();<\/script></body></html>`,{headers:{"content-type":`text/html; charset=utf-8`}})):h(e,await k(new URL(s,r.origin),302,e))}catch(t){return h(e,await A(r.origin,t,e))}}async function H(e){let t=await C.toRequest(e),r=new URL(t.url),i=r.origin,a=r.searchParams.get(`returnTo`),o=_(a,i);if(a&&!o)throw new n(`Invalid returnTo URL: ${a}. Expected a URL with the same origin as the request: ${r.origin}`);try{return await P(e),o?h(e,await k(new URL(o,i),302,e)):h(e,new Response(null,{status:204}))}catch(t){return h(e,await A(i,t,e))}}async function U(e){let t=await C.toRequest(e),n=new URL(t.url).origin;try{return await F(e),h(e,await k(new URL(T.postLogoutRedirectUri,n),302,e))}catch(t){return h(e,await A(n,t,e))}}async function W(e){let t=await C.toRequest(e),n=new URL(t.url).origin;try{let r=await I(t.url),i=new URL(T.loginUri,n);return i.searchParams.set(`session_id`,r.session_id),i.searchParams.set(`short_app_id`,r.short_app_id),i.searchParams.set(`language`,r.language),h(e,await k(i,302,e))}catch(t){return h(e,await A(n,t,e))}}async function G(e){let t=await C.toRequest(e),n=new URL(t.url).origin;try{let t=await R(new URL(T.postLogoutRedirectUri,n),e);return h(e,await k(t,302,e))}catch(t){return h(e,await A(n,t,e))}}async function K(e){if(typeof T.storage.deleteByLogoutToken!=`function`)return new Response(`Back-channel logout requires a storage with deleteByLogoutToken`,{status:501});let t=await C.toRequest(e),n;try{if((t.headers.get(`content-type`)??``).includes(`application/x-www-form-urlencoded`))n=(await t.formData()).get(`logout_token`);else return new Response(`Invalid content type: expected application/x-www-form-urlencoded`,{status:400})}catch{return new Response(`Failed to parse request body`,{status:400})}if(!n)return new Response(`Missing logout_token`,{status:400});let i=r();for(let[e,t]of D)t<=i&&D.delete(e);if(D.has(n))return new Response(`Invalid logout_token: token already used`,{status:400});D.set(n,i+120);let a,o;try{o=await d(T),a=await m({token:n,jwksUri:o.jwks_uri,options:T})}catch(e){return new Response(`Invalid logout_token: ${e.message}`,{status:400})}if(a.iss!==o.issuer)return new Response(`Invalid logout_token: invalid iss claim`,{status:400});if(Array.isArray(a.aud)?!a.aud.includes(T.clientId):a.aud!==T.clientId)return new Response(`Invalid logout_token: invalid aud claim`,{status:400});if(typeof a.iat!=`number`||Math.abs(i-a.iat)>120)return new Response(`Invalid logout_token: invalid or stale iat claim`,{status:400});if(!a.jti)return new Response(`Invalid logout_token: missing jti claim`,{status:400});if(a.nonce!==void 0)return new Response(`Invalid logout_token: nonce claim must not be present`,{status:400});if(!a.events||!(`http://schemas.openid.net/event/backchannel-logout`in a.events))return new Response(`Invalid logout_token: missing ${x} in events`,{status:400});if(!a.sid&&!a.sub)return new Response(`Invalid logout_token: must contain sid or sub claim`,{status:400});let s={};a.sid&&(s.sid=a.sid),a.sub&&(s.sub=a.sub);try{await T.storage.deleteByLogoutToken(s)}catch(e){return new Response(`Failed to delete session: ${e.message}`,{status:500})}return new Response(null,{status:200})}async function q(e){let t=await C.toRequest(e),n=new URL(t.url);return t.method===`GET`&&n.pathname===`${T.authUrlPrefix}/login`?z(e):t.method===`GET`&&n.pathname===`${T.authUrlPrefix}/register`?B(e):t.method===`GET`&&n.pathname===`${T.authUrlPrefix}/callback`?V(e):t.method===`GET`&&n.pathname===`${T.authUrlPrefix}/refresh`?H(e):t.method===`GET`&&n.pathname===`${T.authUrlPrefix}/revoke`?U(e):t.method===`GET`&&n.pathname===`${T.authUrlPrefix}/entry`?W(e):t.method===`GET`&&n.pathname===`${T.authUrlPrefix}/logout`?G(e):t.method===`POST`&&n.pathname===`${T.authUrlPrefix}/backchannel-logout`?K(e):null}return O(),{get options(){return T},getSession:j,updateSession:M,refreshSession:P,revokeSession:F,getEntrySession:I,completeLogin:L,logout:R,handleLogin:z,handleRegister:B,handleCallback:V,handleRefresh:H,handleRevoke:U,handleEntry:W,handleLogout:G,handleBackChannelLogout:K,handler:q}}export{D as BACKCHANNEL_LOGOUT_TOKEN_MAX_AGE_SECONDS,w as COOKIE_CHUNK_SIZE,C as COOKIE_CONTEXT,T as DISALLOWED_PROXY_HEADERS,E as RETURN_TO_COOKIE,O as createBaseServerSDK};
1
+ import{ConfigurationError as e,OidcError as t,ProtocolError as n}from"../utils/errors.mjs";import{timestamp as r}from"../utils/common.mjs";import{isSessionExpired as i,loadSession as a,serializeSession as o}from"../utils/session.mjs";import{a as s,g as c,h as l,n as u,o as d,p as f,t as p,x as m,y as h}from"../assets/oidc.mjs";import{a as g,c as _,d as v,f as y,i as b,l as x,o as S,p as C,r as w,s as T,t as E,u as D}from"../assets/server.mjs";var O=120;function k(y,C){let w=S(y,C),O=new Map,k=new WeakMap;function A(){if(!w.issuer){let t=new e(`Missing option: issuer`);throw w.logging?.error(`Required option missing`,t),t}if(!w.clientId){let t=new e(`Missing option: clientId`);throw w.logging?.error(`Required option missing`,t),t}if(!w.redirectUri){let t=new e(`Missing option: redirectUri`);throw w.logging?.error(`Required option missing`,t),t}if(w.scopes&&!Array.isArray(w.scopes)){let t=new e(`Invalid option: scopes`);throw w.logging?.error(`Invalid option provided`,t),t}}async function j(e,t=302,n){return y.redirect?await y.redirect(e,t,n):new Response(null,{status:t,headers:{location:e.toString()}})}async function M(e,n,r){let i=new URL(`/error`,e);return n instanceof t?(i.searchParams.set(`type`,n.category.toLowerCase()),i.searchParams.set(`error`,n.error),n.errorDescription&&i.searchParams.set(`error_description`,n.errorDescription)):n instanceof Error&&`category`in n?(i.searchParams.set(`type`,n.category.toLowerCase()),i.searchParams.set(`error`,n.name),i.searchParams.set(`error_description`,n.message)):(i.searchParams.set(`type`,`unknown`),i.searchParams.set(`error`,`unknown_error`),i.searchParams.set(`error_description`,n instanceof Error?n.message:`Unknown error`)),j(i,302,r)}async function N(e){return a(await w.storage.get(w.storageTokenName,e))}async function P(e,t={}){if(!(t.autoRefresh??w.autoRefresh))return N(e);let n=typeof e==`object`&&e?e:null,r=n?k.get(n):void 0;if(r)return r;let a=await N(e);if(!a?.refresh_token||!i(a,w.refreshSkew))return a;let o=n?k.get(n):void 0;return o||(o=L(e).catch(()=>null),n&&k.set(n,o)),o}async function F(e,t){await w.storage.set(w.storageTokenName,o(e),t)}async function I(e){await w.storage.delete(w.storageTokenName,e)}async function L(t){w.logging?.debug(`Attempting to refresh session`);let r=await N(t);if(!r)throw new n(`No session available to refresh`);if(typeof r.refresh_token!=`string`)throw new e(`No refresh token available`);try{let e=await l({refreshToken:r.refresh_token,options:w,expectedSub:r.claims?.sub});return await F(e,t),w.logging?.debug(`Session refresh successful`),e}catch(e){throw await I(t),w.logging?.error(`Session refresh failed`,e),e}}async function R(e){let t=await N(e);if(t?.refresh_token?w.logging?.debug(`Attempting to revoke refresh token`):w.logging?.debug(`Attempting to revoke access token`),await I(e),!t?.access_token&&!t?.refresh_token){w.logging?.debug(`Revoke called without session`);return}let n=t.refresh_token?`refresh_token`:`access_token`,r=n===`refresh_token`?t.refresh_token:t.access_token;try{await c({tokenTypeHint:n,token:r,options:w}),n===`refresh_token`?w.logging?.info(`Refresh token successfully revoked`):w.logging?.info(`Access token successfully revoked`)}catch(e){throw w.logging?.error(`Token revocation failed`,e),e}}async function z(e){w.logging?.debug(`Attempting entry request`);let{searchParams:t}=new URL(e);try{let e=new URL(`/provider/flow/entry`,w.issuer),n=await d({url:e,params:t,sdkMode:w.mode===`embedded`?`web-embedded`:`web`,options:w});return w.logging?.debug(`Entry request successful - ${JSON.stringify(n)}`),n}catch(e){throw w.logging?.error(`Entry request failed`,e),e}}async function B(e,t){w.logging?.debug(`Exchanging authorization code for tokens`);try{let r=await s({params:e,options:w});if(!r.access_token)throw new n(`Missing access_token`);return await F(r,t),w.logging?.debug(`Token exchange successful`),w.logging&&(w.logging.xEventId=void 0,w.logging.info(`Login successful`)),r}catch(e){throw w.logging?.error(`Token exchange failed`,e),e}}async function V(e,t){w.logging?.debug(`Attempting to logout`);let n=await N(t);if(await I(t),w.logging?.debug(`Logout initiated`),!n?.id_token)return w.logging?.debug(`Logout called without id token`),new URL(e);let r=await f(w);return u({url:r.end_session_endpoint,idToken:n.id_token,postLogoutRedirectUri:new URL(e).toString()})}async function H(e,t={}){let r=await y.toRequest(e),i=new URL(r.url),{returnTo:a,prompt:o,display:s,login_hint:c,acr_values:l,ui_locales:u,audience:d,...f}=Object.fromEntries(i.searchParams),m=v(a,i.origin),h=await p({params:{prompt:o??f.prompt,display:s??f.display,loginHint:c??f.loginHint,acrValues:(l??f.acrValues)?.split(` `),uiLocales:(u??f.uiLocales)?.split(` `),audiences:(d??f.audiences)?.split(` `),...t},options:w});if(a&&!m)throw new n(`Invalid returnTo URL: ${a}. Expected a URL with the same origin as the request: ${i.origin}`);[`embedded`,`native`].includes(w.mode)&&f.sdk&&h.searchParams.set(`sdk`,f.sdk);let S=await w.httpClient.request(h,{method:`GET`,credentials:`include`,redirect:`manual`});return w.logging?.debug(`Attempting to redirect for login`),m&&x(e,D(b,m)),g(e,_(S))}async function U(e){return H(e,{prompt:`create`})}async function W(e){let t=await y.toRequest(e),r=new URL(t.url),i=Object.fromEntries(r.searchParams);try{let a=await w.stateStorage.get(`sty.${i.state}`);if(!a)throw new n(`State not found or expired. Please try logging in again.`);await B(i,e);let o=m(a),s=T(t.headers.get(`cookie`))[`sty.returnTo`]??w.postLoginRedirectUri;return x(e,D(b,``,{maxAge:0})),o.metadata?.display===`popup`?g(e,new Response(`<!DOCTYPE html><html><body><script>window.opener?.postMessage({}, '*');window.close();<\/script></body></html>`,{headers:{"content-type":`text/html; charset=utf-8`}})):g(e,await j(new URL(s,r.origin),302,e))}catch(t){return g(e,await M(r.origin,t,e))}}async function G(e){let t=await y.toRequest(e),r=new URL(t.url),i=r.origin,a=r.searchParams.get(`returnTo`),o=v(a,i);if(a&&!o)throw new n(`Invalid returnTo URL: ${a}. Expected a URL with the same origin as the request: ${r.origin}`);try{return await L(e),o?g(e,await j(new URL(o,i),302,e)):g(e,new Response(null,{status:204}))}catch(t){return g(e,await M(i,t,e))}}async function K(e){let t=await y.toRequest(e),n=new URL(t.url).origin;try{return await R(e),g(e,await j(new URL(w.postLogoutRedirectUri,n),302,e))}catch(t){return g(e,await M(n,t,e))}}async function q(e){let t=await y.toRequest(e),n=new URL(t.url).origin;try{let r=await z(t.url),i=new URL(w.loginUri,n);return i.searchParams.set(`session_id`,r.session_id),i.searchParams.set(`short_app_id`,r.short_app_id),i.searchParams.set(`language`,r.language),g(e,await j(i,302,e))}catch(t){return g(e,await M(n,t,e))}}async function J(e){let t=await y.toRequest(e),n=new URL(t.url),r=n.origin,i=n.searchParams.get(`returnTo`),a=v(i,r);try{let t=await V(new URL(a??w.postLogoutRedirectUri,r),e);return g(e,await j(t,302,e))}catch(t){return g(e,await M(r,t,e))}}async function Y(e){if(typeof w.storage.deleteByLogoutToken!=`function`)return new Response(`Back-channel logout requires a storage with deleteByLogoutToken`,{status:501});let t=await y.toRequest(e),n;try{if((t.headers.get(`content-type`)??``).includes(`application/x-www-form-urlencoded`))n=(await t.formData()).get(`logout_token`);else return new Response(`Invalid content type: expected application/x-www-form-urlencoded`,{status:400})}catch{return new Response(`Failed to parse request body`,{status:400})}if(!n)return new Response(`Missing logout_token`,{status:400});let i=r();for(let[e,t]of O)t<=i&&O.delete(e);if(O.has(n))return new Response(`Invalid logout_token: token already used`,{status:400});O.set(n,i+120);let a,o;try{o=await f(w),a=await h({token:n,jwksUri:o.jwks_uri,options:w})}catch(e){return new Response(`Invalid logout_token: ${e.message}`,{status:400})}if(a.iss!==o.issuer)return new Response(`Invalid logout_token: invalid iss claim`,{status:400});if(Array.isArray(a.aud)?!a.aud.includes(w.clientId):a.aud!==w.clientId)return new Response(`Invalid logout_token: invalid aud claim`,{status:400});if(typeof a.iat!=`number`||Math.abs(i-a.iat)>120)return new Response(`Invalid logout_token: invalid or stale iat claim`,{status:400});if(!a.jti)return new Response(`Invalid logout_token: missing jti claim`,{status:400});if(a.nonce!==void 0)return new Response(`Invalid logout_token: nonce claim must not be present`,{status:400});if(!a.events||!(`http://schemas.openid.net/event/backchannel-logout`in a.events))return new Response(`Invalid logout_token: missing ${E} in events`,{status:400});if(!a.sid&&!a.sub)return new Response(`Invalid logout_token: must contain sid or sub claim`,{status:400});let s={};a.sid&&(s.sid=a.sid),a.sub&&(s.sub=a.sub);try{await w.storage.deleteByLogoutToken(s)}catch(e){return new Response(`Failed to delete session: ${e.message}`,{status:500})}return new Response(null,{status:200})}async function X(e){let t=await y.toRequest(e),n=new URL(t.url);return t.method===`GET`&&n.pathname===`${w.authUrlPrefix}/login`?H(e):t.method===`GET`&&n.pathname===`${w.authUrlPrefix}/register`?U(e):t.method===`GET`&&n.pathname===`${w.authUrlPrefix}/callback`?W(e):t.method===`GET`&&n.pathname===`${w.authUrlPrefix}/refresh`?G(e):t.method===`GET`&&n.pathname===`${w.authUrlPrefix}/revoke`?K(e):t.method===`GET`&&n.pathname===`${w.authUrlPrefix}/entry`?q(e):t.method===`GET`&&n.pathname===`${w.authUrlPrefix}/logout`?J(e):t.method===`POST`&&n.pathname===`${w.authUrlPrefix}/backchannel-logout`?Y(e):null}return A(),{get options(){return w},getSession:P,updateSession:F,refreshSession:L,revokeSession:R,getEntrySession:z,completeLogin:B,logout:V,handleLogin:H,handleRegister:U,handleCallback:W,handleRefresh:G,handleRevoke:K,handleEntry:q,handleLogout:J,handleBackChannelLogout:Y,handler:X}}export{O as BACKCHANNEL_LOGOUT_TOKEN_MAX_AGE_SECONDS,y as COOKIE_CHUNK_SIZE,C as COOKIE_CONTEXT,w as DISALLOWED_PROXY_HEADERS,b as RETURN_TO_COOKIE,k as createBaseServerSDK};
2
2
  //# sourceMappingURL=base.mjs.map