Skip to content

Production-ready: auth hardening, SSE fix, security polish, conflict resolution - #24

Merged
KafKafrnZ merged 6 commits into
mainfrom
claude/pc-file-access-mnxju
Jul 3, 2026
Merged

KafKafrnZ merged 6 commits into
mainfrom
claude/pc-file-access-mnxju

Conversation

@KafKafrnZ

Copy link
Copy Markdown
Owner

Summary

  • Auth hardening: CSRF middleware, JWT refresh token rotation, fetchWithRefresh() wired into all 5 authenticated pages + tutor streaming
  • SSE fix: AI Tutor was showing "No response received" — SSE parser was silently dropping all tokens from plain-string sse-starlette streams; fixed to treat non-JSON payloads as raw tokens
  • Practice page fix: <Environment preset="night"> was fetching dikhololo_night_1k.hdr from CDN (failed in local dev / offline); replaced with equivalent manual lighting
  • Security polish (from PR fix: frontend security polish — CSP, XSS sanitization, accessibility, password strength #22): rehype-sanitize XSS protection on ReactMarkdown, 4-rule password strength meter (includes special char), htmlFor/aria-live accessibility, Content-Security-Policy header
  • Merge conflict resolution: Resolved 16 conflicts from enterprise audit PR fix: enterprise audit — critical & high severity fixes #21 — kept router-based main.py, merged vercel.json (security + cache headers combined), our proxy.ts with /explore protection
  • 10-gap audit (P-D1→P-D10): structured error codes, pool pre-ping, OG/Twitter metadata, PWA PNG icons, Sentry guards, DEPLOY.md, README.md accuracy fixes, SECURITY.md disclosure link
  • Test fixes: proxy-auth tests now use valid JWT-format tokens (plain strings fail isTokenExpired()); SSE parser tests updated for raw-token fallback behaviour

What changed

Area Change
frontend/lib/sse.ts Raw string payloads returned as {token} instead of {error}
frontend/components/ui/Blackhole.tsx Removed CDN HDR environment; manual scene lights
frontend/app/api/[...path]/route.ts Strip Expect header (Node v24 undici); AbortSignal.timeout(55000)
frontend/proxy.ts /explore protected; isTokenExpired() JWT expiry check
frontend/vercel.json Security headers + static asset cache headers merged
backend/app/core/auth.py hashlib SHA-256 refresh token hashing; secrets generation
backend/app/core/config.py .env.local takes precedence over .env
backend/app/core/error_handler.py Structured api_error() format + client IP in rate-limit logs
backend/app/main.py Clean 94-line router-based entrypoint (dropped 900-line monolith)
backend/railway.toml healthcheckTimeout=30 for fastembed warmup

Test plan

  • Backend: 69 tests pass (pytest backend/tests/ -q)
  • Frontend: 35 tests pass (npm test -- --run)
  • Manual: sign up → sign in → open Tutor → send a message (should get streamed response)
  • Manual: navigate to Practice page (should load without HDR fetch error)
  • Manual: navigate to /explore without auth (should redirect to /login)

Reviewer notes

🤖 Generated with Claude Code

KafKafrnZ and others added 6 commits June 9, 2026 23:06
tutor — SSE parser was returning {error} for non-JSON payloads (plain
string tokens from sse-starlette), causing processSseLine to skip every
token and show "No response received". Fix: catch block now returns the
raw payload as {token} so plain-string streams work alongside JSON-
wrapped streams.

practice — <Environment preset="night"> in Blackhole.tsx tried to load
dikhololo_night_1k.hdr from the jsdelivr CDN. Fails in local dev / when
CDN is blocked. Replaced with equivalent manual ambientLight+pointLight
setup that needs no external assets.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@KafKafrnZ
KafKafrnZ merged commit dd02674 into main Jul 3, 2026
2 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant