Files
dticket.tootaio.com/server/api/auth/change-password.post.ts
xiaomai 377a9617be feat: implement auth system, passkeys, and user management
Add PostgreSQL and Redis integration for users and sessions
Implement password and WebAuthn passkey login flows
Add Docker stack, super-admin seeding, and protected routes
2026-04-12 20:16:43 +08:00

61 lines
1.6 KiB
TypeScript

import { MIN_PASSWORD_LENGTH } from '~~/shared/auth'
import { requireAuth } from '../../utils/auth'
import { hashPassword, verifyPassword } from '../../utils/password'
import { getUserById, updateUserPassword } from '../../utils/user-repository'
export default defineEventHandler(async (event) => {
const auth = await requireAuth(event)
const body = await readBody<{
currentPassword?: string
newPassword?: string
}>(event)
const currentPassword = body.currentPassword?.trim() || ''
const newPassword = body.newPassword?.trim() || ''
if (!currentPassword || !newPassword) {
throw createError({
statusCode: 400,
statusMessage: 'Current password and new password are required'
})
}
if (newPassword.length < MIN_PASSWORD_LENGTH) {
throw createError({
statusCode: 400,
statusMessage: `New password must be at least ${MIN_PASSWORD_LENGTH} characters`
})
}
if (currentPassword === newPassword) {
throw createError({
statusCode: 400,
statusMessage: 'New password must be different from the current password'
})
}
const currentPasswordMatches = await verifyPassword(currentPassword, auth.user.passwordHash)
if (!currentPasswordMatches) {
throw createError({
statusCode: 400,
statusMessage: 'Current password is incorrect'
})
}
const passwordHash = await hashPassword(newPassword)
await updateUserPassword({
userId: auth.user.id,
passwordHash,
mustChangePassword: false
})
const updatedUser = await getUserById(auth.user.id)
return {
user: updatedUser
}
})