Commit Graph

8 Commits (v1.3.55)

Author SHA1 Message Date
nexxo 47812cfca9 Authorize the console's live feed on the operator guard, not the default
POST /broadcasting/auth carries only the 'web' middleware group
(Laravel's own withBroadcasting() registers it that way), so
PusherBroadcaster::auth() resolved retrieveUser() on the DEFAULT guard
before the admin.runs channel's own Auth::guard('operator') check ever
ran — found nobody, since an operator is never signed in on 'web', and
threw straight from there. The guard was correct but unreachable.
Fixed by naming both guards on the channel registration itself.

Also adds broadcasting/auth to RestrictAdminHost::SHARED: in exclusive
mode it was neither admin.* by name nor on the shared list, so it 404'd
on the console host too — degrading silently to wire:poll.4s rather
than breaking outright, which is why nothing screamed.
2026-07-28 13:31:50 +02:00
nexxo 87c49de6e5 Move the console's identity out of the customer table 2026-07-28 10:31:43 +02:00
nexxo 8304f2e7dc fix(admin): self-heal legacy is_admin into Owner (no RBAC bypass); validate datacenter country server-side
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-25 18:19:24 +02:00
nexxo b50f97568f fix(admin): no admin lockout (is_admin fallback); centered modal width; datacenter edit modal + country dropdown
- isOperator()/EnsureAdmin/broadcast fall back to is_admin so a legacy admin is
  never locked out by a stale permission cache
- published modal: centered max-w-lg card (dynamic modalWidth class was purged
  by Tailwind → full-width)
- datacenter edit moved to a modal (no row-height jump); location is now a
  country dropdown (config/countries.php) instead of free text

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-25 18:09:17 +02:00
nexxo c5d60340b7 feat(admin): staff RBAC (spatie) + admin settings page
- 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>
2026-07-25 15:47:42 +02:00
nexxo a9fbb395f9 feat(engine-b): live provisioning progress (admin console + customer dashboard)
Admin /admin/provisioning bound to real runs+steps (poll+admin.runs). Embedded
CustomerProvisioning card shows the logged-in customer their own run live
(per-customer StepAdvanced channel, email-bridged authz). Shared BuildsRunSteps.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-25 11:57:35 +02:00
nexxo 4f724d57c9 feat(engine): orchestrator core (state machine + tick + lock)
StepResult, ProvisioningStep contract, PipelineRegistry, RunRunner (per-run
lock, advance/retry/fail, backoff, timeout, append-only events + Reverb
StepAdvanced), AdvanceRunJob (provisioning queue), minutely Tick, admin.runs
channel. 21 tests.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-25 09:54:52 +02:00
nexxo 2ae7595aff chore: bootstrap CluPilot control-plane (Laravel 13, Docker stack)
- Docker dev stack: app (php-fpm+nginx+vite via supervisor), reverb, queue,
  scheduler, mariadb 11.4, redis 7 — env-driven ports/UID (HOST_UID=1000).
- Laravel 13.8 + Livewire 3.8 (pinned v3 per R2), Tailwind v4, Reverb, Echo,
  phpseclib, wire-elements/modal.
- .env wired to service names; DE default locale (R16); browser Reverb host
  env-driven; self-hosted-fonts-ready vite.config (R14).
- Entrypoint bootstraps vendor/node_modules on fresh checkout; bin/clupilot
  helper (UID/port env-driven) + shell aliases.
- Reviewed with Codex (R15): 7 findings fixed, 1 verified false-positive.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-25 00:21:30 +02:00