kerimatilganandClaude Opus 5.5 5c1174ff90 Setup-Skript: echten API-Token für den Service-Account anlegen
Authentik legt für Service-Accounts nur ein App-Passwort an, das die API als
Bearer-Token ablehnt (403 "Token invalid/expired"). Branding wird erst gesetzt,
wenn das Portal erreichbar ist, damit die Login-Seite kein kaputtes Logo zeigt.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-09-27 12:41:49 +02:00

Handy-Insel Portal

Zentrale Startseite für alle internen Tools der Handy-Insel, nach dem Vorbild von openDesk:

  • Portal (https://portal.handy-insel.de): Begrüßung, Kacheln aller Tools, für die man freigeschaltet ist, und „Aktuelles“ für interne Ankündigungen.
  • Kopfleiste <hi-topbar>: App-Umschalter (9-Punkte-Menü), Benutzermenü und Abmelden. Jedes Tool bindet sie mit einer Zeile ein, dadurch fühlt sich alles wie ein System an.
  • Authentik (https://login.handy-insel.de) bleibt die einzige Quelle für Benutzer, Gruppen und Rechte. Das Portal fragt Authentik, welche Apps ein Benutzer sehen darf. Wer in Authentik keinen Zugriff auf eine App hat, sieht auch keine Kachel.
                 ┌──────────── Authentik (SSO, Gruppen, App-Rechte) ───────────┐
Browser ─► Pangolin ─┬─► portal.handy-insel.de  (Kacheln, Aktuelles, /api/navigation, /topbar.js)
                     ├─► preis. / vvl. / zeit. / timer. / time. / data. / service.
                     │      └─ laden https://portal.handy-insel.de/topbar.js
                     └─► …

Rechte (Authentik-Gruppen)

Gruppe Mitglieder sieht zusätzlich
HI-Mitarbeiter alle Mitarbeiter Preisliste, VVL, Zeiterfassung, Timer, Kundenkarte, Datenübertragungen, Service, Portal
HI-Leitung Hubert Paperless; darf „Aktuelles“ schreiben
HI-Admin Kerim, Michi Paperless, PatchMon, Dev-Instanzen; darf „Aktuelles“ schreiben

Die Zuordnung App → Gruppen steht in scripts/authentik-setup.py (APP_ACCESS) und wird damit in Authentik gesetzt. Das Feld Gruppe einer Authentik-Application bestimmt den Bereich im Portal (leer = „Anwendungen“, z.B. „Administration“). Eigene Icons können in Authentik hochgeladen werden, sonst nimmt das Portal seine Icons aus public/icons/<slug>.svg.

Neues Tool ins Portal aufnehmen

  1. In Authentik eine Application anlegen (Name, Slug, Launch-URL).
  2. Slug in APP_ACCESS eintragen und scripts/authentik-setup.py --apply laufen lassen (oder die Gruppe in Authentik direkt binden).
  3. Optional: Icon public/icons/<slug>.svg und Reihenfolge in APP_ORDER.
  4. Kopfleiste im Tool einbinden (siehe unten).

Kopfleiste in ein Tool einbauen

<script src="https://portal.handy-insel.de/topbar.js" data-app="vvl" defer></script>
  • data-app: Slug der Authentik-Application. Die App wird im Menü markiert und ihr Name neben dem Logo angezeigt.
  • data-sticky: Die Leiste bleibt beim Scrollen oben.
  • data-auto="false": nicht automatisch einfügen, sondern selbst <hi-topbar app="vvl"></hi-topbar> platzieren.
  • Die Leiste ist 44 px hoch und setzt --hi-topbar-height auf <html>. Layouts mit height: 100vh sollten calc(100vh - var(--hi-topbar-height, 0px)) verwenden.
  • Die Leiste nutzt Shadow DOM, CSS-Konflikte mit dem Tool sind also ausgeschlossen.

Content-Security-Policy des Tools erweitern (sonst blockiert der Browser die Leiste):

script-src  … https://portal.handy-insel.de
connect-src … https://portal.handy-insel.de
img-src     … https://portal.handy-insel.de https://login.handy-insel.de

Ist man im Tool angemeldet, im Portal aber nicht, zeigt das Menü „Jetzt anmelden“. Weil die Authentik-Sitzung schon besteht, ist das ein unsichtbarer Redirect zurück ins Tool.

Abmelden

„Abmelden“ im Portal oder in der Kopfleiste beendet die Portal-Sitzung und die Authentik-Sitzung. Die eigenen Sitzungen der Tools laufen bis zu ihrem Ablauf weiter. Für ein echtes Single-Logout braucht jedes Tool einen Backchannel-Logout-Endpunkt; das ist als nächster Ausbauschritt vorgesehen.

Betrieb

Host CT portal (192.168.1.28), Debian 13
Dienst systemctl status hi-portal, Logs: journalctl -u hi-portal -f
Code /opt/hi-portal
Konfiguration /etc/hi-portal/portal.env (siehe .env.example)
Daten /var/lib/hi-portal/portal.db (Sitzungen, Aktuelles)
Pangolin portal.handy-insel.de → http://192.168.1.28:3010. Pangolin-eigene Authentifizierung für diese Ressource aus, das Portal macht den Login selbst.

Erstinstallation

# 1. CT vorbereiten (einmalig)
scp deploy/setup-ct.sh root@192.168.1.28: && ssh root@192.168.1.28 bash setup-ct.sh
# 2. Portal ausspielen
./deploy/deploy.sh root@192.168.1.28
# 3. Authentik einrichten (Probelauf, dann ausführen); schreibt Client-ID/Secret/Token in die portal.env
ssh root@192.168.1.28
AK_TOKEN=<admin-token> python3 /opt/hi-portal/scripts/authentik-setup.py
AK_TOKEN=<admin-token> python3 /opt/hi-portal/scripts/authentik-setup.py --apply --env /etc/hi-portal/portal.env
systemctl restart hi-portal

Update: ./deploy/deploy.sh

Entwicklung

npm install
npm run build
# Server ohne Authentik-Login (nur lokal, in production gesperrt):
NODE_ENV=development DEV_USER=kerim SESSION_SECRET=dev AUTHENTIK_TOKEN=<token> node dist/server/index.js
# Frontend mit Hot-Reload auf :5180 (leitet /api und /auth an :3010 weiter)
npm run dev:web

Aufbau: server/ (Express + TypeScript, openid-client, SQLite), frontend/ (React + Vite + Tailwind), topbar/ (Web-Component, per esbuild gebaut), public/ (Icons, Logo).

S
Description
Handy-Insel Portal – zentrale Startseite und App-Umschalter für alle internen Tools (Authentik-SSO)
Readme
375 KiB
0 Stars 1 Watchers 0 Forks
Languages
TypeScript 75.5%
Python 17.4%
CSS 3.2%
Shell 2.7%
HTML 0.7%
Other 0.5%