1# The events server streams a private repo only to its readers, signed in2# with a passkey: /events/ skips its events, flagged or not (it reads3# git-daemon-export-ok), and /events/<owner>/<repo>/ is the 404 a missing4# repo gets for anyone else, signed in or not. A repo made private while a5# page watches it stops streaming to that page at once, and so does a6# reader's page once they may not read it any more.7. "$(dirname "$0")/../lib.sh"8user dami9user ana10user cat11repo --private dami/secret12repo dami/open13port=$(node -e 'const s = require("net").createServer().listen(0, "127.0.0.1", () => { console.log(s.address().port); s.close(); })')14ev=$FORGE_ROOT/.forge/events.jsonl15: >"$ev"16FORGE_STATE=$FORGE_ROOT/.forge FORGE_EVENTS_PORT=$port node "$T_HOME/lib/events-server.ts" >"$T/events.log" 2>&1 &17T_PIDS="$T_PIDS $!"18es=http://127.0.0.1:$port/events19n=020until http -s -o /dev/null "$es/x/y/" || [ "$n" -ge 50 ]; do sleep 0.1; n=$((n + 1)); done2122code() { http -s -o /dev/null -w '%{http_code}' --max-time 1 "$@" || true; }23eq "$(code "$es/dami/secret/")" 40424eq "$(code "$es/dami/nope/")" 40425eq "$(code "$es/dami/open/")" 20026eq "$(code "$es/")" 2002728http -sN --max-time 4 "$es/" >"$T/all" &29all=$!30http -sN --max-time 4 "$es/dami/open/" >"$T/open" &31one=$!32T_PIDS="$T_PIDS $all $one"33sleep 134push() { printf '{"t":1,"repo":"%s","type":"push","user":"dami","refs":"refs/heads/%s"%s}\n' "$1" "$2" "${3:-}" >>"$ev"; }35push dami/secret flagged ',"private":true'36push dami/secret unflagged37push dami/open before38sleep 139rm "$FORGE_ROOT/dami/open.git/git-daemon-export-ok"40push dami/open after41# The watcher of dami/open is let go before its 4 seconds are up.42if wait "$one"; then :; else fail "the stream of dami/open wasn't closed (http exited $?)"; fi43wait "$all" || true44has "$T/all" '"refs":"refs/heads/before"'45lacks "$T/all" 'dami/secret'46lacks "$T/all" 'refs/heads/after'47has "$T/open" '"refs":"refs/heads/before"'48lacks "$T/open" 'refs/heads/after'49eq "$(code "$es/dami/open/")" 4045051# Signed in: a reader hears it, nobody else does.52export FORGE_BASE_URL=https://forge.test53private_server54ok ssh_as dami readers dami/secret add ana55signin() {56 c=$(ssh_as "$1" passkey | sed -n 's/^ .*#enroll=//p')57 node "$T_HOME/test/authenticator.ts" enroll "$PRIV" "$c" "$T/$1.key"58}59ana=$(signin ana) || fail "ana"60cat=$(signin cat) || fail "cat"61eq "$(code -H "Cookie: __Host-forge=$ana" "$es/dami/secret/")" 20062eq "$(code -H "Cookie: __Host-forge=$cat" "$es/dami/secret/")" 40463eq "$(code -H 'Cookie: __Host-forge=nonsense' "$es/dami/secret/")" 40464eq "$(code -H "Cookie: __Host-forge=$ana" "$es/dami/nope/")" 40465http -sN --max-time 4 -H "Cookie: __Host-forge=$ana" "$es/dami/secret/" >"$T/ana" &66one=$!67http -sN --max-time 4 -H "Cookie: __Host-forge=$cat" "$es/" >"$T/cat" &68all=$!69T_PIDS="$T_PIDS $one $all"70sleep 171push dami/secret for-readers ',"private":true'72sleep 173ok ssh_as dami readers dami/secret rm ana74push dami/secret after-rm ',"private":true'75if wait "$one"; then :; else fail "ana's stream of dami/secret wasn't closed (http exited $?)"; fi76wait "$all" || true77has "$T/ana" '"refs":"refs/heads/for-readers"'78lacks "$T/ana" 'after-rm'79lacks "$T/cat" 'dami/secret'80eq "$(code -H "Cookie: __Host-forge=$ana" "$es/dami/secret/")" 404