@civic/auth 0.1.4-beta.7 → 0.1.5-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 +4 -0
- package/README.md +11 -8
- package/dist/cjs/constants.d.ts +1 -2
- package/dist/cjs/constants.d.ts.map +1 -1
- package/dist/cjs/constants.js +1 -3
- package/dist/cjs/constants.js.map +1 -1
- package/dist/cjs/lib/oauth.d.ts.map +1 -1
- package/dist/cjs/lib/oauth.js +1 -0
- package/dist/cjs/lib/oauth.js.map +1 -1
- package/dist/cjs/nextjs/config.d.ts +3 -0
- package/dist/cjs/nextjs/config.d.ts.map +1 -1
- package/dist/cjs/nextjs/config.js +4 -0
- package/dist/cjs/nextjs/config.js.map +1 -1
- package/dist/cjs/nextjs/hooks/useUserCookie.d.ts.map +1 -1
- package/dist/cjs/nextjs/hooks/useUserCookie.js +2 -0
- package/dist/cjs/nextjs/hooks/useUserCookie.js.map +1 -1
- package/dist/cjs/nextjs/providers/NextAuthProvider.d.ts +2 -2
- package/dist/cjs/nextjs/providers/NextAuthProvider.d.ts.map +1 -1
- package/dist/cjs/nextjs/providers/NextAuthProvider.js +26 -26
- package/dist/cjs/nextjs/providers/NextAuthProvider.js.map +1 -1
- package/dist/cjs/nextjs/routeHandler.d.ts +2 -1
- package/dist/cjs/nextjs/routeHandler.d.ts.map +1 -1
- package/dist/cjs/nextjs/routeHandler.js +122 -38
- package/dist/cjs/nextjs/routeHandler.js.map +1 -1
- package/dist/cjs/reactjs/components/UserButton.d.ts +1 -3
- package/dist/cjs/reactjs/components/UserButton.d.ts.map +1 -1
- package/dist/cjs/reactjs/components/UserButton.js +3 -3
- package/dist/cjs/reactjs/components/UserButton.js.map +1 -1
- package/dist/cjs/reactjs/hooks/useClientTokenExchangeSession.d.ts +3 -0
- package/dist/cjs/reactjs/hooks/useClientTokenExchangeSession.d.ts.map +1 -0
- package/dist/cjs/reactjs/hooks/useClientTokenExchangeSession.js +16 -0
- package/dist/cjs/reactjs/hooks/useClientTokenExchangeSession.js.map +1 -0
- package/dist/cjs/reactjs/providers/AuthProvider.d.ts +11 -0
- package/dist/cjs/reactjs/providers/AuthProvider.d.ts.map +1 -0
- package/dist/cjs/reactjs/providers/AuthProvider.js +108 -0
- package/dist/cjs/reactjs/providers/AuthProvider.js.map +1 -0
- package/dist/cjs/reactjs/providers/CivicAuthProvider.d.ts +6 -0
- package/dist/cjs/reactjs/providers/CivicAuthProvider.d.ts.map +1 -0
- package/dist/cjs/reactjs/providers/CivicAuthProvider.js +38 -0
- package/dist/cjs/reactjs/providers/CivicAuthProvider.js.map +1 -0
- package/dist/cjs/reactjs/providers/ClientTokenExchangeSessionProvider.d.ts +17 -0
- package/dist/cjs/reactjs/providers/ClientTokenExchangeSessionProvider.d.ts.map +1 -0
- package/dist/cjs/reactjs/providers/ClientTokenExchangeSessionProvider.js +185 -0
- package/dist/cjs/reactjs/providers/ClientTokenExchangeSessionProvider.js.map +1 -0
- package/dist/cjs/reactjs/providers/index.d.ts +2 -2
- package/dist/cjs/reactjs/providers/index.d.ts.map +1 -1
- package/dist/cjs/reactjs/providers/index.js +2 -2
- package/dist/cjs/reactjs/providers/index.js.map +1 -1
- package/dist/cjs/server/ServerAuthenticationResolver.d.ts +1 -0
- package/dist/cjs/server/ServerAuthenticationResolver.d.ts.map +1 -1
- package/dist/cjs/server/ServerAuthenticationResolver.js +6 -0
- package/dist/cjs/server/ServerAuthenticationResolver.js.map +1 -1
- package/dist/cjs/services/AuthenticationService.d.ts +8 -2
- package/dist/cjs/services/AuthenticationService.d.ts.map +1 -1
- package/dist/cjs/services/AuthenticationService.js +90 -11
- package/dist/cjs/services/AuthenticationService.js.map +1 -1
- package/dist/cjs/services/types.d.ts +2 -1
- package/dist/cjs/services/types.d.ts.map +1 -1
- package/dist/cjs/services/types.js.map +1 -1
- package/dist/cjs/shared/components/CivicAuthIframe.d.ts +1 -0
- package/dist/cjs/shared/components/CivicAuthIframe.d.ts.map +1 -1
- package/dist/cjs/shared/components/CivicAuthIframe.js +2 -3
- package/dist/cjs/shared/components/CivicAuthIframe.js.map +1 -1
- package/dist/cjs/shared/components/CivicAuthIframeContainer.d.ts +4 -0
- package/dist/cjs/shared/components/CivicAuthIframeContainer.d.ts.map +1 -1
- package/dist/cjs/shared/components/CivicAuthIframeContainer.js +7 -6
- package/dist/cjs/shared/components/CivicAuthIframeContainer.js.map +1 -1
- package/dist/cjs/shared/components/CivicAuthLogoutIframeContainer.d.ts +7 -0
- package/dist/cjs/shared/components/CivicAuthLogoutIframeContainer.d.ts.map +1 -0
- package/dist/cjs/shared/components/CivicAuthLogoutIframeContainer.js +28 -0
- package/dist/cjs/shared/components/CivicAuthLogoutIframeContainer.js.map +1 -0
- package/dist/cjs/shared/components/IFrameAndLoading.d.ts +2 -1
- package/dist/cjs/shared/components/IFrameAndLoading.d.ts.map +1 -1
- package/dist/cjs/shared/components/IFrameAndLoading.js +7 -2
- package/dist/cjs/shared/components/IFrameAndLoading.js.map +1 -1
- package/dist/cjs/shared/hooks/index.d.ts +3 -1
- package/dist/cjs/shared/hooks/index.d.ts.map +1 -1
- package/dist/cjs/shared/hooks/index.js +6 -2
- package/dist/cjs/shared/hooks/index.js.map +1 -1
- package/dist/cjs/shared/hooks/useSignIn.d.ts +3 -2
- package/dist/cjs/shared/hooks/useSignIn.d.ts.map +1 -1
- package/dist/cjs/shared/hooks/useSignIn.js +69 -14
- package/dist/cjs/shared/hooks/useSignIn.js.map +1 -1
- package/dist/cjs/shared/hooks/useWindowFocused.d.ts +5 -0
- package/dist/cjs/shared/hooks/useWindowFocused.d.ts.map +1 -0
- package/dist/cjs/shared/hooks/useWindowFocused.js +24 -0
- package/dist/cjs/shared/hooks/useWindowFocused.js.map +1 -0
- package/dist/cjs/shared/index.d.ts +1 -0
- package/dist/cjs/shared/index.d.ts.map +1 -1
- package/dist/cjs/shared/index.js +5 -3
- package/dist/cjs/shared/index.js.map +1 -1
- package/dist/cjs/shared/lib/types.d.ts +1 -0
- package/dist/cjs/shared/lib/types.d.ts.map +1 -1
- package/dist/cjs/shared/lib/types.js.map +1 -1
- package/dist/cjs/shared/lib/util.d.ts +3 -2
- package/dist/cjs/shared/lib/util.d.ts.map +1 -1
- package/dist/cjs/shared/lib/util.js +7 -3
- package/dist/cjs/shared/lib/util.js.map +1 -1
- package/dist/cjs/shared/providers/AuthContext.d.ts +1 -0
- package/dist/cjs/shared/providers/AuthContext.d.ts.map +1 -1
- package/dist/cjs/shared/providers/AuthContext.js.map +1 -1
- package/dist/cjs/shared/providers/AuthProvider.d.ts +15 -4
- package/dist/cjs/shared/providers/AuthProvider.d.ts.map +1 -1
- package/dist/cjs/shared/providers/AuthProvider.js +12 -3
- package/dist/cjs/shared/providers/AuthProvider.js.map +1 -1
- package/dist/cjs/shared/providers/CivicAuthConfigContext.d.ts +3 -1
- package/dist/cjs/shared/providers/CivicAuthConfigContext.d.ts.map +1 -1
- package/dist/cjs/shared/providers/CivicAuthConfigContext.js +10 -1
- package/dist/cjs/shared/providers/CivicAuthConfigContext.js.map +1 -1
- package/dist/cjs/shared/providers/CivicAuthProvider.d.ts +1 -1
- package/dist/cjs/shared/providers/CivicAuthProvider.d.ts.map +1 -1
- package/dist/cjs/shared/providers/CivicAuthProvider.js +2 -2
- package/dist/cjs/shared/providers/CivicAuthProvider.js.map +1 -1
- package/dist/cjs/shared/providers/ClientTokenExchangeSessionProvider.d.ts.map +1 -1
- package/dist/cjs/shared/providers/ClientTokenExchangeSessionProvider.js +10 -25
- package/dist/cjs/shared/providers/ClientTokenExchangeSessionProvider.js.map +1 -1
- package/dist/cjs/shared/providers/IframeProvider.d.ts +3 -0
- package/dist/cjs/shared/providers/IframeProvider.d.ts.map +1 -1
- package/dist/cjs/shared/providers/IframeProvider.js +9 -3
- package/dist/cjs/shared/providers/IframeProvider.js.map +1 -1
- package/dist/cjs/shared/providers/UserProvider.d.ts +2 -1
- package/dist/cjs/shared/providers/UserProvider.d.ts.map +1 -1
- package/dist/cjs/shared/providers/UserProvider.js +2 -1
- package/dist/cjs/shared/providers/UserProvider.js.map +1 -1
- package/dist/cjs/shared/providers/types.d.ts +3 -1
- package/dist/cjs/shared/providers/types.d.ts.map +1 -1
- package/dist/cjs/shared/providers/types.js.map +1 -1
- package/dist/cjs/shared/version.d.ts +1 -1
- package/dist/cjs/shared/version.js +1 -1
- package/dist/cjs/shared/version.js.map +1 -1
- package/dist/cjs/types.d.ts +1 -0
- package/dist/cjs/types.d.ts.map +1 -1
- package/dist/cjs/types.js.map +1 -1
- package/dist/cjs/version.d.ts +2 -0
- package/dist/cjs/version.d.ts.map +1 -0
- package/dist/cjs/version.js +6 -0
- package/dist/cjs/version.js.map +1 -0
- package/dist/esm/constants.d.ts +1 -2
- package/dist/esm/constants.d.ts.map +1 -1
- package/dist/esm/constants.js +1 -2
- package/dist/esm/constants.js.map +1 -1
- package/dist/esm/lib/oauth.d.ts.map +1 -1
- package/dist/esm/lib/oauth.js +1 -0
- package/dist/esm/lib/oauth.js.map +1 -1
- package/dist/esm/nextjs/config.d.ts +3 -0
- package/dist/esm/nextjs/config.d.ts.map +1 -1
- package/dist/esm/nextjs/config.js +4 -0
- package/dist/esm/nextjs/config.js.map +1 -1
- package/dist/esm/nextjs/hooks/useUserCookie.d.ts.map +1 -1
- package/dist/esm/nextjs/hooks/useUserCookie.js +2 -0
- package/dist/esm/nextjs/hooks/useUserCookie.js.map +1 -1
- package/dist/esm/nextjs/providers/NextAuthProvider.d.ts +2 -2
- package/dist/esm/nextjs/providers/NextAuthProvider.d.ts.map +1 -1
- package/dist/esm/nextjs/providers/NextAuthProvider.js +26 -26
- package/dist/esm/nextjs/providers/NextAuthProvider.js.map +1 -1
- package/dist/esm/nextjs/routeHandler.d.ts +2 -1
- package/dist/esm/nextjs/routeHandler.d.ts.map +1 -1
- package/dist/esm/nextjs/routeHandler.js +123 -40
- package/dist/esm/nextjs/routeHandler.js.map +1 -1
- package/dist/esm/reactjs/components/UserButton.d.ts +1 -3
- package/dist/esm/reactjs/components/UserButton.d.ts.map +1 -1
- package/dist/esm/reactjs/components/UserButton.js +3 -3
- package/dist/esm/reactjs/components/UserButton.js.map +1 -1
- package/dist/esm/reactjs/hooks/useClientTokenExchangeSession.d.ts +3 -0
- package/dist/esm/reactjs/hooks/useClientTokenExchangeSession.d.ts.map +1 -0
- package/dist/esm/reactjs/hooks/useClientTokenExchangeSession.js +13 -0
- package/dist/esm/reactjs/hooks/useClientTokenExchangeSession.js.map +1 -0
- package/dist/esm/reactjs/providers/AuthProvider.d.ts +11 -0
- package/dist/esm/reactjs/providers/AuthProvider.d.ts.map +1 -0
- package/dist/esm/reactjs/providers/AuthProvider.js +72 -0
- package/dist/esm/reactjs/providers/AuthProvider.js.map +1 -0
- package/dist/esm/reactjs/providers/CivicAuthProvider.d.ts +6 -0
- package/dist/esm/reactjs/providers/CivicAuthProvider.d.ts.map +1 -0
- package/dist/esm/reactjs/providers/CivicAuthProvider.js +32 -0
- package/dist/esm/reactjs/providers/CivicAuthProvider.js.map +1 -0
- package/dist/esm/reactjs/providers/ClientTokenExchangeSessionProvider.d.ts +17 -0
- package/dist/esm/reactjs/providers/ClientTokenExchangeSessionProvider.d.ts.map +1 -0
- package/dist/esm/reactjs/providers/ClientTokenExchangeSessionProvider.js +148 -0
- package/dist/esm/reactjs/providers/ClientTokenExchangeSessionProvider.js.map +1 -0
- package/dist/esm/reactjs/providers/index.d.ts +2 -2
- package/dist/esm/reactjs/providers/index.d.ts.map +1 -1
- package/dist/esm/reactjs/providers/index.js +2 -2
- package/dist/esm/reactjs/providers/index.js.map +1 -1
- package/dist/esm/server/ServerAuthenticationResolver.d.ts +1 -0
- package/dist/esm/server/ServerAuthenticationResolver.d.ts.map +1 -1
- package/dist/esm/server/ServerAuthenticationResolver.js +6 -0
- package/dist/esm/server/ServerAuthenticationResolver.js.map +1 -1
- package/dist/esm/services/AuthenticationService.d.ts +8 -2
- package/dist/esm/services/AuthenticationService.d.ts.map +1 -1
- package/dist/esm/services/AuthenticationService.js +90 -11
- package/dist/esm/services/AuthenticationService.js.map +1 -1
- package/dist/esm/services/types.d.ts +2 -1
- package/dist/esm/services/types.d.ts.map +1 -1
- package/dist/esm/services/types.js.map +1 -1
- package/dist/esm/shared/components/CivicAuthIframe.d.ts +1 -0
- package/dist/esm/shared/components/CivicAuthIframe.d.ts.map +1 -1
- package/dist/esm/shared/components/CivicAuthIframe.js +2 -3
- package/dist/esm/shared/components/CivicAuthIframe.js.map +1 -1
- package/dist/esm/shared/components/CivicAuthIframeContainer.d.ts +4 -0
- package/dist/esm/shared/components/CivicAuthIframeContainer.d.ts.map +1 -1
- package/dist/esm/shared/components/CivicAuthIframeContainer.js +7 -7
- package/dist/esm/shared/components/CivicAuthIframeContainer.js.map +1 -1
- package/dist/esm/shared/components/CivicAuthLogoutIframeContainer.d.ts +7 -0
- package/dist/esm/shared/components/CivicAuthLogoutIframeContainer.d.ts.map +1 -0
- package/dist/esm/shared/components/CivicAuthLogoutIframeContainer.js +22 -0
- package/dist/esm/shared/components/CivicAuthLogoutIframeContainer.js.map +1 -0
- package/dist/esm/shared/components/IFrameAndLoading.d.ts +2 -1
- package/dist/esm/shared/components/IFrameAndLoading.d.ts.map +1 -1
- package/dist/esm/shared/components/IFrameAndLoading.js +7 -2
- package/dist/esm/shared/components/IFrameAndLoading.js.map +1 -1
- package/dist/esm/shared/hooks/index.d.ts +3 -1
- package/dist/esm/shared/hooks/index.d.ts.map +1 -1
- package/dist/esm/shared/hooks/index.js +3 -1
- package/dist/esm/shared/hooks/index.js.map +1 -1
- package/dist/esm/shared/hooks/useSignIn.d.ts +3 -2
- package/dist/esm/shared/hooks/useSignIn.d.ts.map +1 -1
- package/dist/esm/shared/hooks/useSignIn.js +70 -15
- package/dist/esm/shared/hooks/useSignIn.js.map +1 -1
- package/dist/esm/shared/hooks/useWindowFocused.d.ts +5 -0
- package/dist/esm/shared/hooks/useWindowFocused.d.ts.map +1 -0
- package/dist/esm/shared/hooks/useWindowFocused.js +21 -0
- package/dist/esm/shared/hooks/useWindowFocused.js.map +1 -0
- package/dist/esm/shared/index.d.ts +1 -0
- package/dist/esm/shared/index.d.ts.map +1 -1
- package/dist/esm/shared/index.js +3 -2
- package/dist/esm/shared/index.js.map +1 -1
- package/dist/esm/shared/lib/types.d.ts +1 -0
- package/dist/esm/shared/lib/types.d.ts.map +1 -1
- package/dist/esm/shared/lib/types.js.map +1 -1
- package/dist/esm/shared/lib/util.d.ts +3 -2
- package/dist/esm/shared/lib/util.d.ts.map +1 -1
- package/dist/esm/shared/lib/util.js +7 -3
- package/dist/esm/shared/lib/util.js.map +1 -1
- package/dist/esm/shared/providers/AuthContext.d.ts +1 -0
- package/dist/esm/shared/providers/AuthContext.d.ts.map +1 -1
- package/dist/esm/shared/providers/AuthContext.js.map +1 -1
- package/dist/esm/shared/providers/AuthProvider.d.ts +15 -4
- package/dist/esm/shared/providers/AuthProvider.d.ts.map +1 -1
- package/dist/esm/shared/providers/AuthProvider.js +12 -3
- package/dist/esm/shared/providers/AuthProvider.js.map +1 -1
- package/dist/esm/shared/providers/CivicAuthConfigContext.d.ts +3 -1
- package/dist/esm/shared/providers/CivicAuthConfigContext.d.ts.map +1 -1
- package/dist/esm/shared/providers/CivicAuthConfigContext.js +10 -1
- package/dist/esm/shared/providers/CivicAuthConfigContext.js.map +1 -1
- package/dist/esm/shared/providers/CivicAuthProvider.d.ts +1 -1
- package/dist/esm/shared/providers/CivicAuthProvider.d.ts.map +1 -1
- package/dist/esm/shared/providers/CivicAuthProvider.js +3 -3
- package/dist/esm/shared/providers/CivicAuthProvider.js.map +1 -1
- package/dist/esm/shared/providers/ClientTokenExchangeSessionProvider.d.ts.map +1 -1
- package/dist/esm/shared/providers/ClientTokenExchangeSessionProvider.js +8 -23
- package/dist/esm/shared/providers/ClientTokenExchangeSessionProvider.js.map +1 -1
- package/dist/esm/shared/providers/IframeProvider.d.ts +3 -0
- package/dist/esm/shared/providers/IframeProvider.d.ts.map +1 -1
- package/dist/esm/shared/providers/IframeProvider.js +9 -3
- package/dist/esm/shared/providers/IframeProvider.js.map +1 -1
- package/dist/esm/shared/providers/UserProvider.d.ts +2 -1
- package/dist/esm/shared/providers/UserProvider.d.ts.map +1 -1
- package/dist/esm/shared/providers/UserProvider.js +2 -1
- package/dist/esm/shared/providers/UserProvider.js.map +1 -1
- package/dist/esm/shared/providers/types.d.ts +3 -1
- package/dist/esm/shared/providers/types.d.ts.map +1 -1
- package/dist/esm/shared/providers/types.js.map +1 -1
- package/dist/esm/shared/version.d.ts +1 -1
- package/dist/esm/shared/version.js +1 -1
- package/dist/esm/shared/version.js.map +1 -1
- package/dist/esm/types.d.ts +1 -0
- package/dist/esm/types.d.ts.map +1 -1
- package/dist/esm/types.js.map +1 -1
- package/dist/esm/version.d.ts +2 -0
- package/dist/esm/version.d.ts.map +1 -0
- package/dist/esm/version.js +3 -0
- package/dist/esm/version.js.map +1 -0
- package/dist/tsconfig.cjs.tsbuildinfo +1 -1
- package/dist/tsconfig.esm.tsbuildinfo +1 -1
- package/package.json +6 -6
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.handler = void 0;
|
|
4
4
|
exports.handleLogout = handleLogout;
|
|
5
|
+
exports.handleLogoutCallback = handleLogoutCallback;
|
|
5
6
|
const server_js_1 = require("next/server.js");
|
|
6
7
|
const cache_js_1 = require("next/cache.js");
|
|
7
8
|
const config_js_1 = require("../nextjs/config.js");
|
|
@@ -15,6 +16,8 @@ const UserSession_js_1 = require("../shared/lib/UserSession.js");
|
|
|
15
16
|
const constants_js_1 = require("../constants.js");
|
|
16
17
|
const oauth_js_1 = require("../lib/oauth.js");
|
|
17
18
|
const types_js_1 = require("../shared/lib/types.js");
|
|
19
|
+
const util_js_1 = require("../shared/lib/util.js");
|
|
20
|
+
const navigation_js_1 = require("next/navigation.js");
|
|
18
21
|
const logger = logger_js_1.loggers.nextjs.handlers.auth;
|
|
19
22
|
class AuthError extends Error {
|
|
20
23
|
status;
|
|
@@ -24,6 +27,8 @@ class AuthError extends Error {
|
|
|
24
27
|
this.name = "AuthError";
|
|
25
28
|
}
|
|
26
29
|
}
|
|
30
|
+
const getAppUrl = (request) => request.cookies.get(types_js_1.CodeVerifier.APP_URL)?.value ||
|
|
31
|
+
request.nextUrl.searchParams.get("appUrl");
|
|
27
32
|
/**
|
|
28
33
|
* create a code verifier and challenge for PKCE
|
|
29
34
|
* saving the verifier in a cookie for later use
|
|
@@ -61,18 +66,42 @@ async function performTokenExchangeAndSetCookies(request, config, code, state, a
|
|
|
61
66
|
const userSession = new UserSession_js_1.GenericUserSession(clientStorage);
|
|
62
67
|
userSession.set(user);
|
|
63
68
|
}
|
|
69
|
+
const generateHtmlResponseWithCallback = (request, callbackUrl) => {
|
|
70
|
+
// we need to replace the URL with resolved config in case the server is hosted
|
|
71
|
+
// behind a reverse proxy or load balancer
|
|
72
|
+
const requestUrl = new URL(request.url);
|
|
73
|
+
const fetchUrl = `${callbackUrl}?${requestUrl.searchParams.toString()}&sameDomainServerTokenExchange=true`;
|
|
74
|
+
return new server_js_1.NextResponse(`<html>
|
|
75
|
+
<body>
|
|
76
|
+
<span style="display:none">
|
|
77
|
+
<script>
|
|
78
|
+
window.onload = function () {
|
|
79
|
+
const appUrl = globalThis.window?.location?.origin;
|
|
80
|
+
fetch('${fetchUrl}&appUrl=' + appUrl).then((response) => {
|
|
81
|
+
response.json().then((jsonResponse) => {
|
|
82
|
+
if (jsonResponse.redirectUrl) {
|
|
83
|
+
window.location.href = jsonResponse.redirectUrl;
|
|
84
|
+
}
|
|
85
|
+
});
|
|
86
|
+
});
|
|
87
|
+
};
|
|
88
|
+
</script>
|
|
89
|
+
</span>
|
|
90
|
+
</body>
|
|
91
|
+
</html>
|
|
92
|
+
`);
|
|
93
|
+
};
|
|
64
94
|
async function handleCallback(request, config) {
|
|
65
95
|
const resolvedConfigs = (0, config_js_1.resolveAuthConfig)(config);
|
|
66
96
|
console.log("handleCallback", { request, resolvedConfigs });
|
|
67
97
|
const code = request.nextUrl.searchParams.get("code");
|
|
68
|
-
const state = request.nextUrl.searchParams.get("state")
|
|
98
|
+
const state = request.nextUrl.searchParams.get("state");
|
|
69
99
|
if (!code || !state)
|
|
70
100
|
throw new AuthError("Bad parameters", 400);
|
|
71
101
|
// appUrl is passed from the client to the server in the query string
|
|
72
102
|
// this is necessary because the server does not have access to the client's window.location.origin
|
|
73
103
|
// and can not accurately determine the appUrl (specially if the app is behind a reverse proxy)
|
|
74
|
-
const appUrl = request
|
|
75
|
-
request.nextUrl.searchParams.get("appUrl");
|
|
104
|
+
const appUrl = getAppUrl(request);
|
|
76
105
|
// If we have a code_verifier cookie and the appUrl, we can do a token exchange.
|
|
77
106
|
// Otherwise, just render an empty page.
|
|
78
107
|
// The initial redirect back from the auth server does not send cookies, because the redirect is from a 3rd-party domain.
|
|
@@ -98,29 +127,9 @@ async function handleCallback(request, config) {
|
|
|
98
127
|
requestUrl: request.url,
|
|
99
128
|
configCallbackUrl: resolvedConfigs.callbackUrl,
|
|
100
129
|
});
|
|
101
|
-
//
|
|
102
|
-
//
|
|
103
|
-
|
|
104
|
-
const fetchUrl = `${resolvedConfigs.callbackUrl}?${requestUrl.searchParams.toString()}&sameDomainServerTokenExchange=true`;
|
|
105
|
-
response = new server_js_1.NextResponse(`<html>
|
|
106
|
-
<body>
|
|
107
|
-
<span style="display:none">
|
|
108
|
-
<script>
|
|
109
|
-
window.onload = function () {
|
|
110
|
-
const appUrl = globalThis.window?.location?.origin;
|
|
111
|
-
fetch('${fetchUrl}&appUrl=' + appUrl).then((response) => {
|
|
112
|
-
response.json().then((jsonResponse) => {
|
|
113
|
-
if (jsonResponse.redirectUrl) {
|
|
114
|
-
window.location.href = jsonResponse.redirectUrl;
|
|
115
|
-
}
|
|
116
|
-
});
|
|
117
|
-
});
|
|
118
|
-
};
|
|
119
|
-
</script>
|
|
120
|
-
</span>
|
|
121
|
-
</body>
|
|
122
|
-
</html>
|
|
123
|
-
`);
|
|
130
|
+
// generate a page that will callback to the same domain, allowing access
|
|
131
|
+
// to the code_verifier cookie and passing the appUrl.
|
|
132
|
+
response = generateHtmlResponseWithCallback(request, resolvedConfigs.callbackUrl);
|
|
124
133
|
}
|
|
125
134
|
response.headers.set("Content-Type", "text/html; charset=utf-8");
|
|
126
135
|
console.log(`handleCallback no code_verifier found, returning ${constants_js_1.TOKEN_EXCHANGE_TRIGGER_TEXT}`);
|
|
@@ -156,23 +165,88 @@ async function handleCallback(request, config) {
|
|
|
156
165
|
* @returns
|
|
157
166
|
*/
|
|
158
167
|
const getAbsoluteRedirectPath = (redirectPath, currentBasePath) => new URL(redirectPath, currentBasePath).href;
|
|
159
|
-
|
|
160
|
-
const
|
|
161
|
-
const
|
|
162
|
-
|
|
168
|
+
const getPostLogoutRedirectUrl = (request, config) => {
|
|
169
|
+
const { loginUrl } = (0, config_js_1.resolveAuthConfig)(config);
|
|
170
|
+
const redirectTarget = loginUrl ?? "/";
|
|
171
|
+
// if the optional loginUrl is provided and it is an absolute URL,
|
|
172
|
+
// use it as the redirect target
|
|
163
173
|
const isAbsoluteRedirect = /^(https?:\/\/|www\.).+/i.test(redirectTarget);
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
174
|
+
if (isAbsoluteRedirect) {
|
|
175
|
+
return redirectTarget;
|
|
176
|
+
}
|
|
177
|
+
// if loginUrl is not defined, the appUrl is passed from the client to the server
|
|
178
|
+
// in the query string or cookies. This is necessary because the server does not
|
|
179
|
+
// have access to the client's window.location and can not accurately determine
|
|
180
|
+
// the appUrl (specially if the app is behind a reverse proxy).
|
|
181
|
+
const appUrl = getAppUrl(request);
|
|
182
|
+
if (appUrl)
|
|
183
|
+
return getAbsoluteRedirectPath(redirectTarget, appUrl);
|
|
184
|
+
return null;
|
|
185
|
+
};
|
|
186
|
+
const revalidateUrlPath = async (url) => {
|
|
170
187
|
try {
|
|
171
|
-
|
|
188
|
+
const path = new URL(url).pathname;
|
|
189
|
+
(0, cache_js_1.revalidatePath)(path);
|
|
172
190
|
}
|
|
173
191
|
catch (error) {
|
|
174
192
|
logger.warn("Failed to revalidate path after logout:", error);
|
|
175
193
|
}
|
|
194
|
+
};
|
|
195
|
+
async function handleLogout(request, config) {
|
|
196
|
+
console.log("handleLogout", { params: request.nextUrl.searchParams });
|
|
197
|
+
const resolvedConfigs = (0, config_js_1.resolveAuthConfig)(config);
|
|
198
|
+
// read the id_token from the cookies
|
|
199
|
+
const cookieStorage = new cookies_js_1.NextjsCookieStorage(resolvedConfigs.cookies?.tokens ?? {});
|
|
200
|
+
const idToken = await cookieStorage.get(types_js_1.OAuthTokens.ID_TOKEN);
|
|
201
|
+
// read the state from the query parameters
|
|
202
|
+
const state = request.nextUrl.searchParams.get("state");
|
|
203
|
+
if (!state || !idToken)
|
|
204
|
+
throw new AuthError("Bad parameters", 400);
|
|
205
|
+
const postLogoutUrl = new URL(resolvedConfigs.logoutCallbackUrl, getAppUrl(request) || request.url);
|
|
206
|
+
const logoutUrl = await (0, util_js_1.generateOauthLogoutUrl)({
|
|
207
|
+
clientId: resolvedConfigs.clientId,
|
|
208
|
+
idToken,
|
|
209
|
+
state,
|
|
210
|
+
redirectUrl: postLogoutUrl.href,
|
|
211
|
+
oauthServer: resolvedConfigs.oauthServer,
|
|
212
|
+
});
|
|
213
|
+
console.log("handleLogout: redirecting to ", logoutUrl);
|
|
214
|
+
return logoutUrl.href;
|
|
215
|
+
}
|
|
216
|
+
async function handleLogoutCallback(request, config) {
|
|
217
|
+
const resolvedConfigs = (0, config_js_1.resolveAuthConfig)(config);
|
|
218
|
+
const state = request.nextUrl.searchParams.get("state") || "";
|
|
219
|
+
if (!state)
|
|
220
|
+
throw new AuthError("Bad parameters", 400);
|
|
221
|
+
const displayMode = (0, oauth_js_1.displayModeFromState)(state, "redirect");
|
|
222
|
+
console.log("handleLogout: clear auth cookies", { state, displayMode });
|
|
223
|
+
await (0, cookies_js_1.clearAuthCookies)(resolvedConfigs);
|
|
224
|
+
// handle logout for iframe display mode
|
|
225
|
+
if (displayMode === "iframe") {
|
|
226
|
+
return server_js_1.NextResponse.json({ status: "success" });
|
|
227
|
+
}
|
|
228
|
+
// handle logout for non-iframe display mode
|
|
229
|
+
let response;
|
|
230
|
+
const redirectUrl = getPostLogoutRedirectUrl(request, resolvedConfigs);
|
|
231
|
+
if (redirectUrl) {
|
|
232
|
+
console.log("handleLogout with redirect mode", { state, redirectUrl });
|
|
233
|
+
// this is comming from the fetch from the HTML page returned by this handler
|
|
234
|
+
if (request.url.includes("sameDomainServerTokenExchange=true")) {
|
|
235
|
+
console.log("handleCallback sameDomainServerTokenExchange = true, returnining redirectUrl", redirectUrl);
|
|
236
|
+
return server_js_1.NextResponse.json({
|
|
237
|
+
status: "success",
|
|
238
|
+
redirectUrl: redirectUrl,
|
|
239
|
+
});
|
|
240
|
+
}
|
|
241
|
+
// just redirect to the app url
|
|
242
|
+
response = server_js_1.NextResponse.redirect(`${redirectUrl}`);
|
|
243
|
+
revalidateUrlPath(redirectUrl);
|
|
244
|
+
}
|
|
245
|
+
else {
|
|
246
|
+
console.log("handleLogout no redirectUrl found", { state });
|
|
247
|
+
response = generateHtmlResponseWithCallback(request, resolvedConfigs.logoutCallbackUrl);
|
|
248
|
+
response.headers.set("Content-Type", "text/html; charset=utf-8");
|
|
249
|
+
}
|
|
176
250
|
return response;
|
|
177
251
|
}
|
|
178
252
|
/**
|
|
@@ -189,6 +263,7 @@ async function handleLogout(request, config) {
|
|
|
189
263
|
*/
|
|
190
264
|
const handler = (authConfig = {}) => async (request) => {
|
|
191
265
|
const config = (0, config_js_1.resolveAuthConfig)(authConfig);
|
|
266
|
+
let redirectUrl = null;
|
|
192
267
|
try {
|
|
193
268
|
const pathname = request.nextUrl.pathname;
|
|
194
269
|
const pathSegments = pathname.split("/");
|
|
@@ -199,7 +274,10 @@ const handler = (authConfig = {}) => async (request) => {
|
|
|
199
274
|
case "callback":
|
|
200
275
|
return await handleCallback(request, config);
|
|
201
276
|
case "logout":
|
|
202
|
-
|
|
277
|
+
redirectUrl = await handleLogout(request, config);
|
|
278
|
+
break;
|
|
279
|
+
case "logoutcallback":
|
|
280
|
+
return await handleLogoutCallback(request, config);
|
|
203
281
|
default:
|
|
204
282
|
throw new AuthError(`Invalid auth route: ${pathname}`, 404);
|
|
205
283
|
}
|
|
@@ -212,6 +290,12 @@ const handler = (authConfig = {}) => async (request) => {
|
|
|
212
290
|
(0, cookies_js_1.clearAuthCookies)(config);
|
|
213
291
|
return response;
|
|
214
292
|
}
|
|
293
|
+
// redirect on Nextjs must be called outside a try-catch block
|
|
294
|
+
// see https://nextjs.org/docs/app/api-reference/functions/redirect
|
|
295
|
+
if (redirectUrl)
|
|
296
|
+
(0, navigation_js_1.redirect)(redirectUrl);
|
|
297
|
+
// do nothing if no redirectUrl
|
|
298
|
+
return server_js_1.NextResponse.json({ status: "ok" });
|
|
215
299
|
};
|
|
216
300
|
exports.handler = handler;
|
|
217
301
|
//# sourceMappingURL=routeHandler.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"routeHandler.js","sourceRoot":"","sources":["../../../src/nextjs/routeHandler.ts"],"names":[],"mappings":"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","sourcesContent":["import type { NextRequest } from \"next/server.js\";\nimport { NextResponse } from \"next/server.js\";\nimport { revalidatePath } from \"next/cache.js\";\nimport type { AuthConfig } from \"@/nextjs/config.js\";\nimport { resolveAuthConfig } from \"@/nextjs/config.js\";\nimport { loggers } from \"@/lib/logger.js\";\nimport {\n clearAuthCookies,\n NextjsClientStorage,\n NextjsCookieStorage,\n} from \"@/nextjs/cookies.js\";\nimport { GenericPublicClientPKCEProducer } from \"@/services/PKCE.js\";\nimport { resolveOAuthAccessCode } from \"@/server/login.js\";\nimport { getUser } from \"@/nextjs/GetUser.js\";\nimport { resolveCallbackUrl } from \"@/nextjs/utils.js\";\nimport { GenericUserSession } from \"@/shared/lib/UserSession.js\";\nimport {\n TOKEN_EXCHANGE_SUCCESS_TEXT,\n TOKEN_EXCHANGE_TRIGGER_TEXT,\n} from \"@/constants.js\";\nimport { serverTokenExchangeFromState } from \"@/lib/oauth.js\";\nimport { CodeVerifier } from \"@/shared/lib/types.js\";\n\nconst logger = loggers.nextjs.handlers.auth;\n\nclass AuthError extends Error {\n constructor(\n message: string,\n public readonly status: number = 401,\n ) {\n super(message);\n this.name = \"AuthError\";\n }\n}\n\n/**\n * create a code verifier and challenge for PKCE\n * saving the verifier in a cookie for later use\n * @returns {Promise<NextResponse>}\n */\nasync function handleChallenge(\n request: NextRequest,\n config: AuthConfig,\n): Promise<NextResponse> {\n const cookieStorage = new NextjsCookieStorage(config.cookies?.tokens ?? {});\n const pkceProducer = new GenericPublicClientPKCEProducer(cookieStorage);\n\n const challenge = await pkceProducer.getCodeChallenge();\n const appUrl = request.nextUrl.searchParams.get(\"appUrl\");\n if (appUrl) {\n cookieStorage.set(CodeVerifier.APP_URL, appUrl);\n }\n return NextResponse.json({ status: \"success\", challenge });\n}\n\nasync function performTokenExchangeAndSetCookies(\n request: NextRequest,\n config: AuthConfig,\n code: string,\n state: string,\n appUrl: string,\n) {\n const resolvedConfigs = resolveAuthConfig(config);\n const cookieStorage = new NextjsCookieStorage(resolvedConfigs.cookies.tokens);\n\n const callbackUrl = resolveCallbackUrl(resolvedConfigs, appUrl);\n try {\n await resolveOAuthAccessCode(code, state, cookieStorage, {\n ...resolvedConfigs,\n redirectUrl: callbackUrl,\n });\n } catch (error) {\n logger.error(\"Token exchange failed:\", error);\n throw new AuthError(\"Failed to authenticate user\", 401);\n }\n\n const user = await getUser();\n if (!user) {\n throw new AuthError(\"Failed to get user info\", 401);\n }\n\n const clientStorage = new NextjsClientStorage();\n const userSession = new GenericUserSession(clientStorage);\n userSession.set(user);\n}\nasync function handleCallback(\n request: NextRequest,\n config: AuthConfig,\n): Promise<NextResponse> {\n const resolvedConfigs = resolveAuthConfig(config);\n console.log(\"handleCallback\", { request, resolvedConfigs });\n const code = request.nextUrl.searchParams.get(\"code\");\n const state = request.nextUrl.searchParams.get(\"state\") || \"\";\n if (!code || !state) throw new AuthError(\"Bad parameters\", 400);\n\n // appUrl is passed from the client to the server in the query string\n // this is necessary because the server does not have access to the client's window.location.origin\n // and can not accurately determine the appUrl (specially if the app is behind a reverse proxy)\n const appUrl =\n request.cookies.get(CodeVerifier.APP_URL)?.value ||\n request.nextUrl.searchParams.get(\"appUrl\");\n\n // If we have a code_verifier cookie and the appUrl, we can do a token exchange.\n // Otherwise, just render an empty page.\n // The initial redirect back from the auth server does not send cookies, because the redirect is from a 3rd-party domain.\n // The client will make an additional call to this route with cookies included, at which point we do the token exchange.\n console.log(\"handleCallback\", {\n code,\n state,\n appUrl,\n });\n\n const codeVerifier = request.cookies.get(CodeVerifier.COOKIE_NAME);\n\n if (!codeVerifier || !appUrl) {\n console.log(\"handleCallback no code_verifier found\", {\n state,\n serverTokenExchange: serverTokenExchangeFromState(`${state}`),\n });\n let response = new NextResponse(\n `<html><body><span style=\"display:none\">${TOKEN_EXCHANGE_TRIGGER_TEXT}</span></body></html>`,\n );\n\n // in server-side token exchange mode we need to launch a page that will trigger the token exchange\n // from the same domain, allowing it access to the code_verifier cookie\n // we only need to do this in redirect mode, as the iframe already triggers a client-side token exchange\n // if no code-verifier cookie is found\n if (state && serverTokenExchangeFromState(state)) {\n console.log(\n \"handleCallback serverTokenExchangeFromState, launching redirect page...\",\n {\n requestUrl: request.url,\n configCallbackUrl: resolvedConfigs.callbackUrl,\n },\n );\n // we need to replace the URL with resolved config in case the server is hosted\n // behind a reverse proxy or load balancer\n const requestUrl = new URL(request.url);\n const fetchUrl = `${resolvedConfigs.callbackUrl}?${requestUrl.searchParams.toString()}&sameDomainServerTokenExchange=true`;\n response = new NextResponse(\n `<html>\n <body>\n <span style=\"display:none\">\n <script>\n window.onload = function () {\n const appUrl = globalThis.window?.location?.origin;\n fetch('${fetchUrl}&appUrl=' + appUrl).then((response) => {\n response.json().then((jsonResponse) => {\n if (jsonResponse.redirectUrl) {\n window.location.href = jsonResponse.redirectUrl;\n }\n });\n });\n };\n </script>\n </span>\n </body>\n </html>\n `,\n );\n }\n response.headers.set(\"Content-Type\", \"text/html; charset=utf-8\");\n console.log(\n `handleCallback no code_verifier found, returning ${TOKEN_EXCHANGE_TRIGGER_TEXT}`,\n );\n return response;\n }\n\n await performTokenExchangeAndSetCookies(\n request,\n resolvedConfigs,\n code,\n state,\n appUrl,\n );\n\n if (request.url.includes(\"sameDomainServerTokenExchange=true\")) {\n console.log(\n \"handleCallback sameDomainServerTokenExchange = true, returnining redirectUrl\",\n appUrl,\n );\n return NextResponse.json({\n status: \"success\",\n redirectUrl: appUrl,\n });\n }\n\n // this is the case where a 'normal' redirect is happening\n if (serverTokenExchangeFromState(state)) {\n console.log(\n \"handleCallback serverTokenExchangeFromState, redirect to appUrl\",\n appUrl,\n );\n if (!appUrl) {\n throw new Error(\"appUrl undefined. Cannot redirect.\");\n }\n return NextResponse.redirect(`${appUrl}`);\n }\n // return an empty HTML response so the iframe doesn't show any response\n // in the short moment between the redirect and the parent window\n // acknowledging the redirect and closing the iframe\n const response = new NextResponse(\n `<html><span style=\"display:none\">${TOKEN_EXCHANGE_SUCCESS_TEXT}</span></html>`,\n );\n response.headers.set(\"Content-Type\", \"text/html; charset=utf-8\");\n return response;\n}\n\n/**\n * If redirectPath is an absolute path, return it as-is.\n * Otherwise for relative paths, append it to the current domain.\n * @param redirectPath\n * @returns\n */\nconst getAbsoluteRedirectPath = (\n redirectPath: string,\n currentBasePath: string,\n) => new URL(redirectPath, currentBasePath).href;\n\nexport async function handleLogout(\n request: NextRequest,\n config: AuthConfig,\n): Promise<NextResponse> {\n const resolvedConfigs = resolveAuthConfig(config);\n const defaultRedirectPath = resolvedConfigs.loginUrl ?? \"/\";\n const redirectTarget =\n new URL(request.url).searchParams.get(\"redirect\") || defaultRedirectPath;\n\n const isAbsoluteRedirect = /^(https?:\\/\\/|www\\.).+/i.test(redirectTarget);\n\n const appUrl = request.nextUrl.searchParams.get(\"appUrl\");\n\n const finalRedirectUrl = isAbsoluteRedirect\n ? redirectTarget\n : getAbsoluteRedirectPath(\n redirectTarget,\n new URL(appUrl ?? request.url).origin,\n );\n\n const response = NextResponse.redirect(finalRedirectUrl);\n\n await clearAuthCookies(config);\n\n try {\n revalidatePath(isAbsoluteRedirect ? finalRedirectUrl : redirectTarget);\n } catch (error) {\n logger.warn(\"Failed to revalidate path after logout:\", error);\n }\n\n return response;\n}\n\n/**\n * Creates an authentication handler for Next.js API routes\n *\n * Usage:\n * ```ts\n * // app/api/auth/[...civicauth]/route.ts\n * import { handler } from '@civic/auth/nextjs'\n * export const GET = handler({\n * // optional config overrides\n * })\n * ```\n */\nexport const handler =\n (authConfig = {}) =>\n async (request: NextRequest): Promise<NextResponse> => {\n const config = resolveAuthConfig(authConfig);\n\n try {\n const pathname = request.nextUrl.pathname;\n const pathSegments = pathname.split(\"/\");\n const lastSegment = pathSegments[pathSegments.length - 1];\n\n switch (lastSegment) {\n case \"challenge\":\n return await handleChallenge(request, config);\n case \"callback\":\n return await handleCallback(request, config);\n case \"logout\":\n return await handleLogout(request, config);\n default:\n throw new AuthError(`Invalid auth route: ${pathname}`, 404);\n }\n } catch (error) {\n logger.error(\"Auth handler error:\", error);\n\n const status = error instanceof AuthError ? error.status : 500;\n const message =\n error instanceof Error ? error.message : \"Authentication failed\";\n\n const response = NextResponse.json({ error: message }, { status });\n\n clearAuthCookies(config);\n return response;\n }\n };\n"]}
|
|
1
|
+
{"version":3,"file":"routeHandler.js","sourceRoot":"","sources":["../../../src/nextjs/routeHandler.ts"],"names":[],"mappings":"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","sourcesContent":["import type { NextRequest } from \"next/server.js\";\nimport { NextResponse } from \"next/server.js\";\nimport { revalidatePath } from \"next/cache.js\";\nimport type { AuthConfig } from \"@/nextjs/config.js\";\nimport { resolveAuthConfig } from \"@/nextjs/config.js\";\nimport { loggers } from \"@/lib/logger.js\";\nimport {\n clearAuthCookies,\n NextjsClientStorage,\n NextjsCookieStorage,\n} from \"@/nextjs/cookies.js\";\nimport { GenericPublicClientPKCEProducer } from \"@/services/PKCE.js\";\nimport { resolveOAuthAccessCode } from \"@/server/login.js\";\nimport { getUser } from \"@/nextjs/GetUser.js\";\nimport { resolveCallbackUrl } from \"@/nextjs/utils.js\";\nimport { GenericUserSession } from \"@/shared/lib/UserSession.js\";\nimport {\n TOKEN_EXCHANGE_SUCCESS_TEXT,\n TOKEN_EXCHANGE_TRIGGER_TEXT,\n} from \"@/constants.js\";\nimport {\n displayModeFromState,\n serverTokenExchangeFromState,\n} from \"@/lib/oauth.js\";\nimport { CodeVerifier, OAuthTokens } from \"@/shared/lib/types.js\";\nimport { generateOauthLogoutUrl } from \"@/shared/lib/util.js\";\nimport { redirect } from \"next/navigation.js\";\n\nconst logger = loggers.nextjs.handlers.auth;\n\nclass AuthError extends Error {\n constructor(\n message: string,\n public readonly status: number = 401,\n ) {\n super(message);\n this.name = \"AuthError\";\n }\n}\n\nconst getAppUrl = (request: NextRequest): string | null =>\n request.cookies.get(CodeVerifier.APP_URL)?.value ||\n request.nextUrl.searchParams.get(\"appUrl\");\n\n/**\n * create a code verifier and challenge for PKCE\n * saving the verifier in a cookie for later use\n * @returns {Promise<NextResponse>}\n */\nasync function handleChallenge(\n request: NextRequest,\n config: AuthConfig,\n): Promise<NextResponse> {\n const cookieStorage = new NextjsCookieStorage(config.cookies?.tokens ?? {});\n const pkceProducer = new GenericPublicClientPKCEProducer(cookieStorage);\n\n const challenge = await pkceProducer.getCodeChallenge();\n const appUrl = request.nextUrl.searchParams.get(\"appUrl\");\n if (appUrl) {\n cookieStorage.set(CodeVerifier.APP_URL, appUrl);\n }\n return NextResponse.json({ status: \"success\", challenge });\n}\n\nasync function performTokenExchangeAndSetCookies(\n request: NextRequest,\n config: AuthConfig,\n code: string,\n state: string,\n appUrl: string,\n) {\n const resolvedConfigs = resolveAuthConfig(config);\n const cookieStorage = new NextjsCookieStorage(resolvedConfigs.cookies.tokens);\n\n const callbackUrl = resolveCallbackUrl(resolvedConfigs, appUrl);\n try {\n await resolveOAuthAccessCode(code, state, cookieStorage, {\n ...resolvedConfigs,\n redirectUrl: callbackUrl,\n });\n } catch (error) {\n logger.error(\"Token exchange failed:\", error);\n throw new AuthError(\"Failed to authenticate user\", 401);\n }\n\n const user = await getUser();\n if (!user) {\n throw new AuthError(\"Failed to get user info\", 401);\n }\n\n const clientStorage = new NextjsClientStorage();\n const userSession = new GenericUserSession(clientStorage);\n userSession.set(user);\n}\n\nconst generateHtmlResponseWithCallback = (\n request: NextRequest,\n callbackUrl: string,\n) => {\n // we need to replace the URL with resolved config in case the server is hosted\n // behind a reverse proxy or load balancer\n const requestUrl = new URL(request.url);\n const fetchUrl = `${callbackUrl}?${requestUrl.searchParams.toString()}&sameDomainServerTokenExchange=true`;\n return new NextResponse(\n `<html>\n <body>\n <span style=\"display:none\">\n <script>\n window.onload = function () {\n const appUrl = globalThis.window?.location?.origin;\n fetch('${fetchUrl}&appUrl=' + appUrl).then((response) => {\n response.json().then((jsonResponse) => {\n if (jsonResponse.redirectUrl) {\n window.location.href = jsonResponse.redirectUrl;\n }\n });\n });\n };\n </script>\n </span>\n </body>\n </html>\n `,\n );\n};\n\nasync function handleCallback(\n request: NextRequest,\n config: AuthConfig,\n): Promise<NextResponse> {\n const resolvedConfigs = resolveAuthConfig(config);\n console.log(\"handleCallback\", { request, resolvedConfigs });\n const code = request.nextUrl.searchParams.get(\"code\");\n const state = request.nextUrl.searchParams.get(\"state\");\n if (!code || !state) throw new AuthError(\"Bad parameters\", 400);\n\n // appUrl is passed from the client to the server in the query string\n // this is necessary because the server does not have access to the client's window.location.origin\n // and can not accurately determine the appUrl (specially if the app is behind a reverse proxy)\n const appUrl = getAppUrl(request);\n\n // If we have a code_verifier cookie and the appUrl, we can do a token exchange.\n // Otherwise, just render an empty page.\n // The initial redirect back from the auth server does not send cookies, because the redirect is from a 3rd-party domain.\n // The client will make an additional call to this route with cookies included, at which point we do the token exchange.\n console.log(\"handleCallback\", {\n code,\n state,\n appUrl,\n });\n\n const codeVerifier = request.cookies.get(CodeVerifier.COOKIE_NAME);\n\n if (!codeVerifier || !appUrl) {\n console.log(\"handleCallback no code_verifier found\", {\n state,\n serverTokenExchange: serverTokenExchangeFromState(`${state}`),\n });\n let response = new NextResponse(\n `<html><body><span style=\"display:none\">${TOKEN_EXCHANGE_TRIGGER_TEXT}</span></body></html>`,\n );\n\n // in server-side token exchange mode we need to launch a page that will trigger the token exchange\n // from the same domain, allowing it access to the code_verifier cookie\n // we only need to do this in redirect mode, as the iframe already triggers a client-side token exchange\n // if no code-verifier cookie is found\n if (state && serverTokenExchangeFromState(state)) {\n console.log(\n \"handleCallback serverTokenExchangeFromState, launching redirect page...\",\n {\n requestUrl: request.url,\n configCallbackUrl: resolvedConfigs.callbackUrl,\n },\n );\n // generate a page that will callback to the same domain, allowing access\n // to the code_verifier cookie and passing the appUrl.\n response = generateHtmlResponseWithCallback(\n request,\n resolvedConfigs.callbackUrl,\n );\n }\n\n response.headers.set(\"Content-Type\", \"text/html; charset=utf-8\");\n console.log(\n `handleCallback no code_verifier found, returning ${TOKEN_EXCHANGE_TRIGGER_TEXT}`,\n );\n return response;\n }\n\n await performTokenExchangeAndSetCookies(\n request,\n resolvedConfigs,\n code,\n state,\n appUrl,\n );\n\n if (request.url.includes(\"sameDomainServerTokenExchange=true\")) {\n console.log(\n \"handleCallback sameDomainServerTokenExchange = true, returnining redirectUrl\",\n appUrl,\n );\n return NextResponse.json({\n status: \"success\",\n redirectUrl: appUrl,\n });\n }\n\n // this is the case where a 'normal' redirect is happening\n if (serverTokenExchangeFromState(state)) {\n console.log(\n \"handleCallback serverTokenExchangeFromState, redirect to appUrl\",\n appUrl,\n );\n if (!appUrl) {\n throw new Error(\"appUrl undefined. Cannot redirect.\");\n }\n return NextResponse.redirect(`${appUrl}`);\n }\n // return an empty HTML response so the iframe doesn't show any response\n // in the short moment between the redirect and the parent window\n // acknowledging the redirect and closing the iframe\n const response = new NextResponse(\n `<html><span style=\"display:none\">${TOKEN_EXCHANGE_SUCCESS_TEXT}</span></html>`,\n );\n response.headers.set(\"Content-Type\", \"text/html; charset=utf-8\");\n return response;\n}\n\n/**\n * If redirectPath is an absolute path, return it as-is.\n * Otherwise for relative paths, append it to the current domain.\n * @param redirectPath\n * @returns\n */\nconst getAbsoluteRedirectPath = (\n redirectPath: string,\n currentBasePath: string,\n) => new URL(redirectPath, currentBasePath).href;\n\nconst getPostLogoutRedirectUrl = (\n request: NextRequest,\n config: AuthConfig,\n): string | null => {\n const { loginUrl } = resolveAuthConfig(config);\n const redirectTarget = loginUrl ?? \"/\";\n\n // if the optional loginUrl is provided and it is an absolute URL,\n // use it as the redirect target\n const isAbsoluteRedirect = /^(https?:\\/\\/|www\\.).+/i.test(redirectTarget);\n if (isAbsoluteRedirect) {\n return redirectTarget;\n }\n\n // if loginUrl is not defined, the appUrl is passed from the client to the server\n // in the query string or cookies. This is necessary because the server does not\n // have access to the client's window.location and can not accurately determine\n // the appUrl (specially if the app is behind a reverse proxy).\n const appUrl = getAppUrl(request);\n if (appUrl) return getAbsoluteRedirectPath(redirectTarget, appUrl);\n\n return null;\n};\n\nconst revalidateUrlPath = async (url: string) => {\n try {\n const path = new URL(url).pathname;\n revalidatePath(path);\n } catch (error) {\n logger.warn(\"Failed to revalidate path after logout:\", error);\n }\n};\n\nexport async function handleLogout(\n request: NextRequest,\n config: AuthConfig,\n): Promise<string> {\n console.log(\"handleLogout\", { params: request.nextUrl.searchParams });\n const resolvedConfigs = resolveAuthConfig(config);\n\n // read the id_token from the cookies\n const cookieStorage = new NextjsCookieStorage(\n resolvedConfigs.cookies?.tokens ?? {},\n );\n const idToken = await cookieStorage.get(OAuthTokens.ID_TOKEN);\n\n // read the state from the query parameters\n const state = request.nextUrl.searchParams.get(\"state\");\n\n if (!state || !idToken) throw new AuthError(\"Bad parameters\", 400);\n\n const postLogoutUrl = new URL(\n resolvedConfigs.logoutCallbackUrl,\n getAppUrl(request) || request.url,\n );\n const logoutUrl = await generateOauthLogoutUrl({\n clientId: resolvedConfigs.clientId,\n idToken,\n state,\n redirectUrl: postLogoutUrl.href,\n oauthServer: resolvedConfigs.oauthServer,\n });\n console.log(\"handleLogout: redirecting to \", logoutUrl);\n\n return logoutUrl.href;\n}\n\nexport async function handleLogoutCallback(\n request: NextRequest,\n config: AuthConfig,\n): Promise<NextResponse> {\n const resolvedConfigs = resolveAuthConfig(config);\n const state = request.nextUrl.searchParams.get(\"state\") || \"\";\n if (!state) throw new AuthError(\"Bad parameters\", 400);\n\n const displayMode = displayModeFromState(state, \"redirect\");\n\n console.log(\"handleLogout: clear auth cookies\", { state, displayMode });\n await clearAuthCookies(resolvedConfigs);\n\n // handle logout for iframe display mode\n if (displayMode === \"iframe\") {\n return NextResponse.json({ status: \"success\" });\n }\n\n // handle logout for non-iframe display mode\n let response;\n const redirectUrl = getPostLogoutRedirectUrl(request, resolvedConfigs);\n\n if (redirectUrl) {\n console.log(\"handleLogout with redirect mode\", { state, redirectUrl });\n\n // this is comming from the fetch from the HTML page returned by this handler\n if (request.url.includes(\"sameDomainServerTokenExchange=true\")) {\n console.log(\n \"handleCallback sameDomainServerTokenExchange = true, returnining redirectUrl\",\n redirectUrl,\n );\n return NextResponse.json({\n status: \"success\",\n redirectUrl: redirectUrl,\n });\n }\n\n // just redirect to the app url\n response = NextResponse.redirect(`${redirectUrl}`);\n revalidateUrlPath(redirectUrl);\n } else {\n console.log(\"handleLogout no redirectUrl found\", { state });\n response = generateHtmlResponseWithCallback(\n request,\n resolvedConfigs.logoutCallbackUrl,\n );\n response.headers.set(\"Content-Type\", \"text/html; charset=utf-8\");\n }\n\n return response;\n}\n\n/**\n * Creates an authentication handler for Next.js API routes\n *\n * Usage:\n * ```ts\n * // app/api/auth/[...civicauth]/route.ts\n * import { handler } from '@civic/auth/nextjs'\n * export const GET = handler({\n * // optional config overrides\n * })\n * ```\n */\nexport const handler =\n (authConfig = {}) =>\n async (request: NextRequest): Promise<NextResponse> => {\n const config = resolveAuthConfig(authConfig);\n\n let redirectUrl: string | null = null;\n\n try {\n const pathname = request.nextUrl.pathname;\n const pathSegments = pathname.split(\"/\");\n const lastSegment = pathSegments[pathSegments.length - 1];\n\n switch (lastSegment) {\n case \"challenge\":\n return await handleChallenge(request, config);\n case \"callback\":\n return await handleCallback(request, config);\n case \"logout\":\n redirectUrl = await handleLogout(request, config);\n break;\n case \"logoutcallback\":\n return await handleLogoutCallback(request, config);\n default:\n throw new AuthError(`Invalid auth route: ${pathname}`, 404);\n }\n } catch (error) {\n logger.error(\"Auth handler error:\", error);\n\n const status = error instanceof AuthError ? error.status : 500;\n const message =\n error instanceof Error ? error.message : \"Authentication failed\";\n\n const response = NextResponse.json({ error: message }, { status });\n\n clearAuthCookies(config);\n return response;\n }\n\n // redirect on Nextjs must be called outside a try-catch block\n // see https://nextjs.org/docs/app/api-reference/functions/redirect\n if (redirectUrl) redirect(redirectUrl);\n\n // do nothing if no redirectUrl\n return NextResponse.json({ status: \"ok\" });\n };\n"]}
|
|
@@ -1,7 +1,5 @@
|
|
|
1
|
-
import type { DisplayMode } from "../../types.js";
|
|
2
1
|
import React from "react";
|
|
3
|
-
declare const UserButton: ({
|
|
4
|
-
displayMode?: DisplayMode;
|
|
2
|
+
declare const UserButton: ({ className }: {
|
|
5
3
|
className?: string;
|
|
6
4
|
}) => React.JSX.Element;
|
|
7
5
|
export { UserButton };
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"UserButton.d.ts","sourceRoot":"","sources":["../../../../src/reactjs/components/UserButton.tsx"],"names":[],"mappings":"AAEA,OAAO,
|
|
1
|
+
{"version":3,"file":"UserButton.d.ts","sourceRoot":"","sources":["../../../../src/reactjs/components/UserButton.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAmD,MAAM,OAAO,CAAC;AAoCxE,QAAA,MAAM,UAAU,kBAAmB;IAAE,SAAS,CAAC,EAAE,MAAM,CAAA;CAAE,sBA+LxD,CAAC;AAEF,OAAO,EAAE,UAAU,EAAE,CAAC"}
|
|
@@ -41,7 +41,7 @@ const ChevronDown = () => (react_1.default.createElement("svg", { xmlns: "http:/
|
|
|
41
41
|
react_1.default.createElement("path", { d: "m6 9 6 6 6-6" })));
|
|
42
42
|
const ChevronUp = () => (react_1.default.createElement("svg", { xmlns: "http://www.w3.org/2000/svg", width: "24", height: "24", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", className: "lucide lucide-chevron-up" },
|
|
43
43
|
react_1.default.createElement("path", { d: "m18 15-6-6-6 6" })));
|
|
44
|
-
const UserButton = ({
|
|
44
|
+
const UserButton = ({ className }) => {
|
|
45
45
|
const [isOpen, setIsOpen] = (0, react_1.useState)(false);
|
|
46
46
|
const [buttonWidth, setButtonWidth] = (0, react_1.useState)(null);
|
|
47
47
|
const { user, signIn, signOut } = (0, index_js_1.useUser)();
|
|
@@ -66,9 +66,9 @@ const UserButton = ({ displayMode, className, }) => {
|
|
|
66
66
|
setIsOpen(false);
|
|
67
67
|
}, [signOut]);
|
|
68
68
|
const handleSignIn = (0, react_1.useCallback)(async () => {
|
|
69
|
-
await signIn(
|
|
69
|
+
await signIn();
|
|
70
70
|
setIsOpen(false);
|
|
71
|
-
}, [signIn
|
|
71
|
+
}, [signIn]);
|
|
72
72
|
const handleEscape = (0, react_1.useCallback)((event) => {
|
|
73
73
|
if (event.key === "Escape") {
|
|
74
74
|
setIsOpen(false);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"UserButton.js","sourceRoot":"","sources":["../../../../src/reactjs/components/UserButton.tsx"],"names":[],"mappings":";AAAA,YAAY,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AACb,uDAAmD;AAEnD,+CAAwE;AAExE,MAAM,WAAW,GAAG,GAAG,EAAE,CAAC,CACxB,uCACE,KAAK,EAAC,4BAA4B,EAClC,KAAK,EAAC,IAAI,EACV,MAAM,EAAC,IAAI,EACX,OAAO,EAAC,WAAW,EACnB,IAAI,EAAC,MAAM,EACX,MAAM,EAAC,cAAc,EACrB,WAAW,EAAC,GAAG,EACf,aAAa,EAAC,OAAO,EACrB,cAAc,EAAC,OAAO,EACtB,SAAS,EAAC,4BAA4B;IAEtC,wCAAM,CAAC,EAAC,cAAc,GAAG,CACrB,CACP,CAAC;AAEF,MAAM,SAAS,GAAG,GAAG,EAAE,CAAC,CACtB,uCACE,KAAK,EAAC,4BAA4B,EAClC,KAAK,EAAC,IAAI,EACV,MAAM,EAAC,IAAI,EACX,OAAO,EAAC,WAAW,EACnB,IAAI,EAAC,MAAM,EACX,MAAM,EAAC,cAAc,EACrB,WAAW,EAAC,GAAG,EACf,aAAa,EAAC,OAAO,EACrB,cAAc,EAAC,OAAO,EACtB,SAAS,EAAC,0BAA0B;IAEpC,wCAAM,CAAC,EAAC,gBAAgB,GAAG,CACvB,CACP,CAAC;AAEF,MAAM,UAAU,GAAG,CAAC,EAClB,WAAW,EACX,SAAS,GAIV,EAAE,EAAE;IACH,MAAM,CAAC,MAAM,EAAE,SAAS,CAAC,GAAG,IAAA,gBAAQ,EAAC,KAAK,CAAC,CAAC;IAC5C,MAAM,CAAC,WAAW,EAAE,cAAc,CAAC,GAAG,IAAA,gBAAQ,EAAgB,IAAI,CAAC,CAAC;IACpE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,GAAG,IAAA,kBAAO,GAAE,CAAC;IAC5C,MAAM,SAAS,GAAG,IAAA,cAAM,EAAoB,IAAI,CAAC,CAAC;IAClD,MAAM,WAAW,GAAG,IAAA,cAAM,EAAiB,IAAI,CAAC,CAAC;IAEjD,IAAA,iBAAS,EAAC,GAAG,EAAE;QACb,IAAI,SAAS,CAAC,OAAO,EAAE,CAAC;YACtB,cAAc,CAAC,SAAS,CAAC,OAAO,CAAC,WAAW,CAAC,CAAC;QAChD,CAAC;IACH,CAAC,EAAE,CAAC,MAAM,CAAC,CAAC,CAAC;IAEb,MAAM,kBAAkB,GAAG,IAAA,mBAAW,EAAC,CAAC,KAAiB,EAAE,EAAE;QAC3D,MAAM,MAAM,GAAG,KAAK,CAAC,MAAqB,CAAC;QAE3C,IACE,SAAS,CAAC,OAAO;YACjB,WAAW,CAAC,OAAO;YACnB,CAAC,SAAS,CAAC,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAC;YACnC,CAAC,WAAW,CAAC,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAC,EACrC,CAAC;YACD,SAAS,CAAC,KAAK,CAAC,CAAC;QACnB,CAAC;IACH,CAAC,EAAE,EAAE,CAAC,CAAC;IAEP,MAAM,aAAa,GAAG,IAAA,mBAAW,EAAC,KAAK,IAAI,EAAE;QAC3C,MAAM,OAAO,EAAE,CAAC;QAEhB,SAAS,CAAC,KAAK,CAAC,CAAC;IACnB,CAAC,EAAE,CAAC,OAAO,CAAC,CAAC,CAAC;IAEd,MAAM,YAAY,GAAG,IAAA,mBAAW,EAAC,KAAK,IAAI,EAAE;QAC1C,MAAM,MAAM,CAAC,WAAW,CAAC,CAAC;QAE1B,SAAS,CAAC,KAAK,CAAC,CAAC;IACnB,CAAC,EAAE,CAAC,MAAM,EAAE,WAAW,CAAC,CAAC,CAAC;IAE1B,MAAM,YAAY,GAAG,IAAA,mBAAW,EAAC,CAAC,KAAoB,EAAE,EAAE;QACxD,IAAI,KAAK,CAAC,GAAG,KAAK,QAAQ,EAAE,CAAC;YAC3B,SAAS,CAAC,KAAK,CAAC,CAAC;QACnB,CAAC;IACH,CAAC,EAAE,EAAE,CAAC,CAAC;IAEP,IAAA,iBAAS,EAAC,GAAG,EAAE;QACb,IAAI,MAAM,EAAE,CAAC;YACX,MAAM,CAAC,gBAAgB,CAAC,OAAO,EAAE,kBAAkB,CAAC,CAAC;YAErD,MAAM,CAAC,gBAAgB,CAAC,SAAS,EAAE,YAAY,CAAC,CAAC;QACnD,CAAC;QAED,OAAO,GAAG,EAAE;YACV,MAAM,CAAC,mBAAmB,CAAC,OAAO,EAAE,kBAAkB,CAAC,CAAC;YAExD,MAAM,CAAC,mBAAmB,CAAC,SAAS,EAAE,YAAY,CAAC,CAAC;QACtD,CAAC,CAAC;IACJ,CAAC,EAAE,CAAC,kBAAkB,EAAE,YAAY,EAAE,MAAM,CAAC,CAAC,CAAC;IAE/C,IAAI,IAAI,EAAE,CAAC;QACT,OAAO,CACL,uCACE,KAAK,EAAE,EAAE,QAAQ,EAAE,UAAU,EAAE,KAAK,EAAE,MAAM,EAAE,EAC9C,EAAE,EAAC,0BAA0B;YAE7B,0CACE,GAAG,EAAE,SAAS,EACd,KAAK,EAAE;oBACL,MAAM,EAAE,SAAS;oBACjB,OAAO,EAAE,MAAM;oBACf,QAAQ,EAAE,OAAO;oBACjB,UAAU,EAAE,QAAQ;oBACpB,cAAc,EAAE,eAAe;oBAC/B,GAAG,EAAE,QAAQ;oBACb,YAAY,EAAE,QAAQ;oBACtB,MAAM,EAAE,mBAAmB;oBAC3B,OAAO,EAAE,cAAc;oBACvB,KAAK,EAAE,SAAS;oBAChB,UAAU,EAAE,MAAM;oBAClB,UAAU,EAAE,uBAAuB;iBACpC,EACD,SAAS,EAAE,SAAS,EACpB,YAAY,EAAE,CAAC,CAAC,EAAE,EAAE,CAClB,CAAC,CAAC,CAAC,aAAa,CAAC,KAAK,CAAC,eAAe,GAAG,SAAS,CAAC,EAErD,YAAY,EAAE,CAAC,CAAC,EAAE,EAAE,CAClB,CAAC,CAAC,CAAC,aAAa,CAAC,KAAK,CAAC,eAAe,GAAG,aAAa,CAAC,EAEzD,OAAO,EAAE,GAAG,EAAE;oBACZ,SAAS,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC,MAAM,CAAC,CAAC;gBACjC,CAAC;gBAEA,IAAI,EAAE,OAAO,CAAC,CAAC,CAAC,CACf,wCACE,KAAK,EAAE;wBACL,QAAQ,EAAE,UAAU;wBACpB,OAAO,EAAE,MAAM;wBACf,MAAM,EAAE,QAAQ;wBAChB,KAAK,EAAE,QAAQ;wBACf,UAAU,EAAE,CAAC;wBACb,GAAG,EAAE,QAAQ;wBACb,QAAQ,EAAE,QAAQ;wBAClB,YAAY,EAAE,QAAQ;qBACvB;oBAED,uCACE,KAAK,EAAE,EAAE,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,SAAS,EAAE,OAAO,EAAE,EAC5D,GAAG,EAAE,IAAI,CAAC,OAAO,EACjB,GAAG,EAAE,IAAI,EAAE,IAAI,IAAI,IAAI,EAAE,KAAK,GAC9B,CACG,CACR,CAAC,CAAC,CAAC,CACF,wCAAM,KAAK,EAAE,EAAE,OAAO,EAAE,OAAO,EAAE,GAAI,CACtC;gBAED,4CAAO,IAAI,EAAE,IAAI,IAAI,IAAI,EAAE,KAAK,CAAQ;gBAExC,wCAAM,KAAK,EAAE,EAAE,OAAO,EAAE,OAAO,EAAE,aAAa,EAAE,MAAM,EAAE,IACrD,MAAM,CAAC,CAAC,CAAC,8BAAC,SAAS,OAAG,CAAC,CAAC,CAAC,8BAAC,WAAW,OAAG,CACpC,CACA;YACT,uCACE,GAAG,EAAE,WAAW,EAChB,KAAK,EACH,MAAM;oBACJ,CAAC,CAAC;wBACE,QAAQ,EAAE,UAAU;wBACpB,IAAI,EAAE,CAAC;wBACP,KAAK,EAAE,WAAW,IAAI,MAAM;wBAC5B,SAAS,EAAE,QAAQ;wBACnB,YAAY,EAAE,QAAQ;wBACtB,eAAe,EAAE,OAAO;wBACxB,OAAO,EAAE,UAAU;wBACnB,KAAK,EAAE,SAAS;wBAChB,SAAS,EACP,yEAAyE;qBAC5E;oBACH,CAAC,CAAC,EAAE,OAAO,EAAE,MAAM,EAAE;gBAGzB,sCAAI,KAAK,EAAE,EAAE,aAAa,EAAE,MAAM,EAAE,MAAM,EAAE,CAAC,EAAE,OAAO,EAAE,CAAC,EAAE;oBACzD;wBACE,0CACE,KAAK,EAAE;gCACL,OAAO,EAAE,OAAO;gCAChB,KAAK,EAAE,MAAM;gCACb,OAAO,EAAE,aAAa;gCACtB,UAAU,EAAE,uBAAuB;gCACnC,UAAU,EAAE,MAAM;gCAClB,MAAM,EAAE,MAAM;gCACd,SAAS,EAAE,QAAQ;gCACnB,MAAM,EAAE,SAAS;6BAClB,EACD,OAAO,EAAE,aAAa,EACtB,YAAY,EAAE,CAAC,CAAC,EAAE,EAAE,CAClB,CAAC,CAAC,CAAC,aAAa,CAAC,KAAK,CAAC,eAAe,GAAG,SAAS,CAAC,EAErD,YAAY,EAAE,CAAC,CAAC,EAAE,EAAE,CAClB,CAAC,CAAC,CAAC,aAAa,CAAC,KAAK,CAAC,eAAe,GAAG,aAAa,CAAC,aAIlD,CACN,CACF,CACD,CACF,CACP,CAAC;IACJ,CAAC;IAED,OAAO,CACL,0CACE,GAAG,EAAE,SAAS,iBACF,gBAAgB,EAC5B,KAAK,EAAE;YACL,MAAM,EAAE,SAAS;YACjB,YAAY,EAAE,QAAQ;YACtB,MAAM,EAAE,mBAAmB;YAC3B,OAAO,EAAE,cAAc;YACvB,UAAU,EAAE,MAAM;YAClB,UAAU,EAAE,uBAAuB;SACpC,EACD,SAAS,EAAE,SAAS,EACpB,YAAY,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,aAAa,CAAC,KAAK,CAAC,eAAe,GAAG,SAAS,CAAC,EACxE,YAAY,EAAE,CAAC,CAAC,EAAE,EAAE,CAClB,CAAC,CAAC,CAAC,aAAa,CAAC,KAAK,CAAC,eAAe,GAAG,aAAa,CAAC,EAEzD,OAAO,EAAE,YAAY,cAGd,CACV,CAAC;AACJ,CAAC,CAAC;AAEO,gCAAU","sourcesContent":["\"use client\";\nimport { useUser } from \"@/reactjs/hooks/index.js\";\nimport type { DisplayMode } from \"@/types.js\";\nimport React, { useCallback, useEffect, useRef, useState } from \"react\";\n\nconst ChevronDown = () => (\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n width=\"24\"\n height=\"24\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n className=\"lucide lucide-chevron-down\"\n >\n <path d=\"m6 9 6 6 6-6\" />\n </svg>\n);\n\nconst ChevronUp = () => (\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n width=\"24\"\n height=\"24\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n className=\"lucide lucide-chevron-up\"\n >\n <path d=\"m18 15-6-6-6 6\" />\n </svg>\n);\n\nconst UserButton = ({\n displayMode,\n className,\n}: {\n displayMode?: DisplayMode;\n className?: string;\n}) => {\n const [isOpen, setIsOpen] = useState(false);\n const [buttonWidth, setButtonWidth] = useState<number | null>(null);\n const { user, signIn, signOut } = useUser();\n const buttonRef = useRef<HTMLButtonElement>(null);\n const dropdownRef = useRef<HTMLDivElement>(null);\n\n useEffect(() => {\n if (buttonRef.current) {\n setButtonWidth(buttonRef.current.offsetWidth);\n }\n }, [isOpen]);\n\n const handleClickOutside = useCallback((event: MouseEvent) => {\n const target = event.target as HTMLElement;\n\n if (\n buttonRef.current &&\n dropdownRef.current &&\n !buttonRef.current.contains(target) &&\n !dropdownRef.current.contains(target)\n ) {\n setIsOpen(false);\n }\n }, []);\n\n const handleSignOut = useCallback(async () => {\n await signOut();\n\n setIsOpen(false);\n }, [signOut]);\n\n const handleSignIn = useCallback(async () => {\n await signIn(displayMode);\n\n setIsOpen(false);\n }, [signIn, displayMode]);\n\n const handleEscape = useCallback((event: KeyboardEvent) => {\n if (event.key === \"Escape\") {\n setIsOpen(false);\n }\n }, []);\n\n useEffect(() => {\n if (isOpen) {\n window.addEventListener(\"click\", handleClickOutside);\n\n window.addEventListener(\"keydown\", handleEscape);\n }\n\n return () => {\n window.removeEventListener(\"click\", handleClickOutside);\n\n window.removeEventListener(\"keydown\", handleEscape);\n };\n }, [handleClickOutside, handleEscape, isOpen]);\n\n if (user) {\n return (\n <div\n style={{ position: \"relative\", width: \"auto\" }}\n id=\"civic-dropdown-container\"\n >\n <button\n ref={buttonRef}\n style={{\n cursor: \"pointer\",\n display: \"flex\",\n minWidth: \"10rem\",\n alignItems: \"center\",\n justifyContent: \"space-between\",\n gap: \"0.5rem\",\n borderRadius: \"9999px\",\n border: \"1px solid #6b7280\",\n padding: \"0.75rem 1rem\",\n color: \"#6b7280\",\n background: \"none\",\n transition: \"background-color 0.2s\",\n }}\n className={className}\n onMouseEnter={(e) =>\n (e.currentTarget.style.backgroundColor = \"#f3f4f6\")\n }\n onMouseLeave={(e) =>\n (e.currentTarget.style.backgroundColor = \"transparent\")\n }\n onClick={() => {\n setIsOpen((isOpen) => !isOpen);\n }}\n >\n {user?.picture ? (\n <span\n style={{\n position: \"relative\",\n display: \"flex\",\n height: \"1.5rem\",\n width: \"1.5rem\",\n flexShrink: 0,\n gap: \"0.5rem\",\n overflow: \"hidden\",\n borderRadius: \"9999px\",\n }}\n >\n <img\n style={{ height: \"100%\", width: \"100%\", objectFit: \"cover\" }}\n src={user.picture}\n alt={user?.name || user?.email}\n />\n </span>\n ) : (\n <span style={{ display: \"block\" }} />\n )}\n\n <span>{user?.name || user?.email}</span>\n\n <span style={{ display: \"block\", pointerEvents: \"none\" }}>\n {isOpen ? <ChevronUp /> : <ChevronDown />}\n </span>\n </button>\n <div\n ref={dropdownRef}\n style={\n isOpen\n ? {\n position: \"absolute\",\n left: 0,\n width: buttonWidth || \"auto\",\n marginTop: \"0.5rem\",\n borderRadius: \"0.5rem\",\n backgroundColor: \"white\",\n padding: \"0.5rem 0\",\n color: \"#6b7280\",\n boxShadow:\n \"0 10px 15px -3px rgba(0, 0, 0, 0.1), 0 4px 6px -2px rgba(0, 0, 0, 0.05)\",\n }\n : { display: \"none\" }\n }\n >\n <ul style={{ listStyleType: \"none\", margin: 0, padding: 0 }}>\n <li>\n <button\n style={{\n display: \"block\",\n width: \"100%\",\n padding: \"0.5rem 1rem\",\n transition: \"background-color 0.2s\",\n background: \"none\",\n border: \"none\",\n textAlign: \"center\",\n cursor: \"pointer\",\n }}\n onClick={handleSignOut}\n onMouseEnter={(e) =>\n (e.currentTarget.style.backgroundColor = \"#f3f4f6\")\n }\n onMouseLeave={(e) =>\n (e.currentTarget.style.backgroundColor = \"transparent\")\n }\n >\n Logout\n </button>\n </li>\n </ul>\n </div>\n </div>\n );\n }\n\n return (\n <button\n ref={buttonRef}\n data-testid=\"sign-in-button\"\n style={{\n cursor: \"pointer\",\n borderRadius: \"9999px\",\n border: \"1px solid #6b7280\",\n padding: \"0.75rem 1rem\",\n background: \"none\",\n transition: \"background-color 0.2s\",\n }}\n className={className}\n onMouseEnter={(e) => (e.currentTarget.style.backgroundColor = \"#f3f4f6\")}\n onMouseLeave={(e) =>\n (e.currentTarget.style.backgroundColor = \"transparent\")\n }\n onClick={handleSignIn}\n >\n Sign in\n </button>\n );\n};\n\nexport { UserButton };\n"]}
|
|
1
|
+
{"version":3,"file":"UserButton.js","sourceRoot":"","sources":["../../../../src/reactjs/components/UserButton.tsx"],"names":[],"mappings":"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","sourcesContent":["\"use client\";\nimport { useUser } from \"@/reactjs/hooks/index.js\";\nimport React, { useCallback, useEffect, useRef, useState } from \"react\";\n\nconst ChevronDown = () => (\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n width=\"24\"\n height=\"24\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n className=\"lucide lucide-chevron-down\"\n >\n <path d=\"m6 9 6 6 6-6\" />\n </svg>\n);\n\nconst ChevronUp = () => (\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n width=\"24\"\n height=\"24\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n className=\"lucide lucide-chevron-up\"\n >\n <path d=\"m18 15-6-6-6 6\" />\n </svg>\n);\n\nconst UserButton = ({ className }: { className?: string }) => {\n const [isOpen, setIsOpen] = useState(false);\n const [buttonWidth, setButtonWidth] = useState<number | null>(null);\n const { user, signIn, signOut } = useUser();\n const buttonRef = useRef<HTMLButtonElement>(null);\n const dropdownRef = useRef<HTMLDivElement>(null);\n\n useEffect(() => {\n if (buttonRef.current) {\n setButtonWidth(buttonRef.current.offsetWidth);\n }\n }, [isOpen]);\n\n const handleClickOutside = useCallback((event: MouseEvent) => {\n const target = event.target as HTMLElement;\n\n if (\n buttonRef.current &&\n dropdownRef.current &&\n !buttonRef.current.contains(target) &&\n !dropdownRef.current.contains(target)\n ) {\n setIsOpen(false);\n }\n }, []);\n\n const handleSignOut = useCallback(async () => {\n await signOut();\n\n setIsOpen(false);\n }, [signOut]);\n\n const handleSignIn = useCallback(async () => {\n await signIn();\n\n setIsOpen(false);\n }, [signIn]);\n\n const handleEscape = useCallback((event: KeyboardEvent) => {\n if (event.key === \"Escape\") {\n setIsOpen(false);\n }\n }, []);\n\n useEffect(() => {\n if (isOpen) {\n window.addEventListener(\"click\", handleClickOutside);\n\n window.addEventListener(\"keydown\", handleEscape);\n }\n\n return () => {\n window.removeEventListener(\"click\", handleClickOutside);\n\n window.removeEventListener(\"keydown\", handleEscape);\n };\n }, [handleClickOutside, handleEscape, isOpen]);\n\n if (user) {\n return (\n <div\n style={{ position: \"relative\", width: \"auto\" }}\n id=\"civic-dropdown-container\"\n >\n <button\n ref={buttonRef}\n style={{\n cursor: \"pointer\",\n display: \"flex\",\n minWidth: \"10rem\",\n alignItems: \"center\",\n justifyContent: \"space-between\",\n gap: \"0.5rem\",\n borderRadius: \"9999px\",\n border: \"1px solid #6b7280\",\n padding: \"0.75rem 1rem\",\n color: \"#6b7280\",\n background: \"none\",\n transition: \"background-color 0.2s\",\n }}\n className={className}\n onMouseEnter={(e) =>\n (e.currentTarget.style.backgroundColor = \"#f3f4f6\")\n }\n onMouseLeave={(e) =>\n (e.currentTarget.style.backgroundColor = \"transparent\")\n }\n onClick={() => {\n setIsOpen((isOpen) => !isOpen);\n }}\n >\n {user?.picture ? (\n <span\n style={{\n position: \"relative\",\n display: \"flex\",\n height: \"1.5rem\",\n width: \"1.5rem\",\n flexShrink: 0,\n gap: \"0.5rem\",\n overflow: \"hidden\",\n borderRadius: \"9999px\",\n }}\n >\n <img\n style={{ height: \"100%\", width: \"100%\", objectFit: \"cover\" }}\n src={user.picture}\n alt={user?.name || user?.email}\n />\n </span>\n ) : (\n <span style={{ display: \"block\" }} />\n )}\n\n <span>{user?.name || user?.email}</span>\n\n <span style={{ display: \"block\", pointerEvents: \"none\" }}>\n {isOpen ? <ChevronUp /> : <ChevronDown />}\n </span>\n </button>\n <div\n ref={dropdownRef}\n style={\n isOpen\n ? {\n position: \"absolute\",\n left: 0,\n width: buttonWidth || \"auto\",\n marginTop: \"0.5rem\",\n borderRadius: \"0.5rem\",\n backgroundColor: \"white\",\n padding: \"0.5rem 0\",\n color: \"#6b7280\",\n boxShadow:\n \"0 10px 15px -3px rgba(0, 0, 0, 0.1), 0 4px 6px -2px rgba(0, 0, 0, 0.05)\",\n }\n : { display: \"none\" }\n }\n >\n <ul style={{ listStyleType: \"none\", margin: 0, padding: 0 }}>\n <li>\n <button\n style={{\n display: \"block\",\n width: \"100%\",\n padding: \"0.5rem 1rem\",\n transition: \"background-color 0.2s\",\n background: \"none\",\n border: \"none\",\n textAlign: \"center\",\n cursor: \"pointer\",\n }}\n onClick={handleSignOut}\n onMouseEnter={(e) =>\n (e.currentTarget.style.backgroundColor = \"#f3f4f6\")\n }\n onMouseLeave={(e) =>\n (e.currentTarget.style.backgroundColor = \"transparent\")\n }\n >\n Logout\n </button>\n </li>\n </ul>\n </div>\n </div>\n );\n }\n\n return (\n <button\n ref={buttonRef}\n data-testid=\"sign-in-button\"\n style={{\n cursor: \"pointer\",\n borderRadius: \"9999px\",\n border: \"1px solid #6b7280\",\n padding: \"0.75rem 1rem\",\n background: \"none\",\n transition: \"background-color 0.2s\",\n }}\n className={className}\n onMouseEnter={(e) => (e.currentTarget.style.backgroundColor = \"#f3f4f6\")}\n onMouseLeave={(e) =>\n (e.currentTarget.style.backgroundColor = \"transparent\")\n }\n onClick={handleSignIn}\n >\n Sign in\n </button>\n );\n};\n\nexport { UserButton };\n"]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useClientTokenExchangeSession.d.ts","sourceRoot":"","sources":["../../../../src/reactjs/hooks/useClientTokenExchangeSession.ts"],"names":[],"mappings":"AAKA,QAAA,MAAM,6BAA6B,oHAMlC,CAAC;AAEF,OAAO,EAAE,6BAA6B,EAAE,CAAC"}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
"use client";
|
|
3
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
4
|
+
exports.useClientTokenExchangeSession = void 0;
|
|
5
|
+
const react_1 = require("react");
|
|
6
|
+
const ClientTokenExchangeSessionProvider_js_1 = require("../../reactjs/providers/ClientTokenExchangeSessionProvider.js");
|
|
7
|
+
// TokenProvider will use this internal context to access session
|
|
8
|
+
const useClientTokenExchangeSession = () => {
|
|
9
|
+
const context = (0, react_1.useContext)(ClientTokenExchangeSessionProvider_js_1.ClientTokenExchangeSessionContext);
|
|
10
|
+
if (!context) {
|
|
11
|
+
throw new Error("useSession must be used within an SessionProvider");
|
|
12
|
+
}
|
|
13
|
+
return context;
|
|
14
|
+
};
|
|
15
|
+
exports.useClientTokenExchangeSession = useClientTokenExchangeSession;
|
|
16
|
+
//# sourceMappingURL=useClientTokenExchangeSession.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useClientTokenExchangeSession.js","sourceRoot":"","sources":["../../../../src/reactjs/hooks/useClientTokenExchangeSession.ts"],"names":[],"mappings":";AAAA,YAAY,CAAC;;;AACb,iCAAmC;AACnC,qHAA8G;AAE9G,iEAAiE;AACjE,MAAM,6BAA6B,GAAG,GAAG,EAAE;IACzC,MAAM,OAAO,GAAG,IAAA,kBAAU,EAAC,yEAAiC,CAAC,CAAC;IAC9D,IAAI,CAAC,OAAO,EAAE,CAAC;QACb,MAAM,IAAI,KAAK,CAAC,mDAAmD,CAAC,CAAC;IACvE,CAAC;IACD,OAAO,OAAO,CAAC;AACjB,CAAC,CAAC;AAEO,sEAA6B","sourcesContent":["\"use client\";\nimport { useContext } from \"react\";\nimport { ClientTokenExchangeSessionContext } from \"@/reactjs/providers/ClientTokenExchangeSessionProvider.js\";\n\n// TokenProvider will use this internal context to access session\nconst useClientTokenExchangeSession = () => {\n const context = useContext(ClientTokenExchangeSessionContext);\n if (!context) {\n throw new Error(\"useSession must be used within an SessionProvider\");\n }\n return context;\n};\n\nexport { useClientTokenExchangeSession };\n"]}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
import type { SessionData } from "../../types.js";
|
|
3
|
+
import type { PKCEConsumer } from "../../services/types.js";
|
|
4
|
+
import type { AuthProviderProps } from "../../shared/providers/types.js";
|
|
5
|
+
export type InternalAuthProviderProps = AuthProviderProps & {
|
|
6
|
+
sessionData?: SessionData;
|
|
7
|
+
pkceConsumer?: PKCEConsumer;
|
|
8
|
+
};
|
|
9
|
+
declare const AuthProvider: ({ children, onSignIn, onSignOut, pkceConsumer, iframeMode, displayMode, }: InternalAuthProviderProps) => React.JSX.Element;
|
|
10
|
+
export { AuthProvider };
|
|
11
|
+
//# sourceMappingURL=AuthProvider.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"AuthProvider.d.ts","sourceRoot":"","sources":["../../../../src/reactjs/providers/AuthProvider.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAuC,MAAM,OAAO,CAAC;AAC5D,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAE9C,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AAMxD,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,6BAA6B,CAAC;AAarE,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,108 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
"use client";
|
|
3
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
4
|
+
if (k2 === undefined) k2 = k;
|
|
5
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
6
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
7
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
8
|
+
}
|
|
9
|
+
Object.defineProperty(o, k2, desc);
|
|
10
|
+
}) : (function(o, m, k, k2) {
|
|
11
|
+
if (k2 === undefined) k2 = k;
|
|
12
|
+
o[k2] = m[k];
|
|
13
|
+
}));
|
|
14
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
15
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
16
|
+
}) : function(o, v) {
|
|
17
|
+
o["default"] = v;
|
|
18
|
+
});
|
|
19
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
20
|
+
var ownKeys = function(o) {
|
|
21
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
22
|
+
var ar = [];
|
|
23
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
24
|
+
return ar;
|
|
25
|
+
};
|
|
26
|
+
return ownKeys(o);
|
|
27
|
+
};
|
|
28
|
+
return function (mod) {
|
|
29
|
+
if (mod && mod.__esModule) return mod;
|
|
30
|
+
var result = {};
|
|
31
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
32
|
+
__setModuleDefault(result, mod);
|
|
33
|
+
return result;
|
|
34
|
+
};
|
|
35
|
+
})();
|
|
36
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
37
|
+
exports.AuthProvider = void 0;
|
|
38
|
+
const react_1 = __importStar(require("react"));
|
|
39
|
+
const AuthContext_js_1 = require("../../shared/providers/AuthContext.js");
|
|
40
|
+
const useSignIn_js_1 = require("../../shared/hooks/useSignIn.js");
|
|
41
|
+
const useIframe_js_1 = require("../../shared/hooks/useIframe.js");
|
|
42
|
+
const useCivicAuthConfig_js_1 = require("../../shared/hooks/useCivicAuthConfig.js");
|
|
43
|
+
const useSession_js_1 = require("../../shared/hooks/useSession.js");
|
|
44
|
+
const IFrameAndLoading_js_1 = require("../../shared/components/IFrameAndLoading.js");
|
|
45
|
+
// Global this object setup
|
|
46
|
+
let globalThisObject;
|
|
47
|
+
if (typeof window !== "undefined") {
|
|
48
|
+
globalThisObject = window;
|
|
49
|
+
}
|
|
50
|
+
else if (typeof global !== "undefined") {
|
|
51
|
+
globalThisObject = global;
|
|
52
|
+
}
|
|
53
|
+
else {
|
|
54
|
+
globalThisObject = Function("return this")();
|
|
55
|
+
}
|
|
56
|
+
globalThisObject.globalThis = globalThisObject;
|
|
57
|
+
const AuthProvider = ({ children, onSignIn, onSignOut, pkceConsumer, iframeMode = "modal", displayMode = "iframe", }) => {
|
|
58
|
+
const authConfig = (0, useCivicAuthConfig_js_1.useCivicAuthConfig)();
|
|
59
|
+
const { redirectUrl } = authConfig || {};
|
|
60
|
+
const { iframeRef } = (0, useIframe_js_1.useIframe)();
|
|
61
|
+
const { signIn, signOut } = (0, useSignIn_js_1.useSignIn)({
|
|
62
|
+
preSignOut: onSignOut,
|
|
63
|
+
pkceConsumer,
|
|
64
|
+
displayMode,
|
|
65
|
+
});
|
|
66
|
+
const [localSessionData, setLocalSessionData] = (0, react_1.useState)();
|
|
67
|
+
const { data: session, error: tokenExchangeError, isLoading: tokenExchangeInProgress, } = (0, useSession_js_1.useSession)();
|
|
68
|
+
(0, react_1.useEffect)(() => {
|
|
69
|
+
if (session) {
|
|
70
|
+
setLocalSessionData(session);
|
|
71
|
+
if (session.authenticated) {
|
|
72
|
+
onSignIn?.();
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
}, [onSignIn, session]);
|
|
76
|
+
const isAuthenticated = (0, react_1.useMemo)(() => {
|
|
77
|
+
return !!localSessionData?.idToken;
|
|
78
|
+
}, [localSessionData]);
|
|
79
|
+
(0, react_1.useEffect)(() => {
|
|
80
|
+
if (iframeMode === "embedded" &&
|
|
81
|
+
redirectUrl &&
|
|
82
|
+
!isAuthenticated &&
|
|
83
|
+
iframeRef?.current) {
|
|
84
|
+
signIn();
|
|
85
|
+
}
|
|
86
|
+
}, [iframeMode, redirectUrl, isAuthenticated, iframeRef, signIn]);
|
|
87
|
+
const isLoading = tokenExchangeInProgress || !authConfig;
|
|
88
|
+
const value = (0, react_1.useMemo)(() => ({
|
|
89
|
+
isLoading,
|
|
90
|
+
error: tokenExchangeError,
|
|
91
|
+
signOut,
|
|
92
|
+
isAuthenticated,
|
|
93
|
+
signIn,
|
|
94
|
+
displayMode,
|
|
95
|
+
}), [
|
|
96
|
+
isLoading,
|
|
97
|
+
tokenExchangeError,
|
|
98
|
+
signOut,
|
|
99
|
+
isAuthenticated,
|
|
100
|
+
signIn,
|
|
101
|
+
displayMode,
|
|
102
|
+
]);
|
|
103
|
+
return (react_1.default.createElement(AuthContext_js_1.AuthContext.Provider, { value: value },
|
|
104
|
+
react_1.default.createElement(IFrameAndLoading_js_1.IFrameAndLoading, { error: tokenExchangeError, isLoading: isLoading }),
|
|
105
|
+
children));
|
|
106
|
+
};
|
|
107
|
+
exports.AuthProvider = AuthProvider;
|
|
108
|
+
//# sourceMappingURL=AuthProvider.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"AuthProvider.js","sourceRoot":"","sources":["../../../../src/reactjs/providers/AuthProvider.tsx"],"names":[],"mappings":"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","sourcesContent":["\"use client\";\n\nimport React, { useEffect, useMemo, useState } from \"react\";\nimport type { 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\";\nimport type { AuthProviderProps } from \"@/shared/providers/types.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 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,\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 signOut,\n isAuthenticated,\n signIn,\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/types.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/reactjs/providers/CivicAuthProvider.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,MAAM,OAAO,CAAC;AAY1B,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,6BAA6B,CAAC;AAErE,KAAK,sBAAsB,GAAG,IAAI,CAAC,iBAAiB,EAAE,cAAc,CAAC,CAAC;AAmCtE,QAAA,MAAM,iBAAiB,2BAA4B,sBAAsB,sBAgBxE,CAAC;AAEF,OAAO,EAAE,iBAAiB,EAAE,KAAK,sBAAsB,EAAE,CAAC"}
|