Bisher richtete die App den Pi per SSH ein: Adresse, Benutzer und Passwort ins Webformular, Knopf druecken. Das verlangte ein SSH-Passwort in einem Browser, ein weiteres Paket (ssh2) und eine Verbindung vom Server zum Pi. Jetzt andersherum. Die App legt einen Link bereit und wartet. Auf dem Pi wird das Skript geholt und gestartet, dort wird der Drucker ausgewaehlt, und am Ende meldet sich der Pi von selbst an. Wer einen Drucker ansteckt, steht ohnehin am Pi - dort gehoert auch die Frage hin, welcher es sein soll. Die Auswahl zeigt Klartextnamen aus dem sysfs: "EPSON TM-T88IV" statt "lp0". Bei mehreren Druckern ist das der Unterschied zwischen Wissen und Raten. Das ausgelieferte Skript ist zusammengesetzt, nicht statisch: einrichten.sh ist eine Vorlage, in die setup.js Adresse, Code, print-server.py und die systemd-Unit einsetzt. Heraus kommt EINE Datei - auf dem Pi ist nichts nachzuladen, und eine halb geglueckte Uebertragung kann es nicht geben. Zwei Endpunkte muessen ohne Anmeldung auskommen, weil der Pi sich bei Authentik nicht anmelden kann. Der Einrichtungscode ist dort der einzige Schluessel: 32 Zeichen, gilt einmal und 30 Minuten, nur im Arbeitsspeicher, zeitkonstant verglichen, hinter einem eigenen Zaehler. Die Adresse des Pi wird der Verbindung entnommen und nicht dem Rumpf der Anmeldung - was der Pi ueber sich behauptet, koennte auch jemand anders behaupten. Die eigene Adresse leitet die App aus dem Host-Kopf ab und prueft sie streng, statt sie zu maskieren: der Wert landet in einem Shell-Skript. Geprueft am echten Pi (Debian 13, TM-T88IV): Link erzeugen, am Pi abholen, Drucker aus der Liste waehlen, Anmeldung, Uebernahme, Probedruck. Dazu die Abweise: verbrauchter Code, falscher Code, Abholung ohne Code, und dass die uebrige API weiterhin 401 liefert. Entfaellt: provision.js, install.sh, die Abhaengigkeit ssh2, das SSH-Formular. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
93 lines
3.7 KiB
Bash
93 lines
3.7 KiB
Bash
# ===========================================================================
|
|
# Timer App - Konfiguration
|
|
# Diese Datei nach ".env" kopieren und ausfuellen. Die .env gehoert NICHT
|
|
# in die Versionsverwaltung.
|
|
# ===========================================================================
|
|
|
|
# --- Netzwerk --------------------------------------------------------------
|
|
|
|
PORT=3003
|
|
|
|
# Auf welcher Adresse gelauscht wird.
|
|
# 127.0.0.1 = nur lokal erreichbar -> RICHTIG, wenn ein Reverse Proxy
|
|
# (nginx, Caddy, Traefik) davorsteht
|
|
# 0.0.0.0 = im ganzen Netz erreichbar -> nur ohne Reverse Proxy, und dann
|
|
# bitte COOKIE_SECURE=false beachten (siehe unten)
|
|
HOST=127.0.0.1
|
|
|
|
# Anzahl der Proxy-Ebenen davor. Bei genau einem Reverse Proxy: 1.
|
|
# Ohne Reverse Proxy: false
|
|
TRUST_PROXY=1
|
|
|
|
# --- Sicherheit ------------------------------------------------------------
|
|
|
|
# ACHTUNG, haeufigste Fehlerquelle beim Deployment:
|
|
# true -> Cookie wird NUR ueber HTTPS gesetzt. Laeuft die App ueber http://,
|
|
# scheitert der Login STUMM (Passwort wird akzeptiert, aber die
|
|
# Sitzung kommt nie zustande).
|
|
# false -> auch ueber http:// nutzbar. Nur im internen Netz vertretbar.
|
|
COOKIE_SECURE=true
|
|
|
|
# Zufaelliger Wert, unterschreibt die Sitzungs-Cookies.
|
|
# Erzeugen mit: npm run gen-secret
|
|
SESSION_SECRET=HIER_EINEN_ZUFALLSWERT_EINSETZEN
|
|
|
|
# Passwort fuer die Anmeldung. ZWEI Wege - bitte den ersten waehlen:
|
|
#
|
|
# 1) EMPFOHLEN: bcrypt-Hash. Erzeugen mit:
|
|
# npm run hash-password -- "MeinPasswort"
|
|
PASSWORD_HASH=
|
|
|
|
# 2) Notfalls Klartext. Wird beim Start gehasht, steht aber lesbar in dieser
|
|
# Datei. Der Server warnt beim Start. Nur eins von beiden setzen.
|
|
#PASSWORD=
|
|
|
|
# Anmeldeversuche pro Zeitfenster (Schutz gegen Durchprobieren)
|
|
LOGIN_MAX_ATTEMPTS=20
|
|
LOGIN_WINDOW_MIN=15
|
|
|
|
# --- Daten -----------------------------------------------------------------
|
|
|
|
# Pfad zur SQLite-Datei. Standard: ../data/timer.db relativ zum backend/.
|
|
# Das Verzeichnis muss existieren und fuer den Dienst-Benutzer schreibbar sein.
|
|
#DB_PATH=/var/lib/timer-app/timer.db
|
|
|
|
# Nur beim allerersten Start relevant: setzt den Anfangstarif.
|
|
# Danach wird der Tarif in der Datenbank gepflegt (Menue "Einstellungen").
|
|
RATE_PER_10MIN=10
|
|
|
|
# --- Bondrucker ------------------------------------------------------------
|
|
# Der Bondrucker haengt per USB an einem Raspberry Pi. Auf dem Pi laeuft die
|
|
# Bruecke aus deploy/bondrucker/ und nimmt fertige Druckdaten per HTTP an.
|
|
#
|
|
# ACHTUNG: Diese vier Werte sind nur die STARTWERTE beim allerersten Start.
|
|
# Danach lebt der Druckerzugang in der Datenbank und wird ueber die Oberflaeche
|
|
# gepflegt - "Einstellungen" -> "Drucker einrichten" legt einen Link bereit,
|
|
# ueber den sich ein Pi selbst einrichtet und anschliessend hier anmeldet.
|
|
# Eine spaetere Aenderung hier bleibt also wirkungslos.
|
|
#
|
|
# Wer gar keinen Drucker hat, laesst alles leer: die App laeuft dann genau wie
|
|
# vorher, nur ohne Bon-Knoepfe.
|
|
|
|
PRINTER_HOST=
|
|
PRINTER_PORT=9100
|
|
|
|
# Muss mit PRINT_TOKEN aus /etc/bondrucker/env auf dem Pi uebereinstimmen.
|
|
# Das Einrichtungsskript gibt den Wert am Ende aus, falls es sich nicht selbst
|
|
# bei der App anmelden konnte.
|
|
PRINTER_TOKEN=
|
|
|
|
# Zeichen je Zeile. 42 = 80-mm-Papier (Standard), 32 = 58-mm-Papier.
|
|
PRINTER_WIDTH=42
|
|
|
|
# Abbruch, wenn der Pi nicht antwortet. Lieber kurz: ein haengender Drucker
|
|
# darf das Beenden eines Timers nicht blockieren.
|
|
PRINTER_TIMEOUT_MS=6000
|
|
|
|
# Adresse, unter der der Drucker-Pi diese App erreicht. Normalerweise LEER
|
|
# lassen: die App leitet sie aus der Anfrage ab, also aus der Adresse, unter der
|
|
# gerade jemand die Einstellungen offen hat. Nur setzen, wenn der Pi die App
|
|
# unter einem anderen Namen erreichen muss als der Browser.
|
|
# Beispiel: PUBLIC_URL=http://192.168.1.50:3003
|
|
PUBLIC_URL=
|