#!/bin/bash # verify.sh — Post-install health check for OAuth token sync # Run anytime to check if everything is working correctly set -uo pipefail RED='\033[0;31m' GREEN='\033[0;32m' YELLOW='\033[1;33m' NC='\033[0m' pass() { echo -e " ${GREEN}[PASS]${NC} $*"; } fail() { echo -e " ${RED}[FAIL]${NC} $*"; } warn() { echo -e " ${YELLOW}[WARN]${NC} $*"; } ERRORS=0 echo "" echo "==========================================" echo " OAuth Token Sync — Health Check" echo "==========================================" echo "" # --- 1. Systemd service --- echo "1. Systemd service status" if systemctl is-active --quiet sync-oauth-token.service 2>/dev/null; then pass "sync-oauth-token.service is active" else fail "sync-oauth-token.service is not running" echo " Fix: systemctl start sync-oauth-token.service" ERRORS=$((ERRORS + 1)) fi if systemctl is-enabled --quiet sync-oauth-token.service 2>/dev/null; then pass "Service is enabled (starts on boot)" else warn "Service is not enabled for boot" echo " Fix: systemctl enable sync-oauth-token.service" fi echo "" # --- 2. inotifywait process --- echo "2. File watcher process" if pgrep -f inotifywait > /dev/null 2>&1; then WATCH_PATH=$(pgrep -af inotifywait | grep -oP '/[^ ]+' | tail -1) pass "inotifywait is running (watching: $WATCH_PATH)" else fail "inotifywait is not running" ERRORS=$((ERRORS + 1)) fi echo "" # --- 3. Source credentials file --- echo "3. Claude CLI credentials file" # Try to find the watched file from the service SYNC_SCRIPT=$(which sync-oauth-token.sh 2>/dev/null || echo "/usr/local/bin/sync-oauth-token.sh") if [ -f "$SYNC_SCRIPT" ]; then SOURCE_FILE=$(grep 'CLAUDE_CREDS_FILE=' "$SYNC_SCRIPT" | head -1 | cut -d'"' -f2) fi SOURCE_FILE="${SOURCE_FILE:-/root/.openclaw/workspaces/workspace-claude-proxy/config/.claude/.credentials.json}" if [ -f "$SOURCE_FILE" ]; then pass "File exists: $SOURCE_FILE" EXPIRES=$(python3 -c " import json, time with open('$SOURCE_FILE') as f: d = json.load(f) exp = d['claudeAiOauth']['expiresAt'] / 1000 remaining = (exp - time.time()) / 3600 status = 'VALID' if remaining > 0 else 'EXPIRED' print(f'{remaining:.1f}h remaining ({status})') " 2>/dev/null || echo "parse error") if echo "$EXPIRES" | grep -q "VALID"; then pass "Token: $EXPIRES" else fail "Token: $EXPIRES" ERRORS=$((ERRORS + 1)) fi else fail "File not found: $SOURCE_FILE" ERRORS=$((ERRORS + 1)) fi echo "" # --- 4. OpenClaw oauth.json --- echo "4. OpenClaw oauth.json" for path in /root/.openclaw/credentials/oauth.json /home/*/.openclaw/credentials/oauth.json; do if [ -f "$path" ]; then OAUTH_FILE="$path" break fi done if [ -n "${OAUTH_FILE:-}" ] && [ -f "$OAUTH_FILE" ]; then HAS_ACCESS=$(python3 -c " import json with open('$OAUTH_FILE') as f: d = json.load(f) a = d.get('anthropic', {}) print('yes' if a.get('access') else 'no') " 2>/dev/null || echo "no") if [ "$HAS_ACCESS" = "yes" ]; then pass "oauth.json exists with anthropic.access field: $OAUTH_FILE" else fail "oauth.json exists but missing anthropic.access field" ERRORS=$((ERRORS + 1)) fi else fail "oauth.json not found" ERRORS=$((ERRORS + 1)) fi echo "" # --- 5. .env file --- echo "5. Environment file (.env)" for path in /root/openclaw/.env; do if [ -f "$path" ]; then ENV_FILE="$path" break fi done if [ -n "${ENV_FILE:-}" ] && [ -f "$ENV_FILE" ]; then if grep -q 'ANTHROPIC_OAUTH_TOKEN=' "$ENV_FILE"; then TOKEN_PREFIX=$(grep 'ANTHROPIC_OAUTH_TOKEN=' "$ENV_FILE" | head -1 | cut -d'"' -f2 | cut -c1-20) pass ".env has ANTHROPIC_OAUTH_TOKEN: ${TOKEN_PREFIX}..." else fail ".env missing ANTHROPIC_OAUTH_TOKEN" ERRORS=$((ERRORS + 1)) fi else fail ".env file not found" ERRORS=$((ERRORS + 1)) fi echo "" # --- 6. Gateway container --- echo "6. Gateway container" GATEWAY=$(docker ps --filter name=openclaw --format '{{.Names}}' 2>/dev/null | grep gateway | head -1) if [ -n "$GATEWAY" ]; then UPTIME=$(docker ps --filter "name=$GATEWAY" --format '{{.Status}}' 2>/dev/null) pass "Gateway running: $GATEWAY ($UPTIME)" # Check container env var matches .env CONTAINER_TOKEN=$(docker exec "$GATEWAY" printenv ANTHROPIC_OAUTH_TOKEN 2>/dev/null | cut -c1-20) if [ -n "$CONTAINER_TOKEN" ]; then pass "Container has ANTHROPIC_OAUTH_TOKEN: ${CONTAINER_TOKEN}..." else warn "Container missing ANTHROPIC_OAUTH_TOKEN env var" fi else fail "No OpenClaw gateway container found" ERRORS=$((ERRORS + 1)) fi echo "" # --- Summary --- echo "==========================================" if [ "$ERRORS" -eq 0 ]; then echo -e " ${GREEN}All checks passed${NC}" else echo -e " ${RED}$ERRORS check(s) failed${NC}" fi echo "==========================================" echo "" echo "Useful commands:" echo " journalctl -u sync-oauth-token.service -f # Watch sync logs" echo " systemctl restart sync-oauth-token.service # Force re-sync" echo " ./scripts/verify.sh # Run this check again" echo "" exit $ERRORS