You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
docs: update release and usage documentation for routing hardening
Document centralized frontend URL/security guardrails and mobile UX guidance across changelogs, README, developer docs, and user manuals to keep implementation and operations aligned.
Made-with: Cursor
Copy file name to clipboardExpand all lines: CHANGELOG.de.md
+7Lines changed: 7 additions & 0 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -4,18 +4,25 @@
4
4
5
5
-**Genehmigungs-Deadlock (App-Teams)**: Abwesenheiten und Zeiteintrags-Korrekturen behandeln „hat Kolleg:innen“ nicht mehr wie „hat eine:n Vorgesetzte:n“. Auto-Genehmigung, wenn **kein zuweisbarer Genehmiger** existiert, folgt `TeamResolverService::hasAssignableManagerForEmployee()` (explizite Team-Manager bei App-Teams; Legacy-Gruppenmodus weiterhin Kollegen-Proxy). Verhindert Anträge, die dauerhaft auf Managerfreigabe warten, obwohl niemand freigeben darf.
6
6
-**Zeiteintrags-Korrekturen**: Gleiche Zuweisbarkeitsregel wie bei Abwesenheiten (zuvor nur Kollegen-IDs).
7
+
-**Admin-Users API auf `/index.php`-Instanzen**: Refresh/Edit/History/Update nutzen nun zuverlässig aufgelöste App-URLs; fehlerhafte Requests wie `search=[object PointerEvent]` treten nicht mehr auf.
8
+
-**Admin-Teams und Settings auf Rewrite-losen Setups**: Zentrale URL-Auflösung enthält jetzt einen robusten `/index.php`-Fallback, wenn `OC.generateUrl()` im Seitenkontext fehlt oder unvollständig ist.
7
9
8
10
### Hinzugefügt
9
11
10
12
-**Repair-Schritt**`ReleaseStuckPendingAbsences`: setzt nach Migration verbliebene `pending`-Abwesenheiten unter derselben Bedingung automatisch auf genehmigt (idempotent).
13
+
-**Frontend-URL-Sicherheitsleitplanken**: Die gemeinsame AJAX-Schicht blockiert externe Cross-Origin-Calls standardmäßig (explizit `allowExternal: true` nötig); Unit-Tests decken URL-Normalisierung und External-Handling ab.
14
+
-**Lint-Leitplanken**: ESLint-Regeln verhindern neue rohe `fetch('/apps/arbeitszeitcheck/...')`-Aufrufe und implizite externe `fetch(...)`-Nutzung außerhalb der vorgesehenen Abstraktionen.
11
15
12
16
### Geändert
13
17
14
18
-**UX**: Abwesenheiten zeigen einen Hinweis, wenn App-Teams aktiv sind und kein Genehmiger zugeordnet ist; in der Detailansicht erscheint bei veralteten hängenden Anträgen ein Warnhinweis (bis Repair/Admin die Teamkonfiguration korrigiert).
19
+
-**Frontend-Architektur**: `ArbeitszeitCheckUtils` stellt nun zentral `getRequestToken()`, `resolveUrl()` und `isExternalUrl()` bereit; genutzt u. a. in `admin-users`, `reports`, `settings` und `validation`.
20
+
-**Mobile UX Konsistenz (WCAG 2.1 AA)**: iPhone-Safe-Area-konforme Abstände, bessere Touch-Targets, klarere Abschnittsstruktur und visuelle Hierarchie für Nutzerseiten (`dashboard`, `time-entries`, `absences`) sowie Managerseiten (`manager-dashboard`, `manager-time-entries`, Mitarbeiter-Abwesenheiten).
15
21
16
22
### Dokumentation
17
23
18
24
- Nutzerhandbücher (EN/DE), `tests/WORKFLOW_ROLE_MATRIX.md` und Entwicklerdokumentation zur Semantik „zuweisbarer Manager“ und zum Repair-Schritt ergänzt.
25
+
- README und Entwicklerdokumentation um zentrale Frontend-URL-Policy, striktes External-Call-Verhalten und Mobile/iOS-Layout-Hinweise ergänzt.
Copy file name to clipboardExpand all lines: CHANGELOG.md
+7Lines changed: 7 additions & 0 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -11,18 +11,25 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
11
11
12
12
-**Approver deadlock (app teams)**: Absence and time-entry correction workflows no longer treat “has colleagues” as “has a manager”. Auto-approval when **no assignable approver** exists now follows `TeamResolverService::hasAssignableManagerForEmployee()` (explicit team managers in app-teams mode; legacy group mode still uses colleagues as a proxy). Prevents requests stuck in “awaiting manager approval” when nobody can approve.
13
13
-**Time entry corrections**: Same assignability rule as absences (previously used colleague IDs only).
14
+
-**Admin users API requests on `/index.php` instances**: Refresh/edit/history/update actions now reliably resolve app URLs and no longer produce invalid requests like `search=[object PointerEvent]`.
15
+
-**Admin teams and settings API reliability on rewrite-less setups**: Central URL resolution now includes a robust `/index.php` fallback when `OC.generateUrl()` is unavailable/incomplete in page context.
14
16
15
17
### Added
16
18
17
19
-**Repair step**`ReleaseStuckPendingAbsences`: post-migration repair auto-approves legacy `pending` absences that still match the “no assignable approver” condition (idempotent).
20
+
-**Frontend URL security guardrails**: Shared AJAX layer now blocks external cross-origin calls by default (explicit `allowExternal: true` required), with unit tests covering URL normalization and external URL handling.
21
+
-**Lint guardrails**: ESLint rules now prevent introducing raw `fetch('/apps/arbeitszeitcheck/...')` and implicit external `fetch(...)` patterns outside approved abstractions.
18
22
19
23
### Changed
20
24
21
25
-**UX**: Absences UI shows an informational callout when app teams are enabled and no approver is assigned; detail view shows a defensive warning if an old `pending` row is still stuck (until repair/admin fixes team setup).
26
+
-**Frontend architecture**: `ArbeitszeitCheckUtils` now provides centralized `getRequestToken()`, `resolveUrl()`, and `isExternalUrl()` primitives used by page scripts (`admin-users`, `reports`, `settings`, `validation`).
27
+
-**Mobile UX consistency (WCAG 2.1 AA focused)**: iPhone-safe-area-aware spacing, improved touch targets, clearer section rhythm, and better visual hierarchy for normal user pages (`dashboard`, `time-entries`, `absences`) and manager pages (`manager-dashboard`, `manager-time-entries`, employee absences view).
22
28
23
29
### Documentation
24
30
25
31
- User manuals (EN/DE), `tests/WORKFLOW_ROLE_MATRIX.md`, and developer documentation updated for assignable-manager semantics and repair step.
32
+
- README and developer documentation updated with centralized frontend URL policy, strict external-call behavior, and mobile/iOS layout guidance.
-**Audit‑Logs**: Lückenlose Nachvollziehbarkeit von Änderungen an Zeiten, Abwesenheiten und Einstellungen
19
+
-**Revisionssichere Monatsfinalisierung** (optional, Admin‑Schalter): Kalendermonat mit Snapshot, Hash und PDF‑Nachweis abschließen; finalisierte Monate bleiben gesperrt, bis eine Administratorin/ein Administrator mit Begründung wieder öffnet
19
20
-**DSGVO‑Support**: Exporte, Löschkonzepte (unter Beachtung der gesetzlichen Aufbewahrung), DPIA‑/Verarbeitungsverzeichnis‑Vorlagen
20
21
21
22
> **Rechtlicher Hinweis (DE):**
@@ -100,12 +101,23 @@ Diese Dateien werden vom Nextcloud App Store für Listung, Detailseite und Revie
100
101
101
102
### Entwicklung & Tests
102
103
103
-
- PHPUnit‑Tests: `composer test` (bzw. `phpunit` mit bereitgestellter `phpunit.xml`)
104
-
- JS‑Build: `npm run build`, Dev‑Watch: `npm run watch`
-**PHP im Docker‑Stack dieses Monorepos:** vom Nextcloud‑Server‑Root `./docker/run-app-phpunit.sh arbeitszeitcheck` oder in der App `composer test:docker` bzw. `npm run test:php:docker`
108
+
-**JavaScript (Vitest):**`npm test`, bei Bedarf `npm run test:watch`
109
+
-**Lint:**`npm run lint`, `npm run stylelint` (sowie `composer lint` für PHP‑Syntaxcheck unter `lib/`)
110
+
-**E2E (Playwright):**`npm run e2e` — erfordert laufende Nextcloud‑Instanz und Umgebungsvariablen (`NC_BASE_URL`, Testnutzer); siehe `docs/Developer-Documentation.en.md`
111
+
-**Alle Tests im Container (Hilfsskript):**`scripts/run-tests-docker.sh` vom App‑ bzw. Repo‑Kontext
112
+
113
+
Hinweis: `npm run build` ist ein Platzhalter (**kein** Bundler‑Build; Frontend ist Vanilla‑JS mit PHP‑Templates).
114
+
115
+
### Frontend Runtime & UX Guardrails
116
+
117
+
-**One URL resolution path:** Frontend requests should use `ArbeitszeitCheckUtils.ajax(...)` (or `ArbeitszeitCheckUtils.resolveUrl(...)` when using `fetch` explicitly) to normalize app URLs reliably on both pretty-URL and `/index.php` installations.
118
+
-**Strict external-call policy:**`ArbeitszeitCheckUtils.ajax(...)` blocks cross-origin URLs by default. External calls require explicit opt-in via `allowExternal: true`.
119
+
-**Lint enforcement:** ESLint rejects raw `fetch('/apps/arbeitszeitcheck/...')` and implicit external `fetch(...)` patterns outside approved abstractions.
120
+
-**Mobile/iPhone consistency:** Shared layout styles in `css/common/` include safe-area-aware spacing and touch-target improvements (WCAG 2.1 AA focus) for user and manager pages.
109
121
110
122
Weitere Details zur Architektur und zu Beitrag‑Richtlinien finden sich in `docs/Developer-Documentation.en.md`.
For reliability and security, all frontend network calls should follow one path:
600
+
601
+
1.**Prefer**`ArbeitszeitCheckUtils.ajax(...)` for app API calls.
602
+
2. If a raw `fetch(...)` is unavoidable, resolve URLs with `ArbeitszeitCheckUtils.resolveUrl(...)` and read CSRF token via `ArbeitszeitCheckUtils.getRequestToken()`.
603
+
3. Do not hardcode raw app URLs in fetch calls (e.g. `fetch('/apps/arbeitszeitcheck/...')`) — lint rules reject this.
604
+
605
+
Behavior implemented in `js/common/utils.js`:
606
+
607
+
-`resolveUrl(...)` normalizes app URLs for both pretty-URL and `/index.php` deployments.
608
+
-`ajax(...)` injects `requesttoken` and `credentials: 'same-origin'`.
609
+
- External cross-origin URLs are blocked by default in `ajax(...)`; explicit opt-in is required with `allowExternal: true`.
610
+
611
+
### Mobile/iPhone layout guidance
612
+
613
+
Shared layout behavior is centralized in:
614
+
615
+
-`css/common/app-layout.css`
616
+
-`css/common/responsive.css`
617
+
-`css/navigation.css`
618
+
619
+
Key rules:
620
+
621
+
- Use safe-area aware spacing (`env(safe-area-inset-*)`) for iPhone notch/home-indicator devices.
622
+
- Keep interactive controls at least ~44px height (WCAG touch-target guidance).
623
+
- Preserve clear section hierarchy: one strong heading, concise helper text, and consistent card/action spacing.
624
+
- Keep mobile behavior in shared CSS first; page CSS should only add local adjustments.
625
+
597
626
### CSS Organization
598
627
599
628
**Use BEM naming:**
@@ -868,6 +897,13 @@ public function getEntry(int $id): JSONResponse
868
897
-`AppAdminMiddleware` is registered in `Application::register()` and gates `AdminController` methods centrally.
869
898
- Unauthorized access to admin pages throws `NotAppAdminException` and resolves to a 403 response.
870
899
900
+
### Frontend request security model
901
+
902
+
- Central request guardrails are implemented in `ArbeitszeitCheckUtils.ajax(...)`.
903
+
- Cross-origin URLs are denied by default; callers must explicitly set `allowExternal: true`.
904
+
- URL normalization and token handling are centralized to avoid route drift and accidental insecure request patterns.
905
+
- ESLint guardrails in `.eslintrc.cjs` enforce this policy for `fetch(...)` usage.
Copy file name to clipboardExpand all lines: docs/README.md
+1-1Lines changed: 1 addition & 1 deletion
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -11,7 +11,7 @@ This folder contains the documentation included with ArbeitszeitCheck for admini
11
11
|[GDPR-Compliance-Guide.en.md](GDPR-Compliance-Guide.en.md)| How to operate ArbeitszeitCheck in a GDPR-compliant way (legal basis, data minimization, employee rights, retention) |
12
12
|[Compliance-Implementation.en.md](Compliance-Implementation.en.md)| Technical implementation of ArbZG compliance checks (breaks, rest periods, real-time vs batch) |
13
13
|[Compliance-Implementation.de.md](Compliance-Implementation.de.md)| Same content in German |
14
-
|[Developer-Documentation.en.md](Developer-Documentation.en.md)| Architecture, development setup, contribution guidelines, and technical notes (including vacation carryover / Resturlaub, assignable-manager / auto-approval semantics) |
14
+
|[Developer-Documentation.en.md](Developer-Documentation.en.md)| Architecture, development setup, contribution guidelines, and technical notes (including vacation carryover / Resturlaub, assignable-manager / auto-approval semantics, centralized frontend URL/security guardrails, and mobile/iPhone UX implementation notes) |
Copy file name to clipboardExpand all lines: docs/User-Manual.de.md
+1Lines changed: 1 addition & 0 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -57,6 +57,7 @@ Im Auswahldialog erscheinen nur Konten aus der Nextcloud-`admin`-Gruppe.
57
57
-**App-Teams (empfohlene Einrichtung):** Wenn Ihre Organisation **App-Teams** nutzt und in der App **kein:e Vorgesetzte:r** für Ihr Team hinterlegt ist, werden Anträge **ohne** Vertretung beim Absenden **automatisch genehmigt**—es gäbe sonst niemanden mit Managerfreigabe. Mit **Vertretung** läuft zuerst der Vertretungs-Schritt. Die Oberfläche kann dazu einen kurzen Hinweis anzeigen.
58
58
-**Älteres Gruppenmodell:** Verhalten folgt dem früheren „gleiche Gruppe“-Modell; die Administration sollte sicherstellen, dass Genehmigungen für Ihre Organisation weiterhin sinnvoll möglich sind.
59
59
-**Manager-Dashboard** (als Führungskraft): Unter **Ausstehende Genehmigungen** erscheint der **Abwesenheitstyp in Ihrer Sprache** (z. B. Urlaub, Krankheit), nicht technische Kurzbezeichnungen. Wo freigeschaltet, bietet **Abwesenheiten der Mitarbeitenden** eine eigene Listen-/Filteransicht.
60
+
-**Mobile Nutzung (Smartphone/Tablet):** Die Oberfläche ist responsiv optimiert (klarere Abschnittsabstände, größere Touch-Ziele, iPhone-Safe-Area-Berücksichtigung). Auf sehr kleinen Displays funktionieren Formulare meist am besten im Hochformat, breite Tabellen/Berichte im Querformat.
60
61
-**Berichte** für Zeiträume erstellen und erlaubte Exporte nutzen (CSV, DATEV, …).
61
62
-**Compliance-Hinweise** (z. B. fehlende Pausen) nach Vorgabe des Arbeitgebers bearbeiten.
Copy file name to clipboardExpand all lines: docs/User-Manual.en.md
+1Lines changed: 1 addition & 0 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -57,6 +57,7 @@ Only users in Nextcloud's `admin` group are eligible in this picker.
57
57
-**App teams (recommended setup):** If your organization uses **app-managed teams** and **no manager is assigned** to your team in the app, requests you submit **without** a substitute are **approved automatically** when you send them—there is nobody who could approve them in the manager workflow. If you **do** pick a substitute, the substitute step still runs first. The UI may show a short explanation when this applies.
58
58
-**Legacy group-based setup:** Behavior follows the older “same group” model; your admin should ensure approvals remain workable for your organization.
59
59
-**Manager dashboard** (if you are a team lead): Under **Pending approvals**, absence requests list each person with the **absence type in your language** (e.g. vacation vs sick leave), not raw internal codes. Where enabled, **Employee absences** provides a dedicated list/filter view of team absences.
60
+
-**Mobile use (phones/tablets):** The UI is optimized for responsive use with clearer section spacing, larger touch targets, and iPhone safe-area aware layout. If you use a very small screen, prefer portrait mode for forms and landscape for wide tables/reports.
60
61
-**Reports**: Generate period reports or exports your admin allows (CSV, DATEV, etc.).
61
62
-**Compliance**: The app may flag violations (e.g. missing breaks); your employer defines how those are handled.
0 commit comments