#!/usr/bin/env bash # bitwarden skill — setup inicial. # # Idempotente. Corre las veces que quieras: # - configura el server # - loguea con API key (si no estaba logueado) # - unlock con master password (si estaba locked) # - guarda session en .cache/session (chmod 600) # # Después de esto, query.sh puede levantar `bw serve` y empezar a llamar. set -euo pipefail SKILL_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)" ENV_FILE="$SKILL_DIR/.env" CACHE_DIR="$SKILL_DIR/.cache" SESSION_FILE="$CACHE_DIR/session" BW_DATA_DIR="$CACHE_DIR/bw" if [[ ! -f "$ENV_FILE" ]]; then echo "ERROR: $ENV_FILE no existe." >&2 echo " cp $SKILL_DIR/.env.example $ENV_FILE y completá los valores." >&2 exit 1 fi mkdir -p "$CACHE_DIR" "$BW_DATA_DIR" chmod 700 "$CACHE_DIR" "$BW_DATA_DIR" 2>/dev/null || true set -a # shellcheck disable=SC1090 source "$ENV_FILE" set +a : "${BW_SERVER:?BW_SERVER no definido en .env}" : "${BW_EMAIL:?BW_EMAIL no definido en .env}" : "${BW_PASSWORD:?BW_PASSWORD no definido en .env}" # Aislar la data de bw a este skill (no contamina ~/.config/Bitwarden CLI) export BITWARDENCLI_APPDATA_DIR="$BW_DATA_DIR" echo "→ Configurando server: $BW_SERVER" bw config server "$BW_SERVER" >/dev/null # Status: unauthenticated | locked | unlocked status="$(bw status 2>/dev/null | python -c "import json,sys; print(json.load(sys.stdin).get('status','unknown'))" 2>/dev/null || echo "unknown")" echo "→ Status actual: $status" # NOTA: usamos `bw login ` directo (no `--apikey`) porque # `bw login --apikey` en bw CLI 2026.4.x deja la cuenta en estado roto # (`toWrappedAccountCryptographicState` null) que después rompe el unlock. # Email+password login es equivalentemente seguro porque la master password # ya vive en este .env de todas formas. if [[ "$status" == "unauthenticated" ]]; then echo "→ Login con email+password (claudecode0)..." session="$(bw login "$BW_EMAIL" "$BW_PASSWORD" --raw 2>&1 | tail -1)" if [[ -z "$session" || ${#session} -lt 40 ]]; then echo "ERROR: bw login falló. Output:" >&2 echo "$session" >&2 exit 2 fi elif [[ "$status" == "locked" ]]; then echo "→ Unlock con master password..." session="$(bw unlock "$BW_PASSWORD" --raw 2>&1 | tail -1)" if [[ -z "$session" || ${#session} -lt 40 ]]; then echo "ERROR: bw unlock falló. Output:" >&2 echo "$session" >&2 exit 2 fi else # unlocked: necesitamos session, pero unlock con vault ya unlocked devuelve la session existente session="$(bw unlock "$BW_PASSWORD" --raw 2>&1 | tail -1)" fi printf '%s' "$session" > "$SESSION_FILE" chmod 600 "$SESSION_FILE" 2>/dev/null || true echo "→ Session guardada en $SESSION_FILE" echo "→ Sync inicial del vault..." BW_SESSION="$(cat "$SESSION_FILE")" bw sync >/dev/null # Verificación final final_status="$(BW_SESSION="$(cat "$SESSION_FILE")" bw status | python -c "import json,sys; d=json.load(sys.stdin); print(d.get('status'), '|', d.get('userEmail'), '|', d.get('serverUrl'))")" echo "→ Listo: $final_status" echo "" echo "Próximo paso: query.sh /status"