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:
1 parent
c8080fb2eb
commit
6630def7b2
14 files changed
+641
-15
No files matched your search
@@ -69,10 +69,21 @@ const requireToken = async (c: Context<{ Variables: Vars }>, next: Next) => {
|
||||
401,
|
||||
)
|
||||
}
|
||||
// Ein PRIVATER Token kommt an keinen oeffentlichen Weg (d4rk-rp-planung#227):
|
||||
// sonst laege ein Polizeifoto nach einem falschen Aufruf unter /f/, fuer
|
||||
// jeden lesbar, der die Adresse kennt.
|
||||
if (token.privat) {
|
||||
return c.json({ error: PRIVAT_NUR_DORT }, 403)
|
||||
}
|
||||
c.set('token', token)
|
||||
await next()
|
||||
}
|
||||
|
||||
/** Die Antwort an einen privaten Token auf einem oeffentlichen Weg. Auch von
|
||||
* fivemanage.ts benutzt -- EIN Satz fuer beide Wachen. */
|
||||
export const PRIVAT_NUR_DORT =
|
||||
'Dieser Token gilt nur fuer den privaten Bereich (/api/privat) und kann hier nicht hochladen.'
|
||||
|
||||
/** Prueft das Gesamtkontingent. Gibt einen SATZ zurueck, wenn es reisst.
|
||||
*
|
||||
* Die Meldung nennt Zahlen: "belegt 1,9 GB von 2 GB, diese Datei braucht 130
|
||||
@@ -126,7 +137,7 @@ function groesse(n: number): string {
|
||||
*
|
||||
* An EINER Stelle, damit die Einordnung beim Hochladen und die Anzeige in der
|
||||
* Galerie nicht auseinanderlaufen koennen. */
|
||||
function artVon(mime: string): string {
|
||||
export function artVon(mime: string): string {
|
||||
const m = mime.split(';')[0]?.trim().toLowerCase() ?? ''
|
||||
if (m.startsWith('image/')) return 'bild'
|
||||
if (m.startsWith('video/')) return 'video'
|
||||
@@ -149,7 +160,7 @@ uploadRoutes.use('/exists', requireToken)
|
||||
uploadRoutes.use('/exists/*', requireToken)
|
||||
|
||||
/** Den Rumpf einsammeln, in welcher der drei Formen er auch kommt. */
|
||||
async function readBody(
|
||||
export async function readBody(
|
||||
c: Context<{ Variables: Vars }>,
|
||||
): Promise<{ data: Buffer; path?: string; filename?: string }> {
|
||||
const contentType = c.req.header('content-type') ?? ''
|
||||
|
||||
Reference in new issue
Block a user