| 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465 |
- #!/usr/bin/env bash
- # bootstrap-super-admin.sh — Create the first super_admin user.
- #
- # Per M13 decision 2.4 (magic-link with psql fallback), this is
- # the fallback path: when the operator can't use the invite flow
- # (e.g. no email service configured yet, or recovery from a
- # forgotten password), they can bootstrap a super_admin directly
- # via psql.
- #
- # Usage:
- # scripts/bootstrap-super-admin.sh [email] [password]
- #
- # Defaults: super@broad-announce.test / test-password-123
- #
- # Requires:
- # - psql in PATH
- # - $BA_POSTGRES_DSN (or pass as PG_DSN env var)
- # - The 009_auth migration applied (the 'auth' schema exists)
- #
- # Idempotent: if the user already exists with status='active', the
- # script just updates the password. If the user doesn't exist, it
- # creates the user with the given credentials.
- set -euo pipefail
- cd "$(dirname "$0")/.."
- EMAIL="${1:-super@broad-announce.test}"
- PASSWORD="${2:-test-password-123}"
- DSN="${BA_POSTGRES_DSN:-${PG_DSN:-postgres://ba:ba@localhost:5432/ba?sslmode=disable}}"
- # Generate bcrypt hash at cost 10 (lower than prod's 12 because
- # the bootstrap runs in seconds, not milliseconds).
- HASH=$(python3 -c "
- import bcrypt
- print(bcrypt.hashpw(b'${PASSWORD}', bcrypt.gensalt(rounds=10)).decode())
- ")
- export PGPASSWORD="$(echo "$DSN" | sed -E 's|.*://[^:]+:([^@]+)@.*|\1|')"
- psql "$DSN" <<SQL
- DO \$\$
- DECLARE
- v_user_id UUID;
- BEGIN
- -- Upsert the super_admin. Email is unique globally when
- -- tenant_id IS NULL.
- INSERT INTO auth.users (tenant_id, email, role, status, password_hash)
- VALUES (NULL, '$EMAIL', 'super_admin', 'active', '$HASH')
- ON CONFLICT (email) WHERE tenant_id IS NULL DO UPDATE
- SET status = 'active',
- password_hash = EXCLUDED.password_hash,
- updated_at = NOW()
- RETURNING id INTO v_user_id;
- RAISE NOTICE 'super_admin ready: % (id=%)', '$EMAIL', v_user_id;
- END \$\$;
- SQL
- echo ""
- echo "next steps:"
- echo " 1. docker compose up -d authd"
- echo " 2. curl -X POST http://localhost:8804/v1/auth/login \\"
- echo " -H 'Content-Type: application/json' \\"
- echo " -d '{\"email\":\"$EMAIL\",\"password\":\"$PASSWORD\"}'"
- echo " 3. bash scripts/m13a_smoke.sh"
|