Skip to content

Commit 05129ef

Browse files
authored
fix: handle expired otps when used by user (#448)
1 parent d8c3be9 commit 05129ef

File tree

3 files changed

+20
-12
lines changed

3 files changed

+20
-12
lines changed

docker/otp-provider/src/controllers/auth-controller.ts

Lines changed: 14 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -104,23 +104,29 @@ export const login = async (oidcProvider: Provider) => {
104104
let validatedOtp = { verified: false, attemptsLeft: 0 };
105105
const { email, otp } = req.body;
106106

107+
let disableResend = 'false';
108+
107109
validatedOtp = await validateOtp(otp, email);
108110

109111
const canRequest = await canRequestOtp(email);
110112

111113
if (canRequest) time = await secondsRemainingToRequestNewOtp(email);
112114

113115
if (!validatedOtp.verified) {
116+
const otpRenderParams = {
117+
uid,
118+
email,
119+
error,
120+
nonce: res.locals.cspNonce,
121+
waitTime: time,
122+
disableResend,
123+
};
114124
if (validatedOtp.attemptsLeft > 0) {
115125
error = `Invalid OTP, you have ${validatedOtp.attemptsLeft} attempts left.`;
116-
return res.render('otp', {
117-
uid,
118-
email,
119-
error,
120-
nonce: res.locals.cspNonce,
121-
waitTime: time,
122-
disableResend: 'false',
123-
});
126+
return res.render('otp', { ...otpRenderParams, error });
127+
} else if (validatedOtp.attemptsLeft === 0 && (await canRequestOtp(email))) {
128+
error = errors.EXPIRED_OTP_WITH_RESEND;
129+
return res.render('otp', { ...otpRenderParams, error });
124130
} else {
125131
result = {
126132
error: 'Invalid or expired OTP',

docker/otp-provider/src/modules/errors.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,4 +2,5 @@ export const errors = {
22
OTPS_LIMIT_REACHED: 'You have reached the maximum number of OTP requests for today. Please try again tomorrow.',
33
EMAIL_REQUIRED: 'Email is required.',
44
INVALID_EMAIL: 'Invalid email.',
5+
EXPIRED_OTP_WITH_RESEND: 'Your OTP has expired. Please request a new one to continue.',
56
};

docker/otp-provider/src/services/otp.ts

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -31,10 +31,11 @@ export const requestNewOtp = async (email: string) => {
3131

3232
export const validateOtp = async (otp: string, email: string) => {
3333
const activeOtp = await getActiveOtp(email);
34-
const otpExpired =
35-
new Date().getTime() - new Date(activeOtp.createdAt).getTime() > Number(OTP_VALIDITY_MINUTES) * 60 * 1000;
36-
if (!activeOtp || activeOtp.otp !== otp || activeOtp.attempts > Number(OTP_ATTEMPTS_ALLOWED) || otpExpired) {
37-
await updateOtpAttempts(activeOtp.otp, email, activeOtp.attempts + 1);
34+
if (!activeOtp) {
35+
return { verified: false, attemptsLeft: 0 };
36+
} else if (activeOtp.otp !== otp || activeOtp.attempts === Number(OTP_ATTEMPTS_ALLOWED)) {
37+
if (activeOtp.attempts < Number(OTP_ATTEMPTS_ALLOWED))
38+
await updateOtpAttempts(activeOtp.otp, email, activeOtp.attempts + 1);
3839
return { verified: false, attemptsLeft: Number(OTP_ATTEMPTS_ALLOWED) - (activeOtp.attempts + 1) };
3940
}
4041
await deleteOtpsByEmail(email);

0 commit comments

Comments
 (0)