comparison mrjunejune/test/config_validation_test.sh @ 264:04fee26ecce0

add authenticated JRPG conversation platform Add reusable auth/session storage, owned conversation recovery, guest quotas, admin workflows, URL-routed conversation UI, mobile frame support, and parallel browser acceptance. Co-authored-by: Copilot <[email protected]>
author MrJuneJune <me@mrjunejune.com>
date Fri, 07 Aug 2026 07:34:12 -0700
parents
children 056790c4fb0d
comparison
equal deleted inserted replaced
263:ee04e4e69fed 264:04fee26ecce0
1 #!/usr/bin/env bash
2 # config_validation_test.sh — startup config validation tests.
3 #
4 # Verifies that the server binary exits 1 (fail-closed) on bad config,
5 # starts cleanly on env-only config (no .config file), and enforces the
6 # loopback requirement for AUTH_DEV_INSECURE_COOKIE.
7 #
8 # Bazel passes the server binary path as $1.
9 set -euo pipefail
10
11 server="$(realpath "$1")"
12 tmpdir="$(mktemp -d)"
13 trap 'rm -rf "$tmpdir"' EXIT
14
15 pass() { printf " %-62s PASS\n" "$1"; }
16 fail() { echo "FAIL: $1" >&2; exit 1; }
17
18 # A valid 64-hex-char secret (32 random bytes) for success cases.
19 GOOD_SECRET="0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef"
20
21 # Helper: run $@ as a command, expect it to exit non-zero ≤ 3 seconds.
22 run_expect_fail() {
23 local label="$1"; shift
24 local out
25 set +e
26 out=$(timeout 3 "$@" 2>&1)
27 local code=$?
28 set -e
29 if [[ $code -eq 0 || $code -eq 124 ]]; then
30 echo "FAIL: '$label' — expected exit 1, got code $code" >&2
31 echo "$out" >&2
32 exit 1
33 fi
34 pass "$label"
35 }
36
37 # Helper: run $@ as a command; expect it to emit an "Initialised" or
38 # listen/startup log line within 5 seconds, then kill it.
39 run_expect_start() {
40 local label="$1"; shift
41 local logfile="$tmpdir/start_${RANDOM}.log"
42 set +e
43 timeout 5 "$@" >"$logfile" 2>&1 &
44 local pid=$!
45 local started=false
46 for _ in $(seq 1 50); do
47 sleep 0.1
48 if grep -q -E 'Initialised|Listening|WTF is going on' "$logfile" 2>/dev/null; then
49 started=true
50 break
51 fi
52 if ! kill -0 "$pid" 2>/dev/null; then
53 break
54 fi
55 done
56 kill "$pid" 2>/dev/null || true
57 wait "$pid" 2>/dev/null || true
58 set -e
59 if [[ "$started" != "true" ]]; then
60 echo "FAIL: '$label' — server did not start (log below)" >&2
61 cat "$logfile" >&2
62 exit 1
63 fi
64 pass "$label"
65 }
66
67 echo ""
68 echo "[config validation]"
69
70 # ── Fail cases ─────────────────────────────────────────────────────────────────
71
72 # Missing secret → exit 1
73 run_expect_fail "missing AUTH_COOKIE_SECRET → exit 1" \
74 env -i "TEST_TMPDIR=$tmpdir" "$server"
75
76 # Secret too short (62 hex chars = 31 bytes)
77 run_expect_fail "short AUTH_COOKIE_SECRET (62 hex) → exit 1" \
78 env -i \
79 "AUTH_COOKIE_SECRET=0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcd" \
80 "SERVER_HOST=127.0.0.1" \
81 "AUTH_DEV_INSECURE_COOKIE=true" \
82 "TEST_TMPDIR=$tmpdir" \
83 "$server"
84
85 # Secret with non-hex characters
86 run_expect_fail "non-hex AUTH_COOKIE_SECRET → exit 1" \
87 env -i \
88 "AUTH_COOKIE_SECRET=ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ" \
89 "SERVER_HOST=127.0.0.1" \
90 "AUTH_DEV_INSECURE_COOKIE=true" \
91 "TEST_TMPDIR=$tmpdir" \
92 "$server"
93
94 # AUTH_DEV_INSECURE_COOKIE=true with non-loopback SERVER_HOST → exit 1
95 run_expect_fail "insecure cookie without loopback SERVER_HOST → exit 1" \
96 env -i \
97 "AUTH_COOKIE_SECRET=$GOOD_SECRET" \
98 "SERVER_HOST=0.0.0.0" \
99 "AUTH_DEV_INSECURE_COOKIE=true" \
100 "TEST_TMPDIR=$tmpdir" \
101 "$server"
102
103 # AUTH_DEV_INSECURE_COOKIE=true with no SERVER_HOST → exit 1
104 run_expect_fail "insecure cookie without any SERVER_HOST → exit 1" \
105 env -i \
106 "AUTH_COOKIE_SECRET=$GOOD_SECRET" \
107 "AUTH_DEV_INSECURE_COOKIE=true" \
108 "TEST_TMPDIR=$tmpdir" \
109 "$server"
110
111 # Bootstrap username set without hash → exit 1
112 run_expect_fail "bootstrap username without hash → exit 1" \
113 env -i \
114 "AUTH_COOKIE_SECRET=$GOOD_SECRET" \
115 "SERVER_HOST=127.0.0.1" \
116 "AUTH_DEV_INSECURE_COOKIE=true" \
117 "AUTH_BOOTSTRAP_USERNAME=admin" \
118 "TEST_TMPDIR=$tmpdir" \
119 "$server"
120
121 # Bootstrap hash with wrong format → exit 1
122 run_expect_fail "bootstrap hash with wrong format → exit 1" \
123 env -i \
124 "AUTH_COOKIE_SECRET=$GOOD_SECRET" \
125 "SERVER_HOST=127.0.0.1" \
126 "AUTH_DEV_INSECURE_COOKIE=true" \
127 "AUTH_BOOTSTRAP_USERNAME=admin" \
128 "AUTH_BOOTSTRAP_PASSWORD_HASH=not-a-real-hash" \
129 "TEST_TMPDIR=$tmpdir" \
130 "$server"
131
132 # Bootstrap hash with partial/truncated format → exit 1
133 run_expect_fail "bootstrap hash truncated (only prefix) → exit 1" \
134 env -i \
135 "AUTH_COOKIE_SECRET=$GOOD_SECRET" \
136 "SERVER_HOST=127.0.0.1" \
137 "AUTH_DEV_INSECURE_COOKIE=true" \
138 "AUTH_BOOTSTRAP_USERNAME=admin" \
139 "AUTH_BOOTSTRAP_PASSWORD_HASH=zenbu-scrypt\$v=1\$N=32768\$r=8\$p=1\$" \
140 "TEST_TMPDIR=$tmpdir" \
141 "$server"
142
143 # idle TTL > abs TTL → exit 1
144 run_expect_fail "idle TTL exceeds abs TTL → exit 1" \
145 env -i \
146 "AUTH_COOKIE_SECRET=$GOOD_SECRET" \
147 "SERVER_HOST=127.0.0.1" \
148 "AUTH_DEV_INSECURE_COOKIE=true" \
149 "AUTH_SESSION_IDLE_TTL=9999999" \
150 "AUTH_SESSION_ABS_TTL=100" \
151 "TEST_TMPDIR=$tmpdir" \
152 "$server"
153
154 # Malformed AUTH_SESSION_IDLE_TTL (non-integer) → exit 1
155 run_expect_fail "malformed AUTH_SESSION_IDLE_TTL → exit 1" \
156 env -i \
157 "AUTH_COOKIE_SECRET=$GOOD_SECRET" \
158 "SERVER_HOST=127.0.0.1" \
159 "AUTH_DEV_INSECURE_COOKIE=true" \
160 "AUTH_SESSION_IDLE_TTL=3600abc" \
161 "TEST_TMPDIR=$tmpdir" \
162 "$server"
163
164 # Malformed AUTH_SESSION_ABS_TTL (non-integer) → exit 1
165 run_expect_fail "malformed AUTH_SESSION_ABS_TTL → exit 1" \
166 env -i \
167 "AUTH_COOKIE_SECRET=$GOOD_SECRET" \
168 "SERVER_HOST=127.0.0.1" \
169 "AUTH_DEV_INSECURE_COOKIE=true" \
170 "AUTH_SESSION_ABS_TTL=not_a_number" \
171 "TEST_TMPDIR=$tmpdir" \
172 "$server"
173
174 # Malformed S3_URL_EXPIRES (non-integer) → exit 1
175 run_expect_fail "malformed S3_URL_EXPIRES → exit 1" \
176 env -i \
177 "AUTH_COOKIE_SECRET=$GOOD_SECRET" \
178 "SERVER_HOST=127.0.0.1" \
179 "AUTH_DEV_INSECURE_COOKIE=true" \
180 "S3_URL_EXPIRES=3600x" \
181 "TEST_TMPDIR=$tmpdir" \
182 "$server"
183
184 # S3_URL_EXPIRES = 0 (not positive) → exit 1
185 run_expect_fail "S3_URL_EXPIRES=0 (non-positive) → exit 1" \
186 env -i \
187 "AUTH_COOKIE_SECRET=$GOOD_SECRET" \
188 "SERVER_HOST=127.0.0.1" \
189 "AUTH_DEV_INSECURE_COOKIE=true" \
190 "S3_URL_EXPIRES=0" \
191 "TEST_TMPDIR=$tmpdir" \
192 "$server"
193
194 # Trusted proxy with invalid chars → exit 1
195 run_expect_fail "invalid trusted proxy (bad chars) → exit 1" \
196 env -i \
197 "AUTH_COOKIE_SECRET=$GOOD_SECRET" \
198 "SERVER_HOST=127.0.0.1" \
199 "AUTH_DEV_INSECURE_COOKIE=true" \
200 "AUTH_TRUSTED_PROXY=not an ip!" \
201 "TEST_TMPDIR=$tmpdir" \
202 "$server"
203
204 # Trusted proxy with out-of-range IPv4 octet (999.999.999.999) → exit 1
205 run_expect_fail "trusted proxy 999.999.999.999 → exit 1" \
206 env -i \
207 "AUTH_COOKIE_SECRET=$GOOD_SECRET" \
208 "SERVER_HOST=127.0.0.1" \
209 "AUTH_DEV_INSECURE_COOKIE=true" \
210 "AUTH_TRUSTED_PROXY=999.999.999.999" \
211 "TEST_TMPDIR=$tmpdir" \
212 "$server"
213
214 # ── Success cases ─────────────────────────────────────────────────────────────
215 # env-only startup (no .config file) with loopback host
216 run_expect_start "env-only startup (no .config) with loopback host" \
217 env -i \
218 "AUTH_COOKIE_SECRET=$GOOD_SECRET" \
219 "SERVER_HOST=127.0.0.1" \
220 "AUTH_DEV_INSECURE_COOKIE=true" \
221 "MRJUNEJUNE_PORT=16969" \
222 "TEST_TMPDIR=$tmpdir" \
223 "$server"
224
225 # Valid IPv4 trusted proxy is accepted
226 run_expect_start "valid IPv4 trusted proxy accepted" \
227 env -i \
228 "AUTH_COOKIE_SECRET=$GOOD_SECRET" \
229 "SERVER_HOST=127.0.0.1" \
230 "AUTH_DEV_INSECURE_COOKIE=true" \
231 "AUTH_TRUSTED_PROXY=10.0.0.1" \
232 "MRJUNEJUNE_PORT=16970" \
233 "TEST_TMPDIR=$tmpdir" \
234 "$server"
235
236 # Valid IPv6 trusted proxy (canonical ::1) is accepted
237 run_expect_start "valid IPv6 trusted proxy (::1) accepted" \
238 env -i \
239 "AUTH_COOKIE_SECRET=$GOOD_SECRET" \
240 "SERVER_HOST=127.0.0.1" \
241 "AUTH_DEV_INSECURE_COOKIE=true" \
242 "AUTH_TRUSTED_PROXY=::1" \
243 "MRJUNEJUNE_PORT=16971" \
244 "TEST_TMPDIR=$tmpdir" \
245 "$server"
246
247 echo ""