function dbConfig(key: string): string { try { const { getDb } = require('./db'); const row = getDb().query('SELECT value FROM content WHERE key = ?').get(key) as { value: string } | null; return row?.value || ''; } catch { return ''; } } function cfg(): { host: string; port: number; user: string; pass: string; from: string } { return { host: dbConfig('smtp_host') || process.env.SMTP_HOST || '', port: parseInt(dbConfig('smtp_port') || process.env.SMTP_PORT || '587'), user: dbConfig('smtp_user') || process.env.SMTP_USER || '', pass: dbConfig('smtp_pass') || process.env.SMTP_PASS || '', from: dbConfig('smtp_from') || process.env.MAIL_FROM || 'shop@zlattea.com', }; } function enabled(): boolean { const c = cfg(); return !!(c.host && c.port && c.user && c.pass); } // minimal text/plain email via direct SMTP/TLS. for production, consider an // external transactional mail api. this path is acceptable for local dev until // volume requires more. export async function sendMail(to: string, subject: string, body: string) { if (!enabled()) { console.log('email skipped (no SMTP config):', subject, to); return; } const c = cfg(); const conn = await require('node:tls').connect({ host: c.host, port: c.port, servername: c.host }); const send = (s: string) => conn.write(s + '\r\n'); let buf = ''; const readUntil = (code: number, timeoutMs = 10000): Promise => new Promise((resolve, reject) => { const t = setTimeout(() => reject(new Error('smtp timeout')), timeoutMs); const onData = (d: Buffer) => { buf += d.toString(); if (buf.includes('\r\n')) { const lines = buf.split('\r\n'); const last = lines[lines.length - 2] || ''; if (last.startsWith(String(code)) || last.startsWith(String(code) + ' ')) { clearTimeout(t); conn.off('data', onData); resolve(last); } } }; conn.on('data', onData); }); await readUntil(220); send(`EHLO ${c.host}`); await readUntil(250); send('AUTH LOGIN'); await readUntil(334); send(Buffer.from(c.user).toString('base64')); await readUntil(334); send(Buffer.from(c.pass).toString('base64')); await readUntil(235); send(`MAIL FROM:<${c.from}>`); await readUntil(250); send(`RCPT TO:<${to}>`); await readUntil(250); send('DATA'); await readUntil(354); const msg = [ `From: Zlattea <${c.from}>`, `To: ${to}`, `Subject: =?UTF-8?B?${Buffer.from(subject).toString('base64')}?=`, 'Content-Type: text/plain; charset=utf-8', '', body, '.', ].join('\r\n'); send(msg); await readUntil(250); send('QUIT'); conn.end(); } export function orderCreatedEmail(to: string, orderId: string, viewToken: string, totalLv: string, itemsDesc: string) { if (!enabled()) return; const url = `${process.env.SITE_URL || 'http://localhost:3000'}/order/${orderId}?t=${viewToken}`; sendMail(to, `Поръчка ${orderId.slice(0, 8)} - Златен чай`, `Благодарим за поръчката! Вашият номер на поръчка: ${orderId.slice(0, 8)}\n\n` + `Продукти:\n${itemsDesc}\n\nОбщо: ${totalLv}\n\n` + `Следете статуса тук: ${url}\n\n` + `Ако сте избрали банков превод или плащане с Lightning/Bitcoin, ще получите допълнителни инструкции на тази страница.\n\n` + `Златен чай`); } export function paymentConfirmedEmail(to: string, orderId: string) { if (!enabled()) return; sendMail(to, `Плащането е получено - Поръчка ${orderId.slice(0, 8)}`, `Плащането за поръчка ${orderId.slice(0, 8)} е получено. Ще ви известим при изпращане.\n\nЗлатен чай`); }