Commit Graph
75 Commits
Author SHA1 Message Date
DorianandClaude Fable 5 e824f4ca7f test(09-02): add failing test for GET /api/auth/me (BOT-01)
Covers missing / malformed / forged / blacklisted / unregistered / valid
JWT cases for the JWT-only identity route that replaces the bare-pubkey
auto-restore path. Route does not exist yet — 6/7 fail as expected.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-30 22:03:18 -04:00
DorianandClaude Fable 5 0511b97cb9 feat(09-01): arena-proxy survives SSE, client-IP forwarding, upstream-down
CI / check (push) Has been cancelled
- Forward client IP via x-forwarded-for/x-real-ip so the canonical arena's
  per-IP rate limiting isn't collapsed to one bucket per node.
- 30s AbortSignal.timeout on non-stream requests; SSE fight streams
  (/api/fights/:id/stream) are exempt (long-lived by design).
- On upstream fetch failure, log and return 502 {error} instead of a
  buffered hang or a 500 stack trace.
- fights.ts: set X-Accel-Buffering: no on the SSE stream response so an
  nginx-fronted arena (nginx-proxy-manager) doesn't buffer live fight events.
- docker-compose.yml: document ARENA_UPSTREAM_URL / TRUSTED_PROXY (commented,
  no active value set here — the canonical arena gets its own compose file
  in a later plan).

TDD: added the SSE/XFF/502 tests, confirmed the 502 test failed against the
prior implementation, then implemented to green (9/9 arena-proxy tests,
17/17 combined with rate-limit.test.ts).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-30 21:32:57 -04:00
Dorian 32e6c19f72 stuff 2026-04-11 19:46:37 +01:00
DorianandClaude Opus 4.6 18e4b05399 fix: practice fights send challenges to polling/webhook bots instead of forcing human mode
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-13 23:23:37 +00:00
DorianandClaude Opus 4.6 8076d860c7 fix: creator auto-creates as bot (poll mode), auto-upgrade existing human records
The creator was being registered with webhookUrl='http://human.local/' and
isHuman=true. Now uses poll.local and isHuman=false. The auto-upgrade logic
on login also converts any existing creator record from human to bot mode.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-13 22:28:43 +00:00
DorianandClaude Opus 4.6 cef9f4188f feat: fix setup guide download with embedded credentials + profile page regenerate secret
- downloadSetupGuide() now triggers a real file download with bot_id/secret injected
- Add POST /api/auth/regenerate-secret endpoint (JWT auth, 3/hour rate limit)
- Add "Download Setup Guide" section to BotProfilePage with secret regeneration flow
- Old secret immediately invalidated on regeneration

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-13 13:35:48 +00:00
DorianandClaude Opus 4.6 cae8f0b83e test: add comprehensive auth audit — 28 tests verify endpoint protection
Covers all 7 admin endpoints (403 without creator pubkey), polling
endpoints (bot auth required), tournament mutations (creator-only),
ranked queue (pubkey ownership), NIP-98 session (signature required),
and 10 public endpoint accessibility checks.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-13 10:37:46 +00:00
DorianandClaude Opus 4.6 18b92fbbdf test: API auth audit — 18 tests verify auth, rate limiting, validation, error sanitization
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-13 10:34:08 +00:00
DorianandClaude Opus 4.6 f15504b400 test: add auth registration edge cases — concurrent names, expired JWT, NIP-98 tampering
Tests concurrent same-name registration (exactly one succeeds),
case-insensitive name collisions, expired JWT rejection, NIP-98
pubkey mismatch, and duplicate pubkey prevention.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-13 10:15:13 +00:00
DorianandClaude Opus 4.6 9b0d251d1c fix: sanitize error responses to prevent internal detail leakage
Add sanitizeError() helper that strips file paths, stack traces, SQLite
errors, and system errors from messages before returning them to clients.
Applied to all route-level catch blocks in payments, queue, fights, and
admin routes. Includes 12 tests for the sanitizer and static analysis
test verifying no route files leak raw err.message.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-13 09:46:38 +00:00
DorianandClaude Opus 4.6 dc9884e27e test: verify wallet disconnect wipes connection data from DB
Add test confirming disconnect-wallet deletes walletConnections rows
and sets hasWallet=false on the bot record.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-13 09:33:50 +00:00
DorianandClaude Opus 4.6 c5744f5984 test: pentest payment edge cases with 10 attack vector tests
Cover amount=0, over-max (999999999), zap non-winner, zap unfinished
fight, invalid wallet method, empty cashu token, claim nonexistent
payment, confirm already-confirmed, confirm outbound payment, claim
payment with no token.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-13 09:32:19 +00:00
DorianandClaude Opus 4.6 2fea2bf8c9 test: verify error responses never leak stack traces or file paths
Add tests confirming production error handler sanitizes all internal
errors (ENOENT, stack traces, file paths). Add static analysis test
verifying no route file passes err.stack to c.json() responses.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-13 09:30:55 +00:00
DorianandClaude Opus 4.6 21bb46c1b0 test: verify admin endpoints require creator pubkey on all routes
Test all 7 admin endpoints (stats, bots, deactivate, activate,
reset-elo, fights, backup) reject non-creator pubkeys and missing
pubkeys with 403. Verifies global middleware guard works correctly.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-13 09:29:08 +00:00
DorianandClaude Opus 4.6 d4c51f0aac fix: tighten auth rate limits to 10/min and add rate limit tests
Reduce login and nostr/session rate limits from 30 to 10 requests per
minute per IP to prevent brute-force attacks. Add tests verifying 429
response after exceeding the limit.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-13 09:28:38 +00:00
DorianandClaude Opus 4.6 2051a95e13 refactor: add centralized Zod validators for all API inputs
Create server/src/lib/validators.ts with reusable schemas for all API
inputs (auth, fights, bets, payments, tournaments, queue, docs).
Import and use in all route handlers, replacing inline validation.
Add formatZodError helper for user-friendly error messages.
77 test cases in validators.test.ts cover valid, invalid, boundary,
and attack inputs (SQL injection, XSS, prototype pollution).

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-13 09:16:04 +00:00
DorianandClaude Opus 4.6 5e40221a2f test: SSE, polling, human, and concurrent fight integration tests
14 integration tests covering full fight lifecycle with real in-memory
DB: SSE event ordering, polling bot challenge/response flow, human
player response submission, and 3 concurrent fights without interference.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-13 05:10:27 +00:00
DorianandClaude Opus 4.6 41c66d7732 test: full fight flow integration test with real in-memory DB
8 tests covering: complete fight lifecycle, HP progression, ELO
updates, concurrent fight prevention, round data validity, ELO
conservation, status transitions, and win streak tracking.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-13 05:00:25 +00:00
DorianandClaude Opus 4.6 11a76cc249 fix: selective leaderboard cache invalidation instead of full clear (BUG-S10)
Only invalidates __alltime__ and current season cache keys on fight completion,
preserving historical season caches. Test verifies selective behavior.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-13 00:03:16 +00:00
DorianandClaude Opus 4.6 c224776c90 test: add payments.test.ts (12 cases) and expand bets.test.ts (30 cases)
Covers wallet connection, invoice creation, payment confirmation, zap validation,
odds calculation, escrow settlement, bet validation, and display conversion.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-13 00:01:17 +00:00
DorianandClaude Opus 4.6 f18b04ba20 test: verify global error handler returns 500 without stack traces (BUG-S7)
Global app.onError handler already in app.ts catches all unhandled route
exceptions. Production mode returns "Internal server error" only.
Tests verify no stack traces or file paths leak in responses.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-12 23:51:12 +00:00
DorianandClaude Opus 4.6 34a83fb0fc test: add auth routes test suite with 13 cases
Tests check-name validation, login pubkey validation, register name/pubkey
validation, register-human validation, NIP-98 session (valid + expired).

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-12 23:43:57 +00:00
DorianandClaude Opus 4.6 5e0bc1dc00 test: verify correct/incorrect feedback in respond endpoint (BUG-1)
Tests confirm checkAnswer integration: correct answer returns
correct: true, wrong answer returns correct: false.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-12 23:17:16 +00:00
DorianandClaude Opus 4.6 370d8643b7 fix: add Zod enum validation for challenge types in webhook tester (BUG-S6)
Validates challenge type against the full CHALLENGE_TYPES enum before
processing. Invalid types now return 400 instead of silently falling
back to speed_blitz.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-12 22:56:26 +00:00
DorianandClaude Opus 4.6 e4a7f47e0f fix: validate Cashu token format before placing bets (BUG-S4)
Added getDecodedToken validation that rejects malformed tokens with
400 before any DB lookups. Tests cover empty, non-base64, truncated,
and random base64 tokens.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-12 22:46:24 +00:00
DorianandClaude Opus 4.6 c6a54d63c4 fix: add rate limiting to /poll endpoint + fix test type errors (BUG-S3)
- Add rateLimit(1_000, 30) middleware to GET /poll endpoint
- Fix Challenge type errors in human-responses test files (missing baseDamage)
- Add rate-limit unit test verifying 429 after exceeding limit

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-12 22:41:59 +00:00
DorianandClaude Opus 4.6 8468c89352 test: verify tournaments .get() is sync + add route tests
better-sqlite3 driver is synchronous — .get() does NOT need await.
Added tests for unknown pubkey (404) and missing pubkey (400) on join.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-12 22:32:37 +00:00
Dorian 29a0a48eb1 human fight sequence fix 2026-03-11 10:02:37 +00:00
Dorian bcbcd17fce challenges fix 2026-03-11 08:35:03 +00:00
DorianandClaude Opus 4.6 68e292183a fix: polling bots play practice fights as human players in browser
Polling bots have no external script running during practice mode,
so the poll would time out giving empty answers. Now overrides the
webhook URL to human.local so the browser UI handles challenges.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-09 19:02:35 +00:00
DorianandClaude Opus 4.6 95ed80335a feat: polling API, HMAC webhook signing, session-only keys, prod audio fix
- Add polling API (GET/POST /api/fights/poll) so bots don't need public URLs
- Add HMAC-SHA256 webhook signing (X-Botfights-Signature header)
- Stop auto-persisting nsec keys — session-only by default with opt-in "Remember on this device"
- Fix production TTS: add wav/mp3/ogg MIME types, /audio/* route, SPA blocklist
- Overhaul docs: mode selector (poll vs webhook), AI-first bot examples, security tab
- Fix duplicate sign-in buttons, login flow bugs

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-09 18:34:22 +00:00
DorianandClaude Opus 4.6 6dc50f5d5d feat: move creator pubkey to env, fix mobile TTS + signer, button loaders
Security:
- Move CREATOR_PUBKEY from hardcoded constant to BOTFIGHTS_CREATOR_PUBKEYS
  env var. Shared isCreatorPubkey() in constants.ts used by auth, admin,
  tournaments. Frontend checks authorization via API, not client-side.

Mobile fixes:
- Nostr signer: poll for window.nostr up to 3s (Amber injects late).
- TTS: auto-unlock AudioContext on first user interaction via
  installAutoUnlock() on fight page mount.

UX:
- Add loading spinners to "I BUILD BOTS" and "I FIGHT MYSELF" buttons.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-09 15:31:58 +00:00
DorianandClaude Opus 4.6 3ba05a66b4 feat: NIP-98 + JWT authentication with signer support
Replace insecure raw-pubkey auth with cryptographic NIP-98 signed
requests and server-issued JWT sessions. Logout now fully clears
all state including nsec. Add yellow "Use Nostr Signer" button
for Amber/NIP-07 remote signers.

- Server: JWT middleware (HMAC-SHA256, 24h expiry), NIP-98 verification
- Server: POST /api/auth/nostr/session endpoint
- Frontend: NIP-98 token builder + authFetch wrapper with JWT Bearer
- Frontend: All authenticated API calls use authFetch
- Security: logout clears JWT, pubkey, bot, nsec, and profile pic

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-09 12:31:25 +00:00
DorianandClaude Opus 4.6 e31d49898b feat: show rejoin link when bot is already in a fight
- Track active fight IDs per bot in orchestrator (Set → Map)
- Return fightId in "already in fight" error responses (409)
- Frontend shows "REJOIN FIGHT" link instead of generic error

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-09 09:27:48 +00:00
DorianandClaude Opus 4.6 3c32f01aa7 feat: add Retry-After header and countdown timer for rate limits
- Rate limiter returns retryAfterSec in response body + Retry-After header
- Registration rate limits: 10 per 10min (was 15/hour)
- Frontend surfaces retry timer in error messages

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-09 09:15:30 +00:00
DorianandClaude Opus 4.6 4cc18048e8 refactor: replace console.log/error with structured logger across server
Migrate all server modules to use the centralized logger (lib/logger.ts)
instead of raw console calls. Lint warnings reduced from 74 to 25.
Remaining warnings are only no-floating-promises in game engine code.

Files updated: orchestrator.ts, ranked-queue.ts, human-responses.ts,
payments.ts, fight-loop.ts, app.ts, routes/payments.ts
Files suppressed: logger.ts, fight-loop-cli.ts, migrate.ts (legitimate console use)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-09 09:06:36 +00:00
DorianandClaude Opus 4.6 3c95adb545 feat: convert all human fights to multiple choice, remove text input
Creative challenges (roast_battle, creative_writing, meme_war,
code_golf, wrestling_match) now auto-generate multiple choice options
from per-type response pools: 1 good answer + 3 weaker distractors.
The free text input UI is commented out but preserved for future use.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-09 08:28:22 +00:00
DorianandClaude Opus 4.6 4074ef94eb feat: add leaderboard cache, performance benchmarks, and verify SSE cleanup
- Add 30s TTL leaderboard cache with invalidation on fight completion
- Add scoreRound performance benchmark: 1000 rounds in <100ms
- Add checkAnswer performance benchmark: 1000 checks in <50ms
- Add adversarial regex backtracking test for checkAnswer
- Verify SSE cleanup: connections, IP counters, spectator counts, event listeners
  all properly decremented in finally block on disconnect

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-09 07:50:46 +00:00
DorianandClaude Opus 4.6 7d9b8b1dbf chore: add ESLint with no-floating-promises and no-console rules
Sets up ESLint 10 flat config with @typescript-eslint/no-floating-promises (error)
and no-console (warn, allow warn/error). Fixes all floating promise errors in
server routes, orchestrator reader cleanup, and frontend composables with void operator.
Game engine files get warning-level for intentional fire-and-forget async.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-09 07:47:43 +00:00
DorianandClaude Opus 4.6 fbc61ef154 fix: add amount validation for zap and bet endpoints
Validate amountSats is a positive integer (1–1,000,000) on both
/zap and /bets/place endpoints to prevent negative, zero, or
absurdly large amounts.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-09 07:34:51 +00:00
DorianandClaude Opus 4.6 5bfb63aa7f fix: add input validation, Zod schemas, rate limiting, and IP trust
- Add Zod schema for webhook response parsing (orchestrator.ts)
- Add Zod schemas for POST /respond and /react request bodies
- Add safe integer validation for batch count param
- Prefer cf-connecting-ip over spoofable x-forwarded-for
- Add ID format validation on URL params
- Add rate limiting on /auth/login (30/min) and /update (10/min)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-09 07:30:49 +00:00
DorianandClaude Opus 4.6 69601cce3a feat: automated backup and production monitoring
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-09 00:33:35 +00:00
DorianandClaude Opus 4.6 8be71e9929 fix: admin and docs bugs
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-09 00:20:00 +00:00
DorianandClaude Opus 4.6 c654ff9f73 feat: interactive bot developer documentation
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-09 00:18:06 +00:00
DorianandClaude Opus 4.6 e10c1dc8aa feat: privacy-respecting analytics
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-09 00:15:20 +00:00
DorianandClaude Opus 4.6 2170e9275c feat: admin dashboard for THE CREATOR
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-09 00:12:36 +00:00
DorianandClaude Opus 4.6 e3a4299dae perf: server memory leak audit
Add periodic cleanup of fightReactions Map (clears when >100 entries).
Add RSS/heap logging every 10 fights in fight-loop for memory monitoring.
Set --max-old-space-size=256 in Docker CMD as safety net.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-09 00:05:03 +00:00
DorianandClaude Opus 4.6 4d1e592365 refactor: standardize error handling with toError() helper
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-08 21:44:17 +00:00
DorianandClaude Opus 4.6 b70c49075e feat: tournament API routes
POST /api/tournaments (create, admin-only),
POST /api/tournaments/:id/join, POST /api/tournaments/:id/start,
GET /api/tournaments (list), GET /api/tournaments/:id (bracket).

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-08 20:58:23 +00:00
DorianandClaude Opus 4.6 38f94c2955 perf: SSE connection pooling and cleanup
Add per-IP SSE connection limit (max 5 concurrent streams). Track
activeSSECount and ssePerIp maps with proper decrement in finally
blocks. Export getActiveSSECount() for admin stats. Change heartbeat
ping from 5s to 15s interval. Connections already clean up on client
disconnect via Hono's streamSSE try/catch/finally pattern.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-08 20:49:56 +00:00