Repository navigation
fix: authorize org routes by membership; drop CurrentUser.organizationId - #374
Conversation
CurrentUser.organizationId was never set (sessions, OAuth bearers and bot tokens all leave it empty), so every check against it failed: the T3 Code link, integration OAuth start, connection status and disconnect answered 401 for every member, and web pages that read it never loaded their org's connections, mentionable bots or commands. The field is gone from CurrentUser (backend and web), so no code can rely on it again. The integration and T3 Code routes check the directory's membership index (requireMember); the web reads the route's organization. Also bundle T3 Code's own logo instead of Brandfetch's t3.chat icon. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
Caution Review failedThe pull request is closed. Walkthrough
Merge Risk:
|
Maple review🟢 Confidence 7/10 · likely safe to merge. Untested authorization wiring on the org HTTP routes decides the number; Replaces the dead
Findings🟠 Warning · F1 · No test pins that
|
| return currentUser | ||
| }) | ||
| /** The caller, once they are an active member of `orgId` (sessions carry no organization). */ | ||
| const requireOrg = (orgId: OrganizationId) => requireMember(orgId).pipe(Effect.andThen(CurrentUser.Context)) |
There was a problem hiding this comment.
Warning
No test pins that requireOrg admits a member and refuses an outsider
F1 · Warning · tests
The behavior this PR fixes — an org route answering a member whose session carries no organization — is exercised by no test. t3code.http.test.ts covers only checkCallback and requireT3CodeBot, so a return to an always-failing org check would pass CI again, as it did before.
Export `requireOrg` and test it against a seeded directory the way `cross-org.test.ts` does for `requireMember`: an active `membership_index` row passes, an outsider fails with `UnauthorizedError`.
🤖 Prompt to fix with an AI agent
In `apps/backend/src/routes/t3code.http.ts:115`: No test pins that `requireOrg` admits a member and refuses an outsider.
The behavior this PR fixes — an org route answering a member whose session carries no organization — is exercised by no test. `t3code.http.test.ts` covers only `checkCallback` and `requireT3CodeBot`, so a return to an always-failing org check would pass CI again, as it did before.
Suggested fix: Export `requireOrg` and test it against a seeded directory the way `cross-org.test.ts` does for `requireMember`: an active `membership_index` row passes, an outsider fails with `UnauthorizedError`.
Verify the problem exists at that location before changing it, and keep the fix to those lines.
Problem
The T3 Code integration page showed "Couldn't load your T3 Code link". In production,
GET /integrations/t3code/:orgIdanswered 401: the trace stops after auth, with no object call.The route checked
currentUser.organizationId !== orgId, but nothing ever setsCurrentUser.organizationId. Session cookies (HazelSession), OAuth bearers and bot tokens all buildCurrentUserwith itundefined/null. It's a leftover from the old JWT-with-org auth, so every check against it failed:getOAuthUrl), connection status and disconnect, returned 401 for every member.shared.currentUser.organizationIdnever loaded their data (it was alwaysnull). That covers the integrations connection lists, the composer's mentionable bots and commands, Discord linking, and the draft's org. Test fixtures set it to a real org, which hid the problem.Fix
organizationIdfromCurrentUser(@hazel/domainand the web session), so the compiler now rejects any code that relies on it.requireMember.bots.tsandrequestOrganizationIddropped theiruser.organizationIdfallbacks. They use the routing hint or object only, which is what they did in practice.shared.organization). The root redirect's membership query drops its "org in the JWT" branch.apps/mobile/assets/widget/T3Mark.svgfrom pingdotgg/t3code), bundled as/images/integrations/t3code.svg, in place of Brandfetch'st3.chat(T3 Chat) icon.Verification
bun run typecheck: 20/20 packages passoxlinton the changed files: no new warnings🤖 Generated with Claude Code
Need help on this PR? Tag
@codesmith-botwith what you need.Summary by CodeRabbit