#!/usr/bin/env bash # agent_browser_remote_login.sh # Opens a headed browser window in a NEW isolated session (separate # localStorage/cookies from agent_browser_login.sh sessions) for testing # NIP-46 remote login. # # Usage: # ./agent_browser_remote_login.sh [session-name] [page] [bunker-uri] # # Examples: # ./agent_browser_remote_login.sh remote1 index.html # ./agent_browser_remote_login.sh remote1 index.html "bunker://..." set -euo pipefail SESSION="${1:-remote-$$}" RAW_URL="${2:-index.html}" BUNKER_URI="${3:-}" BASE_URL="https://laantungir.net/client" # Expand bare page name to full URL if [[ "$RAW_URL" != http* && "$RAW_URL" != /* ]]; then URL="${BASE_URL}/${RAW_URL}" else URL="$RAW_URL" fi echo "[remote_login] Session: $SESSION (isolated from other sessions)" echo "[remote_login] URL: $URL" # Open the page — --session-name gives each session its own isolated storage agent-browser --session-name "$SESSION" open "$URL" agent-browser --session-name "$SESSION" wait --load networkidle # Clear any stored auth so this session starts fresh agent-browser --session-name "$SESSION" eval \ "(()=>{ const keys = Object.keys(localStorage).filter(k=>k.includes('auth')||k.includes('nostr')); keys.forEach(k=>localStorage.removeItem(k)); const skeys = Object.keys(sessionStorage).filter(k=>k.includes('auth')||k.includes('nostr')); skeys.forEach(k=>sessionStorage.removeItem(k)); return 'cleared ' + keys.length + ' localStorage + ' + skeys.length + ' sessionStorage keys'; })()" # Reload so the cleared state takes effect agent-browser --session-name "$SESSION" eval "location.reload()" agent-browser --session-name "$SESSION" wait --load networkidle agent-browser --session-name "$SESSION" wait 1000 echo "[remote_login] Page loaded fresh (no stored auth)." # If a bunker URI was provided, auto-fill and connect if [[ -n "$BUNKER_URI" ]]; then echo "[remote_login] Auto-connecting with bunker URI..." # Click Nostr Connect agent-browser --session-name "$SESSION" eval \ "[...document.querySelectorAll('button')].find(b=>b.textContent.includes('Nostr Connect'))?.click()" agent-browser --session-name "$SESSION" wait 500 # Fill bunker URI — write to a global var first to avoid quoting issues agent-browser --session-name "$SESSION" eval "window._bunkerUri = atob('$(echo -n "$BUNKER_URI" | base64 -w0)')" agent-browser --session-name "$SESSION" eval \ "(()=>{ const i = document.querySelector('input[placeholder*=\"bunker\"]'); if (!i) return 'ERROR: no bunker input found'; i.value = window._bunkerUri; i.dispatchEvent(new Event('input', {bubbles:true})); return 'filled: ' + i.value.substring(0,40); })()" agent-browser --session-name "$SESSION" wait 300 # Click Connect to Bunker agent-browser --session-name "$SESSION" eval \ "[...document.querySelectorAll('button')].find(b=>b.textContent.includes('Connect to Bunker')&&!b.disabled)?.click()" echo "[remote_login] Connect initiated — approve in the bunker window if needed." fi echo "" echo "[remote_login] Session '$SESSION' is ready." echo "To control: agent-browser --session-name \"$SESSION\" snapshot"