claude-cac 1.5.2 → 1.5.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (2) hide show
  1. package/cac +34 -24
  2. package/package.json +1 -1
package/cac CHANGED
@@ -11,7 +11,7 @@ VERSIONS_DIR="$CAC_DIR/versions"
11
11
  # ── utils: colors, read/write, UUID, proxy parsing ───────────────────────
12
12
 
13
13
  # shellcheck disable=SC2034 # used in build-concatenated cac script
14
- CAC_VERSION="1.5.2"
14
+ CAC_VERSION="1.5.3"
15
15
 
16
16
  _read() { [[ -f "$1" ]] && tr -d '[:space:]' < "$1" || echo "${2:-}"; }
17
17
  _die() { printf '%b\n' "$(_red "error:") $*" >&2; exit 1; }
@@ -1273,7 +1273,9 @@ if [[ -f "$_env_dir/persona" ]]; then
1273
1273
  fi
1274
1274
 
1275
1275
  # ── NS-level DNS interception ──
1276
- if [[ -f "$CAC_DIR/cac-dns-guard.js" ]]; then
1276
+ # Use -r (readable) not -f (exists) — root-owned files with mode 600 exist but
1277
+ # can't be read by normal user, causing bun/node to crash silently.
1278
+ if [[ -r "$CAC_DIR/cac-dns-guard.js" ]]; then
1277
1279
  case "${NODE_OPTIONS:-}" in
1278
1280
  *cac-dns-guard.js*) ;; # already injected, skip
1279
1281
  *) export NODE_OPTIONS="${NODE_OPTIONS:-} --require $CAC_DIR/cac-dns-guard.js" ;;
@@ -1284,7 +1286,7 @@ if [[ -f "$CAC_DIR/cac-dns-guard.js" ]]; then
1284
1286
  esac
1285
1287
  fi
1286
1288
  # fallback layer: HOSTALIASES (gethostbyname level)
1287
- [[ -f "$CAC_DIR/blocked_hosts" ]] && export HOSTALIASES="$CAC_DIR/blocked_hosts"
1289
+ [[ -r "$CAC_DIR/blocked_hosts" ]] && export HOSTALIASES="$CAC_DIR/blocked_hosts"
1288
1290
 
1289
1291
  # ── mTLS client certificate ──
1290
1292
  if [[ -f "$_env_dir/client_cert.pem" ]] && [[ -f "$_env_dir/client_key.pem" ]]; then
@@ -1312,7 +1314,7 @@ fi
1312
1314
  [[ -f "$_env_dir/machine_id" ]] && export CAC_MACHINE_ID=$(tr -d '[:space:]' < "$_env_dir/machine_id")
1313
1315
  export CAC_USERNAME="user-$(echo "$_name" | cut -c1-8)"
1314
1316
  export USER="$CAC_USERNAME" LOGNAME="$CAC_USERNAME"
1315
- if [[ -f "$CAC_DIR/fingerprint-hook.js" ]]; then
1317
+ if [[ -r "$CAC_DIR/fingerprint-hook.js" ]]; then
1316
1318
  case "${NODE_OPTIONS:-}" in
1317
1319
  *fingerprint-hook.js*) ;;
1318
1320
  *) export NODE_OPTIONS="--require $CAC_DIR/fingerprint-hook.js ${NODE_OPTIONS:-}" ;;
@@ -1581,9 +1583,24 @@ _ensure_initialized() {
1581
1583
  if [[ -z "$_self_dir" ]] || [[ ! -f "$_self_dir/relay.js" ]]; then
1582
1584
  _self_dir="$(cd "$(dirname "${BASH_SOURCE[0]:-$0}")" && pwd)"
1583
1585
  fi
1584
- [[ -f "$_self_dir/fingerprint-hook.js" ]] && cp "$_self_dir/fingerprint-hook.js" "$CAC_DIR/fingerprint-hook.js"
1585
- [[ -f "$_self_dir/relay.js" ]] && cp "$_self_dir/relay.js" "$CAC_DIR/relay.js"
1586
+ # Warn if running as root — files written here become root-owned and break
1587
+ # normal-user invocations (wrapper has set -e and will silently exit).
1588
+ if [[ $EUID -eq 0 ]]; then
1589
+ echo "[cac] warning: running as root may corrupt ~/.cac/ file ownership" >&2
1590
+ echo "[cac] hint: run as your normal user instead" >&2
1591
+ fi
1592
+ # rm -f first: user owns ~/.cac/ dir so can delete root-owned files even if can't overwrite them
1593
+ if [[ -f "$_self_dir/fingerprint-hook.js" ]]; then
1594
+ rm -f "$CAC_DIR/fingerprint-hook.js" 2>/dev/null || true
1595
+ cp "$_self_dir/fingerprint-hook.js" "$CAC_DIR/fingerprint-hook.js" 2>/dev/null || true
1596
+ fi
1597
+ if [[ -f "$_self_dir/relay.js" ]]; then
1598
+ rm -f "$CAC_DIR/relay.js" 2>/dev/null || true
1599
+ cp "$_self_dir/relay.js" "$CAC_DIR/relay.js" 2>/dev/null || true
1600
+ fi
1601
+ rm -f "$CAC_DIR/cac-dns-guard.js" 2>/dev/null || true
1586
1602
  _write_dns_guard_js 2>/dev/null || true
1603
+ rm -f "$CAC_DIR/blocked_hosts" 2>/dev/null || true
1587
1604
  _write_blocked_hosts 2>/dev/null || true
1588
1605
 
1589
1606
  # PATH (idempotent — always ensure it's in rc file)
@@ -1730,7 +1747,7 @@ _env_cmd_create() {
1730
1747
  mkdir -p "$env_dir"
1731
1748
  [[ -n "$proxy_url" ]] && echo "$proxy_url" > "$env_dir/proxy"
1732
1749
  echo "$(_new_uuid)" > "$env_dir/uuid"
1733
- echo "$(_new_user_id)" > "$env_dir/user_id"
1750
+ touch "$env_dir/user_id"
1734
1751
  echo "$(_new_machine_id)" > "$env_dir/machine_id"
1735
1752
  echo "$(_new_hostname)" > "$env_dir/hostname"
1736
1753
  echo "$(_new_mac)" > "$env_dir/mac_address"
@@ -1823,7 +1840,6 @@ MERGE_EOF
1823
1840
  if [[ -d "$env_dir/.claude" ]]; then
1824
1841
  export CLAUDE_CONFIG_DIR="$env_dir/.claude"
1825
1842
  fi
1826
- _update_claude_json_user_id "$(_read "$env_dir/user_id")" 2>/dev/null || true
1827
1843
 
1828
1844
  local elapsed; elapsed=$(_timer_elapsed)
1829
1845
  echo
@@ -1919,7 +1935,6 @@ _env_cmd_activate() {
1919
1935
  export CLAUDE_CONFIG_DIR="$ENVS_DIR/$name/.claude"
1920
1936
  fi
1921
1937
 
1922
- _update_claude_json_user_id "$(_read "$ENVS_DIR/$name/user_id")"
1923
1938
 
1924
1939
  # Relay lifecycle
1925
1940
  _relay_stop 2>/dev/null || true
@@ -2429,23 +2444,18 @@ cmd_check() {
2429
2444
  else
2430
2445
  _id_issues+=("repo hash not spoofed")
2431
2446
  fi
2432
- # user_id consistency
2447
+ # user_id tracking: sync from .claude.json after login (real userID wins)
2433
2448
  local _uid_ok=true
2434
- local _env_uid; _env_uid=$(_read "$env_dir/user_id" "")
2435
- if [[ -n "$_env_uid" ]]; then
2436
- local _config_dir="${CLAUDE_CONFIG_DIR:-$ENVS_DIR/$current/.claude}"
2437
- local _cj="$_config_dir/.claude.json"
2438
- [[ -f "$_cj" ]] || _cj="$HOME/.claude.json"
2439
- if [[ -f "$_cj" ]]; then
2440
- local _actual_uid
2441
- _actual_uid=$(python3 -c "import json,sys; print(json.load(open(sys.argv[1])).get('userID',''))" "$_cj" 2>/dev/null || true)
2449
+ local _config_dir="${CLAUDE_CONFIG_DIR:-$ENVS_DIR/$current/.claude}"
2450
+ local _cj="$_config_dir/.claude.json"
2451
+ [[ -f "$_cj" ]] || _cj="$HOME/.claude.json"
2452
+ if [[ -f "$_cj" ]]; then
2453
+ local _actual_uid
2454
+ _actual_uid=$(python3 -c "import json,sys; print(json.load(open(sys.argv[1])).get('userID',''))" "$_cj" 2>/dev/null || true)
2455
+ if [[ -n "$_actual_uid" ]]; then
2442
2456
  (( _id_total++ )) || true
2443
- if [[ -n "$_actual_uid" ]] && [[ "$_actual_uid" != "$_env_uid" ]]; then
2444
- _uid_ok=false
2445
- _id_issues+=("user_id mismatch")
2446
- else
2447
- (( _id_ok++ )) || true
2448
- fi
2457
+ echo "$_actual_uid" > "$env_dir/user_id" 2>/dev/null || true
2458
+ (( _id_ok++ )) || true
2449
2459
  fi
2450
2460
  fi
2451
2461
  # billing header
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "claude-cac",
3
- "version": "1.5.2",
3
+ "version": "1.5.3",
4
4
  "description": "Isolate, protect, and manage your Claude Code — versions, environments, identity, and proxy.",
5
5
  "bin": {
6
6
  "cac": "cac"