Files
Laufzettel/src/lib/adressen.ts
T
florian.wildeandClaude Opus 5 e7a2e2d5c7
Prüfung / pruefung (push) Canceled after 0s
Prüfung / e2e (push) Canceled after 0s
feat(tags): QR-Aufkleber, Geraeteseite, Etikettendruck und Scanner
Der Einstieg, fuer den die Anwendung gebaut ist: scannen, sehen was zu tun ist,
loslegen. `/t/<tagCode>` kennt drei Faelle — registriertes Geraet, vorgedruckter
Tag, unbekannter Code —, die Geraeteseite zeigt Zuweisungen, Schnellstart und
Historie, und beides ist am Handy bedienbar.

Im QR steht ausschliesslich `{APP_URL}/t/{tagCode}`: kein Name, keine
Seriennummer, kein Besitzer. Ein Aufkleber haengt jahrelang sichtbar am Geraet
und wird von jedem Telefon gelesen; was darauf steht, ist veroeffentlicht. Die
Masse sind gemessen, nicht behauptet: ein echtes PDF liefert 62 x 29 mm und A4,
und ein bei 300 dpi gerastertes Etikett wird mit demselben Decoder
zurueckgelesen, den auch der Scanner benutzt.

Drei Defekte zeigte erst der gebaute Stand, alle an den Naehten zwischen den
parallel gebauten Teilen: „Starten“ setzte IN_ARBEIT und sprang nicht, „Vorlage
zuweisen“ bot Vorlagen an, die der Dienst danach ablehnte, und die Geraeteliste
verlinkte nichts. Der unabhaengige Review fand drei Blocker — darunter, dass der
Scanner nie die native BarcodeDetector-API benutzte und dass ein Unterpfad in
APP_URL aus dem gedruckten QR herausfiel.

Closes #14

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-25 19:30:50 +00:00

52 lines
2.0 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
/**
* Adressen der Anwendung nach aussen (#007).
*
* Massgeblich ist APP_URL, nicht die eingehende Anfrage. Hinter einem Reverse
* Proxy traegt die Anfrage den internen Host und oft auch das falsche Schema –
* eine daraus gebaute Umleitung schickt den Benutzer dann an eine Adresse, die
* er gar nicht erreicht, und eine daraus gebaute OIDC-Rueckruf-Adresse passt
* nicht zu der beim Anbieter hinterlegten.
*
* Die Herkunft der Anfrage dient nur als Notnagel, damit die Anwendung auch ohne
* gesetzte APP_URL nicht stehen bleibt.
*/
export function oeffentlicheAdresse(pfad: string, ersatzHerkunft: string): URL {
const basis = process.env["APP_URL"]?.trim();
if (basis) {
try {
return new URL(pfad, basis);
} catch {
// Eine unbrauchbare APP_URL soll die Anmeldung nicht blockieren.
}
}
return new URL(pfad, ersatzHerkunft);
}
/**
* Die Basisadresse der Anwendung – **mit** ihrem Pfad (#014).
*
* `oeffentlicheAdresse` loest einen absoluten Pfad gegen die Basis auf, und
* dabei faellt ein Unterpfad heraus: aus `https://firma.de/laufzettel` und
* `/t/LZ-…` wird `https://firma.de/t/LZ-…`. Fuer eine Umleitung im laufenden
* Betrieb faellt das niemandem auf, weil der Reverse Proxy den Pfad ohnehin
* wieder anhaengt. Auf einem **gedruckten Aufkleber** ist es das Ende: er zeigt
* fuer immer ins Leere.
*
* Wer eine Adresse baut, die jemand behaelt, nimmt deshalb diese Basis und
* haengt relativ an. Der Schraegstrich am Ende entscheidet darueber, ob das
* letzte Pfadstueck ersetzt oder ergaenzt wird — er wird hier gesetzt, statt
* darauf zu hoffen.
*/
export function basisAdresse(ersatzHerkunft: string): URL {
const roh = process.env["APP_URL"]?.trim();
let basis: URL;
try {
basis = new URL(roh || ersatzHerkunft);
} catch {
// Eine unbrauchbare APP_URL soll den Druck nicht blockieren.
basis = new URL(ersatzHerkunft);
}
if (!basis.pathname.endsWith("/")) basis.pathname += "/";
return basis;
}