Commit Graph

17 Commits

Author SHA1 Message Date
hsiegeln
92503a1061 feat: add vendor infrastructure page with PG/CH per-tenant view
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-11 23:18:59 +02:00
hsiegeln
e2e5c794a2 feat: add server upgrade action — force-pull latest images and re-provision
All checks were successful
CI / build (push) Successful in 1m19s
CI / docker (push) Successful in 48s
Restart only stops/starts existing containers with the same image. The new
upgrade action removes server + UI containers, force-pulls the latest
Docker images, then re-provisions (preserving app containers, volumes, and
networks). Available to both vendor (tenant detail) and tenant admin
(dashboard).

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-11 10:45:45 +02:00
hsiegeln
d5eead888d feat: server admin password reset via tenant portal
All checks were successful
CI / build (push) Successful in 2m23s
CI / docker (push) Successful in 1m8s
- POST /api/tenant/server/admin-password — resets server's built-in
  admin password via M2M API call to the tenant's server
- Settings page: "Server Admin Password" card
- ServerApiClient.resetServerAdminPassword() calls server's password
  reset endpoint with M2M token

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-11 09:46:30 +02:00
hsiegeln
4121bd64b2 feat: password management for tenant portal
All checks were successful
CI / build (push) Successful in 1m15s
CI / docker (push) Successful in 47s
- POST /api/tenant/password — change own Logto password
- POST /api/tenant/team/{userId}/password — reset team member password
- Settings page: "Change Password" card with confirm field
- Team page: "Reset Password" button per member with inline form
- LogtoManagementClient.updateUserPassword() via Logto Management API

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-11 09:19:48 +02:00
hsiegeln
dd30ee77d4 feat: tenant CA certificate management with staging
Some checks failed
CI / build (push) Successful in 1m7s
CI / docker (push) Has been cancelled
Tenants can upload multiple CA certificates for enterprise SSO providers
that use private certificate authorities.

- New tenant_ca_certs table (V013) with PEM storage in DB
- Stage/activate/delete lifecycle per CA cert
- Aggregated ca.pem rebuild on activate/delete (atomic .wip swap)
- REST API: GET/POST/DELETE on /api/tenant/ca
- UI: CA Certificates section on SSO page with upload, activate, remove

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-10 19:35:04 +02:00
hsiegeln
45bcc954ac feat: certificate management with stage/activate/restore lifecycle
All checks were successful
CI / build (push) Successful in 1m8s
CI / docker (push) Successful in 45s
Provider-based architecture (Docker now, K8s later):
- CertificateManager interface + DockerCertificateManager (file-based)
- Atomic swap via .wip files for safe cert replacement
- Stage -> Activate -> Archive lifecycle with one-deep rollback
- Bootstrap supports user-supplied certs via CERT_FILE/KEY_FILE/CA_FILE
- CA bundle aggregates platform + tenant CAs, distributed to containers
- Vendor UI: Certificates page with upload, activate, restore, discard
- Stale tenant tracking (ca_applied_at) with restart banner
- Conditional TLS skip removal when CA bundle exists

Includes design spec, migration V012, service + controller tests.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-10 18:29:02 +02:00
hsiegeln
7e7a07470b feat: add restart server action for vendor and tenant
Some checks failed
CI / build (push) Failing after 36s
CI / docker (push) Has been skipped
Vendor: POST /api/vendor/tenants/{id}/restart (platform:admin scope)
Tenant: POST /api/tenant/server/restart (tenant:manage scope)

Both call TenantProvisioner.stop() then start() on the server + UI
containers. Restart button on vendor TenantDetailPage (Actions card)
and tenant TenantDashboardPage (Server card). Allowed in any status
including PROVISIONING.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-10 17:21:14 +02:00
hsiegeln
252c18bcff feat: async tenant provisioning with polling UX
Some checks failed
CI / build (push) Failing after 39s
CI / docker (push) Has been skipped
Backend: extract Docker provisioning into @Async method so the API
returns immediately with status=PROVISIONING. The tenant record, Logto
org, admin user, and license are created synchronously; container
provisioning, health check, license push, and OIDC config happen in a
background thread.

Frontend: navigate to tenant detail page immediately after creation.
Detail page polls every 3s while status=PROVISIONING and shows a
spinner indicator. Toast notification when provisioning completes.
Fixes #52.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-10 17:14:26 +02:00
hsiegeln
e559267f1e feat: replace tenant OIDC page with Enterprise SSO connector management
All checks were successful
CI / build (push) Successful in 1m3s
CI / docker (push) Successful in 46s
- Add LogtoManagementClient methods for SSO connector CRUD + org JIT
- Add TenantSsoService with tenant isolation (validates connector-org link)
- Add TenantSsoController at /api/tenant/sso with test endpoint
- Create SsoPage with provider selection, dynamic config form, test button
- Remove old OIDC config endpoints from tenant portal (server OIDC is
  now platform-managed, set during provisioning)
- Sidebar: OIDC -> SSO with Shield icon

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-10 15:48:51 +02:00
hsiegeln
8b94937d38 feat: add audit log viewing for vendor and tenant personas
All checks were successful
CI / build (push) Successful in 52s
CI / docker (push) Successful in 40s
Vendor sees all audit events with tenant filter at /vendor/audit.
Tenant admin sees only their own events at /tenant/audit.
Both support pagination, action/result filters, and text search.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-10 13:07:18 +02:00
hsiegeln
bf3aa57274 feat: restructure frontend routes — vendor/tenant persona split
Splits the flat 3-page UI into /vendor/* (platform:admin) and /tenant/*
(all authenticated users) route trees, with stub pages, new API hooks,
updated Layout with persona-aware sidebar, and SpaController forwarding.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-09 22:29:59 +02:00
hsiegeln
5938643632 feat: strip SaaS UI to vendor management dashboard
- Delete EnvironmentsPage, EnvironmentDetailPage, AppDetailPage
- Delete EnvironmentTree and DeploymentStatusBadge components
- Simplify DashboardPage to show tenant info, license status, server link
- Remove environment/app/deployment routes from router
- Remove environment section from sidebar, keep dashboard/license/platform
- Strip API hooks to tenant/license/me only
- Remove environment/app/deployment/observability types

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-08 00:03:01 +02:00
hsiegeln
4997f7a6a9 feat: move SaaS app to /platform base path, Logto becomes catch-all
All checks were successful
CI / build (push) Successful in 48s
CI / docker (push) Successful in 41s
Eliminates all Logto path enumeration in Traefik. Routing is now:
- /platform/* → cameleer-saas (SPA + API)
- /server/* → server-ui
- /* (catch-all) → Logto (sign-in, OIDC, assets, everything)

Spring context-path handles backend prefix transparently. No changes
needed in controllers, SecurityConfig, or interceptors.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-05 23:06:41 +02:00
hsiegeln
1abf0f827b fix: remove 401 hard redirect, let React Query retry
All checks were successful
CI / build (push) Successful in 40s
CI / docker (push) Successful in 41s
The /api/me call races with TokenSync — fires before the token
provider is set. Removed the hard window.location redirect on 401
from the API client. React Query retries with backoff instead.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-05 03:02:32 +02:00
hsiegeln
827e388349 feat: bootstrap 2 users, tenant, org-scoped tokens, platform admin UI
All checks were successful
CI / build (push) Successful in 40s
CI / docker (push) Successful in 39s
Bootstrap script now creates:
- SaaS Owner (admin/admin) with platform-admin role
- Tenant Admin (camel/camel) in Example Tenant org
- Traditional Web App for cameleer3-server OIDC
- DB records: tenant, default environment, license
- Configures cameleer3-server OIDC via its admin API
All credentials configurable via env vars.

Backend:
- Fix LogtoManagementClient resource URL (https://default.logto.app/api)
- Add getUserRoles/getUserOrganizations to LogtoManagementClient
- Add GET /api/me endpoint (user info, platform admin status, tenants)
- Add GET /api/tenants list-all for platform admins
- Remove insecure X-header forwarding from Traefik

Frontend:
- Org-scoped tokens: getAccessToken(resource, orgId) for tenant context
- OrgResolver component populates org store from /api/me
- useOrganization Zustand store (currentOrgId + currentTenantId)
- Platform admin sidebar section + AdminTenantsPage
- View Dashboard link points to cameleer3-server on port 8081

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-05 02:50:51 +02:00
hsiegeln
0843a33383 refactor: replace hand-rolled OIDC with @logto/react SDK
All checks were successful
CI / build (push) Successful in 38s
CI / docker (push) Successful in 48s
The hand-rolled OIDC flow (manual PKCE, token exchange, URL
construction) was fragile and accumulated multiple bugs. Replaced
with the official @logto/react SDK which handles PKCE, token
exchange, storage, and refresh automatically.

- Add @logto/react SDK dependency
- Add LogtoProvider with runtime config in main.tsx
- Add TokenSync component bridging SDK tokens to API client
- Add useAuth hook replacing Zustand auth store
- Simplify LoginPage to signIn(), CallbackPage to useHandleSignInCallback()
- Delete pkce.ts and auth-store.ts (replaced by SDK)
- Fix react-router-dom → react-router imports in page files
- All 17 React Query hooks unchanged (token provider pattern)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-05 01:17:47 +02:00
hsiegeln
d572926010 feat: add API client with auth middleware and React Query hooks
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-04 21:50:19 +02:00