Commit Graph

17 Commits

Author SHA1 Message Date
fs
3207d71244 harden(logout): enforce POST+CSRF and remove GET logout triggers 2026-04-25 23:35:03 +02:00
fs
6e3fc63c1d feat(tenant): per-theme logos + file-upload + button UI polish
Replace the single tenant avatar with a pair of theme-scoped brand logos.
Render only the theme-matching <img> server-side and swap src on theme
toggle via a JS hook — no reload, no double request, no CSS tricks.

Tenant logos
- TenantLogoService (ImageUploadTrait) with theme whitelist and per-theme
  storage storage/tenants/{uuid}/logo/{light|dark}/, SIZES 128/256/512
- Public serving endpoint auth/tenant-logo-file so login can show the
  logo pre-auth; matching authenticated admin preview endpoint
- appTenantLogoUrl(?size, ?theme) with 4-step fallback cascade; PDF +
  mail always request 'light'
- Admin tenant edit: avatar block replaced by "Tenant logos" details
  block inside the Master-data tab, two side-by-side slots via Pico
  .grid with the core app-file-upload partial
- Policy rename ABILITY_ADMIN_TENANTS_AVATAR_VIEW -> LOGO_VIEW, action
  routes logo / logo-delete / logo-file with theme body/query param
- API endpoint path kept (backward compat), internals on new service
- CLI tenant:logo-migrate-avatars moves legacy avatar/ -> logo/light/
  idempotently (--dry-run, --yes, --cleanup)
- i18n "Tenant image" removed, 12 new keys synced across de/en

File upload component
- Full-width preview + filename/actions below (3D stack layout)
- Fixed 16:9 aspect ratio with 1rem inner padding for consistent
  preview size across any logo aspect
- Transparency checker pattern as background so black logos stay
  visible on dark mode and white logos on light mode
- form="" + deleteFormId support so the partial works with barrier
  forms inside another form

Buttons
- width:100% dropped from button[type="submit"]; scoped back via
  .login-main for the auth-flow primary CTA
- .outline base rule now tints background via color-mix of --app-color
  so secondary/primary/danger outlines all gain a subtle surface
- .outline.secondary restyled Stripe-style in both themes: solid white
  chip with soft shadow in light, solid elevated dark chip with white
  text in dark; neutral border replaces role-colored border
- .app-action-success/.app-action-danger outlines get color-mix bg +
  theme-aware outline-text tokens for stronger contrast
- Filled .primary/.app-action-success/.app-action-danger get raised
  box-shadow (inset highlight + drop) — opt-in via class so chrome
  buttons stay flat
- Dropped the legacy .secondary utility that was clobbering the
  custom-property cascade with a hardcoded muted color

Theme swap
- Logo img carries data-src-light + data-src-dark; theme-toggle JS
  swaps src when data-theme changes, keeping the topbar/login logo in
  sync without a page reload

Quality gates: PHPUnit (2045), PHPStan L5, CS-Fixer, docs link/drift,
codex skills sync — all green.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-24 20:25:53 +02:00
fs
3c6ce0cbdb fix(topbar): resolve theme + tenant-switch endpoints via lurl() to avoid relative URL breakage
Both endpoints were declared as bare relative paths ("admin/users/theme",
"admin/users/switch-tenant") and handed to postForm(), which normalizes
through `new URL(value, window.location.href)`. On a deep route like
/de/admin/permissions that resolves to /de/admin/admin/users/theme —
404 → 302 to error page → HTML response → JSON.parse throws → the theme
toggle reverts visually. The tenant switcher had the same latent bug.

- Topbar renders data-theme-url and data-switch-tenant-url via lurl(), so
  both carry the locale-aware root-anchored path.
- Tenant switcher reads data-switch-tenant-url from the switcher root
  (matching the theme-menu convention) and passes it through to
  switchTenant(); fail-fast warning if the attribute is missing.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-22 20:39:20 +02:00
fs
a3f270408b feat(layout): migrate to full-width topbar with mobile drawer navigation
Move topbar outside the grid container as a standalone sticky header
(Shopify/Stripe pattern). Sidebar and icon bar use position:sticky
relative to topbar height. Mobile uses drawer pattern with backdrop,
focus trap, ESC close, and scroll lock. Tenant branding moved from
sidebar header into the topbar.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-06 22:21:39 +02:00
fs
576a0c51cd feat(guards): add GR-SEC-010 — output escaping enforcement in views
Add architecture test ViewLayerOutputEscapingContractTest that flags
raw <?php echo in .phtml files. Legitimate uses (pre-built ARIA attrs
from navActive(), hardcoded role values, pre-rendered HTML fragments)
must carry an inline // raw-html-ok: reason marker.

Annotated all 11 existing raw echo sites with justification markers.
Added guard to catalog, enforcement map (automated), CLAUDE.md security
section, and never-do-this list.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-06 12:08:25 +02:00
fs
b749b5d192 feat: centralize breadcrumbs in topbar and remove history navigation
Move breadcrumb rendering from individual page templates into the core
topbar. Each page now sets $breadcrumbs in its action .php file; the
topbar renders it automatically via the shared partial.

- Remove global back/forward buttons and app-nav-history.js component
- Remove Alt+Arrow keyboard shortcuts for history navigation
- Render breadcrumb in topbar-left section (replaces button area)
- Clean up breadcrumb CSS: context-neutral base (flex, no margin)
- Recalculate sticky titlebar offset in details container
- Migrate all 41 pages (core + helpdesk, audit, addressbook, api-docs)
- Add missing breadcrumbs to addressbook detail view
- Update architecture contract tests (nav-history references removed)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-05 17:17:06 +02:00
fs
83b65812d0 little refactore 2026-04-01 16:31:59 +02:00
fs
bc72fa50a6 Consolidate settings normalization tests 2026-03-19 19:43:55 +01:00
fs
c7b8fd516a feat: extend module platform with UI slots, runtime components, CLI tooling and {{userId}} search support
Completes the generic module platform that enables modules to contribute
UI elements, runtime JS components, and search resources without any
core hardcoding.

New generic UI slot types:
- topbar.right_item: module-contributed topbar buttons
- layout.body_end_template: module-contributed dialog/overlay templates
- layout.head_style: module-contributed global CSS
- runtime.component: declarative JS component registration with phase ordering

New infrastructure:
- ModuleAutoloader: PSR-4 autoloading for module-local PHP classes
- ModuleRuntimePageBuilder: symlinks module pages into runtime directory
- ModuleRuntimeAssetPublisher: publishes module CSS/JS to web/modules/
- ModulePermissionSynchronizer: syncs module permissions to DB
- CLI scripts: module-runtime-sync, module-build, module-migrate,
  module-permissions-sync, module-assets-sync
- {{userId}} placeholder in SearchDataService for user-scoped search queries
- Component runtime with phased initialization (early/default/late)
- AppContainer.protectExistingBindings() to prevent module→core overwrites
- Architecture tests: ModuleStructureContractTest, CoreTemplateIsolationTest,
  FrontendComponentRuntimeContractTest, AppContainerIsolationContractTest

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-18 22:19:56 +01:00
fs
9688848401 Global Boomarks 2026-03-14 21:45:58 +01:00
fs
2b915f5a43 refactor: extract shared form utils, add aria-live regions and reduced-motion support
DRY duplicated helpers (escapeAttr, belongsToForm, isSubmitControl,
isEditableTarget) into web/js/core/app-form-utils.js and update 7
consumers. Add aria-live="polite" to flash messages, async messages,
and search results for screen reader announcements. Add
prefers-reduced-motion support to CSS tooltips.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-13 22:28:46 +01:00
fs
39a113c5fc fixed wrong warning with single tenant 2026-03-12 12:22:36 +01:00
fs
1cdd7e59c1 chore(ui): update shell layout and header/footer partials 2026-03-11 23:33:17 +01:00
fs
b2dab5bd6c topbar anpassungen 2026-03-05 12:51:53 +01:00
fs
25370a1a55 add composer-unused, comprehensive docs, and project restructure
- Add icanhazstring/composer-unused as dev dependency for dependency hygiene checks
- Add German documentation (docs/) covering architecture, conventions, workflows, and developer checklists
- Add API layer (ApiAuth, ApiBootstrap, ApiResponse), audit, scheduler, custom fields, and SSO services
- Add Microsoft OIDC SSO, API token management, and user lifecycle features
- Add swagger-ui vendor integration and OpenAPI spec
- Add production Docker setup and bin/ scripts
- Update composer dependencies, config, templates, and frontend assets throughout

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-02-22 15:27:35 +01:00
fs
3eb9cc0ac4 big restructure 2026-02-11 19:28:12 +01:00
fs
cd59ccd99b baseline 2026-02-04 23:31:53 +01:00