@civic/auth 0.3.7 → 0.3.8-beta.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +3 -0
- package/dist/cjs/nextjs/GetUser.d.ts +6 -0
- package/dist/cjs/nextjs/GetUser.d.ts.map +1 -0
- package/dist/cjs/nextjs/GetUser.js +11 -0
- package/dist/cjs/nextjs/GetUser.js.map +1 -0
- package/dist/cjs/nextjs/NextAuthenticationRefresherImpl.d.ts +11 -0
- package/dist/cjs/nextjs/NextAuthenticationRefresherImpl.d.ts.map +1 -0
- package/dist/cjs/nextjs/NextAuthenticationRefresherImpl.js +21 -0
- package/dist/cjs/nextjs/NextAuthenticationRefresherImpl.js.map +1 -0
- package/dist/cjs/nextjs/NextClientAuthenticationRefresher.d.ts +3 -4
- package/dist/cjs/nextjs/NextClientAuthenticationRefresher.d.ts.map +1 -1
- package/dist/cjs/nextjs/NextClientAuthenticationRefresher.js +14 -12
- package/dist/cjs/nextjs/NextClientAuthenticationRefresher.js.map +1 -1
- package/dist/cjs/nextjs/NextServerAuthenticationRefresherImpl.d.ts +2 -1
- package/dist/cjs/nextjs/NextServerAuthenticationRefresherImpl.d.ts.map +1 -1
- package/dist/cjs/nextjs/NextServerAuthenticationRefresherImpl.js +10 -2
- package/dist/cjs/nextjs/NextServerAuthenticationRefresherImpl.js.map +1 -1
- package/dist/cjs/nextjs/hooks/useRefresh.d.ts +3 -1
- package/dist/cjs/nextjs/hooks/useRefresh.d.ts.map +1 -1
- package/dist/cjs/nextjs/hooks/useRefresh.js +10 -2
- package/dist/cjs/nextjs/hooks/useRefresh.js.map +1 -1
- package/dist/cjs/nextjs/providers/NextAuthProvider.d.ts.map +1 -1
- package/dist/cjs/nextjs/providers/NextAuthProvider.js +7 -1
- package/dist/cjs/nextjs/providers/NextAuthProvider.js.map +1 -1
- package/dist/cjs/nextjs/routeHandler.d.ts.map +1 -1
- package/dist/cjs/nextjs/routeHandler.js +18 -11
- package/dist/cjs/nextjs/routeHandler.js.map +1 -1
- package/dist/cjs/reactjs/components/LoadingSpinner.d.ts +7 -0
- package/dist/cjs/reactjs/components/LoadingSpinner.d.ts.map +1 -0
- package/dist/cjs/reactjs/components/LoadingSpinner.js +33 -0
- package/dist/cjs/reactjs/components/LoadingSpinner.js.map +1 -0
- package/dist/cjs/reactjs/hooks/useAuth.d.ts +3 -0
- package/dist/cjs/reactjs/hooks/useAuth.d.ts.map +1 -0
- package/dist/cjs/reactjs/hooks/useAuth.js +15 -0
- package/dist/cjs/reactjs/hooks/useAuth.js.map +1 -0
- package/dist/cjs/reactjs/hooks/useSignIn.d.ts +6 -0
- package/dist/cjs/reactjs/hooks/useSignIn.d.ts.map +1 -0
- package/dist/cjs/reactjs/hooks/useSignIn.js +38 -0
- package/dist/cjs/reactjs/hooks/useSignIn.js.map +1 -0
- package/dist/cjs/reactjs/providers/AuthProvider.d.ts.map +1 -1
- package/dist/cjs/reactjs/providers/AuthProvider.js +8 -0
- package/dist/cjs/reactjs/providers/AuthProvider.js.map +1 -1
- package/dist/cjs/reactjs/providers/ClientTokenExchangeSessionProvider.d.ts.map +1 -1
- package/dist/cjs/reactjs/providers/ClientTokenExchangeSessionProvider.js +0 -1
- package/dist/cjs/reactjs/providers/ClientTokenExchangeSessionProvider.js.map +1 -1
- package/dist/cjs/server/refresh.d.ts.map +1 -1
- package/dist/cjs/server/refresh.js +4 -1
- package/dist/cjs/server/refresh.js.map +1 -1
- package/dist/cjs/services/AuthenticationService.d.ts.map +1 -1
- package/dist/cjs/services/AuthenticationService.js +0 -5
- package/dist/cjs/services/AuthenticationService.js.map +1 -1
- package/dist/cjs/shared/components/CivicAuthIframe.d.ts.map +1 -1
- package/dist/cjs/shared/components/CivicAuthIframe.js +7 -1
- package/dist/cjs/shared/components/CivicAuthIframe.js.map +1 -1
- package/dist/cjs/shared/hooks/useClientTokenExchangeSession.d.ts +3 -0
- package/dist/cjs/shared/hooks/useClientTokenExchangeSession.d.ts.map +1 -0
- package/dist/cjs/shared/hooks/useClientTokenExchangeSession.js +16 -0
- package/dist/cjs/shared/hooks/useClientTokenExchangeSession.js.map +1 -0
- package/dist/cjs/shared/hooks/useRefresh.d.ts +3 -1
- package/dist/cjs/shared/hooks/useRefresh.d.ts.map +1 -1
- package/dist/cjs/shared/hooks/useRefresh.js +10 -2
- package/dist/cjs/shared/hooks/useRefresh.js.map +1 -1
- package/dist/cjs/shared/lib/AuthenticationRefresherImpl.d.ts +2 -2
- package/dist/cjs/shared/lib/AuthenticationRefresherImpl.d.ts.map +1 -1
- package/dist/cjs/shared/lib/AuthenticationRefresherImpl.js +7 -4
- package/dist/cjs/shared/lib/AuthenticationRefresherImpl.js.map +1 -1
- package/dist/cjs/shared/lib/BrowserAuthenticationRefresher.d.ts +11 -0
- package/dist/cjs/shared/lib/BrowserAuthenticationRefresher.d.ts.map +1 -0
- package/dist/cjs/shared/lib/BrowserAuthenticationRefresher.js +63 -0
- package/dist/cjs/shared/lib/BrowserAuthenticationRefresher.js.map +1 -0
- package/dist/cjs/shared/lib/GenericAuthenticationRefresher copy.d.ts +18 -0
- package/dist/cjs/shared/lib/GenericAuthenticationRefresher copy.d.ts.map +1 -0
- package/dist/cjs/shared/lib/GenericAuthenticationRefresher copy.js +85 -0
- package/dist/cjs/shared/lib/GenericAuthenticationRefresher copy.js.map +1 -0
- package/dist/cjs/shared/lib/GenericAuthenticationRefresher.d.ts +2 -4
- package/dist/cjs/shared/lib/GenericAuthenticationRefresher.d.ts.map +1 -1
- package/dist/cjs/shared/lib/GenericAuthenticationRefresher.js +9 -36
- package/dist/cjs/shared/lib/GenericAuthenticationRefresher.js.map +1 -1
- package/dist/cjs/shared/lib/util.d.ts.map +1 -1
- package/dist/cjs/shared/lib/util.js +14 -1
- package/dist/cjs/shared/lib/util.js.map +1 -1
- package/dist/cjs/shared/providers/AuthProvider.d.ts +22 -0
- package/dist/cjs/shared/providers/AuthProvider.d.ts.map +1 -0
- package/dist/cjs/shared/providers/AuthProvider.js +108 -0
- package/dist/cjs/shared/providers/AuthProvider.js.map +1 -0
- package/dist/cjs/shared/providers/CivicAuthProvider.d.ts +6 -0
- package/dist/cjs/shared/providers/CivicAuthProvider.d.ts.map +1 -0
- package/dist/cjs/shared/providers/CivicAuthProvider.js +38 -0
- package/dist/cjs/shared/providers/CivicAuthProvider.js.map +1 -0
- package/dist/cjs/shared/providers/ClientTokenExchangeSessionProvider.d.ts +17 -0
- package/dist/cjs/shared/providers/ClientTokenExchangeSessionProvider.d.ts.map +1 -0
- package/dist/cjs/shared/providers/ClientTokenExchangeSessionProvider.js +168 -0
- package/dist/cjs/shared/providers/ClientTokenExchangeSessionProvider.js.map +1 -0
- package/dist/esm/nextjs/GetUser.d.ts +6 -0
- package/dist/esm/nextjs/GetUser.d.ts.map +1 -0
- package/dist/esm/nextjs/GetUser.js +7 -0
- package/dist/esm/nextjs/GetUser.js.map +1 -0
- package/dist/esm/nextjs/NextClientAuthenticationRefresher.d.ts +3 -4
- package/dist/esm/nextjs/NextClientAuthenticationRefresher.d.ts.map +1 -1
- package/dist/esm/nextjs/NextClientAuthenticationRefresher.js +14 -12
- package/dist/esm/nextjs/NextClientAuthenticationRefresher.js.map +1 -1
- package/dist/esm/nextjs/NextServerAuthenticationRefresherImpl.d.ts +2 -1
- package/dist/esm/nextjs/NextServerAuthenticationRefresherImpl.d.ts.map +1 -1
- package/dist/esm/nextjs/NextServerAuthenticationRefresherImpl.js +10 -2
- package/dist/esm/nextjs/NextServerAuthenticationRefresherImpl.js.map +1 -1
- package/dist/esm/nextjs/hooks/useRefresh.d.ts +3 -1
- package/dist/esm/nextjs/hooks/useRefresh.d.ts.map +1 -1
- package/dist/esm/nextjs/hooks/useRefresh.js +10 -2
- package/dist/esm/nextjs/hooks/useRefresh.js.map +1 -1
- package/dist/esm/nextjs/providers/NextAuthProvider.d.ts.map +1 -1
- package/dist/esm/nextjs/providers/NextAuthProvider.js +7 -1
- package/dist/esm/nextjs/providers/NextAuthProvider.js.map +1 -1
- package/dist/esm/nextjs/routeHandler.d.ts.map +1 -1
- package/dist/esm/nextjs/routeHandler.js +18 -11
- package/dist/esm/nextjs/routeHandler.js.map +1 -1
- package/dist/esm/reactjs/hooks/useAuth.d.ts +3 -0
- package/dist/esm/reactjs/hooks/useAuth.d.ts.map +1 -0
- package/dist/esm/reactjs/hooks/useAuth.js +12 -0
- package/dist/esm/reactjs/hooks/useAuth.js.map +1 -0
- package/dist/esm/reactjs/hooks/useSignIn.d.ts +6 -0
- package/dist/esm/reactjs/hooks/useSignIn.d.ts.map +1 -0
- package/dist/esm/reactjs/hooks/useSignIn.js +34 -0
- package/dist/esm/reactjs/hooks/useSignIn.js.map +1 -0
- package/dist/esm/reactjs/providers/AuthProvider.d.ts.map +1 -1
- package/dist/esm/reactjs/providers/AuthProvider.js +8 -0
- package/dist/esm/reactjs/providers/AuthProvider.js.map +1 -1
- package/dist/esm/reactjs/providers/ClientTokenExchangeSessionProvider.d.ts.map +1 -1
- package/dist/esm/reactjs/providers/ClientTokenExchangeSessionProvider.js +1 -2
- package/dist/esm/reactjs/providers/ClientTokenExchangeSessionProvider.js.map +1 -1
- package/dist/esm/server/refresh.d.ts.map +1 -1
- package/dist/esm/server/refresh.js +4 -1
- package/dist/esm/server/refresh.js.map +1 -1
- package/dist/esm/services/AuthenticationService.d.ts.map +1 -1
- package/dist/esm/services/AuthenticationService.js +0 -5
- package/dist/esm/services/AuthenticationService.js.map +1 -1
- package/dist/esm/shared/components/CivicAuthIframe.d.ts.map +1 -1
- package/dist/esm/shared/components/CivicAuthIframe.js +8 -2
- package/dist/esm/shared/components/CivicAuthIframe.js.map +1 -1
- package/dist/esm/shared/hooks/useClientTokenExchangeSession.d.ts +3 -0
- package/dist/esm/shared/hooks/useClientTokenExchangeSession.d.ts.map +1 -0
- package/dist/esm/shared/hooks/useClientTokenExchangeSession.js +13 -0
- package/dist/esm/shared/hooks/useClientTokenExchangeSession.js.map +1 -0
- package/dist/esm/shared/hooks/useRefresh.d.ts +3 -1
- package/dist/esm/shared/hooks/useRefresh.d.ts.map +1 -1
- package/dist/esm/shared/hooks/useRefresh.js +10 -2
- package/dist/esm/shared/hooks/useRefresh.js.map +1 -1
- package/dist/esm/shared/lib/AuthenticationRefresherImpl.d.ts +2 -2
- package/dist/esm/shared/lib/AuthenticationRefresherImpl.d.ts.map +1 -1
- package/dist/esm/shared/lib/AuthenticationRefresherImpl.js +7 -4
- package/dist/esm/shared/lib/AuthenticationRefresherImpl.js.map +1 -1
- package/dist/esm/shared/lib/BrowserAuthenticationRefresher.d.ts +11 -0
- package/dist/esm/shared/lib/BrowserAuthenticationRefresher.d.ts.map +1 -0
- package/dist/esm/shared/lib/BrowserAuthenticationRefresher.js +59 -0
- package/dist/esm/shared/lib/BrowserAuthenticationRefresher.js.map +1 -0
- package/dist/esm/shared/lib/GenericAuthenticationRefresher.d.ts +2 -4
- package/dist/esm/shared/lib/GenericAuthenticationRefresher.d.ts.map +1 -1
- package/dist/esm/shared/lib/GenericAuthenticationRefresher.js +11 -38
- package/dist/esm/shared/lib/GenericAuthenticationRefresher.js.map +1 -1
- package/dist/esm/shared/lib/util.d.ts.map +1 -1
- package/dist/esm/shared/lib/util.js +14 -1
- package/dist/esm/shared/lib/util.js.map +1 -1
- package/dist/esm/shared/providers/AuthProvider.d.ts +22 -0
- package/dist/esm/shared/providers/AuthProvider.d.ts.map +1 -0
- package/dist/esm/shared/providers/AuthProvider.js +72 -0
- package/dist/esm/shared/providers/AuthProvider.js.map +1 -0
- package/dist/esm/shared/providers/CivicAuthProvider.d.ts +6 -0
- package/dist/esm/shared/providers/CivicAuthProvider.d.ts.map +1 -0
- package/dist/esm/shared/providers/CivicAuthProvider.js +32 -0
- package/dist/esm/shared/providers/CivicAuthProvider.js.map +1 -0
- package/dist/esm/shared/providers/ClientTokenExchangeSessionProvider.d.ts +17 -0
- package/dist/esm/shared/providers/ClientTokenExchangeSessionProvider.d.ts.map +1 -0
- package/dist/esm/shared/providers/ClientTokenExchangeSessionProvider.js +131 -0
- package/dist/esm/shared/providers/ClientTokenExchangeSessionProvider.js.map +1 -0
- package/dist/nextjs/providers/NextAuthProvider.d.ts.map +1 -1
- package/dist/nextjs/providers/NextAuthProvider.js +9 -4
- package/dist/nextjs/providers/NextAuthProvider.js.map +1 -1
- package/dist/reactjs/providers/AuthProvider.d.ts.map +1 -1
- package/dist/reactjs/providers/AuthProvider.js +3 -1
- package/dist/reactjs/providers/AuthProvider.js.map +1 -1
- package/dist/shared/components/CivicAuthIframeContainer.d.ts.map +1 -1
- package/dist/shared/components/CivicAuthIframeContainer.js +4 -1
- package/dist/shared/components/CivicAuthIframeContainer.js.map +1 -1
- package/dist/shared/hooks/useSignIn.js +3 -3
- package/dist/shared/hooks/useSignIn.js.map +1 -1
- package/dist/shared/lib/iframeUtils.d.ts +1 -1
- package/dist/shared/lib/iframeUtils.d.ts.map +1 -1
- package/dist/shared/lib/iframeUtils.js +2 -2
- package/dist/shared/lib/iframeUtils.js.map +1 -1
- package/dist/shared/providers/IframeProvider.d.ts +3 -0
- package/dist/shared/providers/IframeProvider.d.ts.map +1 -1
- package/dist/shared/providers/IframeProvider.js +5 -0
- package/dist/shared/providers/IframeProvider.js.map +1 -1
- package/dist/shared/version.d.ts +1 -1
- package/dist/shared/version.d.ts.map +1 -1
- package/dist/shared/version.js +1 -1
- package/dist/shared/version.js.map +1 -1
- package/dist/tsconfig.cjs.tsbuildinfo +1 -1
- package/dist/tsconfig.esm.tsbuildinfo +1 -1
- package/package.json +1 -1
|
@@ -111,6 +111,11 @@ export async function storeServerTokens(storage, tokens) {
|
|
|
111
111
|
const cookieStorage = storage;
|
|
112
112
|
const now = Math.floor(Date.now() / 1000);
|
|
113
113
|
const accessTokenMaxAge = accessTokenExpiresAt && accessTokenExpiresAt - now;
|
|
114
|
+
console.log("storeServerTokens timestamps", {
|
|
115
|
+
now,
|
|
116
|
+
accessTokenMaxAge,
|
|
117
|
+
accessTokenExpiresAt,
|
|
118
|
+
});
|
|
114
119
|
const cookiesOverride = {
|
|
115
120
|
...(accessTokenMaxAge ? { maxAge: accessTokenMaxAge } : {}),
|
|
116
121
|
};
|
|
@@ -120,7 +125,15 @@ export async function storeServerTokens(storage, tokens) {
|
|
|
120
125
|
const refreshCookiesOverride = {
|
|
121
126
|
...(refreshTokenMaxAge ? { maxAge: refreshTokenMaxAge } : {}),
|
|
122
127
|
};
|
|
123
|
-
|
|
128
|
+
console.log("storeServerTokens overrides", {
|
|
129
|
+
cookiesOverride,
|
|
130
|
+
refreshCookiesOverride,
|
|
131
|
+
});
|
|
132
|
+
const idTokenExpiry = decodeJwt(tokens.id_token)?.exp;
|
|
133
|
+
const idTokenMaxAge = idTokenExpiry && idTokenExpiry - now;
|
|
134
|
+
await cookieStorage.set(OAuthTokens.ID_TOKEN, tokens.id_token, {
|
|
135
|
+
...(idTokenMaxAge ? { maxAge: idTokenMaxAge } : {}),
|
|
136
|
+
});
|
|
124
137
|
await cookieStorage.set(OAuthTokens.ACCESS_TOKEN, tokens.access_token, cookiesOverride);
|
|
125
138
|
if (tokens.refresh_token) {
|
|
126
139
|
await cookieStorage.set(OAuthTokens.REFRESH_TOKEN, tokens.refresh_token, refreshCookiesOverride);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"util.js","sourceRoot":"","sources":["../../../../src/shared/lib/util.ts"],"names":[],"mappings":"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","sourcesContent":["// Utility functions shared by auth server and client integrations\n// Typically these functions should be used inside AuthenticationInitiator and AuthenticationResolver implementations\nimport type {\n AuthStorage,\n Endpoints,\n OIDCTokenResponseBody,\n ParsedTokens,\n} from \"@/types.js\";\nimport {\n AUTH_SERVER_LEGACY_SESSION,\n AUTH_SERVER_SESSION,\n OAuthTokens,\n} from \"./types.js\";\nimport { OAuth2Client } from \"oslo/oauth2\";\nimport { getIssuerVariations, getOauthEndpoints } from \"@/lib/oauth.js\";\nimport * as jose from \"jose\";\nimport { withoutUndefined } from \"@/utils.js\";\nimport type { PKCEConsumer, PKCEProducer } from \"@/services/types.js\";\nimport { GenericUserSession } from \"@/shared/lib/UserSession.js\";\nimport { decodeJwt, type JWTPayload } from \"jose\";\nimport type { CookieStorage } from \"./storage.js\";\nimport {\n AUTOREFRESH_TIMEOUT_NAME,\n LOGOUT_STATE,\n REFRESH_IN_PROGRESS,\n} from \"@/constants.js\";\n\n/**\n * Given a PKCE code verifier, derive the code challenge using SHA\n */\nexport async function deriveCodeChallenge(\n codeVerifier: string,\n method: \"Plain\" | \"S256\" = \"S256\",\n): Promise<string> {\n if (method === \"Plain\") {\n console.warn(\"Using insecure plain code challenge method\");\n return codeVerifier;\n }\n\n const encoder = new TextEncoder();\n const data = encoder.encode(codeVerifier);\n const digest = await crypto.subtle.digest(\"SHA-256\", data);\n return btoa(String.fromCharCode(...new Uint8Array(digest)))\n .replace(/\\+/g, \"-\")\n .replace(/\\//g, \"_\")\n .replace(/=+$/, \"\");\n}\n\nexport async function getEndpointsWithOverrides(\n oauthServer: string,\n endpointOverrides: Partial<Endpoints> = {},\n): Promise<Endpoints> {\n const endpoints = await getOauthEndpoints(oauthServer);\n return {\n ...endpoints,\n ...endpointOverrides,\n };\n}\n\nexport async function generateOauthLoginUrl(config: {\n clientId: string;\n scopes: string[];\n state: string;\n redirectUrl: string;\n oauthServer: string;\n nonce?: string;\n endpointOverrides?: Partial<Endpoints>;\n // used to get the PKCE challenge\n pkceConsumer: PKCEConsumer;\n}): Promise<URL> {\n const endpoints = await getEndpointsWithOverrides(\n config.oauthServer,\n config.endpointOverrides,\n );\n const oauth2Client = buildOauth2Client(\n config.clientId,\n config.redirectUrl,\n endpoints,\n );\n const challenge = await config.pkceConsumer.getCodeChallenge();\n const oAuthUrl = await oauth2Client.createAuthorizationURL({\n state: config.state,\n scopes: config.scopes,\n });\n // The OAuth2 client supports PKCE, but does not allow passing in a code challenge from some other source\n // It only allows passing in a code verifier which it then hashes itself.\n oAuthUrl.searchParams.append(\"code_challenge\", challenge);\n oAuthUrl.searchParams.append(\"code_challenge_method\", \"S256\");\n if (config.nonce) {\n // nonce isn't supported by oslo, so we add it manually\n oAuthUrl.searchParams.append(\"nonce\", config.nonce);\n }\n // Required by the auth server for offline_access scope\n oAuthUrl.searchParams.append(\"prompt\", \"consent\");\n\n return oAuthUrl;\n}\n\nexport async function generateOauthLogoutUrl(config: {\n clientId: string;\n redirectUrl: string;\n idToken: string;\n state: string;\n oauthServer: string;\n endpointOverrides?: Partial<Endpoints>;\n}): Promise<URL> {\n const endpoints = await getEndpointsWithOverrides(\n config.oauthServer,\n config.endpointOverrides,\n );\n const endSessionUrl = new URL(endpoints.endsession);\n endSessionUrl.searchParams.append(\"client_id\", config.clientId);\n endSessionUrl.searchParams.append(\"id_token_hint\", config.idToken);\n endSessionUrl.searchParams.append(\"state\", config.state);\n endSessionUrl.searchParams.append(\n \"post_logout_redirect_uri\",\n config.redirectUrl,\n );\n return endSessionUrl;\n}\n\nexport function buildOauth2Client(\n clientId: string,\n redirectUri: string,\n endpoints: Endpoints,\n): OAuth2Client {\n return new OAuth2Client(clientId, endpoints.auth, endpoints.token, {\n redirectURI: redirectUri,\n });\n}\n\nexport async function exchangeTokens(\n code: string,\n state: string,\n pkceProducer: PKCEProducer,\n oauth2Client: OAuth2Client,\n oauthServer: string,\n endpoints: Endpoints,\n) {\n const codeVerifier = await pkceProducer.getCodeVerifier();\n if (!codeVerifier) throw new Error(\"Code verifier not found in state\");\n\n const tokens =\n await oauth2Client.validateAuthorizationCode<OIDCTokenResponseBody>(code, {\n codeVerifier,\n });\n\n // Validate relevant tokens\n try {\n await validateOauth2Tokens(tokens, endpoints, oauth2Client, oauthServer);\n } catch (error) {\n console.error(\"tokenExchange error\", { error, tokens });\n throw new Error(\n `OIDC tokens validation failed: ${(error as Error).message}`,\n );\n }\n return tokens;\n}\n\nexport const getAccessTokenExpiresAt = (\n tokens: OIDCTokenResponseBody,\n): number => {\n const parsedAccessToken = decodeJwt(tokens.access_token);\n if (parsedAccessToken?.exp || false) {\n return parsedAccessToken.exp;\n } else if (tokens.expires_in) {\n const now = Math.floor(new Date().getTime() / 1000);\n return now + tokens.expires_in;\n } else {\n throw new Error(\"Cannot determine access token expiry!\");\n }\n};\nexport async function setAccessTokenExpiresAt(\n storage: AuthStorage | CookieStorage,\n tokens: OIDCTokenResponseBody,\n) {\n // try to extract absolute expiry time from access token but fallback to calculation if not possible\n const accessTokenExpiresAt = getAccessTokenExpiresAt(tokens);\n await storage.set(\n OAuthTokens.ACCESS_TOKEN_EXPIRES_AT,\n accessTokenExpiresAt.toString(),\n );\n}\n\nexport async function storeTokens(\n storage: AuthStorage,\n tokens: OIDCTokenResponseBody,\n) {\n await storage.set(OAuthTokens.ID_TOKEN, tokens.id_token);\n await storage.set(OAuthTokens.ACCESS_TOKEN, tokens.access_token);\n if (tokens.refresh_token) {\n await storage.set(OAuthTokens.REFRESH_TOKEN, tokens.refresh_token);\n }\n await setAccessTokenExpiresAt(storage, tokens);\n}\n\nexport async function storeServerTokens(\n storage: AuthStorage | CookieStorage,\n tokens: OIDCTokenResponseBody,\n) {\n const accessTokenExpiresAt = getAccessTokenExpiresAt(tokens);\n const cookieStorage = storage as CookieStorage;\n const now = Math.floor(Date.now() / 1000);\n const accessTokenMaxAge = accessTokenExpiresAt && accessTokenExpiresAt - now;\n\n const cookiesOverride = {\n ...(accessTokenMaxAge ? { maxAge: accessTokenMaxAge } : {}),\n };\n // the refresh token must be longer-lived than the access token max age to allow time for automatic refresh\n // as it's not a JWT, we derive it from the access token max age and add a margin\n const refreshTokenMaxAge = accessTokenMaxAge && accessTokenMaxAge + 5 * 60;\n const refreshCookiesOverride = {\n ...(refreshTokenMaxAge ? { maxAge: refreshTokenMaxAge } : {}),\n };\n await cookieStorage.set(\n OAuthTokens.ID_TOKEN,\n tokens.id_token,\n cookiesOverride,\n );\n await cookieStorage.set(\n OAuthTokens.ACCESS_TOKEN,\n tokens.access_token,\n cookiesOverride,\n );\n if (tokens.refresh_token) {\n await cookieStorage.set(\n OAuthTokens.REFRESH_TOKEN,\n tokens.refresh_token,\n refreshCookiesOverride,\n );\n }\n await storage.set(\n OAuthTokens.ACCESS_TOKEN_EXPIRES_AT,\n accessTokenExpiresAt.toString(),\n cookiesOverride,\n );\n}\n\nexport async function clearTokens(storage: AuthStorage) {\n console.log(\"clearTokens\");\n // clear all local storage keys related to OAuth and CivicAuth SDK\n const clearOAuthPromises = [\n ...Object.values(OAuthTokens),\n REFRESH_IN_PROGRESS,\n AUTOREFRESH_TIMEOUT_NAME,\n LOGOUT_STATE,\n ].map(async (key) => {\n await storage.delete(key);\n });\n await Promise.all([...clearOAuthPromises]);\n}\n\nexport async function clearAuthServerSession(storage: AuthStorage) {\n await storage.delete(AUTH_SERVER_SESSION);\n await storage.delete(AUTH_SERVER_LEGACY_SESSION);\n}\n\nexport async function clearUser(storage: AuthStorage) {\n const userSession = new GenericUserSession(storage);\n await userSession.clear();\n}\n\nexport async function retrieveTokens(\n storage: AuthStorage,\n): Promise<OIDCTokenResponseBody | null> {\n const idToken = await storage.get(OAuthTokens.ID_TOKEN);\n const accessToken = await storage.get(OAuthTokens.ACCESS_TOKEN);\n const refreshToken = await storage.get(OAuthTokens.REFRESH_TOKEN);\n const accessTokenExpiresAt = await storage.get(\n OAuthTokens.ACCESS_TOKEN_EXPIRES_AT,\n );\n\n if (!idToken || !accessToken) return null;\n\n return {\n id_token: idToken,\n access_token: accessToken,\n refresh_token: refreshToken ?? undefined,\n access_token_expires_at:\n accessTokenExpiresAt !== null\n ? parseInt(accessTokenExpiresAt, 10)\n : undefined, // Convert string to number\n };\n}\n\nexport async function retrieveAccessTokenExpiresAt(\n storage: AuthStorage,\n): Promise<number> {\n return Number(await storage.get(OAuthTokens.ACCESS_TOKEN_EXPIRES_AT));\n}\n\nexport async function validateOauth2Tokens(\n tokens: OIDCTokenResponseBody,\n endpoints: Endpoints,\n oauth2Client: OAuth2Client,\n issuer: string,\n): Promise<ParsedTokens> {\n const JWKS = jose.createRemoteJWKSet(new URL(endpoints.jwks));\n\n // validate the ID token\n const idTokenResponse = await jose.jwtVerify<JWTPayload>(\n tokens.id_token,\n JWKS,\n {\n issuer: getIssuerVariations(issuer),\n audience: oauth2Client.clientId,\n },\n );\n\n // validate the access token\n const accessTokenResponse = await jose.jwtVerify<JWTPayload>(\n tokens.access_token,\n JWKS,\n {\n issuer: getIssuerVariations(issuer),\n },\n );\n\n return withoutUndefined({\n id_token: idTokenResponse.payload,\n access_token: accessTokenResponse.payload,\n refresh_token: tokens.refresh_token,\n });\n}\n"]}
|
|
1
|
+
{"version":3,"file":"util.js","sourceRoot":"","sources":["../../../../src/shared/lib/util.ts"],"names":[],"mappings":"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","sourcesContent":["// Utility functions shared by auth server and client integrations\n// Typically these functions should be used inside AuthenticationInitiator and AuthenticationResolver implementations\nimport type {\n AuthStorage,\n Endpoints,\n OIDCTokenResponseBody,\n ParsedTokens,\n} from \"@/types.js\";\nimport {\n AUTH_SERVER_LEGACY_SESSION,\n AUTH_SERVER_SESSION,\n OAuthTokens,\n} from \"./types.js\";\nimport { OAuth2Client } from \"oslo/oauth2\";\nimport { getIssuerVariations, getOauthEndpoints } from \"@/lib/oauth.js\";\nimport * as jose from \"jose\";\nimport { withoutUndefined } from \"@/utils.js\";\nimport type { PKCEConsumer, PKCEProducer } from \"@/services/types.js\";\nimport { GenericUserSession } from \"@/shared/lib/UserSession.js\";\nimport { decodeJwt, type JWTPayload } from \"jose\";\nimport type { CookieStorage } from \"./storage.js\";\nimport {\n AUTOREFRESH_TIMEOUT_NAME,\n LOGOUT_STATE,\n REFRESH_IN_PROGRESS,\n} from \"@/constants.js\";\n\n/**\n * Given a PKCE code verifier, derive the code challenge using SHA\n */\nexport async function deriveCodeChallenge(\n codeVerifier: string,\n method: \"Plain\" | \"S256\" = \"S256\",\n): Promise<string> {\n if (method === \"Plain\") {\n console.warn(\"Using insecure plain code challenge method\");\n return codeVerifier;\n }\n\n const encoder = new TextEncoder();\n const data = encoder.encode(codeVerifier);\n const digest = await crypto.subtle.digest(\"SHA-256\", data);\n return btoa(String.fromCharCode(...new Uint8Array(digest)))\n .replace(/\\+/g, \"-\")\n .replace(/\\//g, \"_\")\n .replace(/=+$/, \"\");\n}\n\nexport async function getEndpointsWithOverrides(\n oauthServer: string,\n endpointOverrides: Partial<Endpoints> = {},\n): Promise<Endpoints> {\n const endpoints = await getOauthEndpoints(oauthServer);\n return {\n ...endpoints,\n ...endpointOverrides,\n };\n}\n\nexport async function generateOauthLoginUrl(config: {\n clientId: string;\n scopes: string[];\n state: string;\n redirectUrl: string;\n oauthServer: string;\n nonce?: string;\n endpointOverrides?: Partial<Endpoints>;\n // used to get the PKCE challenge\n pkceConsumer: PKCEConsumer;\n}): Promise<URL> {\n const endpoints = await getEndpointsWithOverrides(\n config.oauthServer,\n config.endpointOverrides,\n );\n const oauth2Client = buildOauth2Client(\n config.clientId,\n config.redirectUrl,\n endpoints,\n );\n const challenge = await config.pkceConsumer.getCodeChallenge();\n const oAuthUrl = await oauth2Client.createAuthorizationURL({\n state: config.state,\n scopes: config.scopes,\n });\n // The OAuth2 client supports PKCE, but does not allow passing in a code challenge from some other source\n // It only allows passing in a code verifier which it then hashes itself.\n oAuthUrl.searchParams.append(\"code_challenge\", challenge);\n oAuthUrl.searchParams.append(\"code_challenge_method\", \"S256\");\n if (config.nonce) {\n // nonce isn't supported by oslo, so we add it manually\n oAuthUrl.searchParams.append(\"nonce\", config.nonce);\n }\n // Required by the auth server for offline_access scope\n oAuthUrl.searchParams.append(\"prompt\", \"consent\");\n\n return oAuthUrl;\n}\n\nexport async function generateOauthLogoutUrl(config: {\n clientId: string;\n redirectUrl: string;\n idToken: string;\n state: string;\n oauthServer: string;\n endpointOverrides?: Partial<Endpoints>;\n}): Promise<URL> {\n const endpoints = await getEndpointsWithOverrides(\n config.oauthServer,\n config.endpointOverrides,\n );\n const endSessionUrl = new URL(endpoints.endsession);\n endSessionUrl.searchParams.append(\"client_id\", config.clientId);\n endSessionUrl.searchParams.append(\"id_token_hint\", config.idToken);\n endSessionUrl.searchParams.append(\"state\", config.state);\n endSessionUrl.searchParams.append(\n \"post_logout_redirect_uri\",\n config.redirectUrl,\n );\n return endSessionUrl;\n}\n\nexport function buildOauth2Client(\n clientId: string,\n redirectUri: string,\n endpoints: Endpoints,\n): OAuth2Client {\n return new OAuth2Client(clientId, endpoints.auth, endpoints.token, {\n redirectURI: redirectUri,\n });\n}\n\nexport async function exchangeTokens(\n code: string,\n state: string,\n pkceProducer: PKCEProducer,\n oauth2Client: OAuth2Client,\n oauthServer: string,\n endpoints: Endpoints,\n) {\n const codeVerifier = await pkceProducer.getCodeVerifier();\n if (!codeVerifier) throw new Error(\"Code verifier not found in state\");\n\n const tokens =\n await oauth2Client.validateAuthorizationCode<OIDCTokenResponseBody>(code, {\n codeVerifier,\n });\n\n // Validate relevant tokens\n try {\n await validateOauth2Tokens(tokens, endpoints, oauth2Client, oauthServer);\n } catch (error) {\n console.error(\"tokenExchange error\", { error, tokens });\n throw new Error(\n `OIDC tokens validation failed: ${(error as Error).message}`,\n );\n }\n return tokens;\n}\n\nexport const getAccessTokenExpiresAt = (\n tokens: OIDCTokenResponseBody,\n): number => {\n const parsedAccessToken = decodeJwt(tokens.access_token);\n if (parsedAccessToken?.exp || false) {\n return parsedAccessToken.exp;\n } else if (tokens.expires_in) {\n const now = Math.floor(new Date().getTime() / 1000);\n return now + tokens.expires_in;\n } else {\n throw new Error(\"Cannot determine access token expiry!\");\n }\n};\nexport async function setAccessTokenExpiresAt(\n storage: AuthStorage | CookieStorage,\n tokens: OIDCTokenResponseBody,\n) {\n // try to extract absolute expiry time from access token but fallback to calculation if not possible\n const accessTokenExpiresAt = getAccessTokenExpiresAt(tokens);\n await storage.set(\n OAuthTokens.ACCESS_TOKEN_EXPIRES_AT,\n accessTokenExpiresAt.toString(),\n );\n}\n\nexport async function storeTokens(\n storage: AuthStorage,\n tokens: OIDCTokenResponseBody,\n) {\n await storage.set(OAuthTokens.ID_TOKEN, tokens.id_token);\n await storage.set(OAuthTokens.ACCESS_TOKEN, tokens.access_token);\n if (tokens.refresh_token) {\n await storage.set(OAuthTokens.REFRESH_TOKEN, tokens.refresh_token);\n }\n await setAccessTokenExpiresAt(storage, tokens);\n}\n\nexport async function storeServerTokens(\n storage: AuthStorage | CookieStorage,\n tokens: OIDCTokenResponseBody,\n) {\n const accessTokenExpiresAt = getAccessTokenExpiresAt(tokens);\n const cookieStorage = storage as CookieStorage;\n const now = Math.floor(Date.now() / 1000);\n const accessTokenMaxAge = accessTokenExpiresAt && accessTokenExpiresAt - now;\n console.log(\"storeServerTokens timestamps\", {\n now,\n accessTokenMaxAge,\n accessTokenExpiresAt,\n });\n const cookiesOverride = {\n ...(accessTokenMaxAge ? { maxAge: accessTokenMaxAge } : {}),\n };\n // the refresh token must be longer-lived than the access token max age to allow time for automatic refresh\n // as it's not a JWT, we derive it from the access token max age and add a margin\n const refreshTokenMaxAge = accessTokenMaxAge && accessTokenMaxAge + 5 * 60;\n const refreshCookiesOverride = {\n ...(refreshTokenMaxAge ? { maxAge: refreshTokenMaxAge } : {}),\n };\n console.log(\"storeServerTokens overrides\", {\n cookiesOverride,\n refreshCookiesOverride,\n });\n const idTokenExpiry = decodeJwt(tokens.id_token)?.exp;\n const idTokenMaxAge = idTokenExpiry && idTokenExpiry - now;\n await cookieStorage.set(OAuthTokens.ID_TOKEN, tokens.id_token, {\n ...(idTokenMaxAge ? { maxAge: idTokenMaxAge } : {}),\n });\n await cookieStorage.set(\n OAuthTokens.ACCESS_TOKEN,\n tokens.access_token,\n cookiesOverride,\n );\n if (tokens.refresh_token) {\n await cookieStorage.set(\n OAuthTokens.REFRESH_TOKEN,\n tokens.refresh_token,\n refreshCookiesOverride,\n );\n }\n await storage.set(\n OAuthTokens.ACCESS_TOKEN_EXPIRES_AT,\n accessTokenExpiresAt.toString(),\n cookiesOverride,\n );\n}\n\nexport async function clearTokens(storage: AuthStorage) {\n console.log(\"clearTokens\");\n // clear all local storage keys related to OAuth and CivicAuth SDK\n const clearOAuthPromises = [\n ...Object.values(OAuthTokens),\n REFRESH_IN_PROGRESS,\n AUTOREFRESH_TIMEOUT_NAME,\n LOGOUT_STATE,\n ].map(async (key) => {\n await storage.delete(key);\n });\n await Promise.all([...clearOAuthPromises]);\n}\n\nexport async function clearAuthServerSession(storage: AuthStorage) {\n await storage.delete(AUTH_SERVER_SESSION);\n await storage.delete(AUTH_SERVER_LEGACY_SESSION);\n}\n\nexport async function clearUser(storage: AuthStorage) {\n const userSession = new GenericUserSession(storage);\n await userSession.clear();\n}\n\nexport async function retrieveTokens(\n storage: AuthStorage,\n): Promise<OIDCTokenResponseBody | null> {\n const idToken = await storage.get(OAuthTokens.ID_TOKEN);\n const accessToken = await storage.get(OAuthTokens.ACCESS_TOKEN);\n const refreshToken = await storage.get(OAuthTokens.REFRESH_TOKEN);\n const accessTokenExpiresAt = await storage.get(\n OAuthTokens.ACCESS_TOKEN_EXPIRES_AT,\n );\n if (!idToken || !accessToken) return null;\n\n return {\n id_token: idToken,\n access_token: accessToken,\n refresh_token: refreshToken ?? undefined,\n access_token_expires_at:\n accessTokenExpiresAt !== null\n ? parseInt(accessTokenExpiresAt, 10)\n : undefined, // Convert string to number\n };\n}\n\nexport async function retrieveAccessTokenExpiresAt(\n storage: AuthStorage,\n): Promise<number> {\n return Number(await storage.get(OAuthTokens.ACCESS_TOKEN_EXPIRES_AT));\n}\n\nexport async function validateOauth2Tokens(\n tokens: OIDCTokenResponseBody,\n endpoints: Endpoints,\n oauth2Client: OAuth2Client,\n issuer: string,\n): Promise<ParsedTokens> {\n const JWKS = jose.createRemoteJWKSet(new URL(endpoints.jwks));\n\n // validate the ID token\n const idTokenResponse = await jose.jwtVerify<JWTPayload>(\n tokens.id_token,\n JWKS,\n {\n issuer: getIssuerVariations(issuer),\n audience: oauth2Client.clientId,\n },\n );\n\n // validate the access token\n const accessTokenResponse = await jose.jwtVerify<JWTPayload>(\n tokens.access_token,\n JWKS,\n {\n issuer: getIssuerVariations(issuer),\n },\n );\n\n return withoutUndefined({\n id_token: idTokenResponse.payload,\n access_token: accessTokenResponse.payload,\n refresh_token: tokens.refresh_token,\n });\n}\n"]}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import React, { type ReactNode } from "react";
|
|
2
|
+
import type { Config, DisplayMode, SessionData } from "../../types.js";
|
|
3
|
+
import type { PKCEConsumer } from "../../services/types.js";
|
|
4
|
+
export type IframeMode = "embedded" | "modal";
|
|
5
|
+
export type AuthProviderProps = {
|
|
6
|
+
children: ReactNode;
|
|
7
|
+
clientId: string;
|
|
8
|
+
nonce?: string;
|
|
9
|
+
onSignIn?: (error?: Error) => void;
|
|
10
|
+
onSignOut?: () => Promise<void>;
|
|
11
|
+
iframeMode?: IframeMode;
|
|
12
|
+
config?: Config;
|
|
13
|
+
redirectUrl?: string;
|
|
14
|
+
displayMode?: DisplayMode;
|
|
15
|
+
};
|
|
16
|
+
export type InternalAuthProviderProps = AuthProviderProps & {
|
|
17
|
+
sessionData?: SessionData;
|
|
18
|
+
pkceConsumer?: PKCEConsumer;
|
|
19
|
+
};
|
|
20
|
+
declare const AuthProvider: ({ children, onSignIn, onSignOut, pkceConsumer, iframeMode, displayMode, }: InternalAuthProviderProps) => React.JSX.Element;
|
|
21
|
+
export { AuthProvider };
|
|
22
|
+
//# sourceMappingURL=AuthProvider.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"AuthProvider.d.ts","sourceRoot":"","sources":["../../../../src/shared/providers/AuthProvider.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,EAAE,KAAK,SAAS,EAAgC,MAAM,OAAO,CAAC;AAC5E,OAAO,KAAK,EAAE,MAAM,EAAE,WAAW,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAEnE,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AAkBxD,MAAM,MAAM,UAAU,GAAG,UAAU,GAAG,OAAO,CAAC;AAC9C,MAAM,MAAM,iBAAiB,GAAG;IAC9B,QAAQ,EAAE,SAAS,CAAC;IACpB,QAAQ,EAAE,MAAM,CAAC;IACjB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,QAAQ,CAAC,EAAE,CAAC,KAAK,CAAC,EAAE,KAAK,KAAK,IAAI,CAAC;IACnC,SAAS,CAAC,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;IAChC,UAAU,CAAC,EAAE,UAAU,CAAC;IACxB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,WAAW,CAAC,EAAE,WAAW,CAAC;CAC3B,CAAC;AAEF,MAAM,MAAM,yBAAyB,GAAG,iBAAiB,GAAG;IAC1D,WAAW,CAAC,EAAE,WAAW,CAAC;IAC1B,YAAY,CAAC,EAAE,YAAY,CAAC;CAC7B,CAAC;AAEF,QAAA,MAAM,YAAY,8EAOf,yBAAyB,sBAsE3B,CAAC;AAEF,OAAO,EAAE,YAAY,EAAE,CAAC"}
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import React, { useEffect, useMemo, useState } from "react";
|
|
3
|
+
import { AuthContext } from "../../shared/providers/AuthContext.js";
|
|
4
|
+
import { useSignIn } from "../../shared/hooks/useSignIn.js";
|
|
5
|
+
import { useIframe } from "../../shared/hooks/useIframe.js";
|
|
6
|
+
import { useCivicAuthConfig } from "../../shared/hooks/useCivicAuthConfig.js";
|
|
7
|
+
import { useSession } from "../../shared/hooks/useSession.js";
|
|
8
|
+
import { IFrameAndLoading } from "../../shared/components/IFrameAndLoading.js";
|
|
9
|
+
// Global this object setup
|
|
10
|
+
let globalThisObject;
|
|
11
|
+
if (typeof window !== "undefined") {
|
|
12
|
+
globalThisObject = window;
|
|
13
|
+
}
|
|
14
|
+
else if (typeof global !== "undefined") {
|
|
15
|
+
globalThisObject = global;
|
|
16
|
+
}
|
|
17
|
+
else {
|
|
18
|
+
globalThisObject = Function("return this")();
|
|
19
|
+
}
|
|
20
|
+
globalThisObject.globalThis = globalThisObject;
|
|
21
|
+
const AuthProvider = ({ children, onSignIn, onSignOut, pkceConsumer, iframeMode = "modal", displayMode = "iframe", }) => {
|
|
22
|
+
const authConfig = useCivicAuthConfig();
|
|
23
|
+
const { redirectUrl } = authConfig || {};
|
|
24
|
+
const { iframeRef } = useIframe();
|
|
25
|
+
const { signIn, signOut } = useSignIn({
|
|
26
|
+
preSignOut: onSignOut,
|
|
27
|
+
pkceConsumer,
|
|
28
|
+
displayMode: displayMode,
|
|
29
|
+
});
|
|
30
|
+
const [localSessionData, setLocalSessionData] = useState();
|
|
31
|
+
const { data: session, error: tokenExchangeError, isLoading: tokenExchangeInProgress, } = useSession();
|
|
32
|
+
useEffect(() => {
|
|
33
|
+
if (session) {
|
|
34
|
+
setLocalSessionData(session);
|
|
35
|
+
if (session.authenticated) {
|
|
36
|
+
onSignIn?.();
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
}, [onSignIn, session]);
|
|
40
|
+
const isAuthenticated = useMemo(() => {
|
|
41
|
+
return !!localSessionData?.idToken;
|
|
42
|
+
}, [localSessionData]);
|
|
43
|
+
useEffect(() => {
|
|
44
|
+
if (iframeMode === "embedded" &&
|
|
45
|
+
redirectUrl &&
|
|
46
|
+
!isAuthenticated &&
|
|
47
|
+
iframeRef?.current) {
|
|
48
|
+
signIn();
|
|
49
|
+
}
|
|
50
|
+
}, [iframeMode, redirectUrl, isAuthenticated, iframeRef, signIn]);
|
|
51
|
+
const isLoading = tokenExchangeInProgress || !authConfig;
|
|
52
|
+
const value = useMemo(() => ({
|
|
53
|
+
isLoading,
|
|
54
|
+
error: tokenExchangeError,
|
|
55
|
+
signOut,
|
|
56
|
+
isAuthenticated,
|
|
57
|
+
signIn,
|
|
58
|
+
displayMode,
|
|
59
|
+
}), [
|
|
60
|
+
isLoading,
|
|
61
|
+
tokenExchangeError,
|
|
62
|
+
isAuthenticated,
|
|
63
|
+
signIn,
|
|
64
|
+
signOut,
|
|
65
|
+
displayMode,
|
|
66
|
+
]);
|
|
67
|
+
return (React.createElement(AuthContext.Provider, { value: value },
|
|
68
|
+
React.createElement(IFrameAndLoading, { error: tokenExchangeError, isLoading: isLoading }),
|
|
69
|
+
children));
|
|
70
|
+
};
|
|
71
|
+
export { AuthProvider };
|
|
72
|
+
//# sourceMappingURL=AuthProvider.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"AuthProvider.js","sourceRoot":"","sources":["../../../../src/shared/providers/AuthProvider.tsx"],"names":[],"mappings":"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","sourcesContent":["\"use client\";\n\nimport React, { type ReactNode, useEffect, useMemo, useState } from \"react\";\nimport type { Config, DisplayMode, SessionData } from \"@/types.js\";\nimport { AuthContext } from \"@/shared/providers/AuthContext.js\";\nimport type { PKCEConsumer } from \"@/services/types.js\";\nimport { useSignIn } from \"@/shared/hooks/useSignIn.js\";\nimport { useIframe } from \"@/shared/hooks/useIframe.js\";\nimport { useCivicAuthConfig } from \"@/shared/hooks/useCivicAuthConfig.js\";\nimport { useSession } from \"@/shared/hooks/useSession.js\";\nimport { IFrameAndLoading } from \"@/shared/components/IFrameAndLoading.js\";\n\n// Global this object setup\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\nexport type IframeMode = \"embedded\" | \"modal\";\nexport type AuthProviderProps = {\n children: ReactNode;\n clientId: string;\n nonce?: string;\n onSignIn?: (error?: Error) => void;\n onSignOut?: () => Promise<void>;\n iframeMode?: IframeMode;\n config?: Config;\n redirectUrl?: string;\n displayMode?: DisplayMode;\n};\n\nexport type InternalAuthProviderProps = AuthProviderProps & {\n sessionData?: SessionData;\n pkceConsumer?: PKCEConsumer;\n};\n\nconst AuthProvider = ({\n children,\n onSignIn,\n onSignOut,\n pkceConsumer,\n iframeMode = \"modal\",\n displayMode = \"iframe\",\n}: InternalAuthProviderProps) => {\n const authConfig = useCivicAuthConfig();\n const { redirectUrl } = authConfig || {};\n const { iframeRef } = useIframe();\n\n const { signIn, signOut } = useSignIn({\n preSignOut: onSignOut,\n pkceConsumer,\n displayMode: displayMode,\n });\n\n const [localSessionData, setLocalSessionData] =\n useState<SessionData | null>();\n\n const {\n data: session,\n error: tokenExchangeError,\n isLoading: tokenExchangeInProgress,\n } = useSession();\n\n useEffect(() => {\n if (session) {\n setLocalSessionData(session);\n if (session.authenticated) {\n onSignIn?.();\n }\n }\n }, [onSignIn, session]);\n\n const isAuthenticated = useMemo(() => {\n return !!localSessionData?.idToken;\n }, [localSessionData]);\n\n useEffect(() => {\n if (\n iframeMode === \"embedded\" &&\n redirectUrl &&\n !isAuthenticated &&\n iframeRef?.current\n ) {\n signIn();\n }\n }, [iframeMode, redirectUrl, isAuthenticated, iframeRef, signIn]);\n\n const isLoading = tokenExchangeInProgress || !authConfig;\n const value = useMemo(\n () => ({\n isLoading,\n error: tokenExchangeError as Error | null,\n signOut,\n isAuthenticated,\n signIn,\n displayMode,\n }),\n [\n isLoading,\n tokenExchangeError,\n isAuthenticated,\n signIn,\n signOut,\n displayMode,\n ],\n );\n\n return (\n <AuthContext.Provider value={value}>\n <IFrameAndLoading error={tokenExchangeError} isLoading={isLoading} />\n {children}\n </AuthContext.Provider>\n );\n};\n\nexport { AuthProvider };\n"]}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
import { type AuthProviderProps } from "../../shared/providers/AuthProvider.js";
|
|
3
|
+
type CivicAuthProviderProps = Omit<AuthProviderProps, "pkceConsumer">;
|
|
4
|
+
declare const CivicAuthProvider: ({ children, ...props }: CivicAuthProviderProps) => React.JSX.Element;
|
|
5
|
+
export { CivicAuthProvider, type CivicAuthProviderProps };
|
|
6
|
+
//# sourceMappingURL=CivicAuthProvider.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"CivicAuthProvider.d.ts","sourceRoot":"","sources":["../../../../src/shared/providers/CivicAuthProvider.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,MAAM,OAAO,CAAC;AAC1B,OAAO,EAEL,KAAK,iBAAiB,EACvB,MAAM,oCAAoC,CAAC;AAY5C,KAAK,sBAAsB,GAAG,IAAI,CAAC,iBAAiB,EAAE,cAAc,CAAC,CAAC;AAmCtE,QAAA,MAAM,iBAAiB,2BAA4B,sBAAsB,sBAexE,CAAC;AAEF,OAAO,EAAE,iBAAiB,EAAE,KAAK,sBAAsB,EAAE,CAAC"}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import React from "react";
|
|
3
|
+
import { AuthProvider, } from "../../shared/providers/AuthProvider.js";
|
|
4
|
+
import { BrowserPublicClientPKCEProducer } from "../../services/PKCE.js";
|
|
5
|
+
import { UserProvider } from "../../shared/providers/UserProvider.js";
|
|
6
|
+
import { LocalStorageAdapter } from "../../browser/storage.js";
|
|
7
|
+
import { CivicAuthConfigProvider } from "../../shared/providers/CivicAuthConfigContext.js";
|
|
8
|
+
import { IframeProvider } from "../../shared/providers/IframeProvider.js";
|
|
9
|
+
import { ClientTokenExchangeSessionProvider } from "../../shared/providers/ClientTokenExchangeSessionProvider.js";
|
|
10
|
+
import { SessionProvider } from "../../shared/providers/SessionProvider.js";
|
|
11
|
+
import { useClientTokenExchangeSession } from "../../shared/hooks/useClientTokenExchangeSession.js";
|
|
12
|
+
import { TokenProvider } from "../../shared/providers/TokenProvider.js";
|
|
13
|
+
import { useAuth } from "../../shared/hooks/useAuth.js";
|
|
14
|
+
const WrapperUserProvider = ({ children }) => {
|
|
15
|
+
const { signIn, signOut, displayMode } = useAuth();
|
|
16
|
+
return (React.createElement(UserProvider, { storage: new LocalStorageAdapter(), signIn: signIn, signOut: signOut, displayMode: displayMode }, children));
|
|
17
|
+
};
|
|
18
|
+
const WrapperSessionAuthProvider = ({ children, ...props }) => {
|
|
19
|
+
const sessionData = useClientTokenExchangeSession();
|
|
20
|
+
return (React.createElement(SessionProvider, { ...sessionData },
|
|
21
|
+
React.createElement(IframeProvider, { iframeMode: props.iframeMode },
|
|
22
|
+
React.createElement(AuthProvider, { ...props, pkceConsumer: new BrowserPublicClientPKCEProducer() },
|
|
23
|
+
React.createElement(TokenProvider, null,
|
|
24
|
+
React.createElement(WrapperUserProvider, null, children))))));
|
|
25
|
+
};
|
|
26
|
+
const CivicAuthProvider = ({ children, ...props }) => {
|
|
27
|
+
return (React.createElement(CivicAuthConfigProvider, { oauthServer: props?.config?.oauthServer, clientId: props?.clientId, redirectUrl: props?.redirectUrl, nonce: props?.nonce },
|
|
28
|
+
React.createElement(ClientTokenExchangeSessionProvider, null,
|
|
29
|
+
React.createElement(WrapperSessionAuthProvider, { ...props }, children))));
|
|
30
|
+
};
|
|
31
|
+
export { CivicAuthProvider };
|
|
32
|
+
//# sourceMappingURL=CivicAuthProvider.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"CivicAuthProvider.js","sourceRoot":"","sources":["../../../../src/shared/providers/CivicAuthProvider.tsx"],"names":[],"mappings":"AAAA,YAAY,CAAC;AACb,OAAO,KAAK,MAAM,OAAO,CAAC;AAC1B,OAAO,EACL,YAAY,GAEb,MAAM,oCAAoC,CAAC;AAC5C,OAAO,EAAE,+BAA+B,EAAE,MAAM,oBAAoB,CAAC;AACrE,OAAO,EAAE,YAAY,EAAE,MAAM,oCAAoC,CAAC;AAClE,OAAO,EAAE,mBAAmB,EAAE,MAAM,sBAAsB,CAAC;AAC3D,OAAO,EAAE,uBAAuB,EAAE,MAAM,8CAA8C,CAAC;AACvF,OAAO,EAAE,cAAc,EAAE,MAAM,sCAAsC,CAAC;AACtE,OAAO,EAAE,kCAAkC,EAAE,MAAM,0DAA0D,CAAC;AAC9G,OAAO,EAAE,eAAe,EAAE,MAAM,uCAAuC,CAAC;AACxE,OAAO,EAAE,6BAA6B,EAAE,MAAM,iDAAiD,CAAC;AAChG,OAAO,EAAE,aAAa,EAAE,MAAM,qCAAqC,CAAC;AACpE,OAAO,EAAE,OAAO,EAAE,MAAM,2BAA2B,CAAC;AAIpD,MAAM,mBAAmB,GAAG,CAAC,EAAE,QAAQ,EAAiC,EAAE,EAAE;IAC1E,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,WAAW,EAAE,GAAG,OAAO,EAAE,CAAC;IACnD,OAAO,CACL,oBAAC,YAAY,IACX,OAAO,EAAE,IAAI,mBAAmB,EAAE,EAClC,MAAM,EAAE,MAAM,EACd,OAAO,EAAE,OAAO,EAChB,WAAW,EAAE,WAAW,IAEvB,QAAQ,CACI,CAChB,CAAC;AACJ,CAAC,CAAC;AACF,MAAM,0BAA0B,GAAG,CAAC,EAClC,QAAQ,EACR,GAAG,KAAK,EACe,EAAE,EAAE;IAC3B,MAAM,WAAW,GAAG,6BAA6B,EAAE,CAAC;IACpD,OAAO,CACL,oBAAC,eAAe,OAAK,WAAW;QAC9B,oBAAC,cAAc,IAAC,UAAU,EAAE,KAAK,CAAC,UAAU;YAC1C,oBAAC,YAAY,OACP,KAAK,EACT,YAAY,EAAE,IAAI,+BAA+B,EAAE;gBAEnD,oBAAC,aAAa;oBACZ,oBAAC,mBAAmB,QAAE,QAAQ,CAAuB,CACvC,CACH,CACA,CACD,CACnB,CAAC;AACJ,CAAC,CAAC;AACF,MAAM,iBAAiB,GAAG,CAAC,EAAE,QAAQ,EAAE,GAAG,KAAK,EAA0B,EAAE,EAAE;IAC3E,OAAO,CACL,oBAAC,uBAAuB,IACtB,WAAW,EAAE,KAAK,EAAE,MAAM,EAAE,WAAW,EACvC,QAAQ,EAAE,KAAK,EAAE,QAAQ,EACzB,WAAW,EAAE,KAAK,EAAE,WAAW,EAC/B,KAAK,EAAE,KAAK,EAAE,KAAK;QAEnB,oBAAC,kCAAkC;YACjC,oBAAC,0BAA0B,OAAK,KAAK,IAClC,QAAQ,CACkB,CACM,CACb,CAC3B,CAAC;AACJ,CAAC,CAAC;AAEF,OAAO,EAAE,iBAAiB,EAA+B,CAAC","sourcesContent":["\"use client\";\nimport React from \"react\";\nimport {\n AuthProvider,\n type AuthProviderProps,\n} from \"@/shared/providers/AuthProvider.js\";\nimport { BrowserPublicClientPKCEProducer } from \"@/services/PKCE.js\";\nimport { UserProvider } from \"@/shared/providers/UserProvider.js\";\nimport { LocalStorageAdapter } from \"@/browser/storage.js\";\nimport { CivicAuthConfigProvider } from \"@/shared/providers/CivicAuthConfigContext.js\";\nimport { IframeProvider } from \"@/shared/providers/IframeProvider.js\";\nimport { ClientTokenExchangeSessionProvider } from \"@/shared/providers/ClientTokenExchangeSessionProvider.js\";\nimport { SessionProvider } from \"@/shared/providers/SessionProvider.js\";\nimport { useClientTokenExchangeSession } from \"@/shared/hooks/useClientTokenExchangeSession.js\";\nimport { TokenProvider } from \"@/shared/providers/TokenProvider.js\";\nimport { useAuth } from \"@/shared/hooks/useAuth.js\";\n\ntype CivicAuthProviderProps = Omit<AuthProviderProps, \"pkceConsumer\">;\n\nconst WrapperUserProvider = ({ children }: { children: React.ReactNode }) => {\n const { signIn, signOut, displayMode } = useAuth();\n return (\n <UserProvider\n storage={new LocalStorageAdapter()}\n signIn={signIn}\n signOut={signOut}\n displayMode={displayMode}\n >\n {children}\n </UserProvider>\n );\n};\nconst WrapperSessionAuthProvider = ({\n children,\n ...props\n}: CivicAuthProviderProps) => {\n const sessionData = useClientTokenExchangeSession();\n return (\n <SessionProvider {...sessionData}>\n <IframeProvider iframeMode={props.iframeMode}>\n <AuthProvider\n {...props}\n pkceConsumer={new BrowserPublicClientPKCEProducer()}\n >\n <TokenProvider>\n <WrapperUserProvider>{children}</WrapperUserProvider>\n </TokenProvider>\n </AuthProvider>\n </IframeProvider>\n </SessionProvider>\n );\n};\nconst CivicAuthProvider = ({ children, ...props }: CivicAuthProviderProps) => {\n return (\n <CivicAuthConfigProvider\n oauthServer={props?.config?.oauthServer}\n clientId={props?.clientId}\n redirectUrl={props?.redirectUrl}\n nonce={props?.nonce}\n >\n <ClientTokenExchangeSessionProvider>\n <WrapperSessionAuthProvider {...props}>\n {children}\n </WrapperSessionAuthProvider>\n </ClientTokenExchangeSessionProvider>\n </CivicAuthConfigProvider>\n );\n};\n\nexport { CivicAuthProvider, type CivicAuthProviderProps };\n"]}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import type { ReactNode } from "react";
|
|
2
|
+
import React from "react";
|
|
3
|
+
import type { SessionData } from "../../types.js";
|
|
4
|
+
export type ClientTokenExchangeSessionProviderOutput = {
|
|
5
|
+
data: SessionData | null;
|
|
6
|
+
error: Error | null;
|
|
7
|
+
isLoading: boolean;
|
|
8
|
+
doTokenExchange: null | ((url: string) => Promise<void>);
|
|
9
|
+
};
|
|
10
|
+
declare const ClientTokenExchangeSessionContext: React.Context<ClientTokenExchangeSessionProviderOutput>;
|
|
11
|
+
type ClientTokenExchangeSessionContextType = {
|
|
12
|
+
children: ReactNode;
|
|
13
|
+
};
|
|
14
|
+
declare const ClientTokenExchangeSessionProvider: ({ children, }: ClientTokenExchangeSessionContextType) => React.JSX.Element;
|
|
15
|
+
export type { ClientTokenExchangeSessionContextType as SessionContextType };
|
|
16
|
+
export { ClientTokenExchangeSessionProvider, ClientTokenExchangeSessionContext, };
|
|
17
|
+
//# sourceMappingURL=ClientTokenExchangeSessionProvider.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ClientTokenExchangeSessionProvider.d.ts","sourceRoot":"","sources":["../../../../src/shared/providers/ClientTokenExchangeSessionProvider.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AACvC,OAAO,KAMN,MAAM,OAAO,CAAC;AAIf,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAS9C,MAAM,MAAM,wCAAwC,GAAG;IACrD,IAAI,EAAE,WAAW,GAAG,IAAI,CAAC;IACzB,KAAK,EAAE,KAAK,GAAG,IAAI,CAAC;IACpB,SAAS,EAAE,OAAO,CAAC;IACnB,eAAe,EAAE,IAAI,GAAG,CAAC,CAAC,GAAG,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC;CAC1D,CAAC;AAcF,QAAA,MAAM,iCAAiC,yDACkC,CAAC;AAE1E,KAAK,qCAAqC,GAAG;IAC3C,QAAQ,EAAE,SAAS,CAAC;CACrB,CAAC;AAEF,QAAA,MAAM,kCAAkC,kBAErC,qCAAqC,sBAsIvC,CAAC;AAEF,YAAY,EAAE,qCAAqC,IAAI,kBAAkB,EAAE,CAAC;AAC5E,OAAO,EACL,kCAAkC,EAClC,iCAAiC,GAClC,CAAC"}
|
|
@@ -0,0 +1,131 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import React, { createContext, useCallback, useEffect, useMemo, useState, } from "react";
|
|
3
|
+
import { BrowserAuthenticationService } from "../../services/AuthenticationService.js";
|
|
4
|
+
import { isWindowInIframe } from "../../lib/windowUtil.js";
|
|
5
|
+
import { useCurrentUrl, useCivicAuthConfig, useWindowFocused, useRefresh, } from "../../shared/hooks/index.js";
|
|
6
|
+
import { LocalStorageAdapter } from "../../browser/storage.js";
|
|
7
|
+
const defaultSession = {
|
|
8
|
+
data: {
|
|
9
|
+
authenticated: false,
|
|
10
|
+
idToken: undefined,
|
|
11
|
+
accessToken: undefined,
|
|
12
|
+
displayMode: "iframe",
|
|
13
|
+
},
|
|
14
|
+
error: null,
|
|
15
|
+
isLoading: false,
|
|
16
|
+
doTokenExchange: null,
|
|
17
|
+
};
|
|
18
|
+
// Context for exposing session specifically to the TokenProvider
|
|
19
|
+
const ClientTokenExchangeSessionContext = createContext(defaultSession);
|
|
20
|
+
const ClientTokenExchangeSessionProvider = ({ children, }) => {
|
|
21
|
+
const authConfig = useCivicAuthConfig();
|
|
22
|
+
const [authService, setAuthService] = useState();
|
|
23
|
+
const [error, setError] = useState(null);
|
|
24
|
+
const [isLoading, setIsLoading] = useState(false);
|
|
25
|
+
const [session, setSession] = useState(null);
|
|
26
|
+
const { isWindowFocused } = useWindowFocused();
|
|
27
|
+
const currentUrl = useCurrentUrl();
|
|
28
|
+
useRefresh(session);
|
|
29
|
+
useEffect(() => {
|
|
30
|
+
if (!currentUrl || !authConfig)
|
|
31
|
+
return;
|
|
32
|
+
const { redirectUrl, clientId, oauthServer, scopes, logoutRedirectUrl, logoutUrl, } = authConfig;
|
|
33
|
+
BrowserAuthenticationService.build({
|
|
34
|
+
clientId,
|
|
35
|
+
redirectUrl,
|
|
36
|
+
logoutRedirectUrl,
|
|
37
|
+
logoutUrl,
|
|
38
|
+
oauthServer,
|
|
39
|
+
scopes,
|
|
40
|
+
displayMode: "iframe",
|
|
41
|
+
}).then(setAuthService);
|
|
42
|
+
}, [currentUrl, authConfig]);
|
|
43
|
+
const isInIframe = isWindowInIframe(globalThis.window);
|
|
44
|
+
const doTokenExchange = useCallback(async (inUrl) => {
|
|
45
|
+
if (!authService)
|
|
46
|
+
return;
|
|
47
|
+
const url = new URL(inUrl);
|
|
48
|
+
const code = url.searchParams.get("code");
|
|
49
|
+
const state = url.searchParams.get("state");
|
|
50
|
+
if (code && state) {
|
|
51
|
+
try {
|
|
52
|
+
setIsLoading(true);
|
|
53
|
+
await authService.tokenExchange(code, state);
|
|
54
|
+
}
|
|
55
|
+
catch (error) {
|
|
56
|
+
setError(error);
|
|
57
|
+
setSession({ authenticated: false });
|
|
58
|
+
}
|
|
59
|
+
setIsLoading(false);
|
|
60
|
+
}
|
|
61
|
+
}, [authService]);
|
|
62
|
+
const onSignIn = useCallback(async () => {
|
|
63
|
+
if (!authService)
|
|
64
|
+
return;
|
|
65
|
+
const session = await authService.getSessionData();
|
|
66
|
+
setSession(session);
|
|
67
|
+
}, [authService]);
|
|
68
|
+
const onSignOut = useCallback(() => {
|
|
69
|
+
setSession({ authenticated: false });
|
|
70
|
+
}, []);
|
|
71
|
+
useEffect(() => {
|
|
72
|
+
LocalStorageAdapter.emitter.on("signIn", onSignIn);
|
|
73
|
+
LocalStorageAdapter.emitter.on("signOut", onSignOut);
|
|
74
|
+
return () => {
|
|
75
|
+
LocalStorageAdapter.emitter.off("signIn", onSignIn);
|
|
76
|
+
LocalStorageAdapter.emitter.off("signOut", onSignOut);
|
|
77
|
+
};
|
|
78
|
+
}, [onSignIn, onSignOut]);
|
|
79
|
+
useEffect(() => {
|
|
80
|
+
if (!authConfig) {
|
|
81
|
+
setIsLoading(true);
|
|
82
|
+
}
|
|
83
|
+
else {
|
|
84
|
+
setIsLoading(false);
|
|
85
|
+
}
|
|
86
|
+
}, [authConfig]);
|
|
87
|
+
// Handle page load or refocus
|
|
88
|
+
useEffect(() => {
|
|
89
|
+
if (!authConfig || !authService || !currentUrl || isInIframe || isLoading) {
|
|
90
|
+
return;
|
|
91
|
+
}
|
|
92
|
+
const abortController = new AbortController();
|
|
93
|
+
const onPageLoad = async () => {
|
|
94
|
+
// if we have existing tokens, then validate them and return the session data
|
|
95
|
+
// otherwise check if we have a code in the url and exchange it for tokens
|
|
96
|
+
// if we have neither, return undefined
|
|
97
|
+
const existingSessionData = await authService.validateExistingSession();
|
|
98
|
+
if (existingSessionData.authenticated) {
|
|
99
|
+
setSession(existingSessionData);
|
|
100
|
+
return;
|
|
101
|
+
}
|
|
102
|
+
if (abortController.signal.aborted ||
|
|
103
|
+
!new URL(currentUrl).searchParams.get("code")) {
|
|
104
|
+
return;
|
|
105
|
+
}
|
|
106
|
+
await doTokenExchange(currentUrl);
|
|
107
|
+
};
|
|
108
|
+
onPageLoad();
|
|
109
|
+
return () => {
|
|
110
|
+
abortController.abort();
|
|
111
|
+
};
|
|
112
|
+
}, [
|
|
113
|
+
authConfig,
|
|
114
|
+
authService,
|
|
115
|
+
currentUrl,
|
|
116
|
+
doTokenExchange,
|
|
117
|
+
isInIframe,
|
|
118
|
+
isLoading,
|
|
119
|
+
isWindowFocused,
|
|
120
|
+
session?.authenticated,
|
|
121
|
+
]);
|
|
122
|
+
const value = useMemo(() => ({
|
|
123
|
+
data: session,
|
|
124
|
+
error,
|
|
125
|
+
isLoading,
|
|
126
|
+
doTokenExchange: authService ? doTokenExchange : null,
|
|
127
|
+
}), [session, error, isLoading, authService, doTokenExchange]);
|
|
128
|
+
return (React.createElement(ClientTokenExchangeSessionContext.Provider, { value: value }, children));
|
|
129
|
+
};
|
|
130
|
+
export { ClientTokenExchangeSessionProvider, ClientTokenExchangeSessionContext, };
|
|
131
|
+
//# sourceMappingURL=ClientTokenExchangeSessionProvider.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ClientTokenExchangeSessionProvider.js","sourceRoot":"","sources":["../../../../src/shared/providers/ClientTokenExchangeSessionProvider.tsx"],"names":[],"mappings":"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","sourcesContent":["\"use client\";\nimport type { ReactNode } from \"react\";\nimport React, {\n createContext,\n useCallback,\n useEffect,\n useMemo,\n useState,\n} from \"react\";\nimport { BrowserAuthenticationService } from \"@/services/AuthenticationService.js\";\nimport type { AuthenticationResolver } from \"@/services/types.js\";\nimport { isWindowInIframe } from \"@/lib/windowUtil.js\";\nimport type { SessionData } from \"@/types.js\";\nimport {\n useCurrentUrl,\n useCivicAuthConfig,\n useWindowFocused,\n useRefresh,\n} from \"@/shared/hooks/index.js\";\nimport { LocalStorageAdapter } from \"@/browser/storage.js\";\n\nexport type ClientTokenExchangeSessionProviderOutput = {\n data: SessionData | null;\n error: Error | null;\n isLoading: boolean;\n doTokenExchange: null | ((url: string) => Promise<void>);\n};\nconst defaultSession: ClientTokenExchangeSessionProviderOutput = {\n data: {\n authenticated: false,\n idToken: undefined,\n accessToken: undefined,\n displayMode: \"iframe\",\n },\n error: null,\n isLoading: false,\n doTokenExchange: null,\n};\n\n// Context for exposing session specifically to the TokenProvider\nconst ClientTokenExchangeSessionContext =\n createContext<ClientTokenExchangeSessionProviderOutput>(defaultSession);\n\ntype ClientTokenExchangeSessionContextType = {\n children: ReactNode;\n};\n\nconst ClientTokenExchangeSessionProvider = ({\n children,\n}: ClientTokenExchangeSessionContextType) => {\n const authConfig = useCivicAuthConfig();\n const [authService, setAuthService] = useState<AuthenticationResolver>();\n const [error, setError] = useState<Error | null>(null);\n const [isLoading, setIsLoading] = useState(false);\n const [session, setSession] = useState<SessionData | null>(null);\n const { isWindowFocused } = useWindowFocused();\n const currentUrl = useCurrentUrl();\n\n useRefresh(session);\n\n useEffect(() => {\n if (!currentUrl || !authConfig) return;\n\n const {\n redirectUrl,\n clientId,\n oauthServer,\n scopes,\n logoutRedirectUrl,\n logoutUrl,\n } = authConfig;\n BrowserAuthenticationService.build({\n clientId,\n redirectUrl,\n logoutRedirectUrl,\n logoutUrl,\n oauthServer,\n scopes,\n displayMode: \"iframe\",\n }).then(setAuthService);\n }, [currentUrl, authConfig]);\n\n const isInIframe = isWindowInIframe(globalThis.window);\n\n const doTokenExchange = useCallback(\n async (inUrl: string) => {\n if (!authService) return;\n const url = new URL(inUrl);\n const code = url.searchParams.get(\"code\");\n const state = url.searchParams.get(\"state\");\n if (code && state) {\n try {\n setIsLoading(true);\n await authService.tokenExchange(code, state);\n } catch (error) {\n setError(error as Error);\n setSession({ authenticated: false });\n }\n setIsLoading(false);\n }\n },\n [authService],\n );\n\n const onSignIn = useCallback(async () => {\n if (!authService) return;\n const session = await authService.getSessionData();\n setSession(session);\n }, [authService]);\n\n const onSignOut = useCallback(() => {\n setSession({ authenticated: false });\n }, []);\n\n useEffect(() => {\n LocalStorageAdapter.emitter.on(\"signIn\", onSignIn);\n LocalStorageAdapter.emitter.on(\"signOut\", onSignOut);\n return () => {\n LocalStorageAdapter.emitter.off(\"signIn\", onSignIn);\n LocalStorageAdapter.emitter.off(\"signOut\", onSignOut);\n };\n }, [onSignIn, onSignOut]);\n\n useEffect(() => {\n if (!authConfig) {\n setIsLoading(true);\n } else {\n setIsLoading(false);\n }\n }, [authConfig]);\n // Handle page load or refocus\n useEffect(() => {\n if (!authConfig || !authService || !currentUrl || isInIframe || isLoading) {\n return;\n }\n const abortController = new AbortController();\n const onPageLoad = async () => {\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 setSession(existingSessionData);\n return;\n }\n if (\n abortController.signal.aborted ||\n !new URL(currentUrl).searchParams.get(\"code\")\n ) {\n return;\n }\n await doTokenExchange(currentUrl);\n };\n onPageLoad();\n return () => {\n abortController.abort();\n };\n }, [\n authConfig,\n authService,\n currentUrl,\n doTokenExchange,\n isInIframe,\n isLoading,\n isWindowFocused,\n session?.authenticated,\n ]);\n\n const value = useMemo(\n () => ({\n data: session,\n error,\n isLoading,\n doTokenExchange: authService ? doTokenExchange : null,\n }),\n [session, error, isLoading, authService, doTokenExchange],\n );\n\n return (\n <ClientTokenExchangeSessionContext.Provider value={value}>\n {children}\n </ClientTokenExchangeSessionContext.Provider>\n );\n};\n\nexport type { ClientTokenExchangeSessionContextType as SessionContextType };\nexport {\n ClientTokenExchangeSessionProvider,\n ClientTokenExchangeSessionContext,\n};\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"NextAuthProvider.d.ts","sourceRoot":"","sources":["../../../src/nextjs/providers/NextAuthProvider.tsx"],"names":[],"mappings":"AAKA,OAAO,EAEL,KAAK,sBAAsB,EAC5B,MAAM,oBAAoB,CAAC;AAe5B,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,6BAA6B,CAAC;
|
|
1
|
+
{"version":3,"file":"NextAuthProvider.d.ts","sourceRoot":"","sources":["../../../src/nextjs/providers/NextAuthProvider.tsx"],"names":[],"mappings":"AAKA,OAAO,EAEL,KAAK,sBAAsB,EAC5B,MAAM,oBAAoB,CAAC;AAe5B,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,6BAA6B,CAAC;AAerE,KAAK,kCAAkC,GAAG,IAAI,CAC5C,iBAAiB,EACjB,UAAU,CACX,GAAG;IACF,cAAc,EAAE,sBAAsB,CAAC;CACxC,CAAC;AACF,KAAK,0BAA0B,GAAG,IAAI,CACpC,kCAAkC,EAClC,UAAU,GAAG,gBAAgB,GAAG,aAAa,CAC9C,CAAC;AAgIF,QAAA,MAAM,qBAAqB,2BAGxB,0BAA0B,qDA0C5B,CAAC;AAEF,OAAO,EAAE,qBAAqB,EAAE,KAAK,0BAA0B,EAAE,CAAC"}
|
|
@@ -24,9 +24,10 @@ import { AuthStatus } from "../../types.js";
|
|
|
24
24
|
import { useRefresh } from "../../nextjs/hooks/useRefresh.js";
|
|
25
25
|
import { useCurrentUrl, useSession } from "../../shared/hooks/index.js";
|
|
26
26
|
import { BrowserCookieStorage } from "../../shared/index.js";
|
|
27
|
+
import { getIframeRef } from "../../shared/lib/iframeUtils.js";
|
|
27
28
|
const CivicNextAuthTokenProviderInternal = ({ children, isLoading, displayMode = "iframe", user, fetchUser, ...props }) => {
|
|
28
29
|
const { iframeMode, resolvedConfig } = props;
|
|
29
|
-
const { iframeRef, setIframeIsVisible } = useIframe();
|
|
30
|
+
const { iframeRef, setIframeIsVisible, isIframeMounted, setIframeMounted } = useIframe();
|
|
30
31
|
const civicAuthConfig = useCivicAuthConfig();
|
|
31
32
|
const { challengeUrl } = resolvedConfig;
|
|
32
33
|
const pkceConsumer = new ConfidentialClientPKCEConsumer(challengeUrl);
|
|
@@ -34,11 +35,12 @@ const CivicNextAuthTokenProviderInternal = ({ children, isLoading, displayMode =
|
|
|
34
35
|
const currentUrl = useCurrentUrl();
|
|
35
36
|
useEffect(() => {
|
|
36
37
|
if (session?.authenticated) {
|
|
38
|
+
setIframeMounted(false);
|
|
37
39
|
// the session is authenticated, so don't show the login iframe
|
|
38
40
|
setIframeIsVisible(false);
|
|
39
41
|
return;
|
|
40
42
|
}
|
|
41
|
-
}, [session?.authenticated, setIframeIsVisible]);
|
|
43
|
+
}, [session?.authenticated, setIframeIsVisible, setIframeMounted]);
|
|
42
44
|
const postSignOut = useCallback(async () => {
|
|
43
45
|
// user is signed out, manually update the user from cookies to not wait for polling
|
|
44
46
|
await fetchUser();
|
|
@@ -50,9 +52,11 @@ const CivicNextAuthTokenProviderInternal = ({ children, isLoading, displayMode =
|
|
|
50
52
|
displayMode,
|
|
51
53
|
});
|
|
52
54
|
useEffect(() => {
|
|
53
|
-
|
|
55
|
+
const ref = getIframeRef(iframeRef?.current, true);
|
|
56
|
+
if (isIframeMounted &&
|
|
57
|
+
civicAuthConfig &&
|
|
54
58
|
!session?.authenticated &&
|
|
55
|
-
|
|
59
|
+
ref &&
|
|
56
60
|
authStatus === AuthStatus.UNAUTHENTICATED &&
|
|
57
61
|
displayMode === "iframe" &&
|
|
58
62
|
!currentUrl?.includes("code=")) {
|
|
@@ -60,6 +64,7 @@ const CivicNextAuthTokenProviderInternal = ({ children, isLoading, displayMode =
|
|
|
60
64
|
}
|
|
61
65
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
62
66
|
}, [
|
|
67
|
+
isIframeMounted,
|
|
63
68
|
currentUrl,
|
|
64
69
|
iframeMode,
|
|
65
70
|
iframeRef,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"NextAuthProvider.js","sourceRoot":"","sources":["../../../src/nextjs/providers/NextAuthProvider.tsx"],"names":[],"mappings":"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","sourcesContent":["\"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 React, { useCallback, useEffect, useState } from \"react\";\nimport {\n resolveAuthConfig,\n type AuthConfigWithDefaults,\n} from \"@/nextjs/config.js\";\nimport { resolveCallbackUrl } from \"@/nextjs/utils.js\";\nimport { ConfidentialClientPKCEConsumer } from \"@/services/PKCE.js\";\nimport { UserProvider } from \"@/shared/providers/UserProvider.js\";\nimport { useUserCookie } from \"@/nextjs/hooks/useUserCookie.js\";\nimport { CivicAuthConfigProvider } from \"@/shared/providers/CivicAuthConfigContext.js\";\nimport { SessionProvider } from \"@/shared/providers/SessionProvider.js\";\nimport { IframeProvider } from \"@/shared/providers/IframeProvider.js\";\nimport { TokenProvider } from \"@/shared/providers/TokenProvider.js\";\nimport { useSignIn } from \"@/shared/hooks/useSignIn.js\";\nimport { useCivicAuthConfig } from \"@/shared/hooks/useCivicAuthConfig.js\";\nimport { IFrameAndLoading } from \"@/shared/components/IFrameAndLoading.js\";\nimport { BlockDisplay } from \"@/shared/components/BlockDisplay.js\";\nimport { LoadingIcon } from \"@/shared/components/LoadingIcon.js\";\nimport { useIframe } from \"@/shared/hooks/useIframe.js\";\nimport type { AuthProviderProps } from \"@/shared/providers/types.js\";\nimport { useIsInIframe } from \"@/shared/hooks/useIsInIframe.js\";\nimport { AuthStatus, type UnknownObject, type User } from \"@/types.js\";\nimport { useRefresh } from \"@/nextjs/hooks/useRefresh.js\";\nimport { useCurrentUrl, useSession } from \"@/shared/hooks/index.js\";\nimport { BrowserCookieStorage } from \"@/shared/index.js\";\n\ntype CivicNextAuthTokenProviderInternalProps<TUser extends UnknownObject> =\n NextCivicAuthProviderInternalProps & {\n isLoading: boolean;\n idToken?: string;\n user: User<TUser> | null;\n fetchUser: () => Promise<void>;\n };\ntype NextCivicAuthProviderInternalProps = Omit<\n AuthProviderProps,\n \"clientId\"\n> & {\n resolvedConfig: AuthConfigWithDefaults;\n};\ntype NextCivicAuthProviderProps = Omit<\n NextCivicAuthProviderInternalProps,\n \"clientId\" | \"resolvedConfig\" | \"redirectUrl\"\n>;\n\nconst CivicNextAuthTokenProviderInternal = <\n TUser extends UnknownObject = UnknownObject,\n>({\n children,\n isLoading,\n displayMode = \"iframe\",\n user,\n fetchUser,\n ...props\n}: CivicNextAuthTokenProviderInternalProps<TUser>) => {\n const { iframeMode, resolvedConfig } = props;\n const { iframeRef, setIframeIsVisible } = useIframe();\n const civicAuthConfig = useCivicAuthConfig();\n const { challengeUrl } = resolvedConfig;\n const pkceConsumer = new ConfidentialClientPKCEConsumer(challengeUrl);\n const { data: session } = useSession();\n const currentUrl = useCurrentUrl();\n\n useEffect(() => {\n if (session?.authenticated) {\n // the session is authenticated, so don't show the login iframe\n setIframeIsVisible(false);\n return;\n }\n }, [session?.authenticated, setIframeIsVisible]);\n\n const postSignOut = useCallback(async () => {\n // user is signed out, manually update the user from cookies to not wait for polling\n await fetchUser();\n await props?.onSignOut?.();\n }, [fetchUser, props]);\n\n const { signIn, startSignIn, signOut, authStatus } = useSignIn({\n postSignOut,\n pkceConsumer,\n displayMode,\n });\n\n useEffect(() => {\n if (\n civicAuthConfig &&\n !session?.authenticated &&\n iframeRef?.current &&\n authStatus === AuthStatus.UNAUTHENTICATED &&\n displayMode === \"iframe\" &&\n !currentUrl?.includes(\"code=\")\n ) {\n startSignIn();\n }\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [\n currentUrl,\n iframeMode,\n iframeRef,\n civicAuthConfig,\n session?.authenticated,\n authStatus,\n startSignIn,\n displayMode,\n ]);\n\n const { error: refreshError } = useRefresh(session);\n\n useEffect(() => {\n if (refreshError) {\n console.error(\"Error refreshing token, signing out...\", refreshError);\n signOut();\n }\n }, [refreshError, signOut]);\n\n return (\n <TokenProvider>\n <UserProvider\n storage={new BrowserCookieStorage()}\n user={user}\n signOut={signOut}\n signIn={signIn}\n displayMode={displayMode}\n authStatus={authStatus}\n >\n <IFrameAndLoading error={null} isLoading={isLoading} />\n {isLoading && (\n <BlockDisplay>\n <LoadingIcon />\n </BlockDisplay>\n )}\n {children}\n </UserProvider>\n </TokenProvider>\n );\n};\n\nconst CivicNextAuthProviderInternal = ({\n children,\n ...props\n}: NextCivicAuthProviderInternalProps) => {\n // if the SDK loads in an iframe, we show the loading spinner as the iframe\n // will be waiting to be minimized\n const isLoading = useIsInIframe();\n const { user, idToken, fetchUser } = useUserCookie();\n\n const session = {\n authenticated: !!user,\n idToken,\n };\n\n return (\n <SessionProvider data={session} isLoading={isLoading}>\n <CivicNextAuthTokenProviderInternal\n {...props}\n user={user}\n idToken={idToken}\n fetchUser={fetchUser}\n isLoading={isLoading}\n >\n {children}\n </CivicNextAuthTokenProviderInternal>\n </SessionProvider>\n );\n};\n\nconst CivicNextAuthProvider = ({\n children,\n ...props\n}: NextCivicAuthProviderProps) => {\n const resolvedConfig = resolveAuthConfig();\n const {\n clientId,\n oauthServer,\n callbackUrl,\n challengeUrl,\n logoutUrl,\n refreshUrl,\n logoutCallbackUrl,\n } = resolvedConfig;\n const [redirectUrl, setRedirectUrl] = useState<string>(\"\");\n\n useEffect(() => {\n if (typeof globalThis.window !== \"undefined\") {\n const appUrl = globalThis.window.location.origin;\n setRedirectUrl(resolveCallbackUrl(resolvedConfig, appUrl));\n }\n }, [callbackUrl, resolvedConfig]);\n\n return (\n <CivicAuthConfigProvider\n oauthServer={oauthServer}\n clientId={clientId}\n redirectUrl={redirectUrl}\n logoutRedirectUrl={logoutCallbackUrl}\n nonce={props?.nonce}\n challengeUrl={challengeUrl}\n refreshUrl={refreshUrl}\n logoutUrl={logoutUrl}\n logoutCallbackUrl={logoutCallbackUrl}\n >\n <IframeProvider iframeMode={props.iframeMode}>\n <CivicNextAuthProviderInternal\n {...props}\n resolvedConfig={resolvedConfig}\n >\n {children}\n </CivicNextAuthProviderInternal>\n </IframeProvider>\n </CivicAuthConfigProvider>\n );\n};\n\nexport { CivicNextAuthProvider, type NextCivicAuthProviderProps };\n"]}
|
|
1
|
+
{"version":3,"file":"NextAuthProvider.js","sourceRoot":"","sources":["../../../src/nextjs/providers/NextAuthProvider.tsx"],"names":[],"mappings":"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","sourcesContent":["\"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 React, { useCallback, useEffect, useState } from \"react\";\nimport {\n resolveAuthConfig,\n type AuthConfigWithDefaults,\n} from \"@/nextjs/config.js\";\nimport { resolveCallbackUrl } from \"@/nextjs/utils.js\";\nimport { ConfidentialClientPKCEConsumer } from \"@/services/PKCE.js\";\nimport { UserProvider } from \"@/shared/providers/UserProvider.js\";\nimport { useUserCookie } from \"@/nextjs/hooks/useUserCookie.js\";\nimport { CivicAuthConfigProvider } from \"@/shared/providers/CivicAuthConfigContext.js\";\nimport { SessionProvider } from \"@/shared/providers/SessionProvider.js\";\nimport { IframeProvider } from \"@/shared/providers/IframeProvider.js\";\nimport { TokenProvider } from \"@/shared/providers/TokenProvider.js\";\nimport { useSignIn } from \"@/shared/hooks/useSignIn.js\";\nimport { useCivicAuthConfig } from \"@/shared/hooks/useCivicAuthConfig.js\";\nimport { IFrameAndLoading } from \"@/shared/components/IFrameAndLoading.js\";\nimport { BlockDisplay } from \"@/shared/components/BlockDisplay.js\";\nimport { LoadingIcon } from \"@/shared/components/LoadingIcon.js\";\nimport { useIframe } from \"@/shared/hooks/useIframe.js\";\nimport type { AuthProviderProps } from \"@/shared/providers/types.js\";\nimport { useIsInIframe } from \"@/shared/hooks/useIsInIframe.js\";\nimport { AuthStatus, type UnknownObject, type User } from \"@/types.js\";\nimport { useRefresh } from \"@/nextjs/hooks/useRefresh.js\";\nimport { useCurrentUrl, useSession } from \"@/shared/hooks/index.js\";\nimport { BrowserCookieStorage } from \"@/shared/index.js\";\nimport { getIframeRef } from \"@/shared/lib/iframeUtils.js\";\n\ntype CivicNextAuthTokenProviderInternalProps<TUser extends UnknownObject> =\n NextCivicAuthProviderInternalProps & {\n isLoading: boolean;\n idToken?: string;\n user: User<TUser> | null;\n fetchUser: () => Promise<void>;\n };\ntype NextCivicAuthProviderInternalProps = Omit<\n AuthProviderProps,\n \"clientId\"\n> & {\n resolvedConfig: AuthConfigWithDefaults;\n};\ntype NextCivicAuthProviderProps = Omit<\n NextCivicAuthProviderInternalProps,\n \"clientId\" | \"resolvedConfig\" | \"redirectUrl\"\n>;\n\nconst CivicNextAuthTokenProviderInternal = <\n TUser extends UnknownObject = UnknownObject,\n>({\n children,\n isLoading,\n displayMode = \"iframe\",\n user,\n fetchUser,\n ...props\n}: CivicNextAuthTokenProviderInternalProps<TUser>) => {\n const { iframeMode, resolvedConfig } = props;\n const { iframeRef, setIframeIsVisible, isIframeMounted, setIframeMounted } =\n useIframe();\n const civicAuthConfig = useCivicAuthConfig();\n const { challengeUrl } = resolvedConfig;\n const pkceConsumer = new ConfidentialClientPKCEConsumer(challengeUrl);\n const { data: session } = useSession();\n const currentUrl = useCurrentUrl();\n\n useEffect(() => {\n if (session?.authenticated) {\n setIframeMounted(false);\n // the session is authenticated, so don't show the login iframe\n setIframeIsVisible(false);\n return;\n }\n }, [session?.authenticated, setIframeIsVisible, setIframeMounted]);\n\n const postSignOut = useCallback(async () => {\n // user is signed out, manually update the user from cookies to not wait for polling\n await fetchUser();\n await props?.onSignOut?.();\n }, [fetchUser, props]);\n\n const { signIn, startSignIn, signOut, authStatus } = useSignIn({\n postSignOut,\n pkceConsumer,\n displayMode,\n });\n\n useEffect(() => {\n const ref = getIframeRef(iframeRef?.current, true);\n if (\n isIframeMounted &&\n civicAuthConfig &&\n !session?.authenticated &&\n ref &&\n authStatus === AuthStatus.UNAUTHENTICATED &&\n displayMode === \"iframe\" &&\n !currentUrl?.includes(\"code=\")\n ) {\n startSignIn();\n }\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [\n isIframeMounted,\n currentUrl,\n iframeMode,\n iframeRef,\n civicAuthConfig,\n session?.authenticated,\n authStatus,\n startSignIn,\n displayMode,\n ]);\n\n const { error: refreshError } = useRefresh(session);\n\n useEffect(() => {\n if (refreshError) {\n console.error(\"Error refreshing token, signing out...\", refreshError);\n signOut();\n }\n }, [refreshError, signOut]);\n\n return (\n <TokenProvider>\n <UserProvider\n storage={new BrowserCookieStorage()}\n user={user}\n signOut={signOut}\n signIn={signIn}\n displayMode={displayMode}\n authStatus={authStatus}\n >\n <IFrameAndLoading error={null} isLoading={isLoading} />\n {isLoading && (\n <BlockDisplay>\n <LoadingIcon />\n </BlockDisplay>\n )}\n {children}\n </UserProvider>\n </TokenProvider>\n );\n};\n\nconst CivicNextAuthProviderInternal = ({\n children,\n ...props\n}: NextCivicAuthProviderInternalProps) => {\n // if the SDK loads in an iframe, we show the loading spinner as the iframe\n // will be waiting to be minimized\n const isLoading = useIsInIframe();\n const { user, idToken, fetchUser } = useUserCookie();\n\n const session = {\n authenticated: !!user,\n idToken,\n };\n\n return (\n <SessionProvider data={session} isLoading={isLoading}>\n <CivicNextAuthTokenProviderInternal\n {...props}\n user={user}\n idToken={idToken}\n fetchUser={fetchUser}\n isLoading={isLoading}\n >\n {children}\n </CivicNextAuthTokenProviderInternal>\n </SessionProvider>\n );\n};\n\nconst CivicNextAuthProvider = ({\n children,\n ...props\n}: NextCivicAuthProviderProps) => {\n const resolvedConfig = resolveAuthConfig();\n const {\n clientId,\n oauthServer,\n callbackUrl,\n challengeUrl,\n logoutUrl,\n refreshUrl,\n logoutCallbackUrl,\n } = resolvedConfig;\n const [redirectUrl, setRedirectUrl] = useState<string>(\"\");\n\n useEffect(() => {\n if (typeof globalThis.window !== \"undefined\") {\n const appUrl = globalThis.window.location.origin;\n setRedirectUrl(resolveCallbackUrl(resolvedConfig, appUrl));\n }\n }, [callbackUrl, resolvedConfig]);\n\n return (\n <CivicAuthConfigProvider\n oauthServer={oauthServer}\n clientId={clientId}\n redirectUrl={redirectUrl}\n logoutRedirectUrl={logoutCallbackUrl}\n nonce={props?.nonce}\n challengeUrl={challengeUrl}\n refreshUrl={refreshUrl}\n logoutUrl={logoutUrl}\n logoutCallbackUrl={logoutCallbackUrl}\n >\n <IframeProvider iframeMode={props.iframeMode}>\n <CivicNextAuthProviderInternal\n {...props}\n resolvedConfig={resolvedConfig}\n >\n {children}\n </CivicNextAuthProviderInternal>\n </IframeProvider>\n </CivicAuthConfigProvider>\n );\n};\n\nexport { CivicNextAuthProvider, type NextCivicAuthProviderProps };\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"AuthProvider.d.ts","sourceRoot":"","sources":["../../../src/reactjs/providers/AuthProvider.tsx"],"names":[],"mappings":"AAGA,OAAO,EAAE,KAAK,WAAW,EAAE,MAAM,YAAY,CAAC;AAE9C,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AAMxD,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,6BAA6B,CAAC;
|
|
1
|
+
{"version":3,"file":"AuthProvider.d.ts","sourceRoot":"","sources":["../../../src/reactjs/providers/AuthProvider.tsx"],"names":[],"mappings":"AAGA,OAAO,EAAE,KAAK,WAAW,EAAE,MAAM,YAAY,CAAC;AAE9C,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AAMxD,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,6BAA6B,CAAC;AAiBrE,MAAM,MAAM,yBAAyB,GAAG,iBAAiB,GAAG;IAC1D,WAAW,CAAC,EAAE,WAAW,CAAC;IAC1B,YAAY,CAAC,EAAE,YAAY,CAAC;CAC7B,CAAC;AAEF,QAAA,MAAM,YAAY,8EAOf,yBAAyB,qDA+F3B,CAAC;AAEF,OAAO,EAAE,YAAY,EAAE,CAAC"}
|
|
@@ -11,6 +11,7 @@ import { IFrameAndLoading } from "../../shared/components/IFrameAndLoading.js";
|
|
|
11
11
|
import { useIsInIframe } from "../../shared/hooks/useIsInIframe.js";
|
|
12
12
|
import { useCurrentUrl } from "../../shared/hooks/useCurrentUrl.js";
|
|
13
13
|
import { useRefresh } from "../../shared/hooks/useRefresh.js";
|
|
14
|
+
import { getIframeRef } from "../../shared/lib/iframeUtils.js";
|
|
14
15
|
// Global this object setup
|
|
15
16
|
let globalThisObject;
|
|
16
17
|
if (typeof window !== "undefined") {
|
|
@@ -47,9 +48,10 @@ const AuthProvider = ({ children, onSignIn, onSignOut, pkceConsumer, iframeMode
|
|
|
47
48
|
return !!localSessionData?.idToken;
|
|
48
49
|
}, [localSessionData]);
|
|
49
50
|
useEffect(() => {
|
|
51
|
+
const ref = getIframeRef(iframeRef?.current, true);
|
|
50
52
|
if (redirectUrl &&
|
|
51
53
|
!isAuthenticated &&
|
|
52
|
-
|
|
54
|
+
ref &&
|
|
53
55
|
displayMode === "iframe" &&
|
|
54
56
|
!currentUrl?.includes("code=")) {
|
|
55
57
|
startSignIn();
|