CluPilotCloud/resources/views/livewire/admin
nexxo 0d9b62eb50 feat(vpn): ownership, a Developer role, and password-gated config retrieval
Reworked after a design consultation with Codex, which pushed back on my first
proposal in three useful ways.

Ownership and rights:
- vpn.manage split into vpn.view.all and vpn.manage.all. Seeing an access is
  not managing it, and neither is holding its private key.
- Record-level rules live in VpnPeerPolicy, not in permissions: an access
  belongs to a person, and ownership is what grants sight of it. Every operator
  reaches the page, but sees only their own unless they may see all.
- Issuing an access is not self-service — it reaches the management network, so
  it needs vpn.manage.all even for oneself.
- New Developer role: sees everything, manages nothing. Writing code does not
  imply authority over other people's access.
- kind (staff|host|system) replaces a null user_id that had to mean two
  different things at once.

Config storage, opt-in per access:
- Downloading is owner-only — explicitly NOT for view.all or manage.all. An
  admin who needs access revokes this one and issues their own, which keeps the
  record of who holds what honest.
- The password is asked on EVERY retrieval, rate-limited. Laravel's
  password.confirm keeps a 15-minute session stamp, which would authorise
  unlimited later downloads from an unattended browser.
- Stored under VPN_CONFIG_KEY, not APP_KEY: a leaked application key must not
  also hand over the management network. Purged on revocation and when a staff
  member is revoked — console taken away, tunnel left open was the worst case.
- The plaintext never enters a Livewire snapshot (the page polls every five
  seconds); the component carries an opaque handle instead.

Also: copy button works without HTTPS again (navigator.clipboard only exists in
a secure context, so over http it silently did nothing), plus config download
as a file and a QR code for the mobile apps.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-25 22:31:54 +02:00
..
confirm-delete-datacenter.blade.php fix(ui): make modal cancel buttons work; serve the app over the HTTPS domains 2026-07-25 21:24:03 +02:00
confirm-delete-vpn-peer.blade.php feat(admin): VPN access management with live peer state 2026-07-25 21:38:12 +02:00
confirm-remove-host.blade.php fix(ui): make modal cancel buttons work; serve the app over the HTTPS domains 2026-07-25 21:24:03 +02:00
customers.blade.php fix: seat limit + suspend guard per Codex; harden factory email uniqueness 2026-07-25 14:53:15 +02:00
datacenters.blade.php fix(admin): no admin lockout (is_admin fallback); centered modal width; datacenter edit modal + country dropdown 2026-07-25 18:09:17 +02:00
edit-datacenter.blade.php fix(ui): make modal cancel buttons work; serve the app over the HTTPS domains 2026-07-25 21:24:03 +02:00
host-create.blade.php feat(admin): datacenters management (create + select) 2026-07-25 13:25:17 +02:00
host-detail.blade.php feat(admin): host reserve edit + maintenance drain; customer suspend/reactivate 2026-07-25 14:30:21 +02:00
hosts.blade.php feat(admin): scalable host list (search/filter/health) + host detail redesign 2026-07-25 14:27:53 +02:00
instances.blade.php feat(admin): dark Tactical-Terminal operator console 2026-07-25 08:35:03 +02:00
maintenance.blade.php fix(portal): no silent no-ops without a customer; maintenance visible per instance; maintenance form redesign 2026-07-25 19:10:44 +02:00
overview.blade.php feat(admin): datacenter edit+delete (guarded); MRR chart fills card; host-load as meters 2026-07-25 14:22:15 +02:00
provisioning.blade.php feat(admin): provisioning liveness — per-run progress bar, last-activity, stale warning 2026-07-25 18:11:17 +02:00
revenue.blade.php feat(admin): dark Tactical-Terminal operator console 2026-07-25 08:35:03 +02:00
settings.blade.php fix(admin): shown-once temp password for invited staff; suppress announcements for cancelled windows at send time 2026-07-25 16:23:21 +02:00
vpn-config-access.blade.php feat(vpn): ownership, a Developer role, and password-gated config retrieval 2026-07-25 22:31:54 +02:00
vpn.blade.php feat(vpn): ownership, a Developer role, and password-gated config retrieval 2026-07-25 22:31:54 +02:00