refactor(runtime): prefer env-backed secrets at runtime

This commit is contained in:
2026-03-30 19:17:32 +02:00
parent 4f5d410b94
commit fed7aa5b61
13 changed files with 532 additions and 71 deletions
+41 -4
View File
@@ -4,6 +4,8 @@
*/
import nodemailer from "nodemailer";
import { prisma as db } from "@capakraken/db";
import { logger } from "./logger.js";
import { resolveSystemSettingsRuntime } from "./system-settings-runtime.js";
interface EmailPayload {
to: string | string[];
@@ -12,9 +14,43 @@ interface EmailPayload {
html?: string;
}
function sanitizeSmtpDiagnostic(err: unknown): string {
const message = err instanceof Error ? err.message : String(err);
return message
.replace(/https?:\/\/[^\s)\]}]+/gi, "<redacted-url>")
.replace(/\b[^\s@]+@[^\s@]+\.[^\s@]+\b/g, "<redacted-email>")
.replace(/\b(?:[A-Za-z0-9-]+\.)+[A-Za-z]{2,}\b/g, "<redacted-host>")
.replace(/^Error:\s*/, "")
.slice(0, 300);
}
export function parseSmtpError(err: unknown): string {
const message = err instanceof Error ? err.message : String(err);
const lower = message.toLowerCase();
if (lower.includes("auth") || lower.includes("invalid login") || lower.includes("535")) {
return "SMTP authentication failed — check username and password.";
}
if (lower.includes("certificate") || lower.includes("tls") || lower.includes("ssl")) {
return "SMTP TLS negotiation failed — verify port and TLS settings.";
}
if (
lower.includes("econnrefused")
|| lower.includes("enotfound")
|| lower.includes("etimedout")
|| lower.includes("timeout")
) {
return "Cannot reach the SMTP server — check host, port, and network access.";
}
return "SMTP connection failed — review host, port, TLS, and credentials.";
}
async function getSmtpConfig() {
const settings = await db.systemSettings.findUnique({ where: { id: "singleton" } });
if (!settings?.smtpHost) return null;
const settings = resolveSystemSettingsRuntime(
await db.systemSettings.findUnique({ where: { id: "singleton" } }),
);
if (!settings.smtpHost) return null;
return {
host: settings.smtpHost,
port: settings.smtpPort ?? 587,
@@ -53,7 +89,7 @@ export async function sendEmail(payload: EmailPayload): Promise<boolean> {
return true;
} catch (err) {
console.error("[email] Failed to send email:", err);
logger.warn({ diagnostic: sanitizeSmtpDiagnostic(err) }, "Email send failed");
return false;
}
}
@@ -76,6 +112,7 @@ export async function testSmtpConnection(): Promise<{ ok: boolean; error?: strin
await transporter.verify();
return { ok: true };
} catch (err) {
return { ok: false, error: err instanceof Error ? err.message : String(err) };
logger.warn({ diagnostic: sanitizeSmtpDiagnostic(err) }, "SMTP connection test failed");
return { ok: false, error: parseSmtpError(err) };
}
}