Privater Bereich /api/privat fuer Behoerdenfotos (d4rk-rp-planung#227 H1)

Polizeifotos aus dem Spiel duerfen nicht unter /f/ liegen, wo jeder sie mit
der Adresse bekommt. Neu:

- eigener Ordner DATA_DIR/privat neben files/ (fuer /f/ und /t/ durch
  Bauart unerreichbar), eigene Tabelle privat_media, eigene Vorschauen
- PUT/GET /api/privat/datei/<pfad>, ?vorschau=1; kein Ueberschreiben (409),
  kein Loeschweg; Cache-Control private, no-store
- Token-Fessel "privat": ein privater Token kommt an keinen oeffentlichen
  Weg (upload, Fivemanage, Liste), ein oeffentlicher an keinen privaten
- Dashboard: Kaestchen "nur privater Bereich" beim Anlegen und Bearbeiten,
  Marke in der Liste
- checkPathUnter: dieselbe Pfadregel fuer beide Ablagen
- tools/sichern.ps1 packt privat/ mit und zaehlt Dateien gegen Eintraege

Geprueft mit tools/privat-pruefen.mjs gegen einen Wegwerf-Container des
Abbilds: 21/21, mit Kontrollen (oeffentliches Bild MUSS unter /f/ kommen).
Dashboard gemessen (kopfloser Edge): 7/7.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
This commit is contained in:
D4rkst3randClaude Opus 5.5 committed 2026-10-16 21:36:16 +02:00
1 parent c8080fb2eb
commit 6630def7b2
14 files changed
+641 -15

No files matched your search

+6
View File
@@ -36,6 +36,7 @@ import { fivemanageRoutes } from './routes/fivemanage.js'
import { freigabeRoutes } from './routes/freigabe.js'
import { statusRoutes } from './routes/status.js'
import { dashRoutes, papierkorbAusleeren } from './routes/dash.js'
import { privatRoutes } from './routes/privat.js'
const app = new Hono()
@@ -232,6 +233,11 @@ app.route('/api', uploadRoutes)
app.route('/api', fivemanageRoutes)
app.route('/api/dash', dashRoutes)
// Der private Bereich (d4rk-rp-planung#227): nur mit einem Token, der die
// Fessel "privat" traegt. VOR /api eingehaengt waere es dasselbe -- uploadRoutes
// kennt keinen Pfad /privat --, aber die eigene Zeile macht die Grenze sichtbar.
app.route('/api/privat', privatRoutes)
// Die Freigaben. OHNE Anmeldung und mit Absicht kurz: /s/<schluessel> laesst
// sich vorlesen und abtippen.
app.route('/api/s', freigabeRoutes)