EnsureCustomerActive used session()->invalidate() to sign a suspended
or closed customer out. In shared-host mode the console and the
portal keep their login key in one session, so invalidate() (flush()
+ migrate(true)) silently signed out an operator elsewhere in that
same browser too. Same fix as the console's own /logout route:
regenerate() gets a fresh session id without flushing attributes
belonging to another guard.
- 5 operator roles (Owner/Admin/Support/Billing/Read-only) seeded via migration
with a capability catalogue; app checks capabilities via Gate, never role names
- every mutating admin action authorizes server-side (hosts/datacenters/customers/
impersonate/provisioning); is_admin reads migrated to console.view / isOperator()
- admin /settings: own account + Owner-only staff invite/role/revoke with
last-owner, self-role and customer-collision guards (transactional)
- sidebar 'zum Kundenportal' link replaced with Settings
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>