179 lines
7 KiB
JavaScript
Executable file
179 lines
7 KiB
JavaScript
Executable file
'use strict';
|
|
const FormData = require('form-data');
|
|
const Mailgun = require('mailgun.js');
|
|
|
|
let mg = null;
|
|
|
|
function getClient() {
|
|
if (!mg) {
|
|
const mailgun = new Mailgun(FormData);
|
|
mg = mailgun.client({ username: 'api', key: process.env.MAILGUN_API_KEY });
|
|
}
|
|
return mg;
|
|
}
|
|
|
|
// ---------------------------------------------------------------------------
|
|
// Shared HTML email wrapper — L'Oréal branded, table-based for email clients
|
|
// ---------------------------------------------------------------------------
|
|
function emailWrapper({ headline, bodyHtml, ctaUrl, ctaLabel, footerNote }) {
|
|
return `<!DOCTYPE html>
|
|
<html lang="en">
|
|
<head>
|
|
<meta charset="UTF-8">
|
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
<title>${headline}</title>
|
|
</head>
|
|
<body style="margin:0;padding:0;background-color:#f4f4f0;font-family:'Helvetica Neue',Helvetica,Arial,sans-serif;">
|
|
<table width="100%" cellpadding="0" cellspacing="0" border="0" style="background-color:#f4f4f0;padding:40px 0;">
|
|
<tr>
|
|
<td align="center">
|
|
<table width="560" cellpadding="0" cellspacing="0" border="0" style="max-width:560px;width:100%;">
|
|
|
|
<!-- ── Header ── -->
|
|
<tr>
|
|
<td style="background-color:#0a0a0a;padding:28px 40px 24px;">
|
|
<table width="100%" cellpadding="0" cellspacing="0" border="0">
|
|
<tr>
|
|
<td>
|
|
<p style="margin:0;font-size:11px;letter-spacing:0.35em;color:#9a9a9a;text-transform:uppercase;font-weight:400;">
|
|
L’ORÉAL · PARIS
|
|
</p>
|
|
<p style="margin:6px 0 0;font-size:22px;letter-spacing:0.12em;color:#ffffff;text-transform:uppercase;font-weight:700;line-height:1;">
|
|
SLA Calculator
|
|
</p>
|
|
</td>
|
|
<td align="right" valign="bottom">
|
|
<span style="display:inline-block;width:28px;height:3px;background-color:#e11d48;border-radius:2px;"></span>
|
|
</td>
|
|
</tr>
|
|
</table>
|
|
</td>
|
|
</tr>
|
|
|
|
<!-- ── Red accent bar ── -->
|
|
<tr>
|
|
<td style="background-color:#e11d48;height:3px;font-size:0;line-height:0;"> </td>
|
|
</tr>
|
|
|
|
<!-- ── Body ── -->
|
|
<tr>
|
|
<td style="background-color:#ffffff;padding:44px 40px 36px;">
|
|
|
|
<!-- Headline -->
|
|
<h1 style="margin:0 0 20px;font-size:26px;font-weight:700;color:#0a0a0a;letter-spacing:-0.01em;line-height:1.25;">
|
|
${headline}
|
|
</h1>
|
|
|
|
<!-- Body copy -->
|
|
${bodyHtml}
|
|
|
|
<!-- CTA button -->
|
|
<table cellpadding="0" cellspacing="0" border="0" style="margin:32px 0 0;">
|
|
<tr>
|
|
<td style="background-color:#e11d48;border-radius:2px;">
|
|
<a href="${ctaUrl}"
|
|
style="display:inline-block;padding:14px 32px;font-size:12px;font-weight:700;letter-spacing:0.15em;text-transform:uppercase;color:#ffffff;text-decoration:none;border-radius:2px;">
|
|
${ctaLabel}
|
|
</a>
|
|
</td>
|
|
</tr>
|
|
</table>
|
|
|
|
<!-- Fallback URL -->
|
|
<p style="margin:20px 0 0;font-size:11px;color:#9a9a9a;line-height:1.6;">
|
|
If the button doesn’t work, copy and paste this link into your browser:<br>
|
|
<a href="${ctaUrl}" style="color:#e11d48;word-break:break-all;">${ctaUrl}</a>
|
|
</p>
|
|
|
|
</td>
|
|
</tr>
|
|
|
|
<!-- ── Footer note ── -->
|
|
<tr>
|
|
<td style="background-color:#f9f9f7;border-top:1px solid #ebebeb;padding:20px 40px;">
|
|
<p style="margin:0;font-size:11px;color:#9a9a9a;line-height:1.7;">
|
|
${footerNote}
|
|
</p>
|
|
</td>
|
|
</tr>
|
|
|
|
<!-- ── Footer ── -->
|
|
<tr>
|
|
<td style="padding:20px 40px 0;">
|
|
<p style="margin:0;font-size:10px;color:#b0b0a8;letter-spacing:0.05em;text-align:center;line-height:1.6;">
|
|
© ${new Date().getFullYear()} L’Oréal. All rights reserved.<br>
|
|
This is an automated message — please do not reply.
|
|
</p>
|
|
</td>
|
|
</tr>
|
|
|
|
</table>
|
|
</td>
|
|
</tr>
|
|
</table>
|
|
</body>
|
|
</html>`;
|
|
}
|
|
|
|
// ---------------------------------------------------------------------------
|
|
|
|
async function sendPasswordResetEmail(toEmail, rawToken) {
|
|
const resetUrl = `${process.env.APP_BASE_URL}?reset_token=${rawToken}`;
|
|
const from = process.env.MAILGUN_FROM || 'noreply@loreal.com';
|
|
|
|
const html = emailWrapper({
|
|
headline: 'Reset your password',
|
|
ctaUrl: resetUrl,
|
|
ctaLabel: 'Reset my password',
|
|
bodyHtml: `
|
|
<p style="margin:0 0 12px;font-size:15px;color:#3a3a3a;line-height:1.7;">
|
|
We received a request to reset the password for your SLA Calculator account.
|
|
Click the button below to choose a new password.
|
|
</p>
|
|
<p style="margin:0;font-size:13px;color:#9a9a9a;line-height:1.7;">
|
|
This link expires in <strong style="color:#3a3a3a;">1 hour</strong>.
|
|
</p>`,
|
|
footerNote: 'If you did not request a password reset, you can safely ignore this email — your password will not be changed.',
|
|
});
|
|
|
|
const text = `Reset your SLA Calculator password\n\nWe received a request to reset your password.\n\nClick the link below to set a new password (valid for 1 hour):\n${resetUrl}\n\nIf you did not request this, please ignore this email.`;
|
|
|
|
return getClient().messages.create(process.env.MAILGUN_DOMAIN, {
|
|
from,
|
|
to: [toEmail],
|
|
subject: 'Reset your SLA Calculator password',
|
|
text,
|
|
html,
|
|
});
|
|
}
|
|
|
|
async function sendVerificationEmail(toEmail, rawToken) {
|
|
const verifyUrl = `${process.env.APP_BASE_URL}?verify_token=${rawToken}`;
|
|
const from = process.env.MAILGUN_FROM || 'noreply@loreal.com';
|
|
|
|
const html = emailWrapper({
|
|
headline: 'Verify your email address',
|
|
ctaUrl: verifyUrl,
|
|
ctaLabel: 'Verify my email',
|
|
bodyHtml: `
|
|
<p style="margin:0 0 12px;font-size:15px;color:#3a3a3a;line-height:1.7;">
|
|
Welcome to the SLA Calculator. Please verify your email address to activate your account.
|
|
</p>
|
|
<p style="margin:0;font-size:13px;color:#9a9a9a;line-height:1.7;">
|
|
This link expires in <strong style="color:#3a3a3a;">24 hours</strong>.
|
|
</p>`,
|
|
footerNote: 'If you did not create an SLA Calculator account, you can safely ignore this email.',
|
|
});
|
|
|
|
const text = `Verify your SLA Calculator email\n\nPlease verify your email address to activate your account:\n${verifyUrl}\n\nThis link is valid for 24 hours.`;
|
|
|
|
return getClient().messages.create(process.env.MAILGUN_DOMAIN, {
|
|
from,
|
|
to: [toEmail],
|
|
subject: 'Verify your SLA Calculator email',
|
|
text,
|
|
html,
|
|
});
|
|
}
|
|
|
|
module.exports = { sendPasswordResetEmail, sendVerificationEmail };
|