55 lines
4.3 KiB
JavaScript
55 lines
4.3 KiB
JavaScript
const DEFAULT_ACCOUNT_EMAIL_TEMPLATES = {
|
|
verificationSubject: 'Verify your Pulse Signage email address',
|
|
verificationBody: 'Hello [b][[display_name]][/b]!\n[[action_button]]\nThis [u]link[/u] expires in [i][[expiry_time]][/i].\nConfirm this email address: [[url]]',
|
|
resetSubject: 'Reset your Pulse Signage password',
|
|
resetBody: 'Hello [b][[display_name]][/b]!\n[[action_button]]\nThis [u]link[/u] expires in [i][[expiry_time]][/i].\nChoose a new password: [[url]]'
|
|
};
|
|
|
|
function formatAccountEmailExpiry(value, unit) {
|
|
const amount = Number(value);
|
|
const normalizedAmount = Number.isFinite(amount) && amount > 0 ? Math.round(amount) : 30;
|
|
const normalizedUnit = unit === 'hours' ? 'hour' : 'minute';
|
|
return normalizedAmount + ' ' + normalizedUnit + (normalizedAmount === 1 ? '' : 's');
|
|
}
|
|
|
|
function renderAccountEmailTemplate(subject, body, variables) {
|
|
const values = variables || {};
|
|
const replaceVariables = function (value) {
|
|
return String(value || '').replace(/\[\[([a-z_]+)\]\]/g, function (_match, key) {
|
|
return Object.prototype.hasOwnProperty.call(values, key) ? String(values[key]) : _match;
|
|
});
|
|
};
|
|
const renderedSubject = replaceVariables(subject);
|
|
const renderedText = replaceVariables(body);
|
|
const plainText = renderedText.replace(/\[(?:b|i|u)\]([\s\S]*?)\[\/(?:b|i|u)\]/gi, '$1');
|
|
const escapedBody = renderedText.replace(/&/g, '&').replace(/</g, '<').replace(/>/g, '>').replace(/"/g, '"').replace(/\[b\]([\s\S]*?)\[\/b\]/gi, '<strong>$1</strong>').replace(/\[i\]([\s\S]*?)\[\/i\]/gi, '<em>$1</em>').replace(/\[u\]([\s\S]*?)\[\/u\]/gi, '<u>$1</u>');
|
|
const actionLabel = String(values.action_label || 'Continue').replace(/&/g, '&').replace(/</g, '<').replace(/>/g, '>').replace(/"/g, '"');
|
|
const actionUrl = values.url ? String(values.url).replace(/&/g, '&').replace(/"/g, '"') : '';
|
|
const actionAlignment = values.action_alignment === 'left' || values.action_alignment === 'right' ? values.action_alignment : 'center';
|
|
const actionButton = actionUrl ? '<a href="' + actionUrl + '" style="display:inline-block;background:#111827;color:#ffffff;padding:12px 22px;text-decoration:none;border-radius:4px;font-weight:600;">' + actionLabel + '</a>' : '';
|
|
const actionBlock = actionButton ? '<div style="margin:24px 0;text-align:' + actionAlignment + ';">' + actionButton + '</div>' : '';
|
|
const plainLink = actionUrl ? '<a href="' + actionUrl + '">' + actionUrl + '</a>' : '';
|
|
const escapedBodyUrl = values.url ? String(values.url).replace(/&/g, '&').replace(/</g, '<').replace(/>/g, '>').replace(/"/g, '"') : '';
|
|
const hasButtonPlaceholder = escapedBody.indexOf('[[action_button]]') !== -1;
|
|
const hasUrlPlaceholder = String(body || '').indexOf('[[url]]') !== -1;
|
|
const bodyWithAction = hasButtonPlaceholder
|
|
? escapedBody.split(escapedBodyUrl).join(plainLink).replace(/\[\[action_button\]\]/g, actionBlock).replace(/\[\[action_link\]\]/g, plainLink)
|
|
: hasUrlPlaceholder
|
|
? escapedBody.split(actionUrl).join(actionBlock + plainLink)
|
|
: escapedBody.replace(/\[\[action_link\]\]/g, plainLink).replace(actionUrl, plainLink);
|
|
const bodyHtml = bodyWithAction.split(/\r?\n(?:[ \t]*\r?\n)+/).map(function (paragraph) {
|
|
const paragraphHtml = paragraph.replace(/\r?\n/g, '<br>');
|
|
if (paragraphHtml.indexOf(actionBlock) !== -1 && actionBlock) {
|
|
return paragraphHtml.split(actionBlock).map(function (part, index, parts) {
|
|
const text = part ? '<p style="margin:0 0 16px;">' + part + '</p>' : '';
|
|
return text + (index < parts.length - 1 ? actionBlock : '');
|
|
}).join('');
|
|
}
|
|
return paragraphHtml ? '<p style="margin:0 0 16px;">' + paragraphHtml + '</p>' : '';
|
|
}).join('');
|
|
const html = '<!doctype html><html><body style="margin:0;background:#f4f4f5;font-family:Arial,sans-serif;color:#27364b;"><div style="padding:24px 12px;"><div style="max-width:560px;margin:0 auto;text-align:center;color:#111827;font-size:20px;font-weight:700;padding:0 0 16px;">Pulse Signage</div><div style="max-width:560px;margin:0 auto;background:#ffffff;padding:32px;border-radius:4px;text-align:left;">' + bodyHtml + '</div></div></body></html>';
|
|
return { subject: renderedSubject, text: plainText, html: html };
|
|
}
|
|
|
|
module.exports = { DEFAULT_ACCOUNT_EMAIL_TEMPLATES, formatAccountEmailExpiry, renderAccountEmailTemplate };
|