fix: five dashboard improvements across booking, vehicles, profile, and UI

- fix(auth): guard extractNames() against Authentik sending full name in
  given_name field (e.g. "Matthias Hochmeister" + family_name "Hochmeister");
  detect by checking given_name ends with family_name suffix, fall through
  to name-splitting so Vorname/Nachname display correctly in Profile

- fix(db): add migration 018 to repair broken BEFORE UPDATE triggers on
  veranstaltungen and veranstaltung_kategorien; old triggers called
  update_updated_at_column() which references NEW.updated_at, but both
  tables use aktualisiert_am, causing every category/event edit to fail

- feat(booking): open vehicle booking creation to all authenticated users;
  only dashboard_admin / dashboard_moderator can change the Buchungsart
  (type select disabled for regular members); edit and cancel still
  restricted to WRITE_GROUPS

- feat(vehicles): VehicleDashboardCard now fetches equipment warnings via
  equipmentApi.getVehicleWarnings() in parallel and shows an alert when
  any vehicle equipment is not einsatzbereit

- fix(ui): add MuiTextField defaultProps (InputLabelProps.shrink=true) and
  MuiOutlinedInput notch legend font-size override to theme to eliminate
  floating-label / border conflict on click

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
Matthias Hochmeister
2026-03-03 11:04:57 +01:00
parent 2306741c4d
commit 3101f1a9c5
6 changed files with 79 additions and 10 deletions

View File

@@ -19,8 +19,16 @@ function extractNames(userInfo: { name?: string; given_name?: string; family_nam
const familyName = userInfo.family_name?.trim();
// If Authentik provides both and they differ, use them directly
// BUT: guard against the case where given_name is actually the full name
// (e.g. Authentik sends given_name="Matthias Hochmeister", family_name="Hochmeister")
if (givenName && familyName && givenName !== familyName) {
return { given_name: givenName, family_name: familyName };
const looksLikeFullName =
givenName.includes(' ') &&
(givenName.endsWith(' ' + familyName) || givenName === familyName);
if (!looksLikeFullName) {
return { given_name: givenName, family_name: familyName };
}
// Fall through to split the name field
}
// Fall back to splitting the name field