Zum Inhalt springen

Betrieb

Systemeinstellungen in der Oberfläche

Erreichbar über das Zahnrad im Kopfbereich → Einstellungen, nur für Administratoren. Sieben Bereiche mit eigener Adresse:

Bereich Inhalt
Allgemein Name der Installation, Logo
Funktionen ein systemweiter Schalter: darf ein Link dauerhaft gelten
Links vertrauenswürdige Ziel-Domains, Vorschauseite, Prüf-Frist, zwei Beschränkungen
Erscheinungsbild eigene tokens.css mit Farben und Schrift
E-Mail Versandweg, Absender, SMTP-Zugang, Test-Mail
Wartung Aufräumen von Hand anstoßen, Testlauf
Systemdaten Fassung und Aktualisierung, Betriebswerte, Diagnose, Bericht zum Kopieren

Der Bereich Links ist der wichtigste und steht deshalb in einem eigenen Kapitel: siehe Ziel-Prüfung.

Allgemein

Name erscheint als Wortmarke (wenn kein Logo hinterlegt ist), im Browser-Titel, in allen System-Mails und als Aussteller in der Authenticator-App. Hier darf der Unternehmensname stehen. Leer lassen setzt den Standard.

Logo erscheint im Kopfbereich und im Kopf der Mails. Empfohlen: SVG oder PNG mit durchsichtigem Hintergrund, Höhe etwa 32 Pixel. Ohne Logo steht dort der Name.

Bereits eingerichtete Zwei-Faktor-Anmeldungen behalten den alten Namen in der Authenticator-App. Der Aussteller steckt im QR-Code, nicht auf dem Server.

Funktionen

Eine Karte je Entscheidung: wem die Links gehören, die Gültigkeit von Shortlinks, eigene Kurz-Links, QR-Codes und der Passwortschutz von Links. Alle Werte stehen ab Werk so, wie sich das System ohne sie verhält — eine Aktualisierung nimmt einer laufenden Installation nichts weg, ohne dass jemand es entscheidet. Neben jeder Entscheidung steht, wie viele Links heute davon betroffen wären.

Eine Ausnahme von „nimmt nichts weg": der Schalter ganz oben. Ein Wechsel vom gemeinsamen Bestand in den Benutzer-Modus löscht alle Bereiche — die Links bleiben, die Gruppierung nicht. Die Karte nennt die Zahl vorher; rückgängig machen lässt es sich nicht. Was dabei genau passiert, steht unter Was der Schalter mit den Bereichen macht.

„Kein Ablauf" zur Auswahl stellen. Ohne diesen Schalter muss bei jedem Link ein Zeitraum gewählt werden. Bestehende dauerhafte Links laufen weiter — ihre Empfänger können nichts dafür. Die Option verschwindet nur aus allen Masken; beim nächsten Speichern eines solchen Links ist ein Zeitraum fällig, und die Maske sagt das vorher.

Warum das überhaupt ein Schalter ist: Ein dauerhafter Link hat kein berechenbares Ende. Das Aufräumen kann ihn nie stilllegen, also bleibt er, bis jemand ihn löscht. Wer eine Installation aufräumbar halten will, verbietet die Option — dann hat jeder Link ein Ende.

Höchstdauer. Vorgabe: ohne Begrenzung. Längere Zeiträume verschwinden aus allen Masken und aus der serverseitigen Prüfung — eine Grenze, die nur die Auswahl kürzt, wäre mit einem gefälschten Formularwert umgangen.

Eine Höchstdauer schließt „Kein Ablauf" mit aus, sonst wäre sie mit einem Griff zu umgehen. Beides zusammen wird beim Speichern abgelehnt und nicht stillschweigend aufgelöst: Ein Formular, das eine Angabe kommentarlos umdeutet, hinterlässt einen Betreiber, der eine Erfolgsmeldung gelesen und ein anderes Verhalten bekommen hat.

Bestehende Links werden nicht gekürzt. Beim Bearbeiten bleibt „Unverändert" wählbar, auch wenn die Restlaufzeit über der Höchstdauer liegt. Andernfalls verkürzte schon das Speichern eines geänderten Titels die Laufzeit eines Links im Umlauf — und das trifft dessen Empfänger, nicht den Bearbeitenden. Die Grenze gilt für neu gewählte Zeiträume.

Vorbelegung beim Anlegen. Womit die Auswahl steht, wenn niemand sie anfasst — und das ist der Regelfall: Die meisten Links entstehen, ohne dass jemand das Feld öffnet. Ohne Eintrag bleibt es bei „Kein Ablauf", also beim bisherigen Verhalten. Eine Vorbelegung, die es unter den geltenden Regeln nicht gibt („Kein Ablauf" bei verbotenen Dauerlinks, ein Zeitraum über der Höchstdauer), wird abgelehnt.

Eigene Kurz-Links zulassen. Vorgabe: ja. Ohne Häkchen bekommt jeder neue Link eine gewürfelte Adresse, und das Feld verschwindet aus der Anlegen-Maske — kein gesperrtes Feld, das eine Möglichkeit erklärt, die es hier nicht gibt.

Warum das eine Entscheidung ist, die vorher fällt: Eine Wunsch-Adresse ist bequem und in einer Installation mit mehreren Konten zugleich ein Verteilungsproblem. Wer als Erster shop, kontakt oder 2026 nimmt, hat sie für immer — eine vergebene Adresse wird nie wieder frei. Zurückdrehen lässt sich das nicht.

Der Schalter wirkt auch serverseitig: Ein trotzdem geschickter Wunsch wird abgelehnt, und die Live-Prüfung antwortet nicht mehr mit „frei". Ohne das wäre er ein Vorschlag, den ein selbst gebautes Formular oder eine noch offene alte Seite übergeht.

Bestehende Wunsch-Adressen bleiben unangetastet und funktionieren weiter. Die Karte nennt eine Schätzung, wie viele es sind — ob eine Adresse gewünscht oder gewürfelt war, wurde nie festgehalten, deshalb ist die Zahl eine Untergrenze.

QR-Codes

QR-Codes bereitstellen. Vorgabe: ja. Ohne Häkchen verschwinden sie aus allen Masken, und die Download-Adresse antwortet 404 — nicht 403. Eine 403 hieße „dir fehlt das Recht" und schickte den Nutzer zu Ihnen, um etwas zu erbitten, das es in dieser Installation gar nicht gibt.

Der Code führt auf die Kurz-Link, nicht auf das Ziel. Das ist der ganze Zweck: Ein gedruckter Code auf das Ziel gäbe alles auf, was dieser Dienst kann — Ablauf, Klick-Limit, Passwortschutz und ein später korrigiertes Ziel. Angeboten werden zwei Fassungen: PNG für Bildschirm, Präsentation und E-Mail, SVG für den Druck.

Warum die Vorgabe hier „an" ist, anders als bei einem Schalter, der etwas wegnimmt: Die Funktion ist neu, es gibt nichts wegzunehmen — und ihr Zweck ist gerade, den Nutzern einen Weg zu ersparen. Ein neuer Schalter, der auf „aus" steht, ist eine Funktion, die niemand findet.

Ausschalten nimmt nichts weg, was im Umlauf ist. Ein bereits heruntergeladener oder gedruckter Code funktioniert weiter — er ist nichts anderes als der Kurz-Link in einem anderen Gewand. Es lassen sich nur keine neuen mehr laden.

Was das System nicht kann: Logo in der Mitte, Farben, gerundete Module. Jede dieser Verzierungen kostet Lesbarkeit, und ein Code, der im Halbdunkel nicht erkannt wird, ist als Aushang wertlos. Wer gestaltete Codes braucht, erzeugt sie aus dem Kurz-Link mit einem eigenen Werkzeug.

Technische Voraussetzung: die PHP-Erweiterung zlib — sie steckt in jedem üblichen PHP-Bau und steht deshalb nicht unter den Voraussetzungen. Fehlt sie doch, sagt die Karte es, das Häkchen bleibt trotzdem gespeichert, und die Codes tauchen erst auf, wenn die Erweiterung da ist. Bewusst nicht ins Häkchen zurückgeschrieben: Nach einem Serverumzug stünde die Funktion sonst auf „aus", ohne dass jemand sie abgeschaltet hätte.

Weder GD noch Imagick werden gebraucht. Die Bibliothek bacon/bacon-qr-code erzeugt nur SVG, EPS und Imagick; das PNG entsteht deshalb in der Anwendung selbst (App\Support\QrCode) — ein Schwarz-Weiß-Bild mit Farbtiefe 1, für das es keine Bildbibliothek braucht. Eine neue Pflicht-Erweiterung für eine Funktion, die Wege abnehmen soll, wäre der falsche Tausch: composer install bräche beim nächsten Update auf jedem Server ohne sie.

In welcher Fassung ein Konto den Code im Dialog nach dem Anlegen bekommt, entscheidet es selbst unter Nutzereinstellungen (Vorgabe PNG). Auf der Detailseite und im seitlichen Detailbereich stehen immer beide.

Mindestlänge, 4 bis 64 Zeichen, Vorgabe 8. Sie war lange fest auf 4 und damit deutlich unter den zwölf Zeichen, die dieselbe Anwendung für ein Konto-Passwort verlangt.

Ein Link-Passwort ist etwas anderes als ein Konto-Passwort: Es schützt eine öffentlich erreichbare Adresse und wird einem Empfänger über einen zweiten Kanal mitgeteilt und dort abgetippt. Eine Länge, die niemand weitergeben mag, führt dazu, dass der Schutz gar nicht erst gesetzt wird — deshalb 8 und nicht 12.

Bestehende Links bleiben unangetastet. Ein gespeichertes Passwort lässt sich nicht nachmessen, und ein Link im Umlauf würde für seine Empfänger unbrauchbar. Geprüft wird, sobald jemand ein Passwort setzt; der Hilfetext am Feld nennt die geltende Zahl.

Der Eingabe-Endpunkt ist auf zehn Versuche je zehn Minuten gedrosselt. Durchprobieren ist damit teuer — ein kurzes Passwort bleibt gegenüber jemandem, der den Link und den Anlass kennt, trotzdem ein schwaches Versprechen.

Erscheinungsbild

Farben und Schrift der gesamten Installation stecken in einer einzigen Datei, tokens.css. Der Weg ist bewusst: herunterladen — im Editor ändern — hochladen.

  1. Gerüst herunterladen. Ist noch kein eigenes Theme hinterlegt, kommt die mitgelieferte Datei; sonst die derzeit aktive. Sie ist durchgehend kommentiert, es steht also an jeder Variablen, was sie bewirkt.
  2. Ändern. Geändert werden die Werte, nicht die Namen. Ein Variablenname, den es nicht gibt, bleibt wirkungslos — die Seite bleibt heil, die Änderung passiert nur nicht. Ebenso wichtig ist der Platz: Es wirkt nur, was in :root, in .dark oder in einem anderen gewöhnlichen Selektor steht. :root gilt im hellen Modus (und im dunklen, sofern .dark nichts anderes sagt), .dark nur im dunklen.
  3. Hochladen. Nur .css. Die Datei wird vollständig übernommen und als <style>-Block in den Kopf jeder Seite gesetzt.

Die zwei Ebenen — hier entscheidet sich der Aufwand

Die Datei ist in zwei Abschnitte geteilt, und welchen Sie anfassen, entscheidet, wie viel sich ändert.

Ebene 1 — Grundpalette (--c-…). Acht Werte, und die ganze Installation sieht anders aus. --c-ink ist die Textfarbe, --c-surface-50 der Seitengrund, --c-border die Linienfarbe, --c-brand der Akzent — je einmal für hell (:root) und dunkel (.dark). Alles, was nichts Eigenes sagt, folgt diesen Werten.

Ebene 2 — Element-Tokens (--e-…). Ein Wert je Element. Auszugsweise:

Element Token
Fließtext --e-body
Überschriften --e-heading (h1/h2), --e-subheading (h3/h4)
Feld-Beschriftungen --e-label, Hilfetexte --e-help
Fließtext-Links --e-link, Unterstrich beim Zeigen --e-link-hover
Kopfleiste --e-nav (Fläche), --e-on-nav (Links und Symbole), --e-nav-line
Menüs --e-menu, --e-on-menu, --e-menu-line
Buttons --e-button (Fläche), --e-on-button (Beschriftung), --e-button-line
Buttons, zweite Stufe --e-button-secondary, --e-on-button-secondary, --e-button-secondary-line
Karten --e-card, --e-card-line
Tabellen --e-table, --e-table-head, --e-table-line
Dialoge und Toasts --e-dialog, --e-toast samt -line
Formularfelder --e-input, --e-on-input, --e-input-line, --e-input-hint
Trennlinien allgemein --e-line
Fußzeile --e-footer, --e-on-footer, --e-footer-line
Zeigen mit der Maus (alle Bedienelemente) --e-hover und --e-on-hover, je Element zusätzlich --e-button-hover, --e-nav-hover, …

Die vollständige Liste steht kommentiert in der Datei; jeder Token trägt dort seinen Zweck. Jeder dieser Werte zeigt per Vorgabe auf Ebene 1 und erbt, solange Sie ihn nicht anfassen.

Das ist der praktische Unterschied: Überschriften in Ihrer Hausfarbe bei schwarzem Fließtext sind eine Zeile —

:root {
    --e-heading: #1d4ed8;
}

— und nicht der Versuch, --c-ink zu ändern, was Fließtext, Überschriften, Kartenrahmen und Menütexte in einem Zug erwischt hätte.

Ein fester Farbwert gilt in beiden Modi. Sobald ein Element-Token auf eine Farbe statt auf die Palette zeigt, ist die Vererbung unterbrochen — auch im dunklen Modus. Soll er dort anders sein, wiederholen Sie ihn im Block .dark. Prüfen Sie in diesem Fall den Kontrast in beiden Modi.

Es gibt keinen Farbwähler. Dreißig Farbfelder in einem Formular könnten weniger und würden das Wichtigste nicht mitliefern: die Erklärung, welche Variable wohin wirkt.

Zurücksetzen stellt das mitgelieferte Theme wieder her. Die hochgeladene Datei wird dabei gelöscht — wer sie behalten will, lädt sie vorher herunter.

Wo die Datei liegt: storage/app/private/theme/tokens.css. Das Verzeichnis storage/ ist vom Deployment ausgenommen, eine Aktualisierung überschreibt das Theme also nicht. Ins Backup gehört es trotzdem (siehe Backup).

Wer Farben ändert, ändert Kontraste. Die Statusfarben dieser Anwendung sind auf knapp über 4,5:1 ausgelegt, in hell und dunkel getrennt. Der Abstand ist bewusst knapp (kräftige Farben lesen sich besser als blasse) und damit empfindlich. ACCESSIBILITY.md enthält die gemessenen Werte als Ausgangspunkt.

@theme wirkt hier nicht. Wer die Datei resources/css/tokens.css direkt aus dem Quelltext nimmt statt das Gerüst herunterzuladen, findet dort @theme-Blöcke. Die gehören zum Bauvorgang von Tailwind; ein Browser kennt diese Anweisung nicht und überliest sie samt Inhalt — ohne Fehlermeldung. Das Ergebnis sieht aus wie „halb übernommen": Die Farben greifen, Schrift, Radien und Statusfarben nicht. Das Gerüst aus dieser Oberfläche hat die Blöcke bereits an den richtigen Platz gerückt; wird trotzdem eine Datei mit @theme hochgeladen, meldet die Seite die betroffenen Zeilen — und übernimmt die Datei dennoch.

Hinweis auf fremde Server. Enthält die Datei ein @import oder ein url() auf eine fremde Adresse — typisch bei aus dem Netz kopierten Themes, die ihre Schrift von einem CDN holen —, wird das nach dem Hochladen mit Zeilennummer angezeigt. Das Theme ist trotzdem aktiv: Die Entscheidung gehört dem Betreiber. Zu bedenken ist nur, dass dann bei jedem Seitenaufruf die IP-Adresse jedes Besuchers an diesen Server geht. Das gehört in die Datenschutzerklärung — oder die Dateien werden lokal abgelegt.

Schriften werden nicht über die Oberfläche hochgeladen. Die Dateien (.woff2) werden von Hand nach public/fonts/ gelegt, der passende @font-face-Block gehört in die eigene tokens.css. Grund: Web-Schriften sind lizenzpflichtig, und wer eine ablegt, muss die Lizenz haben. Das ist eine Entscheidung am Server, keine in einem Browser-Formular.

E-Mail

Ohne Mail-Versand lassen sich keine Konten einrichten. Zwei Wege:

  • SMTP (empfohlen): Server, Port, Verschlüsselung, Benutzername, Passwort. Zustellbarkeit und Fehler sind nachvollziehbar. Port 587 für STARTTLS, 465 für SSL.
  • sendmail: nutzt das Mailsystem des Servers. Ohne korrekte SPF- und DKIM-Einträge landen solche Nachrichten oft im Spam-Ordner.

Das SMTP-Passwort wird verschlüsselt in der Datenbank abgelegt (mit APP_KEY) und nie wieder angezeigt. Ein leeres Passwortfeld bedeutet „unverändert lassen"; zum Entfernen gibt es eine eigene Auswahl.

Werte aus der Datenbank haben Vorrang vor der .env. Leere Felder bedeuten: es gilt der .env-Wert.

Die Test-Mail prüft den gespeicherten Zugang, nicht die Eingaben im Formular — also erst speichern, dann testen. Scheitert der Versand, steht die Meldung des Servers im Klartext da; sie ist hier die eigentliche Information.

Das Postfach der Absenderadresse muss jemand ansehen. Nutzer sehen bei jedem Link-Versand, ob der Mailserver die Nachricht angenommen hat — mehr kann diese Installation nicht wissen. Stellt der empfangende Server sie anschließend nicht zu, geht die Fehlermeldung an den Envelope-Absender, also an die unter Absenderadresse eingetragene Systemadresse, und nicht an den Nutzer.

Der Mail-Versand ist außerdem Voraussetzung für eine Einstellung im Bereich Links. Ist „Betroffene Links automatisch stilllegen" eingeschaltet, geht bei jedem Stilllegen eine Nachricht an den Eigentümer. Ohne Versand legt die Anwendung still, ohne dass es jemand erfährt — der Eigentümer merkt es erst an der Rückfrage seiner Empfänger. Die Einstellungsseite warnt in diesem Fall.

Systemdaten

Ganz oben steht die Fassung dieser Installation und, sofern die Prüfung eingeschaltet ist, ob es eine neuere gibt.

Offene Punkte holen den Administrator ab — sie warten nicht auf dieser Seite. Findet die Anwendung etwas, das dem ordnungsgemäßen Betrieb entgegensteht, steht das unter der Kopfzeile auf jeder Seite, für Administratoren und nur für sie. Derselbe Text, dieselbe Liste wie hier oben.

Der Grund ist die Eigenschaft, die alle diese Punkte teilen: Sie fallen im Alltag nicht auf. Ein fehlender Cron-Eintrag sieht aus wie ein System, in dem gerade nichts abzuräumen war. Ein aktiver Debug-Modus sieht aus wie gar nichts. Eine fehlende Public Suffix List sieht aus wie eine Anwendung, die eben gern Vorschauseiten zeigt. Wer diese Seite von sich aus aufruft, hat den Verdacht bereits — und genau der fehlt.

Die Meldung lässt sich nicht schließen. Das ist Absicht: Ein Schließen-Knopf machte aus jedem dieser Punkte eine Sache, die man auch wegklicken kann. Sie endet auf genau einem Weg, nämlich indem der Punkt behoben wird — danach verschwindet sie von selbst. Einzige Ausnahme beim Zeitpunkt: Ob die Public Suffix List vorliegt, wird aus Geschwindigkeitsgründen bis zu eine Minute lang gemerkt (php artisan shortlink:suffix-list setzt das sofort zurück). Alles andere — .env, Einstellungen, Cron — wirkt beim nächsten Seitenaufruf. Diese Seite hier prüft immer frisch.

Nutzer ohne Betriebsrechte sehen die Meldung nie. Ein fehlender Cron-Eintrag ist nichts, was sie beheben können, und eine dauerhafte Meldung ohne Handlungsmöglichkeit nutzt nur die Aufmerksamkeit ab, auf die es beim Administrator ankommt.

Auf neue Fassungen hinweisen ist ein Schalter auf dieser Seite. SHORTLINK_UPDATE_CHECK in der .env ist dabei nur der Ausgangswert — er gilt, solange hier niemand etwas entschieden hat; danach gilt die Entscheidung auf der Seite, in beide Richtungen. Die Seite nennt daneben, worauf der Ausgangswert steht.

Die Abfrage verrät dem Server hinter SHORTLINK_UPDATE_SOURCE IP-Adresse und Zeitpunkt dieser Installation — sonst nichts: keine Kennung, keine Nutzungsdaten, keine Rückmeldung über das Ergebnis. In einem abgeschotteten Netz ist sie ohnehin nur ein Timeout. Aktualisiert wird dadurch nichts.

Wo nachgesehen wird, bleibt in der .env (SHORTLINK_UPDATE_SOURCE, wirksam nach php artisan config:cache). Auf welchen Server diese Installation hört, ist eine Vertrauensentscheidung und gehört nicht in ein Formular, das jeder Administrator absenden kann — anders als das reine Ein und Aus, das nur eine Verbindung nach draußen abstellt oder wieder zulässt.

Die installierte Fassung steht in der Datei VERSION im Projektverzeichnis. Paket und Deployment schreiben sie; wer aus dem Quellcode installiert hat, sieht „unbekannt" — dann fehlt der Maßstab, und die Seite sagt das, statt zu raten.

Gibt es eine neuere Fassung, erscheint ein Knopf Paket bereitstellen. Er lädt das Release-Archiv, hält es gegen die veröffentlichte SHA256-Prüfsumme und entpackt es nach storage/app/private/updates/. Eingespielt wird dabei nichts. Danach zeigt die Seite den einen Befehl, der noch fehlt — mit dem Pfad dieser Installation schon eingesetzt:

sh storage/app/private/updates/<fassung>/update.sh /pfad/zu/dieser/installation

Mit --dry-run angehängt zeigt er vorher, was sich ändern würde. Was update.sh im Einzelnen tut und welche Wege es außerdem gibt: Aktualisieren.

Warum kein Knopf, der die Aktualisierung durchführt? Damit der Webserver den Programmcode überschreiben könnte, den er selbst ausführt, müsste app/, config/ und vendor/ für ihn beschreibbar sein. Jede Schreiblücke irgendwo im System wäre damit ein Weg, eigenen Code auszuführen. Diese Installation hält den Code bewusst unbeschreibbar — die Oberfläche nimmt deshalb den mühsamen Teil ab (URL suchen, Prüfsumme vergleichen, entpacken), der riskante bleibt ein Befehl im Terminal.

Die Prüfung ist abschaltbar (SHORTLINK_UPDATE_CHECK=false). Sie fragt einmal täglich beim Anbieter nach und verrät ihm dabei, dass es diese Installation gibt — samt IP-Adresse und Zeitpunkt. Nach außen geht eine GET-Anfrage und sonst nichts: keine Kennung dieser Installation, keine Nutzungsdaten. In einem abgeschotteten Netz läuft sie ohnehin nur in einen Timeout. Abgeschaltet erscheint statt der Fassungsangabe ein entsprechender Hinweis; alles andere funktioniert unverändert.

Bereitgestellte Pakete räumt shortlink:cleanup wieder ab, sobald sie eingespielt sind — Maßstab ist die Fassung, nicht das Alter.

Darunter: Webserver, PHP, Laravel, Datenbank, belegter und freier Speicher, Arbeitsspeicher sowie Queue, Cache und Sitzungen.

Oben stehen Warnungen, die Handeln erfordern. Es sind genau vier:

  • APP_ENV steht auf local — dann sind mehrere Schutzmaßnahmen abgeschaltet, unter anderem die Sperre gegen destruktive Datenbankbefehle (migrate:fresh, db:wipe).
  • APP_DEBUG=true — zeigt bei Fehlern interne Pfade und Konfigurationswerte.
  • Das Klick-Protokoll wird nie automatisch gelöscht (SHORTLINK_CLICK_LOG_RETENTION_DAYS=-1). Das ist eine gültige Wahl, aber eine, die personenbezogene Einträge unbefristet stehen lässt.
  • Die Public Suffix List fehlt oder ist nicht lesbar. Folge: jedes Ziel bekommt eine Vorschauseite.

Darunter die ausführliche Diagnose auf einen weiteren Klick und ein Bericht als Klartext zum Kopieren. Der Bericht enthält bewusst keine Zugangsdaten und keine Schlüssel — auch nicht gekürzt —, damit er ohne Prüfung in ein Ticket oder eine Nachricht eingefügt werden kann.

Quelle dieser Seite: docs/betrieb/einstellungen.md im Repository. Sie wird beim Bauen daraus erzeugt — Änderungen gehören in die Markdown-Datei, nicht in diese Seite.