Initial import of AbelBirdNest Stock

This commit is contained in:
2026-05-16 18:25:51 +07:00
commit 14bb9bf744
472 changed files with 70671 additions and 0 deletions

View File

@ -0,0 +1,84 @@
import { NextResponse } from "next/server";
import { z } from "zod";
import { createAuditTrailSafe } from "@/lib/audit-trail";
import { hashPassword, verifyPassword } from "@/lib/auth";
import { requireApiAccess } from "@/lib/authorization";
import { prisma } from "@/lib/prisma";
const changePasswordSchema = z
.object({
current_password: z.string().min(1, "Password saat ini wajib diisi"),
password: z.string().min(8, "Password baru minimal 8 karakter"),
password_confirmation: z.string().min(8, "Konfirmasi password minimal 8 karakter")
})
.refine((value) => value.password === value.password_confirmation, {
message: "Konfirmasi password tidak sama",
path: ["password_confirmation"]
});
export async function POST(request: Request) {
const auth = requireApiAccess(request);
if (!auth.ok) return auth.response;
try {
const body = await request.json();
const parsed = changePasswordSchema.safeParse(body);
if (!parsed.success) {
return NextResponse.json(
{
message: "Validasi gagal",
errors: parsed.error.flatten().fieldErrors
},
{ status: 422 }
);
}
const user = await prisma.user.findUnique({
where: { id: BigInt(auth.user.id) }
});
if (!user || !user.passwordHash) {
return NextResponse.json({ message: "User tidak ditemukan" }, { status: 404 });
}
if (!verifyPassword(parsed.data.current_password, user.passwordHash)) {
return NextResponse.json(
{
message: "Password saat ini tidak valid"
},
{ status: 422 }
);
}
await prisma.user.update({
where: { id: user.id },
data: {
passwordHash: hashPassword(parsed.data.password)
}
});
await createAuditTrailSafe({
userId: user.id,
action: "PASSWORD_CHANGED",
entityType: "AUTH",
entityId: user.id,
method: request.method,
pathname: new URL(request.url).pathname,
statusCode: 200,
summary: "User mengganti password akun sendiri"
});
return NextResponse.json({
message: "Password berhasil diperbarui"
});
} catch (error) {
return NextResponse.json(
{
message: error instanceof Error ? error.message : "Gagal mengganti password"
},
{ status: 500 }
);
}
}