diff --git a/server/api/auth/login.post.ts b/server/api/auth/login.post.ts index 7ecda42..e047eb7 100644 --- a/server/api/auth/login.post.ts +++ b/server/api/auth/login.post.ts @@ -22,14 +22,6 @@ export default defineEventHandler(async (event) => { 'cf-connecting-ip': cfConnectingIp, 'getRequestIP': getRequestIP(event) }) - - // Check rate limit: 5 attempts per 15 minutes - if (!checkRateLimit(clientIp, 'login', 5, 15)) { - throw createError({ - statusCode: 429, - message: 'Too many login attempts. Please try again in 15 minutes.' - }) - } const body = await readBody(event) const { username, password } = body @@ -44,6 +36,14 @@ export default defineEventHandler(async (event) => { const user = getUserByUsername(username.toLowerCase()) if (!user) { + // Check rate limit ONLY on failed attempt + if (!checkRateLimit(clientIp, 'login', 5, 15)) { + console.log(`[LOGIN BLOCKED] Rate limited - Username not found: ${username.toLowerCase()}, IP: ${clientIp}`) + throw createError({ + statusCode: 429, + message: 'Too many login attempts. Please try again in 15 minutes.' + }) + } console.log(`[LOGIN FAILED] Username not found: ${username.toLowerCase()}, IP: ${clientIp}`) throw createError({ statusCode: 401, @@ -55,6 +55,14 @@ export default defineEventHandler(async (event) => { const passwordMatch = await bcrypt.compare(password, user.password) if (!passwordMatch) { + // Check rate limit ONLY on failed attempt + if (!checkRateLimit(clientIp, 'login', 5, 15)) { + console.log(`[LOGIN BLOCKED] Rate limited - Invalid password for user: ${username.toLowerCase()}, IP: ${clientIp}`) + throw createError({ + statusCode: 429, + message: 'Too many login attempts. Please try again in 15 minutes.' + }) + } console.log(`[LOGIN FAILED] Invalid password for user: ${username.toLowerCase()}, IP: ${clientIp}`) throw createError({ statusCode: 401,