diff --git a/docker/logto-bootstrap.sh b/docker/logto-bootstrap.sh index 8760e51..0415d2b 100644 --- a/docker/logto-bootstrap.sh +++ b/docker/logto-bootstrap.sh @@ -407,8 +407,33 @@ else }") ADMIN_USER_ID=$(echo "$ADMIN_RESPONSE" | jq -r '.id') log "Created platform owner: $ADMIN_USER_ID" - # No global role assigned — owner role is org-scoped. - # SaaS vendor role is injected via docker/vendor-seed.sh on hosted environments. +fi + +# --- Always create saas-vendor role and assign to admin user --- +# The admin user needs platform:admin to manage tenants via the vendor console. +log "Ensuring saas-vendor role exists..." +EXISTING_ROLES=$(api_get "/api/roles") +VENDOR_ROLE_ID=$(echo "$EXISTING_ROLES" | jq -r '.[] | select(.name == "saas-vendor" and .type == "User") | .id') + +if [ -z "$VENDOR_ROLE_ID" ]; then + ALL_SCOPE_IDS=$(api_get "/api/resources/$API_RESOURCE_ID/scopes" | jq '[.[].id]') + log "Creating saas-vendor role with all scopes..." + VENDOR_ROLE_RESPONSE=$(api_post "/api/roles" "{ + \"name\": \"saas-vendor\", + \"description\": \"SaaS vendor — full platform control across all tenants\", + \"type\": \"User\", + \"scopeIds\": $ALL_SCOPE_IDS + }") + VENDOR_ROLE_ID=$(echo "$VENDOR_ROLE_RESPONSE" | jq -r '.id') + log "Created saas-vendor role: $VENDOR_ROLE_ID" +else + log "saas-vendor role exists: $VENDOR_ROLE_ID" +fi + +# Assign vendor role to admin user +if [ -n "$VENDOR_ROLE_ID" ] && [ "$VENDOR_ROLE_ID" != "null" ] && [ -n "$ADMIN_USER_ID" ]; then + api_post "/api/users/$ADMIN_USER_ID/roles" "{\"roleIds\": [\"$VENDOR_ROLE_ID\"]}" >/dev/null 2>&1 + log "Assigned saas-vendor role to admin user." fi # --- Grant SaaS admin Logto console access (admin tenant, port 3002) --- @@ -590,28 +615,9 @@ chmod 644 "$BOOTSTRAP_FILE" if [ "$VENDOR_SEED_ENABLED" = "true" ]; then log "" - log "=== Phase 12: Vendor Seed ===" - - # Create saas-vendor global role with all API scopes - log "Checking for saas-vendor role..." - EXISTING_ROLES=$(api_get "/api/roles") - VENDOR_ROLE_ID=$(echo "$EXISTING_ROLES" | jq -r '.[] | select(.name == "saas-vendor" and .type == "User") | .id') - - if [ -n "$VENDOR_ROLE_ID" ]; then - log "saas-vendor role exists: $VENDOR_ROLE_ID" - else - ALL_SCOPE_IDS=$(api_get "/api/resources/$API_RESOURCE_ID/scopes" | jq '[.[].id]') - log "Creating saas-vendor role with all scopes..." - VENDOR_ROLE_RESPONSE=$(api_post "/api/roles" "{ - \"name\": \"saas-vendor\", - \"description\": \"SaaS vendor — full platform control across all tenants\", - \"type\": \"User\", - \"scopeIds\": $ALL_SCOPE_IDS - }") - VENDOR_ROLE_ID=$(echo "$VENDOR_ROLE_RESPONSE" | jq -r '.id') - log "Created saas-vendor role: $VENDOR_ROLE_ID" - fi + log "=== Phase 12: Vendor Seed (separate vendor user) ===" + # saas-vendor role already created above — just create the separate vendor user # Create vendor user log "Checking for vendor user '$VENDOR_USER'..." VENDOR_USER_ID=$(api_get "/api/users?search=$VENDOR_USER" | jq -r ".[] | select(.username == \"$VENDOR_USER\") | .id")