diff --git a/packages/demo-app/src/App.tsx b/packages/demo-app/src/App.tsx index 3494778ec..04517fbf1 100644 --- a/packages/demo-app/src/App.tsx +++ b/packages/demo-app/src/App.tsx @@ -29,6 +29,7 @@ const Main = () => { const [showDevPanel, setShowDevPanel] = useState(getLocalData('ui').showDevPanel ?? false); const error = params.get('error'); const errorDescription = params.get('error_description'); + const redirectUri = window.location.origin + window.location.pathname; const toggleDevPanel = useCallback(() => { setShowDevPanel((previous) => { @@ -42,6 +43,11 @@ const Main = () => { return; } + const oneTimeToken = params.get('one_time_token'); + const loginHint = params.get('login_hint'); + + const hasMagicLinkParams = Boolean(oneTimeToken && loginHint); + const loadIdTokenClaims = async () => { const userInfo = await getIdTokenClaims(); setUser(userInfo ?? { sub: 'N/A', username: 'N/A' }); @@ -52,19 +58,28 @@ const Main = () => { void loadIdTokenClaims(); } + const extraParams = Object.fromEntries( + new URLSearchParams([ + ...new URLSearchParams(config.signInExtraParams).entries(), + ...new URLSearchParams(window.location.search).entries(), + ]).entries() + ); + // If user is not authenticated, redirect to sign-in page if (!isAuthenticated) { + void signIn({ redirectUri, extraParams }); + } + + if (isAuthenticated && hasMagicLinkParams) { void signIn({ - redirectUri: window.location.origin + window.location.pathname, - extraParams: Object.fromEntries( - new URLSearchParams([ - ...new URLSearchParams(config.signInExtraParams).entries(), - ...new URLSearchParams(window.location.search).entries(), - ]).entries() - ), + clearTokens: false, + redirectUri, + extraParams, }); + window.history.replaceState({}, '', window.location.pathname); } }, [ + params, config.signInExtraParams, error, getIdTokenClaims, @@ -73,6 +88,7 @@ const Main = () => { isLoading, signIn, user, + redirectUri, ]); useEffect(() => { @@ -90,25 +106,6 @@ const Main = () => { }; }, []); - // Handle one-time token authentication - useEffect(() => { - const oneTimeToken = params.get('one_time_token'); - const loginHint = params.get('login_hint'); - - if (oneTimeToken && loginHint) { - void signIn({ - clearTokens: false, - redirectUri: window.location.origin + window.location.pathname, - extraParams: Object.fromEntries( - new URLSearchParams([ - ...new URLSearchParams(config.signInExtraParams).entries(), - ...new URLSearchParams(window.location.search).entries(), - ]).entries() - ), - }); - } - }, [config.signInExtraParams, params, signIn]); - if (isInCallback) { return ; } diff --git a/packages/demo-app/src/Callback.tsx b/packages/demo-app/src/Callback.tsx index b4f552e3c..9138267d6 100644 --- a/packages/demo-app/src/Callback.tsx +++ b/packages/demo-app/src/Callback.tsx @@ -1,6 +1,13 @@ -import { useHandleSignInCallback } from '@logto/react'; +import { useHandleSignInCallback, useLogto } from '@logto/react'; +import { useEffect } from 'react'; const Callback = () => { + const { clearAllTokens } = useLogto(); + + useEffect(() => { + void clearAllTokens(); + }, [clearAllTokens]); + const { error } = useHandleSignInCallback(() => { window.location.assign('/demo-app'); });