Files

86 lines
3.3 KiB
JavaScript
Raw Permalink Normal View History

2026-09-13 20:12:28 +01:00
'use strict';
const { db } = require('../db');
const DEFAULTS = {
request_to_admin: {
subject: 'Action needed: access request from {{username}} awaiting approval',
body_html:
'<h2>Access request pending approval</h2>' +
'<p><strong>{{username}}</strong> ({{email}}) has requested access to ' +
'the {{target_type}} <strong>{{target_name}}</strong>.</p>' +
'<p>Requested at {{created_at}}. Request reference #{{request_id}}.</p>' +
'<p><strong>{{pending_count}}</strong> request(s) are currently waiting for a decision.</p>' +
'<p><a href="{{approvals_url}}" style="display:inline-block;background:#1f7a70;color:#fff;' +
'padding:10px 18px;border-radius:8px;text-decoration:none;font-weight:600">' +
'Review pending requests</a></p>' +
'<p style="font-size:12px;color:#6b7280">If the button does not work, open: {{approvals_url}}</p>',
},
approval_to_user: {
subject: 'Your access request was approved',
body_html:
'<h2>Request approved</h2>' +
'<p>Hello {{username}},</p>' +
'<p>Your request to access the {{target_type}} <strong>{{target_name}}</strong> ' +
'has been <strong>approved</strong>. You may now open it from the View Data page.</p>' +
'<p><strong>{{validity}}</strong> — access expires on {{expires_at}}.</p>' +
'<p>A live countdown is shown next to the folder on the View Data page.</p>',
},
denial_to_user: {
subject: 'Your access request was declined',
body_html:
'<h2>Request declined</h2>' +
'<p>Hello {{username}},</p>' +
'<p>Unfortunately your request to access the {{target_type}} ' +
'<strong>{{target_name}}</strong> was not approved at this time.</p>',
},
};
function seedDefaults() {
const exists = db.prepare('SELECT key FROM email_templates WHERE key = ?');
const insert = db.prepare(
'INSERT INTO email_templates (key, subject, body_html) VALUES (?, ?, ?)'
);
for (const [key, t] of Object.entries(DEFAULTS)) {
if (!exists.get(key)) insert.run(key, t.subject, t.body_html);
}
}
function getTemplate(key) {
return (
db.prepare('SELECT * FROM email_templates WHERE key = ?').get(key) ||
DEFAULTS[key]
);
}
function render(str, vars) {
return String(str).replace(/\{\{\s*([\w.]+)\s*\}\}/g, (_, k) =>
vars[k] !== undefined && vars[k] !== null ? String(vars[k]) : ''
);
}
/** Returns { subject, html } with placeholders filled and footer appended. */
function buildEmail(key, vars) {
const t = getTemplate(key);
const footer =
'<hr style="margin-top:32px;border:none;border-top:1px solid #d8d8d8">' +
'<p style="color:#8a8a8a;font-size:12px;margin-top:12px">' +
'© 2026 Martinhal IT - Joao Vaz - Version 1.5 Patch 0.2</p>';
return {
subject: render(t.subject, vars),
html: render(t.body_html, vars) + footer,
};
}
const PLACEHOLDERS = {
request_to_admin: ['username', 'email', 'target_type', 'target_name', 'created_at',
'request_id', 'pending_count', 'approvals_url', 'portal_url'],
approval_to_user: ['username', 'email', 'target_type', 'target_name', 'portal_url',
'validity', 'expires_at'],
denial_to_user: ['username', 'email', 'target_type', 'target_name', 'portal_url'],
};
module.exports = {
seedDefaults, getTemplate, render, buildEmail,
DEFAULTS, PLACEHOLDERS, KEYS: Object.keys(DEFAULTS),
};