Registration creates a new account plus its first user; login authenticates an existing one; both set a deklarix_session cookie (HttpOnly, SameSite=Strict, Secure only when the request itself came over TLS — hardcoding Secure=true would break local http://localhost development, since browsers won't store a Secure cookie over plaintext). requirePage protects full-page GETs (redirects to /login); requireAPI protects the htmx/download endpoints (401, since those are only ever called from an already-authenticated page — an unauthenticated hit there is the exception, e.g. a session expiring mid-use). handleCheck now creates submissions under the current account. handleArchive and handleDossierDownload compare the submission's account against the caller's and return 404 on mismatch — not 403, which would confirm the ID exists to a different tenant. Login failure uses the same message for "no such email" and "wrong password" to avoid account enumeration. Restructured templates along the way: layout.html now only holds reusable fragments ("head", "nav"); each full page (index/login/register) is its own top-level named template. The previous layout+content nesting would have broken the moment a second page defined "content" — Go's html/template keys blocks by name across the whole parsed set, not per file, so two pages both defining "content" would silently overwrite each other. Verified against a real running instance (not just Go's test recorder): started the compiled binary against a fresh Postgres and drove the whole flow with curl — anonymous redirect, registration setting a real cookie, authenticated page load, logout clearing both the cookie and the server-side session row, and being locked out again afterward. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
34 lines
970 B
HTML
34 lines
970 B
HTML
{{define "index"}}<!doctype html>
|
|
<html lang="de">
|
|
<head>{{template "head" .}}</head>
|
|
<body>
|
|
{{template "nav" .}}
|
|
<h1>Pre-Publish-Prüfung</h1>
|
|
<p>Caption und Plattform eingeben, um auf Kennzeichnungsrisiken zu prüfen.</p>
|
|
|
|
<form hx-post="/pruefen" hx-target="#ergebnis" hx-swap="innerHTML">
|
|
<label for="platform">Plattform</label>
|
|
<select id="platform" name="platform" required>
|
|
<option value="instagram">Instagram</option>
|
|
<option value="tiktok">TikTok</option>
|
|
</select>
|
|
|
|
<label for="post_type">Beitragstyp</label>
|
|
<select id="post_type" name="post_type" required>
|
|
<option value="feed">Feed</option>
|
|
<option value="reel">Reel</option>
|
|
<option value="story">Story</option>
|
|
<option value="video">Video</option>
|
|
</select>
|
|
|
|
<label for="caption">Caption</label>
|
|
<textarea id="caption" name="caption" rows="6" required></textarea>
|
|
|
|
<button type="submit">Prüfen</button>
|
|
</form>
|
|
|
|
<div id="ergebnis"></div>
|
|
</body>
|
|
</html>
|
|
{{end}}
|