From 7effc559cad9b2e82a552f2a4d363569549d558a Mon Sep 17 00:00:00 2001 From: Nicolas Carlier Date: Tue, 17 Oct 2023 19:48:37 +0000 Subject: [PATCH] chore(ui): use static OIDC redirect URI --- ui/src/auth/AuthProvider.tsx | 32 ++++++++++++++++++++++--------- ui/src/auth/helper.ts | 11 ++--------- ui/src/auth/oidc-configuration.ts | 3 +-- 3 files changed, 26 insertions(+), 20 deletions(-) diff --git a/ui/src/auth/AuthProvider.tsx b/ui/src/auth/AuthProvider.tsx index a32dc0e9c..5967c7f56 100644 --- a/ui/src/auth/AuthProvider.tsx +++ b/ui/src/auth/AuthProvider.tsx @@ -17,6 +17,8 @@ interface AuthContextType { logout: (args?: SignoutRedirectArgs) => Promise } +const redirectKey = 'readflow.redirect' + const AuthContext = createContext({} as AuthContextType) export const AuthProvider: FC = ({ children }) => { @@ -27,7 +29,15 @@ export const AuthProvider: FC = ({ children }) => { const { search } = useLocation() const history = useHistory() - const login = useCallback(userManager.signinRedirect.bind(userManager), [userManager]) + const login = useCallback(async () => { + try { + localStorage.setItem(redirectKey, JSON.stringify(history.location)) + console.debug('saving location', JSON.stringify(history.location)) + await userManager.signinRedirect() + } catch (err) { + setError(err) + } + }, [userManager]) const logout = useCallback(userManager.signoutRedirect.bind(userManager), [userManager]) const handleLoginFlow = useCallback(async () => { setIsLoading(true) @@ -45,30 +55,34 @@ export const AuthProvider: FC = ({ children }) => { console.info('callback from Authority server: sign in...') const user = await userManager.signinCallback() if (user) { - console.debug('logged user:', user.profile?.preferred_username) - clearAuthParams(params) + console.debug('logged user:', user.profile?.sub) setUser(user) - history.replace({ - search: params.toString(), + const redirect = localStorage.getItem(redirectKey) + if (redirect) { + localStorage.removeItem(redirectKey) + console.debug('restoring location', redirect) + return history.replace(JSON.parse(redirect)) + } + return history.replace({ + search: clearAuthParams(params), }) - return } } // otherwise handle user state: const user = await userManager.getUser() if (user) { - console.debug('authenticated user:', user?.profile.preferred_username) + console.debug('authenticated user:', user?.profile.sub) setUser(user) } else { console.info('user not authenticated, redirecting to sign-in page...') - await userManager.signinRedirect() + login() } } catch (err) { setError(err) } finally { setIsLoading(false) } - }, [userManager, search]) + }, [userManager, search, login]) // main login flow const didInitialize = useRef(false) diff --git a/ui/src/auth/helper.ts b/ui/src/auth/helper.ts index 28e3e1afc..916bf44f2 100644 --- a/ui/src/auth/helper.ts +++ b/ui/src/auth/helper.ts @@ -1,9 +1,9 @@ const authParams = ['code', 'state', 'session_state', 'error'] as const -export const clearAuthParams = (params: URLSearchParams): URLSearchParams => { +export const clearAuthParams = (params: URLSearchParams): string => { authParams.forEach(param => params.delete(param)) - return params + return params.toString() } export const hasAuthParams = (params: URLSearchParams): boolean => { @@ -14,10 +14,3 @@ export const hasAuthParams = (params: URLSearchParams): boolean => { } return false } - -export const getCleanedRedirectURI = (href: string): string => { - const url = new URL(href) - clearAuthParams(url.searchParams) - console.debug('computed redirect URI:', url.href) - return url.href -} diff --git a/ui/src/auth/oidc-configuration.ts b/ui/src/auth/oidc-configuration.ts index ed146f285..23de5706b 100644 --- a/ui/src/auth/oidc-configuration.ts +++ b/ui/src/auth/oidc-configuration.ts @@ -1,11 +1,10 @@ import { UserManagerSettings } from 'oidc-client-ts' import { AUTHORITY, CLIENT_ID } from '../config' -import { getCleanedRedirectURI } from './helper' export const config: UserManagerSettings = { authority: AUTHORITY, client_id: CLIENT_ID, - redirect_uri: getCleanedRedirectURI(document.location.href), + redirect_uri: `${document.location.origin}/login`, monitorSession: document.location.hostname !== 'localhost', response_type: 'code', scope: 'openid',