fix(BUG-021): remove verification code from API response, send via email
- Replace Resend email service with nodemailer via local postfix relay - Remove code field from POST /v1/signup/free response - Send 6-digit verification code via email only (noreply@docfast.dev) - Add extra_hosts for Docker-to-host SMTP relay - Fire-and-forget email sending to avoid blocking API response
This commit is contained in:
parent
a67c16cd0f
commit
210fb26ec1
5 changed files with 50 additions and 54 deletions
|
|
@ -1,52 +1,27 @@
|
|||
const RESEND_API_KEY = process.env.RESEND_API_KEY;
|
||||
const BASE_URL = process.env.BASE_URL || "https://docfast.dev";
|
||||
import nodemailer from "nodemailer";
|
||||
|
||||
export async function sendVerificationEmail(email: string, token: string): Promise<boolean> {
|
||||
const verifyUrl = `${BASE_URL}/verify?token=${token}`;
|
||||
|
||||
if (!RESEND_API_KEY || RESEND_API_KEY === "FILL_IN") {
|
||||
console.log(`\n📧 VERIFICATION EMAIL (no Resend configured)`);
|
||||
console.log(` To: ${email}`);
|
||||
console.log(` URL: ${verifyUrl}\n`);
|
||||
return true;
|
||||
}
|
||||
const transporter = nodemailer.createTransport({
|
||||
host: process.env.SMTP_HOST || "host.docker.internal",
|
||||
port: Number(process.env.SMTP_PORT || 25),
|
||||
secure: false,
|
||||
connectionTimeout: 5000,
|
||||
greetingTimeout: 5000,
|
||||
socketTimeout: 10000,
|
||||
tls: { rejectUnauthorized: false },
|
||||
});
|
||||
|
||||
export async function sendVerificationEmail(email: string, code: string): Promise<boolean> {
|
||||
try {
|
||||
const res = await fetch("https://api.resend.com/emails", {
|
||||
method: "POST",
|
||||
headers: {
|
||||
"Authorization": `Bearer ${RESEND_API_KEY}`,
|
||||
"Content-Type": "application/json",
|
||||
},
|
||||
body: JSON.stringify({
|
||||
from: "DocFast <noreply@docfast.dev>",
|
||||
to: [email],
|
||||
subject: "Verify your DocFast account",
|
||||
html: `
|
||||
<div style="font-family: -apple-system, sans-serif; max-width: 480px; margin: 0 auto; padding: 40px 20px;">
|
||||
<h1 style="font-size: 24px; margin-bottom: 16px;">⚡ Welcome to DocFast</h1>
|
||||
<p style="color: #555; line-height: 1.6;">Click the button below to verify your email and get your API key:</p>
|
||||
<a href="${verifyUrl}" style="display: inline-block; background: #34d399; color: #0b0d11; padding: 14px 28px; border-radius: 8px; font-weight: 600; text-decoration: none; margin: 24px 0;">Verify Email →</a>
|
||||
<p style="color: #999; font-size: 13px; margin-top: 24px;">This link expires in 24 hours. If you didn't sign up for DocFast, ignore this email.</p>
|
||||
</div>
|
||||
`,
|
||||
}),
|
||||
const info = await transporter.sendMail({
|
||||
from: "DocFast <noreply@docfast.dev>",
|
||||
to: email,
|
||||
subject: "DocFast - Verify your email",
|
||||
text: `Your DocFast verification code is: ${code}\n\nThis code expires in 15 minutes.\n\nIf you didn't sign up for DocFast, ignore this email.`,
|
||||
});
|
||||
|
||||
if (!res.ok) {
|
||||
const err = await res.text();
|
||||
console.error(`Resend API error: ${res.status} ${err}`);
|
||||
// Fallback to console
|
||||
console.log(`\n📧 VERIFICATION EMAIL (Resend failed, logging)`);
|
||||
console.log(` To: ${email}`);
|
||||
console.log(` URL: ${verifyUrl}\n`);
|
||||
}
|
||||
console.log(`📧 Verification email sent to ${email}: ${info.messageId}`);
|
||||
return true;
|
||||
} catch (err) {
|
||||
console.error("Email send error:", err);
|
||||
console.log(`\n📧 VERIFICATION EMAIL (fallback)`);
|
||||
console.log(` To: ${email}`);
|
||||
console.log(` URL: ${verifyUrl}\n`);
|
||||
return true;
|
||||
console.error(`📧 Failed to send verification email to ${email}:`, err);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue