New modules: - server/mailer.mjs: nodemailer transport wrapper - server/mail_perms.mjs: runtime permission store, persisted to disk New actions: - send-email: checks (caller, to, topic) permission before sending - set-mail-permission: grant/revoke permissions, gated by canApprove - get-mail-permissions: list current permissions Handler signature extended to handler(params, ctx) where ctx carries caller, users, mail_perm_store and mailer_send. Existing handlers ignore ctx so the change is backwards-compatible. SMTP config lives in secrets.json under optional 'smtp' key. Mail permissions path via --mail-perms or CONDUIT_MAIL_PERMS. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
24 lines
635 B
JavaScript
24 lines
635 B
JavaScript
import { readFileSync } from "fs";
|
|
|
|
export function load_secrets(file_path) {
|
|
if (!file_path) {
|
|
throw new Error("--secrets <path> is required");
|
|
}
|
|
let raw;
|
|
try {
|
|
raw = readFileSync(file_path, "utf8");
|
|
} catch (err) {
|
|
throw new Error(`Cannot read secrets file at ${file_path}: ${err.message}`);
|
|
}
|
|
let parsed;
|
|
try {
|
|
parsed = JSON.parse(raw);
|
|
} catch (err) {
|
|
throw new Error(`Secrets file is not valid JSON: ${err.message}`);
|
|
}
|
|
if (!parsed.users || typeof parsed.users !== 'object') {
|
|
throw new Error("Secrets file must have a top-level 'users' object");
|
|
}
|
|
return parsed; // callers destructure { users, smtp }
|
|
}
|