harden browser routes with csrf checks and lock internal/dev endpoints

This commit is contained in:
Codex
2026-02-18 15:27:47 +00:00
parent 4814342156
commit f672677d4f
7 changed files with 200 additions and 30 deletions

View File

@@ -270,7 +270,7 @@ function renderLoginPage({ returnTo = "/app", error = null }) {
});
}
function renderAppPage({ userId, summary, jobs, flash = null }) {
function renderAppPage({ userId, summary, jobs, flash = null, showDeveloperActions = true }) {
const flashMarkup = flash ? `<div role="alert" class="alert alert-info mb-6 flex items-center gap-2 text-sm shadow-sm"><svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" class="stroke-current shrink-0 w-5 h-5"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M13 16h-1v-4h-1m1-4h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z"></path></svg><span>${escapeHtml(flash)}</span></div>` : "";
const jobsMarkup = jobs.length === 0
@@ -294,6 +294,33 @@ function renderAppPage({ userId, summary, jobs, flash = null }) {
</a>`).join("")}
</div>`;
const developerActionsMarkup = showDeveloperActions
? `<div class="space-y-6">
<div class="card bg-base-100 shadow-sm border border-base-content/10 sticky top-24">
<div class="card-body p-5">
<h2 class="card-title text-sm font-bold uppercase tracking-wider opacity-60 mb-2">Developer Actions</h2>
<form method="POST" action="/app/actions/topup" class="mb-4">
<label class="label text-xs font-medium pl-0">Top Up Credits</label>
<div class="join w-full">
<input name="amount" type="number" min="1" max="500" value="10" class="input input-bordered input-sm join-item w-full" />
<button class="btn btn-primary btn-sm join-item">Add</button>
</div>
</form>
<div class="divider my-2"></div>
<form method="POST" action="/app/actions/simulate-mention" class="flex flex-col gap-3">
<label class="label text-xs font-medium pl-0">Simulate Mention</label>
<input name="title" required class="input input-bordered input-sm w-full" placeholder="Article Title" />
<textarea name="body" required rows="3" class="textarea textarea-bordered textarea-sm w-full" placeholder="Paste article text..."></textarea>
<button class="btn btn-accent btn-sm w-full">Generate</button>
</form>
</div>
</div>
</div>`
: "";
return shell({
title: "Dashboard | XArtAudio",
user: { authenticated: true, userId },
@@ -325,8 +352,8 @@ function renderAppPage({ userId, summary, jobs, flash = null }) {
</div>
</div>
<div class="grid gap-8 md:grid-cols-3 mb-12">
<div class="md:col-span-2 space-y-8">
<div class="grid gap-8 ${showDeveloperActions ? "md:grid-cols-3" : ""} mb-12">
<div class="${showDeveloperActions ? "md:col-span-2" : ""} space-y-8">
<section>
<div class="flex items-center justify-between mb-6">
<h2 class="text-xl font-bold flex items-center gap-2">
@@ -337,31 +364,7 @@ function renderAppPage({ userId, summary, jobs, flash = null }) {
${jobsMarkup}
</section>
</div>
<div class="space-y-6">
<div class="card bg-base-100 shadow-sm border border-base-content/10 sticky top-24">
<div class="card-body p-5">
<h2 class="card-title text-sm font-bold uppercase tracking-wider opacity-60 mb-2">Developer Actions</h2>
<form method="POST" action="/app/actions/topup" class="mb-4">
<label class="label text-xs font-medium pl-0">Top Up Credits</label>
<div class="join w-full">
<input name="amount" type="number" min="1" max="500" value="10" class="input input-bordered input-sm join-item w-full" />
<button class="btn btn-primary btn-sm join-item">Add</button>
</div>
</form>
<div class="divider my-2"></div>
<form method="POST" action="/app/actions/simulate-mention" class="flex flex-col gap-3">
<label class="label text-xs font-medium pl-0">Simulate Mention</label>
<input name="title" required class="input input-bordered input-sm w-full" placeholder="Article Title" />
<textarea name="body" required rows="3" class="textarea textarea-bordered textarea-sm w-full" placeholder="Paste article text..."></textarea>
<button class="btn btn-accent btn-sm w-full">Generate</button>
</form>
</div>
</div>
</div>
${developerActionsMarkup}
</div>
`,
});