mirror of
https://origin.cursor.com/mrdevmx/panels.git
synced 2026-10-09 19:03:17 +00:00
100 lines
3 KiB
TypeScript
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
|
|
`;
|
|
}
|