panels-origin/api/mail.ts
2026-08-21 16:55:01 -05:00

100 lines
3 KiB
TypeScript

import type { PlatformDb } from "./platform_db.ts";
import { config } from "./config.ts";
import { resolveSmtp, smtpConfigured as smtpConfiguredFromDb } from "./smtp.ts";
export type MailPayload = {
to: string;
subject: string;
text: string;
};
export function smtpConfigured(platformDb: PlatformDb): boolean {
return smtpConfiguredFromDb(platformDb);
}
/** Envía correo por SMTP. Si no hay SMTP, no falla: sent=false. */
export async function sendMail(
platformDb: PlatformDb,
payload: MailPayload,
): Promise<{ sent: boolean; error?: string; message_id?: string }> {
if (!smtpConfigured(platformDb)) {
return { sent: false, error: "SMTP no configurado o deshabilitado" };
}
const s = resolveSmtp(platformDb);
try {
const nodemailer = await import("npm:nodemailer@6.9.16");
const transporter = nodemailer.createTransport({
host: s.host,
port: s.port,
secure: s.port === 465,
requireTLS: s.port === 587,
auth: s.username ? { user: s.username, pass: s.password } : undefined,
connectionTimeout: 20000,
greetingTimeout: 20000,
socketTimeout: 30000,
tls: {
// Algunos hosting (cPanel) usan certs que fallan la validación estricta en Deno
rejectUnauthorized: false,
servername: s.host,
},
});
const info = await transporter.sendMail({
from: s.from_address,
to: payload.to,
subject: payload.subject,
text: payload.text,
});
const messageId = typeof info?.messageId === "string" ? info.messageId : undefined;
console.log(`[smtp] sent to=${payload.to} id=${messageId ?? "—"} host=${s.host}:${s.port}`);
return { sent: true, message_id: messageId };
} catch (e) {
const msg = e instanceof Error ? e.message : "Error al enviar correo";
console.error(`[smtp] fail to=${payload.to}:`, msg);
return { sent: false, error: msg };
}
}
/** Prueba de conexión / envío a un destinatario. */
export async function testSmtp(
platformDb: PlatformDb,
to: string,
): Promise<{ sent: boolean; error?: string; message_id?: string }> {
const dest = (to ?? "").trim();
if (!dest || !/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(dest)) {
return { sent: false, error: "Indique un correo de prueba válido" };
}
return sendMail(platformDb, {
to: dest,
subject: "PANELS — prueba SMTP",
text: `Este es un correo de prueba de la configuración SMTP de PANELS.
Si recibió este mensaje, el SMTP está funcionando.
Enviado: ${new Date().toISOString()}
Destinatario: ${dest}
`,
});
}
export function accessEmailBody(opts: {
companyName: string;
username: string;
password: string;
contactName?: string;
}): string {
const hi = opts.contactName ? `Hola ${opts.contactName},` : "Hola,";
return `${hi}
Su empresa "${opts.companyName}" ya tiene acceso a PANELS.
Usuario (administrador): ${opts.username}
Contraseña temporal: ${opts.password}
Inicie sesión en: ${config.panelLoginUrl}
Por seguridad, al entrar por primera vez deberá cambiar la contraseña.
— Equipo PANELS
`;
}