@civic/auth 0.0.1-beta.18 → 0.0.1-beta.19

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 (68) hide show
  1. package/dist/AuthProvider-Bj_Prt1x.d.ts +21 -0
  2. package/dist/AuthProvider-DUAoX4G9.d.mts +21 -0
  3. package/dist/{index-DTimUlkB.d.ts → UserProvider-CMLaYOUD.d.ts} +1 -2
  4. package/dist/{index-DvjkKpkk.d.mts → UserProvider-Cbm8MZkJ.d.mts} +1 -2
  5. package/dist/chunk-5UQQYXCX.js +1 -0
  6. package/dist/chunk-5UQQYXCX.js.map +1 -0
  7. package/dist/chunk-BFESCRFK.mjs +118 -0
  8. package/dist/chunk-BFESCRFK.mjs.map +1 -0
  9. package/dist/{chunk-G3P5TIO2.mjs → chunk-CBQ3HKRV.mjs} +123 -232
  10. package/dist/chunk-CBQ3HKRV.mjs.map +1 -0
  11. package/dist/chunk-CRTRMMJ7.js.map +1 -1
  12. package/dist/{chunk-SEKF2WZX.js → chunk-CZ3AVCKD.js} +16 -71
  13. package/dist/chunk-CZ3AVCKD.js.map +1 -0
  14. package/dist/chunk-DJFTZS4P.js +118 -0
  15. package/dist/chunk-DJFTZS4P.js.map +1 -0
  16. package/dist/chunk-HTTTZ2BP.mjs +223 -0
  17. package/dist/chunk-HTTTZ2BP.mjs.map +1 -0
  18. package/dist/{chunk-RF23Q4V6.js → chunk-O2SODTR3.js} +114 -223
  19. package/dist/chunk-O2SODTR3.js.map +1 -0
  20. package/dist/chunk-O6DPCPRH.js +223 -0
  21. package/dist/chunk-O6DPCPRH.js.map +1 -0
  22. package/dist/chunk-PMJAV4JJ.mjs +1 -0
  23. package/dist/chunk-PMJAV4JJ.mjs.map +1 -0
  24. package/dist/chunk-UADVRCHY.mjs +710 -0
  25. package/dist/chunk-UADVRCHY.mjs.map +1 -0
  26. package/dist/chunk-VJVRFKDH.js +710 -0
  27. package/dist/chunk-VJVRFKDH.js.map +1 -0
  28. package/dist/{chunk-5XL2ST72.mjs → chunk-X3FQBE22.mjs} +15 -70
  29. package/dist/chunk-X3FQBE22.mjs.map +1 -0
  30. package/dist/index.d.mts +2 -2
  31. package/dist/index.d.ts +2 -2
  32. package/dist/index.js +2 -1
  33. package/dist/index.js.map +1 -1
  34. package/dist/index.mjs +1 -0
  35. package/dist/nextjs/client.css +335 -0
  36. package/dist/nextjs/client.css.map +1 -0
  37. package/dist/nextjs/client.d.mts +12 -0
  38. package/dist/nextjs/client.d.ts +12 -0
  39. package/dist/nextjs/client.js +179 -0
  40. package/dist/nextjs/client.js.map +1 -0
  41. package/dist/nextjs/client.mjs +179 -0
  42. package/dist/nextjs/client.mjs.map +1 -0
  43. package/dist/nextjs.d.mts +35 -7
  44. package/dist/nextjs.d.ts +35 -7
  45. package/dist/nextjs.js +129 -42
  46. package/dist/nextjs.js.map +1 -1
  47. package/dist/nextjs.mjs +116 -29
  48. package/dist/nextjs.mjs.map +1 -1
  49. package/dist/react.d.mts +7 -31
  50. package/dist/react.d.ts +7 -31
  51. package/dist/react.js +15 -835
  52. package/dist/react.js.map +1 -1
  53. package/dist/react.mjs +47 -867
  54. package/dist/react.mjs.map +1 -1
  55. package/dist/server.d.mts +3 -24
  56. package/dist/server.d.ts +3 -24
  57. package/dist/server.js +4 -2
  58. package/dist/server.js.map +1 -1
  59. package/dist/server.mjs +4 -2
  60. package/dist/storage-B2eAQNdv.d.ts +25 -0
  61. package/dist/storage-BJPUpxhm.d.mts +25 -0
  62. package/dist/{types-b4c1koXj.d.mts → types-Bqm9OCZN.d.mts} +5 -2
  63. package/dist/{types-b4c1koXj.d.ts → types-Bqm9OCZN.d.ts} +5 -2
  64. package/package.json +24 -15
  65. package/dist/chunk-5XL2ST72.mjs.map +0 -1
  66. package/dist/chunk-G3P5TIO2.mjs.map +0 -1
  67. package/dist/chunk-RF23Q4V6.js.map +0 -1
  68. package/dist/chunk-SEKF2WZX.js.map +0 -1
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/shared/types.ts","../src/shared/util.ts","../src/lib/oauth.ts","../src/utils.ts","../src/lib/jwt.ts","../src/shared/UserSession.ts","../src/shared/session.ts","../src/constants.ts","../src/browser/storage.ts","../src/services/PKCE.ts","../src/services/AuthenticationService.ts","../src/services/types.ts","../src/lib/windowUtil.ts","../src/lib/postMessage.ts"],"sourcesContent":["export enum OAuthTokens {\n ID_TOKEN = \"id_token\",\n ACCESS_TOKEN = \"access_token\",\n REFRESH_TOKEN = \"refresh_token\",\n}\n\nexport enum CodeVerifier {\n COOKIE_NAME = \"code_verifier\",\n}\nexport enum UserStorage {\n USER = \"user\",\n}\nexport interface CookieConfig {\n secure?: boolean;\n sameSite?: \"strict\" | \"lax\" | \"none\";\n domain?: string;\n path?: string;\n maxAge?: number;\n httpOnly?: boolean;\n}\n\nexport type TokensCookieConfig = Record<\n OAuthTokens | CodeVerifier,\n CookieConfig\n>;\n","// Utility functions shared by auth server and client integrations\n// Typically these functions should be used inside AuthenticationInitiator and AuthenticationResolver implementations\n\nimport {\n AuthStorage,\n Endpoints,\n JWTPayload,\n OIDCTokenResponseBody,\n ParsedTokens,\n} from \"@/types.js\";\nimport { CodeVerifier, OAuthTokens } from \"./types\";\nimport { OAuth2Client } from \"oslo/oauth2\";\nimport { getIssuerVariations, getOauthEndpoints } from \"@/lib/oauth.js\";\nimport * as jose from \"jose\";\nimport { withoutUndefined } from \"@/utils.js\";\nimport { PKCEConsumer, PKCEProducer } from \"@/services/types.js\";\nimport { GenericUserSession } from \"./UserSession\";\n\n/**\n * Given a PKCE code verifier, derive the code challenge using SHA\n */\nexport async function deriveCodeChallenge(\n codeVerifier: string,\n method: \"Plain\" | \"S256\" = \"S256\",\n): Promise<string> {\n if (method === \"Plain\") {\n console.warn(\"Using insecure plain code challenge method\");\n return codeVerifier;\n }\n\n const encoder = new TextEncoder();\n const data = encoder.encode(codeVerifier);\n const digest = await crypto.subtle.digest(\"SHA-256\", data);\n return btoa(String.fromCharCode(...new Uint8Array(digest)))\n .replace(/\\+/g, \"-\")\n .replace(/\\//g, \"_\")\n .replace(/=+$/, \"\");\n}\n\nexport async function getEndpointsWithOverrides(\n oauthServer: string,\n endpointOverrides: Partial<Endpoints> = {},\n) {\n const endpoints = await getOauthEndpoints(oauthServer);\n return {\n ...endpoints,\n ...endpointOverrides,\n };\n}\n\nexport async function generateOauthLoginUrl(config: {\n clientId: string;\n scopes: string[];\n state: string;\n redirectUrl: string;\n oauthServer: string;\n nonce?: string;\n endpointOverrides?: Partial<Endpoints>;\n // used to get the PKCE challenge\n pkceConsumer: PKCEConsumer;\n}): Promise<URL> {\n const endpoints = await getEndpointsWithOverrides(\n config.oauthServer,\n config.endpointOverrides,\n );\n const oauth2Client = buildOauth2Client(\n config.clientId,\n config.redirectUrl,\n endpoints,\n );\n const challenge = await config.pkceConsumer.getCodeChallenge();\n const oAuthUrl = await oauth2Client.createAuthorizationURL({\n state: config.state,\n scopes: config.scopes,\n });\n // The OAuth2 client supports PKCE, but does not allow passing in a code challenge from some other source\n // It only allows passing in a code verifier which it then hashes itself.\n oAuthUrl.searchParams.append(\"code_challenge\", challenge);\n oAuthUrl.searchParams.append(\"code_challenge_method\", \"S256\");\n if (config.nonce) {\n // nonce isn't supported by oslo, so we add it manually\n oAuthUrl.searchParams.append(\"nonce\", config.nonce);\n }\n // Required by the auth server for offline_access scope\n oAuthUrl.searchParams.append(\"prompt\", \"consent\");\n\n console.log(\"Generated OAuth URL\", oAuthUrl.toString());\n return oAuthUrl;\n}\n\nexport async function generateOauthLogoutUrl(config: {\n clientId: string;\n scopes: string[];\n oauthServer: string;\n endpointOverrides?: Partial<Endpoints>;\n // used to get the PKCE challenge\n pkceConsumer: PKCEConsumer;\n}): Promise<URL> {\n // TODO\n return new URL(\"http://localhost\");\n}\n\nexport function buildOauth2Client(\n clientId: string,\n redirectUri: string,\n endpoints: Endpoints,\n): OAuth2Client {\n return new OAuth2Client(clientId, endpoints.auth, endpoints.token, {\n redirectURI: redirectUri,\n });\n}\n\nexport async function exchangeTokens(\n code: string,\n state: string,\n pkceProducer: PKCEProducer,\n oauth2Client: OAuth2Client,\n oauthServer: string,\n endpoints: Endpoints,\n) {\n const codeVerifier = await pkceProducer.getCodeVerifier();\n if (!codeVerifier) throw new Error(\"Code verifier not found in state\");\n\n const tokens =\n await oauth2Client.validateAuthorizationCode<OIDCTokenResponseBody>(code, {\n codeVerifier,\n });\n\n // Validate relevant tokens\n try {\n await validateOauth2Tokens(tokens, endpoints, oauth2Client, oauthServer);\n } catch (error) {\n console.error(\"tokenExchange error\", { error, tokens });\n throw new Error(\n `OIDC tokens validation failed: ${(error as Error).message}`,\n );\n }\n\n return tokens;\n}\n\nexport function storeTokens(\n storage: AuthStorage,\n tokens: OIDCTokenResponseBody,\n) {\n // store tokens in storage ( TODO we should probably store them against the state to allow multiple logins )\n storage.set(OAuthTokens.ID_TOKEN, tokens.id_token);\n storage.set(OAuthTokens.ACCESS_TOKEN, tokens.access_token);\n if (tokens.refresh_token)\n storage.set(OAuthTokens.REFRESH_TOKEN, tokens.refresh_token);\n}\n\nexport function clearTokens(storage: AuthStorage) {\n Object.values(OAuthTokens).forEach((cookie) => {\n storage.set(cookie, \"\");\n });\n Object.values(CodeVerifier.COOKIE_NAME).forEach((cookie) => {\n storage.set(cookie, \"\");\n });\n}\nexport function clearUser(storage: AuthStorage) {\n const userSession = new GenericUserSession(storage);\n userSession.set(null);\n}\n\nexport function retrieveTokens(\n storage: AuthStorage,\n): OIDCTokenResponseBody | null {\n const idToken = storage.get(OAuthTokens.ID_TOKEN);\n const accessToken = storage.get(OAuthTokens.ACCESS_TOKEN);\n const refreshToken = storage.get(OAuthTokens.REFRESH_TOKEN);\n\n if (!idToken || !accessToken) return null;\n\n return {\n id_token: idToken,\n access_token: accessToken,\n refresh_token: refreshToken ?? undefined,\n };\n}\n\nexport async function validateOauth2Tokens(\n tokens: OIDCTokenResponseBody,\n endpoints: Endpoints,\n oauth2Client: OAuth2Client,\n issuer: string,\n): Promise<ParsedTokens> {\n const JWKS = jose.createRemoteJWKSet(new URL(endpoints.jwks));\n\n // validate the ID token\n const idTokenResponse = await jose.jwtVerify<JWTPayload>(\n tokens.id_token,\n JWKS,\n {\n issuer: getIssuerVariations(issuer),\n audience: oauth2Client.clientId,\n },\n );\n\n // validate the access token\n const accessTokenResponse = await jose.jwtVerify<JWTPayload>(\n tokens.access_token,\n JWKS,\n {\n issuer: getIssuerVariations(issuer),\n },\n );\n\n return withoutUndefined({\n id_token: idTokenResponse.payload,\n access_token: accessTokenResponse.payload,\n refresh_token: tokens.refresh_token,\n });\n}\n","import { DisplayMode, Endpoints, OpenIdConfiguration } from \"@/types\";\nimport { v4 as uuid } from \"uuid\";\n\nconst getIssuerVariations = (issuer: string): string[] => {\n const issuerWithoutSlash = issuer.endsWith(\"/\")\n ? issuer.slice(0, issuer.length - 1)\n : issuer;\n\n const issuerWithSlash = `${issuerWithoutSlash}/`;\n\n return [issuerWithoutSlash, issuerWithSlash];\n};\n\nconst addSlashIfNeeded = (url: string): string =>\n url.endsWith(\"/\") ? url : `${url}/`;\n\nconst getOauthEndpoints = async (oauthServer: string): Promise<Endpoints> => {\n const openIdConfigResponse = await fetch(\n `${addSlashIfNeeded(oauthServer)}.well-known/openid-configuration`,\n );\n const openIdConfig =\n (await openIdConfigResponse.json()) as OpenIdConfiguration;\n return {\n jwks: openIdConfig.jwks_uri,\n auth: openIdConfig.authorization_endpoint,\n token: openIdConfig.token_endpoint,\n userinfo: openIdConfig.userinfo_endpoint,\n };\n};\n\n/**\n * creates a state string for the OAuth2 flow, encoding the display mode too for future use\n * @param {DisplayMode} displayMode\n * @returns {string}\n */\nconst generateState = (\n displayMode: DisplayMode,\n serverTokenExchange?: boolean,\n): string => {\n const jsonString = JSON.stringify({\n uuid: uuid(),\n displayMode,\n ...(serverTokenExchange ? { serverTokenExchange } : {}),\n });\n return btoa(jsonString);\n};\n\n/**\n * parses the state string from the OAuth2 flow, decoding the display mode too\n * @param state\n * @param sessionDisplayMode\n * @returns { uuid: string, displayMode: DisplayMode }\n */\nconst displayModeFromState = (\n state: string,\n sessionDisplayMode: DisplayMode | undefined,\n): DisplayMode | undefined => {\n try {\n const jsonString = atob(state);\n return JSON.parse(jsonString).displayMode;\n } catch {\n console.error(\"Failed to parse displayMode from state:\", state);\n return sessionDisplayMode;\n }\n};\n\nconst serverTokenExchangeFromState = (state: string): boolean | undefined => {\n try {\n const jsonString = atob(state);\n return JSON.parse(jsonString).serverTokenExchange;\n } catch {\n console.error(\"Failed to parse serverTokenExchange from state:\", state);\n return undefined;\n }\n};\n\nexport {\n serverTokenExchangeFromState,\n getIssuerVariations,\n getOauthEndpoints,\n displayModeFromState,\n generateState,\n};\n","import { clsx, type ClassValue } from \"clsx\";\nimport { twMerge } from \"tailwind-merge\";\n\n/**\n * Checks if a popup window is blocked by the browser.\n *\n * This function attempts to open a small popup window and then checks if it was successfully created.\n * If the popup is blocked by the browser, the function returns `true`. Otherwise, it returns `false`.\n *\n * @returns {boolean} - `true` if the popup is blocked, `false` otherwise.\n */\nconst isPopupBlocked = (): boolean => {\n // First we try to open a small popup window. It either returns a window object or null.\n const popup = window.open(\"\", \"\", \"width=1,height=1\");\n\n // If window.open() returns null, popup is definitely blocked\n if (!popup) {\n return true;\n }\n\n try {\n // Try to access a property of the popup to check if it's usable\n if (typeof popup.closed === \"undefined\") {\n throw new Error(\"Popup is blocked\");\n }\n } catch {\n // Accessing the popup's properties throws an error if the popup is blocked\n return true;\n }\n\n // Close the popup immediately if it was opened\n popup.close();\n return false;\n};\n\nconst cn = (...inputs: ClassValue[]) => {\n return twMerge(clsx(inputs));\n};\n\n// This type narrows T as far as it can by:\n// - removing all keys where the value is `undefined`\n// - making keys that are not undefined required\n// So, for example: given { a: string | undefined, b: string | undefined },\n// if you pass in { a: \"foo\" }, it returns an object of type: { a: string }\ntype WithoutUndefined<T> = {\n [K in keyof T as undefined extends T[K] ? never : K]: T[K];\n};\nexport const withoutUndefined = <T extends { [K in keyof T]: unknown }>(\n obj: T,\n): WithoutUndefined<T> => {\n const result = {} as WithoutUndefined<T>;\n\n for (const key in obj) {\n if (obj[key] !== undefined) {\n // TypeScript needs assurance that key is a valid key in WithoutUndefined<T>\n // We use type assertion here\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n (result as any)[key] = obj[key];\n }\n }\n\n return result;\n};\n\nexport { cn, isPopupBlocked };\n","import { ForwardedTokens, ForwardedTokensJWT } from \"@/types.js\";\n\nexport const convertForwardedTokenFormat = (\n inputTokens: ForwardedTokensJWT,\n): ForwardedTokens =>\n Object.fromEntries(\n Object.entries(inputTokens).map(([source, tokens]) => [\n source,\n {\n idToken: tokens?.id_token,\n accessToken: tokens?.access_token,\n refreshToken: tokens?.refresh_token,\n },\n ]),\n );\n","import { AuthStorage, ForwardedTokensJWT, User } from \"@/types\";\nimport { UserStorage } from \"./types\";\nimport { convertForwardedTokenFormat } from \"@/lib/jwt\";\n\nexport interface UserSession {\n get(): User | null;\n set(user: User): void;\n}\n\nexport class GenericUserSession implements UserSession {\n constructor(readonly storage: AuthStorage) {}\n\n get(): User | null {\n const user = this.storage.get(UserStorage.USER);\n return user ? JSON.parse(user) : null;\n }\n\n set(user: User | null): void {\n const forwardedTokens = user?.forwardedTokens\n ? convertForwardedTokenFormat(user?.forwardedTokens as ForwardedTokensJWT)\n : null;\n const value = user ? JSON.stringify({ ...user, forwardedTokens }) : \"\";\n this.storage.set(UserStorage.USER, value);\n }\n}\n","import { retrieveTokens } from \"@/shared/util.js\";\nimport { parseJWT } from \"oslo/jwt\";\nimport { AuthStorage, User } from \"@/types.js\";\n\nexport async function getUser(storage: AuthStorage): Promise<User | null> {\n const tokens = retrieveTokens(storage);\n if (!tokens) return null;\n\n // Assumes all information is in the ID token\n return (parseJWT(tokens.id_token)?.payload as User) ?? null;\n}\n","const DEFAULT_SCOPES = [\n \"openid\",\n \"profile\",\n \"email\",\n \"forwardedTokens\",\n \"offline_access\",\n];\nconst IFRAME_ID = \"civic-auth-iframe\";\n\nconst AUTH_SERVER = \"https://auth-dev.civic.com/oauth\";\n\nconst DEFAULT_OAUTH_GET_PARAMS = [\"code\", \"state\", \"iss\"];\n\n// The server's callback handler renders this text if it needs the front-end to make an additional token exchange call,\n// for the iframe case where cookies are not sent along with the initial redirect.\nconst TOKEN_EXCHANGE_TRIGGER_TEXT = \"sameDomainCodeExchangeRequired\";\n\nconst TOKEN_EXCHANGE_SUCCESS_TEXT = \"serverSideTokenExchangeSuccess\";\n\nconst DEFAULT_DISPLAY_MODE = \"iframe\";\nexport {\n DEFAULT_SCOPES,\n DEFAULT_OAUTH_GET_PARAMS,\n DEFAULT_DISPLAY_MODE,\n IFRAME_ID,\n AUTH_SERVER,\n TOKEN_EXCHANGE_TRIGGER_TEXT,\n TOKEN_EXCHANGE_SUCCESS_TEXT,\n};\n","import { AuthStorage } from \"@/types\";\n\nexport class LocalStorageAdapter implements AuthStorage {\n get(key: string): string {\n return localStorage.getItem(key) || \"\";\n }\n\n set(key: string, value: string): void {\n localStorage.setItem(key, value);\n }\n}\n","import { deriveCodeChallenge } from \"@/shared/util.js\";\nimport { generateCodeVerifier } from \"oslo/oauth2\";\nimport { LocalStorageAdapter } from \"@/browser/storage.js\";\nimport { PKCEConsumer, PKCEProducer } from \"@/services/types.ts\";\nimport { AuthStorage } from \"@/types\";\nimport { CodeVerifier } from \"@/shared/types\";\n\n/** A PKCE consumer that retrieves the challenge from a server endpoint */\nexport class ConfidentialClientPKCEConsumer implements PKCEConsumer {\n constructor(private pkceChallengeEndpoint: string) {}\n async getCodeChallenge(): Promise<string> {\n const response = await fetch(this.pkceChallengeEndpoint);\n const data = (await response.json()) as { challenge: string };\n return data.challenge;\n }\n}\n\n/** A PKCE Producer that can generate and store a code verifier, but is agnostic as to the storage location */\nexport class GenericPublicClientPKCEProducer implements PKCEProducer {\n constructor(private storage: AuthStorage) {}\n\n // if there is already a verifier, return it,\n // If not, create a new one and store it\n async getCodeChallenge(): Promise<string> {\n // let verifier = await this.getCodeVerifier();\n // if (!verifier) {\n const verifier = generateCodeVerifier();\n this.storage.set(CodeVerifier.COOKIE_NAME, verifier);\n // }\n return deriveCodeChallenge(verifier);\n }\n // if there is already a verifier, return it,\n async getCodeVerifier(): Promise<string | null> {\n return this.storage.get(CodeVerifier.COOKIE_NAME);\n }\n}\n\n/** A PKCE Producer that is expected to run on a browser, and does not need a backend */\nexport class BrowserPublicClientPKCEProducer extends GenericPublicClientPKCEProducer {\n constructor() {\n super(new LocalStorageAdapter());\n }\n}\n","// Proposals for revised versions of the SessionService AKA AuthSessionService\n\nimport {\n DisplayMode,\n Endpoints,\n LoginPostMessage,\n OIDCTokenResponseBody,\n SessionData,\n} from \"@/types.js\";\nimport { BrowserPublicClientPKCEProducer } from \"@/services/PKCE.js\";\nimport {\n clearTokens,\n clearUser,\n exchangeTokens,\n generateOauthLoginUrl,\n generateOauthLogoutUrl,\n getEndpointsWithOverrides,\n retrieveTokens,\n storeTokens,\n validateOauth2Tokens,\n} from \"@/shared/util.js\";\nimport { displayModeFromState, generateState } from \"@/lib/oauth.js\";\nimport { OAuth2Client } from \"oslo/oauth2\";\nimport { LocalStorageAdapter } from \"@/browser/storage.js\";\nimport {\n AuthenticationInitiator,\n AuthenticationResolver,\n PKCEConsumer,\n PopupError,\n} from \"@/services/types.js\";\nimport { removeParamsWithoutReload } from \"@/lib/windowUtil\";\nimport { DEFAULT_OAUTH_GET_PARAMS } from \"@/constants\";\nimport { validateLoginAppPostMessage } from \"@/lib/postMessage\";\n\n/**\n * An authentication initiator that works on a browser. Since this is just triggering\n * login and logout, session data is not stored here.\n * An associated AuthenticationResolver would be needed to get the session data.\n * Storage is needed for the code verifier, this is the domain of the PKCEConsumer\n * The storage used by the PKCEConsumer should be available to the AuthenticationResolver.\n *\n * Example usage:\n *\n * 1) Client-only SPA -eg a react app with no server:\n * new BrowserAuthenticationInitiator({\n * pkceConsumer: new BrowserPublicClientPKCEProducer(), // generate and retrieve the challenge client-side\n * ... other config\n * })\n *\n * 2) Client-side of a client/server app - eg a react app with a backend:\n * new BrowserAuthenticationInitiator({\n * pkceConsumer: new ConfidentialClientPKCEConsumer(\"https://myserver.com/pkce\"), // get the challenge from the server\n * ... other config\n * })\n */\nexport class BrowserAuthenticationInitiator implements AuthenticationInitiator {\n private postMessageHandler: null | ((event: MessageEvent) => void) = null;\n\n protected config: {\n clientId: string;\n redirectUrl: string;\n state: string;\n scopes: string[];\n // determines whether to trigger the login/logout in an iframe, a new browser window, or redirect the current one.\n displayMode: DisplayMode;\n oauthServer: string;\n // the endpoints to use for the login (if not obtained from the auth server\n endpointOverrides?: Partial<Endpoints>;\n // used to get the PKCE challenge\n pkceConsumer: PKCEConsumer;\n // the nonce to use for the login\n nonce?: string;\n };\n\n constructor(config: typeof this.config) {\n this.config = config;\n console.log(\"BrowserAuthenticationInitiator constructor\", this.config);\n }\n\n async handleLoginAppPopupFailed(redirectUrl: string) {\n console.warn(\n \"Login app popup failed open a popup, using redirect mode instead...\",\n redirectUrl,\n );\n window.location.href = redirectUrl;\n }\n\n // Use the config (Client ID, scopes OAuth Server, Endpoints, PKCEConsumer) to generate a new login url\n // and then use the display mode to decide how to send the user there\n async signIn(iframeRef: HTMLIFrameElement | null): Promise<URL> {\n const url = await generateOauthLoginUrl(this.config);\n\n this.postMessageHandler = (event: MessageEvent) => {\n const thisURL = new URL(window.location.href);\n if (\n event.origin.endsWith(\"civic.com\") ||\n thisURL.hostname === \"localhost\"\n ) {\n if (!validateLoginAppPostMessage(event.data, this.config.clientId)) {\n console.log(\"Received invalid message from login app\", event.data);\n return;\n }\n const loginMessage = event.data as LoginPostMessage;\n console.log(\"Received message from login app\", event.data);\n this.handleLoginAppPopupFailed(loginMessage.data.url);\n }\n };\n window.addEventListener(\"message\", this.postMessageHandler);\n if (this.config.displayMode === \"iframe\") {\n if (!iframeRef)\n throw new Error(\"iframeRef is required for displayMode 'iframe'\");\n iframeRef.setAttribute(\"src\", url.toString());\n }\n if (this.config.displayMode === \"redirect\") {\n window.location.href = url.toString();\n }\n if (this.config.displayMode === \"new_tab\") {\n try {\n const popupWindow = window.open(url.toString(), \"_blank\");\n console.log(\"signIn\", popupWindow);\n if (!popupWindow) {\n throw new PopupError(\"Failed to open popup window\");\n }\n } catch (error) {\n console.error(\"popupWindow\", error);\n throw new PopupError(\n \"window.open has thrown: Failed to open popup window\",\n );\n }\n }\n return url;\n }\n\n async signOut(): Promise<URL> {\n const localStorage = new LocalStorageAdapter();\n clearTokens(localStorage);\n clearUser(localStorage);\n // TODO open the iframe or new tab etc: the logout URL is not currently\n // supported by on the oauth, so just clear state until then\n const url = await generateOauthLogoutUrl(this.config);\n return url;\n }\n\n cleanup() {\n if (this.postMessageHandler) {\n window.removeEventListener(\"message\", this.postMessageHandler);\n }\n }\n}\n\n/** A general-purpose authentication initiator, that just generates urls, but lets\n * the caller decide how to use them. This is useful for server-side applications\n * that may serve this URL to their front-ends or just call them directly\n */\nexport class GenericAuthenticationInitiator implements AuthenticationInitiator {\n protected config: {\n clientId: string;\n redirectUrl: string;\n state: string;\n scopes: string[];\n oauthServer: string;\n nonce?: string;\n // the endpoints to use for the login (if not obtained from the auth server)\n endpointOverrides?: Partial<Endpoints>;\n // used to get the PKCE challenge\n pkceConsumer: PKCEConsumer;\n };\n\n constructor(config: typeof this.config) {\n this.config = config;\n console.log(\"GenericAuthenticationInitiator constructor\", {\n config,\n });\n }\n\n // Use the config (Client ID, scopes OAuth Server, Endpoints, PKCEConsumer) to generate a new login url\n // and simply return the url\n async signIn(): Promise<URL> {\n return generateOauthLoginUrl(this.config);\n }\n\n async signOut(): Promise<URL> {\n return generateOauthLogoutUrl(this.config);\n }\n}\n\ntype BrowserAuthenticationConfig = {\n clientId: string;\n redirectUrl: string;\n scopes: string[];\n oauthServer: string;\n endpointOverrides?: Partial<Endpoints>;\n displayMode: DisplayMode;\n};\n\n/**\n * An authentication resolver that can run on the browser (i.e. a public client)\n * It uses PKCE for security. PKCE and Session data are stored in local storage\n */\nexport class BrowserAuthenticationService extends BrowserAuthenticationInitiator {\n private oauth2client: OAuth2Client | undefined;\n private endpoints: Endpoints | undefined;\n\n // TODO WIP - perhaps we want to keep resolver and initiator separate here\n constructor(\n config: BrowserAuthenticationConfig,\n // Since we are running fully on the client, we produce as well as consume the PKCE challenge\n protected pkceProducer = new BrowserPublicClientPKCEProducer(),\n ) {\n console.log(\"BrowserAuthenticationService constructor\", {\n config,\n });\n super({\n ...config,\n state: generateState(config.displayMode),\n // Store and retrieve the PKCE challenge in local storage\n pkceConsumer: pkceProducer,\n });\n }\n\n // TODO too much code duplication here between the browser and the server variant.\n // Suggestion for refactor: Standardise the config for AuthenticationResolvers and create a one-shot\n // function for generating an oauth2client from it\n async init(): Promise<this> {\n // resolve oauth config\n this.endpoints = await getEndpointsWithOverrides(\n this.config.oauthServer,\n this.config.endpointOverrides,\n );\n this.oauth2client = new OAuth2Client(\n this.config.clientId,\n this.endpoints.auth,\n this.endpoints.token,\n {\n redirectURI: this.config.redirectUrl,\n },\n );\n\n return this;\n }\n\n // Two responsibilities:\n // 1. resolve the auth code to get the tokens (should use library code)\n // 2. store the tokens in local storage\n async tokenExchange(\n code: string,\n state: string,\n ): Promise<OIDCTokenResponseBody> {\n if (!this.oauth2client) await this.init();\n const codeVerifier = await this.pkceProducer.getCodeVerifier();\n if (!codeVerifier) throw new Error(\"Code verifier not found in storage\");\n\n // exchange auth code for tokens\n const tokens = await exchangeTokens(\n code,\n state,\n this.pkceProducer,\n this.oauth2client!, // clean up types here to avoid the ! operator\n this.config.oauthServer,\n this.endpoints!, // clean up types here to avoid the ! operator\n );\n\n storeTokens(new LocalStorageAdapter(), tokens);\n\n // cleanup the browser window if needed\n const parsedDisplayMode = displayModeFromState(\n state,\n this.config.displayMode,\n );\n\n if (parsedDisplayMode === \"new_tab\") {\n // Close the popup window\n window.close();\n }\n // these are the default oAuth params that get added to the URL in redirect which we want to remove if present\n removeParamsWithoutReload(DEFAULT_OAUTH_GET_PARAMS);\n return tokens;\n }\n\n // Get the session data from local storage\n async getSessionData(): Promise<SessionData | null> {\n const storageData = retrieveTokens(new LocalStorageAdapter());\n\n if (!storageData) return null;\n\n return {\n authenticated: !!storageData.id_token,\n idToken: storageData.id_token,\n accessToken: storageData.access_token,\n refreshToken: storageData.refresh_token,\n };\n }\n\n async validateExistingSession(): Promise<SessionData> {\n try {\n const sessionData = await this.getSessionData();\n if (!sessionData?.idToken || !sessionData.accessToken) {\n const unAuthenticatedSession = { ...sessionData, authenticated: false };\n clearTokens(new LocalStorageAdapter());\n return unAuthenticatedSession;\n }\n if (!this.endpoints || !this.oauth2client) await this.init();\n\n // this function will throw if any of the tokens are invalid\n await validateOauth2Tokens(\n {\n access_token: sessionData.accessToken,\n id_token: sessionData.idToken,\n refresh_token: sessionData.refreshToken,\n },\n this.endpoints!,\n this.oauth2client!,\n this.config.oauthServer,\n );\n return sessionData;\n } catch (error) {\n console.warn(\"Failed to validate existing tokens\", error);\n const unAuthenticatedSession = {\n authenticated: false,\n };\n clearTokens(new LocalStorageAdapter());\n return unAuthenticatedSession;\n }\n }\n\n static async build(\n config: BrowserAuthenticationConfig,\n ): Promise<AuthenticationResolver> {\n const resolver = new BrowserAuthenticationService(config);\n await resolver.init();\n\n return resolver;\n }\n}\n","import { OIDCTokenResponseBody, SessionData } from \"@/types.js\";\n\n// A PKCEConsumer can get a code challenge to use in the login process\n// A PKCEProducer can also generate and store verifiers. The producer must also be a consumer in order to get the challenge from an existing flow\n// Examples:\n// - Client-only SPA: The SPA generates the code challenge and verifier, stores the verifier in state and returns the code challenge\n// Note - The SPA should use PKCEProducer instead to do both\n// - Client-side of a client/server app: The client calls the backend to get the challenge.\n// - Server-side: The server should generate a new stored verifier and derive the challenge from it.\nexport interface PKCEConsumer {\n // Retrieve a new PKCE challenge\n getCodeChallenge(): Promise<string>;\n}\n\n// All producers are consumers, because the producer can get its own challenge\nexport interface PKCEProducer extends PKCEConsumer {\n // Retrieve the PKCE challenge from the session if one exists\n getCodeVerifier(): Promise<string | null>;\n}\n\n// A service that can initiate requests to login or log out\nexport interface AuthenticationInitiator {\n // trigger a new login\n signIn(iframeRef: HTMLIFrameElement | null): Promise<URL>;\n\n // trigger a new logout\n signOut(): Promise<URL>;\n}\n\n// A service that can resolve an authentication request according to the OAuth Auth Code grant types\nexport interface AuthenticationResolver {\n // Given an auth code, get the tokens from the auth server and store them. works in PKCE and non-PKCE environments\n // Note, if we choose later to implement other grants, this method would move into a subinterface specifically\n // for the authorization code grant type.\n // The return type is just for convenience and can be ignored, as the same data would be provided by getSessionData\n tokenExchange(code: string, state: string): Promise<OIDCTokenResponseBody>;\n\n // If the tokens have already been retrieved, return them\n getSessionData(): Promise<SessionData | null>;\n\n // If an existing session is found, validate it and return the session data\n validateExistingSession(): Promise<SessionData>;\n}\n\nexport interface AuthenticationRefresher {\n refreshTokens: () => Promise<OIDCTokenResponseBody>;\n}\n\nexport class PopupError extends Error {\n constructor(message: string) {\n super(message);\n Object.setPrototypeOf(this, PopupError.prototype);\n }\n}\n","const isWindowInIframe = (window: Window): boolean => {\n if (typeof window !== \"undefined\") {\n // use the window width to determine if we're in an iframe or not\n try {\n if (window?.frameElement?.id === \"civic-auth-iframe\") {\n return true;\n }\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n } catch (_e) {\n // If we get an error, we're not in an iframe\n return false;\n }\n }\n return false;\n};\n\nconst removeParamsWithoutReload = (paramsToRemove: string[]) => {\n const url = new URL(window.location.href);\n paramsToRemove.forEach((param: string) => {\n url.searchParams.delete(param);\n });\n try {\n window.history.replaceState({}, \"\", url);\n } catch (error) {\n console.warn(\"window.history.replaceState failed\", error);\n }\n};\n\nexport { isWindowInIframe, removeParamsWithoutReload };\n","import { LoginPostMessage } from \"@/types\";\n\nconst validateLoginAppPostMessage = (\n event: LoginPostMessage,\n clientId: string,\n): boolean => {\n const caseEvent = event as LoginPostMessage;\n console.log(\"caseEvent\", caseEvent);\n if (\n !caseEvent.clientId ||\n !caseEvent.data.url ||\n !caseEvent.source ||\n !caseEvent.type ||\n caseEvent.clientId !== clientId ||\n caseEvent.source !== \"civicloginApp\"\n ) {\n return false;\n }\n return true;\n};\n\nexport { validateLoginAppPostMessage };\n"],"mappings":"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","names":["OAuthTokens","OAuth2Client","window","localStorage","OAuth2Client"]}
@@ -1 +1 @@
1
- {"version":3,"sources":["/Users/lucas/dev/civic/civic-auth/packages/civic-auth-client/dist/chunk-CRTRMMJ7.js"],"names":[],"mappings":"AAAA,6EAAI,UAAU,EAAE,MAAM,CAAC,cAAc;AACrC,IAAI,WAAW,EAAE,MAAM,CAAC,gBAAgB;AACxC,IAAI,kBAAkB,EAAE,MAAM,CAAC,yBAAyB;AACxD,IAAI,oBAAoB,EAAE,MAAM,CAAC,qBAAqB;AACtD,IAAI,aAAa,EAAE,MAAM,CAAC,SAAS,CAAC,cAAc;AAClD,IAAI,aAAa,EAAE,MAAM,CAAC,SAAS,CAAC,oBAAoB;AACxD,IAAI,gBAAgB,EAAE,CAAC,GAAG,EAAE,GAAG,EAAE,KAAK,EAAE,GAAG,IAAI,GAAG,IAAI,EAAE,SAAS,CAAC,GAAG,EAAE,GAAG,EAAE,EAAE,UAAU,EAAE,IAAI,EAAE,YAAY,EAAE,IAAI,EAAE,QAAQ,EAAE,IAAI,EAAE,MAAM,CAAC,EAAE,EAAE,GAAG,CAAC,GAAG,EAAE,EAAE,KAAK;AAC/J,IAAI,eAAe,EAAE,CAAC,CAAC,EAAE,CAAC,EAAE,GAAG;AAC/B,EAAE,IAAI,CAAC,IAAI,KAAK,GAAG,EAAE,GAAG,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC;AAChC,IAAI,GAAG,CAAC,YAAY,CAAC,IAAI,CAAC,CAAC,EAAE,IAAI,CAAC;AAClC,MAAM,eAAe,CAAC,CAAC,EAAE,IAAI,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC;AACvC,EAAE,GAAG,CAAC,mBAAmB;AACzB,IAAI,IAAI,CAAC,IAAI,KAAK,GAAG,mBAAmB,CAAC,CAAC,CAAC,EAAE;AAC7C,MAAM,GAAG,CAAC,YAAY,CAAC,IAAI,CAAC,CAAC,EAAE,IAAI,CAAC;AACpC,QAAQ,eAAe,CAAC,CAAC,EAAE,IAAI,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC;AACzC,IAAI;AACJ,EAAE,OAAO,CAAC;AACV,CAAC;AACD,IAAI,cAAc,EAAE,CAAC,CAAC,EAAE,CAAC,EAAE,GAAG,UAAU,CAAC,CAAC,EAAE,iBAAiB,CAAC,CAAC,CAAC,CAAC;AACjE,IAAI,UAAU,EAAE,CAAC,MAAM,EAAE,OAAO,EAAE,GAAG;AACrC,EAAE,IAAI,OAAO,EAAE,CAAC,CAAC;AACjB,EAAE,IAAI,CAAC,IAAI,KAAK,GAAG,MAAM;AACzB,IAAI,GAAG,CAAC,YAAY,CAAC,IAAI,CAAC,MAAM,EAAE,IAAI,EAAE,GAAG,OAAO,CAAC,OAAO,CAAC,IAAI,EAAE,EAAE,CAAC;AACpE,MAAM,MAAM,CAAC,IAAI,EAAE,EAAE,MAAM,CAAC,IAAI,CAAC;AACjC,EAAE,GAAG,CAAC,OAAO,GAAG,KAAK,GAAG,mBAAmB;AAC3C,IAAI,IAAI,CAAC,IAAI,KAAK,GAAG,mBAAmB,CAAC,MAAM,CAAC,EAAE;AAClD,MAAM,GAAG,CAAC,OAAO,CAAC,OAAO,CAAC,IAAI,EAAE,EAAE,EAAE,GAAG,YAAY,CAAC,IAAI,CAAC,MAAM,EAAE,IAAI,CAAC;AACtE,QAAQ,MAAM,CAAC,IAAI,EAAE,EAAE,MAAM,CAAC,IAAI,CAAC;AACnC,IAAI;AACJ,EAAE,OAAO,MAAM;AACf,CAAC;AACD,IAAI,QAAQ,EAAE,CAAC,MAAM,EAAE,WAAW,EAAE,SAAS,EAAE,GAAG;AAClD,EAAE,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,MAAM,EAAE,GAAG;AAC1C,IAAI,IAAI,UAAU,EAAE,CAAC,KAAK,EAAE,GAAG;AAC/B,MAAM,IAAI;AACV,QAAQ,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;AACnC,MAAM,EAAE,MAAM,CAAC,CAAC,EAAE;AAClB,QAAQ,MAAM,CAAC,CAAC,CAAC;AACjB,MAAM;AACN,IAAI,CAAC;AACL,IAAI,IAAI,SAAS,EAAE,CAAC,KAAK,EAAE,GAAG;AAC9B,MAAM,IAAI;AACV,QAAQ,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;AACpC,MAAM,EAAE,MAAM,CAAC,CAAC,EAAE;AAClB,QAAQ,MAAM,CAAC,CAAC,CAAC;AACjB,MAAM;AACN,IAAI,CAAC;AACL,IAAI,IAAI,KAAK,EAAE,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC,KAAK,EAAE,OAAO,CAAC,CAAC,CAAC,KAAK,EAAE,EAAE,OAAO,CAAC,OAAO,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,SAAS,EAAE,QAAQ,CAAC;AACpG,IAAI,IAAI,CAAC,CAAC,UAAU,EAAE,SAAS,CAAC,KAAK,CAAC,MAAM,EAAE,WAAW,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC;AACnE,EAAE,CAAC,CAAC;AACJ,CAAC;AACD;AACA;AACE;AACA;AACA;AACA;AACF,yIAAC","file":"/Users/lucas/dev/civic/civic-auth/packages/civic-auth-client/dist/chunk-CRTRMMJ7.js"}
1
+ {"version":3,"sources":["/Users/kevincolgan/code/civic-auth/packages/civic-auth-client/dist/chunk-CRTRMMJ7.js"],"names":[],"mappings":"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","file":"/Users/kevincolgan/code/civic-auth/packages/civic-auth-client/dist/chunk-CRTRMMJ7.js"}
@@ -1,10 +1,6 @@
1
1
  "use strict";Object.defineProperty(exports, "__esModule", {value: true}); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
2
2
 
3
-
4
-
5
-
6
- var _chunkRF23Q4V6js = require('./chunk-RF23Q4V6.js');
7
-
3
+ var _chunkO2SODTR3js = require('./chunk-O2SODTR3.js');
8
4
 
9
5
 
10
6
 
@@ -62,6 +58,8 @@ var loggers = {
62
58
 
63
59
  // src/nextjs/config.ts
64
60
  var logger = loggers.nextjs.handlers.auth;
61
+ var appUrl = process.env.NEXT_PUBLIC_DASHBOARD_URL || "";
62
+ var defaultServerSecure = !appUrl.startsWith("http://localhost");
65
63
  var defaultAuthConfig = {
66
64
  oauthServer: "https://auth-dev.civic.com/oauth",
67
65
  callbackUrl: "/api/auth/callback",
@@ -73,26 +71,32 @@ var defaultAuthConfig = {
73
71
  cookies: {
74
72
  tokens: {
75
73
  ["id_token" /* ID_TOKEN */]: {
76
- secure: true,
74
+ secure: defaultServerSecure,
77
75
  httpOnly: true,
78
76
  sameSite: "strict",
79
77
  path: "/"
80
78
  },
81
79
  ["access_token" /* ACCESS_TOKEN */]: {
82
- secure: true,
80
+ secure: defaultServerSecure,
83
81
  httpOnly: true,
84
82
  sameSite: "strict",
85
83
  path: "/"
86
84
  },
87
85
  ["refresh_token" /* REFRESH_TOKEN */]: {
88
- secure: true,
86
+ secure: defaultServerSecure,
87
+ httpOnly: true,
88
+ sameSite: "strict",
89
+ path: "/"
90
+ },
91
+ ["code_verifier" /* COOKIE_NAME */]: {
92
+ secure: defaultServerSecure,
89
93
  httpOnly: true,
90
94
  sameSite: "strict",
91
95
  path: "/"
92
96
  }
93
97
  },
94
98
  user: {
95
- secure: true,
99
+ secure: defaultServerSecure,
96
100
  httpOnly: false,
97
101
  sameSite: "strict",
98
102
  path: "/",
@@ -104,7 +108,7 @@ var defaultAuthConfig = {
104
108
  var resolveAuthConfig = (config = {}) => {
105
109
  var _a, _b, _c, _d, _e, _f;
106
110
  logger.debug("resolveAuthConfig inputs", JSON.stringify(config, null, 2));
107
- const configFromEnv = _chunkRF23Q4V6js.withoutUndefined.call(void 0, {
111
+ const configFromEnv = _chunkO2SODTR3js.withoutUndefined.call(void 0, {
108
112
  clientId: process.env._civic_auth_client_id,
109
113
  oauthServer: process.env._civic_oauth_server,
110
114
  callbackUrl: process.env._civic_auth_callback_url,
@@ -158,69 +162,10 @@ var createCivicAuthPlugin = (clientId, authConfig = {}) => {
158
162
  };
159
163
  };
160
164
 
161
- // src/nextjs/utils.ts
162
- var resolveCallbackUrl = (config, alternativeUrl) => {
163
- var _a;
164
- const baseUrl = (_a = config.appUrl) != null ? _a : alternativeUrl;
165
- const callbackUrl = new URL(config == null ? void 0 : config.callbackUrl, baseUrl).toString();
166
- return callbackUrl.toString();
167
- };
168
-
169
- // src/nextjs/cookies.ts
170
- var _headersjs = require('next/headers.js');
171
- var clearAuthCookies = () => _chunkCRTRMMJ7js.__async.call(void 0, void 0, null, function* () {
172
- const cookieStorage = new NextjsCookieStorage();
173
- _chunkRF23Q4V6js.clearTokens.call(void 0, cookieStorage);
174
- const clientStorage = new NextjsClientStorage();
175
- const userSession = new (0, _chunkRF23Q4V6js.GenericUserSession)(clientStorage);
176
- userSession.set(null);
177
- });
178
- var NextjsCookieStorage = class extends _chunkRF23Q4V6js.CookieStorage {
179
- constructor(config = {}) {
180
- super({
181
- secure: true,
182
- httpOnly: true
183
- });
184
- this.config = config;
185
- }
186
- get(key) {
187
- var _a;
188
- return ((_a = _headersjs.cookies.call(void 0, ).get(key)) == null ? void 0 : _a.value) || null;
189
- }
190
- set(key, value) {
191
- var _a, _b;
192
- const cookieSettings = (_b = (_a = this.config) == null ? void 0 : _a[key]) != null ? _b : this.settings;
193
- console.log(
194
- "NextjsCookieStorage.set",
195
- JSON.stringify({ key, value, cookieSettings }, null, 2)
196
- );
197
- _headersjs.cookies.call(void 0, ).set(key, value, cookieSettings);
198
- }
199
- };
200
- var NextjsClientStorage = class extends _chunkRF23Q4V6js.CookieStorage {
201
- constructor(config = {}) {
202
- super(_chunkCRTRMMJ7js.__spreadProps.call(void 0, _chunkCRTRMMJ7js.__spreadValues.call(void 0, {}, config), {
203
- secure: false,
204
- httpOnly: false
205
- }));
206
- }
207
- get(key) {
208
- var _a;
209
- return ((_a = _headersjs.cookies.call(void 0, ).get(key)) == null ? void 0 : _a.value) || null;
210
- }
211
- set(key, value) {
212
- _headersjs.cookies.call(void 0, ).set(key, value, this.settings);
213
- }
214
- };
215
-
216
-
217
-
218
-
219
-
220
165
 
221
166
 
222
167
 
223
168
 
224
169
 
225
- exports.loggers = loggers; exports.defaultAuthConfig = defaultAuthConfig; exports.resolveAuthConfig = resolveAuthConfig; exports.createCivicAuthPlugin = createCivicAuthPlugin; exports.resolveCallbackUrl = resolveCallbackUrl; exports.clearAuthCookies = clearAuthCookies; exports.NextjsCookieStorage = NextjsCookieStorage; exports.NextjsClientStorage = NextjsClientStorage;
226
- //# sourceMappingURL=chunk-SEKF2WZX.js.map
170
+ exports.loggers = loggers; exports.defaultAuthConfig = defaultAuthConfig; exports.resolveAuthConfig = resolveAuthConfig; exports.createCivicAuthPlugin = createCivicAuthPlugin;
171
+ //# sourceMappingURL=chunk-CZ3AVCKD.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["/Users/kevincolgan/code/civic-auth/packages/civic-auth-client/dist/chunk-CZ3AVCKD.js","../src/lib/logger.ts","../src/nextjs/config.ts"],"names":[],"mappings":"AAAA;AACE;AACF,sDAA4B;AAC5B;AACE;AACA;AACF,sDAA4B;AAC5B;AACA;ACRA,4EAAkB;AAElB,IAAM,aAAA,EAAe,aAAA;AASrB,IAAM,YAAA,EAAN,MAAoC;AAAA,EAMlC,WAAA,CAAY,SAAA,EAAmB;AAE7B,IAAA,IAAA,CAAK,YAAA,EAAc,6BAAA,CAAM,EAAA;AACD,IAAA;AACA,IAAA;AACC,IAAA;AAEA,IAAA;AACD,IAAA;AACA,IAAA;AACC,IAAA;AAC3B,EAAA;AAEiD,EAAA;AACrB,IAAA;AAC5B,EAAA;AAEgD,EAAA;AACrB,IAAA;AAC3B,EAAA;AAEgD,EAAA;AACrB,IAAA;AAC3B,EAAA;AAEiD,EAAA;AACrB,IAAA;AAC5B,EAAA;AACF;AAE6B;AAIN;AAAA;AAEb,EAAA;AACe,IAAA;AACI,IAAA;AACf,IAAA;AACW,MAAA;AACrB,IAAA;AACF,EAAA;AAAA;AAEO,EAAA;AACoB,IAAA;AACL,IAAA;AACE,IAAA;AACxB,EAAA;AAAA;AAEU,EAAA;AACiB,IAAA;AACH,IAAA;AACxB,EAAA;AACF;ADd8B;AACA;AE/CA;AAuBH;AACE;AAK8C;AAC5D,EAAA;AACA,EAAA;AACC,EAAA;AACH,EAAA;AACD,EAAA;AACI,EAAA;AACJ,EAAA;AACD,EAAA;AACC,IAAA;AACN,MAAA;AACU,QAAA;AACE,QAAA;AACA,QAAA;AACJ,QAAA;AACR,MAAA;AACA,MAAA;AACU,QAAA;AACE,QAAA;AACA,QAAA;AACJ,QAAA;AACR,MAAA;AACA,MAAA;AACU,QAAA;AACE,QAAA;AACA,QAAA;AACJ,QAAA;AACR,MAAA;AACA,MAAA;AACU,QAAA;AACE,QAAA;AACA,QAAA;AACJ,QAAA;AACR,MAAA;AACF,IAAA;AACM,IAAA;AACI,MAAA;AACE,MAAA;AACA,MAAA;AACJ,MAAA;AACO,MAAA;AAAA;AACf,IAAA;AACF,EAAA;AACF;AAoBE;AAvGF,EAAA;AAyGe,EAAA;AAES,EAAA;AACE,IAAA;AACG,IAAA;AACA,IAAA;AACC,IAAA;AACJ,IAAA;AACF,IAAA;AACG,IAAA;AACN,IAAA;AACA,IAAA;AACI,IAAA;AAGtB,EAAA;AACoB,EAAA;AAAA;AAIV,IAAA;AACC,MAAA;AAKF,MAAA;AAKR,IAAA;AACF,EAAA;AAEO,EAAA;AACL,IAAA;AACe,IAAA;AACjB,EAAA;AACa,EAAA;AACI,EAAA;AACC,IAAA;AAClB,EAAA;AACO,EAAA;AACT;AA0BE;AAGoC,EAAA;AAC3B,IAAA;AACL,MAAA;AACe,MAAA;AACjB,IAAA;AACuB,IAAA;AAChB,IAAA;AAEA,MAAA;AAAA;AAGH,QAAA;AACqB,QAAA;AACrB,QAAA;AACA,QAAA;AACA,QAAA;AACA,QAAA;AACqB,QAAA;AACC,QAAA;AACA,QAAA;AACtB,QAAA;AACF,MAAA;AACF,IAAA;AACF,EAAA;AACF;AFtC8B;AACA;AACA;AACA;AACA;AACA;AACA","file":"/Users/kevincolgan/code/civic-auth/packages/civic-auth-client/dist/chunk-CZ3AVCKD.js","sourcesContent":[null,"import debug from \"debug\";\n\nconst PACKAGE_NAME = \"@civic/auth\";\n\nexport interface Logger {\n debug(message: string, ...args: unknown[]): void;\n info(message: string, ...args: unknown[]): void;\n warn(message: string, ...args: unknown[]): void;\n error(message: string, ...args: unknown[]): void;\n}\n\nclass DebugLogger implements Logger {\n private debugLogger: debug.Debugger;\n private infoLogger: debug.Debugger;\n private warnLogger: debug.Debugger;\n private errorLogger: debug.Debugger;\n\n constructor(namespace: string) {\n // Format: @org/package:library:component:level\n this.debugLogger = debug(`${PACKAGE_NAME}:${namespace}:debug`);\n this.infoLogger = debug(`${PACKAGE_NAME}:${namespace}:info`);\n this.warnLogger = debug(`${PACKAGE_NAME}:${namespace}:warn`);\n this.errorLogger = debug(`${PACKAGE_NAME}:${namespace}:error`);\n\n this.debugLogger.color = \"4\";\n this.infoLogger.color = \"2\";\n this.warnLogger.color = \"3\";\n this.errorLogger.color = \"1\";\n }\n\n debug(message: string, ...args: unknown[]): void {\n this.debugLogger(message, ...args);\n }\n\n info(message: string, ...args: unknown[]): void {\n this.infoLogger(message, ...args);\n }\n\n warn(message: string, ...args: unknown[]): void {\n this.warnLogger(message, ...args);\n }\n\n error(message: string, ...args: unknown[]): void {\n this.errorLogger(message, ...args);\n }\n}\n\nexport const createLogger = (namespace: string): Logger =>\n new DebugLogger(namespace);\n\n// Pre-configured loggers for different parts of your package\nexport const loggers = {\n // Next.js specific loggers\n nextjs: {\n routes: createLogger(\"api:routes\"),\n middleware: createLogger(\"api:middleware\"),\n handlers: {\n auth: createLogger(\"api:handlers:auth\"),\n },\n },\n // React specific loggers\n react: {\n components: createLogger(\"react:components\"),\n hooks: createLogger(\"react:hooks\"),\n context: createLogger(\"react:context\"),\n },\n // Shared utilities loggers\n services: {\n validation: createLogger(\"utils:validation\"),\n network: createLogger(\"utils:network\"),\n },\n} as const;\n","/* eslint-disable turbo/no-undeclared-env-vars */\nimport { NextConfig } from \"next\";\nimport { loggers } from \"@/lib/logger\";\nimport { withoutUndefined } from \"@/utils\";\nimport {\n CodeVerifier,\n CookieConfig,\n OAuthTokens,\n TokensCookieConfig,\n} from \"@/shared/types\";\n\nconst logger = loggers.nextjs.handlers.auth;\n\nexport type CookiesConfigObject = {\n tokens: TokensCookieConfig;\n user: CookieConfig;\n};\nexport type AuthConfigWithDefaults = {\n clientId: string;\n oauthServer: string;\n callbackUrl: string;\n loginUrl: string;\n logoutUrl: string;\n appUrl?: string;\n challengeUrl: string;\n include: string[];\n exclude: string[];\n cookies: CookiesConfigObject;\n};\n\nexport type AuthConfig = Partial<AuthConfigWithDefaults>;\n\nexport type DefinedAuthConfig = AuthConfigWithDefaults;\n\nconst appUrl = process.env.NEXT_PUBLIC_DASHBOARD_URL || \"\";\nconst defaultServerSecure = !appUrl.startsWith(\"http://localhost\");\n\n/**\n * Default configuration values that will be used if not overridden\n */\nexport const defaultAuthConfig: Omit<AuthConfigWithDefaults, \"clientId\"> = {\n oauthServer: \"https://auth-dev.civic.com/oauth\",\n callbackUrl: \"/api/auth/callback\",\n challengeUrl: \"/api/auth/challenge\",\n logoutUrl: \"/api/auth/logout\",\n loginUrl: \"/\",\n include: [\"/*\"],\n exclude: [],\n cookies: {\n tokens: {\n [OAuthTokens.ID_TOKEN]: {\n secure: defaultServerSecure,\n httpOnly: true,\n sameSite: \"strict\",\n path: \"/\",\n },\n [OAuthTokens.ACCESS_TOKEN]: {\n secure: defaultServerSecure,\n httpOnly: true,\n sameSite: \"strict\",\n path: \"/\",\n },\n [OAuthTokens.REFRESH_TOKEN]: {\n secure: defaultServerSecure,\n httpOnly: true,\n sameSite: \"strict\",\n path: \"/\",\n },\n [CodeVerifier.COOKIE_NAME]: {\n secure: defaultServerSecure,\n httpOnly: true,\n sameSite: \"strict\",\n path: \"/\",\n },\n },\n user: {\n secure: defaultServerSecure,\n httpOnly: false,\n sameSite: \"strict\",\n path: \"/\",\n maxAge: 60 * 60, // 1 hour\n },\n },\n};\n\n/**\n * Resolves the authentication configuration by combining:\n * 1. Default values\n * 2. Environment variables (set internally by the plugin)\n * 3. Explicitly passed configuration\n *\n * Note: Developers should not set _civic_auth_* environment variables directly.\n * Instead, pass configuration to the createCivicAuthPlugin in next.config.js:\n *\n * @example\n * ```js\n * // next.config.js\n * export default createCivicAuthPlugin({\n * callbackUrl: '/custom/callback',\n * })\n * ```\n */\nexport const resolveAuthConfig = (\n config: AuthConfig = {},\n): AuthConfigWithDefaults & { clientId: string } => {\n logger.debug(\"resolveAuthConfig inputs\", JSON.stringify(config, null, 2));\n // Read configuration that was set by the plugin via environment variables\n const configFromEnv = withoutUndefined({\n clientId: process.env._civic_auth_client_id,\n oauthServer: process.env._civic_oauth_server,\n callbackUrl: process.env._civic_auth_callback_url,\n challengeUrl: process.env._civic_auth_challenge_url,\n loginUrl: process.env._civic_auth_login_url,\n appUrl: process.env._civic_auth_app_url,\n logoutUrl: process.env._civic_auth_logout_url,\n include: process.env._civic_auth_includes?.split(\",\"),\n exclude: process.env._civic_auth_excludes?.split(\",\"),\n cookies: process.env._civic_auth_cookie_config\n ? JSON.parse(process.env._civic_auth_cookie_config)\n : undefined,\n }) as AuthConfig;\n const mergedConfig = {\n ...defaultAuthConfig,\n ...configFromEnv, // Apply plugin-set config\n ...config, // Override with directly passed config\n cookies: {\n tokens: {\n ...defaultAuthConfig.cookies.tokens,\n ...(configFromEnv?.cookies?.tokens || {}),\n ...(config.cookies?.tokens || {}),\n },\n user: {\n ...defaultAuthConfig.cookies.user,\n ...(configFromEnv?.cookies?.user || {}),\n ...(config.cookies?.user || {}),\n },\n },\n };\n\n logger.debug(\n \"Config from environment:\",\n JSON.stringify(configFromEnv, null, 2),\n );\n logger.debug(\"Resolved config:\", JSON.stringify(mergedConfig, null, 2));\n if (mergedConfig.clientId === undefined) {\n throw new Error(\"Civic Auth client ID is required\");\n }\n return mergedConfig as AuthConfigWithDefaults & { clientId: string };\n};\n\n/**\n * Creates a Next.js plugin that handles auth configuration.\n *\n * This is the main configuration point for the auth system.\n * Do not set _civic_auth_* environment variables directly - instead,\n * pass your configuration here:\n *\n * @example\n * ```js\n * // next.config.js\n * export default createCivicAuthPlugin({\n * clientId: 'my-client-id',\n * callbackUrl: '/custom/callback',\n * loginUrl: '/custom/login',\n * logoutUrl: '/custom/logout',\n * include: ['/protected/*'],\n * exclude: ['/public/*']\n * })\n * ```\n *\n * The plugin sets internal environment variables that are used by\n * the auth system. These variables should not be set manually.\n */\nexport const createCivicAuthPlugin = (\n clientId: string,\n authConfig: AuthConfig = {},\n) => {\n return (nextConfig?: NextConfig) => {\n logger.debug(\n \"createCivicAuthPlugin nextConfig\",\n JSON.stringify(nextConfig, null, 2),\n );\n const resolvedConfig = resolveAuthConfig({ ...authConfig, clientId });\n return {\n ...nextConfig,\n env: {\n ...nextConfig?.env,\n // Internal environment variables - do not set these manually\n _civic_auth_client_id: clientId,\n _civic_oauth_server: resolvedConfig.oauthServer,\n _civic_auth_callback_url: resolvedConfig.callbackUrl,\n _civic_auth_challenge_url: resolvedConfig.challengeUrl,\n _civic_auth_login_url: resolvedConfig.loginUrl,\n _civic_auth_logout_url: resolvedConfig.logoutUrl,\n _civic_auth_app_url: resolvedConfig.appUrl,\n _civic_auth_includes: resolvedConfig.include.join(\",\"),\n _civic_auth_excludes: resolvedConfig.exclude.join(\",\"),\n _civic_auth_cookie_config: JSON.stringify(resolvedConfig.cookies),\n },\n };\n };\n};\n"]}
@@ -0,0 +1,118 @@
1
+ "use strict";Object.defineProperty(exports, "__esModule", {value: true});
2
+
3
+ var _chunkO6DPCPRHjs = require('./chunk-O6DPCPRH.js');
4
+
5
+
6
+
7
+ var _chunkO2SODTR3js = require('./chunk-O2SODTR3.js');
8
+
9
+
10
+
11
+
12
+ var _chunkCRTRMMJ7js = require('./chunk-CRTRMMJ7.js');
13
+
14
+ // src/nextjs/cookies.ts
15
+ var _headersjs = require('next/headers.js');
16
+ var createTokenCookies = (response, sessionData, config) => {
17
+ var _a, _b;
18
+ const maxAge = (_a = sessionData.expiresIn) != null ? _a : 3600;
19
+ const cookieOptions = _chunkCRTRMMJ7js.__spreadProps.call(void 0, _chunkCRTRMMJ7js.__spreadValues.call(void 0, {}, (_b = config.cookies) == null ? void 0 : _b.tokens), {
20
+ maxAge
21
+ });
22
+ if (sessionData.accessToken) {
23
+ response.cookies.set("access_token", sessionData.accessToken, _chunkCRTRMMJ7js.__spreadProps.call(void 0, _chunkCRTRMMJ7js.__spreadValues.call(void 0, {}, cookieOptions), {
24
+ httpOnly: true
25
+ }));
26
+ }
27
+ if (sessionData.idToken) {
28
+ response.cookies.set("id_token", sessionData.idToken, _chunkCRTRMMJ7js.__spreadProps.call(void 0, _chunkCRTRMMJ7js.__spreadValues.call(void 0, {}, cookieOptions), {
29
+ httpOnly: true
30
+ }));
31
+ }
32
+ if (sessionData.refreshToken) {
33
+ response.cookies.set("refresh_token", sessionData.refreshToken, _chunkCRTRMMJ7js.__spreadProps.call(void 0, _chunkCRTRMMJ7js.__spreadValues.call(void 0, {}, cookieOptions), {
34
+ httpOnly: true
35
+ }));
36
+ }
37
+ };
38
+ var createUserInfoCookie = (response, user, sessionData, config) => {
39
+ var _a, _b, _c;
40
+ if (!user) {
41
+ response.cookies.set("user", "", _chunkCRTRMMJ7js.__spreadProps.call(void 0, _chunkCRTRMMJ7js.__spreadValues.call(void 0, {}, (_a = config.cookies) == null ? void 0 : _a.user), {
42
+ maxAge: 0
43
+ }));
44
+ return;
45
+ }
46
+ const maxAge = (_b = sessionData.expiresIn) != null ? _b : 3600;
47
+ const frontendUser = _chunkCRTRMMJ7js.__spreadValues.call(void 0, {}, user);
48
+ response.cookies.set("user", JSON.stringify(frontendUser), _chunkCRTRMMJ7js.__spreadProps.call(void 0, _chunkCRTRMMJ7js.__spreadValues.call(void 0, {}, (_c = config.cookies) == null ? void 0 : _c.user), {
49
+ maxAge
50
+ }));
51
+ };
52
+ var clearAuthCookies = (config) => _chunkCRTRMMJ7js.__async.call(void 0, void 0, null, function* () {
53
+ var _a;
54
+ const cookieStorage = new NextjsCookieStorage((_a = config.cookies) == null ? void 0 : _a.tokens);
55
+ _chunkO2SODTR3js.clearTokens.call(void 0, cookieStorage);
56
+ const clientStorage = new NextjsClientStorage();
57
+ const userSession = new (0, _chunkO2SODTR3js.GenericUserSession)(clientStorage);
58
+ userSession.set(null);
59
+ });
60
+ var NextjsCookieStorage = class extends _chunkO6DPCPRHjs.CookieStorage {
61
+ constructor(config = {}) {
62
+ super({
63
+ secure: true,
64
+ httpOnly: true
65
+ });
66
+ this.config = config;
67
+ }
68
+ get(key) {
69
+ var _a;
70
+ return ((_a = _headersjs.cookies.call(void 0, ).get(key)) == null ? void 0 : _a.value) || null;
71
+ }
72
+ set(key, value) {
73
+ var _a;
74
+ const cookieSettings = ((_a = this.config) == null ? void 0 : _a[key]) || _chunkCRTRMMJ7js.__spreadValues.call(void 0, {}, this.settings);
75
+ console.log(
76
+ "NextjsCookieStorage.set",
77
+ JSON.stringify(
78
+ { key, value, config: this.config, cookieSettings },
79
+ null,
80
+ 2
81
+ )
82
+ );
83
+ _headersjs.cookies.call(void 0, ).set(key, value, cookieSettings);
84
+ }
85
+ };
86
+ var NextjsClientStorage = class extends _chunkO6DPCPRHjs.CookieStorage {
87
+ constructor(config = {}) {
88
+ super(_chunkCRTRMMJ7js.__spreadProps.call(void 0, _chunkCRTRMMJ7js.__spreadValues.call(void 0, {}, config), {
89
+ secure: false,
90
+ httpOnly: false
91
+ }));
92
+ }
93
+ get(key) {
94
+ var _a;
95
+ return ((_a = _headersjs.cookies.call(void 0, ).get(key)) == null ? void 0 : _a.value) || null;
96
+ }
97
+ set(key, value) {
98
+ _headersjs.cookies.call(void 0, ).set(key, value, this.settings);
99
+ }
100
+ };
101
+
102
+ // src/nextjs/utils.ts
103
+ var resolveCallbackUrl = (config, alternativeUrl) => {
104
+ var _a;
105
+ const baseUrl = (_a = config.appUrl) != null ? _a : alternativeUrl;
106
+ const callbackUrl = new URL(config == null ? void 0 : config.callbackUrl, baseUrl).toString();
107
+ return callbackUrl.toString();
108
+ };
109
+
110
+
111
+
112
+
113
+
114
+
115
+
116
+
117
+ exports.createTokenCookies = createTokenCookies; exports.createUserInfoCookie = createUserInfoCookie; exports.clearAuthCookies = clearAuthCookies; exports.NextjsCookieStorage = NextjsCookieStorage; exports.NextjsClientStorage = NextjsClientStorage; exports.resolveCallbackUrl = resolveCallbackUrl;
118
+ //# sourceMappingURL=chunk-DJFTZS4P.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["/Users/kevincolgan/code/civic-auth/packages/civic-auth-client/dist/chunk-DJFTZS4P.js","../src/nextjs/cookies.ts","../src/nextjs/utils.ts"],"names":[],"mappings":"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","file":"/Users/kevincolgan/code/civic-auth/packages/civic-auth-client/dist/chunk-DJFTZS4P.js","sourcesContent":[null,"import { SessionData, UnknownObject, User } from \"@/types\";\nimport { NextResponse } from \"next/server\";\nimport { AuthConfig, CookiesConfigObject } from \"@/nextjs/config\";\nimport { CookieStorage, CookieStorageSettings } from \"@/server\";\nimport { cookies } from \"next/headers.js\";\nimport { GenericUserSession } from \"@/shared/UserSession\";\nimport { clearTokens } from \"@/shared/util\";\nimport { CodeVerifier, OAuthTokens, TokensCookieConfig } from \"@/shared/types\";\n\n/**\n * Creates HTTP-only cookies for authentication tokens\n */\nconst createTokenCookies = (\n response: NextResponse,\n sessionData: SessionData,\n config: AuthConfig,\n) => {\n const maxAge = sessionData.expiresIn ?? 3600;\n const cookieOptions = {\n ...config.cookies?.tokens,\n maxAge,\n };\n\n if (sessionData.accessToken) {\n response.cookies.set(\"access_token\", sessionData.accessToken, {\n ...cookieOptions,\n httpOnly: true,\n });\n }\n\n if (sessionData.idToken) {\n response.cookies.set(\"id_token\", sessionData.idToken, {\n ...cookieOptions,\n httpOnly: true,\n });\n }\n\n if (sessionData.refreshToken) {\n response.cookies.set(\"refresh_token\", sessionData.refreshToken, {\n ...cookieOptions,\n httpOnly: true,\n });\n }\n};\n\n/**\n * Creates a client-readable cookie with user info\n */\nconst createUserInfoCookie = (\n response: NextResponse,\n user: User<UnknownObject> | null,\n sessionData: SessionData,\n config: AuthConfig,\n) => {\n if (!user) {\n response.cookies.set(\"user\", \"\", {\n ...config.cookies?.user,\n maxAge: 0,\n });\n return;\n }\n const maxAge = sessionData.expiresIn ?? 3600;\n\n // TODO select fields to include in the user cookie\n const frontendUser = {\n ...user,\n };\n\n // TODO make call to get user info from the\n // auth server /userinfo endpoint when it's available\n // then add to the default claims above\n\n response.cookies.set(\"user\", JSON.stringify(frontendUser), {\n ...config.cookies?.user,\n maxAge,\n });\n};\n\n/**\n * Clears all authentication cookies\n */\nconst clearAuthCookies = async (config: AuthConfig) => {\n // clear session, and tokens\n const cookieStorage = new NextjsCookieStorage(config.cookies?.tokens);\n clearTokens(cookieStorage);\n\n // clear user\n const clientStorage = new NextjsClientStorage();\n const userSession = new GenericUserSession(clientStorage);\n userSession.set(null);\n};\n\ntype KeySetter = OAuthTokens | CodeVerifier;\nclass NextjsCookieStorage extends CookieStorage {\n constructor(readonly config: Partial<TokensCookieConfig> = {}) {\n super({\n secure: true,\n httpOnly: true,\n });\n }\n\n get(key: string): string | null {\n return cookies().get(key)?.value || null;\n }\n\n set(key: KeySetter, value: string): void {\n const cookieSettings = this.config?.[key as KeySetter] || {\n ...this.settings,\n };\n console.log(\n \"NextjsCookieStorage.set\",\n JSON.stringify(\n { key, value, config: this.config, cookieSettings },\n null,\n 2,\n ),\n );\n cookies().set(key, value, cookieSettings);\n }\n}\n\nclass NextjsClientStorage extends CookieStorage {\n constructor(config: Partial<CookieStorageSettings> = {}) {\n super({\n ...config,\n secure: false,\n httpOnly: false,\n });\n }\n\n get(key: string): string | null {\n return cookies().get(key)?.value || null;\n }\n\n set(key: string, value: string): void {\n cookies().set(key, value, this.settings);\n }\n}\n\nexport {\n createTokenCookies,\n createUserInfoCookie,\n clearAuthCookies,\n NextjsCookieStorage,\n NextjsClientStorage,\n};\n","import { AuthConfigWithDefaults } from \"@/nextjs/config\";\n\nexport const resolveCallbackUrl = (\n config: AuthConfigWithDefaults,\n alternativeUrl?: string,\n): string => {\n const baseUrl = config.appUrl ?? alternativeUrl;\n const callbackUrl = new URL(config?.callbackUrl, baseUrl).toString();\n return callbackUrl.toString();\n};\n"]}
@@ -0,0 +1,223 @@
1
+ import {
2
+ AUTH_SERVER,
3
+ DEFAULT_SCOPES,
4
+ GenericAuthenticationInitiator,
5
+ GenericPublicClientPKCEProducer,
6
+ exchangeTokens,
7
+ getEndpointsWithOverrides,
8
+ retrieveTokens,
9
+ storeTokens
10
+ } from "./chunk-CBQ3HKRV.mjs";
11
+ import {
12
+ __async,
13
+ __spreadProps,
14
+ __spreadValues
15
+ } from "./chunk-RGHW4PYM.mjs";
16
+
17
+ // src/shared/storage.ts
18
+ var DEFAULT_COOKIE_DURATION = 60 * 15;
19
+ var CookieStorage = class {
20
+ constructor(settings = {}) {
21
+ var _a, _b, _c, _d, _e;
22
+ this.settings = {
23
+ httpOnly: (_a = settings.httpOnly) != null ? _a : true,
24
+ secure: (_b = settings.secure) != null ? _b : true,
25
+ // the callback request comes the auth server
26
+ // 'lax' ensures the code_verifier cookie is sent with the request
27
+ sameSite: (_c = settings.sameSite) != null ? _c : "lax",
28
+ expires: (_d = settings.expires) != null ? _d : new Date(Date.now() + 1e3 * DEFAULT_COOKIE_DURATION),
29
+ path: (_e = settings.path) != null ? _e : "/"
30
+ };
31
+ }
32
+ };
33
+
34
+ // src/server/ServerAuthenticationResolver.ts
35
+ import { OAuth2Client } from "oslo/oauth2";
36
+ var ServerAuthenticationResolver = class _ServerAuthenticationResolver {
37
+ constructor(authConfig, storage, endpointOverrides) {
38
+ this.authConfig = authConfig;
39
+ this.storage = storage;
40
+ this.endpointOverrides = endpointOverrides;
41
+ console.log("ServerAuthenticationResolver constructor", {
42
+ authConfig,
43
+ storage,
44
+ endpointOverrides
45
+ });
46
+ this.pkceProducer = new GenericPublicClientPKCEProducer(storage);
47
+ }
48
+ validateExistingSession() {
49
+ throw new Error("Method not implemented.");
50
+ }
51
+ init() {
52
+ return __async(this, null, function* () {
53
+ this.endpoints = yield getEndpointsWithOverrides(
54
+ this.authConfig.oauthServer,
55
+ this.endpointOverrides
56
+ );
57
+ this.oauth2client = new OAuth2Client(
58
+ this.authConfig.clientId,
59
+ this.endpoints.auth,
60
+ this.endpoints.token,
61
+ {
62
+ redirectURI: this.authConfig.redirectUrl
63
+ }
64
+ );
65
+ return this;
66
+ });
67
+ }
68
+ tokenExchange(code, state) {
69
+ return __async(this, null, function* () {
70
+ if (!this.oauth2client) yield this.init();
71
+ const codeVerifier = yield this.pkceProducer.getCodeVerifier();
72
+ if (!codeVerifier) throw new Error("Code verifier not found in storage");
73
+ const tokens = yield exchangeTokens(
74
+ code,
75
+ state,
76
+ this.pkceProducer,
77
+ this.oauth2client,
78
+ // clean up types here to avoid the ! operator
79
+ this.authConfig.oauthServer,
80
+ this.endpoints
81
+ // clean up types here to avoid the ! operator
82
+ );
83
+ storeTokens(this.storage, tokens);
84
+ return tokens;
85
+ });
86
+ }
87
+ getSessionData() {
88
+ return __async(this, null, function* () {
89
+ const storageData = retrieveTokens(this.storage);
90
+ if (!storageData) return null;
91
+ return {
92
+ authenticated: !!storageData.id_token,
93
+ idToken: storageData.id_token,
94
+ accessToken: storageData.access_token,
95
+ refreshToken: storageData.refresh_token
96
+ };
97
+ });
98
+ }
99
+ static build(authConfig, storage, endpointOverrides) {
100
+ return __async(this, null, function* () {
101
+ const resolver = new _ServerAuthenticationResolver(
102
+ authConfig,
103
+ storage,
104
+ endpointOverrides
105
+ );
106
+ yield resolver.init();
107
+ return resolver;
108
+ });
109
+ }
110
+ };
111
+
112
+ // src/server/login.ts
113
+ function resolveOAuthAccessCode(code, state, storage, config) {
114
+ return __async(this, null, function* () {
115
+ var _a;
116
+ const authSessionService = yield ServerAuthenticationResolver.build(
117
+ __spreadProps(__spreadValues({}, config), {
118
+ oauthServer: (_a = config.oauthServer) != null ? _a : AUTH_SERVER
119
+ }),
120
+ storage,
121
+ config.endpointOverrides
122
+ );
123
+ return authSessionService.tokenExchange(code, state);
124
+ });
125
+ }
126
+ function isLoggedIn(storage) {
127
+ return !!storage.get("id_token");
128
+ }
129
+ function buildLoginUrl(config, storage) {
130
+ return __async(this, null, function* () {
131
+ var _a, _b, _c;
132
+ const state = (_a = config.state) != null ? _a : Math.random().toString(36).substring(2);
133
+ const scopes = (_b = config.scopes) != null ? _b : DEFAULT_SCOPES;
134
+ const pkceProducer = new GenericPublicClientPKCEProducer(storage);
135
+ const authInitiator = new GenericAuthenticationInitiator(__spreadProps(__spreadValues({}, config), {
136
+ state,
137
+ scopes,
138
+ oauthServer: (_c = config.oauthServer) != null ? _c : AUTH_SERVER,
139
+ // When retrieving the PKCE challenge on the server-side, we produce it and store it in the session
140
+ pkceConsumer: pkceProducer
141
+ }));
142
+ return authInitiator.signIn();
143
+ });
144
+ }
145
+
146
+ // src/shared/GenericAuthenticationRefresher.ts
147
+ import { OAuth2Client as OAuth2Client2 } from "oslo/oauth2";
148
+ var GenericAuthenticationRefresher = class _GenericAuthenticationRefresher {
149
+ constructor(authConfig, storage, endpointOverrides) {
150
+ this.authConfig = authConfig;
151
+ this.storage = storage;
152
+ this.endpointOverrides = endpointOverrides;
153
+ console.log("GenericAuthenticationRefresher constructor", {
154
+ authConfig,
155
+ endpointOverrides
156
+ });
157
+ }
158
+ init() {
159
+ return __async(this, null, function* () {
160
+ this.endpoints = yield getEndpointsWithOverrides(
161
+ this.authConfig.oauthServer,
162
+ this.endpointOverrides
163
+ );
164
+ this.oauth2client = new OAuth2Client2(
165
+ this.authConfig.clientId,
166
+ this.endpoints.auth,
167
+ this.endpoints.token,
168
+ {
169
+ redirectURI: this.authConfig.redirectUrl
170
+ }
171
+ );
172
+ return this;
173
+ });
174
+ }
175
+ static build(authConfig, storage, endpointOverrides) {
176
+ return __async(this, null, function* () {
177
+ const refresher = new _GenericAuthenticationRefresher(
178
+ authConfig,
179
+ storage,
180
+ endpointOverrides
181
+ );
182
+ yield refresher.init();
183
+ return refresher;
184
+ });
185
+ }
186
+ refreshTokens() {
187
+ return __async(this, null, function* () {
188
+ if (!this.oauth2client) yield this.init();
189
+ const tokens = retrieveTokens(this.storage);
190
+ if (!(tokens == null ? void 0 : tokens.refresh_token)) throw new Error("No refresh token available");
191
+ const oauth2Client = this.oauth2client;
192
+ const refreshedTokens = yield oauth2Client.refreshAccessToken(
193
+ tokens.refresh_token
194
+ );
195
+ storeTokens(this.storage, refreshedTokens);
196
+ return tokens;
197
+ });
198
+ }
199
+ };
200
+
201
+ // src/server/refresh.ts
202
+ function refreshTokens(storage, config) {
203
+ return __async(this, null, function* () {
204
+ var _a;
205
+ const refresher = yield GenericAuthenticationRefresher.build(
206
+ __spreadProps(__spreadValues({}, config), {
207
+ oauthServer: (_a = config.oauthServer) != null ? _a : AUTH_SERVER
208
+ }),
209
+ storage,
210
+ config.endpointOverrides
211
+ );
212
+ return refresher.refreshTokens();
213
+ });
214
+ }
215
+
216
+ export {
217
+ CookieStorage,
218
+ resolveOAuthAccessCode,
219
+ isLoggedIn,
220
+ buildLoginUrl,
221
+ refreshTokens
222
+ };
223
+ //# sourceMappingURL=chunk-HTTTZ2BP.mjs.map