From 5754b0ca81df7088d7ff61b3e7171ea440b7bb06 Mon Sep 17 00:00:00 2001 From: hsiegeln <37154749+hsiegeln@users.noreply.github.com> Date: Sun, 26 Apr 2026 12:31:12 +0200 Subject: [PATCH] fix: set Logto display name from email during onboarding Email-registered users have no name field in Logto, causing empty OIDC name claims. After adding user to org, derive display name from email local part (john.doe@acme.com -> john.doe) if name is not already set. Also adds updateUserProfile() to LogtoManagementClient. Co-Authored-By: Claude Opus 4.6 (1M context) --- .../saas/identity/LogtoManagementClient.java | 12 ++++++++++++ .../cameleer/saas/onboarding/OnboardingService.java | 12 ++++++++++++ 2 files changed, 24 insertions(+) diff --git a/src/main/java/net/siegeln/cameleer/saas/identity/LogtoManagementClient.java b/src/main/java/net/siegeln/cameleer/saas/identity/LogtoManagementClient.java index 8defdc2..d91c563 100644 --- a/src/main/java/net/siegeln/cameleer/saas/identity/LogtoManagementClient.java +++ b/src/main/java/net/siegeln/cameleer/saas/identity/LogtoManagementClient.java @@ -526,6 +526,18 @@ public class LogtoManagementClient { .toBodilessEntity(); } + /** Update a user's profile fields (e.g. name). */ + public void updateUserProfile(String userId, Map profile) { + if (!isAvailable()) throw new IllegalStateException("Logto not configured"); + restClient.patch() + .uri(config.getLogtoEndpoint() + "/api/users/" + userId) + .header("Authorization", "Bearer " + getAccessToken()) + .contentType(MediaType.APPLICATION_JSON) + .body(profile) + .retrieve() + .toBodilessEntity(); + } + /** Get a user by ID. Returns username, primaryEmail, name. */ @SuppressWarnings("unchecked") public Map getUser(String userId) { diff --git a/src/main/java/net/siegeln/cameleer/saas/onboarding/OnboardingService.java b/src/main/java/net/siegeln/cameleer/saas/onboarding/OnboardingService.java index bfd987d..32102e6 100644 --- a/src/main/java/net/siegeln/cameleer/saas/onboarding/OnboardingService.java +++ b/src/main/java/net/siegeln/cameleer/saas/onboarding/OnboardingService.java @@ -8,6 +8,7 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.stereotype.Service; +import java.util.Map; import java.util.UUID; /** @@ -52,6 +53,17 @@ public class OnboardingService { logtoClient.assignOrganizationRole(tenant.getLogtoOrgId(), logtoUserId, ownerRoleId); } log.info("Added user {} as owner of tenant {}", logtoUserId, slug); + + // Set display name from email if not already set (email-registered users have no name) + var user = logtoClient.getUser(logtoUserId); + if (user != null && (user.get("name") == null || String.valueOf(user.get("name")).isBlank())) { + String email = String.valueOf(user.getOrDefault("primaryEmail", "")); + if (!email.isBlank() && email.contains("@")) { + String displayName = email.substring(0, email.indexOf('@')); + logtoClient.updateUserProfile(logtoUserId, Map.of("name", displayName)); + log.info("Set display name '{}' for user {}", displayName, logtoUserId); + } + } } catch (Exception e) { log.warn("Failed to add user {} to org for tenant {}: {}", logtoUserId, slug, e.getMessage()); }