#!/usr/bin/env bash # # setup-dev-user.sh — Create a local-dev user account end-to-end. # # Calls mana-auth's POST /api/v1/auth/register (which goes through # Better Auth's signUpEmail), then runs an idempotent SQL UPDATE to # mark the email as verified and lift the access tier to 'founder' # so the new user can immediately exercise every tier-gated module. # # Why both steps? # - Better Auth's createUser hashes the password the way the runtime # expects (scrypt). Hand-rolling INSERTs in raw SQL would either # hash wrong (login fails) or pull a moving-target dependency. # - The local mana-auth has `requireEmailVerification: true` and no # real SMTP wired up. The verification token sits in # `auth.verification` waiting for someone to click it. The SQL # bypass at the end is the standard local-dev shortcut. # - The default tier is `public`. Founder is the highest tier so # every requiredTier check passes — that's the point of a dev # account. # # Usage: # ./scripts/dev/setup-dev-user.sh # creates the 3 default accounts # ./scripts/dev/setup-dev-user.sh email@x.de pass # creates a single account # # Defaults are tills95@gmail.com, tilljkb@gmail.com, rajiehq@gmail.com # all with password "Aa-123456789". # # Idempotent: existing users get tier/email_verified re-applied without # touching their password. Re-running the script after a partial setup # is safe. # # Prereqs: # - Postgres up + reachable at localhost:5432 (`pnpm docker:up`) # - mana-auth running on :3001 (`pnpm dev:auth`) # - psql in PATH set -euo pipefail # ─── Config ────────────────────────────────────────────────── AUTH_URL="${AUTH_URL:-http://localhost:3001}" DB_HOST="${DB_HOST:-localhost}" DB_PORT="${DB_PORT:-5432}" DB_USER="${DB_USER:-mana}" DB_PASS="${DB_PASS:-devpassword}" DB_NAME="${DB_NAME:-mana_platform}" TIER="${TIER:-founder}" GREEN='\033[0;32m' YELLOW='\033[1;33m' RED='\033[0;31m' DIM='\033[2m' NC='\033[0m' # ─── Preflight ─────────────────────────────────────────────── if ! command -v psql >/dev/null 2>&1; then echo -e "${RED}error:${NC} psql not in PATH. Install postgres client first." exit 1 fi if ! curl -fsS "${AUTH_URL}/health" >/dev/null 2>&1 \ && ! curl -fsS "${AUTH_URL}/api/v1/auth/signup-status" >/dev/null 2>&1; then echo -e "${RED}error:${NC} mana-auth not reachable at ${AUTH_URL}." echo -e "${DIM} Start it with: pnpm dev:auth${NC}" exit 1 fi # ─── Create-or-promote one user ────────────────────────────── create_user() { local email="$1" local password="$2" local name name="${email%@*}" echo -e "\n${GREEN}→${NC} ${email}" # Step 1: register via mana-auth (Better Auth signUpEmail under the hood) local response http_code response=$(curl -sS -o /tmp/setup-dev-user.body -w "%{http_code}" \ -X POST "${AUTH_URL}/api/v1/auth/register" \ -H "Content-Type: application/json" \ -d "{\"email\":\"${email}\",\"password\":\"${password}\",\"name\":\"${name}\"}" \ || true) http_code="${response}" local body body="$(cat /tmp/setup-dev-user.body || true)" rm -f /tmp/setup-dev-user.body case "${http_code}" in 200|201) echo -e " ${DIM}registered${NC}" ;; 409) echo -e " ${YELLOW}already exists${NC} — re-applying tier/verification" ;; 429) echo -e " ${RED}rate limit hit${NC}: ${body}" return 1 ;; *) echo -e " ${RED}register failed (HTTP ${http_code})${NC}: ${body}" return 1 ;; esac # Step 2: idempotent SQL — verify email + lift tier. # Quoting note: the table is auth.users (Better Auth schema), columns # are email_verified + access_tier. The access_tier enum lives in the # public schema (Drizzle's pgEnum default), so the cast is just # `::access_tier`, NOT `auth.access_tier`. We bind email + tier as # psql vars to dodge any quoting weirdness. PGPASSWORD="${DB_PASS}" psql -q \ -h "${DB_HOST}" -p "${DB_PORT}" -U "${DB_USER}" -d "${DB_NAME}" \ -v ON_ERROR_STOP=1 \ -v email="${email}" \ -v tier="${TIER}" \ <<-'SQL' UPDATE auth.users SET email_verified = true, access_tier = :'tier'::access_tier, updated_at = NOW() WHERE email = :'email'; SQL # Verify final state and report local row row=$(PGPASSWORD="${DB_PASS}" psql -t -A \ -h "${DB_HOST}" -p "${DB_PORT}" -U "${DB_USER}" -d "${DB_NAME}" \ -c "SELECT id, email_verified, access_tier, role FROM auth.users WHERE email = '${email}';") if [[ -z "${row}" ]]; then echo -e " ${RED}user row missing after register${NC}" return 1 fi echo -e " ${DIM}${row}${NC}" echo -e " ${GREEN}✓${NC} email=${email} password=${password} tier=${TIER}" } # ─── Main ──────────────────────────────────────────────────── if [[ $# -eq 2 ]]; then create_user "$1" "$2" else echo -e "${GREEN}Creating default dev users (${TIER} tier)…${NC}" create_user "tills95@gmail.com" "Aa-123456789" create_user "tilljkb@gmail.com" "Aa-123456789" create_user "rajiehq@gmail.com" "Aa-123456789" fi echo -e "\n${GREEN}✓ Done.${NC} Login at ${AUTH_URL/3001/5173}/login"