chore(repo): initialize planarchy workspace
This commit is contained in:
@@ -0,0 +1,81 @@
|
||||
/**
|
||||
* Email sending utility using nodemailer.
|
||||
* Non-blocking — errors are logged, not thrown.
|
||||
*/
|
||||
import nodemailer from "nodemailer";
|
||||
import { prisma as db } from "@planarchy/db";
|
||||
|
||||
interface EmailPayload {
|
||||
to: string | string[];
|
||||
subject: string;
|
||||
text: string;
|
||||
html?: string;
|
||||
}
|
||||
|
||||
async function getSmtpConfig() {
|
||||
const settings = await db.systemSettings.findUnique({ where: { id: "singleton" } });
|
||||
if (!settings?.smtpHost) return null;
|
||||
return {
|
||||
host: settings.smtpHost,
|
||||
port: settings.smtpPort ?? 587,
|
||||
secure: settings.smtpTls === false ? false : true,
|
||||
auth:
|
||||
settings.smtpUser && settings.smtpPassword
|
||||
? { user: settings.smtpUser, pass: settings.smtpPassword }
|
||||
: undefined,
|
||||
from: settings.smtpFrom ?? settings.smtpUser ?? "noreply@planarchy.app",
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Send an email. Swallows errors so calling code is never blocked.
|
||||
* Returns true if sent successfully.
|
||||
*/
|
||||
export async function sendEmail(payload: EmailPayload): Promise<boolean> {
|
||||
try {
|
||||
const config = await getSmtpConfig();
|
||||
if (!config) return false;
|
||||
|
||||
const transporter = nodemailer.createTransport({
|
||||
host: config.host,
|
||||
port: config.port,
|
||||
secure: config.secure,
|
||||
auth: config.auth,
|
||||
});
|
||||
|
||||
await transporter.sendMail({
|
||||
from: config.from,
|
||||
to: Array.isArray(payload.to) ? payload.to.join(", ") : payload.to,
|
||||
subject: payload.subject,
|
||||
text: payload.text,
|
||||
html: payload.html,
|
||||
});
|
||||
|
||||
return true;
|
||||
} catch (err) {
|
||||
console.error("[email] Failed to send email:", err);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Test SMTP connection. Returns { ok: boolean; error?: string }.
|
||||
*/
|
||||
export async function testSmtpConnection(): Promise<{ ok: boolean; error?: string }> {
|
||||
try {
|
||||
const config = await getSmtpConfig();
|
||||
if (!config) return { ok: false, error: "SMTP not configured" };
|
||||
|
||||
const transporter = nodemailer.createTransport({
|
||||
host: config.host,
|
||||
port: config.port,
|
||||
secure: config.secure,
|
||||
auth: config.auth,
|
||||
});
|
||||
|
||||
await transporter.verify();
|
||||
return { ok: true };
|
||||
} catch (err) {
|
||||
return { ok: false, error: err instanceof Error ? err.message : String(err) };
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user