fix: bootstrap extracts username from admin email for Logto
All checks were successful
CI / build (push) Successful in 1m47s
CI / docker (push) Successful in 20s

Logto rejects @ in usernames. Extract local part (before @) as the
Logto username, use full email as primaryEmail. Also validates admin
user creation succeeded (logs error instead of silently continuing
with null ID).

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
hsiegeln
2026-04-25 21:03:54 +02:00
parent 1d26ae481e
commit 4cc3e096b5
2 changed files with 32 additions and 17 deletions

View File

@@ -25,10 +25,18 @@ API_RESOURCE_INDICATOR="https://api.cameleer.local"
API_RESOURCE_NAME="Cameleer SaaS API"
# Users (configurable via env vars)
# In SaaS mode, SAAS_ADMIN_USER is the admin's email address (e.g. admin@company.com).
# The local part (before @) is used as the Logto username; the full value as primaryEmail.
SAAS_ADMIN_USER="${SAAS_ADMIN_USER:-admin}"
SAAS_ADMIN_PASS="${SAAS_ADMIN_PASS:-admin}"
# In SaaS mode, SAAS_ADMIN_USER is the admin's email address.
# Use it as both username and primaryEmail in Logto.
# Extract username (local part) for Logto — Logto rejects @ in usernames
if echo "$SAAS_ADMIN_USER" | grep -q '@'; then
ADMIN_USERNAME="${SAAS_ADMIN_USER%%@*}"
ADMIN_EMAIL="$SAAS_ADMIN_USER"
else
ADMIN_USERNAME="$SAAS_ADMIN_USER"
ADMIN_EMAIL=""
fi
# No server config — servers are provisioned dynamically by the admin console
@@ -391,20 +399,27 @@ log "API resource scopes assigned to organization roles."
# ============================================================
# --- Platform Owner ---
log "Checking for platform owner user '$SAAS_ADMIN_USER'..."
ADMIN_USER_ID=$(api_get "/api/users?search=$SAAS_ADMIN_USER" | jq -r ".[] | select(.username == \"$SAAS_ADMIN_USER\") | .id")
log "Checking for platform owner user '$ADMIN_USERNAME'..."
ADMIN_USER_ID=$(api_get "/api/users?search=$ADMIN_USERNAME" | jq -r ".[] | select(.username == \"$ADMIN_USERNAME\") | .id")
if [ -n "$ADMIN_USER_ID" ]; then
log "Platform owner exists: $ADMIN_USER_ID"
else
log "Creating platform owner '$SAAS_ADMIN_USER'..."
ADMIN_RESPONSE=$(api_post "/api/users" "{
\"username\": \"$SAAS_ADMIN_USER\",
\"password\": \"$SAAS_ADMIN_PASS\",
\"name\": \"Platform Owner\",
\"primaryEmail\": \"$SAAS_ADMIN_USER\"
}")
# Build user JSON — include primaryEmail only if SAAS_ADMIN_USER is an email
ADMIN_USER_JSON="{\"username\": \"$ADMIN_USERNAME\", \"password\": \"$SAAS_ADMIN_PASS\", \"name\": \"Platform Owner\""
if [ -n "$ADMIN_EMAIL" ]; then
ADMIN_USER_JSON="$ADMIN_USER_JSON, \"primaryEmail\": \"$ADMIN_EMAIL\""
log "Creating platform owner '$ADMIN_USERNAME' (email: $ADMIN_EMAIL)..."
else
log "Creating platform owner '$ADMIN_USERNAME'..."
fi
ADMIN_USER_JSON="$ADMIN_USER_JSON}"
ADMIN_RESPONSE=$(api_post "/api/users" "$ADMIN_USER_JSON")
ADMIN_USER_ID=$(echo "$ADMIN_RESPONSE" | jq -r '.id')
log "Created platform owner: $ADMIN_USER_ID"
if [ -z "$ADMIN_USER_ID" ] || [ "$ADMIN_USER_ID" = "null" ]; then
log "ERROR: Failed to create platform owner. Response: $(echo "$ADMIN_RESPONSE" | head -c 300)"
else
log "Created platform owner: $ADMIN_USER_ID"
fi
fi
# --- Grant SaaS admin Logto console access (admin tenant, port 3002) ---
@@ -444,12 +459,12 @@ else
-d "$2" "${LOGTO_ADMIN_ENDPOINT}${1}" 2>/dev/null || true
}
# Check if admin user already exists on admin tenant
ADMIN_TENANT_USER_ID=$(admin_api_get "/api/users?search=$SAAS_ADMIN_USER" | jq -r ".[] | select(.username == \"$SAAS_ADMIN_USER\") | .id" 2>/dev/null)
# Check if admin user already exists on admin tenant (uses ADMIN_USERNAME, not email)
ADMIN_TENANT_USER_ID=$(admin_api_get "/api/users?search=$ADMIN_USERNAME" | jq -r ".[] | select(.username == \"$ADMIN_USERNAME\") | .id" 2>/dev/null)
if [ -z "$ADMIN_TENANT_USER_ID" ] || [ "$ADMIN_TENANT_USER_ID" = "null" ]; then
log "Creating admin console user '$SAAS_ADMIN_USER'..."
log "Creating admin console user '$ADMIN_USERNAME'..."
ADMIN_TENANT_RESPONSE=$(admin_api_post "/api/users" "{
\"username\": \"$SAAS_ADMIN_USER\",
\"username\": \"$ADMIN_USERNAME\",
\"password\": \"$SAAS_ADMIN_PASS\",
\"name\": \"Platform Admin\"
}")