import { afterEach, beforeEach, describe, expect, it, vi } from "vitest"; import nodemailer from "nodemailer"; import { logger } from "../lib/logger.js"; import { testSmtpConnection } from "../lib/email.js"; const { findUnique, verify, createTransport } = vi.hoisted(() => { const verify = vi.fn(); return { findUnique: vi.fn(), verify, createTransport: vi.fn(() => ({ verify, sendMail: vi.fn(), })), }; }); vi.mock("@capakraken/db", () => ({ prisma: { systemSettings: { findUnique, }, }, })); vi.mock("nodemailer", () => ({ default: { createTransport, }, })); vi.mock("../lib/logger.js", () => ({ logger: { error: vi.fn(), warn: vi.fn(), info: vi.fn(), debug: vi.fn(), }, })); describe("email runtime config hardening", () => { beforeEach(() => { vi.clearAllMocks(); findUnique.mockResolvedValue({ smtpHost: "smtp.secret.internal", smtpPort: 587, smtpUser: "alice@example.com", smtpPassword: "super-secret", smtpTls: true, }); }); afterEach(() => { vi.unstubAllEnvs(); }); it("returns a classified SMTP auth error without leaking diagnostics", async () => { verify.mockRejectedValueOnce( new Error("Invalid login for alice@example.com against smtp.secret.internal"), ); const result = await testSmtpConnection(); expect(result).toEqual({ ok: false, error: "SMTP authentication failed — check username and password.", }); expect(nodemailer.createTransport).toHaveBeenCalledWith({ host: "smtp.secret.internal", port: 587, secure: true, auth: { user: "alice@example.com", pass: "super-secret", }, }); expect(logger.warn).toHaveBeenCalledWith( expect.objectContaining({ diagnostic: expect.any(String), }), "SMTP connection test failed", ); const diagnostic = vi.mocked(logger.warn).mock.calls[0]?.[0]; expect(JSON.stringify(diagnostic)).toContain(""); expect(JSON.stringify(diagnostic)).toContain(""); expect(JSON.stringify(diagnostic)).not.toContain("alice@example.com"); expect(JSON.stringify(diagnostic)).not.toContain("smtp.secret.internal"); }); it("prefers SMTP_PASSWORD from the environment at runtime", async () => { vi.stubEnv("SMTP_PASSWORD", "env-smtp-password"); findUnique.mockResolvedValue({ smtpHost: "smtp.secret.internal", smtpPort: 587, smtpUser: "alice@example.com", smtpPassword: "db-password", smtpTls: true, }); verify.mockResolvedValueOnce(true); const result = await testSmtpConnection(); expect(result).toEqual({ ok: true }); expect(nodemailer.createTransport).toHaveBeenCalledWith({ host: "smtp.secret.internal", port: 587, secure: true, auth: { user: "alice@example.com", pass: "env-smtp-password", }, }); }); });