86 lines
3.0 KiB
Bash
86 lines
3.0 KiB
Bash
#!/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 <email> <password>` 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"
|