#!/bin/bash # One-shot post-synapse provisioning: create admin user (idempotent) and # write /data/shared/credentials.json for the TUI and MCP server. set -euo pipefail DATA=/data DOMAIN=${MATRIX_SERVER_NAME:-localhost} USER=${MATRIX_USER:-admin} PASS=${MATRIX_PASSWORD:?} MXID="@${USER}:${DOMAIN}" HS=http://synapse:8008 REG_SECRET=$(cat $DATA/secrets/registration_shared_secret 2>/dev/null || true) log() { echo "[provision] $*"; } # already provisioned and token still valid? then no-op if [ -f "$DATA/shared/credentials.json" ]; then TOK=$(yq -p json '.access_token' "$DATA/shared/credentials.json") if curl -sf -H "Authorization: Bearer $TOK" "$HS/_matrix/client/v3/account/whoami" >/dev/null; then log "credentials already valid, nothing to do" exit 0 fi fi login() { curl -sf -X POST "$HS/_matrix/client/v3/login" \ -d "{\"type\":\"m.login.password\",\"identifier\":{\"type\":\"m.id.user\",\"user\":\"$USER\"},\"password\":$(python3 -c "import json,sys;print(json.dumps(sys.argv[1]))" "$PASS"),\"initial_device_display_name\":\"provision\"}" } RESP=$(login || true) if [ -z "$RESP" ]; then log "admin user missing, registering $MXID" NONCE=$(curl -sf "$HS/_synapse/admin/v1/register" | yq -p json '.nonce') MAC=$(printf '%s\0%s\0%s\0admin' "$NONCE" "$USER" "$PASS" | openssl dgst -sha1 -hmac "$REG_SECRET" | awk '{print $NF}') RESP=$(python3 - "$NONCE" "$USER" "$PASS" "$MAC" <<'EOF' | curl -sf -X POST "$HS/_synapse/admin/v1/register" -d @- import json, sys n, u, p, m = sys.argv[1:5] print(json.dumps({"nonce": n, "username": u, "password": p, "admin": True, "mac": m})) EOF ) [ -n "$RESP" ] || { log "registration failed"; exit 1; } fi TOKEN=$(echo "$RESP" | yq -p json '.access_token') DEVICE=$(echo "$RESP" | yq -p json '.device_id') python3 - "$HS" "$MXID" "$PASS" "$TOKEN" "$DEVICE" <<'EOF' > $DATA/shared/credentials.json.new import json, sys hs, mxid, pw, tok, dev = sys.argv[1:6] print(json.dumps({"homeserver": hs, "user_id": mxid, "password": pw, "access_token": tok, "device_id": dev}, indent=2)) EOF mv $DATA/shared/credentials.json.new $DATA/shared/credentials.json chmod a+rw $DATA/shared/credentials.json log "credentials written for $MXID"