Files
Lageplan/src/app/api/auth/forgot-password/route.ts

74 lines
3.2 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import { NextRequest, NextResponse } from 'next/server'
import { prisma } from '@/lib/db'
import { randomBytes } from 'crypto'
import { sendEmail, getSmtpConfig } from '@/lib/email'
export async function POST(req: NextRequest) {
try {
const { email } = await req.json()
if (!email) {
return NextResponse.json({ error: 'E-Mail erforderlich' }, { status: 400 })
}
const user = await (prisma as any).user.findUnique({ where: { email } })
// Always return success to prevent email enumeration
if (!user) {
return NextResponse.json({ success: true, message: 'Falls ein Konto mit dieser E-Mail existiert, wurde ein Link gesendet.' })
}
// Generate reset token (32 bytes hex = 64 chars)
const resetToken = randomBytes(32).toString('hex')
const resetTokenExpiry = new Date(Date.now() + 60 * 60 * 1000) // 1 hour
await (prisma as any).user.update({
where: { id: user.id },
data: { resetToken, resetTokenExpiry },
})
// Try to send email
const smtpConfig = await getSmtpConfig()
const host = req.headers.get('host') || 'localhost:3000'
const protocol = host.includes('localhost') ? 'http' : 'https'
const resetUrl = `${protocol}://${host}/reset-password?token=${resetToken}`
if (smtpConfig) {
try {
await sendEmail(
user.email,
'Passwort zurücksetzen Lageplan',
`
<div style="font-family: sans-serif; max-width: 500px; margin: 0 auto;">
<h2 style="color: #dc2626;">Passwort zurücksetzen</h2>
<p>Hallo ${user.name},</p>
<p>Sie haben eine Passwort-Zurücksetzung angefordert. Klicken Sie auf den folgenden Link:</p>
<p style="margin: 24px 0;">
<a href="${resetUrl}" style="background: #dc2626; color: white; padding: 12px 24px; border-radius: 6px; text-decoration: none; font-weight: bold;">
Passwort zurücksetzen
</a>
</p>
<p style="color: #666; font-size: 14px;">Dieser Link ist 1 Stunde gültig.</p>
<p style="color: #666; font-size: 14px;">Falls Sie diese Anfrage nicht gestellt haben, ignorieren Sie diese E-Mail.</p>
<hr style="border: none; border-top: 1px solid #eee; margin: 24px 0;" />
<p style="color: #999; font-size: 12px;">Lageplan Feuerwehr Krokier-App</p>
</div>
`
)
return NextResponse.json({ success: true, message: 'Falls ein Konto mit dieser E-Mail existiert, wurde ein Link gesendet.' })
} catch (emailErr) {
console.error('Failed to send reset email:', emailErr)
// Fall through to show token directly
}
}
// No SMTP configured or email failed → log token server-side only, never expose to client
console.log(`[Password Reset] No SMTP configured. Reset URL: ${resetUrl}`)
return NextResponse.json({
success: true,
message: 'Falls ein Konto mit dieser E-Mail existiert, wurde ein Link gesendet. (SMTP nicht konfiguriert — siehe Server-Logs)',
})
} catch (error) {
console.error('Forgot password error:', error)
return NextResponse.json({ error: 'Serverfehler' }, { status: 500 })
}
}