전체 코드, 구조 검토 - P2 코드 수정 진행

This commit is contained in:
2026-07-04 15:59:50 +09:00
parent 2231ac4bfe
commit 0a9aee58e0
9 changed files with 83 additions and 25 deletions
+36 -1
View File
@@ -7,6 +7,32 @@ import { logger } from "@/lib/logger";
const AUTH_CTX = "auth";
type AttemptRecord = { count: number; until: number };
const loginAttempts = new Map<string, AttemptRecord>();
const MAX_ATTEMPTS = 5;
const LOCKOUT_MS = 15 * 60 * 1000;
function isLockedOut(adminName: string): boolean {
const record = loginAttempts.get(adminName);
if (!record || record.count < MAX_ATTEMPTS) return false;
if (record.until > Date.now()) return true;
loginAttempts.delete(adminName);
return false;
}
function recordFailure(adminName: string): void {
const record = loginAttempts.get(adminName) ?? { count: 0, until: 0 };
record.count += 1;
if (record.count >= MAX_ATTEMPTS) {
record.until = Date.now() + LOCKOUT_MS;
}
loginAttempts.set(adminName, record);
}
function clearAttempts(adminName: string): void {
loginAttempts.delete(adminName);
}
const credentialsSchema = z.object({
adminName: z.string().trim().min(1),
password: z.string().min(1),
@@ -53,6 +79,7 @@ export const {
},
session: {
strategy: "jwt",
maxAge: 8 * 60 * 60,
},
providers: [
Credentials({
@@ -67,8 +94,14 @@ export const {
return null;
}
const { db } = await import("@/lib/db");
const { adminName, password } = parsedCredentials.data;
if (isLockedOut(adminName)) {
logger.warn(AUTH_CTX, "login blocked (rate limit)", { adminName });
return null;
}
const { db } = await import("@/lib/db");
const admins = await db.$queryRaw<AdminAuthRow[]>`
SELECT AdminID, Name, Email, AccountType, ActivateStatus
FROM admin
@@ -81,10 +114,12 @@ export const {
const activateStatus = Number(admin?.ActivateStatus);
if (!admin || activateStatus === ACTIVATE_STATUSES.PENDING) {
recordFailure(adminName);
logger.warn(AUTH_CTX, "login failed", { adminName });
return null;
}
clearAttempts(adminName);
logger.info(AUTH_CTX, "login success", { adminName, adminID });
return {
id: String(adminID),