@civic/auth 0.0.1-beta.0 → 0.0.1-beta.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/react/hooks/useUser.tsx","../src/react/providers/UserProvider.tsx","../src/react/hooks/useAuth.tsx","../src/react/hooks/useToken.tsx","../src/react/providers/TokenProvider.tsx","../src/react/providers/AuthProvider.tsx","../src/services/UserInfoService.ts","../src/services/SessionService.ts","../src/lib/oauth.ts","../src/utils.ts","../src/react/components/CivicAuthIframe.tsx","../src/react/components/LoadingIcon.tsx","../src/react/components/UserButton.tsx","../src/react/providers/ParamsProvider.tsx","../src/react/providers/SessionProvider.tsx","../src/constants.ts","../src/config.ts","../src/react/providers/CivicProvider.tsx","../src/react/hooks/useParams.tsx","../src/react/hooks/useSession.tsx"],"sourcesContent":["import { useContext } from \"react\";\nimport { UserContext, UserContextType } from \"@/react/providers\";\n\nconst useUser = <\n T extends Record<string, unknown> = Record<string, never>,\n>(): UserContextType<T> => {\n const context = useContext(UserContext);\n\n if (!context) {\n throw new Error(\"useUser must be used within a UserProvider\");\n }\n\n return context as UserContextType<T>;\n};\n\nexport { useUser };\n","import { createContext, ReactNode } from \"react\";\nimport { useQuery, UseQueryResult } from \"@tanstack/react-query\";\nimport { EmptyObject, User } from \"@/types\";\nimport { useAuth } from \"@/react/hooks/useAuth\";\nimport { useToken } from \"@/react/hooks/useToken\";\nimport { JWT, parseJWT } from \"oslo/jwt\";\nimport { useSession } from \"@/react/hooks\";\nimport { AuthContextType } from \"./AuthProvider\";\n\ntype UserContextType<\n T extends Record<string, unknown> & JWT[\"payload\"] = Record<string, unknown> &\n JWT[\"payload\"],\n> = {\n user: User<T> | null;\n isLoading: boolean;\n error: Error | null;\n refetch: () => void;\n} & AuthContextType;\n\nconst UserContext = createContext<UserContextType | null>(null);\n\nconst UserProvider = <T extends EmptyObject>({\n children,\n}: {\n children: ReactNode;\n}) => {\n const { isLoading: authLoading, error: authError } = useAuth();\n const session = useSession();\n const { forwardedTokens, idToken, accessToken, refreshToken } = useToken();\n const { isAuthenticated, signIn, signOut } = useAuth();\n\n const fetchUser = async (): Promise<User<T> | null> => {\n if (!session?.idToken) {\n return null;\n }\n // Implement actual user fetching logic here\n // This is where you'd use the access token to fetch user data from your API\n // For now, we'll return a mock user\n\n const parsedJWT = parseJWT(session.idToken);\n\n if (!parsedJWT) {\n return null;\n }\n\n const user = parsedJWT.payload as User<T>;\n\n return {\n ...user,\n forwardedTokens,\n idToken,\n accessToken,\n refreshToken,\n };\n };\n\n const {\n data: user,\n isLoading: userLoading,\n error: userError,\n refetch,\n }: UseQueryResult<User<T> | null, Error> = useQuery({\n queryKey: [\"user\", session?.accessToken],\n queryFn: fetchUser,\n enabled: !!session?.accessToken, // Only run the query if we have an access token\n });\n\n const isLoading = authLoading || userLoading;\n const error = authError || userError;\n\n return (\n <UserContext.Provider\n value={{\n user: user as User<T>,\n isLoading,\n error,\n refetch,\n isAuthenticated,\n signIn,\n signOut,\n }}\n >\n {children}\n </UserContext.Provider>\n );\n};\n\nexport type { UserContextType };\n\nexport { UserProvider, UserContext };\n","import { AuthContext } from \"@/react/providers\";\nimport { useContext } from \"react\";\n\nconst useAuth = () => {\n const context = useContext(AuthContext);\n\n if (!context) {\n throw new Error(\"useAuth must be used within an AuthProvider\");\n }\n\n return context;\n};\n\nexport { useAuth };\n","import { useContext } from \"react\";\nimport { TokenContext } from \"@/react/providers\";\n\nconst useToken = () => {\n const context = useContext(TokenContext);\n\n if (!context) {\n throw new Error(\"useToken must be used within a TokenProvider\");\n }\n\n return context;\n};\n\nexport { useToken };\n","import { createContext, ReactNode, useMemo } from \"react\";\nimport { useMutation, useQueryClient } from \"@tanstack/react-query\";\nimport { useAuth } from \"@/react/hooks\";\nimport { ForwardedTokens, Tokens } from \"@/types\";\nimport { parseJWT } from \"oslo/jwt\";\nimport { useSession } from \"@/react/hooks\";\n\ntype TokenContextType = {\n accessToken: string | null;\n idToken: string | null;\n forwardedTokens: ForwardedTokens;\n refreshToken: () => Promise<void>;\n isLoading: boolean;\n error: Error | null;\n};\n\nconst TokenContext = createContext<TokenContextType | undefined>(undefined);\n\nconst TokenProvider = ({ children }: { children: ReactNode }) => {\n const { isLoading, error: authError } = useAuth();\n const session = useSession();\n const queryClient = useQueryClient();\n\n const refreshTokenMutation = useMutation({\n mutationFn: async () => {\n // Implement token refresh logic here\n throw new Error(\"Method not implemented.\");\n },\n onSuccess: () => {\n // Invalidate and refetch queries that depend on the auth session\n queryClient.invalidateQueries({ queryKey: [\"session\"] });\n },\n });\n\n const decodeTokens = useMemo(() => {\n if (!session?.idToken) return null;\n\n const parsedJWT = parseJWT(session.idToken);\n\n if (!parsedJWT) return null;\n\n const { forwardedTokens } = parsedJWT.payload as Tokens;\n\n return forwardedTokens;\n }, [session?.idToken]);\n\n const value = useMemo(\n () => ({\n accessToken: session.accessToken || null,\n idToken: session.idToken || null,\n forwardedTokens: decodeTokens || {},\n refreshToken: refreshTokenMutation.mutateAsync,\n isLoading,\n error: (authError || refreshTokenMutation.error) as Error | null,\n }),\n [\n session.accessToken,\n session.idToken,\n decodeTokens,\n refreshTokenMutation.mutateAsync,\n refreshTokenMutation.error,\n isLoading,\n authError,\n ],\n );\n\n return (\n <TokenContext.Provider value={value}>{children}</TokenContext.Provider>\n );\n};\n\nexport type { TokenContextType };\nexport { TokenProvider, TokenContext };\n","\"use client\";\n\nimport {\n createContext,\n useState,\n useEffect,\n useMemo,\n useCallback,\n ReactNode,\n} from \"react\";\nimport { useQuery, useMutation, useQueryClient } from \"@tanstack/react-query\";\nimport { AuthSessionServiceImpl } from \"@/services\";\nimport { Config, DisplayMode } from \"@/types\";\nimport { CivicAuthIframe } from \"@/react/components\";\nimport { ParamsProvider } from \"./ParamsProvider\";\nimport { TokenProvider } from \"./TokenProvider\";\nimport { UserProvider } from \"./UserProvider\";\nimport { SessionProvider } from \"./SessionProvider\";\nimport { DEFAULT_SCOPES } from \"@/constants\";\nimport { authConfig } from \"@/config\";\nimport { LoadingIcon } from \"../components/LoadingIcon\";\n\ntype AuthContextType = {\n signIn: (displayMode?: DisplayMode) => Promise<void>;\n isAuthenticated: boolean;\n isLoading: boolean;\n error: Error | null;\n signOut: () => Promise<void>;\n};\n\ntype AuthProviderProps = {\n children: ReactNode;\n clientId: string;\n redirectUrl?: string;\n nonce?: string;\n config?: Config;\n onSignIn?: (error?: Error) => void; // Updated to include an optional error parameter\n onSignOut?: () => void;\n};\n\nconst AuthContext = createContext<AuthContextType | null>(null);\n\n// Global this object setup (unchanged)\nlet globalThisObject;\nif (typeof window !== \"undefined\") {\n globalThisObject = window;\n} else if (typeof global !== \"undefined\") {\n globalThisObject = global;\n} else {\n globalThisObject = Function(\"return this\")();\n}\nglobalThisObject.globalThis = globalThisObject;\n\nconst AuthProvider = ({\n children,\n clientId,\n redirectUrl: inputRedirectUrl,\n config = authConfig,\n nonce,\n onSignIn,\n onSignOut,\n}: AuthProviderProps) => {\n const [iframeUrl, setIframeUrl] = useState<string | null>(null);\n const [currentUrl, setCurrentUrl] = useState<string | null>(null);\n const [isInIframe, setIsInIframe] = useState(false);\n const [authResponseUrl, setAuthResponseUrl] = useState<string | null>(null);\n const [tokenExchangeInProgress, setTokenExchangeInProgress] = useState(false);\n const [tokenExchangeError, setTokenExchangeError] = useState<Error>();\n const queryClient = useQueryClient();\n\n // check if the current window is in an iframe with the iframe id, and set an isInIframe state\n useEffect(() => {\n if (typeof globalThis.window !== \"undefined\") {\n setCurrentUrl(globalThis.window.location.href);\n let isInIframeVal = false;\n // use the window width to determine if we're in an iframe or not\n try {\n if (globalThis.window?.frameElement?.id === \"civic-auth-iframe\") {\n isInIframeVal = 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 isInIframeVal = false;\n }\n console.log(\"isInIframeVal\", isInIframeVal);\n setIsInIframe(isInIframeVal);\n }\n }, []);\n\n const redirectUrl = useMemo(\n () => (inputRedirectUrl || currentUrl || \"\").split(\"?\")[0],\n [currentUrl, inputRedirectUrl],\n );\n\n const authService = useMemo<AuthSessionServiceImpl | null>(\n () =>\n currentUrl\n ? new AuthSessionServiceImpl(\n clientId,\n redirectUrl,\n config?.oauthServer,\n config?.endpoints,\n )\n : null,\n [currentUrl, clientId, redirectUrl, config],\n );\n\n const {\n data: session,\n isLoading,\n error,\n } = useQuery({\n queryKey: [\"session\"],\n queryFn: async () => {\n const url = new URL(globalThis.window.location.href || \"\");\n console.log(\"AuthProvider useQuery\", { isInIframe, url, authService });\n if (!authService) {\n return { authenticated: false };\n }\n\n // if we have existing tokens, then validate them and return the session data\n // otherwise check if we have a code in the url and exchange it for tokens\n // if we have neither, return undefined\n const existingSessionData = await authService.validateExistingSession();\n if (existingSessionData.authenticated) {\n return existingSessionData;\n }\n const code = url.searchParams.get(\"code\");\n if (code && !isInIframe) {\n try {\n console.log(\"AuthProvider useQuery code\", { isInIframe, code });\n setTokenExchangeInProgress(true);\n const newSession = await authService.tokenExchange(\n globalThis.window.location.href,\n );\n setTokenExchangeInProgress(false);\n onSignIn?.(); // Call onSignIn without an error if successful\n return newSession;\n } catch (error) {\n setTokenExchangeError(error as Error);\n onSignIn?.(\n error instanceof Error ? error : new Error(\"Failed to sign in\"),\n ); // Pass the error to onSignIn\n return { authenticated: false };\n }\n }\n return existingSessionData;\n },\n enabled: !!authService && !!currentUrl && !isInIframe,\n });\n\n const signOutMutation = useMutation({\n mutationFn: async () => {\n // Implement signOut logic here\n authService?.updateSessionData({});\n setAuthResponseUrl(null);\n onSignOut?.();\n // clear session data and cookies\n },\n onSuccess: () => {\n queryClient.setQueryData([\"session\"], null);\n },\n });\n\n const signIn = useCallback(\n async (overrideDisplayMode: DisplayMode = \"iframe\") => {\n if (!authService) return;\n\n const url = await authService.getAuthorizationUrl(\n // This is the default scope. We will eventually pull this from the partner dashboard\n DEFAULT_SCOPES,\n overrideDisplayMode,\n nonce,\n );\n\n // For iframe mode we need popups to not be blocked because the login app will try to open IDP login in a popup\n if (overrideDisplayMode === \"iframe\") {\n setIframeUrl(url);\n return;\n }\n authService.loadAuthorizationUrl(url, overrideDisplayMode);\n },\n [authService, nonce],\n );\n\n const isAuthenticated = useMemo(\n () => (session ? session.authenticated : false),\n [session],\n );\n\n useEffect(() => {\n if (!authService || !authResponseUrl) return;\n const url = new URL(authResponseUrl);\n const code = url.searchParams.get(\"code\");\n console.log(\"AuthProvider useEffect code\", {\n isAuthenticated,\n code,\n tokenExchangeInProgress,\n isInIframe,\n });\n if (code && !isAuthenticated && !tokenExchangeInProgress && !isInIframe) {\n try {\n setTokenExchangeInProgress(true);\n authService\n .tokenExchange(authResponseUrl)\n .then((newSession) => {\n queryClient.setQueryData([\"session\"], newSession);\n setIframeUrl(null); // Close the iframe\n onSignIn?.(); // Call onSignIn without an error if successful\n })\n .catch((error) => {\n setTokenExchangeError(error as Error);\n })\n .finally(() => {\n setTokenExchangeInProgress(false);\n });\n } catch (error) {\n setTokenExchangeInProgress(false);\n onSignIn?.(\n error instanceof Error ? error : new Error(\"Failed to sign in\"),\n ); // Pass the error to onSignIn\n }\n }\n }, [\n authService,\n onSignIn,\n queryClient,\n isAuthenticated,\n authResponseUrl,\n tokenExchangeInProgress,\n isInIframe,\n ]);\n\n const value = useMemo(\n () => ({\n isLoading,\n error: error as Error | null,\n signOut: signOutMutation.mutate,\n isAuthenticated,\n signIn,\n }),\n [isLoading, error, signOutMutation.mutate, isAuthenticated, signIn],\n );\n return (\n <AuthContext.Provider\n value={{\n ...value,\n signOut: async () => {\n await signOutMutation.mutateAsync();\n },\n }}\n >\n <ParamsProvider\n clientId={clientId}\n redirectUrl={redirectUrl}\n config={config}\n nonce={nonce}\n >\n <SessionProvider session={session}>\n <TokenProvider>\n <UserProvider>\n {!isInIframe && iframeUrl && !session?.authenticated && (\n <CivicAuthIframe\n authUrl={iframeUrl}\n redirectUri={redirectUrl}\n setAuthResponseUrl={setAuthResponseUrl}\n onClose={() => setIframeUrl(null)}\n />\n )}\n {(tokenExchangeInProgress ||\n tokenExchangeError ||\n isLoading ||\n isInIframe) && (\n <div className=\"absolute left-0 top-0 z-[9999] flex h-screen w-screen items-center justify-center bg-white\">\n {\" \"}\n <div className=\"absolute inset-0 flex items-center justify-center bg-white\">\n {tokenExchangeError ? (\n <div>Error: {tokenExchangeError.message}</div>\n ) : (\n <LoadingIcon />\n )}\n </div>\n </div>\n )}\n {children}\n </UserProvider>\n </TokenProvider>\n </SessionProvider>\n </ParamsProvider>\n </AuthContext.Provider>\n );\n};\n\nexport type { AuthContextType, AuthProviderProps };\n\nexport { AuthProvider, AuthContext };\n","import { UserInfoService, Endpoints } from \"@/types\";\n\nexport class UserInfoServiceImpl implements UserInfoService {\n constructor(private endpoints: Endpoints) {}\n\n async getUserInfo<T>(accessToken: string): Promise<T> {\n // Implement user info request logic\n return {\n id: \"user123\",\n name: \"John Doe\",\n email: \"john@example.com\",\n picture: \"https://example.com/john.jpg\",\n given_name: \"John\",\n family_name: \"Doe\",\n created_at: new Date(),\n updated_at: new Date(),\n country: \"US\",\n accessToken,\n } as T;\n }\n}\n","import {\n AuthSessionService,\n DisplayMode,\n UserInfoService,\n SessionData,\n OIDCTokenResponseBody,\n UnknownObject,\n Endpoints,\n} from \"../types\";\nimport { UserInfoServiceImpl } from \"./UserInfoService\";\nimport { OAuth2Client, generateCodeVerifier } from \"oslo/oauth2\";\nimport * as jose from \"jose\";\nimport {\n displayModeFromState,\n generateState,\n getIssuerVariations,\n getOauthEndpoints,\n} from \"@/lib/oauth\";\nimport { isPopupBlocked } from \"@/utils\";\n\nexport class AuthSessionServiceImpl implements AuthSessionService {\n private _endpoints: Endpoints | undefined;\n private _oauth2Client: OAuth2Client | undefined;\n private _userInfoService: UserInfoService | undefined;\n private codeVerifier: string | undefined = undefined;\n private state: string | undefined = undefined;\n\n constructor(\n readonly clientId: string,\n readonly redirectUrl: string,\n readonly oauthServer: string,\n inputEndpoints?: Endpoints | undefined,\n ) {\n this.codeVerifier = generateCodeVerifier();\n this._endpoints = inputEndpoints;\n }\n private async getUserInfoService(): Promise<UserInfoService> {\n if (this._userInfoService) {\n return this._userInfoService;\n }\n const endpoints = await this.getEndpoints();\n\n this._userInfoService = new UserInfoServiceImpl(endpoints);\n return this._userInfoService;\n }\n private async getEndpoints(): Promise<Endpoints> {\n if (this._endpoints) {\n return this._endpoints;\n }\n this._endpoints = await getOauthEndpoints(this.oauthServer);\n return this._endpoints;\n }\n\n private async getOauth2Client() {\n if (this._oauth2Client) {\n return this._oauth2Client;\n }\n const endpoints = await this.getEndpoints();\n this._oauth2Client = new OAuth2Client(\n this.clientId,\n endpoints.auth,\n endpoints.token,\n // this\n { redirectURI: this.redirectUrl },\n );\n return this._oauth2Client;\n }\n\n getSessionData(): SessionData {\n return JSON.parse(\n localStorage.getItem(`civic-auth:${this.clientId}`) || \"{}\",\n ) as SessionData;\n }\n\n updateSessionData(data: Partial<SessionData>): void {\n localStorage.setItem(\n `civic-auth:${this.clientId}`,\n JSON.stringify({ ...data }),\n );\n }\n\n async getAuthorizationUrl(\n scopes: string[],\n displayMode: DisplayMode,\n nonce?: string,\n ): Promise<string> {\n const state = generateState(displayMode);\n this.state = state;\n const existingSessionData = this.getSessionData();\n this.updateSessionData({\n ...existingSessionData,\n codeVerifier: this.codeVerifier,\n displayMode,\n });\n const oauth2Client = await this.getOauth2Client();\n const oAuthUrl = await oauth2Client.createAuthorizationURL({\n state,\n codeVerifier: this.codeVerifier,\n codeChallengeMethod: \"S256\",\n scopes,\n });\n if (nonce) {\n // nonce isn't supported by oslo, so we add it manually\n oAuthUrl.searchParams.append(\"nonce\", nonce);\n }\n return oAuthUrl.toString();\n }\n\n // TODO fix the Window reference\n loadAuthorizationUrl(authorizationURL: string, displayMode: DisplayMode) {\n switch (displayMode) {\n case \"iframe\":\n // Implement iframe logic\n break;\n case \"redirect\":\n window.location.href = authorizationURL;\n break;\n case \"new_tab\":\n window.open(authorizationURL, \"_blank\");\n break;\n case \"custom_tab\":\n // Implement custom tab logic (might require native app integration)\n break;\n }\n }\n\n async init(): Promise<void> {\n this.updateSessionData({ authenticated: false });\n }\n\n determineDisplayMode(displayMode: DisplayMode): DisplayMode {\n // If popups are blocked and we're in iframe mode, we need to override the display mode to redirect\n if (isPopupBlocked() && displayMode === \"iframe\") {\n displayMode = \"redirect\";\n }\n // TODO: Add additional checks to determine the display mode for new_mode if new tabs are blocked.\n return displayMode;\n }\n\n async signIn(\n displayMode: DisplayMode,\n scopes: string[],\n nonce: string,\n ): Promise<void> {\n const authorizationURL = await this.getAuthorizationUrl(\n scopes,\n displayMode,\n nonce,\n );\n\n this.loadAuthorizationUrl(authorizationURL, displayMode);\n }\n\n async tokenExchange(responseUrl: string): Promise<SessionData> {\n let session = this.getSessionData();\n if (!session.authenticated) {\n const url = new URL(responseUrl);\n const authorizationCode = url.searchParams.get(\"code\");\n const returnedState = url.searchParams.get(\"state\");\n if (!authorizationCode || !returnedState) {\n throw new Error(\"Invalid authorization response\");\n }\n const codeVerifier = this.getSessionData().codeVerifier as string;\n const oauth2Client = await this.getOauth2Client();\n const tokens =\n await oauth2Client.validateAuthorizationCode<OIDCTokenResponseBody>(\n authorizationCode,\n {\n codeVerifier,\n },\n );\n\n // Validate relevant tokens\n try {\n await this.validateTokens(tokens);\n } catch (error) {\n console.error(\"tokenExchange tokens\", { error, tokens });\n throw new Error(\n `OIDC tokens validation failed: ${(error as Error).message}`,\n );\n }\n const parsedDisplayMode = displayModeFromState(\n returnedState,\n session.displayMode,\n );\n // Update session with authentication result\n session = {\n ...session,\n displayMode: parsedDisplayMode,\n idToken: tokens.id_token,\n authenticated: true,\n state: returnedState,\n accessToken: tokens.access_token,\n refreshToken: tokens.refresh_token,\n expiresIn: tokens.expires_in,\n };\n this.updateSessionData(session);\n }\n if (session.displayMode === \"new_tab\") {\n // Close the popup window\n window.close();\n } else if (session.displayMode === \"redirect\") {\n // TODO: Determine if there is anything additional to do here\n }\n return session;\n }\n\n async refreshToken(): Promise<SessionData> {\n const sessionData = this.getSessionData();\n if (!sessionData.refreshToken) {\n throw new Error(\"No refresh token available\");\n }\n const oauth2Client = await this.getOauth2Client();\n const tokens = await oauth2Client.refreshAccessToken<OIDCTokenResponseBody>(\n sessionData.refreshToken,\n );\n\n const session = {\n ...sessionData,\n idToken: tokens.id_token,\n authenticated: true,\n accessToken: tokens.access_token,\n refreshToken: tokens.refresh_token,\n expiresIn: tokens.expires_in,\n };\n\n this.updateSessionData(session);\n return session;\n }\n\n async getUserInfo<T extends UnknownObject>(): Promise<T> {\n const sessionData = this.getSessionData();\n if (!sessionData.accessToken) {\n throw new Error(\"No access token available\");\n }\n const userInfoService = await this.getUserInfoService();\n return userInfoService.getUserInfo<T>(sessionData.accessToken);\n }\n\n /**\n * Uses the jose library to validate a JWT token using the OAuth JWKS endpoint\n * @param {string} token\n * @returns {Promise<jose.JWTPayload>}\n * @throws {Error} if the token is invalid\n */\n async validateTokens(\n tokens: OIDCTokenResponseBody,\n ): Promise<\n Record<\"idToken\" | \"accessToken\" | \"refreshToken\", jose.JWTPayload>\n > {\n const endpoints = await this.getEndpoints();\n const JWKS = jose.createRemoteJWKSet(new URL(endpoints.jwks));\n const returnPayload: Record<string, jose.JWTPayload> = {};\n // const payload = {};\n // validate the ID token\n console.log(\"issuer\", getIssuerVariations(this.oauthServer));\n const idTokenResponse = await jose.jwtVerify(tokens.id_token, JWKS, {\n issuer: getIssuerVariations(this.oauthServer),\n audience: this.clientId,\n });\n returnPayload.idToken = idTokenResponse.payload;\n // validate the access token\n const accessTokenResponse = await jose.jwtVerify(\n tokens.access_token,\n JWKS,\n {\n issuer: getIssuerVariations(this.oauthServer),\n },\n );\n returnPayload.accessToken = accessTokenResponse.payload;\n\n if (tokens.refresh_token) {\n // validate the refresh token\n const refreshResponse = await jose.jwtVerify(tokens.refresh_token, JWKS, {\n issuer: getIssuerVariations(this.oauthServer),\n });\n returnPayload.refreshToken = refreshResponse.payload;\n }\n return returnPayload;\n }\n\n async validateExistingSession(): Promise<SessionData> {\n const sessionData = this.getSessionData();\n try {\n if (!sessionData.idToken || !sessionData.accessToken) {\n const unAuthenticatedSession = { ...sessionData, authenticated: false };\n this.updateSessionData(unAuthenticatedSession);\n return unAuthenticatedSession;\n }\n await this.validateTokens({\n id_token: sessionData.idToken as string,\n access_token: sessionData.accessToken as string,\n refresh_token: sessionData.refreshToken as string,\n });\n sessionData.authenticated = true;\n return sessionData;\n } catch (error) {\n console.warn(\"Failed to validate existing tokens\", error);\n const unAuthenticatedSession = { ...sessionData, authenticated: false };\n this.updateSessionData(unAuthenticatedSession);\n return unAuthenticatedSession;\n }\n }\n}\n","import { DisplayMode, Endpoints, OpenIdConfiguration } from \"@/types\";\nimport { v4 as uuid } from \"uuid\";\n\nexport const getIssuerVariations = (issuer: string): string[] => {\n const issuerWithoutSlash = issuer.endsWith(\"/\")\n ? issuer.slice(0, issuer.length - 1)\n : issuer;\n const issuerWithSlash = `${issuerWithoutSlash}/`;\n return [issuerWithoutSlash, issuerWithSlash];\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 = (displayMode: DisplayMode): string => {\n const jsonString = JSON.stringify({\n uuid: uuid(),\n displayMode,\n });\n return Buffer.from(jsonString).toString(\"base64\");\n};\n\n/**\n * parses the state string from the OAuth2 flow, decoding the display mode too\n * @param state\n * @returns { uuid: string, displayMode: DisplayMode }\n */\nconst displayModeFromState = (\n state: string,\n sessionDisplayMode: DisplayMode | undefined,\n): DisplayMode | undefined => {\n try {\n const jsonString = Buffer.from(state, \"base64\").toString();\n return JSON.parse(jsonString).displayMode;\n } catch (_e) {\n return sessionDisplayMode;\n }\n};\n\nexport { getOauthEndpoints, displayModeFromState, generateState };\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\nexport { cn, isPopupBlocked };\n","import React, { useCallback, useEffect, useRef, useState } from \"react\";\nimport { LoadingIcon } from \"./LoadingIcon\";\n\ntype CivicAuthIframeProps = {\n authUrl: string;\n redirectUri: string;\n setAuthResponseUrl: (authResponse: string) => void;\n onClose: () => void;\n};\n\nconst CloseIcon = () => (\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n width=\"24\"\n height=\"24\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n className=\"lucide lucide-x\"\n >\n <path d=\"M18 6 6 18\" />\n <path d=\"m6 6 12 12\" />\n </svg>\n);\n\nconst IFRAME_ID = \"civic-auth-iframe\";\n\nconst CivicAuthIframe = ({\n authUrl,\n redirectUri,\n setAuthResponseUrl,\n onClose,\n}: CivicAuthIframeProps) => {\n const iframeRef = useRef<HTMLIFrameElement>(null);\n const [isLoading, setIsLoading] = useState(true);\n const processIframeUrl = useCallback(() => {\n if (iframeRef.current && iframeRef.current.contentWindow) {\n try {\n const iframeUrl = iframeRef.current.contentWindow.location.href;\n if (iframeUrl.startsWith(redirectUri)) {\n setAuthResponseUrl(iframeUrl);\n\n return true; // Successfully processed the URL\n }\n } catch {\n // If we get here, the iframe hasn't redirected to our origin yet\n console.log(\"Waiting for redirect...\");\n }\n }\n return false; // Haven't processed the URL yet\n }, [redirectUri, setAuthResponseUrl]);\n\n const intervalId = useRef<NodeJS.Timeout>();\n // useEffect(() => {\n // intervalId.current = setInterval(() => {\n // if (processIframeUrl()) {\n // clearInterval(intervalId.current);\n // }\n // }, 500);\n // return () => clearInterval(intervalId.current);\n // }, [processIframeUrl, redirectUri, setAuthResponseUrl]);\n\n // handle Escape\n useEffect(() => {\n const handleEscape = (event: KeyboardEvent) => {\n if (event.key === \"Escape\") {\n onClose();\n }\n };\n\n window.addEventListener(\"keydown\", handleEscape);\n\n return () => window.removeEventListener(\"keydown\", handleEscape);\n });\n\n const handleIframeLoad = () => {\n setIsLoading(false);\n console.log(\"handleIframeLoad\");\n if (processIframeUrl() && intervalId.current) {\n clearInterval(intervalId.current);\n }\n };\n\n return (\n <div\n className=\"absolute left-0 top-0 z-[9999] flex h-screen w-screen items-center justify-center bg-neutral-950 bg-opacity-50\"\n onClick={onClose}\n >\n <div\n className=\"relative rounded-3xl bg-white p-6 shadow-lg\"\n onClick={(e) => e.stopPropagation()}\n >\n <button\n className=\"absolute right-4 top-4 flex cursor-pointer items-center justify-center border-none bg-transparent p-1 text-neutral-400\"\n onClick={onClose}\n >\n <CloseIcon />\n </button>\n\n {isLoading && (\n <div className=\"absolute inset-0 flex items-center justify-center rounded-3xl bg-neutral-100\">\n <LoadingIcon />\n </div>\n )}\n\n <iframe\n id={IFRAME_ID}\n ref={iframeRef}\n src={authUrl}\n className=\"h-48 w-80 border-none\"\n onLoad={handleIframeLoad}\n />\n </div>\n </div>\n );\n};\n\nexport type { CivicAuthIframeProps };\n\nexport { CivicAuthIframe };\n","const LoadingIcon = () => (\n <div role=\"status\">\n <svg\n aria-hidden=\"true\"\n className=\"inline h-8 w-8 animate-spin fill-neutral-600 text-neutral-200 dark:fill-neutral-300 dark:text-neutral-600\"\n viewBox=\"0 0 100 101\"\n fill=\"none\"\n xmlns=\"http://www.w3.org/2000/svg\"\n >\n <path\n d=\"M100 50.5908C100 78.2051 77.6142 100.591 50 100.591C22.3858 100.591 0 78.2051 0 50.5908C0 22.9766 22.3858 0.59082 50 0.59082C77.6142 0.59082 100 22.9766 100 50.5908ZM9.08144 50.5908C9.08144 73.1895 27.4013 91.5094 50 91.5094C72.5987 91.5094 90.9186 73.1895 90.9186 50.5908C90.9186 27.9921 72.5987 9.67226 50 9.67226C27.4013 9.67226 9.08144 27.9921 9.08144 50.5908Z\"\n fill=\"currentColor\"\n />\n <path\n d=\"M93.9676 39.0409C96.393 38.4038 97.8624 35.9116 97.0079 33.5539C95.2932 28.8227 92.871 24.3692 89.8167 20.348C85.8452 15.1192 80.8826 10.7238 75.2124 7.41289C69.5422 4.10194 63.2754 1.94025 56.7698 1.05124C51.7666 0.367541 46.6976 0.446843 41.7345 1.27873C39.2613 1.69328 37.813 4.19778 38.4501 6.62326C39.0873 9.04874 41.5694 10.4717 44.0505 10.1071C47.8511 9.54855 51.7191 9.52689 55.5402 10.0491C60.8642 10.7766 65.9928 12.5457 70.6331 15.2552C75.2735 17.9648 79.3347 21.5619 82.5849 25.841C84.9175 28.9121 86.7997 32.2913 88.1811 35.8758C89.083 38.2158 91.5421 39.6781 93.9676 39.0409Z\"\n fill=\"currentFill\"\n />\n </svg>\n <span className=\"sr-only\">Loading...</span>\n </div>\n);\n\nexport { LoadingIcon };\n","import { useAuth, useUser } from \"@/react/hooks\";\nimport { DisplayMode } from \"@/types\";\nimport { cn } from \"@/utils\";\nimport { useEffect, useState } from \"react\";\n\nconst ChevronDown = () => (\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n width=\"24\"\n height=\"24\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n className=\"lucide lucide-chevron-down\"\n >\n <path d=\"m6 9 6 6 6-6\" />\n </svg>\n);\n\nconst ChevronUp = () => (\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n width=\"24\"\n height=\"24\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n className=\"lucide lucide-chevron-up\"\n >\n <path d=\"m18 15-6-6-6 6\" />\n </svg>\n);\n\nconst UserButton = ({\n displayMode,\n className,\n}: {\n displayMode?: DisplayMode;\n className?: string;\n}) => {\n const [isOpen, setIsOpen] = useState(false);\n const { signIn, isAuthenticated, signOut } = useAuth();\n const { user } = useUser();\n\n // close the dropdown when the user presses the escape key\n useEffect(() => {\n const handleEscape = (event: KeyboardEvent) => {\n if (event.key === \"Escape\") {\n setIsOpen(false);\n }\n };\n\n if (isOpen) {\n window.addEventListener(\"keydown\", handleEscape);\n }\n\n return () => {\n window.removeEventListener(\"keydown\", handleEscape);\n };\n }, [isOpen]);\n\n // close the dropdown when the user clicks outside of it\n useEffect(() => {\n const handleClick = (event: MouseEvent) => {\n const target = event.target as HTMLElement;\n if (!target.closest(\"#civic-dropdown-container\")) {\n setIsOpen(false);\n }\n };\n\n if (isOpen) {\n window.addEventListener(\"click\", handleClick);\n }\n\n return () => {\n window.removeEventListener(\"click\", handleClick);\n };\n }, [isOpen]);\n\n // set the dropdown to false when the user signs out\n useEffect(() => {\n if (!isAuthenticated) {\n setIsOpen(false);\n }\n }, [isAuthenticated]);\n\n if (isAuthenticated) {\n return (\n <div className=\"relative\" id=\"civic-dropdown-container\">\n <button\n className={cn(\n \"flex w-full items-center justify-between gap-2 rounded-full border border-neutral-500 px-3 py-2 text-neutral-500 transition-colors hover:bg-neutral-200 hover:bg-opacity-50\",\n className,\n )}\n onClick={() => setIsOpen((isOpen) => !isOpen)}\n >\n {user?.picture ? (\n <span className=\"relative flex h-10 w-10 shrink-0 gap-2 overflow-hidden rounded-full\">\n <img\n className=\"h-full w-full object-cover\"\n src={user.picture}\n alt={user?.name || user?.email}\n />\n </span>\n ) : (\n <div />\n )}\n\n <span>{user?.name || user?.email}</span>\n\n {isOpen ? <ChevronUp /> : <ChevronDown />}\n </button>\n <div\n className={\n isOpen\n ? \"absolute right-0 mt-2 w-full rounded-lg bg-white py-2 text-neutral-500 shadow-xl\"\n : \"hidden\"\n }\n >\n <ul>\n <li>\n <button\n className=\"block w-full px-4 py-2 transition-colors hover:bg-neutral-200 hover:bg-opacity-50\"\n onClick={() => signOut()}\n >\n Logout\n </button>\n </li>\n </ul>\n </div>\n </div>\n );\n }\n\n return (\n <button\n className={cn(\n \"rounded-full border border-neutral-500 px-3 py-2 transition-colors hover:bg-neutral-200 hover:bg-opacity-50\",\n className,\n )}\n onClick={() => signIn(displayMode)}\n >\n Sign in\n </button>\n );\n};\n\nexport { UserButton };\n","import { createContext, ReactNode } from \"react\";\nimport { Config } from \"@/types\";\n\ntype ParamsProviderProps = {\n children: ReactNode;\n clientId: string;\n redirectUrl?: string;\n nonce?: string;\n config?: Config;\n};\n\ntype ParamsContextType = Omit<ParamsProviderProps, \"children\">;\n\nconst ParamsContext = createContext<ParamsContextType | null>(null);\n\nconst ParamsProvider = ({\n children,\n clientId,\n redirectUrl,\n config,\n nonce,\n}: ParamsProviderProps) => {\n // Not sure if it's valid to use the setAuthResponse callback rather than a post-message\n const value = {\n clientId,\n redirectUrl,\n config,\n nonce,\n };\n return (\n <ParamsContext.Provider value={value}>{children}</ParamsContext.Provider>\n );\n};\n\nexport type { ParamsProviderProps, ParamsContextType };\n\nexport { ParamsProvider, ParamsContext };\n","import { SessionData } from \"@/types\";\nimport React, { createContext, ReactNode } from \"react\";\n\nconst defaultSession: SessionData = {\n authenticated: false,\n idToken: undefined,\n accessToken: undefined,\n displayMode: \"iframe\",\n};\n\n// Context for exposing session specifically to the TokenProvider\nconst SessionContext = createContext<SessionData>(defaultSession);\n\ntype SessionContextType = {\n children: ReactNode;\n session?: SessionData;\n};\n\nconst SessionProvider = ({ children, session }: SessionContextType) => (\n <SessionContext.Provider value={session || defaultSession}>\n {children}\n </SessionContext.Provider>\n);\n\nexport type { SessionContextType };\nexport { SessionProvider, SessionContext };\n","export const DEFAULT_SCOPES = [\"openid\", \"profile\", \"email\", \"forwardedTokens\"];\n","import { Config } from \"@/types\";\n\nexport const authConfig: Config = {\n // TODO change this to the production URL once we're out of beta\n oauthServer: \"https://auth-dev.civic.com/oauth/\",\n};\n","import { AuthProvider, AuthProviderProps } from \"./AuthProvider\";\nimport { QueryClient, QueryClientProvider } from \"@tanstack/react-query\";\n\nconst queryClient = new QueryClient();\n\ntype CivicProviderProps = AuthProviderProps;\n\nconst CivicProvider = ({ children, ...props }: CivicProviderProps) => {\n return (\n <QueryClientProvider client={queryClient}>\n <AuthProvider {...props}>{children}</AuthProvider>\n </QueryClientProvider>\n );\n};\n\nexport { CivicProvider };\n","import { ParamsContext } from \"@/react/providers\";\nimport { useContext } from \"react\";\n\nconst useParams = () => {\n const context = useContext(ParamsContext);\n\n if (!context) {\n throw new Error(\"useParams must be used within an ParamsProvider\");\n }\n\n return context;\n};\n\nexport { useParams };\n","import { useContext } from \"react\";\nimport { SessionContext } from \"@/react/providers\";\n\n// TokenProvider will use this internal context to access session\nconst useSession = () => {\n const context = useContext(SessionContext);\n if (!context) {\n throw new Error(\"useSession must be used within an SessionProvider\");\n }\n return context;\n};\n\nexport { useSession };\n"],"mappings":"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","names":["useContext","useContext","useContext","user","createContext","parseJWT","jsx","createContext","queryClient","parseJWT","createContext","useState","useEffect","useMemo","useCallback","useQuery","useMutation","useQueryClient","jsx","jsx","jsxs","useEffect","useState","jsx","jsxs","isOpen","createContext","jsx","createContext","jsx","jsx","jsxs","createContext","useState","queryClient","useQueryClient","useEffect","useMemo","useQuery","error","useMutation","useCallback","jsx","useContext","useContext","useContext","useContext"]}
1
+ {"version":3,"sources":["../src/react/hooks/useUser.tsx","../src/react/providers/UserProvider.tsx","../src/react/hooks/useAuth.tsx","../src/react/hooks/useToken.tsx","../src/react/providers/TokenProvider.tsx","../src/lib/jwt.ts","../src/shared/AuthProvider.tsx","../src/services/UserInfoService.ts","../src/services/SessionService.ts","../src/lib/oauth.ts","../src/utils.ts","../src/constants.ts","../src/react/components/CivicAuthIframe.tsx","../src/react/components/CivicAuthIframeModal.tsx","../src/react/components/LoadingIcon.tsx","../src/react/components/CloseIcon.tsx","../src/react/components/UserButton.tsx","../src/react/components/SignInButton.tsx","../src/react/components/SignOutButton.tsx","../src/lib/logger.ts","../src/nextjs/config.ts","../src/react/components/NextLogOut.tsx","../src/react/providers/SessionProvider.tsx","../src/config.ts","../src/lib/windowUtil.ts","../src/shared/CivicAuthProvider.tsx","../src/react/providers/NextAuthProvider.tsx","../src/react/hooks/useUserCookie.ts","../src/lib/cookies.ts","../src/react/hooks/useSession.tsx"],"sourcesContent":["\"use client\";\nimport { useContext } from \"react\";\nimport { UserContext, UserContextType } from \"@/react/providers\";\n\nconst useUser = <\n T extends Record<string, unknown> = Record<string, never>,\n>(): UserContextType<T> => {\n const context = useContext(UserContext);\n\n if (!context) {\n throw new Error(\"useUser must be used within a UserProvider\");\n }\n\n return context as UserContextType<T>;\n};\n\nexport { useUser };\n","\"use client\";\nimport { createContext, ReactNode } from \"react\";\nimport { useQuery, UseQueryResult } from \"@tanstack/react-query\";\nimport { EmptyObject, User, UserInfoService } from \"@/types\";\nimport { useAuth } from \"@/react/hooks/useAuth\";\nimport { useToken } from \"@/react/hooks/useToken\";\nimport { JWT } from \"oslo/jwt\";\nimport { useSession } from \"@/react/hooks\";\nimport { AuthContextType } from \"../../shared/AuthProvider\";\n\ntype UserContextType<\n T extends Record<string, unknown> & JWT[\"payload\"] = Record<string, unknown> &\n JWT[\"payload\"],\n> = {\n user: User<T> | null;\n} & Omit<AuthContextType, \"isAuthenticated\">;\n\nconst UserContext = createContext<UserContextType | null>(null);\n\nconst UserProvider = <T extends EmptyObject>({\n children,\n userInfoService,\n}: {\n children: ReactNode;\n userInfoService: UserInfoService | undefined;\n}) => {\n const { isLoading: authLoading, error: authError } = useAuth();\n const session = useSession();\n const { forwardedTokens, idToken, accessToken, refreshToken } = useToken();\n const { signIn, signOut } = useAuth();\n\n const fetchUser = async (): Promise<User<T> | null> => {\n if (!accessToken || !userInfoService) {\n return null;\n }\n const user = await userInfoService?.getUserInfo<T>(accessToken, idToken);\n if (!user) {\n return null;\n }\n return {\n ...user,\n forwardedTokens,\n idToken,\n accessToken,\n refreshToken,\n };\n };\n\n const {\n data: user,\n isLoading: userLoading,\n error: userError,\n }: UseQueryResult<User<T> | null, Error> = useQuery({\n queryKey: [\"user\", session?.idToken],\n queryFn: fetchUser,\n enabled: !!session?.idToken, // Only run the query if we have an access token\n });\n\n const isLoading = authLoading || userLoading;\n const error = authError || userError;\n\n return (\n <UserContext.Provider\n value={{\n user: user ?? null,\n isLoading,\n error,\n signIn,\n signOut,\n }}\n >\n {children}\n </UserContext.Provider>\n );\n};\n\nexport type { UserContextType };\n\nexport { UserProvider, UserContext };\n","\"use client\";\nimport { AuthContext } from \"@/react/providers\";\nimport { useContext } from \"react\";\n\nconst useAuth = () => {\n const context = useContext(AuthContext);\n\n if (!context) {\n throw new Error(\"useAuth must be used within an AuthProvider\");\n }\n\n return context;\n};\n\nexport { useAuth };\n","\"use client\";\nimport { useContext } from \"react\";\nimport { TokenContext } from \"@/react/providers\";\n\nconst useToken = () => {\n const context = useContext(TokenContext);\n\n if (!context) {\n throw new Error(\"useToken must be used within a TokenProvider\");\n }\n\n return context;\n};\n\nexport { useToken };\n","\"use client\";\nimport { createContext, ReactNode, useMemo } from \"react\";\nimport { useMutation, useQueryClient } from \"@tanstack/react-query\";\nimport { useAuth } from \"@/react/hooks\";\nimport { ForwardedTokens, IdToken } from \"@/types\";\nimport { parseJWT } from \"oslo/jwt\";\nimport { useSession } from \"@/react/hooks\";\nimport { convertForwardedTokenFormat } from \"@/lib/jwt.ts\";\n\ntype TokenContextType = {\n accessToken: string | null;\n idToken: string | null;\n forwardedTokens: ForwardedTokens;\n refreshToken: () => Promise<void>;\n isLoading: boolean;\n error: Error | null;\n};\n\nconst TokenContext = createContext<TokenContextType | undefined>(undefined);\n\nconst TokenProvider = ({ children }: { children: ReactNode }) => {\n const { isLoading, error: authError } = useAuth();\n const session = useSession();\n const queryClient = useQueryClient();\n\n const refreshTokenMutation = useMutation({\n mutationFn: async () => {\n // Implement token refresh logic here\n throw new Error(\"Method not implemented.\");\n },\n onSuccess: () => {\n // Invalidate and refetch queries that depend on the auth session\n queryClient.invalidateQueries({ queryKey: [\"session\"] });\n },\n });\n\n const decodeTokens = useMemo(() => {\n if (!session?.idToken) return null;\n\n const parsedJWT = parseJWT(session.idToken) as IdToken | null;\n\n if (!parsedJWT) return null;\n\n const { forwardedTokens } = parsedJWT.payload;\n\n return forwardedTokens\n ? convertForwardedTokenFormat(forwardedTokens)\n : null;\n }, [session?.idToken]);\n\n const value = useMemo(\n () => ({\n accessToken: session.accessToken || null,\n idToken: session.idToken || null,\n forwardedTokens: decodeTokens || {},\n refreshToken: refreshTokenMutation.mutateAsync,\n isLoading,\n error: (authError || refreshTokenMutation.error) as Error | null,\n }),\n [\n session.accessToken,\n session.idToken,\n decodeTokens,\n refreshTokenMutation.mutateAsync,\n refreshTokenMutation.error,\n isLoading,\n authError,\n ],\n );\n\n return (\n <TokenContext.Provider value={value}>{children}</TokenContext.Provider>\n );\n};\n\nexport type { TokenContextType };\nexport { TokenProvider, TokenContext };\n","import { ForwardedTokens, ForwardedTokensJWT } from \"@/types.ts\";\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","\"use client\";\nimport {\n createContext,\n useState,\n useEffect,\n useMemo,\n useCallback,\n ReactNode,\n useRef,\n} from \"react\";\nimport { useQuery, useMutation, useQueryClient } from \"@tanstack/react-query\";\nimport { AuthSessionServiceImpl } from \"@/services\";\nimport { Config, DisplayMode, UserInfoService } from \"@/types\";\nimport { CivicAuthIframeModal } from \"@/react/components\";\nimport { TokenProvider } from \"../react/providers/TokenProvider\";\nimport { UserProvider } from \"../react/providers/UserProvider\";\nimport { SessionProvider } from \"../react/providers/SessionProvider\";\nimport { DEFAULT_SCOPES } from \"@/constants\";\nimport { authConfig } from \"@/config\";\nimport { LoadingIcon } from \"../react/components/LoadingIcon\";\nimport { isWindowInIframe } from \"@/lib/windowUtil\";\n\ntype AuthContextType = {\n signIn: (displayMode?: DisplayMode) => Promise<void>;\n isAuthenticated: boolean;\n isLoading: boolean;\n error: Error | null;\n signOut: () => Promise<void>;\n};\n\ntype AuthProviderProps = {\n children: ReactNode;\n clientId: string;\n redirectUrl?: string;\n nonce?: string;\n config?: Config;\n onSignIn?: (error?: Error) => void; // Updated to include an optional error parameter\n onSignOut?: () => void;\n authServiceImpl?: AuthSessionServiceImpl;\n serverSideTokenExchange?: boolean;\n};\n\nconst AuthContext = createContext<AuthContextType | null>(null);\n\n// Global this object setup (unchanged)\nlet globalThisObject;\nif (typeof window !== \"undefined\") {\n globalThisObject = window;\n} else if (typeof global !== \"undefined\") {\n globalThisObject = global;\n} else {\n globalThisObject = Function(\"return this\")();\n}\nglobalThisObject.globalThis = globalThisObject;\n\nconst AuthProvider = ({\n children,\n clientId,\n redirectUrl: inputRedirectUrl,\n config = authConfig,\n nonce,\n onSignIn,\n onSignOut,\n authServiceImpl,\n serverSideTokenExchange,\n}: AuthProviderProps) => {\n const [iframeUrl, setIframeUrl] = useState<string | null>(null);\n const [currentUrl, setCurrentUrl] = useState<string | null>(null);\n const [isInIframe, setIsInIframe] = useState(false);\n const [authResponseUrl, setAuthResponseUrl] = useState<string | null>(null);\n const [tokenExchangeError, setTokenExchangeError] = useState<Error>();\n const queryClient = useQueryClient();\n const iframeRef = useRef<HTMLIFrameElement>(null);\n\n // check if the current window is in an iframe with the iframe id, and set an isInIframe state\n useEffect(() => {\n if (typeof globalThis.window !== \"undefined\") {\n setCurrentUrl(globalThis.window.location.href);\n const isInIframeVal = isWindowInIframe(globalThis.window);\n setIsInIframe(isInIframeVal);\n }\n }, []);\n\n const redirectUrl = useMemo(\n () => (inputRedirectUrl || currentUrl || \"\").split(\"?\")[0],\n [currentUrl, inputRedirectUrl],\n );\n\n const authService = useMemo<AuthSessionServiceImpl | null>(\n () =>\n currentUrl\n ? authServiceImpl ||\n new AuthSessionServiceImpl(\n clientId,\n redirectUrl,\n config?.oauthServer,\n config?.endpoints,\n )\n : null,\n [currentUrl, clientId, redirectUrl, config, authServiceImpl],\n );\n\n const [userInfoService, setUserInfoService] = useState<UserInfoService>();\n useEffect(() => {\n if (!authService) return;\n authService.getUserInfoService().then(setUserInfoService);\n }, [authService]);\n\n const {\n data: session,\n isLoading,\n error,\n } = useQuery({\n queryKey: [\"session\", authResponseUrl, iframeUrl, currentUrl, isInIframe],\n queryFn: async () => {\n if (!authService) {\n return { authenticated: false };\n }\n const url = new URL(\n authResponseUrl\n ? authResponseUrl\n : globalThis.window.location.href || \"\",\n );\n\n const code = url.searchParams.get(\"code\");\n if (code && !isInIframe && !serverSideTokenExchange) {\n try {\n console.log(\"AuthProvider useQuery code\", { isInIframe, code });\n const newSession = await authService.tokenExchange(url.toString());\n onSignIn?.(); // Call onSignIn without an error if successful\n return newSession;\n } catch (error) {\n setTokenExchangeError(error as Error);\n onSignIn?.(\n error instanceof Error ? error : new Error(\"Failed to sign in\"),\n ); // Pass the error to onSignIn\n return { authenticated: false };\n }\n }\n // if we have existing tokens, then validate them and return the session data\n // otherwise check if we have a code in the url and exchange it for tokens\n // if we have neither, return undefined\n const existingSessionData = await authService.validateExistingSession();\n if (existingSessionData.authenticated) {\n return existingSessionData;\n }\n return existingSessionData;\n },\n });\n\n const signOutMutation = useMutation({\n mutationFn: async () => {\n // Implement signOut logic here\n authService?.updateSessionData({});\n setIframeUrl(null);\n setAuthResponseUrl(null);\n onSignOut?.();\n },\n onSuccess: () => {\n queryClient.setQueryData(\n [\"session\", authResponseUrl, iframeUrl, currentUrl, isInIframe],\n null,\n );\n },\n });\n\n const signIn = useCallback(\n async (overrideDisplayMode: DisplayMode = \"iframe\") => {\n if (!authService) return;\n\n const url = await authService.getAuthorizationUrl(\n // This is the default scope. We will eventually pull this from the partner dashboard\n DEFAULT_SCOPES,\n overrideDisplayMode,\n nonce,\n );\n\n // For iframe mode we need popups to not be blocked because the login app will try to open IDP login in a popup\n if (overrideDisplayMode === \"iframe\") {\n setIframeUrl(url);\n return;\n }\n authService.loadAuthorizationUrl(url, overrideDisplayMode);\n },\n [authService, nonce],\n );\n\n const isAuthenticated = useMemo(\n () => (session ? session.authenticated : false),\n [session],\n );\n\n const value = useMemo(\n () => ({\n isLoading,\n error: error as Error | null,\n signOut: async () => {\n await signOutMutation.mutateAsync();\n },\n isAuthenticated,\n signIn,\n }),\n [isLoading, error, signOutMutation, isAuthenticated, signIn],\n );\n return (\n <AuthContext.Provider value={value}>\n <SessionProvider session={session}>\n <TokenProvider>\n <UserProvider userInfoService={userInfoService}>\n {!isInIframe && iframeUrl && !session?.authenticated && (\n <CivicAuthIframeModal\n iframeRef={iframeRef}\n authUrl={iframeUrl}\n redirectUri={redirectUrl}\n setAuthResponseUrl={setAuthResponseUrl}\n onClose={() => setIframeUrl(null)}\n />\n )}\n {(tokenExchangeError ||\n isLoading ||\n error ||\n (isInIframe && !(tokenExchangeError || error))) && (\n <div className=\"absolute left-0 top-0 z-50 flex h-screen w-screen items-center justify-center bg-white\">\n <div className=\"absolute inset-0 flex items-center justify-center bg-white\">\n {tokenExchangeError || error ? (\n <div>\n Error:{\" \"}\n {(tokenExchangeError || (error as Error)).message}\n </div>\n ) : (\n <LoadingIcon />\n )}\n </div>\n </div>\n )}\n {children}\n </UserProvider>\n </TokenProvider>\n </SessionProvider>\n </AuthContext.Provider>\n );\n};\n\nexport type { AuthContextType, AuthProviderProps };\n\nexport { AuthProvider, AuthContext };\n","import { UserInfoService, Endpoints } from \"@/types\";\nimport { parseJWT } from \"oslo/jwt\";\n\nexport class UserInfoServiceImpl implements UserInfoService {\n constructor(private endpoints: Endpoints) {}\n\n extractUserFromIdToken<T>(idToken: string): T | null {\n const parsedJWT = parseJWT(idToken);\n if (!parsedJWT) {\n return null;\n }\n return parsedJWT.payload as T;\n }\n\n async getUserInfo<T>(\n accessToken: string,\n idToken: string | null,\n ): Promise<T | null> {\n if (idToken) {\n return this.extractUserFromIdToken<T>(idToken);\n }\n\n const userInfo = await fetch(this.endpoints.userinfo, {\n headers: { Authorization: `Bearer ${accessToken}` },\n });\n return userInfo.json() as T;\n }\n}\n","import {\n AuthSessionService,\n DisplayMode,\n UserInfoService,\n SessionData,\n OIDCTokenResponseBody,\n UnknownObject,\n Endpoints,\n User,\n} from \"../types\";\nimport { UserInfoServiceImpl } from \"./UserInfoService\";\nimport { OAuth2Client, generateCodeVerifier } from \"oslo/oauth2\";\nimport * as jose from \"jose\";\nimport {\n displayModeFromState,\n generateState,\n getIssuerVariations,\n getOauthEndpoints,\n} from \"@/lib/oauth\";\nimport { isPopupBlocked } from \"@/utils\";\n\nexport type StorageInterface = {\n get(): SessionData;\n getUser(): User<UnknownObject> | null;\n set(data: Partial<SessionData>): void;\n setUser(data: User<UnknownObject> | null): void;\n clear(): void;\n};\n\nexport class AuthSessionServiceImpl implements AuthSessionService {\n private endpoints: Endpoints | undefined;\n private oauth2Client: OAuth2Client | undefined;\n private userInfoService: UserInfoService | undefined;\n private codeVerifier: string | undefined = undefined;\n private refreshTokenTimeout: NodeJS.Timeout | null = null;\n\n constructor(\n readonly clientId: string,\n readonly redirectUrl: string,\n readonly oauthServer: string,\n readonly inputEndpoints?: Partial<Endpoints> | undefined,\n ) {\n this.codeVerifier = this.getCodeVerifier();\n this.endpoints = inputEndpoints as Endpoints;\n }\n\n protected getCodeVerifier(): string {\n return generateCodeVerifier();\n }\n\n public async getUserInfoService(): Promise<UserInfoService> {\n if (this.userInfoService) {\n return this.userInfoService;\n }\n const endpoints = await this.getEndpoints();\n\n this.userInfoService = new UserInfoServiceImpl(endpoints);\n return this.userInfoService;\n }\n\n protected async getEndpoints(): Promise<Endpoints> {\n if (this.endpoints?.auth) {\n return this.endpoints;\n }\n const jwksEndpoints = await getOauthEndpoints(this.oauthServer);\n return this.endpoints\n ? { ...this.endpoints, ...jwksEndpoints }\n : jwksEndpoints;\n }\n\n protected async getOauth2Client() {\n if (this.oauth2Client) {\n return this.oauth2Client;\n }\n const endpoints = await this.getEndpoints();\n this.oauth2Client = new OAuth2Client(\n this.clientId,\n endpoints.auth,\n endpoints.token,\n // this\n { redirectURI: this.redirectUrl },\n );\n return this.oauth2Client;\n }\n\n getSessionData(): SessionData {\n return JSON.parse(\n localStorage.getItem(`civic-auth:${this.clientId}`) || \"{}\",\n ) as SessionData;\n }\n\n updateSessionData(data: Partial<SessionData>): void {\n localStorage.setItem(\n `civic-auth:${this.clientId}`,\n JSON.stringify({ ...data }),\n );\n }\n\n getUser(): User<UnknownObject> | null {\n return JSON.parse(\n localStorage.getItem(`civic-auth:${this.clientId}:user`) || \"{}\",\n ) as User<UnknownObject>;\n }\n\n setUser(data: User<UnknownObject> | null): void {\n localStorage.setItem(\n `civic-auth:${this.clientId}:user`,\n JSON.stringify(data === null ? {} : data),\n );\n }\n\n clearSessionData(): void {\n localStorage.setItem(`civic-auth:${this.clientId}`, JSON.stringify({}));\n }\n\n async getAuthorizationUrlWithChallenge(\n state: string,\n scopes: string[],\n ): Promise<URL> {\n const oauth2Client = await this.getOauth2Client();\n if (this.endpoints?.challenge) {\n const challenge = await fetch(this.endpoints.challenge).then((res) =>\n res.json().then((data) => data.challenge),\n );\n const oAuthUrl = await oauth2Client.createAuthorizationURL({\n state,\n scopes,\n });\n oAuthUrl.searchParams.append(\"code_challenge\", challenge);\n oAuthUrl.searchParams.append(\"code_challenge_method\", \"S256\");\n return oAuthUrl;\n }\n const oAuthUrl = await oauth2Client.createAuthorizationURL({\n state,\n codeVerifier: this.codeVerifier,\n codeChallengeMethod: \"S256\",\n scopes,\n });\n return oAuthUrl;\n }\n async getAuthorizationUrl(\n scopes: string[],\n displayMode: DisplayMode,\n nonce?: string,\n ): Promise<string> {\n const state = generateState(displayMode);\n const existingSessionData = this.getSessionData();\n this.updateSessionData({\n ...existingSessionData,\n codeVerifier: this.codeVerifier,\n displayMode,\n });\n const oAuthUrl = await this.getAuthorizationUrlWithChallenge(state, scopes);\n if (nonce) {\n // nonce isn't supported by oslo, so we add it manually\n oAuthUrl.searchParams.append(\"nonce\", nonce);\n }\n oAuthUrl.searchParams.append(\"prompt\", \"consent\");\n return oAuthUrl.toString();\n }\n\n // TODO fix the Window reference\n loadAuthorizationUrl(authorizationURL: string, displayMode: DisplayMode) {\n switch (displayMode) {\n case \"iframe\":\n // Implement iframe logic\n break;\n case \"redirect\":\n window.location.href = authorizationURL;\n break;\n case \"new_tab\":\n window.open(authorizationURL, \"_blank\");\n break;\n case \"custom_tab\":\n // Implement custom tab logic (might require native app integration)\n break;\n }\n }\n\n async init(): Promise<void> {\n this.updateSessionData({ authenticated: false });\n }\n\n determineDisplayMode(displayMode: DisplayMode): DisplayMode {\n // If popups are blocked and we're in iframe mode, we need to override the display mode to redirect\n if (isPopupBlocked() && displayMode === \"iframe\") {\n displayMode = \"redirect\";\n }\n // TODO: Add additional checks to determine the display mode for new_mode if new tabs are blocked.\n return displayMode;\n }\n\n async signIn(\n displayMode: DisplayMode,\n scopes: string[],\n nonce: string,\n ): Promise<void> {\n const authorizationURL = await this.getAuthorizationUrl(\n scopes,\n displayMode,\n nonce,\n );\n\n this.loadAuthorizationUrl(authorizationURL, displayMode);\n }\n\n async tokenExchange(responseUrl: string): Promise<SessionData> {\n let session = this.getSessionData();\n\n if (!session.authenticated) {\n const url = new URL(responseUrl);\n const authorizationCode = url.searchParams.get(\"code\");\n const returnedState = url.searchParams.get(\"state\");\n if (!authorizationCode || !returnedState) {\n throw new Error(\"Invalid authorization response\");\n }\n const codeVerifier = session.codeVerifier;\n const oauth2Client = await this.getOauth2Client();\n const tokens =\n await oauth2Client.validateAuthorizationCode<OIDCTokenResponseBody>(\n authorizationCode,\n {\n codeVerifier,\n },\n );\n\n // Validate relevant tokens\n try {\n await this.validateTokens(tokens);\n } catch (error) {\n console.error(\"tokenExchange tokens\", { error, tokens });\n throw new Error(\n `OIDC tokens validation failed: ${(error as Error).message}`,\n );\n }\n const parsedDisplayMode = displayModeFromState(\n returnedState,\n session.displayMode,\n );\n // Update session with authentication result\n session = {\n ...session,\n displayMode: parsedDisplayMode,\n idToken: tokens.id_token,\n authenticated: true,\n state: returnedState,\n accessToken: tokens.access_token,\n refreshToken: tokens.refresh_token,\n timestamp: Date.now(),\n expiresIn: tokens.expires_in,\n };\n this.updateSessionData(session);\n const user = await (\n await this.getUserInfoService()\n ).getUserInfo(tokens.access_token, tokens.id_token || null);\n this.setUser(user);\n }\n\n // Set up automatic token refresh\n this.setupTokenRefresh(session);\n\n if (session.displayMode === \"new_tab\") {\n // Close the popup window\n window.close();\n } else if (session.displayMode === \"redirect\") {\n // TODO: Determine if there is anything additional to do here\n }\n return session;\n }\n\n private setupTokenRefresh(session: SessionData): void {\n if (this.refreshTokenTimeout) {\n clearTimeout(this.refreshTokenTimeout);\n }\n\n if (session.expiresIn) {\n // Calculate remaining time by subtracting elapsed time from total expiration time\n const elapsedTime = Date.now() - (session.timestamp || 0);\n const remainingTime = session.expiresIn * 1000 - elapsedTime;\n // Refresh the token 1 minute before it expires\n const refreshTime = Math.max(0, remainingTime - 60000);\n\n this.refreshTokenTimeout = setTimeout(() => {\n this.refreshToken()\n .then((newSession) => {\n console.log(\"Token refreshed successfully\", newSession);\n })\n .catch((error) => {\n console.error(\"Failed to refresh token:\", error);\n // Handle the error (e.g., log out the user or retry)\n // TODO this should be replaced by the real logout once it is available\n this.updateSessionData({});\n });\n }, refreshTime);\n }\n }\n\n async refreshToken(): Promise<SessionData> {\n const sessionData = this.getSessionData();\n if (!sessionData.refreshToken) {\n throw new Error(\"No refresh token available\");\n }\n const oauth2Client = await this.getOauth2Client();\n const tokens = await oauth2Client.refreshAccessToken<OIDCTokenResponseBody>(\n sessionData.refreshToken,\n );\n\n // Update session data\n const session = {\n ...sessionData,\n idToken: tokens.id_token,\n authenticated: true,\n accessToken: tokens.access_token,\n refreshToken: tokens.refresh_token,\n timestamp: Date.now(),\n expiresIn: tokens.expires_in,\n };\n this.updateSessionData(session);\n\n // Schedule next automatic refresh\n this.setupTokenRefresh(session);\n\n return session;\n }\n\n async getUserInfo<T extends UnknownObject>(): Promise<User<T> | null> {\n const sessionData = this.getSessionData();\n if (!sessionData.accessToken) {\n throw new Error(\"No access token available\");\n }\n const userInfoService = await this.getUserInfoService();\n return userInfoService.getUserInfo<T>(\n sessionData.accessToken,\n sessionData.idToken || null,\n );\n }\n\n /**\n * Uses the jose library to validate a JWT token using the OAuth JWKS endpoint\n * @param {string} token\n * @returns {Promise<jose.JWTPayload>}\n * @throws {Error} if the token is invalid\n */\n async validateTokens(\n tokens: OIDCTokenResponseBody,\n ): Promise<\n Record<\"idToken\" | \"accessToken\" | \"refreshToken\", jose.JWTPayload | string>\n > {\n const endpoints = await this.getEndpoints();\n const JWKS = jose.createRemoteJWKSet(new URL(endpoints.jwks));\n const returnPayload: Record<string, jose.JWTPayload | string> = {};\n // const payload = {};\n // validate the ID token\n console.log(\"issuer\", getIssuerVariations(this.oauthServer));\n const idTokenResponse = await jose.jwtVerify(tokens.id_token, JWKS, {\n issuer: getIssuerVariations(this.oauthServer),\n audience: this.clientId,\n });\n returnPayload.idToken = idTokenResponse.payload;\n // validate the access token\n const accessTokenResponse = await jose.jwtVerify(\n tokens.access_token,\n JWKS,\n {\n issuer: getIssuerVariations(this.oauthServer),\n },\n );\n returnPayload.accessToken = accessTokenResponse.payload;\n\n if (tokens.refresh_token) {\n returnPayload.refreshToken = tokens.refresh_token;\n }\n return returnPayload;\n }\n\n async validateExistingSession(): Promise<SessionData> {\n const sessionData = this.getSessionData();\n try {\n if (!sessionData.idToken || !sessionData.accessToken) {\n const unAuthenticatedSession = { ...sessionData, authenticated: false };\n this.updateSessionData(unAuthenticatedSession);\n return unAuthenticatedSession;\n }\n await this.validateTokens({\n id_token: sessionData.idToken as string,\n access_token: sessionData.accessToken as string,\n refresh_token: sessionData.refreshToken as string,\n });\n sessionData.authenticated = true;\n return sessionData;\n } catch (error) {\n console.warn(\"Failed to validate existing tokens\", error);\n const unAuthenticatedSession = {\n authenticated: false,\n };\n this.updateSessionData(unAuthenticatedSession);\n return unAuthenticatedSession;\n }\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 = (displayMode: DisplayMode): string => {\n const jsonString = JSON.stringify({\n uuid: uuid(),\n displayMode,\n });\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 * @returns { uuid: string, displayMode: DisplayMode }\n */\nconst displayModeFromState = (\n state: string,\n sessionDisplayMode: DisplayMode | undefined,\n): DisplayMode | undefined => {\n try {\n const jsonString = btoa(state);\n\n return JSON.parse(jsonString).displayMode;\n } catch (e) {\n console.error(\"Failed to parse displayMode from state:\", e);\n\n return sessionDisplayMode;\n }\n};\n\nexport {\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\nexport { cn, isPopupBlocked };\n","const DEFAULT_SCOPES = [\n \"openid\",\n \"profile\",\n \"email\",\n \"forwardedTokens\",\n \"offline_access\",\n];\nconst IFRAME_ID = \"civic-auth-iframe\";\n\nexport { DEFAULT_SCOPES, IFRAME_ID };\n","\"use client\";\nimport { IFRAME_ID } from \"@/constants\";\nimport { forwardRef } from \"react\";\n\ntype CivicAuthIframeProps = {\n authUrl: string;\n onLoad?: () => void;\n};\n\nconst CivicAuthIframe = forwardRef<HTMLIFrameElement, CivicAuthIframeProps>(\n ({ authUrl, onLoad }, ref) => {\n return (\n <iframe\n id={IFRAME_ID}\n ref={ref}\n src={authUrl}\n className=\"h-96 w-80 border-none\"\n onLoad={onLoad}\n />\n );\n },\n);\n\nCivicAuthIframe.displayName = \"CivicAuthIframe\";\n\nexport type { CivicAuthIframeProps };\n\nexport { CivicAuthIframe };\n","\"use client\";\nimport { useCallback, useEffect, useRef, useState } from \"react\";\nimport { LoadingIcon } from \"./LoadingIcon\";\nimport { CloseIcon } from \"./CloseIcon\";\nimport { CivicAuthIframe } from \"./CivicAuthIframe\";\n\ntype CivicAuthIframeModalProps = {\n authUrl: string;\n redirectUri: string;\n setAuthResponseUrl: (authResponse: string) => void;\n onClose: () => void;\n iframeRef: React.RefObject<HTMLIFrameElement>;\n redirectInProgress?: boolean;\n closeOnRedirect?: boolean;\n};\n\nconst CivicAuthIframeModal = ({\n authUrl,\n redirectUri,\n setAuthResponseUrl,\n onClose,\n iframeRef,\n redirectInProgress = false,\n closeOnRedirect = true,\n}: CivicAuthIframeModalProps) => {\n const [isLoading, setIsLoading] = useState(true);\n\n const processIframeUrl = useCallback(() => {\n if (iframeRef.current && iframeRef.current.contentWindow) {\n try {\n const iframeUrl = iframeRef.current.contentWindow.location.href;\n\n if (iframeUrl.startsWith(redirectUri)) {\n setAuthResponseUrl(iframeUrl);\n if (closeOnRedirect) onClose();\n return true; // Successfully processed the URL\n }\n } catch {\n // If we get here, the iframe hasn't redirected to our origin yet\n console.log(\"Waiting for redirect...\");\n }\n }\n return false; // Haven't processed the URL yet\n }, [closeOnRedirect, iframeRef, onClose, redirectUri, setAuthResponseUrl]);\n\n const intervalId = useRef<NodeJS.Timeout>();\n\n const handleEscape = useCallback(\n (event: KeyboardEvent) => {\n if (event.key === \"Escape\") {\n onClose();\n }\n },\n [onClose],\n );\n\n // handle Escape\n useEffect(() => {\n window.addEventListener(\"keydown\", handleEscape);\n\n return () => window.removeEventListener(\"keydown\", handleEscape);\n });\n\n const handleIframeLoad = () => {\n setIsLoading(false);\n console.log(\"handleIframeLoad\");\n if (processIframeUrl() && intervalId.current) {\n clearInterval(intervalId.current);\n }\n };\n\n return (\n <div\n className=\"absolute left-0 top-0 z-50 flex h-screen w-screen items-center justify-center bg-neutral-950 bg-opacity-50\"\n onClick={onClose}\n >\n <div\n className=\"relative rounded-3xl bg-white p-6 shadow-lg\"\n onClick={(e) => e.stopPropagation()}\n >\n <button\n className=\"absolute right-4 top-4 flex cursor-pointer items-center justify-center border-none bg-transparent p-1 text-neutral-400\"\n onClick={onClose}\n >\n <CloseIcon />\n </button>\n\n {(isLoading || redirectInProgress) && (\n <div className=\"absolute inset-0 flex items-center justify-center rounded-3xl bg-neutral-100\">\n <LoadingIcon />\n </div>\n )}\n\n <CivicAuthIframe\n ref={iframeRef}\n authUrl={authUrl}\n onLoad={handleIframeLoad}\n />\n </div>\n </div>\n );\n};\n\nexport type { CivicAuthIframeModalProps };\n\nexport { CivicAuthIframeModal };\n","const LoadingIcon = () => (\n <div role=\"status\">\n <svg\n aria-hidden=\"true\"\n className=\"inline h-8 w-8 animate-spin fill-neutral-600 text-neutral-200 dark:fill-neutral-300 dark:text-neutral-600\"\n viewBox=\"0 0 100 101\"\n fill=\"none\"\n xmlns=\"http://www.w3.org/2000/svg\"\n >\n <path\n d=\"M100 50.5908C100 78.2051 77.6142 100.591 50 100.591C22.3858 100.591 0 78.2051 0 50.5908C0 22.9766 22.3858 0.59082 50 0.59082C77.6142 0.59082 100 22.9766 100 50.5908ZM9.08144 50.5908C9.08144 73.1895 27.4013 91.5094 50 91.5094C72.5987 91.5094 90.9186 73.1895 90.9186 50.5908C90.9186 27.9921 72.5987 9.67226 50 9.67226C27.4013 9.67226 9.08144 27.9921 9.08144 50.5908Z\"\n fill=\"currentColor\"\n />\n <path\n d=\"M93.9676 39.0409C96.393 38.4038 97.8624 35.9116 97.0079 33.5539C95.2932 28.8227 92.871 24.3692 89.8167 20.348C85.8452 15.1192 80.8826 10.7238 75.2124 7.41289C69.5422 4.10194 63.2754 1.94025 56.7698 1.05124C51.7666 0.367541 46.6976 0.446843 41.7345 1.27873C39.2613 1.69328 37.813 4.19778 38.4501 6.62326C39.0873 9.04874 41.5694 10.4717 44.0505 10.1071C47.8511 9.54855 51.7191 9.52689 55.5402 10.0491C60.8642 10.7766 65.9928 12.5457 70.6331 15.2552C75.2735 17.9648 79.3347 21.5619 82.5849 25.841C84.9175 28.9121 86.7997 32.2913 88.1811 35.8758C89.083 38.2158 91.5421 39.6781 93.9676 39.0409Z\"\n fill=\"currentFill\"\n />\n </svg>\n <span className=\"sr-only\">Loading...</span>\n </div>\n);\n\nexport { LoadingIcon };\n","const CloseIcon = () => (\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n width=\"24\"\n height=\"24\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n className=\"lucide lucide-x\"\n >\n <path d=\"M18 6 6 18\" />\n <path d=\"m6 6 12 12\" />\n </svg>\n);\n\nexport { CloseIcon };\n","\"use client\";\nimport { useAuth, useUser } from \"@/react/hooks\";\nimport { DisplayMode } from \"@/types\";\nimport { cn } from \"@/utils\";\nimport { useCallback, useEffect, useState } from \"react\";\n\nconst ChevronDown = () => (\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n width=\"24\"\n height=\"24\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n className=\"lucide lucide-chevron-down\"\n >\n <path d=\"m6 9 6 6 6-6\" />\n </svg>\n);\n\nconst ChevronUp = () => (\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n width=\"24\"\n height=\"24\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n className=\"lucide lucide-chevron-up\"\n >\n <path d=\"m18 15-6-6-6 6\" />\n </svg>\n);\n\nconst UserButton = ({\n displayMode,\n className,\n}: {\n displayMode?: DisplayMode;\n className?: string;\n}) => {\n const [isOpen, setIsOpen] = useState(false);\n const { signIn, isAuthenticated, signOut } = useAuth();\n const { user } = useUser();\n\n const handleClickOutside = useCallback((event: MouseEvent) => {\n const target = event.target as HTMLElement;\n\n if (!target.closest(\"#civic-dropdown-container\")) {\n setIsOpen(false);\n }\n }, []);\n\n const handleSignOut = useCallback(async () => {\n await signOut();\n\n setIsOpen(false);\n }, [signOut]);\n\n const handleSignIn = useCallback(async () => {\n await signIn(displayMode);\n\n setIsOpen(false);\n }, [signIn, displayMode]);\n\n const handleEscape = useCallback((event: KeyboardEvent) => {\n if (event.key === \"Escape\") {\n setIsOpen(false);\n }\n }, []);\n\n useEffect(() => {\n if (isOpen) {\n window.addEventListener(\"click\", handleClickOutside);\n\n window.addEventListener(\"keydown\", handleEscape);\n }\n\n return () => {\n window.removeEventListener(\"click\", handleClickOutside);\n\n window.removeEventListener(\"keydown\", handleEscape);\n };\n }, [handleClickOutside, handleEscape, isOpen]);\n\n if (isAuthenticated) {\n return (\n <div className=\"relative\" id=\"civic-dropdown-container\">\n <button\n className={cn(\n \"flex w-full items-center justify-between gap-2 rounded-full border border-neutral-500 px-3 py-2 text-neutral-500 transition-colors hover:bg-neutral-200 hover:bg-opacity-50\",\n className,\n )}\n onClick={() => setIsOpen((isOpen) => !isOpen)}\n >\n {user?.picture ? (\n <span className=\"relative flex h-10 w-10 shrink-0 gap-2 overflow-hidden rounded-full\">\n <img\n className=\"h-full w-full object-cover\"\n src={user.picture}\n alt={user?.name || user?.email}\n />\n </span>\n ) : (\n <div />\n )}\n\n <span>{user?.name || user?.email}</span>\n\n {isOpen ? <ChevronUp /> : <ChevronDown />}\n </button>\n <div\n className={\n isOpen\n ? \"absolute right-0 mt-2 w-full rounded-lg bg-white py-2 text-neutral-500 shadow-xl\"\n : \"hidden\"\n }\n >\n <ul>\n <li>\n <button\n className=\"block w-full px-4 py-2 transition-colors hover:bg-neutral-200 hover:bg-opacity-50\"\n onClick={handleSignOut}\n >\n Logout\n </button>\n </li>\n </ul>\n </div>\n </div>\n );\n }\n\n return (\n <button\n className={cn(\n \"rounded-full border border-neutral-500 px-3 py-2 transition-colors hover:bg-neutral-200 hover:bg-opacity-50\",\n className,\n )}\n onClick={handleSignIn}\n >\n Sign in\n </button>\n );\n};\n\nexport { UserButton };\n","\"use client\";\nimport { cn } from \"@/utils\";\nimport { useAuth } from \"@/react/hooks\";\nimport { DisplayMode } from \"@/types\";\n\nconst SignInButton = ({\n displayMode,\n className,\n}: {\n displayMode?: DisplayMode;\n className?: string;\n}) => {\n const { signIn } = useAuth();\n\n return (\n <button\n className={cn(\n \"rounded-full border border-neutral-500 px-3 py-2 transition-colors hover:bg-neutral-200 hover:bg-opacity-50\",\n className,\n )}\n onClick={() => signIn(displayMode)}\n >\n Sign In\n </button>\n );\n};\n\nexport { SignInButton };\n","\"use client\";\nimport { cn } from \"@/utils\";\nimport { useAuth } from \"@/react/hooks\";\n\nconst SignOutButton = ({ className }: { className?: string }) => {\n const { signOut } = useAuth();\n\n return (\n <button\n className={cn(\n \"rounded-full border border-neutral-500 px-3 py-2 transition-colors hover:bg-neutral-200 hover:bg-opacity-50\",\n className,\n )}\n onClick={() => signOut()}\n >\n Sign Out\n </button>\n );\n};\n\nexport { SignOutButton };\n","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 */\n\"use server\";\nimport { NextConfig } from \"next\";\nimport { loggers } from \"@/lib/logger\";\n\nconst logger = loggers.nextjs.handlers.auth;\n\nexport interface CookieConfig {\n secure?: boolean;\n sameSite?: \"strict\" | \"lax\" | \"none\";\n domain?: string;\n path?: string;\n maxAge?: number;\n}\n\nexport type AuthConfigWithDefaults = {\n clientId: string;\n oauthServer: string;\n callbackUrl: string;\n loginUrl: string;\n logoutUrl: string;\n challengeUrl: string;\n include: string[];\n exclude: string[];\n cookies: {\n tokens: CookieConfig;\n user: CookieConfig;\n };\n};\n\nexport type AuthConfig = Partial<AuthConfigWithDefaults>;\n\nexport type DefinedAuthConfig = AuthConfigWithDefaults;\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 sameSite: \"strict\",\n path: \"/\",\n maxAge: 60 * 60, // 1 hour\n },\n user: {\n sameSite: \"strict\",\n path: \"/\",\n maxAge: 60 * 60, // 1 hour\n },\n },\n};\n\nconst withoutUndefined = <T extends { [k: string]: unknown }>(\n obj: T,\n): Partial<T> => {\n const result: Partial<T> = {};\n for (const key in obj) {\n if (obj[key] !== undefined) {\n result[key] = obj[key];\n }\n }\n return result;\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 // 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 loginUrl: process.env._civic_auth_login_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 });\n\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 ...(config.cookies?.tokens || {}),\n },\n user: {\n ...defaultAuthConfig.cookies.user,\n ...(config.cookies?.user || {}),\n },\n },\n };\n\n logger.debug(\"Config from environment:\", configFromEnv);\n logger.debug(\"Resolved config:\", mergedConfig);\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 tefault 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 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_login_url: resolvedConfig.loginUrl,\n _civic_auth_logout_url: resolvedConfig.logoutUrl,\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","/**\n * Trigger a backend API that logs the user out and then redirects to the homepage (TODO parameterize the redirect)\n */\nimport { resolveAuthConfig } from \"@/nextjs/config.js\";\nimport React, { ReactNode } from \"react\";\n\nconst NextLogOut = ({ children }: { children: ReactNode }) => {\n const config = resolveAuthConfig();\n const logoutUrl = `${config.logoutUrl}`;\n\n return <a href={logoutUrl}>{children}</a>;\n};\n\nexport { NextLogOut };\n","\"use client\";\nimport { SessionData } from \"@/types\";\nimport React, { createContext, ReactNode } from \"react\";\n\nconst defaultSession: SessionData = {\n authenticated: false,\n idToken: undefined,\n accessToken: undefined,\n displayMode: \"iframe\",\n};\n\n// Context for exposing session specifically to the TokenProvider\nconst SessionContext = createContext<SessionData>(defaultSession);\n\ntype SessionContextType = {\n children: ReactNode;\n session?: SessionData;\n};\n\nconst SessionProvider = ({ children, session }: SessionContextType) => (\n <SessionContext.Provider value={session || defaultSession}>\n {children}\n </SessionContext.Provider>\n);\n\nexport type { SessionContextType };\nexport { SessionProvider, SessionContext };\n","import { Config } from \"@/types\";\n\nexport const authConfig: Config = {\n // TODO change this to the production URL once we're out of beta\n oauthServer: \"https://auth-dev.civic.com/oauth/\",\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\nexport { isWindowInIframe };\n","\"use client\";\nimport { AuthProvider, AuthProviderProps } from \"./AuthProvider\";\nimport { QueryClient, QueryClientProvider } from \"@tanstack/react-query\";\n\n// adding the styles import here to be added to the bundle\nimport \"@civic/auth/styles.css\";\n\nconst queryClient = new QueryClient();\n\ntype CivicAuthProviderProps = Omit<\n AuthProviderProps,\n \"authServiceImpl\" | \"serverSideTokenExchange\"\n>;\n\nconst CivicAuthProvider = ({ children, ...props }: CivicAuthProviderProps) => {\n return (\n <QueryClientProvider client={queryClient}>\n <AuthProvider {...props}>{children}</AuthProvider>\n </QueryClientProvider>\n );\n};\n\nexport { CivicAuthProvider };\n","\"use client\";\n/**\n * A very small context provider for the user object - it takes the user object from the cookie and provides it to the app.\n */\nimport { createContext, useContext, useEffect, useMemo, useState } from \"react\";\nimport { useUserCookie } from \"../hooks/useUserCookie.js\";\nimport { AuthProvider, AuthProviderProps } from \"@/shared/AuthProvider.js\";\nimport { QueryClient, QueryClientProvider } from \"@tanstack/react-query\";\nimport { AuthSessionServiceImpl } from \"@/services\";\nimport { UnknownObject, User } from \"@/types.js\";\nimport { resolveAuthConfig } from \"@/nextjs/config.js\";\n\nconst queryClient = new QueryClient();\n\ntype UserContextType = {\n user: User<UnknownObject> | null;\n};\n\nconst defaultUserContext = { user: null };\nconst UserContext = createContext<UserContextType>(defaultUserContext);\n\ntype NextCivicAuthProviderProps = Omit<AuthProviderProps, \"clientId\">;\n\nexport const CivicNextAuthProvider = ({\n children,\n ...props\n}: NextCivicAuthProviderProps) => {\n const user = useUserCookie();\n const [redirectUrl, setRedirectUrl] = useState<string>(\"\");\n const { clientId, oauthServer, callbackUrl, challengeUrl } =\n resolveAuthConfig();\n\n useEffect(() => {\n if (typeof globalThis.window !== \"undefined\") {\n const currentUrl = globalThis.window.location.href;\n setRedirectUrl(new URL(callbackUrl, currentUrl).toString());\n }\n }, [callbackUrl]);\n\n // create a custom authService that uses a challenge endpoint to get\n // the challenge to add to the auth request\n const authService = useMemo<AuthSessionServiceImpl | undefined>(() => {\n if (redirectUrl && clientId && oauthServer) {\n return new AuthSessionServiceImpl(clientId, redirectUrl, oauthServer, {\n challenge: challengeUrl,\n });\n }\n return undefined;\n }, [redirectUrl, clientId, oauthServer, challengeUrl]);\n\n return (\n <QueryClientProvider client={queryClient}>\n <AuthProvider\n {...props}\n config={{ oauthServer }}\n clientId={clientId}\n authServiceImpl={authService}\n serverSideTokenExchange={true}\n >\n <UserContext.Provider value={user}>{children}</UserContext.Provider>\n </AuthProvider>\n </QueryClientProvider>\n );\n};\nexport const useNextUser = () => useContext(UserContext);\n","\"use client\";\nimport { useEffect, useRef } from \"react\";\nimport { useRouter } from \"next/navigation.js\";\nimport { useQuery } from \"@tanstack/react-query\";\nimport { getCookieValue } from \"@/lib/cookies.js\";\n\nconst getUserFromCookie = () => {\n const userCookie = getCookieValue(\"user\", globalThis.window);\n return userCookie;\n};\n\nexport const useUserCookie = () => {\n const hasRunRef = useRef(false);\n const router = useRouter();\n\n const { data: user } = useQuery({\n queryKey: [\"user\"],\n queryFn: () => getUserFromCookie(),\n refetchInterval: 2000,\n refetchIntervalInBackground: true,\n enabled: !hasRunRef.current,\n refetchOnWindowFocus: true,\n });\n\n useEffect(() => {\n if (user) {\n if (!hasRunRef.current) {\n hasRunRef.current = true;\n router.refresh();\n }\n } else {\n hasRunRef.current = false;\n }\n }, [user, router]);\n\n return user;\n};\n","const getCookieValue = (key: string, window: Window) => {\n const cookie = window.document.cookie;\n if (!cookie) return null;\n const cookies = cookie.split(\";\");\n for (const c of cookies) {\n const [name, value] = c.trim().split(\"=\");\n if (name === key) {\n try {\n return JSON.parse(decodeURIComponent(value));\n } catch (e) {\n console.log(\"Error parsing cookie value\", e);\n return value;\n }\n }\n }\n return null;\n};\nexport { getCookieValue };\n","\"use client\";\nimport { useContext } from \"react\";\nimport { SessionContext } from \"@/react/providers\";\n\n// TokenProvider will use this internal context to access session\nconst useSession = () => {\n const context = useContext(SessionContext);\n if (!context) {\n throw new Error(\"useSession must be used within an SessionProvider\");\n }\n return context;\n};\n\nexport { useSession };\n"],"mappings":"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","names":["useContext","useContext","useContext","user","createContext","jsx","createContext","queryClient","createContext","useState","useEffect","useMemo","useCallback","useRef","useQuery","useMutation","useQueryClient","parseJWT","parseJWT","oAuthUrl","jsx","jsx","jsx","jsxs","jsx","jsxs","useCallback","useEffect","useState","jsx","jsxs","useState","useCallback","useEffect","isOpen","jsx","jsx","jsx","createContext","jsx","window","jsx","jsxs","createContext","useState","queryClient","useQueryClient","useRef","useEffect","useMemo","useQuery","error","useMutation","useCallback","jsx","createContext","useContext","useEffect","useMemo","useState","useEffect","useRef","useQuery","window","useRef","useQuery","useEffect","QueryClient","QueryClientProvider","jsx","queryClient","QueryClient","UserContext","createContext","useState","useEffect","useMemo","QueryClientProvider","useContext","useContext","useContext","useContext"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@civic/auth",
3
- "version": "0.0.1-beta.0",
3
+ "version": "0.0.1-beta.1",
4
4
  "files": [
5
5
  "dist"
6
6
  ],
@@ -37,26 +37,43 @@
37
37
  },
38
38
  "./styles.css": "./dist/index.css"
39
39
  },
40
+ "scripts": {
41
+ "build": "tsup",
42
+ "prepublish": "tsup",
43
+ "dev:watch": "tsup --watch",
44
+ "test": "vitest",
45
+ "lint": "eslint \"src/**/*.ts*\"",
46
+ "lint:fix": "pnpm lint --fix",
47
+ "clean": "rm -rf .turbo dist node_modules",
48
+ "test:update": "vitest --update"
49
+ },
40
50
  "dependencies": {
41
51
  "@tanstack/react-query": "^5.56.2",
42
52
  "autoprefixer": "^10.4.20",
43
53
  "clsx": "^2.1.1",
54
+ "debug": "^4.3.7",
44
55
  "jose": "^5.9.4",
45
- "next": "14.2.14",
46
56
  "oslo": "^1.2.1",
57
+ "picomatch": "^4.0.2",
47
58
  "postcss": "8.4.47",
48
59
  "tailwind-merge": "^2.5.3",
49
60
  "tailwindcss": "3.4.13",
50
61
  "uuid": "^10.0.0"
51
62
  },
52
63
  "devDependencies": {
64
+ "@repo/eslint-config": "workspace:*",
65
+ "@repo/typescript-config": "workspace:*",
53
66
  "@testing-library/jest-dom": "^6.5.0",
54
67
  "@testing-library/react": "16.0.1",
68
+ "@types/debug": "^4.1.12",
55
69
  "@types/node": "^22.7.4",
70
+ "@types/picomatch": "^3.0.1",
56
71
  "@types/react": "18.3.11",
57
72
  "@types/react-dom": "18.3.0",
58
73
  "@vitejs/plugin-react": "^4.3.2",
74
+ "esbuild-plugin-css-modules": "^0.3.0",
59
75
  "eslint": "^8.57.1",
76
+ "next": "14.2.14",
60
77
  "prettier": "^3.3.3",
61
78
  "prettier-plugin-tailwindcss": "^0.6.8",
62
79
  "react": "18.3.1",
@@ -65,22 +82,9 @@
65
82
  "tsup": "^8.3.0",
66
83
  "vite": "^5.4.8",
67
84
  "vite-plugin-dts": "^4.2.3",
68
- "vitest": "^2.1.2",
69
- "@repo/typescript-config": "0.0.0",
70
- "@repo/eslint-config": "0.0.0"
85
+ "vitest": "^2.1.2"
71
86
  },
72
87
  "peerDependencies": {
73
- "@types/react": "18.3.1",
74
- "@types/react-dom": "18.3.0"
75
- },
76
- "scripts": {
77
- "build": "tsup",
78
- "prepublish": "tsup",
79
- "dev": "tsup --watch",
80
- "test": "vitest",
81
- "lint": "eslint \"src/**/*.ts*\"",
82
- "lint:fix": "pnpm lint --fix",
83
- "clean": "rm -rf .turbo dist node_modules",
84
- "test:update": "vitest --update"
88
+ "next": "^14.2.10"
85
89
  }
86
- }
90
+ }
@@ -1,52 +0,0 @@
1
- import { JWT } from 'oslo/jwt';
2
-
3
- type UnknownObject = Record<string, unknown>;
4
- type EmptyObject = Record<string, never>;
5
- type DisplayMode = "iframe" | "redirect" | "new_tab" | "custom_tab";
6
- type Endpoints = {
7
- jwks: string;
8
- auth: string;
9
- token: string;
10
- userinfo: string;
11
- };
12
- type Config = {
13
- oauthServer: string;
14
- endpoints?: Endpoints;
15
- };
16
- type SessionData = {
17
- authenticated: boolean;
18
- state?: string;
19
- accessToken?: string;
20
- refreshToken?: string;
21
- idToken?: string;
22
- expiresIn?: number;
23
- codeVerifier?: string;
24
- displayMode?: DisplayMode;
25
- openerUrl?: string;
26
- };
27
- type ForwardedTokens = Record<string, {
28
- idToken?: string;
29
- accessToken?: string;
30
- refreshToken?: string;
31
- }>;
32
- type Tokens = {
33
- idToken: string;
34
- accessToken: string;
35
- refreshToken: string;
36
- forwardedTokens: ForwardedTokens;
37
- };
38
- interface BaseUser {
39
- id: string;
40
- email?: string;
41
- name?: string;
42
- picture?: string;
43
- given_name?: string;
44
- family_name?: string;
45
- created_at?: Date;
46
- updated_at?: Date;
47
- }
48
- type User<T extends UnknownObject = EmptyObject> = BaseUser & T & JWT["payload"] & Tokens & {
49
- [key: string]: unknown;
50
- };
51
-
52
- export type { Config as C, DisplayMode as D, Endpoints as E, ForwardedTokens as F, SessionData as S, Tokens as T, User as U };
@@ -1,52 +0,0 @@
1
- import { JWT } from 'oslo/jwt';
2
-
3
- type UnknownObject = Record<string, unknown>;
4
- type EmptyObject = Record<string, never>;
5
- type DisplayMode = "iframe" | "redirect" | "new_tab" | "custom_tab";
6
- type Endpoints = {
7
- jwks: string;
8
- auth: string;
9
- token: string;
10
- userinfo: string;
11
- };
12
- type Config = {
13
- oauthServer: string;
14
- endpoints?: Endpoints;
15
- };
16
- type SessionData = {
17
- authenticated: boolean;
18
- state?: string;
19
- accessToken?: string;
20
- refreshToken?: string;
21
- idToken?: string;
22
- expiresIn?: number;
23
- codeVerifier?: string;
24
- displayMode?: DisplayMode;
25
- openerUrl?: string;
26
- };
27
- type ForwardedTokens = Record<string, {
28
- idToken?: string;
29
- accessToken?: string;
30
- refreshToken?: string;
31
- }>;
32
- type Tokens = {
33
- idToken: string;
34
- accessToken: string;
35
- refreshToken: string;
36
- forwardedTokens: ForwardedTokens;
37
- };
38
- interface BaseUser {
39
- id: string;
40
- email?: string;
41
- name?: string;
42
- picture?: string;
43
- given_name?: string;
44
- family_name?: string;
45
- created_at?: Date;
46
- updated_at?: Date;
47
- }
48
- type User<T extends UnknownObject = EmptyObject> = BaseUser & T & JWT["payload"] & Tokens & {
49
- [key: string]: unknown;
50
- };
51
-
52
- export type { Config as C, DisplayMode as D, Endpoints as E, ForwardedTokens as F, SessionData as S, Tokens as T, User as U };