Files
livedash-node/app/api/reset-password/route.ts
Kaj Kowalski 7f48a085bf feat: comprehensive security and architecture improvements
- Add Zod validation schemas with strong password requirements (12+ chars, complexity)
- Implement rate limiting for authentication endpoints (registration, password reset)
- Remove duplicate MetricCard component, consolidate to ui/metric-card.tsx
- Update README.md to use pnpm commands consistently
- Enhance authentication security with 12-round bcrypt hashing
- Add comprehensive input validation for all API endpoints
- Fix security vulnerabilities in user registration and password reset flows

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-06-28 01:52:53 +02:00

77 lines
1.9 KiB
TypeScript

import { NextRequest, NextResponse } from "next/server";
import { prisma } from "../../../lib/prisma";
import { resetPasswordSchema, validateInput } from "../../../lib/validation";
import bcrypt from "bcryptjs";
import crypto from "crypto";
export async function POST(request: NextRequest) {
try {
const body = await request.json();
// Validate input with strong password requirements
const validation = validateInput(resetPasswordSchema, body);
if (!validation.success) {
return NextResponse.json(
{
success: false,
error: "Validation failed",
details: validation.errors,
},
{ status: 400 }
);
}
const { token, password } = validation.data;
// Hash the token to compare with stored hash
const tokenHash = crypto.createHash("sha256").update(token).digest("hex");
const user = await prisma.user.findFirst({
where: {
resetToken: tokenHash,
resetTokenExpiry: { gte: new Date() },
},
});
if (!user) {
return NextResponse.json(
{
success: false,
error:
"Invalid or expired token. Please request a new password reset.",
},
{ status: 400 }
);
}
// Hash password with higher rounds for better security
const hashedPassword = await bcrypt.hash(password, 12);
await prisma.user.update({
where: { id: user.id },
data: {
password: hashedPassword,
resetToken: null,
resetTokenExpiry: null,
},
});
return NextResponse.json(
{
success: true,
message: "Password has been reset successfully.",
},
{ status: 200 }
);
} catch (error) {
console.error("Reset password error:", error);
return NextResponse.json(
{
success: false,
error: "An internal server error occurred. Please try again later.",
},
{ status: 500 }
);
}
}