feat(scripts): add mustache render-template via Responses pages

Add HTML template kind to Responses with a seeded system email-default
template, render-template.js using Mustache, and html body support in
send-email. Templates are editable but system pages cannot be deleted.

Co-authored-by: Nasyarobby Putra <nasyarobby@gmail.com>
This commit is contained in:
Cursor Agent
2026-08-15 01:44:51 +00:00
co-authored by nsrb
parent 23ce72fec2
commit 46e2cbb83b
12 changed files with 426 additions and 50 deletions
+6 -6
View File
@@ -8,7 +8,7 @@ import {
deleteHttpAuth,
revealHttpAuthLiterals,
} from "../../http-auths-store.js";
import { getHttpPageByName } from "../../http-pages-store.js";
import { getHttpPageByName, assertHttpResponsePage } from "../../http-pages-store.js";
/**
* @param {import("fastify").FastifyInstance} fastify
@@ -62,11 +62,11 @@ export default async function httpAuthsPlugin(fastify) {
String(body.unauthorized_response).length > 0
) {
const page = await getHttpPageByName(String(body.unauthorized_response));
if (!page) {
return reply
.code(400)
.send({ error: `unknown response page "${body.unauthorized_response}"` });
}
assertHttpResponsePage(
page,
String(body.unauthorized_response),
"unauthorized_response",
);
}
const auth = await upsertHttpAuth({
name: String(body.name),
+9 -1
View File
@@ -2,6 +2,7 @@ import {
assertPageName,
assertMime,
assertHttpStatus,
assertPageKind,
listHttpPages,
getHttpPageById,
getHttpPageByName,
@@ -37,11 +38,13 @@ export default async function httpPagesPlugin(fastify) {
content?: string,
mime?: string,
status?: number,
kind?: string,
}} */ (req.body ?? {});
try {
assertPageName(String(body.name ?? ""));
assertMime(body.mime);
assertHttpStatus(body.status, 200);
const kind = assertPageKind(body.kind, "response");
if (typeof body.content !== "string") {
return reply.code(400).send({ error: "content must be a string" });
}
@@ -50,6 +53,7 @@ export default async function httpPagesPlugin(fastify) {
content: body.content,
mime: String(body.mime),
status: body.status,
kind,
});
return reply.send({ page });
} catch (err) {
@@ -63,7 +67,11 @@ export default async function httpPagesPlugin(fastify) {
if (!existing) {
return reply.code(404).send({ error: "page not found" });
}
await deleteHttpPage(id);
try {
await deleteHttpPage(id);
} catch (err) {
return reply.code(err.statusCode ?? 500).send({ error: err.message });
}
return { ok: true };
});
}