import { NextResponse } from "next/server"; import crypto from "crypto"; import { z } from "zod"; const requestSchema = z.object({ username: z.string().min(1, "Username is required"), }); export async function POST(request) { try { const body = await request.json(); const { username } = requestSchema.parse(body); // Import database here to avoid edge runtime issues const { default: db } = await import("@/lib/db.js"); // Check if user exists and is active const user = db .prepare("SELECT id, username, name FROM users WHERE username = ? AND is_active = 1") .get(username); if (!user) { // Don't reveal if user exists or not for security return NextResponse.json( { message: "If the username exists, a password reset link has been sent." }, { status: 200 } ); } // Generate reset token const token = crypto.randomBytes(32).toString("hex"); const expiresAt = new Date(Date.now() + 60 * 60 * 1000).toISOString(); // 1 hour // Delete any existing tokens for this user db.prepare("DELETE FROM password_reset_tokens WHERE user_id = ?").run(user.id); // Insert new token db.prepare( "INSERT INTO password_reset_tokens (user_id, token, expires_at) VALUES (?, ?, ?)" ).run(user.id, token, expiresAt); // TODO: Send email with reset link // For now, return the token for testing purposes console.log(`Password reset token for ${username}: ${token}`); // Log audit event try { const { logAuditEventSafe, AUDIT_ACTIONS, RESOURCE_TYPES } = await import("@/lib/auditLogSafe.js"); await logAuditEventSafe({ action: AUDIT_ACTIONS.PASSWORD_RESET_REQUEST, userId: user.id, resourceType: RESOURCE_TYPES.USER, details: { username: user.username }, }); } catch (auditError) { console.error("Failed to log audit event:", auditError); } return NextResponse.json( { message: "If the username exists, a password reset link has been sent." }, { status: 200 } ); } catch (error) { console.error("Password reset request error:", error); return NextResponse.json( { error: "Internal server error" }, { status: 500 } ); } }