整合資料庫、完成登入註冊忘記密碼功能
This commit is contained in:
101
lib/services/email-service.ts
Normal file
101
lib/services/email-service.ts
Normal file
@@ -0,0 +1,101 @@
|
||||
// =====================================================
|
||||
// 郵件服務
|
||||
// =====================================================
|
||||
|
||||
import nodemailer from 'nodemailer';
|
||||
|
||||
// 郵件配置
|
||||
const emailConfig = {
|
||||
host: process.env.SMTP_HOST || 'smtp.gmail.com',
|
||||
port: parseInt(process.env.SMTP_PORT || '587'),
|
||||
secure: false, // true for 465, false for other ports
|
||||
auth: {
|
||||
user: process.env.SMTP_USER,
|
||||
pass: process.env.SMTP_PASS,
|
||||
},
|
||||
};
|
||||
|
||||
// 創建郵件傳輸器
|
||||
const transporter = nodemailer.createTransport(emailConfig);
|
||||
|
||||
export class EmailService {
|
||||
// 發送密碼重設郵件
|
||||
static async sendPasswordResetEmail(email: string, resetToken: string, userName: string) {
|
||||
try {
|
||||
const resetUrl = `${process.env.NEXT_PUBLIC_APP_URL || 'http://localhost:3000'}/reset-password?token=${resetToken}`;
|
||||
|
||||
const mailOptions = {
|
||||
from: `"${process.env.NEXT_PUBLIC_APP_NAME || 'AI 展示平台'}" <${emailConfig.auth.user}>`,
|
||||
to: email,
|
||||
subject: '密碼重設請求',
|
||||
html: `
|
||||
<div style="font-family: Arial, sans-serif; max-width: 600px; margin: 0 auto;">
|
||||
<div style="background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); padding: 30px; text-align: center;">
|
||||
<h1 style="color: white; margin: 0; font-size: 24px;">密碼重設請求</h1>
|
||||
</div>
|
||||
|
||||
<div style="padding: 30px; background: #f9f9f9;">
|
||||
<h2 style="color: #333; margin-top: 0;">親愛的 ${userName},</h2>
|
||||
|
||||
<p style="color: #666; line-height: 1.6;">
|
||||
我們收到了您的密碼重設請求。請點擊下方按鈕來重設您的密碼:
|
||||
</p>
|
||||
|
||||
<div style="text-align: center; margin: 30px 0;">
|
||||
<a href="${resetUrl}"
|
||||
style="background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
|
||||
color: white;
|
||||
padding: 15px 30px;
|
||||
text-decoration: none;
|
||||
border-radius: 5px;
|
||||
display: inline-block;
|
||||
font-weight: bold;">
|
||||
重設密碼
|
||||
</a>
|
||||
</div>
|
||||
|
||||
<p style="color: #666; line-height: 1.6; font-size: 14px;">
|
||||
如果按鈕無法點擊,請複製以下連結到瀏覽器中:<br>
|
||||
<a href="${resetUrl}" style="color: #667eea; word-break: break-all;">${resetUrl}</a>
|
||||
</p>
|
||||
|
||||
<div style="background: #fff3cd; border: 1px solid #ffeaa7; padding: 15px; border-radius: 5px; margin: 20px 0;">
|
||||
<p style="color: #856404; margin: 0; font-size: 14px;">
|
||||
<strong>注意:</strong>此連結將在 1 小時後過期,請盡快完成密碼重設。
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<p style="color: #666; line-height: 1.6; font-size: 14px;">
|
||||
如果您沒有請求密碼重設,請忽略此郵件。您的密碼將保持不變。
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div style="background: #333; color: white; padding: 20px; text-align: center; font-size: 12px;">
|
||||
<p style="margin: 0;">此郵件由 ${process.env.NEXT_PUBLIC_APP_NAME || 'AI 展示平台'} 系統自動發送</p>
|
||||
</div>
|
||||
</div>
|
||||
`,
|
||||
};
|
||||
|
||||
const result = await transporter.sendMail(mailOptions);
|
||||
console.log('密碼重設郵件發送成功:', result.messageId);
|
||||
return { success: true, messageId: result.messageId };
|
||||
|
||||
} catch (error) {
|
||||
console.error('發送密碼重設郵件失敗:', error);
|
||||
return { success: false, error: error.message };
|
||||
}
|
||||
}
|
||||
|
||||
// 測試郵件配置
|
||||
static async testEmailConfig() {
|
||||
try {
|
||||
await transporter.verify();
|
||||
console.log('郵件配置驗證成功');
|
||||
return { success: true };
|
||||
} catch (error) {
|
||||
console.error('郵件配置驗證失敗:', error);
|
||||
return { success: false, error: error.message };
|
||||
}
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user