diff --git a/backend/src/controllers/v3/authController.ts b/backend/src/controllers/v3/authController.ts index 7066dc866..e6492ef31 100644 --- a/backend/src/controllers/v3/authController.ts +++ b/backend/src/controllers/v3/authController.ts @@ -28,6 +28,7 @@ declare module 'jsonwebtoken' { userId: string; email: string; authProvider: AuthProvider; + isUserCompleted: boolean, } } diff --git a/backend/src/utils/auth.ts b/backend/src/utils/auth.ts index fac1af5b4..02627fed8 100644 --- a/backend/src/utils/auth.ts +++ b/backend/src/utils/auth.ts @@ -74,7 +74,7 @@ const initializePassport = async () => { let user = await User.findOne({ authProvider: AuthProvider.GOOGLE, authId: profile.id, - }) + }).select('+publicKey') if (!user) { user = await new User({ @@ -89,6 +89,7 @@ const initializePassport = async () => { userId: user._id.toString(), email: user.email, authProvider: user.authProvider, + isUserCompleted: !!user.publicKey }, expiresIn: await getJwtProviderAuthLifetime(), secret: await getJwtProviderAuthSecret(), diff --git a/frontend/src/components/login/PasswordInputStep.tsx b/frontend/src/components/login/PasswordInputStep.tsx index 77d9b7ae0..819f76528 100644 --- a/frontend/src/components/login/PasswordInputStep.tsx +++ b/frontend/src/components/login/PasswordInputStep.tsx @@ -33,15 +33,15 @@ export default function PasswordInputStep({ const handleLogin = async () => { try { setIsLoading(true); - const isLoginSuccessful = await attemptLogin({ + const loginAttempt = await attemptLogin({ email, password }); - if (isLoginSuccessful && isLoginSuccessful.success) { + if (loginAttempt && loginAttempt.success) { // case: login was successful - if (isLoginSuccessful.mfaEnabled) { + if (loginAttempt.mfaEnabled) { // case: login requires MFA step setStep(2); setIsLoading(false); diff --git a/frontend/src/components/signup/UserInfoStep.tsx b/frontend/src/components/signup/UserInfoStep.tsx index dc49ce02f..e62d1d3a4 100644 --- a/frontend/src/components/signup/UserInfoStep.tsx +++ b/frontend/src/components/signup/UserInfoStep.tsx @@ -167,6 +167,7 @@ export default function UserInfoStep({ // unset signup JWT token and set JWT token SecurityClient.setSignupToken(''); SecurityClient.setToken(response.token); + SecurityClient.setProviderAuthToken(''); saveTokenToLocalStorage({ publicKey, diff --git a/frontend/src/components/utilities/attemptLogin.ts b/frontend/src/components/utilities/attemptLogin.ts index 90a9876ea..c5bc39810 100644 --- a/frontend/src/components/utilities/attemptLogin.ts +++ b/frontend/src/components/utilities/attemptLogin.ts @@ -91,7 +91,9 @@ const attemptLogin = async ( token ) { // case: MFA is not enabled - + + // unset provider auth token in case it was used + SecurityClient.setProviderAuthToken(''); // set JWT token SecurityClient.setToken(token); diff --git a/frontend/src/components/utilities/attemptLoginMfa.ts b/frontend/src/components/utilities/attemptLoginMfa.ts index 58d3b2330..b7d499817 100644 --- a/frontend/src/components/utilities/attemptLoginMfa.ts +++ b/frontend/src/components/utilities/attemptLoginMfa.ts @@ -36,7 +36,10 @@ const attemptLoginMfa = async ({ }, async () => { try { const clientPublicKey = client.getPublicKey(); - const { salt } = await login1(email, clientPublicKey); + const { salt } = await login1({ + email, + clientPublicKey, + }); const { encryptionVersion, @@ -56,6 +59,7 @@ const attemptLoginMfa = async ({ // unset temporary (MFA) JWT token and set JWT token SecurityClient.setMfaToken(''); SecurityClient.setToken(token); + SecurityClient.setProviderAuthToken(''); const privateKey = await KeyService.decryptPrivateKey({ encryptionVersion, diff --git a/frontend/src/hooks/useProviderAuth.ts b/frontend/src/hooks/useProviderAuth.ts index dc380d7c1..bda90e6e6 100644 --- a/frontend/src/hooks/useProviderAuth.ts +++ b/frontend/src/hooks/useProviderAuth.ts @@ -9,14 +9,19 @@ export const useProviderAuth = () => { const [providerAuthToken, setProviderAuthToken] = useState( SecurityClient.getProviderAuthToken() || '' ); + const [isProviderUserCompleted, setIsProviderUserCompleted] = useState(); useEffect(() => { const handleStorageChange = (event: StorageEvent) => { if (event.storageArea === localStorage && event.key === PROVIDER_AUTH_TOKEN_KEY) { if (event.newValue) { const token = event.newValue; - const { userId: resultUserId, email: resultEmail } = jwt_decode(token) as any; - + const { + userId: resultUserId, + email: resultEmail, + isUserCompleted: resultIsUserCompleted, + } = jwt_decode(token) as any; + setIsProviderUserCompleted(resultIsUserCompleted); setProviderAuthToken(token); setEmail(resultEmail); setUserId(resultUserId); @@ -24,6 +29,7 @@ export const useProviderAuth = () => { setProviderAuthToken(''); setEmail(''); setUserId(''); + setIsProviderUserCompleted(false); } setProviderAuthToken(event.newValue || ''); } @@ -32,9 +38,14 @@ export const useProviderAuth = () => { window.addEventListener('storage', handleStorageChange); if (providerAuthToken) { - const { userId: resultUserId, email: resultEmail } = jwt_decode(providerAuthToken) as any; + const { + userId: resultUserId, + email: resultEmail, + isUserCompleted: resultIsUserCompleted, + } = jwt_decode(providerAuthToken) as any; setEmail(resultEmail); setUserId(resultUserId); + setIsProviderUserCompleted(resultIsUserCompleted); } return () => { @@ -44,10 +55,11 @@ export const useProviderAuth = () => { return { email, + isProviderUserCompleted, providerAuthToken, userId, - setProviderAuthToken, setEmail, + setProviderAuthToken, setUserId, }; }; diff --git a/frontend/src/pages/login.tsx b/frontend/src/pages/login.tsx index 2be66ce61..01fe98675 100644 --- a/frontend/src/pages/login.tsx +++ b/frontend/src/pages/login.tsx @@ -27,9 +27,14 @@ export default function Login() { const { providerAuthToken, email: providerEmail, - setProviderAuthToken + setProviderAuthToken, + isProviderUserCompleted, } = useProviderAuth(); + if (providerAuthToken && isProviderUserCompleted === false) { + router.push('/signup'); + } + const setLanguage = async (to: string) => { router.push('/login', '/login', { locale: to }); localStorage.setItem('lang', to); diff --git a/frontend/src/pages/signup.tsx b/frontend/src/pages/signup.tsx index 8388b763b..d47044599 100644 --- a/frontend/src/pages/signup.tsx +++ b/frontend/src/pages/signup.tsx @@ -35,7 +35,15 @@ export default function SignUp() { const { data: serverDetails } = useFetchServerStatus(); const [isSignupWithEmail, setIsSignupWithEmail] = useState(false); const { t } = useTranslation(); - const { email: providerEmail, providerAuthToken } = useProviderAuth(); + const { + email: providerEmail, + providerAuthToken, + isProviderUserCompleted, + } = useProviderAuth(); + + if (providerAuthToken && isProviderUserCompleted) { + router.push('/login'); + } if (providerAuthToken && step < 3) { setStep(3);