import { z } from 'zod' import { getUserByUsername, verifyPassword, resetLoginAttempts, updateLastLogin, incrementLoginAttempts, validatePassword } from '../../modules/auth/user' import { createToken } from '../../modules/oauth' import { generateAccessToken, generateRefreshToken } from '../../utils/jwt' const loginSchema = z.object({ username: z.string().min(1, '用户名不能为空'), password: z.string().min(1, '密码不能为空') }) export default defineEventHandler(async (event) => { const body = await readBody(event) const result = loginSchema.safeParse(body) if (!result.success) { throw createError({ statusCode: 400, message: result.error.errors[0].message }) } const { username, password } = result.data const user = getUserByUsername(username) if (!user) { throw createError({ statusCode: 401, message: '用户名或密码错误' }) } if (user.status !== 'active') { throw createError({ statusCode: 403, message: '账户已被禁用' }) } if (user.locked_until && new Date(user.locked_until) > new Date()) { throw createError({ statusCode: 423, message: `账户已被锁定,请于 ${new Date(user.locked_until).toLocaleString()} 后重试` }) } if (!verifyPassword(password, user.password_hash!)) { incrementLoginAttempts(user.id) const attempts = (user.login_attempts || 0) + 1 if (attempts >= 5) { const lockedUntil = new Date(Date.now() + 30 * 60 * 1000) incrementLoginAttempts(user.id, lockedUntil) throw createError({ statusCode: 423, message: '密码错误次数过多,账户已被锁定30分钟' }) } throw createError({ statusCode: 401, message: `用户名或密码错误(剩余${5 - attempts}次)` }) } resetLoginAttempts(user.id) updateLastLogin(user.id) const payload = { sub: user.username, userId: user.id, username: user.username, role: user.role_name!, permissions: user.permissions || [] } const { accessToken, refreshToken } = createToken(user.id, 'system') const jwtAccessToken = generateAccessToken(payload) const jwtRefreshToken = generateRefreshToken(payload) return { success: true, data: { accessToken: jwtAccessToken, refreshToken: jwtRefreshToken, expiresIn: 7 * 24 * 60 * 60, tokenType: 'Bearer', user: { id: user.id, username: user.username, email: user.email, realName: user.real_name, avatar: user.avatar, role: user.role_name, permissions: user.permissions } } } })