#!/usr/bin/env bash _sync_service_secrets() { source "$LEADTECH/scripts/env_paths.sh" || { echo "env_paths.sh introuvable" >&2; return 1; } if [ ! -f "$SECRETS_KDBX" ]; then echo "Coffre introuvable : $SECRETS_KDBX" >&2 return 1 fi if ! command -v keepassxc-cli >/dev/null 2>&1; then echo "keepassxc-cli introuvable" >&2 return 1 fi if ! command -v expect >/dev/null 2>&1; then echo "expect introuvable" >&2 return 1 fi local target_file case "$(uname -s)" in Darwin) target_file="$HOME/.config/auto-secrets/service.env" ;; Linux) target_file="$HOME/.config/auto-secrets/service.env" ;; *) echo "OS non supporté" >&2; return 1 ;; esac mkdir -p "$(dirname "$target_file")" touch "$target_file" chmod 600 "$target_file" if [ -z "${KDBX_PASSWORD:-}" ]; then printf "Mot de passe KeePassXC : " >&2 stty -echo IFS= read -r KDBX_PASSWORD stty echo printf '\n' >&2 fi echo "Sync des secrets de service..." >&2 # Export CSV complet — log_file capture tout dès le début du spawn local tmpfile tmpfile=$(mktemp) KDBX_PASSWORD="$KDBX_PASSWORD" SECRETS_KDBX="$SECRETS_KDBX" TMPFILE="$tmpfile" expect <<'EOF' log_user 0 log_file -noappend $env(TMPFILE) set timeout 30 spawn keepassxc-cli export --format csv $env(SECRETS_KDBX) expect "Saisir le mot de passe pour déverrouiller*" send -- "$env(KDBX_PASSWORD)\r" expect eof catch wait result exit [lindex $result 3] EOF local rc=$? local csv csv=$(cat "$tmpfile") rm -f "$tmpfile" [ $rc -ne 0 ] && { echo "Impossible d'exporter le coffre." >&2; return 1; } # Parser le CSV avec python3 — gère les champs multilignes et les virgules dans les valeurs # On cherche la ligne d'en-tête CSV pour ignorer le bruit du buffer expect local rendered_lines rendered_lines=$(printf '%s' "$csv" | python3 -c " import sys, csv, re, io raw = sys.stdin.read() start = raw.find('\"Group\"') if start == -1: sys.exit(0) clean = raw[start:] reader = csv.DictReader(io.StringIO(clean)) for row in reader: group = row.get('Group', '') title = row.get('Title', '') password = row.get('Password', '') if group != 'Racine/services' and not group.startswith('Racine/services/'): continue if not re.match(r'^[A-Z_][A-Z0-9_]*\$', title): continue if not password: continue print(title + '=' + password) ") if [ -z "$rendered_lines" ]; then echo "Aucun secret de service chargé." >&2 return 1 fi local loaded loaded=$(echo "$rendered_lines" | grep -c '.') printf '%s\n' "$rendered_lines" > "$target_file" chmod 600 "$target_file" echo "Secrets de service écrits dans : $target_file" echo "Secrets de service chargés : $loaded" } _sync_service_secrets unset -f _sync_service_secrets