# Zeitwerk

Zeitwerk ist eine mobile Webarbeitszeiterfassung für mehrere Mitarbeiter. Die App verwendet PHP 8.3 und MariaDB und kommt ohne externe PHP-Pakete aus.

## Berechtigungs- und Verschlüsselungsmodell

- Der Admin kann Mitarbeiter einladen, aktivieren und deaktivieren.
- Admin-Endpunkte liefern ausschließlich Kontodaten. Sie haben keinen Zugriff auf Arbeitszeiten, Dienstpläne, Sollzeiten, Stundenlöhne oder Exporte.
- Jeder Mitarbeiter erhält bei der E-Mail-Verifizierung einen eigenen zufälligen 256-Bit-Datenschlüssel.
- Dieser Schlüssel wird mit einem durch Argon2id aus dem Mitarbeiterpasswort abgeleiteten Schlüssel geschützt.
- Private Profile, Arbeitszeiten und Dienstpläne werden mit XChaCha20-Poly1305 authentifiziert verschlüsselt in MariaDB gespeichert.
- E-Mail-Adressen werden mit dem separaten Anwendungsschlüssel verschlüsselt und zusätzlich über einen HMAC-Suchwert eindeutig zugeordnet.
- Passwörter werden unabhängig davon mit PHP Argon2id gehasht.

Wichtig: `APP_KEY` und die MariaDB-Sicherung müssen getrennt gesichert werden. Geht der Anwendungsschlüssel verloren, können E-Mail-Adressen nicht wiederhergestellt werden. Vergisst ein Mitarbeiter sein Passwort, ist für eine Wiederherstellung seiner privaten Daten ein separat zu entwerfender Recovery-Prozess erforderlich. Der Admin besitzt bewusst keinen Generalschlüssel für diese Daten.

## Funktionen

- Mehrere Mitarbeiterkonten mit E-Mail-Verifizierung
- Strikt getrennter Adminbereich ohne Einsicht in Mitarbeiterdaten
- Ein- und Ausstempeln sowie manuelle Korrektur von Arbeitszeiten
- Wochenstunden, Monatsstunden oder Dienstplan als Sollzeit
- Antippbarer Monatskalender mit Tagesdetailansicht
- Verschlüsselter persönlicher Dienstplan
- Tages-, Wochen- und Monatsauswertung inklusive Sollabweichung
- Voraussichtlicher Monatslohn anhand des persönlichen Stundenlohns
- Vollständiger Datenexport als JSON-Datei per E-Mail
- Mobile Darstellung und persistenter Dark Mode

## Voraussetzungen

- PHP 8.3 mit `pdo_mysql`, `sodium`, `openssl` und `mbstring`
- MariaDB 10.11 oder neuer
- SMTP-Zugang mit TLS
- Für öffentlichen Betrieb ein HTTPS-Reverse-Proxy

## Installation

1. Datenbank und Benutzer in MariaDB anlegen:

   ```sql
   CREATE DATABASE zeitwerk CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
   CREATE USER 'zeitwerk'@'127.0.0.1' IDENTIFIED BY 'EIN_LANGES_ZUFAELLIGES_PASSWORT';
   GRANT SELECT, INSERT, UPDATE, DELETE, CREATE, ALTER, INDEX, REFERENCES ON zeitwerk.* TO 'zeitwerk'@'127.0.0.1';
   FLUSH PRIVILEGES;
   ```

2. Konfiguration anlegen:

   ```bash
   cp .env.example .env
   php bin/generate-key.php
   ```

   Die Ausgabe des zweiten Befehls als `APP_KEY` in `.env` eintragen. Danach MariaDB-, SMTP- und URL-Werte in `.env` ergänzen. Die Datei darf nicht veröffentlicht oder in Git eingecheckt werden.

3. Schema installieren:

   ```bash
   php bin/migrate.php
   ```

4. Für die lokale Prüfung starten:

   ```bash
   php -S 127.0.0.1:8080 -t public public/router.php
   ```

   Beim ersten Aufruf wird das Administratorkonto eingerichtet.

## Produktionsbetrieb

Der Document-Root des Webservers muss auf `public/` zeigen. Alle anderen Ordner und insbesondere `.env` dürfen nicht vom Webserver ausgeliefert werden. HTTPS ist Pflicht; bei HTTPS muss `APP_SECURE_COOKIE=1` gesetzt sein. Der eingebaute PHP-Server ist nur für Entwicklung und Tests gedacht.

Empfohlen sind zusätzlich:

- Caddy oder nginx als HTTPS-Reverse-Proxy
- ein PHP-FPM-Dienst unter einem eingeschränkten Systembenutzer
- regelmäßige verschlüsselte Sicherungen von MariaDB und `.env` an getrennten Orten
- SMTP mit STARTTLS oder implizitem TLS
- serverseitige Rate-Limits für `/api/login` am Reverse-Proxy

## Datensicherung

Die Mitarbeiter können ihre entschlüsselten persönlichen Daten selbst per E-Mail anfordern. Serverseitige Backups bleiben verschlüsselt; hierfür MariaDB und `.env` getrennt sichern.
