From 45b5f473c9f8e569907a84bd55afeef90c6a37c9 Mon Sep 17 00:00:00 2001 From: hsiegeln <37154749+hsiegeln@users.noreply.github.com> Date: Sun, 26 Apr 2026 19:48:20 +0200 Subject: [PATCH] =?UTF-8?q?refactor(auth):=20post-review=20tidy=20?= =?UTF-8?q?=E2=80=94=20drop=20@NotNull,=20refresh=20e2e=20comment,=20use?= =?UTF-8?q?=20oidc.primary?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-Authored-By: Claude Sonnet 4.6 --- .../cameleer/server/app/dto/AuthCapabilitiesResponse.java | 3 +-- ui/src/auth/LoginPage.tsx | 8 ++++---- ui/src/test/e2e/fixtures.ts | 5 +++-- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/cameleer-server-app/src/main/java/com/cameleer/server/app/dto/AuthCapabilitiesResponse.java b/cameleer-server-app/src/main/java/com/cameleer/server/app/dto/AuthCapabilitiesResponse.java index ef2c4b0a..7466af68 100644 --- a/cameleer-server-app/src/main/java/com/cameleer/server/app/dto/AuthCapabilitiesResponse.java +++ b/cameleer-server-app/src/main/java/com/cameleer/server/app/dto/AuthCapabilitiesResponse.java @@ -1,7 +1,6 @@ package com.cameleer.server.app.dto; import io.swagger.v3.oas.annotations.media.Schema; -import jakarta.validation.constraints.NotNull; @Schema(description = "Authentication capabilities reported to the SPA so it can render the login page deterministically") public record AuthCapabilitiesResponse( @@ -12,7 +11,7 @@ public record AuthCapabilitiesResponse( @Schema(description = "OIDC interactive login") public record Oidc( @Schema(description = "Whether OIDC is configured AND enabled") boolean enabled, - @Schema(description = "Best-effort display label, e.g. \"Logto\", \"Keycloak\", \"Single Sign-On\"") @NotNull String providerName, + @Schema(description = "Best-effort display label, e.g. \"Logto\", \"Keycloak\", \"Single Sign-On\"") String providerName, @Schema(description = "When true, OIDC is the canonical entry point and the SPA hides the local form unless ?local is set") boolean primary ) {} diff --git a/ui/src/auth/LoginPage.tsx b/ui/src/auth/LoginPage.tsx index 881b17aa..515b3de8 100644 --- a/ui/src/auth/LoginPage.tsx +++ b/ui/src/auth/LoginPage.tsx @@ -52,14 +52,14 @@ export function LoginPage() { if (isAuthenticated) return ; if (capsLoading) return null; - const oidcEnabled = caps?.oidc?.enabled === true; + const oidcPrimary = caps?.oidc?.primary === true; const adminRecoveryOnly = caps?.localAccounts?.adminRecoveryOnly === true; const providerName = caps?.oidc?.providerName || 'Single Sign-On'; // Render decisions - const showSsoPrimary = oidcEnabled && adminRecoveryOnly && !forceLocal; - const showLocalForm = !oidcEnabled || forceLocal || !adminRecoveryOnly || capsFailed; - const showAdminRecoveryBanner = oidcEnabled && adminRecoveryOnly && forceLocal; + const showSsoPrimary = oidcPrimary && adminRecoveryOnly && !forceLocal; + const showLocalForm = !oidcPrimary || forceLocal || !adminRecoveryOnly || capsFailed; + const showAdminRecoveryBanner = oidcPrimary && adminRecoveryOnly && forceLocal; const handleSubmit = (e: FormEvent) => { e.preventDefault(); diff --git a/ui/src/test/e2e/fixtures.ts b/ui/src/test/e2e/fixtures.ts index 2a02ead3..f27b9dad 100644 --- a/ui/src/test/e2e/fixtures.ts +++ b/ui/src/test/e2e/fixtures.ts @@ -19,8 +19,9 @@ type Fixtures = { export const test = base.extend({ loggedIn: [ async ({ page }, use) => { - // `?local` keeps the login page's auto-OIDC-redirect from firing so the - // form-based login works even when an OIDC config happens to be present. + // Navigate to ?local to bypass the SSO-primary page and reach the local + // form directly, so the fixture works regardless of whether OIDC is + // configured on the test server. await page.goto('/login?local'); await page.getByLabel(/username/i).fill(ADMIN_USER); await page.getByLabel(/password/i).fill(ADMIN_PASS);