diff --git a/backend/src/server/routes/v1/user-router.ts b/backend/src/server/routes/v1/user-router.ts index aa3962c5a..0253ac86b 100644 --- a/backend/src/server/routes/v1/user-router.ts +++ b/backend/src/server/routes/v1/user-router.ts @@ -49,6 +49,7 @@ export const registerUserRouter = async (server: FastifyZodProvider) => { await server.services.user.unlockUser(req.params.userId, req.query.token); } catch (err) { logger.error(`User unlock failed for ${req.params.userId}`); + logger.error(err); } return res.redirect(`${appCfg.SITE_URL}/login`); } diff --git a/backend/src/services/auth/auth-fns.ts b/backend/src/services/auth/auth-fns.ts index 4911cc258..036d9068e 100644 --- a/backend/src/services/auth/auth-fns.ts +++ b/backend/src/services/auth/auth-fns.ts @@ -59,7 +59,7 @@ export const enforceUserLockStatus = (isLocked: boolean, temporaryLockDateEnd?: if (timeDiff < 0) throw new UnauthorizedError({ name: "User Locked", - message: `User is locked due to multiple failed login attempts. Try logging in again after ${Math.round( + message: `User is locked due to multiple failed login attempts. Try again after ${Math.round( (-1 * timeDiff) / 1000 )} seconds.` }); diff --git a/backend/src/services/user/user-fns.ts b/backend/src/services/user/user-fns.ts index 2750bb87e..e8a0905f8 100644 --- a/backend/src/services/user/user-fns.ts +++ b/backend/src/services/user/user-fns.ts @@ -38,7 +38,7 @@ export const processFailedMfaAttempt = async (userId: string, userDAL: Pick PROGRESSIVE_DELAY_INTERVAL * progressiveDelaysInMins.length) { + if (user.consecutiveFailedMfaAttempts >= PROGRESSIVE_DELAY_INTERVAL * (progressiveDelaysInMins.length + 1)) { return ( await tx(TableName.Users) .where("id", userId) diff --git a/frontend/src/views/Login/components/InitialStep/InitialStep.tsx b/frontend/src/views/Login/components/InitialStep/InitialStep.tsx index f3b40300e..a4e5e89f5 100644 --- a/frontend/src/views/Login/components/InitialStep/InitialStep.tsx +++ b/frontend/src/views/Login/components/InitialStep/InitialStep.tsx @@ -105,8 +105,18 @@ export const InitialStep = ({ setStep, email, setEmail, password, setPassword }: }); } } - } catch (err) { + } catch (err: any) { console.error(err); + if (err.response.data.error === "User Locked") { + createNotification({ + title: err.response.data.error, + text: err.response.data.message, + type: "error" + }); + setIsLoading(false); + return; + } + setLoginError(true); createNotification({ text: "Login unsuccessful. Double-check your credentials and try again.", diff --git a/frontend/src/views/Login/components/MFAStep/MFAStep.tsx b/frontend/src/views/Login/components/MFAStep/MFAStep.tsx index eaaac88a9..249c043b6 100644 --- a/frontend/src/views/Login/components/MFAStep/MFAStep.tsx +++ b/frontend/src/views/Login/components/MFAStep/MFAStep.tsx @@ -46,20 +46,7 @@ type Props = { callbackPort?: string | null; }; -interface VerifyMfaTokenError { - response: { - data: { - context: { - code: string; - triesLeft: number; - }; - }; - status: number; - }; -} - export const MFAStep = ({ email, password, providerAuthToken }: Props) => { - const router = useRouter(); const [isLoading, setIsLoading] = useState(false); const [isLoadingResend, setIsLoadingResend] = useState(false); @@ -178,20 +165,31 @@ export const MFAStep = ({ email, password, providerAuthToken }: Props) => { }); } } - } catch (err) { - const error = err as VerifyMfaTokenError; + } catch (err: any) { + if (err.response.data.error === "User Locked") { + createNotification({ + title: err.response.data.error, + text: err.response.data.message, + type: "error" + }); + setIsLoading(false); + return; + } + createNotification({ text: "Failed to log in", type: "error" }); - if (error?.response?.status === 500) { - window.location.reload(); - } else if (error?.response?.data?.context?.triesLeft) { - setTriesLeft(error?.response?.data?.context?.triesLeft); - if (error.response.data.context.triesLeft === 0) { - window.location.reload(); - } + if (triesLeft) { + setTriesLeft((left) => { + if (triesLeft === 1) { + window.location.reload(); + } + return (left as number) - 1; + }); + } else { + setTriesLeft(2); } setIsLoading(false);