v_2.3
This commit is contained in:
@@ -0,0 +1,85 @@
|
||||
'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 2.3</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),
|
||||
};
|
||||
Reference in New Issue
Block a user