fix: use internal mailcow relay (port 25) for all SMTP transports
SMTP auth on port 587 was broken across all modules due to stale credentials. Since rspace is on the mailcow Docker network, all 6 SMTP transports now use unauthenticated relay on port 25 when the host is the internal postfix container. Fixes emails for: payment receipts, space invitations, inbox approvals, agent notifications, scheduled emails, and publication sharing. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
parent
4919ca1021
commit
42546c9a63
|
|
@ -18,11 +18,13 @@ async function getSmtpTransport() {
|
|||
try {
|
||||
const nodemailer = await import("nodemailer");
|
||||
const createTransport = (nodemailer as any).default?.createTransport || nodemailer.createTransport;
|
||||
const isInternal = SMTP_HOST.includes('mailcow') || SMTP_HOST.includes('postfix');
|
||||
_transport = createTransport({
|
||||
host: SMTP_HOST,
|
||||
port: SMTP_PORT,
|
||||
secure: SMTP_PORT === 465,
|
||||
auth: SMTP_USER ? { user: SMTP_USER, pass: SMTP_PASS } : undefined,
|
||||
port: isInternal ? 25 : SMTP_PORT,
|
||||
secure: !isInternal && SMTP_PORT === 465,
|
||||
...(isInternal ? {} : SMTP_USER ? { auth: { user: SMTP_USER, pass: SMTP_PASS } } : {}),
|
||||
tls: { rejectUnauthorized: false },
|
||||
});
|
||||
return _transport;
|
||||
} catch (e) {
|
||||
|
|
|
|||
|
|
@ -50,13 +50,15 @@ async function getSmtpTransport() {
|
|||
try {
|
||||
const nodemailer = await import("nodemailer");
|
||||
const createTransport = (nodemailer as any).default?.createTransport || nodemailer.createTransport;
|
||||
const isInternal = SMTP_HOST.includes('mailcow') || SMTP_HOST.includes('postfix');
|
||||
_smtpTransport = createTransport({
|
||||
host: SMTP_HOST,
|
||||
port: SMTP_PORT,
|
||||
secure: SMTP_PORT === 465,
|
||||
auth: SMTP_USER ? { user: SMTP_USER, pass: SMTP_PASS } : undefined,
|
||||
port: isInternal ? 25 : SMTP_PORT,
|
||||
secure: !isInternal && SMTP_PORT === 465,
|
||||
...(isInternal ? {} : SMTP_USER ? { auth: { user: SMTP_USER, pass: SMTP_PASS } } : {}),
|
||||
tls: { rejectUnauthorized: false },
|
||||
});
|
||||
console.log(`[Inbox] SMTP transport configured: ${SMTP_HOST}:${SMTP_PORT}`);
|
||||
console.log(`[Inbox] SMTP transport configured: ${SMTP_HOST}:${isInternal ? 25 : SMTP_PORT}`);
|
||||
return _smtpTransport;
|
||||
} catch (e) {
|
||||
console.error("[Inbox] Failed to create SMTP transport:", e);
|
||||
|
|
|
|||
|
|
@ -29,15 +29,19 @@ let _smtpTransport: Transporter | null = null;
|
|||
|
||||
function getSmtpTransport(): Transporter | null {
|
||||
if (_smtpTransport) return _smtpTransport;
|
||||
if (!process.env.SMTP_PASS) return null;
|
||||
const host = process.env.SMTP_HOST || "mail.rmail.online";
|
||||
const isInternal = host.includes('mailcow') || host.includes('postfix');
|
||||
if (!process.env.SMTP_PASS && !isInternal) return null;
|
||||
_smtpTransport = createTransport({
|
||||
host: process.env.SMTP_HOST || "mail.rmail.online",
|
||||
port: Number(process.env.SMTP_PORT) || 587,
|
||||
secure: Number(process.env.SMTP_PORT) === 465,
|
||||
auth: {
|
||||
user: process.env.SMTP_USER || "noreply@rmail.online",
|
||||
pass: process.env.SMTP_PASS,
|
||||
},
|
||||
host,
|
||||
port: isInternal ? 25 : (Number(process.env.SMTP_PORT) || 587),
|
||||
secure: !isInternal && Number(process.env.SMTP_PORT) === 465,
|
||||
...(isInternal ? {} : {
|
||||
auth: {
|
||||
user: process.env.SMTP_USER || "noreply@rmail.online",
|
||||
pass: process.env.SMTP_PASS!,
|
||||
},
|
||||
}),
|
||||
tls: { rejectUnauthorized: false },
|
||||
});
|
||||
return _smtpTransport;
|
||||
|
|
|
|||
|
|
@ -52,15 +52,19 @@ let _smtpTransport: Transporter | null = null;
|
|||
|
||||
function getSmtpTransport(): Transporter | null {
|
||||
if (_smtpTransport) return _smtpTransport;
|
||||
if (!process.env.SMTP_PASS) return null;
|
||||
const host = process.env.SMTP_HOST || "mail.rmail.online";
|
||||
const isInternal = host.includes('mailcow') || host.includes('postfix');
|
||||
if (!process.env.SMTP_PASS && !isInternal) return null;
|
||||
_smtpTransport = createTransport({
|
||||
host: process.env.SMTP_HOST || "mail.rmail.online",
|
||||
port: Number(process.env.SMTP_PORT) || 587,
|
||||
secure: Number(process.env.SMTP_PORT) === 465,
|
||||
auth: {
|
||||
user: process.env.SMTP_USER || "noreply@rmail.online",
|
||||
pass: process.env.SMTP_PASS,
|
||||
},
|
||||
host,
|
||||
port: isInternal ? 25 : (Number(process.env.SMTP_PORT) || 587),
|
||||
secure: !isInternal && Number(process.env.SMTP_PORT) === 465,
|
||||
...(isInternal ? {} : {
|
||||
auth: {
|
||||
user: process.env.SMTP_USER || "noreply@rmail.online",
|
||||
pass: process.env.SMTP_PASS!,
|
||||
},
|
||||
}),
|
||||
tls: { rejectUnauthorized: false },
|
||||
});
|
||||
return _smtpTransport;
|
||||
|
|
|
|||
|
|
@ -43,15 +43,16 @@ let _smtpTransport: any = null;
|
|||
|
||||
async function getSmtpTransport() {
|
||||
if (_smtpTransport) return _smtpTransport;
|
||||
if (!SMTP_PASS) return null;
|
||||
const isInternal = SMTP_HOST.includes('mailcow') || SMTP_HOST.includes('postfix');
|
||||
if (!SMTP_PASS && !isInternal) return null;
|
||||
try {
|
||||
const nodemailer = await import("nodemailer");
|
||||
const createTransport = (nodemailer as any).default?.createTransport || nodemailer.createTransport;
|
||||
_smtpTransport = createTransport({
|
||||
host: SMTP_HOST,
|
||||
port: SMTP_PORT,
|
||||
secure: SMTP_PORT === 465,
|
||||
auth: SMTP_USER ? { user: SMTP_USER, pass: SMTP_PASS } : undefined,
|
||||
port: isInternal ? 25 : SMTP_PORT,
|
||||
secure: !isInternal && SMTP_PORT === 465,
|
||||
...(isInternal ? {} : SMTP_USER ? { auth: { user: SMTP_USER, pass: SMTP_PASS } } : {}),
|
||||
tls: { rejectUnauthorized: false },
|
||||
});
|
||||
console.log("[email] SMTP transport configured");
|
||||
|
|
|
|||
|
|
@ -2097,17 +2097,23 @@ spaces.post("/:slug/copy-shapes", async (c) => {
|
|||
|
||||
let inviteTransport: Transporter | null = null;
|
||||
|
||||
if (process.env.SMTP_PASS) {
|
||||
inviteTransport = createTransport({
|
||||
host: process.env.SMTP_HOST || "mail.rmail.online",
|
||||
port: Number(process.env.SMTP_PORT) || 587,
|
||||
secure: Number(process.env.SMTP_PORT) === 465,
|
||||
auth: {
|
||||
user: process.env.SMTP_USER || "noreply@rmail.online",
|
||||
pass: process.env.SMTP_PASS,
|
||||
},
|
||||
tls: { rejectUnauthorized: false },
|
||||
});
|
||||
{
|
||||
const host = process.env.SMTP_HOST || "mail.rmail.online";
|
||||
const isInternal = host.includes('mailcow') || host.includes('postfix');
|
||||
if (process.env.SMTP_PASS || isInternal) {
|
||||
inviteTransport = createTransport({
|
||||
host,
|
||||
port: isInternal ? 25 : (Number(process.env.SMTP_PORT) || 587),
|
||||
secure: !isInternal && Number(process.env.SMTP_PORT) === 465,
|
||||
...(isInternal ? {} : {
|
||||
auth: {
|
||||
user: process.env.SMTP_USER || "noreply@rmail.online",
|
||||
pass: process.env.SMTP_PASS!,
|
||||
},
|
||||
}),
|
||||
tls: { rejectUnauthorized: false },
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
// ── Enhanced invite by email (with token + role) ──
|
||||
|
|
|
|||
Loading…
Reference in New Issue