When an admin manually unlocks an account, both the account-level lockout and all IP-based rate limits for the login endpoint are now cleared. This ensures legitimate users can immediately attempt to login after being unlocked, without being blocked by stale rate limit cache entries. Changes: - Added clearAllRateLimitsForEndpoint() function to database utils - Modified unlock endpoint to clear login rate limits after unlocking - Updated success message to reflect rate limit clearing - Enhanced logging to track rate limit clearing operations Fixes issue where users would see "Too many login attempts" message even with correct credentials after admin unlock, due to persistent IP rate limit cache from previous failed attempts. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
63 lines
1.8 KiB
TypeScript
63 lines
1.8 KiB
TypeScript
import { unlockAccount, getUserByUsername, getDatabase, clearAllRateLimitsForEndpoint } from '~/server/utils/database'
|
|
import { getSessionUsername } from '~/server/utils/auth'
|
|
|
|
export default defineEventHandler(async (event) => {
|
|
const username = await getSessionUsername(event)
|
|
|
|
if (!username) {
|
|
throw createError({
|
|
statusCode: 401,
|
|
message: 'Unauthorized'
|
|
})
|
|
}
|
|
|
|
const user = getUserByUsername(username)
|
|
|
|
if (!user || user.is_admin !== 1) {
|
|
throw createError({
|
|
statusCode: 403,
|
|
message: 'Forbidden - Admin access required'
|
|
})
|
|
}
|
|
|
|
const id = parseInt(event.context.params?.id || '')
|
|
|
|
if (isNaN(id)) {
|
|
throw createError({
|
|
statusCode: 400,
|
|
message: 'Invalid user ID'
|
|
})
|
|
}
|
|
|
|
// Get target user info
|
|
const db = getDatabase()
|
|
const targetUser = db.prepare('SELECT username, failed_login_attempts, locked_until FROM users WHERE id = ?')
|
|
.get(id) as { username: string, failed_login_attempts: number, locked_until: string | null } | undefined
|
|
|
|
if (!targetUser) {
|
|
throw createError({
|
|
statusCode: 404,
|
|
message: 'User not found'
|
|
})
|
|
}
|
|
|
|
// Unlock the account (resets account-level lockout)
|
|
unlockAccount(id)
|
|
|
|
// Clear ALL IP-based rate limits for the login endpoint
|
|
// This ensures the user can immediately attempt to login without being blocked by stale rate limits
|
|
clearAllRateLimitsForEndpoint('login')
|
|
|
|
console.log(`[ACCOUNT UNLOCKED] Admin ${username} unlocked account: ${targetUser.username} and cleared all login rate limits`)
|
|
|
|
return {
|
|
success: true,
|
|
message: `Account unlocked successfully. Failed attempts and rate limits have been reset.`,
|
|
user: {
|
|
username: targetUser.username,
|
|
previousAttempts: targetUser.failed_login_attempts,
|
|
wasLocked: !!targetUser.locked_until
|
|
}
|
|
}
|
|
})
|