Новый изменения

This commit is contained in:
Web-serfer 2026-05-04 21:01:24 +05:00
parent bd77761489
commit 8ae05f40c4

View file

@ -1,3 +1,4 @@
import nodemailer from 'nodemailer';
import type { EmailOptions } from '../globalInterfaces';
const isDev = import.meta.env.DEV;
@ -7,6 +8,11 @@ const isProduction = hasProductionFlag || forceProduction || !isDev;
const RESEND_API_KEY = isProduction ? (import.meta.env.RESEND_API_KEY || '') : '';
const SMTP_HOST = isProduction ? (import.meta.env.SMTP_HOST || '') : '';
const SMTP_PORT = isProduction ? (import.meta.env.SMTP_PORT || '465') : '1025';
const SMTP_AUTH_USER = isProduction ? (import.meta.env.SMTP_AUTH_USER || '') : '';
const SMTP_AUTH_PASS = isProduction ? (import.meta.env.SMTP_AUTH_PASS || '') : '';
const FROM_EMAIL = isProduction
? (import.meta.env.FROM_EMAIL || 'noreply@localhost')
: 'noreply@localhost';
@ -17,12 +23,23 @@ const SITE_URL = isProduction
console.log('[EMAIL] isDev:', isDev);
console.log('[EMAIL] isProduction:', isProduction);
console.log('[EMAIL] Using Resend:', isProduction && !!RESEND_API_KEY);
console.log('[EMAIL] SMTP:', SMTP_HOST, ':', SMTP_PORT);
function getTransporter() {
return nodemailer.createTransport({
host: SMTP_HOST,
port: parseInt(SMTP_PORT),
secure: SMTP_PORT === '465',
connectionTimeout: 15000,
auth: SMTP_AUTH_USER ? {
user: SMTP_AUTH_USER,
pass: SMTP_AUTH_PASS,
} : undefined,
});
}
async function sendViaResend(options: EmailOptions): Promise<boolean> {
try {
console.log('[RESEND] Sending to:', options.to);
const response = await fetch('https://api.resend.com/emails', {
method: 'POST',
headers: {
@ -53,11 +70,27 @@ async function sendViaResend(options: EmailOptions): Promise<boolean> {
}
export async function sendEmail(options: EmailOptions): Promise<boolean> {
if (SMTP_HOST && SMTP_AUTH_PASS) {
try {
const info = await getTransporter().sendMail({
from: `${FROM_NAME} <${FROM_EMAIL}>`,
to: options.to,
subject: options.subject,
html: options.html,
});
console.log('[SMTP] Email sent:', info.messageId);
return true;
} catch (error) {
console.error('[SMTP] Email send error:', error);
return false;
}
}
if (isProduction && RESEND_API_KEY) {
return sendViaResend(options);
}
console.log('[DEV] Email not sent (no Resend key):', options.to);
console.log('[DEV] Email not sent:', options.to);
return false;
}
@ -79,28 +112,21 @@ export function generateVerifyEmailHtml(firstName: string, verifyLink: string):
<tr>
<td align="center">
<table width="100%" cellpadding="0" cellspacing="0" style="max-width: 600px; background-color: #ffffff; border-radius: 16px; overflow: hidden; box-shadow: 0 4px 20px rgba(0,0,0,0.08);">
<!-- Header -->
<tr>
<td style="background: linear-gradient(135deg, #1e3050 0%, #2d4a6f 100%); padding: 30px 40px; text-align: center;">
<h1 style="color: #ffffff; margin: 0; font-size: 28px; font-weight: 700;">Автоюрист Сургут</h1>
<p style="color: rgba(255,255,255,0.8); margin: 10px 0 0 0; font-size: 16px;">Юридические услуги для автовладельцев</p>
</td>
</tr>
<!-- Content -->
<tr>
<td style="padding: 40px;">
<h2 style="color: #1e3050; margin: 0 0 20px 0; font-size: 24px; font-weight: 700;">Добро пожаловать, ${firstName}!</h2>
<p style="color: #64748b; font-size: 16px; line-height: 1.6; margin: 0 0 20px 0;">
Благодарим за регистрацию на сайте <strong>avtourist-surgut.ru</strong>. Мы рады, что вы выбрали нас для решения юридических вопросов, связанных с автомобилем.
</p>
<p style="color: #64748b; font-size: 16px; line-height: 1.6; margin: 0 0 30px 0;">
Для завершения регистрации и активации вашего аккаунта, пожалуйста, подтвердите ваш email, нажав на кнопку ниже:
</p>
<!-- Button -->
<table width="100%" cellpadding="0" cellspacing="0">
<tr>
<td align="center">
@ -112,54 +138,11 @@ export function generateVerifyEmailHtml(firstName: string, verifyLink: string):
</table>
</td>
</tr>
<!-- Features -->
<tr>
<td style="background-color: #f8fafc; padding: 30px 40px;">
<table width="100%" cellpadding="0" cellspacing="0">
<tr>
<td align="center" style="padding: 0 10px;">
<div style="width: 48px; height: 48px; background: linear-gradient(135deg, #eac26e 0%, #ce9f40 100%); border-radius: 12px; display: inline-flex; align-items: center; justify-content: center; margin-bottom: 12px;">
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="white" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
<path d="M22 16.92v3a2 2 0 0 1-2.18 2 19.79 19.79 0 0 1-8.63-3.07 19.5 19.5 0 0 1-6-6 19.79 19.79 0 0 1-3.07-8.67A2 2 0 0 1 4.11 2h3a2 2 0 0 1 2 1.72 12.84 12.84 0 0 0 .7 2.81 2 2 0 0 1-.45 2.11L8.09 9.91a16 16 0 0 0 6 6l1.27-1.27a2 2 0 0 1 2.11-.45 12.84 12.84 0 0 0 2.81.7A2 2 0 0 1 22 16.92z"></path>
</svg>
</div>
<p style="color: #1e3050; font-size: 13px; font-weight: 600; margin: 0;">Бесплатная консультация</p>
</td>
<td align="center" style="padding: 0 10px;">
<div style="width: 48px; height: 48px; background: linear-gradient(135deg, #eac26e 0%, #ce9f40 100%); border-radius: 12px; display: inline-flex; align-items: center; justify-content: center; margin-bottom: 12px;">
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="white" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
<path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"></path>
<polyline points="14 2 14 8 20 8"></polyline>
<line x1="16" y1="13" x2="8" y2="13"></line>
<line x1="16" y1="17" x2="8" y2="17"></line>
</svg>
</div>
<p style="color: #1e3050; font-size: 13px; font-weight: 600; margin: 0;">Оплата за результат</p>
</td>
<td align="center" style="padding: 0 10px;">
<div style="width: 48px; height: 48px; background: linear-gradient(135deg, #eac26e 0%, #ce9f40 100%); border-radius: 12px; display: inline-flex; align-items: center; justify-content: center; margin-bottom: 12px;">
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="white" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
<circle cx="12" cy="12" r="10"></circle>
<polyline points="12 6 12 12 16 14"></polyline>
</svg>
</div>
<p style="color: #1e3050; font-size: 13px; font-weight: 600; margin: 0;">Работаем 24/7</p>
</td>
</tr>
</table>
</td>
</tr>
<!-- Footer -->
<tr>
<td style="background-color: #1e3050; padding: 24px 40px; text-align: center;">
<p style="color: rgba(255,255,255,0.6); font-size: 14px; margin: 0;">
© 2026 Автоюрист Сургут. Все права защищены.
</p>
<p style="color: rgba(255,255,255,0.4); font-size: 12px; margin: 10px 0 0 0;">
Это письмо отправлено автоматически, пожалуйста, не отвечайте на него.
</p>
</td>
</tr>
</table>