Forgot password implementierung

This commit is contained in:
Timo Knuth
2025-11-18 19:21:29 +01:00
parent 8ecd58b176
commit 424c61a176
11 changed files with 758 additions and 30 deletions

104
src/lib/email.ts Normal file
View File

@@ -0,0 +1,104 @@
import { Resend } from 'resend';
const resend = new Resend(process.env.RESEND_API_KEY);
export async function sendPasswordResetEmail(email: string, resetToken: string) {
const appUrl = process.env.NEXT_PUBLIC_APP_URL || 'http://localhost:3050';
const resetUrl = `${appUrl}/reset-password?token=${resetToken}`;
try {
await resend.emails.send({
from: 'QR Master <onboarding@resend.dev>', // Use Resend's testing domain
to: email,
subject: 'Reset Your Password - QR Master',
html: `
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Reset Your Password</title>
</head>
<body style="margin: 0; padding: 0; font-family: Arial, sans-serif; background-color: #f4f4f4;">
<table width="100%" cellpadding="0" cellspacing="0" style="background-color: #f4f4f4; padding: 20px 0;">
<tr>
<td align="center">
<table width="600" cellpadding="0" cellspacing="0" style="background-color: #ffffff; border-radius: 8px; overflow: hidden; box-shadow: 0 2px 8px rgba(0,0,0,0.1);">
<!-- Header -->
<tr>
<td style="background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); padding: 40px 30px; text-align: center;">
<h1 style="margin: 0; color: #ffffff; font-size: 28px; font-weight: bold;">QR Master</h1>
</td>
</tr>
<!-- Content -->
<tr>
<td style="padding: 40px 30px;">
<h2 style="margin: 0 0 20px 0; color: #333333; font-size: 24px;">Reset Your Password</h2>
<p style="margin: 0 0 20px 0; color: #666666; font-size: 16px; line-height: 1.5;">
Hi there,
</p>
<p style="margin: 0 0 30px 0; color: #666666; font-size: 16px; line-height: 1.5;">
You requested to reset your password for your QR Master account. Click the button below to choose a new password:
</p>
<!-- Button -->
<table width="100%" cellpadding="0" cellspacing="0">
<tr>
<td align="center" style="padding: 20px 0;">
<a href="${resetUrl}" style="background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); color: #ffffff; text-decoration: none; padding: 16px 40px; border-radius: 6px; font-size: 16px; font-weight: bold; display: inline-block;">
Reset Password
</a>
</td>
</tr>
</table>
<p style="margin: 30px 0 20px 0; color: #666666; font-size: 14px; line-height: 1.5;">
Or copy and paste this link into your browser:
</p>
<p style="margin: 0 0 30px 0; padding: 15px; background-color: #f8f8f8; border-radius: 4px; word-break: break-all;">
<a href="${resetUrl}" style="color: #667eea; text-decoration: none; font-size: 14px;">${resetUrl}</a>
</p>
<div style="border-top: 1px solid #eeeeee; padding-top: 20px; margin-top: 30px;">
<p style="margin: 0 0 10px 0; color: #999999; font-size: 13px; line-height: 1.5;">
<strong>This link will expire in 1 hour.</strong>
</p>
<p style="margin: 0; color: #999999; font-size: 13px; line-height: 1.5;">
If you didn't request a password reset, you can safely ignore this email. Your password will not be changed.
</p>
</div>
</td>
</tr>
<!-- Footer -->
<tr>
<td style="background-color: #f8f8f8; padding: 30px; text-align: center; border-top: 1px solid #eeeeee;">
<p style="margin: 0 0 10px 0; color: #999999; font-size: 12px;">
© 2025 QR Master. All rights reserved.
</p>
<p style="margin: 0; color: #999999; font-size: 12px;">
This is an automated email. Please do not reply.
</p>
</td>
</tr>
</table>
</td>
</tr>
</table>
</body>
</html>
`,
});
console.log('Password reset email sent successfully to:', email);
return { success: true };
} catch (error) {
console.error('Error sending password reset email:', error);
throw new Error('Failed to send password reset email');
}
}