+ {t(I18nKey.AUTH$EMAIL_VERIFIED_PLEASE_LOGIN)} +
+- {t(I18nKey.AUTH$BY_SIGNING_UP_YOU_AGREE_TO_OUR)}{" "} - - {t(I18nKey.COMMON$TERMS_OF_SERVICE)} - {" "} - {t(I18nKey.COMMON$AND)}{" "} - - {t(I18nKey.COMMON$PRIVACY_POLICY)} - - . -
++ {t(I18nKey.AUTH$BY_SIGNING_UP_YOU_AGREE_TO_OUR)}{" "} + + {t(I18nKey.COMMON$TERMS_OF_SERVICE)} + {" "} + {t(I18nKey.COMMON$AND)}{" "} + + {t(I18nKey.COMMON$PRIVACY_POLICY)} + + . +
+ ); +} diff --git a/frontend/src/hooks/use-email-verification.ts b/frontend/src/hooks/use-email-verification.ts new file mode 100644 index 0000000000..c0068395b5 --- /dev/null +++ b/frontend/src/hooks/use-email-verification.ts @@ -0,0 +1,63 @@ +import React from "react"; +import { useSearchParams } from "react-router"; + +/** + * Hook to handle email verification logic from URL query parameters. + * Manages the email verification modal state and email verified state + * based on query parameters in the URL. + * + * @returns An object containing: + * - emailVerificationModalOpen: boolean state for modal visibility + * - setEmailVerificationModalOpen: function to control modal visibility + * - emailVerified: boolean state for email verification status + * - setEmailVerified: function to control email verification status + * - hasDuplicatedEmail: boolean state for duplicate email error status + */ +export function useEmailVerification() { + const [searchParams, setSearchParams] = useSearchParams(); + const [emailVerificationModalOpen, setEmailVerificationModalOpen] = + React.useState(false); + const [emailVerified, setEmailVerified] = React.useState(false); + const [hasDuplicatedEmail, setHasDuplicatedEmail] = React.useState(false); + + // Check for email verification query parameters + React.useEffect(() => { + const emailVerificationRequired = searchParams.get( + "email_verification_required", + ); + const emailVerifiedParam = searchParams.get("email_verified"); + const duplicatedEmailParam = searchParams.get("duplicated_email"); + let shouldUpdate = false; + + if (emailVerificationRequired === "true") { + setEmailVerificationModalOpen(true); + searchParams.delete("email_verification_required"); + shouldUpdate = true; + } + + if (emailVerifiedParam === "true") { + setEmailVerified(true); + searchParams.delete("email_verified"); + shouldUpdate = true; + } + + if (duplicatedEmailParam === "true") { + setHasDuplicatedEmail(true); + searchParams.delete("duplicated_email"); + shouldUpdate = true; + } + + // Clean up the URL by removing parameters if any were found + if (shouldUpdate) { + setSearchParams(searchParams, { replace: true }); + } + }, [searchParams, setSearchParams]); + + return { + emailVerificationModalOpen, + setEmailVerificationModalOpen, + emailVerified, + setEmailVerified, + hasDuplicatedEmail, + }; +} diff --git a/frontend/src/i18n/declaration.ts b/frontend/src/i18n/declaration.ts index 0dd668cacc..e3ed93db2f 100644 --- a/frontend/src/i18n/declaration.ts +++ b/frontend/src/i18n/declaration.ts @@ -730,6 +730,8 @@ export enum I18nKey { MICROAGENT_MANAGEMENT$USE_MICROAGENTS = "MICROAGENT_MANAGEMENT$USE_MICROAGENTS", AUTH$BY_SIGNING_UP_YOU_AGREE_TO_OUR = "AUTH$BY_SIGNING_UP_YOU_AGREE_TO_OUR", AUTH$NO_PROVIDERS_CONFIGURED = "AUTH$NO_PROVIDERS_CONFIGURED", + AUTH$PLEASE_CHECK_EMAIL_TO_VERIFY = "AUTH$PLEASE_CHECK_EMAIL_TO_VERIFY", + AUTH$EMAIL_VERIFIED_PLEASE_LOGIN = "AUTH$EMAIL_VERIFIED_PLEASE_LOGIN", AUTH$DUPLICATE_EMAIL_ERROR = "AUTH$DUPLICATE_EMAIL_ERROR", COMMON$TERMS_OF_SERVICE = "COMMON$TERMS_OF_SERVICE", COMMON$AND = "COMMON$AND", diff --git a/frontend/src/i18n/translation.json b/frontend/src/i18n/translation.json index 2950b3ab72..81df3b6f7d 100644 --- a/frontend/src/i18n/translation.json +++ b/frontend/src/i18n/translation.json @@ -11679,6 +11679,38 @@ "de": "Mindestens ein Identitätsanbieter muss konfiguriert werden (z.B. GitHub)", "uk": "Принаймні один постачальник ідентифікації має бути налаштований (наприклад, GitHub)" }, + "AUTH$PLEASE_CHECK_EMAIL_TO_VERIFY": { + "en": "Please check your email to verify your account.", + "ja": "アカウントを確認するためにメールを確認してください。", + "zh-CN": "请检查您的电子邮件以验证您的账户。", + "zh-TW": "請檢查您的電子郵件以驗證您的帳戶。", + "ko-KR": "계정을 확인하려면 이메일을 확인하세요.", + "no": "Vennligst sjekk e-posten din for å bekrefte kontoen din.", + "it": "Controlla la tua email per verificare il tuo account.", + "pt": "Por favor, verifique seu e-mail para verificar sua conta.", + "es": "Por favor, verifica tu correo electrónico para verificar tu cuenta.", + "ar": "يرجى التحقق من بريدك الإلكتروني للتحقق من حسابك.", + "fr": "Veuillez vérifier votre e-mail pour vérifier votre compte.", + "tr": "Hesabınızı doğrulamak için lütfen e-postanızı kontrol edin.", + "de": "Bitte überprüfen Sie Ihre E-Mail, um Ihr Konto zu verifizieren.", + "uk": "Будь ласка, перевірте свою електронну пошту, щоб підтвердити свій обліковий запис." + }, + "AUTH$EMAIL_VERIFIED_PLEASE_LOGIN": { + "en": "Your email has been verified. Please login below.", + "ja": "メールアドレスが確認されました。下記からログインしてください。", + "zh-CN": "您的电子邮件已验证。请在下方登录。", + "zh-TW": "您的電子郵件已驗證。請在下方登錄。", + "ko-KR": "이메일이 확인되었습니다. 아래에서 로그인하세요.", + "no": "E-posten din er bekreftet. Vennligst logg inn nedenfor.", + "it": "La tua email è stata verificata. Effettua il login qui sotto.", + "pt": "Seu e-mail foi verificado. Por favor, faça login abaixo.", + "es": "Tu correo electrónico ha sido verificado. Por favor, inicia sesión a continuación.", + "ar": "تم التحقق من بريدك الإلكتروني. يرجى تسجيل الدخول أدناه.", + "fr": "Votre e-mail a été vérifié. Veuillez vous connecter ci-dessous.", + "tr": "E-postanız doğrulandı. Lütfen aşağıdan giriş yapın.", + "de": "Ihre E-Mail wurde verifiziert. Bitte melden Sie sich unten an.", + "uk": "Вашу електронну пошту підтверджено. Будь ласка, увійдіть нижче." + }, "AUTH$DUPLICATE_EMAIL_ERROR": { "en": "Your account is unable to be created. Please use a different login or try again.", "ja": "アカウントを作成できません。別のログインを使用するか、もう一度お試しください。", diff --git a/frontend/src/routes/root-layout.tsx b/frontend/src/routes/root-layout.tsx index 876c4d8c11..73da04ea8f 100644 --- a/frontend/src/routes/root-layout.tsx +++ b/frontend/src/routes/root-layout.tsx @@ -15,6 +15,7 @@ import { useConfig } from "#/hooks/query/use-config"; import { Sidebar } from "#/components/features/sidebar/sidebar"; import { AuthModal } from "#/components/features/waitlist/auth-modal"; import { ReauthModal } from "#/components/features/waitlist/reauth-modal"; +import { EmailVerificationModal } from "#/components/features/waitlist/email-verification-modal"; import { AnalyticsConsentFormModal } from "#/components/features/analytics/analytics-consent-form-modal"; import { useSettings } from "#/hooks/query/use-settings"; import { useMigrateUserConsent } from "#/hooks/use-migrate-user-consent"; @@ -26,6 +27,7 @@ import { useAutoLogin } from "#/hooks/use-auto-login"; import { useAuthCallback } from "#/hooks/use-auth-callback"; import { useReoTracking } from "#/hooks/use-reo-tracking"; import { useSyncPostHogConsent } from "#/hooks/use-sync-posthog-consent"; +import { useEmailVerification } from "#/hooks/use-email-verification"; import { LOCAL_STORAGE_KEYS } from "#/utils/local-storage"; import { EmailVerificationGuard } from "#/components/features/guards/email-verification-guard"; import { MaintenanceBanner } from "#/components/features/maintenance/maintenance-banner"; @@ -91,6 +93,12 @@ export default function MainApp() { const effectiveGitHubAuthUrl = isOnTosPage ? null : gitHubAuthUrl; const [consentFormIsOpen, setConsentFormIsOpen] = React.useState(false); + const { + emailVerificationModalOpen, + setEmailVerificationModalOpen, + emailVerified, + hasDuplicatedEmail, + } = useEmailVerification(); // Auto-login if login method is stored in local storage useAutoLogin(); @@ -236,9 +244,18 @@ export default function MainApp() { appMode={config.data?.APP_MODE} providersConfigured={config.data?.PROVIDERS_CONFIGURED} authUrl={config.data?.AUTH_URL} + emailVerified={emailVerified} + hasDuplicatedEmail={hasDuplicatedEmail} /> )} {renderReAuthModal &&