Skip to content

fix: platform hardening — security, API contracts, UX, tests#22

Open
Javaris500 wants to merge 1 commit into
mainfrom
audit/platform-hardening-phase1-6
Open

fix: platform hardening — security, API contracts, UX, tests#22
Javaris500 wants to merge 1 commit into
mainfrom
audit/platform-hardening-phase1-6

Conversation

@Javaris500

Copy link
Copy Markdown

Summary

Full platform audit and hardening across 6 phases (18 tasks). Resolves issues #17, #18, #19, #20 and addresses 14 additional findings from a comprehensive security and edge-case audit.

55 files changed, 46 new tests, 0 regressions.

Phase 1 — Unblock Users

  • Fix workspace creation always returning 422 (client sent directory, backend expects path)
  • Fix response unwrapping for 8+ entity endpoints (sessions, issues, projects, goals, workspaces) — backend wraps as {entity: data} but client was reading flat

Phase 2 — Security

  • Add authorization checks to organization, workspace, and user controllers
  • Fix WorkspaceAuth plug to check :id param on workspace routes (was only checking workspace_id)
  • Scope workspace.activate to current user — was archiving every workspace in the DB
  • Add workspace scoping to session controller (show, transcript, message, stream)
  • Fix agent index fallback that leaked all agents to users with no workspaces

Phase 3 — UX Stability

  • Add token refresh attempt + redirect to /auth on 401 (was silently failing)
  • Add .catch() to initializeAuth() with error UI and retry button (was hanging forever)

Phase 4 — Data Accuracy

  • Fix session chain key mismatch (chain vs sessions)
  • Remove dead sessions.create() (no backend route, never called from UI)

Phase 5 — Hardening

  • Fix dashboard auto-refresh interval leak on unmount
  • Strengthen email validation from ~r/@/ to proper format check
  • Safe integer parsing (parse_int/2) across 19 controllers (prevents 500 on ?limit=abc)
  • Wrap org creation + membership in Ecto.Multi transaction
  • Move API keys from localStorage to sessionStorage on web builds
  • Align TypeScript types with actual backend responses (Issue.labels, Goal, Project)

Phase 6 — Foundation

  • 7 new test files covering auth, workspace, org, session, agent, user controllers + user schema
  • Shared config.ts for API base URL (was hardcoded in 3 files)
  • Disable rate limiter in test env for reliable test execution

Test plan

  • mix compile --warnings-as-errors passes clean
  • 46 new tests, 0 failures
  • Full suite: 209 tests, 20 failures (all 20 pre-existing — Bash adapter on Windows, governance executor API)
  • 0 regressions introduced
  • Manual: register new account → onboarding → dashboard (verify workspace name shows correctly)
  • Manual: create org/workspace/agent → verify cross-user access returns 403
  • Manual: expire token → verify redirect to /auth

See docs/AUDIT-CHECKLIST.md for the full audit with per-issue explanations.

🤖 Generated with Claude Code

…test coverage

Resolves issues #17, #18, #19, #20 and addresses 18 audit findings across 6 phases.

Security (Phase 2):
- Add authorization checks to org/workspace/user controllers
- Fix WorkspaceAuth plug to check :id on workspace routes
- Scope workspace.activate to current user only (was archiving all users)
- Add workspace scoping to session controller (show/transcript/message/stream)
- Fix agent index fallback leaking all agents for new users

API contracts (Phase 1 & 4):
- Fix workspace creation 422 (client sends directory, backend expects path)
- Fix response unwrapping for sessions, issues, projects, goals, workspaces
- Fix session chain key mismatch (chain vs sessions)
- Remove dead sessions.create() — no backend route exists

UX stability (Phase 3):
- Add token refresh + redirect to /auth on 401 expiry
- Add .catch() error handler to initializeAuth() with retry UI

Hardening (Phase 5):
- Fix dashboard auto-refresh interval leak on unmount
- Strengthen email validation regex (was only checking for @)
- Safe integer parsing across 19 controllers (parse_int helper)
- Wrap org creation + membership in Ecto.Multi transaction
- Move API keys from localStorage to sessionStorage on web builds
- Align TypeScript types with actual backend responses

Foundation (Phase 6):
- Add 7 new test files (46 tests, 0 failures, 0 regressions)
- Extract shared API base URL config (client.ts, sse.ts, websocket.ts)
- Disable rate limiter in test env for reliable test execution

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
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