Initial commit
This commit is contained in:
64
app/api/auth/change-password/route.ts
Normal file
64
app/api/auth/change-password/route.ts
Normal file
@@ -0,0 +1,64 @@
|
||||
import { NextRequest } from "next/server";
|
||||
import { z } from "zod";
|
||||
import { getSession } from "../../../../lib/auth/session";
|
||||
import { getPrisma } from "../../../../lib/db";
|
||||
import { hashPassword, verifyPassword } from "../../../../lib/auth/password";
|
||||
import { isStrongPassword } from "../../../../lib/auth/validation";
|
||||
import { ok, fail } from "../../../../lib/http";
|
||||
|
||||
export const runtime = "nodejs";
|
||||
|
||||
const Body = z.object({
|
||||
currentPassword: z.string().min(1),
|
||||
newPassword: z.string().min(8),
|
||||
confirmPassword: z.string().min(8),
|
||||
});
|
||||
|
||||
export async function POST(req: NextRequest) {
|
||||
const session = await getSession();
|
||||
if (!session) return fail(new Error("Unauthorized"), { status: 401 });
|
||||
|
||||
const prisma = await getPrisma();
|
||||
if (!prisma) return fail(new Error("Database not configured"), { status: 503, isAdmin: session.role === "ADMIN" });
|
||||
|
||||
const parsed = Body.safeParse(await req.json().catch(() => ({})));
|
||||
if (!parsed.success) return fail(new Error("Invalid input"));
|
||||
|
||||
const user = await prisma.user.findUnique({
|
||||
where: { id: session.sub },
|
||||
include: { credential: true }
|
||||
});
|
||||
if (!user || !user.credential) return fail(new Error("Invalid user or no password set"));
|
||||
|
||||
if (parsed.data.newPassword !== parsed.data.confirmPassword) {
|
||||
return fail(new Error("Passwords do not match"));
|
||||
}
|
||||
if (!isStrongPassword(parsed.data.newPassword)) {
|
||||
return fail(new Error("Password is not strong enough"));
|
||||
}
|
||||
|
||||
// 🔥 Only verify current password if NOT forced reset
|
||||
if (!user.forcePasswordReset) {
|
||||
const okPw = await verifyPassword(
|
||||
parsed.data.currentPassword,
|
||||
user.credential.password
|
||||
);
|
||||
if (!okPw) return fail(new Error("Invalid password"));
|
||||
}
|
||||
|
||||
const newHash = await hashPassword(parsed.data.newPassword);
|
||||
await prisma.credential.update({
|
||||
where: { userId: user.id },
|
||||
data: { password: newHash },
|
||||
});
|
||||
|
||||
// Clear force password reset flag if it was set
|
||||
if (user.forcePasswordReset) {
|
||||
await prisma.user.update({
|
||||
where: { id: user.id },
|
||||
data: { forcePasswordReset: false },
|
||||
});
|
||||
}
|
||||
|
||||
return ok({ message: "Password updated" });
|
||||
}
|
||||
Reference in New Issue
Block a user