Files
morsequest/server/mailer.js
T
kitadmin bbebc31624 fix(mailer): add TLS settings for internal SMTP relay
- rejectUnauthorized: false (relay cert is for mail.keylinkit.net, not 172.17.0.1)
- connection/greeting/socket timeouts for reliability

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-30 03:23:44 +00:00

67 lines
2.5 KiB
JavaScript

'use strict'
const nodemailer = require('nodemailer')
const SMTP_HOST = process.env.SMTP_HOST || ''
const SMTP_PORT = parseInt(process.env.SMTP_PORT || '587', 10)
const SMTP_USER = process.env.SMTP_USER || ''
const SMTP_PASS = process.env.SMTP_PASS || ''
const APP_URL = (process.env.APP_URL || 'http://localhost:3001').replace(/\/$/, '')
const FROM_ADDR = SMTP_USER
? `"MorseQuest" <${SMTP_USER}>`
: '"MorseQuest" <noreply@morsequest.keylinkit.net>'
let transport = null
if (SMTP_HOST && SMTP_USER && SMTP_PASS) {
transport = nodemailer.createTransport({
host: SMTP_HOST,
port: SMTP_PORT,
secure: SMTP_PORT === 465,
auth: { user: SMTP_USER, pass: SMTP_PASS },
connectionTimeout: 10_000,
greetingTimeout: 10_000,
socketTimeout: 15_000,
tls: { rejectUnauthorized: false }, // tunnel relay cert is for mail.keylinkit.net, not 172.17.0.1
})
console.log(`[mailer] SMTP configured: ${SMTP_HOST}:${SMTP_PORT}`)
} else {
console.warn('[mailer] SMTP not configured — magic links will be logged only')
}
async function send(to, subject, html) {
if (!transport) {
console.log(`[mailer] Would send to ${to}: ${subject}`)
return
}
await transport.sendMail({ from: FROM_ADDR, to, subject, html })
}
async function sendMagicLink(email, token) {
const link = `${APP_URL}/api/auth/verify?token=${token}`
const subject = 'Your MorseQuest Login Link'
const html = `
<div style="font-family:'Open Sans',sans-serif;max-width:480px;margin:0 auto;
padding:2rem;background:#F5E6D3;border:2px solid #D4AF37">
<h1 style="font-family:'Cinzel',serif;color:#3C2415;font-size:1.4rem;margin-bottom:1rem">
&#x26A1; MorseQuest Login
</h1>
<p style="color:#3C2415;line-height:1.6">
Click the button below to log in to MorseQuest. This link is valid for 24 hours
and can only be used once.
</p>
<div style="text-align:center;margin:2rem 0">
<a href="${link}"
style="display:inline-block;padding:0.8rem 2rem;background:#D4AF37;
color:#3C2415;text-decoration:none;font-family:'Cinzel',serif;
font-size:1rem;font-weight:600;border:2px solid #3C2415">
Begin Your Quest &rsaquo;
</a>
</div>
<p style="color:#654321;font-size:0.85rem;line-height:1.5">
If you didn't request this link, you can ignore this email safely.
</p>
</div>`
await send(email, subject, html)
}
module.exports = { sendMagicLink }