import type { PlatformDb } from "./platform_db.ts"; import { config } from "./config.ts"; export type SmtpSettings = { host: string; port: number; username: string; password: string; from_address: string; enabled: boolean; updated_at?: string; }; export type SmtpPublic = { host: string; port: number; username: string; from_address: string; enabled: boolean; configured: boolean; has_password: boolean; updated_at: string | null; source: "db" | "env" | "none"; }; type SmtpRow = { host: string; port: number; username: string; password: string; from_address: string; enabled: number; updated_at: string; }; function trim(v: unknown): string { return (v ?? "").toString().trim(); } function fromEnv(): SmtpSettings { return { host: config.smtpHost, port: config.smtpPort || 587, username: config.smtpUser, password: config.smtpPass, from_address: config.smtpFrom, enabled: Boolean(config.smtpHost && config.smtpFrom), }; } function readRow(platformDb: PlatformDb): SmtpRow | undefined { try { return platformDb.prepare( `SELECT host, port, username, password, from_address, enabled, updated_at FROM smtp_settings WHERE id = 1`, ).get() as SmtpRow | undefined; } catch { return undefined; } } /** Config efectiva: fila en platform.db si hay host; si no, variables de entorno. */ export function resolveSmtp(platformDb: PlatformDb): SmtpSettings & { source: "db" | "env" | "none" } { const row = readRow(platformDb); if (row && trim(row.host)) { return { host: trim(row.host), port: Number(row.port) || 587, username: trim(row.username), password: row.password ?? "", from_address: trim(row.from_address) || config.smtpFrom, enabled: Number(row.enabled) === 1, updated_at: row.updated_at, source: "db", }; } const env = fromEnv(); if (env.host) return { ...env, source: "env" }; return { ...env, enabled: false, source: "none" }; } export function smtpConfigured(platformDb: PlatformDb): boolean { const s = resolveSmtp(platformDb); return s.enabled && Boolean(s.host && s.from_address); } export function smtpPublicView(platformDb: PlatformDb): SmtpPublic { const s = resolveSmtp(platformDb); return { host: s.host, port: s.port, username: s.username, from_address: s.from_address, enabled: s.enabled, configured: smtpConfigured(platformDb), has_password: Boolean(s.password), updated_at: s.updated_at ?? null, source: s.source, }; } export type SaveSmtpInput = { host?: string; port?: number | string; username?: string; password?: string; from_address?: string; enabled?: boolean; /** Si true y password vacío, conserva la contraseña actual. */ keep_password?: boolean; }; function looksLikeEmailFrom(value: string): boolean { // Acepta "user@dom.com" o "Nombre " return /(?:^|<)[^\s<>@]+@[^\s<>@]+\.[^\s<>@]+(?:>|$)/.test(value); } export function saveSmtpSettings( platformDb: PlatformDb, input: SaveSmtpInput, ): { error?: string; settings?: SmtpPublic } { const host = trim(input.host); const fromAddress = trim(input.from_address); const username = trim(input.username); const port = Number(input.port ?? 587); if (!Number.isFinite(port) || port < 1 || port > 65535) { return { error: "Puerto SMTP inválido" }; } const enabled = input.enabled !== false; if (enabled && !host) return { error: "Host SMTP obligatorio si está habilitado" }; if (enabled && !fromAddress) return { error: "Remitente (From) obligatorio si está habilitado" }; if (enabled && fromAddress && !looksLikeEmailFrom(fromAddress)) { return { error: 'Remitente inválido. Use un correo, ej. PANELS ', }; } const current = readRow(platformDb); let password = input.password ?? ""; if ((input.keep_password || password === "") && current?.password) { password = current.password; } platformDb.prepare( `INSERT INTO smtp_settings (id, host, port, username, password, from_address, enabled, updated_at) VALUES (1, ?, ?, ?, ?, ?, ?, datetime('now')) ON CONFLICT(id) DO UPDATE SET host = excluded.host, port = excluded.port, username = excluded.username, password = excluded.password, from_address = excluded.from_address, enabled = excluded.enabled, updated_at = datetime('now')`, ).run(host, port, username, password, fromAddress, enabled ? 1 : 0); return { settings: smtpPublicView(platformDb) }; }