chore: Screenshot-Instanz mit eingerichteten Meldewegen

Die Wegwerf-Instanz bekommt je Lauf ein frisch erzeugtes VAPID-Paar und
einen Mailhost, den es nie geben wird. Damit zeigen die Bilder den
eingerichteten Normalfall statt zweier Warnhinweise — und im Verzeichnis
bleibt kein privater Schluessel liegen.

Kein Push-Geraet mehr in den Demo-Daten: Seine Schluessel liegen
verschluesselt, und der Versand entfernt jedes Geraet, dessen Schluessel
er nicht lesen kann. Der erfundene Eintrag waere beim ersten Lauf wieder
verschwunden.

Dass der Browser im Bild "blockiert" meldet, laesst sich nicht abstellen:
Chromium im Kopflosbetrieb antwortet auf Notification.permission immer so.
Das Handbuch sagt es jetzt dazu.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
Florian Wilde
2026-09-11 13:34:40 +02:00
co-authored by Claude Opus 5
parent 7bef4351ec
commit 35ecb2fa78
4 changed files with 25 additions and 15 deletions
+11
View File
@@ -57,5 +57,16 @@ services:
WEBAUTHN_RP_NAME: Planer
WEBAUTHN_ORIGIN: http://127.0.0.1:${SCREENSHOT_APP_PORT:-3200}
DEMO_MODUS: 'true'
# Damit die Karte "Benachrichtigungen" den Normalfall zeigt und nicht
# den Hinweis, dass nichts eingerichtet ist. Das Schluesselpaar erzeugt
# scripts/screenshots.ts fuer jeden Lauf neu – es steht bewusst nirgends
# im Verzeichnis.
VAPID_OEFFENTLICH: ${SCREENSHOT_VAPID_OEFFENTLICH:-}
VAPID_PRIVAT: ${SCREENSHOT_VAPID_PRIVAT:-}
VAPID_KONTAKT: mailto:planer@planer.invalid
# Ein Host, den es nie geben wird: die Oberflaeche zeigt E-Mail als
# moeglich, hinaus geht trotzdem nichts.
SMTP_HOST: smtp.planer.invalid
SMTP_ABSENDER: Planer <planer@planer.invalid>
ports:
- '${SCREENSHOT_APP_PORT:-3200}:3000'
+3
View File
@@ -6,6 +6,9 @@ Wichtige. Was du hier einschaltest, kommt. Alles andere nicht.
![Benachrichtigungen in den Einstellungen](../bilder/benachrichtigungen-hell-schreibtisch.png)
_Der Browser auf dem Bild hat Benachrichtigungen blockiert — so sieht die
Karte aus, wenn die Erlaubnis fehlt. Wie du sie erteilst, steht weiter unten._
Du findest die Einstellung unter **Einstellungen → Benachrichtigungen**.
## Die zwei Wege
+4 -15
View File
@@ -437,21 +437,10 @@ async function main(): Promise<void> {
},
})
await db.pushGeraet.deleteMany({ where: { benutzerId: benutzer.id } })
await db.pushGeraet.create({
data: {
benutzerId: benutzer.id,
// Erfunden und unerreichbar. Die Schlüsselfelder halten sonst
// verschlüsselte Werte; hier stehen Platzhalter, weil aus der
// Demo-Instanz ohnehin nichts hinausgeht.
endpunkt: 'https://push.invalid/demo-arbeitsplatz',
p256dh: 'demo',
auth: 'demo',
bezeichnung: 'Firefox auf Windows',
erstelltAm: new Date(Date.UTC(2026, 1, 3, 8, 20)),
zuletztBenutzt: new Date(Date.UTC(2026, 2, 17, 6, 5)),
},
})
// Kein Push-Gerät in den Demo-Daten: Seine Schlüssel liegen
// verschlüsselt, und der Versand entfernt jedes Gerät, dessen Schlüssel er
// nicht lesen kann. Ein erfundener Eintrag verschwände beim ersten Lauf
// wieder — die Bilder zeigen deshalb den Zustand vor der ersten Anmeldung.
console.log(`Demo-Daten stehen bereit. Anmeldung: ${DEMO_EMAIL}`)
}
+7
View File
@@ -14,6 +14,7 @@
*/
import { spawnSync } from 'node:child_process'
import { fileURLToPath } from 'node:url'
import webpush from 'web-push'
const WURZEL = fileURLToPath(new URL('..', import.meta.url))
const PROJEKT = 'planer-screenshots'
@@ -22,10 +23,16 @@ const COMPOSE_DATEI = 'docker-compose.screenshots.yml'
const APP_PORT = process.env.SCREENSHOT_APP_PORT ?? '3200'
const DB_PORT = process.env.SCREENSHOT_DB_PORT ?? '5455'
// Frisches Paar je Lauf: Die Bilder sollen die eingerichtete Anwendung
// zeigen, ohne dass irgendwo ein privater Schluessel liegen bleibt.
const VAPID = webpush.generateVAPIDKeys()
const UMGEBUNG = {
...process.env,
SCREENSHOT_APP_PORT: APP_PORT,
SCREENSHOT_DB_PORT: DB_PORT,
SCREENSHOT_VAPID_OEFFENTLICH: VAPID.publicKey,
SCREENSHOT_VAPID_PRIVAT: VAPID.privateKey,
}
function meldung(text: string): void {