mirror of
https://github.com/awatertrevi/infisical.git
synced 2026-09-22 13:39:35 +00:00
feat: integration user lock flow to frontend
This commit is contained in:
@@ -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`);
|
||||
}
|
||||
|
||||
@@ -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.`
|
||||
});
|
||||
|
||||
@@ -38,7 +38,7 @@ export const processFailedMfaAttempt = async (userId: string, userDAL: Pick<TUse
|
||||
const progressiveDelaysInMins = [5, 30, 60];
|
||||
|
||||
// lock user when failed attempt exceeds threshold
|
||||
if (user.consecutiveFailedMfaAttempts > PROGRESSIVE_DELAY_INTERVAL * progressiveDelaysInMins.length) {
|
||||
if (user.consecutiveFailedMfaAttempts >= PROGRESSIVE_DELAY_INTERVAL * (progressiveDelaysInMins.length + 1)) {
|
||||
return (
|
||||
await tx(TableName.Users)
|
||||
.where("id", userId)
|
||||
|
||||
@@ -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.",
|
||||
|
||||
@@ -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);
|
||||
|
||||
Reference in New Issue
Block a user