export const dynamic = 'force-dynamic' import { NextRequest, NextResponse } from 'next/server' import { asAdmin } from '@/lib/db/with-user' import { users, passwordResetTokens } from '@/lib/db/schema' import { eq } from 'drizzle-orm' import { createHash, randomBytes } from 'crypto' import { sendPasswordResetEmail } from '@/lib/notifications/mailer' export async function POST(req: NextRequest) { const { email } = await req.json() if (!email) return NextResponse.json({ ok: true }) // don't reveal user existence const [user] = await asAdmin(db => db.select({ id: users.id, name: users.name }).from(users) .where(eq(users.email, email.toLowerCase())).limit(1) ) if (!user) return NextResponse.json({ ok: true }) // silent const rawToken = randomBytes(32).toString('hex') const tokenHash = createHash('sha256').update(rawToken).digest('hex') const expiresAt = new Date(Date.now() + 60 * 60 * 1000) // 1 hour await asAdmin(db => db.insert(passwordResetTokens).values({ userId: user.id, tokenHash, expiresAt, })) const appUrl = process.env.APP_URL ?? '' const resetLink = `${appUrl}/reset-password?token=${rawToken}` await sendPasswordResetEmail({ to: email, name: user.name, resetLink }) return NextResponse.json({ ok: true }) }