#!/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" <