From 8f694aceb7b048794eb3b6ae2efe105ebe61153f Mon Sep 17 00:00:00 2001 From: pengx17 Date: Fri, 25 Oct 2024 03:43:00 +0000 Subject: [PATCH] fix(core): redirect to old page after login via 404 page (#8588) fix AF-1487 When visit a cloud worskapce page without login, we should allow the user to redirect back to that page after login. The logic is only added for this case, including login with email magin link + google login. Login with password is already working without changes. --- .../server/src/plugins/oauth/controller.ts | 1 - .../affine/auth/after-sign-in-send-email.tsx | 10 ++++- .../affine/auth/after-sign-up-send-email.tsx | 11 ++++-- .../core/src/components/affine/auth/index.tsx | 10 ++++- .../core/src/components/affine/auth/oauth.tsx | 38 ++++++++++++++----- .../src/components/affine/auth/send-email.tsx | 1 + .../affine/auth/sign-in-with-password.tsx | 18 ++++++++- .../src/components/affine/auth/sign-in.tsx | 18 +++++++-- .../frontend/core/src/desktop/pages/404.tsx | 6 ++- .../src/desktop/pages/auth/magic-link.tsx | 18 +++++++-- .../src/desktop/pages/auth/oauth-callback.tsx | 10 ++++- .../core/src/desktop/pages/auth/sign-in.tsx | 16 +++++--- .../core/src/modules/cloud/services/auth.ts | 13 ++++++- 13 files changed, 135 insertions(+), 35 deletions(-) diff --git a/packages/backend/server/src/plugins/oauth/controller.ts b/packages/backend/server/src/plugins/oauth/controller.ts index 999c34ef3d..d553aedf22 100644 --- a/packages/backend/server/src/plugins/oauth/controller.ts +++ b/packages/backend/server/src/plugins/oauth/controller.ts @@ -111,7 +111,6 @@ export class OAuthController { await this.auth.setCookies(req, res, user.id); res.send({ id: user.id, - /* @deprecated */ redirectUri: state.redirectUri, }); } diff --git a/packages/frontend/core/src/components/affine/auth/after-sign-in-send-email.tsx b/packages/frontend/core/src/components/affine/auth/after-sign-in-send-email.tsx index 99916c6424..d2e4b68d41 100644 --- a/packages/frontend/core/src/components/affine/auth/after-sign-in-send-email.tsx +++ b/packages/frontend/core/src/components/affine/auth/after-sign-in-send-email.tsx @@ -19,6 +19,7 @@ import { Captcha, useCaptcha } from './use-captcha'; export const AfterSignInSendEmail = ({ setAuthData: setAuth, email, + redirectUrl, }: AuthPanelProps<'afterSignInSendEmail'>) => { const [resendCountDown, setResendCountDown] = useState(60); @@ -44,7 +45,12 @@ export const AfterSignInSendEmail = ({ try { if (verifyToken) { setResendCountDown(60); - await authService.sendEmailMagicLink(email, verifyToken, challenge); + await authService.sendEmailMagicLink( + email, + verifyToken, + challenge, + redirectUrl + ); } } catch (err) { console.error(err); @@ -53,7 +59,7 @@ export const AfterSignInSendEmail = ({ }); } setIsSending(false); - }, [authService, challenge, email, verifyToken]); + }, [authService, challenge, email, redirectUrl, verifyToken]); const onSignInWithPasswordClick = useCallback(() => { setAuth({ state: 'signInWithPassword' }); diff --git a/packages/frontend/core/src/components/affine/auth/after-sign-up-send-email.tsx b/packages/frontend/core/src/components/affine/auth/after-sign-up-send-email.tsx index be1e0c0b96..04c9c257a2 100644 --- a/packages/frontend/core/src/components/affine/auth/after-sign-up-send-email.tsx +++ b/packages/frontend/core/src/components/affine/auth/after-sign-up-send-email.tsx @@ -19,7 +19,7 @@ import { Captcha, useCaptcha } from './use-captcha'; export const AfterSignUpSendEmail: FC< AuthPanelProps<'afterSignUpSendEmail'> -> = ({ setAuthData, email }) => { +> = ({ setAuthData, email, redirectUrl }) => { const [resendCountDown, setResendCountDown] = useState(60); useEffect(() => { @@ -42,7 +42,12 @@ export const AfterSignUpSendEmail: FC< setIsSending(true); try { if (verifyToken) { - await authService.sendEmailMagicLink(email, verifyToken, challenge); + await authService.sendEmailMagicLink( + email, + verifyToken, + challenge, + redirectUrl + ); } setResendCountDown(60); } catch (err) { @@ -52,7 +57,7 @@ export const AfterSignUpSendEmail: FC< }); } setIsSending(false); - }, [authService, challenge, email, verifyToken]); + }, [authService, challenge, email, redirectUrl, verifyToken]); return ( <> diff --git a/packages/frontend/core/src/components/affine/auth/index.tsx b/packages/frontend/core/src/components/affine/auth/index.tsx index bf4a2642fe..b6ec7edfe2 100644 --- a/packages/frontend/core/src/components/affine/auth/index.tsx +++ b/packages/frontend/core/src/components/affine/auth/index.tsx @@ -30,6 +30,7 @@ export type AuthPanelProps = { updates: { state: T } & Difference, AuthAtomType> ) => void; onSkip?: () => void; + redirectUrl?: string; } & Extract; const config: { @@ -58,7 +59,13 @@ export function AuthModal() { ); } -export function AuthPanel({ onSkip }: { onSkip?: () => void }) { +export function AuthPanel({ + onSkip, + redirectUrl, +}: { + onSkip?: () => void; + redirectUrl?: string | null; +}) { const t = useI18n(); const [authAtomValue, setAuthAtom] = useAtom(authAtom); const authService = useService(AuthService); @@ -98,6 +105,7 @@ export function AuthPanel({ onSkip }: { onSkip?: () => void }) { const props = { ...authAtomValue, onSkip, + redirectUrl, setAuthData, }; diff --git a/packages/frontend/core/src/components/affine/auth/oauth.tsx b/packages/frontend/core/src/components/affine/auth/oauth.tsx index 8f765678ae..f464e160ed 100644 --- a/packages/frontend/core/src/components/affine/auth/oauth.tsx +++ b/packages/frontend/core/src/components/affine/auth/oauth.tsx @@ -29,7 +29,7 @@ const OAuthProviderMap: Record< }, }; -export function OAuth() { +export function OAuth({ redirectUrl }: { redirectUrl?: string }) { const serverConfig = useService(ServerConfigService).serverConfig; const oauth = useLiveData(serverConfig.features$.map(r => r?.oauth)); const oauthProviders = useLiveData( @@ -41,25 +41,43 @@ export function OAuth() { } return oauthProviders?.map(provider => ( - + )); } -function OAuthProvider({ provider }: { provider: OAuthProviderType }) { +function OAuthProvider({ + provider, + redirectUrl, +}: { + provider: OAuthProviderType; + redirectUrl?: string; +}) { const { icon } = OAuthProviderMap[provider]; const onClick = useCallback(() => { - let oauthUrl = - (BUILD_CONFIG.isElectron || BUILD_CONFIG.isIOS || BUILD_CONFIG.isAndroid - ? BUILD_CONFIG.serverUrlPrefix - : '') + `/oauth/login?provider=${provider}`; + const params = new URLSearchParams(); - if (BUILD_CONFIG.isElectron) { - oauthUrl += `&client=${appInfo?.schema}`; + params.set('provider', provider); + + if (redirectUrl) { + params.set('redirect_uri', redirectUrl); } + if (BUILD_CONFIG.isElectron && appInfo) { + params.set('client', appInfo.schema); + } + + const oauthUrl = + (BUILD_CONFIG.isElectron || BUILD_CONFIG.isIOS || BUILD_CONFIG.isAndroid + ? BUILD_CONFIG.serverUrlPrefix + : '') + `/oauth/login?${params.toString()}`; + popupWindow(oauthUrl); - }, [provider]); + }, [provider, redirectUrl]); return (