fix(auth): populate project picker for tokens without scoped_organizations#3279
Open
dmarticus wants to merge 2 commits into
Open
fix(auth): populate project picker for tokens without scoped_organizations#3279dmarticus wants to merge 2 commits into
dmarticus wants to merge 2 commits into
Conversation
…nizations Local PostHog backends mint project-scoped OAuth tokens with an empty `scoped_organizations` list — only `scoped_teams` gets populated. The old code trusted `scoped_organizations` as the sole source of orgs to enumerate, so an empty array meant zero fetches, an empty `orgProjectsMap`, and a project picker stuck on "No projects" even though the user had a valid current org. Fall back to the `organization.id` we already pull from `/api/users/@me/` when the token doesn't specify orgs. The org endpoint accepts team-scoped tokens fine (confirmed 200 against a local backend), so this populates the picker without changing the OAuth consent flow, token scoping, or any existing session behavior. The "empty scoped_organizations no-retry path" from #2655 still holds: if `@me` also has no organization (genuinely orgless user), `orgIdsToFetch` stays empty and the recovery loop never spins. The test that pinned that behavior is retitled to reflect its real defense (no org anywhere, not just no scoped orgs) and a positive test is added for the team-scoped fallback. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
|
Merging to
After your PR is submitted to the merge queue, this comment will be automatically updated with its status. If the PR fails, failure details will also be posted here |
|
React Doctor found no issues in the changed files. 🎉 Reviewed by React Doctor for commit |
Contributor
|
Reviews (1): Last reviewed commit: "fix(auth): fall back to @me current org ..." | Re-trigger Greptile |
Greptile spotted that the two new tests share `scopedOrgs: []` and differ only in what /api/users/@me/ returns. Collapse them into an it.each and absorb the inline vi.stubGlobal into stubOrgFetch via an optional `orgless` param. Also asserts the "no drift after connectivity emit" invariant for both rows instead of just the orgless one, so the recovery-loop no-op is defended on the fallback path too. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2 tasks
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Problem
Signing in to PostHog Code against a local backend (
localhost:8010) leaves the project picker stuck on "No projects" even though the user has membership in an org with teams. OAuth completes, the user profile renders (name, avatar, org), but the picker is empty and there's nothing to select.Confirmed by log diagnostics on a local Hedgehog Inc. account:
Root cause
Local PostHog backends mint project-scoped OAuth tokens (
required_access_level=projecton the authorize URL) with an emptyscoped_organizationslist — onlyscoped_teamsgets populated. The old code atpackages/core/src/auth/auth.ts:593trustedscoped_organizationsas the sole source of orgs to enumerate:Empty array → zero orgs iterated → empty
orgProjectsMap→ "No projects."Fix
Fall back to
organization.idfrom/api/users/@me/when the token doesn't specify orgs. We already fetch@metwo lines later — we were just throwing the current org id away.Confirmed the org endpoint (
/api/organizations/<id>/) returns 200 under a team-scoped token against a local backend, so this populates the picker without touching the OAuth consent flow, token scoping, or any existing session behavior.What this doesn't change
required_access_level=project, still mints team-scoped tokens. Security posture unchanged.@mealso has no organization (truly orgless user),orgIdsToFetchstays empty,orgProjectsIncompletestays false, and the recovery loop never spins.scoped_organizationsis populated for hosted PostHog tokens, so the fallback branch is dead code for them. Behavior identical to before.Related PRs
scope=*sign-in works). The picker fix here plus the server-side fixes there together give a one-shot working local sign-in for PostHog Code.Test updates
does not attempt recovery when the token grants no scoped organizations→does not attempt recovery when the user has no organization at all. The old title/heuristic was too narrow — it equated emptyscoped_organizationswith "no orgs," when the correct discriminator is@me.organization. The test now stubsorganization: nullon@meand keeps the same 0-fetches / null-project assertions to defend Gustavo's stranded-session concern from fix(auth): Auto-recover project-less session after re-auth #2655.falls back to the @me current org when the token has no scoped organizationsto pin the fixed behavior.How did you test this?
hoglet start, signed in againstlocalhost:8010on a Hedgebox Inc. account, watched the picker go from "No projects" to a populated list of 2 projects.pnpm --filter @posthog/core test -- auth— 43 auth tests pass (2143 core total, +1 new)pnpm --filter @posthog/core typecheck— cleanpnpm exec biome lint packages/core— cleanAutomatic notifications
🤖 Generated with Claude Code