#!/usr/bin/env bash set -euo pipefail base_url="${SPARKYFITNESS_BASE_URL:-http://sparkyfitness-server.health.svc.cluster.local:3010}" frontend_url="${SPARKYFITNESS_FRONTEND_URL:?SPARKYFITNESS_FRONTEND_URL is required}" admin_email="${SPARKYFITNESS_ADMIN_EMAIL:?SPARKYFITNESS_ADMIN_EMAIL is required}" admin_password="${SPARKYFITNESS_ADMIN_PASSWORD:?SPARKYFITNESS_ADMIN_PASSWORD is required}" oidc_client_id="${SPARKYFITNESS_OIDC_CLIENT_ID:?SPARKYFITNESS_OIDC_CLIENT_ID is required}" oidc_client_secret="${SPARKYFITNESS_OIDC_CLIENT_SECRET:?SPARKYFITNESS_OIDC_CLIENT_SECRET is required}" oidc_issuer_url="${SPARKYFITNESS_OIDC_ISSUER_URL:?SPARKYFITNESS_OIDC_ISSUER_URL is required}" wait_for_server() { for attempt in 1 2 3 4 5 6 7 8 9 10; do if curl -fsS "${base_url}/health" >/dev/null 2>&1; then return 0 fi sleep $((attempt * 3)) done return 1 } cookie_jar="$(mktemp)" trap 'rm -f "${cookie_jar}"' EXIT auth_login() { local payload payload="$(jq -nc --arg email "${admin_email}" --arg password "${admin_password}" '{email:$email,password:$password}')" local status status="$(curl -sS -o /tmp/sparkyfitness_login.json -w "%{http_code}" \ -c "${cookie_jar}" -b "${cookie_jar}" \ -H "Content-Type: application/json" \ -X POST "${base_url}/auth/login" \ -d "${payload}")" if [ "${status}" = "200" ]; then return 0 fi return 1 } auth_register() { local payload payload="$(jq -nc --arg email "${admin_email}" --arg password "${admin_password}" --arg full_name "Sparky Admin" '{email:$email,password:$password,full_name:$full_name}')" curl -sS -o /tmp/sparkyfitness_register.json -w "%{http_code}" \ -c "${cookie_jar}" -b "${cookie_jar}" \ -H "Content-Type: application/json" \ -X POST "${base_url}/auth/register" \ -d "${payload}" } if ! wait_for_server; then echo "SparkyFitness is not responding at ${base_url}" >&2 exit 1 fi if ! auth_login; then status="$(auth_register)" if [ "${status}" = "409" ]; then if ! auth_login; then echo "Admin login failed after existing user detected" >&2 exit 1 fi elif [ "${status}" = "201" ]; then if ! auth_login; then echo "Admin login failed after registration" >&2 exit 1 fi elif [ "${status}" = "403" ]; then echo "Registration disabled; unable to bootstrap admin user" >&2 exit 1 else echo "Admin registration failed (status ${status})" >&2 exit 1 fi fi settings_json="$(curl -sS -b "${cookie_jar}" "${base_url}/admin/global-settings")" if [ -z "${settings_json}" ]; then echo "Failed to fetch SparkyFitness global settings" >&2 exit 1 fi email_enabled="$(echo "${settings_json}" | jq -r '.enable_email_password_login // true')" mfa_mandatory="$(echo "${settings_json}" | jq -r '.is_mfa_mandatory // .mfa_mandatory // false')" settings_payload="$(jq -nc \ --argjson enable_email_password_login "${email_enabled}" \ --argjson is_oidc_active true \ --argjson is_mfa_mandatory "${mfa_mandatory}" \ '{enable_email_password_login:$enable_email_password_login,is_oidc_active:$is_oidc_active,is_mfa_mandatory:$is_mfa_mandatory}')" status="$(curl -sS -o /dev/null -w "%{http_code}" -b "${cookie_jar}" \ -H "Content-Type: application/json" \ -X PUT "${base_url}/admin/global-settings" \ -d "${settings_payload}")" if [ "${status}" != "200" ]; then echo "Failed to update SparkyFitness global settings (status ${status})" >&2 exit 1 fi providers_json="$(curl -sS -b "${cookie_jar}" "${base_url}/admin/oidc-settings")" provider_id="$(echo "${providers_json}" | jq -r --arg issuer "${oidc_issuer_url}" '.[] | select(.issuer_url==$issuer) | .id' 2>/dev/null | head -n1 || true)" redirect_uri="${frontend_url%/}/oidc-callback" provider_payload="$(jq -nc \ --arg issuer_url "${oidc_issuer_url}" \ --arg client_id "${oidc_client_id}" \ --arg client_secret "${oidc_client_secret}" \ --arg redirect_uri "${redirect_uri}" \ --arg scope "openid profile email" \ --arg token_endpoint_auth_method "client_secret_post" \ --argjson response_types '["code"]' \ --argjson is_active true \ --arg display_name "Atlas SSO" \ --argjson auto_register true \ --arg signing_algorithm "RS256" \ --arg profile_signing_algorithm "none" \ --argjson timeout 30000 \ '{issuer_url:$issuer_url,client_id:$client_id,client_secret:$client_secret,redirect_uris:[$redirect_uri],scope:$scope,token_endpoint_auth_method:$token_endpoint_auth_method,response_types:$response_types,is_active:$is_active,display_name:$display_name,auto_register:$auto_register,signing_algorithm:$signing_algorithm,profile_signing_algorithm:$profile_signing_algorithm,timeout:$timeout}')" if [ -n "${provider_id}" ] && [ "${provider_id}" != "null" ]; then status="$(curl -sS -o /dev/null -w "%{http_code}" -b "${cookie_jar}" \ -H "Content-Type: application/json" \ -X PUT "${base_url}/admin/oidc-settings/${provider_id}" \ -d "${provider_payload}")" else status="$(curl -sS -o /dev/null -w "%{http_code}" -b "${cookie_jar}" \ -H "Content-Type: application/json" \ -X POST "${base_url}/admin/oidc-settings" \ -d "${provider_payload}")" fi if [ "${status}" != "200" ] && [ "${status}" != "201" ]; then echo "Failed to upsert SparkyFitness OIDC provider (status ${status})" >&2 exit 1 fi