@civic/auth 0.9.5 → 0.9.6-beta.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +14 -1
- package/dist/nextjs/actions.d.ts +12 -0
- package/dist/nextjs/actions.d.ts.map +1 -0
- package/dist/nextjs/actions.js +26 -0
- package/dist/nextjs/actions.js.map +1 -0
- package/dist/nextjs/config.d.ts +2 -0
- package/dist/nextjs/config.d.ts.map +1 -1
- package/dist/nextjs/config.js +3 -2
- package/dist/nextjs/config.js.map +1 -1
- package/dist/nextjs/cookies.d.ts.map +1 -1
- package/dist/nextjs/cookies.js +45 -3
- package/dist/nextjs/cookies.js.map +1 -1
- package/dist/nextjs/hooks/useInitialAuthConfig.d.ts +31 -0
- package/dist/nextjs/hooks/useInitialAuthConfig.d.ts.map +1 -0
- package/dist/nextjs/hooks/useInitialAuthConfig.js +109 -0
- package/dist/nextjs/hooks/useInitialAuthConfig.js.map +1 -0
- package/dist/nextjs/index.d.ts +1 -0
- package/dist/nextjs/index.d.ts.map +1 -1
- package/dist/nextjs/index.js +13 -3
- package/dist/nextjs/index.js.map +1 -1
- package/dist/nextjs/providers/NextAuthProvider.d.ts +6 -7
- package/dist/nextjs/providers/NextAuthProvider.d.ts.map +1 -1
- package/dist/nextjs/providers/NextAuthProvider.js +19 -138
- package/dist/nextjs/providers/NextAuthProvider.js.map +1 -1
- package/dist/nextjs/providers/NextAuthProviderClient.d.ts +11 -0
- package/dist/nextjs/providers/NextAuthProviderClient.d.ts.map +1 -0
- package/dist/nextjs/providers/NextAuthProviderClient.js +62 -0
- package/dist/nextjs/providers/NextAuthProviderClient.js.map +1 -0
- package/dist/nextjs/providers/ServerUserContext.d.ts +2 -0
- package/dist/nextjs/providers/ServerUserContext.d.ts.map +1 -0
- package/dist/nextjs/providers/ServerUserContext.js +5 -0
- package/dist/nextjs/providers/ServerUserContext.js.map +1 -0
- package/dist/nextjs/routeHandler.d.ts.map +1 -1
- package/dist/nextjs/routeHandler.js +241 -352
- package/dist/nextjs/routeHandler.js.map +1 -1
- package/dist/react-router-7/components/UserButton.js +1 -1
- package/dist/react-router-7/components/UserButton.js.map +1 -1
- package/dist/react-router-7/routeHandler.d.ts.map +1 -1
- package/dist/react-router-7/routeHandler.js +1 -0
- package/dist/react-router-7/routeHandler.js.map +1 -1
- package/dist/react-router-7/useUser.d.ts.map +1 -1
- package/dist/react-router-7/useUser.js +13 -2
- package/dist/react-router-7/useUser.js.map +1 -1
- package/dist/reactjs/components/ButtonContentOrLoader.d.ts.map +1 -1
- package/dist/reactjs/components/ButtonContentOrLoader.js +2 -4
- package/dist/reactjs/components/ButtonContentOrLoader.js.map +1 -1
- package/dist/reactjs/components/CivicAuthIframeContainer.d.ts +2 -0
- package/dist/reactjs/components/CivicAuthIframeContainer.d.ts.map +1 -0
- package/dist/reactjs/components/CivicAuthIframeContainer.js +26 -0
- package/dist/reactjs/components/CivicAuthIframeContainer.js.map +1 -0
- package/dist/reactjs/components/SignInButton.d.ts.map +1 -1
- package/dist/reactjs/components/SignInButton.js +11 -1
- package/dist/reactjs/components/SignInButton.js.map +1 -1
- package/dist/reactjs/components/UserButton.d.ts +9 -2
- package/dist/reactjs/components/UserButton.d.ts.map +1 -1
- package/dist/reactjs/components/UserButton.js +41 -9
- package/dist/reactjs/components/UserButton.js.map +1 -1
- package/dist/reactjs/components/index.d.ts +1 -0
- package/dist/reactjs/components/index.d.ts.map +1 -1
- package/dist/reactjs/components/index.js +1 -0
- package/dist/reactjs/components/index.js.map +1 -1
- package/dist/reactjs/core/GlobalAuthManager.d.ts +26 -0
- package/dist/reactjs/core/GlobalAuthManager.d.ts.map +1 -1
- package/dist/reactjs/core/GlobalAuthManager.js +76 -5
- package/dist/reactjs/core/GlobalAuthManager.js.map +1 -1
- package/dist/reactjs/hooks/useUser.d.ts +19 -2
- package/dist/reactjs/hooks/useUser.d.ts.map +1 -1
- package/dist/reactjs/hooks/useUser.js +95 -7
- package/dist/reactjs/hooks/useUser.js.map +1 -1
- package/dist/reactjs/index.d.ts +1 -2
- package/dist/reactjs/index.d.ts.map +1 -1
- package/dist/reactjs/index.js +1 -2
- package/dist/reactjs/index.js.map +1 -1
- package/dist/reactjs/providers/CivicAuthProvider.d.ts +2 -1
- package/dist/reactjs/providers/CivicAuthProvider.d.ts.map +1 -1
- package/dist/reactjs/providers/CivicAuthProvider.js +3 -1
- package/dist/reactjs/providers/CivicAuthProvider.js.map +1 -1
- package/dist/server/ServerAuthenticationResolver.d.ts.map +1 -1
- package/dist/server/ServerAuthenticationResolver.js +18 -0
- package/dist/server/ServerAuthenticationResolver.js.map +1 -1
- package/dist/server/index.d.ts +1 -1
- package/dist/server/index.d.ts.map +1 -1
- package/dist/server/index.js.map +1 -1
- package/dist/server/session.d.ts +51 -0
- package/dist/server/session.d.ts.map +1 -1
- package/dist/server/session.js +276 -15
- package/dist/server/session.js.map +1 -1
- package/dist/shared/components/SVGLoading.js +1 -1
- package/dist/shared/components/SVGLoading.js.map +1 -1
- package/dist/shared/components/UserButtonPresentation.d.ts.map +1 -0
- package/dist/shared/components/UserButtonPresentation.js.map +1 -0
- package/dist/shared/hooks/index.d.ts +1 -2
- package/dist/shared/hooks/index.d.ts.map +1 -1
- package/dist/shared/hooks/index.js +1 -2
- package/dist/shared/hooks/index.js.map +1 -1
- package/dist/shared/hooks/useBfcacheHandler.d.ts +23 -0
- package/dist/shared/hooks/useBfcacheHandler.d.ts.map +1 -0
- package/dist/shared/hooks/useBfcacheHandler.js +65 -0
- package/dist/shared/hooks/useBfcacheHandler.js.map +1 -0
- package/dist/shared/index.d.ts +1 -0
- package/dist/shared/index.d.ts.map +1 -1
- package/dist/shared/index.js +1 -0
- package/dist/shared/index.js.map +1 -1
- package/dist/shared/lib/util.d.ts +32 -0
- package/dist/shared/lib/util.d.ts.map +1 -1
- package/dist/shared/lib/util.js +79 -0
- package/dist/shared/lib/util.js.map +1 -1
- package/dist/shared/providers/AuthStatusContext.d.ts.map +1 -1
- package/dist/shared/providers/AuthStatusContext.js +2 -1
- package/dist/shared/providers/AuthStatusContext.js.map +1 -1
- package/dist/shared/providers/CivicAuthConfigContext.d.ts +2 -1
- package/dist/shared/providers/CivicAuthConfigContext.d.ts.map +1 -1
- package/dist/shared/providers/CivicAuthConfigContext.js +5 -2
- package/dist/shared/providers/CivicAuthConfigContext.js.map +1 -1
- package/dist/shared/providers/types.d.ts +1 -0
- package/dist/shared/providers/types.d.ts.map +1 -1
- package/dist/shared/providers/types.js.map +1 -1
- package/dist/shared/utils/locationChange.d.ts +34 -0
- package/dist/shared/utils/locationChange.d.ts.map +1 -0
- package/dist/shared/utils/locationChange.js +28 -0
- package/dist/shared/utils/locationChange.js.map +1 -0
- 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/vanillajs/auth/AuthenticationEvents.d.ts +10 -1
- package/dist/vanillajs/auth/AuthenticationEvents.d.ts.map +1 -1
- package/dist/vanillajs/auth/AuthenticationEvents.js +29 -0
- package/dist/vanillajs/auth/AuthenticationEvents.js.map +1 -1
- package/dist/vanillajs/auth/BackendAuthenticationRefresher.d.ts.map +1 -1
- package/dist/vanillajs/auth/BackendAuthenticationRefresher.js +2 -2
- package/dist/vanillajs/auth/BackendAuthenticationRefresher.js.map +1 -1
- package/dist/vanillajs/auth/CivicAuth.d.ts +32 -0
- package/dist/vanillajs/auth/CivicAuth.d.ts.map +1 -1
- package/dist/vanillajs/auth/CivicAuth.js +255 -55
- package/dist/vanillajs/auth/CivicAuth.js.map +1 -1
- package/dist/vanillajs/auth/SessionManager.d.ts +3 -2
- package/dist/vanillajs/auth/SessionManager.d.ts.map +1 -1
- package/dist/vanillajs/auth/SessionManager.js +33 -7
- package/dist/vanillajs/auth/SessionManager.js.map +1 -1
- package/dist/vanillajs/auth/config/ConfigProcessor.d.ts.map +1 -1
- package/dist/vanillajs/auth/config/ConfigProcessor.js +2 -14
- package/dist/vanillajs/auth/config/ConfigProcessor.js.map +1 -1
- package/dist/vanillajs/auth/handlers/IframeAuthHandler.d.ts.map +1 -1
- package/dist/vanillajs/auth/handlers/IframeAuthHandler.js +64 -11
- package/dist/vanillajs/auth/handlers/IframeAuthHandler.js.map +1 -1
- package/dist/vanillajs/auth/handlers/MessageHandler.d.ts.map +1 -1
- package/dist/vanillajs/auth/handlers/MessageHandler.js +4 -1
- package/dist/vanillajs/auth/handlers/MessageHandler.js.map +1 -1
- package/dist/vanillajs/auth/handlers/PopupHandler.d.ts.map +1 -1
- package/dist/vanillajs/auth/handlers/PopupHandler.js +3 -1
- package/dist/vanillajs/auth/handlers/PopupHandler.js.map +1 -1
- package/dist/vanillajs/auth/types/AuthTypes.d.ts +11 -1
- package/dist/vanillajs/auth/types/AuthTypes.d.ts.map +1 -1
- package/dist/vanillajs/auth/types/AuthTypes.js.map +1 -1
- package/dist/vanillajs/iframe/IframeManager.d.ts +22 -1
- package/dist/vanillajs/iframe/IframeManager.d.ts.map +1 -1
- package/dist/vanillajs/iframe/IframeManager.js +184 -22
- package/dist/vanillajs/iframe/IframeManager.js.map +1 -1
- package/dist/vanillajs/types/index.d.ts +1 -1
- package/dist/vanillajs/types/index.d.ts.map +1 -1
- package/dist/vanillajs/types/index.js +1 -1
- package/dist/vanillajs/types/index.js.map +1 -1
- package/dist/vanillajs/ui/LoadingComponents.d.ts +4 -0
- package/dist/vanillajs/ui/LoadingComponents.d.ts.map +1 -1
- package/dist/vanillajs/ui/LoadingComponents.js +51 -1
- package/dist/vanillajs/ui/LoadingComponents.js.map +1 -1
- package/package.json +3 -3
- package/dist/nextjs/hooks/index.d.ts +0 -2
- package/dist/nextjs/hooks/index.d.ts.map +0 -1
- package/dist/nextjs/hooks/index.js +0 -2
- package/dist/nextjs/hooks/index.js.map +0 -1
- package/dist/nextjs/hooks/usePrevious.d.ts +0 -2
- package/dist/nextjs/hooks/usePrevious.d.ts.map +0 -1
- package/dist/nextjs/hooks/usePrevious.js +0 -9
- package/dist/nextjs/hooks/usePrevious.js.map +0 -1
- package/dist/nextjs/hooks/useUserCookie.d.ts +0 -9
- package/dist/nextjs/hooks/useUserCookie.d.ts.map +0 -1
- package/dist/nextjs/hooks/useUserCookie.js +0 -109
- package/dist/nextjs/hooks/useUserCookie.js.map +0 -1
- package/dist/react-router-7/components/UserButtonPresentation.d.ts.map +0 -1
- package/dist/react-router-7/components/UserButtonPresentation.js.map +0 -1
- package/dist/shared/components/BlockDisplay.d.ts +0 -6
- package/dist/shared/components/BlockDisplay.d.ts.map +0 -1
- package/dist/shared/components/BlockDisplay.js +0 -30
- package/dist/shared/components/BlockDisplay.js.map +0 -1
- package/dist/shared/components/CivicAuthIframe.d.ts +0 -10
- package/dist/shared/components/CivicAuthIframe.d.ts.map +0 -1
- package/dist/shared/components/CivicAuthIframe.js +0 -49
- package/dist/shared/components/CivicAuthIframe.js.map +0 -1
- package/dist/shared/components/CivicAuthIframeContainer.d.ts +0 -15
- package/dist/shared/components/CivicAuthIframeContainer.d.ts.map +0 -1
- package/dist/shared/components/CivicAuthIframeContainer.js +0 -177
- package/dist/shared/components/CivicAuthIframeContainer.js.map +0 -1
- package/dist/shared/components/CivicAuthLogoutIframeContainer.d.ts +0 -6
- package/dist/shared/components/CivicAuthLogoutIframeContainer.d.ts.map +0 -1
- package/dist/shared/components/CivicAuthLogoutIframeContainer.js +0 -51
- package/dist/shared/components/CivicAuthLogoutIframeContainer.js.map +0 -1
- package/dist/shared/components/IFrameAndLoading.d.ts +0 -7
- package/dist/shared/components/IFrameAndLoading.d.ts.map +0 -1
- package/dist/shared/components/IFrameAndLoading.js +0 -66
- package/dist/shared/components/IFrameAndLoading.js.map +0 -1
- package/dist/shared/hooks/useAuth.d.ts +0 -3
- package/dist/shared/hooks/useAuth.d.ts.map +0 -1
- package/dist/shared/hooks/useAuth.js +0 -12
- package/dist/shared/hooks/useAuth.js.map +0 -1
- package/dist/shared/hooks/useIframe.d.ts +0 -3
- package/dist/shared/hooks/useIframe.d.ts.map +0 -1
- package/dist/shared/hooks/useIframe.js +0 -13
- package/dist/shared/hooks/useIframe.js.map +0 -1
- package/dist/shared/hooks/useIsInIframe.d.ts +0 -7
- package/dist/shared/hooks/useIsInIframe.d.ts.map +0 -1
- package/dist/shared/hooks/useIsInIframe.js +0 -23
- package/dist/shared/hooks/useIsInIframe.js.map +0 -1
- package/dist/shared/hooks/useSignIn.d.ts +0 -20
- package/dist/shared/hooks/useSignIn.d.ts.map +0 -1
- package/dist/shared/hooks/useSignIn.js +0 -358
- package/dist/shared/hooks/useSignIn.js.map +0 -1
- package/dist/shared/providers/IframeProvider.d.ts +0 -28
- package/dist/shared/providers/IframeProvider.d.ts.map +0 -1
- package/dist/shared/providers/IframeProvider.js +0 -64
- package/dist/shared/providers/IframeProvider.js.map +0 -1
- /package/dist/{react-router-7 → shared}/components/UserButtonPresentation.d.ts +0 -0
- /package/dist/{react-router-7 → shared}/components/UserButtonPresentation.js +0 -0
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"usePrevious.d.ts","sourceRoot":"","sources":["../../../src/nextjs/hooks/usePrevious.ts"],"names":[],"mappings":"AAEA,wBAAgB,WAAW,CAAC,CAAC,EAAE,KAAK,EAAE,CAAC,iBAMtC"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"usePrevious.js","sourceRoot":"","sources":["../../../src/nextjs/hooks/usePrevious.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,EAAE,MAAM,OAAO,CAAC;AAE1C,MAAM,UAAU,WAAW,CAAI,KAAQ;IACrC,MAAM,GAAG,GAAG,MAAM,EAAK,CAAC;IACxB,SAAS,CAAC,GAAG,EAAE;QACb,GAAG,CAAC,OAAO,GAAG,KAAK,CAAC;IACtB,CAAC,EAAE,CAAC,KAAK,CAAC,CAAC,CAAC;IACZ,OAAO,GAAG,CAAC,OAAO,CAAC;AACrB,CAAC","sourcesContent":["import { useEffect, useRef } from \"react\";\n\nexport function usePrevious<T>(value: T) {\n const ref = useRef<T>();\n useEffect(() => {\n ref.current = value;\n }, [value]);\n return ref.current;\n}\n"]}
|
|
@@ -1,9 +0,0 @@
|
|
|
1
|
-
import type { EmptyObject, User } from "../../types.js";
|
|
2
|
-
export declare const useUserCookie: <T extends EmptyObject>() => {
|
|
3
|
-
user: User<T> | null;
|
|
4
|
-
idToken: string | undefined;
|
|
5
|
-
userChanged: boolean;
|
|
6
|
-
fetchUser: (abortController?: AbortController) => void;
|
|
7
|
-
isLoading: boolean;
|
|
8
|
-
};
|
|
9
|
-
//# sourceMappingURL=useUserCookie.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"useUserCookie.d.ts","sourceRoot":"","sources":["../../../src/nextjs/hooks/useUserCookie.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,WAAW,EAAE,IAAI,EAAE,MAAM,YAAY,CAAC;AAwBpD,eAAO,MAAM,aAAa,GAAI,CAAC,SAAS,WAAW;;;;kCAwBA,eAAe;;CAiFjE,CAAC"}
|
|
@@ -1,109 +0,0 @@
|
|
|
1
|
-
"use client";
|
|
2
|
-
import { useCallback, useEffect, useRef, useState } from "react";
|
|
3
|
-
import { OAuthTokenTypes, UserStorage } from "../../shared/lib/types.js";
|
|
4
|
-
import { objectsAreEqual } from "../../lib/obj.js";
|
|
5
|
-
import { BrowserCookieStorage } from "../../shared/index.js";
|
|
6
|
-
import { useIsClient } from "usehooks-ts";
|
|
7
|
-
const browserCookieStorage = new BrowserCookieStorage();
|
|
8
|
-
const getUserAndTokenFromCookie = () => {
|
|
9
|
-
const userCookie = browserCookieStorage.getSync(UserStorage.USER);
|
|
10
|
-
const idTokenCookie = browserCookieStorage.getSync(OAuthTokenTypes.ID_TOKEN);
|
|
11
|
-
return {
|
|
12
|
-
[UserStorage.USER]: userCookie ? JSON.parse(userCookie) : undefined,
|
|
13
|
-
[OAuthTokenTypes.ID_TOKEN]: idTokenCookie || undefined,
|
|
14
|
-
};
|
|
15
|
-
};
|
|
16
|
-
export const useUserCookie = () => {
|
|
17
|
-
// need to make sure this is only run on the client
|
|
18
|
-
// because it uses cookies that expect a document object to be present to read from
|
|
19
|
-
const isClient = useIsClient();
|
|
20
|
-
const response = (isClient && getUserAndTokenFromCookie()) || {};
|
|
21
|
-
// initialise user and token from cookies so that we don't
|
|
22
|
-
// have to wait for the first fetch to expose these values
|
|
23
|
-
const userData = response[UserStorage.USER];
|
|
24
|
-
const tokenData = response[OAuthTokenTypes.ID_TOKEN];
|
|
25
|
-
// we need both a ref and state for the user and token
|
|
26
|
-
// because the ref is used to compare the previous value
|
|
27
|
-
// to the new value to see if it has changed
|
|
28
|
-
// and the state is used to trigger a re-render
|
|
29
|
-
// when the value changes
|
|
30
|
-
const userRef = useRef(userData);
|
|
31
|
-
const tokenRef = useRef(tokenData);
|
|
32
|
-
const [user, setUser] = useState(userData);
|
|
33
|
-
const [idToken, setToken] = useState(tokenData);
|
|
34
|
-
const [userChanged, setUserChanged] = useState(false);
|
|
35
|
-
const userChangedToggle = useRef(false);
|
|
36
|
-
const [initialFetchComplete, setInitialFetchComplete] = useState(!!userData);
|
|
37
|
-
const fetchUser = useCallback((abortController) => {
|
|
38
|
-
if (abortController?.signal.aborted) {
|
|
39
|
-
setInitialFetchComplete(true);
|
|
40
|
-
return;
|
|
41
|
-
}
|
|
42
|
-
const response = getUserAndTokenFromCookie() || {};
|
|
43
|
-
const userData = response[UserStorage.USER];
|
|
44
|
-
const tokenData = response[OAuthTokenTypes.ID_TOKEN];
|
|
45
|
-
if (abortController?.signal.aborted) {
|
|
46
|
-
setInitialFetchComplete(true);
|
|
47
|
-
return;
|
|
48
|
-
}
|
|
49
|
-
// we use objectsAreEqual here comparing the object references could trigger
|
|
50
|
-
// unnecessary re-renders if the object is the same but a new reference is created
|
|
51
|
-
if (!objectsAreEqual(userData, userRef.current)) {
|
|
52
|
-
userRef.current = userData || null;
|
|
53
|
-
setUser(userData || null);
|
|
54
|
-
// Toggle userChanged to force effect to fire
|
|
55
|
-
userChangedToggle.current = !userChangedToggle.current;
|
|
56
|
-
setUserChanged(userChangedToggle.current);
|
|
57
|
-
}
|
|
58
|
-
if (tokenData !== tokenRef.current) {
|
|
59
|
-
tokenRef.current = tokenData;
|
|
60
|
-
setToken(tokenData);
|
|
61
|
-
}
|
|
62
|
-
setInitialFetchComplete(true);
|
|
63
|
-
}, []);
|
|
64
|
-
/**
|
|
65
|
-
* Set up a listener for when the user cookies change which will be triggered
|
|
66
|
-
* by server-side during token exchange. We are able to receive these updates as the auth
|
|
67
|
-
* calls will be running in the iframe and the cookies will be set in the parent window.
|
|
68
|
-
*/
|
|
69
|
-
useEffect(() => {
|
|
70
|
-
let abortController = new AbortController();
|
|
71
|
-
const cookieListener = () => {
|
|
72
|
-
// pass an abort controller to fetchUser to cancel any in-flight requests
|
|
73
|
-
// that might have been triggered before re-render
|
|
74
|
-
abortController = new AbortController();
|
|
75
|
-
fetchUser(abortController);
|
|
76
|
-
};
|
|
77
|
-
document.addEventListener("visibilitychange", cookieListener);
|
|
78
|
-
window.addEventListener("storage", cookieListener);
|
|
79
|
-
window.addEventListener("focus", cookieListener);
|
|
80
|
-
// set the user and token ref from cookies again as the component has now mounted
|
|
81
|
-
// so cookies might be available that weren't there at initialisation above
|
|
82
|
-
const response = getUserAndTokenFromCookie() || {};
|
|
83
|
-
const userData = response[UserStorage.USER];
|
|
84
|
-
const tokenData = response[OAuthTokenTypes.ID_TOKEN];
|
|
85
|
-
userRef.current = userData;
|
|
86
|
-
tokenRef.current = tokenData;
|
|
87
|
-
setUser(userData);
|
|
88
|
-
setToken(tokenData);
|
|
89
|
-
fetchUser(abortController);
|
|
90
|
-
// poll for changes to the cookies every 2 seconds
|
|
91
|
-
// this is required as react doesn't have a built-in hook that will change on cookie changes
|
|
92
|
-
const intervalId = setInterval(cookieListener, 2000);
|
|
93
|
-
return () => {
|
|
94
|
-
abortController.abort();
|
|
95
|
-
document.removeEventListener("visibilitychange", cookieListener);
|
|
96
|
-
window.removeEventListener("storage", cookieListener);
|
|
97
|
-
window.removeEventListener("focus", cookieListener);
|
|
98
|
-
clearInterval(intervalId);
|
|
99
|
-
};
|
|
100
|
-
}, [fetchUser]);
|
|
101
|
-
return {
|
|
102
|
-
user,
|
|
103
|
-
idToken,
|
|
104
|
-
userChanged,
|
|
105
|
-
fetchUser,
|
|
106
|
-
isLoading: !initialFetchComplete,
|
|
107
|
-
};
|
|
108
|
-
};
|
|
109
|
-
//# sourceMappingURL=useUserCookie.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"useUserCookie.js","sourceRoot":"","sources":["../../../src/nextjs/hooks/useUserCookie.ts"],"names":[],"mappings":"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","sourcesContent":["\"use client\";\nimport { useCallback, useEffect, useRef, useState } from \"react\";\nimport type { EmptyObject, User } from \"@/types.js\";\nimport { OAuthTokenTypes, UserStorage } from \"@/shared/lib/types.js\";\nimport { objectsAreEqual } from \"@/lib/obj.js\";\nimport { BrowserCookieStorage } from \"@/shared/index.js\";\nimport { useIsClient } from \"usehooks-ts\";\n\ntype UserAndTokenFromCookie = {\n [UserStorage.USER]: User | undefined;\n [OAuthTokenTypes.ID_TOKEN]: string | undefined;\n};\nconst browserCookieStorage = new BrowserCookieStorage();\nconst getUserAndTokenFromCookie = (): UserAndTokenFromCookie => {\n const userCookie = browserCookieStorage.getSync(\n UserStorage.USER,\n ) as unknown as string | null;\n const idTokenCookie = browserCookieStorage.getSync(\n OAuthTokenTypes.ID_TOKEN,\n ) as unknown as string | null;\n return {\n [UserStorage.USER]: userCookie ? JSON.parse(userCookie) : undefined,\n [OAuthTokenTypes.ID_TOKEN]: idTokenCookie || undefined,\n };\n};\n\nexport const useUserCookie = <T extends EmptyObject>() => {\n // need to make sure this is only run on the client\n // because it uses cookies that expect a document object to be present to read from\n const isClient = useIsClient();\n const response =\n (isClient && getUserAndTokenFromCookie()) || ({} as UserAndTokenFromCookie);\n // initialise user and token from cookies so that we don't\n // have to wait for the first fetch to expose these values\n const userData = response[UserStorage.USER] as User<T>;\n const tokenData = response[OAuthTokenTypes.ID_TOKEN];\n\n // we need both a ref and state for the user and token\n // because the ref is used to compare the previous value\n // to the new value to see if it has changed\n // and the state is used to trigger a re-render\n // when the value changes\n const userRef = useRef(userData);\n const tokenRef = useRef(tokenData);\n const [user, setUser] = useState<User<T> | null>(userData);\n const [idToken, setToken] = useState<string | undefined>(tokenData);\n const [userChanged, setUserChanged] = useState<boolean>(false);\n const userChangedToggle = useRef(false);\n const [initialFetchComplete, setInitialFetchComplete] = useState(!!userData);\n\n const fetchUser = useCallback((abortController?: AbortController) => {\n if (abortController?.signal.aborted) {\n setInitialFetchComplete(true);\n return;\n }\n\n const response = getUserAndTokenFromCookie() || {};\n const userData = response[UserStorage.USER] as User<T>;\n const tokenData = response[OAuthTokenTypes.ID_TOKEN];\n\n if (abortController?.signal.aborted) {\n setInitialFetchComplete(true);\n return;\n }\n\n // we use objectsAreEqual here comparing the object references could trigger\n // unnecessary re-renders if the object is the same but a new reference is created\n if (!objectsAreEqual(userData, userRef.current)) {\n userRef.current = userData || null;\n setUser(userData || null);\n // Toggle userChanged to force effect to fire\n userChangedToggle.current = !userChangedToggle.current;\n setUserChanged(userChangedToggle.current);\n }\n if (tokenData !== tokenRef.current) {\n tokenRef.current = tokenData;\n setToken(tokenData);\n }\n setInitialFetchComplete(true);\n }, []);\n\n /**\n * Set up a listener for when the user cookies change which will be triggered\n * by server-side during token exchange. We are able to receive these updates as the auth\n * calls will be running in the iframe and the cookies will be set in the parent window.\n */\n useEffect(() => {\n let abortController = new AbortController();\n const cookieListener = () => {\n // pass an abort controller to fetchUser to cancel any in-flight requests\n // that might have been triggered before re-render\n abortController = new AbortController();\n fetchUser(abortController);\n };\n\n document.addEventListener(\"visibilitychange\", cookieListener);\n window.addEventListener(\"storage\", cookieListener);\n window.addEventListener(\"focus\", cookieListener);\n\n // set the user and token ref from cookies again as the component has now mounted\n // so cookies might be available that weren't there at initialisation above\n const response =\n getUserAndTokenFromCookie() || ({} as UserAndTokenFromCookie);\n const userData = response[UserStorage.USER] as User<T>;\n const tokenData = response[OAuthTokenTypes.ID_TOKEN];\n userRef.current = userData;\n tokenRef.current = tokenData;\n setUser(userData);\n setToken(tokenData);\n fetchUser(abortController);\n\n // poll for changes to the cookies every 2 seconds\n // this is required as react doesn't have a built-in hook that will change on cookie changes\n const intervalId = setInterval(cookieListener, 2000);\n\n return () => {\n abortController.abort();\n document.removeEventListener(\"visibilitychange\", cookieListener);\n window.removeEventListener(\"storage\", cookieListener);\n window.removeEventListener(\"focus\", cookieListener);\n clearInterval(intervalId);\n };\n }, [fetchUser]);\n\n return {\n user,\n idToken,\n userChanged,\n fetchUser,\n isLoading: !initialFetchComplete,\n };\n};\n"]}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"UserButtonPresentation.d.ts","sourceRoot":"","sources":["../../../src/react-router-7/components/UserButtonPresentation.tsx"],"names":[],"mappings":"AAEA,UAAU,2BAA2B;IACnC,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,KAAK,CAAC,EAAE,KAAK,CAAC,aAAa,CAAC;IAC5B,OAAO,CAAC,EAAE,MAAM,IAAI,CAAC;IACrB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,QAAQ,EAAE,KAAK,CAAC,SAAS,CAAC;CAC3B;AAED,wBAAgB,sBAAsB,CAAC,EACrC,SAAS,EACT,KAAK,EACL,OAAO,EACP,aAAa,EAAE,UAAU,EACzB,QAAQ,GACT,EAAE,2BAA2B,oDA0B7B"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"UserButtonPresentation.js","sourceRoot":"","sources":["../../../src/react-router-7/components/UserButtonPresentation.tsx"],"names":[],"mappings":"AAAA,YAAY,CAAC;;AAUb,MAAM,UAAU,sBAAsB,CAAC,EACrC,SAAS,EACT,KAAK,EACL,OAAO,EACP,aAAa,EAAE,UAAU,EACzB,QAAQ,GACoB;IAC5B,OAAO,CACL,iBACE,SAAS,EAAE,SAAS,EACpB,KAAK,EAAE;YACL,MAAM,EAAE,SAAS;YACjB,YAAY,EAAE,QAAQ;YACtB,MAAM,EAAE,mBAAmB;YAC3B,OAAO,EAAE,cAAc;YACvB,KAAK,EAAE,SAAS;YAChB,UAAU,EAAE,uBAAuB;YACnC,QAAQ,EAAE,KAAK;YACf,GAAG,KAAK;SACT,EACD,OAAO,EAAE,OAAO,iBACH,UAAU,EACvB,YAAY,EAAE,CAAC,CAAC,EAAE,EAAE;YAClB,CAAC,CAAC,aAAa,CAAC,KAAK,CAAC,eAAe,GAAG,SAAS,CAAC;QACpD,CAAC,EACD,YAAY,EAAE,CAAC,CAAC,EAAE,EAAE;YAClB,CAAC,CAAC,aAAa,CAAC,KAAK,CAAC,eAAe,GAAG,EAAE,CAAC;QAC7C,CAAC,YAEA,QAAQ,GACF,CACV,CAAC;AACJ,CAAC","sourcesContent":["\"use client\";\n\ninterface UserButtonPresentationProps {\n className?: string;\n style?: React.CSSProperties;\n onClick?: () => void;\n \"data-testid\"?: string;\n children: React.ReactNode;\n}\n\nexport function UserButtonPresentation({\n className,\n style,\n onClick,\n \"data-testid\": dataTestId,\n children,\n}: UserButtonPresentationProps) {\n return (\n <button\n className={className}\n style={{\n cursor: \"pointer\",\n borderRadius: \"9999px\",\n border: \"1px solid #6b7280\",\n padding: \"0.75rem 1rem\",\n color: \"#6b7280\",\n transition: \"background-color 0.2s\",\n minWidth: \"9em\",\n ...style,\n }}\n onClick={onClick}\n data-testid={dataTestId}\n onMouseEnter={(e) => {\n e.currentTarget.style.backgroundColor = \"#f3f4f6\";\n }}\n onMouseLeave={(e) => {\n e.currentTarget.style.backgroundColor = \"\";\n }}\n >\n {children}\n </button>\n );\n}\n"]}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"BlockDisplay.d.ts","sourceRoot":"","sources":["../../../src/shared/components/BlockDisplay.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,SAAS,EAAE,MAAM,OAAO,CAAC;AAIvC,QAAA,MAAM,YAAY,iBAAkB;IAAE,QAAQ,EAAE,SAAS,CAAA;CAAE,4DAmC1D,CAAC;AACF,OAAO,EAAE,YAAY,EAAE,CAAC"}
|
|
@@ -1,30 +0,0 @@
|
|
|
1
|
-
import { jsx as _jsx } from "@emotion/react/jsx-runtime";
|
|
2
|
-
import {} from "react";
|
|
3
|
-
import { useIframe } from "../hooks/useIframe.js";
|
|
4
|
-
import { useIsClient } from "usehooks-ts";
|
|
5
|
-
const BlockDisplay = ({ children }) => {
|
|
6
|
-
const { backgroundColor } = useIframe();
|
|
7
|
-
const isClient = useIsClient();
|
|
8
|
-
// don't render in server-mode as the appearance changes after load
|
|
9
|
-
return !isClient ? null : (_jsx("div", { id: "iframe-block-display-wrapper", style: {
|
|
10
|
-
position: "absolute",
|
|
11
|
-
left: 0,
|
|
12
|
-
top: 0,
|
|
13
|
-
zIndex: 200,
|
|
14
|
-
display: "flex",
|
|
15
|
-
height: "100vh",
|
|
16
|
-
width: "100vw",
|
|
17
|
-
alignItems: "center",
|
|
18
|
-
justifyContent: "center",
|
|
19
|
-
backgroundColor,
|
|
20
|
-
}, children: _jsx("div", { id: "iframe-block-display", style: {
|
|
21
|
-
position: "relative",
|
|
22
|
-
inset: 0,
|
|
23
|
-
display: "flex",
|
|
24
|
-
alignItems: "center",
|
|
25
|
-
justifyContent: "center",
|
|
26
|
-
backgroundColor,
|
|
27
|
-
}, children: children }) }));
|
|
28
|
-
};
|
|
29
|
-
export { BlockDisplay };
|
|
30
|
-
//# sourceMappingURL=BlockDisplay.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"BlockDisplay.js","sourceRoot":"","sources":["../../../src/shared/components/BlockDisplay.tsx"],"names":[],"mappings":";AAAA,OAAO,EAAkB,MAAM,OAAO,CAAC;AACvC,OAAO,EAAE,SAAS,EAAE,MAAM,uBAAuB,CAAC;AAClD,OAAO,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAE1C,MAAM,YAAY,GAAG,CAAC,EAAE,QAAQ,EAA2B,EAAE,EAAE;IAC7D,MAAM,EAAE,eAAe,EAAE,GAAG,SAAS,EAAE,CAAC;IACxC,MAAM,QAAQ,GAAG,WAAW,EAAE,CAAC;IAC/B,mEAAmE;IACnE,OAAO,CAAC,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CACxB,cACE,EAAE,EAAC,8BAA8B,EACjC,KAAK,EAAE;YACL,QAAQ,EAAE,UAAU;YACpB,IAAI,EAAE,CAAC;YACP,GAAG,EAAE,CAAC;YACN,MAAM,EAAE,GAAG;YACX,OAAO,EAAE,MAAM;YACf,MAAM,EAAE,OAAO;YACf,KAAK,EAAE,OAAO;YACd,UAAU,EAAE,QAAQ;YACpB,cAAc,EAAE,QAAQ;YACxB,eAAe;SAChB,YAED,cACE,EAAE,EAAC,sBAAsB,EACzB,KAAK,EAAE;gBACL,QAAQ,EAAE,UAAU;gBACpB,KAAK,EAAE,CAAC;gBACR,OAAO,EAAE,MAAM;gBACf,UAAU,EAAE,QAAQ;gBACpB,cAAc,EAAE,QAAQ;gBACxB,eAAe;aAChB,YAEA,QAAQ,GACL,GACF,CACP,CAAC;AACJ,CAAC,CAAC;AACF,OAAO,EAAE,YAAY,EAAE,CAAC","sourcesContent":["import { type ReactNode } from \"react\";\nimport { useIframe } from \"../hooks/useIframe.js\";\nimport { useIsClient } from \"usehooks-ts\";\n\nconst BlockDisplay = ({ children }: { children: ReactNode }) => {\n const { backgroundColor } = useIframe();\n const isClient = useIsClient();\n // don't render in server-mode as the appearance changes after load\n return !isClient ? null : (\n <div\n id=\"iframe-block-display-wrapper\"\n style={{\n position: \"absolute\",\n left: 0,\n top: 0,\n zIndex: 200,\n display: \"flex\",\n height: \"100vh\",\n width: \"100vw\",\n alignItems: \"center\",\n justifyContent: \"center\",\n backgroundColor,\n }}\n >\n <div\n id=\"iframe-block-display\"\n style={{\n position: \"relative\",\n inset: 0,\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"center\",\n backgroundColor,\n }}\n >\n {children}\n </div>\n </div>\n );\n};\nexport { BlockDisplay };\n"]}
|
|
@@ -1,10 +0,0 @@
|
|
|
1
|
-
import React from "react";
|
|
2
|
-
type CivicAuthIframeProps = {
|
|
3
|
-
onLoad?: () => void;
|
|
4
|
-
id: string;
|
|
5
|
-
isRedirecting?: boolean;
|
|
6
|
-
};
|
|
7
|
-
declare const CivicAuthIframe: React.ForwardRefExoticComponent<CivicAuthIframeProps & React.RefAttributes<HTMLIFrameElement>>;
|
|
8
|
-
export type { CivicAuthIframeProps };
|
|
9
|
-
export { CivicAuthIframe };
|
|
10
|
-
//# sourceMappingURL=CivicAuthIframe.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"CivicAuthIframe.d.ts","sourceRoot":"","sources":["../../../src/shared/components/CivicAuthIframe.tsx"],"names":[],"mappings":"AACA,OAAO,KAAqB,MAAM,OAAO,CAAC;AAM1C,KAAK,oBAAoB,GAAG;IAC1B,MAAM,CAAC,EAAE,MAAM,IAAI,CAAC;IACpB,EAAE,EAAE,MAAM,CAAC;IACX,aAAa,CAAC,EAAE,OAAO,CAAC;CACzB,CAAC;AAEF,QAAA,MAAM,eAAe,gGA6EpB,CAAC;AAIF,YAAY,EAAE,oBAAoB,EAAE,CAAC;AAErC,OAAO,EAAE,eAAe,EAAE,CAAC"}
|
|
@@ -1,49 +0,0 @@
|
|
|
1
|
-
"use client";
|
|
2
|
-
import { jsx as _jsx, jsxs as _jsxs } from "@emotion/react/jsx-runtime";
|
|
3
|
-
import React, { forwardRef } from "react";
|
|
4
|
-
import { IframeResizer } from "@civic/iframe-resizer";
|
|
5
|
-
import SVGLoading from "./SVGLoading.js";
|
|
6
|
-
import { useIframe } from "../hooks/useIframe.js";
|
|
7
|
-
import { useIsClient } from "usehooks-ts";
|
|
8
|
-
const CivicAuthIframe = forwardRef(({ onLoad, id, isRedirecting }, ref) => {
|
|
9
|
-
const [isLoaded, setIsLoaded] = React.useState(false);
|
|
10
|
-
const { iframeMode, backgroundColor } = useIframe();
|
|
11
|
-
const iframeRef = ref;
|
|
12
|
-
const isClient = useIsClient();
|
|
13
|
-
// don't render on the server as the appearance changes when the iframe is loaded from login-app post-messages
|
|
14
|
-
return !isClient ? null : (_jsxs("div", { style: {
|
|
15
|
-
position: "relative",
|
|
16
|
-
borderRadius: isLoaded ? "26px" : 0,
|
|
17
|
-
overflow: "hidden",
|
|
18
|
-
transition: "all 250ms ease",
|
|
19
|
-
backgroundColor: isLoaded ? backgroundColor : "transparent",
|
|
20
|
-
minHeight: iframeMode !== "embedded" ? "26px" : "auto",
|
|
21
|
-
}, children: [!isLoaded || isRedirecting ? (_jsx("div", { "data-testid": "iframe-shimmer-loader", style: {
|
|
22
|
-
width: "100%",
|
|
23
|
-
height: "26px",
|
|
24
|
-
display: "flex",
|
|
25
|
-
alignItems: "center",
|
|
26
|
-
justifyContent: "center",
|
|
27
|
-
position: "absolute",
|
|
28
|
-
top: "50%",
|
|
29
|
-
left: "50%",
|
|
30
|
-
transform: "translate(-50%, -50%)",
|
|
31
|
-
borderRadius: "13px",
|
|
32
|
-
overflow: "hidden",
|
|
33
|
-
}, children: iframeMode !== "embedded" && (_jsx(SVGLoading, { backgroundColor: backgroundColor })) })) : null, _jsx("div", { style: {
|
|
34
|
-
opacity: isLoaded ? 1 : 0,
|
|
35
|
-
transition: "opacity 250ms ease",
|
|
36
|
-
}, children: !isRedirecting && (_jsx(IframeResizer, { ref: iframeRef, id: id, "data-testid": "civic-auth-iframe-with-resizer", initialHeight: iframeMode !== "embedded" ? "26px" : "max-content", animate: true, animationDuration: 250, checkOrigin: false, style: {
|
|
37
|
-
width: "100%",
|
|
38
|
-
border: "none",
|
|
39
|
-
minWidth: "100%",
|
|
40
|
-
backgroundColor: isLoaded ? backgroundColor : "transparent",
|
|
41
|
-
pointerEvents: "auto",
|
|
42
|
-
}, onLoad: () => {
|
|
43
|
-
setIsLoaded(true);
|
|
44
|
-
onLoad?.();
|
|
45
|
-
}, allow: "camera; screen-wake-lock; publickey-credentials-get *; publickey-credentials-create *;", allowFullScreen: true })) })] }));
|
|
46
|
-
});
|
|
47
|
-
CivicAuthIframe.displayName = "CivicAuthIframe";
|
|
48
|
-
export { CivicAuthIframe };
|
|
49
|
-
//# sourceMappingURL=CivicAuthIframe.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"CivicAuthIframe.js","sourceRoot":"","sources":["../../../src/shared/components/CivicAuthIframe.tsx"],"names":[],"mappings":"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","sourcesContent":["\"use client\";\nimport React, { forwardRef } from \"react\";\nimport { IframeResizer } from \"@civic/iframe-resizer\";\nimport SVGLoading from \"./SVGLoading.js\";\nimport { useIframe } from \"../hooks/useIframe.js\";\nimport { useIsClient } from \"usehooks-ts\";\n\ntype CivicAuthIframeProps = {\n onLoad?: () => void;\n id: string;\n isRedirecting?: boolean; // Optional prop to indicate if the iframe is redirecting\n};\n\nconst CivicAuthIframe = forwardRef<HTMLIFrameElement, CivicAuthIframeProps>(\n ({ onLoad, id, isRedirecting }, ref) => {\n const [isLoaded, setIsLoaded] = React.useState(false);\n const { iframeMode, backgroundColor } = useIframe();\n const iframeRef = ref;\n const isClient = useIsClient();\n\n // don't render on the server as the appearance changes when the iframe is loaded from login-app post-messages\n return !isClient ? null : (\n <div\n style={{\n position: \"relative\",\n borderRadius: isLoaded ? \"26px\" : 0,\n overflow: \"hidden\",\n transition: \"all 250ms ease\",\n backgroundColor: isLoaded ? backgroundColor : \"transparent\",\n minHeight: iframeMode !== \"embedded\" ? \"26px\" : \"auto\",\n }}\n >\n {/* show the shimmer effect while loading or redirecting */}\n {!isLoaded || isRedirecting ? (\n <div\n data-testid=\"iframe-shimmer-loader\"\n style={{\n width: \"100%\",\n height: \"26px\",\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"center\",\n position: \"absolute\",\n top: \"50%\",\n left: \"50%\",\n transform: \"translate(-50%, -50%)\",\n borderRadius: \"13px\",\n overflow: \"hidden\",\n }}\n >\n {iframeMode !== \"embedded\" && (\n <SVGLoading backgroundColor={backgroundColor} />\n )}\n </div>\n ) : null}\n <div\n style={{\n opacity: isLoaded ? 1 : 0,\n transition: \"opacity 250ms ease\",\n }}\n >\n {/* don't need to show the iframe at all if we are redirecting */}\n {!isRedirecting && (\n <IframeResizer\n ref={iframeRef}\n id={id}\n data-testid={\"civic-auth-iframe-with-resizer\"}\n initialHeight={iframeMode !== \"embedded\" ? \"26px\" : \"max-content\"}\n animate={true}\n animationDuration={250}\n checkOrigin={false}\n style={{\n width: \"100%\",\n border: \"none\",\n minWidth: \"100%\",\n backgroundColor: isLoaded ? backgroundColor : \"transparent\",\n pointerEvents: \"auto\",\n }}\n onLoad={() => {\n setIsLoaded(true);\n onLoad?.();\n }}\n allow=\"camera; screen-wake-lock; publickey-credentials-get *; publickey-credentials-create *;\"\n allowFullScreen\n />\n )}\n </div>\n </div>\n );\n },\n);\n\nCivicAuthIframe.displayName = \"CivicAuthIframe\";\n\nexport type { CivicAuthIframeProps };\n\nexport { CivicAuthIframe };\n"]}
|
|
@@ -1,15 +0,0 @@
|
|
|
1
|
-
import React from "react";
|
|
2
|
-
type CivicAuthIframeContainerProps = {
|
|
3
|
-
onClose?: () => void;
|
|
4
|
-
closeOnRedirect?: boolean;
|
|
5
|
-
};
|
|
6
|
-
export declare function IframeChrome({ children, onClose, isFrameLoaded, isRedirecting, }: {
|
|
7
|
-
children: React.ReactNode;
|
|
8
|
-
onClose?: () => void;
|
|
9
|
-
isFrameLoaded: boolean;
|
|
10
|
-
isRedirecting?: boolean;
|
|
11
|
-
}): import("@emotion/react/jsx-runtime").JSX.Element;
|
|
12
|
-
declare const CivicAuthIframeContainer: ({ onClose, closeOnRedirect, }: CivicAuthIframeContainerProps) => import("@emotion/react/jsx-runtime").JSX.Element;
|
|
13
|
-
export type { CivicAuthIframeContainerProps };
|
|
14
|
-
export { CivicAuthIframeContainer };
|
|
15
|
-
//# sourceMappingURL=CivicAuthIframeContainer.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"CivicAuthIframeContainer.d.ts","sourceRoot":"","sources":["../../../src/shared/components/CivicAuthIframeContainer.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAmD,MAAM,OAAO,CAAC;AAcxE,KAAK,6BAA6B,GAAG;IACnC,OAAO,CAAC,EAAE,MAAM,IAAI,CAAC;IACrB,eAAe,CAAC,EAAE,OAAO,CAAC;CAC3B,CAAC;AAeF,wBAAgB,YAAY,CAAC,EAC3B,QAAQ,EACR,OAAO,EACP,aAAa,EACb,aAAa,GACd,EAAE;IACD,QAAQ,EAAE,KAAK,CAAC,SAAS,CAAC;IAC1B,OAAO,CAAC,EAAE,MAAM,IAAI,CAAC;IACrB,aAAa,EAAE,OAAO,CAAC;IACvB,aAAa,CAAC,EAAE,OAAO,CAAC;CACzB,oDA8DA;AAED,QAAA,MAAM,wBAAwB,kCAG3B,6BAA6B,qDA4K/B,CAAC;AAEF,YAAY,EAAE,6BAA6B,EAAE,CAAC;AAE9C,OAAO,EAAE,wBAAwB,EAAE,CAAC"}
|
|
@@ -1,177 +0,0 @@
|
|
|
1
|
-
"use client";
|
|
2
|
-
import { jsx as _jsx, jsxs as _jsxs } from "@emotion/react/jsx-runtime";
|
|
3
|
-
import React, { useCallback, useEffect, useRef, useState } from "react";
|
|
4
|
-
import { LoadingIcon } from "../../shared/components/LoadingIcon.js";
|
|
5
|
-
import { CloseIcon } from "../../shared/components/CloseIcon.js";
|
|
6
|
-
import { CivicAuthIframe } from "../../shared/components/CivicAuthIframe.js";
|
|
7
|
-
import { useIframe } from "../../shared/hooks/index.js";
|
|
8
|
-
import { TOKEN_EXCHANGE_SUCCESS_TEXT, TOKEN_EXCHANGE_TRIGGER_TEXT, } from "../../constants.js";
|
|
9
|
-
import { useCivicAuthConfig } from "../../shared/hooks/index.js";
|
|
10
|
-
import { useClientTokenExchangeSession } from "../../shared/hooks/index.js";
|
|
11
|
-
import { getIframeRef } from "../lib/iframeUtils.js";
|
|
12
|
-
import { useIsClient } from "usehooks-ts";
|
|
13
|
-
function NoChrome({ children, }) {
|
|
14
|
-
return (_jsx("div", { "data-testid": "civic-iframe-no-chrome", style: { position: "relative" }, children: children }));
|
|
15
|
-
}
|
|
16
|
-
export function IframeChrome({ children, onClose, isFrameLoaded, isRedirecting, }) {
|
|
17
|
-
const { setIframeAborted } = useIframe();
|
|
18
|
-
return (_jsx("div", { style: {
|
|
19
|
-
position: "absolute",
|
|
20
|
-
left: 0,
|
|
21
|
-
top: 0,
|
|
22
|
-
zIndex: 50,
|
|
23
|
-
display: "flex",
|
|
24
|
-
height: "100vh",
|
|
25
|
-
width: "100vw",
|
|
26
|
-
alignItems: "center",
|
|
27
|
-
justifyContent: "center",
|
|
28
|
-
backgroundColor: "rgba(17, 24, 39, 0.5)",
|
|
29
|
-
backdropFilter: "blur(4px)",
|
|
30
|
-
}, onClick: () => {
|
|
31
|
-
setIframeAborted(true);
|
|
32
|
-
onClose?.();
|
|
33
|
-
}, children: _jsxs("div", { "data-testid": "iframe-chrome", style: {
|
|
34
|
-
position: "relative",
|
|
35
|
-
overflow: "hidden",
|
|
36
|
-
paddingLeft: "0",
|
|
37
|
-
paddingRight: "0",
|
|
38
|
-
paddingBottom: "0",
|
|
39
|
-
width: "22rem",
|
|
40
|
-
}, onClick: (e) => e.stopPropagation(), children: [isFrameLoaded && !isRedirecting && (_jsx("button", { style: {
|
|
41
|
-
position: "absolute",
|
|
42
|
-
right: "0.6rem",
|
|
43
|
-
top: "0.6rem",
|
|
44
|
-
cursor: "pointer",
|
|
45
|
-
alignItems: "center",
|
|
46
|
-
justifyContent: "center",
|
|
47
|
-
border: "none",
|
|
48
|
-
backgroundColor: "transparent",
|
|
49
|
-
padding: "0.25rem",
|
|
50
|
-
color: "#9ca3af",
|
|
51
|
-
zIndex: 100,
|
|
52
|
-
}, onClick: () => {
|
|
53
|
-
setIframeAborted(true);
|
|
54
|
-
onClose?.();
|
|
55
|
-
}, children: _jsx(CloseIcon, {}) })), children] }) }));
|
|
56
|
-
}
|
|
57
|
-
const CivicAuthIframeContainer = ({ onClose, closeOnRedirect = true, }) => {
|
|
58
|
-
const config = useCivicAuthConfig();
|
|
59
|
-
const [tokenExchangeUrl, setTokenExchangeUrl] = useState(null);
|
|
60
|
-
const { doTokenExchange } = useClientTokenExchangeSession();
|
|
61
|
-
const { iframeRef, iframeMode, backgroundColor, setIframeMounted } = useIframe();
|
|
62
|
-
const [isIframeContentLoaded, setIsIframeContentLoaded] = useState(false);
|
|
63
|
-
const [isRedirecting, setIsRedirecting] = useState(false);
|
|
64
|
-
useEffect(() => {
|
|
65
|
-
setIframeMounted(true);
|
|
66
|
-
}, [setIframeMounted]);
|
|
67
|
-
useEffect(() => {
|
|
68
|
-
if (tokenExchangeUrl) {
|
|
69
|
-
doTokenExchange?.(tokenExchangeUrl);
|
|
70
|
-
}
|
|
71
|
-
}, [doTokenExchange, tokenExchangeUrl]);
|
|
72
|
-
const processIframeUrl = useCallback(() => {
|
|
73
|
-
if (!config)
|
|
74
|
-
return;
|
|
75
|
-
if (iframeRef && iframeRef.current) {
|
|
76
|
-
const ref = getIframeRef(iframeRef.current);
|
|
77
|
-
if (ref?.contentWindow) {
|
|
78
|
-
try {
|
|
79
|
-
const iframeUrl = ref.contentWindow.location.href;
|
|
80
|
-
// we know that oauth has finished when the iframe redirects to our redirectUrl
|
|
81
|
-
if (iframeUrl.startsWith(config.redirectUrl)) {
|
|
82
|
-
const iframeBody = ref.contentWindow.document.body.innerHTML;
|
|
83
|
-
// If we're doing a server token exchange, we need to call the server a second time
|
|
84
|
-
// using a fetch so that we're on the same domain and cookies can be sent and read
|
|
85
|
-
// The server will use the presence of the code_verifier cookie to determine whether to do a token exchange or not.
|
|
86
|
-
// On the initial (3rd party) redirect from the auth server, the cookie won't be sent, so the server-side callback route will just render a blank page,
|
|
87
|
-
// and we'll do the exchange request from here, which will include the cookies.
|
|
88
|
-
if (iframeBody.includes(TOKEN_EXCHANGE_TRIGGER_TEXT)) {
|
|
89
|
-
const params = new URL(iframeUrl).searchParams;
|
|
90
|
-
const appUrl = globalThis.window?.location?.origin;
|
|
91
|
-
fetch(`${config.redirectUrl}?${params.toString()}&appUrl=${appUrl}`);
|
|
92
|
-
}
|
|
93
|
-
else {
|
|
94
|
-
// if we're doing token-exchange in the client, we can just set the authResponseUrl
|
|
95
|
-
// to be handled by the auth provider
|
|
96
|
-
// iframeRef.current.setAttribute("src", "");
|
|
97
|
-
setTokenExchangeUrl(iframeUrl);
|
|
98
|
-
}
|
|
99
|
-
if (iframeBody.includes(TOKEN_EXCHANGE_SUCCESS_TEXT) &&
|
|
100
|
-
config.loginSuccessUrl) {
|
|
101
|
-
globalThis.window.location.href = config.loginSuccessUrl;
|
|
102
|
-
}
|
|
103
|
-
if (closeOnRedirect)
|
|
104
|
-
onClose?.();
|
|
105
|
-
return true; // Successfully processed the URL
|
|
106
|
-
}
|
|
107
|
-
}
|
|
108
|
-
catch {
|
|
109
|
-
// ignore errors while waiting for redirect
|
|
110
|
-
}
|
|
111
|
-
}
|
|
112
|
-
}
|
|
113
|
-
return false; // Haven't processed the URL yet
|
|
114
|
-
}, [closeOnRedirect, config, iframeRef, onClose]);
|
|
115
|
-
const intervalId = useRef();
|
|
116
|
-
const handleEscape = useCallback((event) => {
|
|
117
|
-
if (event.key === "Escape") {
|
|
118
|
-
onClose?.();
|
|
119
|
-
}
|
|
120
|
-
}, [onClose]);
|
|
121
|
-
// handle Escape
|
|
122
|
-
useEffect(() => {
|
|
123
|
-
window.addEventListener("keydown", handleEscape);
|
|
124
|
-
window.addEventListener("locationWillChange", () => {
|
|
125
|
-
console.log("locationWillChange event triggered, setting isRedirecting to true");
|
|
126
|
-
// If the location will
|
|
127
|
-
// Show loading state
|
|
128
|
-
setIsRedirecting(true);
|
|
129
|
-
});
|
|
130
|
-
return () => window.removeEventListener("keydown", handleEscape);
|
|
131
|
-
});
|
|
132
|
-
const handleIframeLoad = useCallback(() => {
|
|
133
|
-
setIsIframeContentLoaded(true);
|
|
134
|
-
const iframeHasUrl = processIframeUrl();
|
|
135
|
-
if (iframeHasUrl && intervalId.current) {
|
|
136
|
-
clearInterval(intervalId.current);
|
|
137
|
-
}
|
|
138
|
-
}, [processIframeUrl, intervalId]);
|
|
139
|
-
const WrapperComponent = iframeMode === "embedded" ? NoChrome : IframeChrome;
|
|
140
|
-
const isClient = useIsClient();
|
|
141
|
-
// if the iframe is embedded, we need to handle the loading state differently
|
|
142
|
-
if (iframeMode === "embedded") {
|
|
143
|
-
return (_jsx(WrapperComponent, { onClose: onClose, isFrameLoaded: isIframeContentLoaded, children: _jsxs("div", { style: {
|
|
144
|
-
minHeight: isIframeContentLoaded ? "auto" : "225px",
|
|
145
|
-
backgroundColor: isClient ? backgroundColor : "#8E949D",
|
|
146
|
-
borderRadius: "26px",
|
|
147
|
-
position: "relative",
|
|
148
|
-
transition: "all 0.5s ease-in-out",
|
|
149
|
-
display: "flex",
|
|
150
|
-
alignItems: "center",
|
|
151
|
-
justifyContent: "center",
|
|
152
|
-
overflow: "hidden",
|
|
153
|
-
}, children: [!isIframeContentLoaded && (_jsx("div", { style: {
|
|
154
|
-
position: "absolute",
|
|
155
|
-
top: 0,
|
|
156
|
-
left: 0,
|
|
157
|
-
right: 0,
|
|
158
|
-
bottom: 0,
|
|
159
|
-
display: "flex",
|
|
160
|
-
alignItems: "center",
|
|
161
|
-
justifyContent: "center",
|
|
162
|
-
}, children: _jsx(LoadingIcon, {}) })), _jsx("div", { style: {
|
|
163
|
-
width: "100%",
|
|
164
|
-
minWidth: "100%",
|
|
165
|
-
alignItems: "center",
|
|
166
|
-
justifyContent: "center",
|
|
167
|
-
borderRadius: "26px",
|
|
168
|
-
overflow: "hidden",
|
|
169
|
-
opacity: isIframeContentLoaded ? 1 : 0,
|
|
170
|
-
transition: "opacity 0.5s ease-in-out",
|
|
171
|
-
}, children: _jsx(CivicAuthIframe, { ref: iframeRef, id: "civic-auth-iframe", onLoad: handleIframeLoad }) })] }) }));
|
|
172
|
-
}
|
|
173
|
-
// if the iframe is not embedded, we can just render the iframe directly
|
|
174
|
-
return (_jsx(WrapperComponent, { onClose: onClose, isFrameLoaded: isIframeContentLoaded, isRedirecting: isRedirecting, children: _jsx(CivicAuthIframe, { ref: iframeRef, id: "civic-auth-iframe", onLoad: handleIframeLoad, isRedirecting: isRedirecting }) }));
|
|
175
|
-
};
|
|
176
|
-
export { CivicAuthIframeContainer };
|
|
177
|
-
//# sourceMappingURL=CivicAuthIframeContainer.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"CivicAuthIframeContainer.js","sourceRoot":"","sources":["../../../src/shared/components/CivicAuthIframeContainer.tsx"],"names":[],"mappings":"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","sourcesContent":["\"use client\";\n\nimport React, { useCallback, useEffect, useRef, useState } from \"react\";\nimport { LoadingIcon } from \"@/shared/components/LoadingIcon.js\";\nimport { CloseIcon } from \"@/shared/components/CloseIcon.js\";\nimport { CivicAuthIframe } from \"@/shared/components/CivicAuthIframe.js\";\nimport { useIframe } from \"@/shared/hooks/index.js\";\nimport {\n TOKEN_EXCHANGE_SUCCESS_TEXT,\n TOKEN_EXCHANGE_TRIGGER_TEXT,\n} from \"@/constants.js\";\nimport { useCivicAuthConfig } from \"@/shared/hooks/index.js\";\nimport { useClientTokenExchangeSession } from \"@/shared/hooks/index.js\";\nimport { getIframeRef } from \"../lib/iframeUtils.js\";\nimport { useIsClient } from \"usehooks-ts\";\n\ntype CivicAuthIframeContainerProps = {\n onClose?: () => void;\n closeOnRedirect?: boolean;\n};\n\nfunction NoChrome({\n children,\n}: {\n children: React.ReactNode;\n onClose?: () => void;\n}) {\n return (\n <div data-testid=\"civic-iframe-no-chrome\" style={{ position: \"relative\" }}>\n {children}\n </div>\n );\n}\n\nexport function IframeChrome({\n children,\n onClose,\n isFrameLoaded,\n isRedirecting,\n}: {\n children: React.ReactNode;\n onClose?: () => void;\n isFrameLoaded: boolean;\n isRedirecting?: boolean;\n}) {\n const { setIframeAborted } = useIframe();\n\n return (\n <div\n style={{\n position: \"absolute\",\n left: 0,\n top: 0,\n zIndex: 50,\n display: \"flex\",\n height: \"100vh\",\n width: \"100vw\",\n alignItems: \"center\",\n justifyContent: \"center\",\n backgroundColor: \"rgba(17, 24, 39, 0.5)\",\n backdropFilter: \"blur(4px)\",\n }}\n onClick={() => {\n setIframeAborted(true);\n onClose?.();\n }}\n >\n <div\n data-testid=\"iframe-chrome\"\n style={{\n position: \"relative\",\n overflow: \"hidden\",\n paddingLeft: \"0\",\n paddingRight: \"0\",\n paddingBottom: \"0\",\n width: \"22rem\",\n }}\n onClick={(e) => e.stopPropagation()}\n >\n {isFrameLoaded && !isRedirecting && (\n <button\n style={{\n position: \"absolute\",\n right: \"0.6rem\",\n top: \"0.6rem\",\n cursor: \"pointer\",\n alignItems: \"center\",\n justifyContent: \"center\",\n border: \"none\",\n backgroundColor: \"transparent\",\n padding: \"0.25rem\",\n color: \"#9ca3af\",\n zIndex: 100,\n }}\n onClick={() => {\n setIframeAborted(true);\n onClose?.();\n }}\n >\n <CloseIcon />\n </button>\n )}\n {children}\n </div>\n </div>\n );\n}\n\nconst CivicAuthIframeContainer = ({\n onClose,\n closeOnRedirect = true,\n}: CivicAuthIframeContainerProps) => {\n const config = useCivicAuthConfig();\n const [tokenExchangeUrl, setTokenExchangeUrl] = useState<string | null>(null);\n const { doTokenExchange } = useClientTokenExchangeSession();\n const { iframeRef, iframeMode, backgroundColor, setIframeMounted } =\n useIframe();\n const [isIframeContentLoaded, setIsIframeContentLoaded] = useState(false);\n const [isRedirecting, setIsRedirecting] = useState(false);\n useEffect(() => {\n setIframeMounted(true);\n }, [setIframeMounted]);\n\n useEffect(() => {\n if (tokenExchangeUrl) {\n doTokenExchange?.(tokenExchangeUrl);\n }\n }, [doTokenExchange, tokenExchangeUrl]);\n\n const processIframeUrl = useCallback(() => {\n if (!config) return;\n if (iframeRef && iframeRef.current) {\n const ref = getIframeRef(iframeRef.current)!;\n if (ref?.contentWindow) {\n try {\n const iframeUrl = ref.contentWindow.location.href;\n // we know that oauth has finished when the iframe redirects to our redirectUrl\n if (iframeUrl.startsWith(config.redirectUrl)) {\n const iframeBody = ref.contentWindow.document.body.innerHTML;\n\n // If we're doing a server token exchange, we need to call the server a second time\n // using a fetch so that we're on the same domain and cookies can be sent and read\n // The server will use the presence of the code_verifier cookie to determine whether to do a token exchange or not.\n // On the initial (3rd party) redirect from the auth server, the cookie won't be sent, so the server-side callback route will just render a blank page,\n // and we'll do the exchange request from here, which will include the cookies.\n if (iframeBody.includes(TOKEN_EXCHANGE_TRIGGER_TEXT)) {\n const params = new URL(iframeUrl).searchParams;\n const appUrl = globalThis.window?.location?.origin;\n fetch(\n `${config.redirectUrl}?${params.toString()}&appUrl=${appUrl}`,\n );\n } else {\n // if we're doing token-exchange in the client, we can just set the authResponseUrl\n // to be handled by the auth provider\n // iframeRef.current.setAttribute(\"src\", \"\");\n setTokenExchangeUrl(iframeUrl);\n }\n if (\n iframeBody.includes(TOKEN_EXCHANGE_SUCCESS_TEXT) &&\n config.loginSuccessUrl\n ) {\n globalThis.window.location.href = config.loginSuccessUrl;\n }\n\n if (closeOnRedirect) onClose?.();\n return true; // Successfully processed the URL\n }\n } catch {\n // ignore errors while waiting for redirect\n }\n }\n }\n return false; // Haven't processed the URL yet\n }, [closeOnRedirect, config, iframeRef, onClose]);\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 window.addEventListener(\"locationWillChange\", () => {\n console.log(\n \"locationWillChange event triggered, setting isRedirecting to true\",\n );\n // If the location will\n // Show loading state\n setIsRedirecting(true);\n });\n return () => window.removeEventListener(\"keydown\", handleEscape);\n });\n\n const handleIframeLoad = useCallback(() => {\n setIsIframeContentLoaded(true);\n\n const iframeHasUrl = processIframeUrl();\n if (iframeHasUrl && intervalId.current) {\n clearInterval(intervalId.current);\n }\n }, [processIframeUrl, intervalId]);\n\n const WrapperComponent = iframeMode === \"embedded\" ? NoChrome : IframeChrome;\n const isClient = useIsClient();\n // if the iframe is embedded, we need to handle the loading state differently\n if (iframeMode === \"embedded\") {\n return (\n <WrapperComponent onClose={onClose} isFrameLoaded={isIframeContentLoaded}>\n <div\n style={{\n minHeight: isIframeContentLoaded ? \"auto\" : \"225px\",\n backgroundColor: isClient ? backgroundColor : \"#8E949D\",\n borderRadius: \"26px\",\n position: \"relative\",\n transition: \"all 0.5s ease-in-out\",\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"center\",\n overflow: \"hidden\",\n }}\n >\n {/* always load the loading spinner in the center of the iframe */}\n {!isIframeContentLoaded && (\n <div\n style={{\n position: \"absolute\",\n top: 0,\n left: 0,\n right: 0,\n bottom: 0,\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"center\",\n }}\n >\n <LoadingIcon />\n </div>\n )}\n <div\n style={{\n width: \"100%\",\n minWidth: \"100%\",\n alignItems: \"center\",\n justifyContent: \"center\",\n borderRadius: \"26px\",\n overflow: \"hidden\",\n opacity: isIframeContentLoaded ? 1 : 0,\n transition: \"opacity 0.5s ease-in-out\",\n }}\n >\n <CivicAuthIframe\n ref={iframeRef}\n id={\"civic-auth-iframe\"}\n onLoad={handleIframeLoad}\n />\n </div>\n </div>\n </WrapperComponent>\n );\n }\n\n // if the iframe is not embedded, we can just render the iframe directly\n return (\n <WrapperComponent\n onClose={onClose}\n isFrameLoaded={isIframeContentLoaded}\n isRedirecting={isRedirecting}\n >\n <CivicAuthIframe\n ref={iframeRef}\n id={\"civic-auth-iframe\"}\n onLoad={handleIframeLoad}\n isRedirecting={isRedirecting} // Pass the isRedirecting state to the iframe\n />\n </WrapperComponent>\n );\n};\n\nexport type { CivicAuthIframeContainerProps };\n\nexport { CivicAuthIframeContainer };\n"]}
|
|
@@ -1,6 +0,0 @@
|
|
|
1
|
-
type CivicAuthLogoutIframeContainerProps = {
|
|
2
|
-
isLoading?: boolean;
|
|
3
|
-
};
|
|
4
|
-
declare const CivicAuthLogoutIframeContainer: ({ isLoading, }: CivicAuthLogoutIframeContainerProps) => import("@emotion/react/jsx-runtime").JSX.Element | null;
|
|
5
|
-
export { CivicAuthLogoutIframeContainer };
|
|
6
|
-
//# sourceMappingURL=CivicAuthLogoutIframeContainer.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"CivicAuthLogoutIframeContainer.d.ts","sourceRoot":"","sources":["../../../src/shared/components/CivicAuthLogoutIframeContainer.tsx"],"names":[],"mappings":"AAWA,KAAK,mCAAmC,GAAG;IACzC,SAAS,CAAC,EAAE,OAAO,CAAC;CACrB,CAAC;AAEF,QAAA,MAAM,8BAA8B,mBAEjC,mCAAmC,4DA4DrC,CAAC;AAEF,OAAO,EAAE,8BAA8B,EAAE,CAAC"}
|
|
@@ -1,51 +0,0 @@
|
|
|
1
|
-
"use client";
|
|
2
|
-
import { jsx as _jsx, jsxs as _jsxs } from "@emotion/react/jsx-runtime";
|
|
3
|
-
import { CivicAuthIframe } from "../../shared/components/CivicAuthIframe.js";
|
|
4
|
-
import { useIframe } from "../../shared/hooks/index.js";
|
|
5
|
-
import { LoadingIcon } from "./LoadingIcon.js";
|
|
6
|
-
import { IframeChrome } from "./CivicAuthIframeContainer.js";
|
|
7
|
-
import { useIsClient } from "usehooks-ts";
|
|
8
|
-
import { useCallback } from "react";
|
|
9
|
-
import { getIframeRef } from "../lib/iframeUtils.js";
|
|
10
|
-
import { LOGOUT_SUCCESS_TEXT } from "../../constants.js";
|
|
11
|
-
const CivicAuthLogoutIframeContainer = ({ isLoading = false, }) => {
|
|
12
|
-
const { logoutIframeRef } = useIframe();
|
|
13
|
-
const isClient = useIsClient();
|
|
14
|
-
const processLogoutIframeUrl = useCallback(() => {
|
|
15
|
-
if (logoutIframeRef && logoutIframeRef.current) {
|
|
16
|
-
const ref = getIframeRef(logoutIframeRef.current);
|
|
17
|
-
if (!ref?.contentWindow) {
|
|
18
|
-
return;
|
|
19
|
-
}
|
|
20
|
-
try {
|
|
21
|
-
const iframeBody = ref.contentWindow.document.body.innerHTML;
|
|
22
|
-
// If we have LOGOUT_SUCCESS_TEXT in the body, we know the logout succeeded on the server,
|
|
23
|
-
// and we should redirect the parent to the post logout success URL indicated in the included link tag.
|
|
24
|
-
if (iframeBody.includes(LOGOUT_SUCCESS_TEXT)) {
|
|
25
|
-
const link = ref.contentWindow.document.querySelector("a[rel='civic-auth-post-logout-redirect-url']");
|
|
26
|
-
if (link) {
|
|
27
|
-
const redirectUrl = link.getAttribute("href");
|
|
28
|
-
if (redirectUrl && redirectUrl !== "#") {
|
|
29
|
-
window.location.href = redirectUrl;
|
|
30
|
-
return true;
|
|
31
|
-
}
|
|
32
|
-
}
|
|
33
|
-
}
|
|
34
|
-
}
|
|
35
|
-
catch {
|
|
36
|
-
// ignore errors while waiting for redirect
|
|
37
|
-
}
|
|
38
|
-
}
|
|
39
|
-
return false; // Haven't processed the URL yet
|
|
40
|
-
}, [logoutIframeRef]);
|
|
41
|
-
// don't render the in server-mode as the appearance changes after load
|
|
42
|
-
return !isClient ? null : (_jsxs(IframeChrome, { isFrameLoaded: true, children: [isLoading ? (_jsx("div", { id: "civic-auth-loading-icon-wrapper", style: {
|
|
43
|
-
position: "absolute",
|
|
44
|
-
inset: 0,
|
|
45
|
-
display: "flex",
|
|
46
|
-
alignItems: "center",
|
|
47
|
-
justifyContent: "center",
|
|
48
|
-
}, children: _jsx(LoadingIcon, {}) })) : null, _jsx(CivicAuthIframe, { ref: logoutIframeRef, id: "civic-auth-logout-iframe", onLoad: processLogoutIframeUrl })] }));
|
|
49
|
-
};
|
|
50
|
-
export { CivicAuthLogoutIframeContainer };
|
|
51
|
-
//# sourceMappingURL=CivicAuthLogoutIframeContainer.js.map
|