Documentation Index
Fetch the complete documentation index at: https://docs.nullpass.xyz/llms.txt
Use this file to discover all available pages before exploring further.
Endpoint
Overview
Changes the authenticated user’s password. Requires the current password for verification. Password is hashed with bcrypt before storage.
Request
Current password for verification
New password. Minimum 8 characters.
Response
“Password changed successfully”
Implementation Details
Process Flow
- Authentication: Verifies user is authenticated
- Current Password Check: Compares provided password with stored hash
- Password Hashing: Hashes new password with bcrypt (10 rounds)
- Update: Updates password hash in database
- Audit Logging: Logs
PASSWORD_CHANGE event
Code Reference
export async function POST(request: NextRequest) {
const corsResponse = handleCors(request)
if (corsResponse) return corsResponse
const blocked = await protectRoute(request, { requested: 2 })
if (blocked) return blocked
const auth = await requireAuth(request)
if ('error' in auth) return auth.error
try {
const body = await request.json()
const validated = changePasswordSchema.parse(body)
const user = await prisma.user.findUnique({
where: { id: auth.userId },
select: {
id: true,
passwordHash: true,
},
})
if (!user || !user.passwordHash) {
return errorResponse('User not found', 404, request.headers.get('origin'))
}
const isValid = await bcrypt.compare(validated.currentPassword, user.passwordHash)
if (!isValid) {
logger.warn('Password change failed: Invalid current password', auth.userId)
return errorResponse('Invalid current password', 401, request.headers.get('origin'))
}
const newPasswordHash = await bcrypt.hash(validated.newPassword, 10)
await prisma.user.update({
where: { id: auth.userId },
data: {
passwordHash: newPasswordHash,
},
})
await createAuditLog(auth.userId, 'PASSWORD_CHANGE', {})
return jsonResponse({ success: true, message: 'Password changed successfully' }, 200, request.headers.get('origin'))
} catch (error: any) {
if (error.name === 'ZodError') {
logger.warn('Password change validation error:', error.errors)
return errorResponse(error.errors[0].message, 400, request.headers.get('origin'))
}
logger.error('Change password error:', error)
return errorResponse('Internal server error', 500, request.headers.get('origin'))
}
}
Status Codes
Password changed successfully
Validation error (new password too short, etc.)
Invalid current password or missing authentication
Example Request
curl -X POST https://auth.nullpass.xyz/api/auth/password \
-H "Authorization: Bearer YOUR_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"currentPassword": "oldpassword123",
"newPassword": "newsecurepassword456"
}'
Example Response
{
"success": true,
"message": "Password changed successfully"
}
Security Considerations
- Current password must be verified before change
- New password is hashed with bcrypt (10 rounds)
- Rate limiting applied (2 requests per bucket)
- All password changes are logged in audit trail
- Old password hash is completely replaced (no history kept)
Audit Events
- PASSWORD_CHANGE: Password successfully changed
Bearer authentication header of the form Bearer <token>, where <token> is your auth token.
Required if 2FA is enabled
Password changed successfully