#!/usr/bin/env bash set -euo pipefail ACTION="${1:-}" ARG1="${2:-}" ARG2="${3:-}" ARG3="${4:-}" if [[ -z "$ACTION" ]]; then echo "missing action" >&2 exit 2 fi # Fixed host paths to avoid caller-controlled command execution. REPO_DIR="${NUQLOUD_REPO_DIR:-/opt/nuqloud/Qortal-Nextcloud-Integration}" COMPOSE_FILE="${NUQLOUD_COMPOSE_FILE:-docker-compose.devprod.nossl.yml}" ENV_FILE="${NUQLOUD_ENV_FILE:-.env.devprod}" if [[ ! -d "$REPO_DIR" ]]; then echo "repo not found: $REPO_DIR" >&2 exit 3 fi cd "$REPO_DIR" case "$ACTION" in broker-health) docker compose --env-file "$ENV_FILE" -f "$COMPOSE_FILE" exec -T broker \ node -e 'fetch("http://localhost:3000/api/health").then(r=>r.text()).then(t=>console.log(t)).catch(e=>{console.error(e);process.exit(1)})' ;; invite-create) # ARG1=createdBy ARG2=hours ARG3+=comment docker compose --env-file "$ENV_FILE" -f "$COMPOSE_FILE" exec -T broker \ node -e 'const createdBy=process.argv[1]||"cloudOps"; const hrs=Number(process.argv[2]||"24"); const comment=String(process.argv.slice(3).join(" ")||"").trim(); const t=process.env.BROKER_INTERNAL_API_TOKEN; if(!t) throw new Error("BROKER_INTERNAL_API_TOKEN missing"); const body={createdBy,expiresInHours:hrs}; if(comment) body.comment=comment.slice(0,500); fetch("http://localhost:3000/api/oidc/invites",{method:"POST",headers:{"content-type":"application/json","x-broker-internal-token":t},body:JSON.stringify(body)}).then(async r=>{const b=await r.text(); console.log(r.status,b); if(!r.ok) process.exit(1)}).catch(e=>{console.error(e);process.exit(1)})' "$ARG1" "$ARG2" "${@:4}" ;; provision-upsert) # ARG1=qortalAddress ARG2=email docker compose --env-file "$ENV_FILE" -f "$COMPOSE_FILE" exec -T broker \ node -e 'const q=String(process.argv[1]||"").trim(); const email=String(process.argv[2]||"").trim(); if(!q) throw new Error("qortalAddress required"); const t=process.env.BROKER_INTERNAL_API_TOKEN; if(!t) throw new Error("BROKER_INTERNAL_API_TOKEN missing"); fetch("http://localhost:3000/api/provision/upsert",{method:"POST",headers:{"content-type":"application/json","x-broker-internal-token":t},body:JSON.stringify({qortalAddress:q,email})}).then(async r=>{const b=await r.text(); console.log(r.status,b); if(!r.ok) process.exit(1)}).catch(e=>{console.error(e);process.exit(1)})' "$ARG1" "$ARG2" ;; *) echo "unsupported action: $ACTION" >&2 exit 2 ;; esac