Skip to content

Commit c651aeb

Browse files
committed
feat: implement OTP request blocking for existing valid OTPs in UsersService
1 parent f44908c commit c651aeb

File tree

1 file changed

+26
-0
lines changed

1 file changed

+26
-0
lines changed

src/services/identity/UsersService.ts

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -212,6 +212,32 @@ class UsersService {
212212

213213
async sendEmailOtp(email: string) {
214214
const normalizedEmail = email.toLowerCase()
215+
216+
// Check if there's already a valid OTP for this email
217+
// This prevents creating new OTPs while a valid one exists, mitigating
218+
// the attack vector where an attacker spam OTP requests
219+
// to prevent the user from logging in
220+
const existingOtp = await this.otpRepository.findOne({
221+
where: {
222+
email: normalizedEmail,
223+
hashedOtp: {
224+
[Op.regexp]: "\\S+", // at least one non-whitespace character (i.e. is truthy!)
225+
},
226+
},
227+
})
228+
if (existingOtp && existingOtp.expiresAt >= new Date()) {
229+
logger.info({
230+
message: "OTP request blocked: valid OTP already exists",
231+
meta: {
232+
email: normalizedEmail,
233+
expiresAt: existingOtp.expiresAt,
234+
},
235+
})
236+
// Return silently to avoid revealing whether an OTP exists
237+
// This maintains security by not leaking information about existing OTPs
238+
return
239+
}
240+
215241
const { otp, hashedOtp } = await this.otpService.generateLoginOtpWithHash()
216242

217243
// Reset attempts to login

0 commit comments

Comments
 (0)