Skip to content

Commit a2856df

Browse files
committed
Fixes
1 parent 20a5789 commit a2856df

2 files changed

Lines changed: 95 additions & 61 deletions

File tree

apps/code/src/renderer/features/auth/stores/authStore.ts

Lines changed: 78 additions & 60 deletions
Original file line numberDiff line numberDiff line change
@@ -187,41 +187,6 @@ async function attemptRefreshWithActivityCheck(
187187
}
188188
}
189189

190-
function buildOrgProjectsMapFromUser(
191-
user: Record<string, unknown>,
192-
): Record<string, OrgProjects> {
193-
const org = user?.organization as
194-
| {
195-
id?: string;
196-
name?: string;
197-
teams?: { id: number | string; name?: string }[];
198-
}
199-
| undefined;
200-
201-
if (!org?.id) return {};
202-
203-
const orgId = String(org.id);
204-
const teams = Array.isArray(org.teams) ? org.teams : [];
205-
206-
return {
207-
[orgId]: {
208-
orgName: org.name ?? "Unknown Organization",
209-
projects: teams
210-
.filter(
211-
(t): t is { id: number | string; name?: string } =>
212-
t != null &&
213-
typeof t === "object" &&
214-
(typeof t.id === "number" || typeof t.id === "string"),
215-
)
216-
.map((t) => ({
217-
id: Number(t.id),
218-
name: t.name ?? `Project ${t.id}`,
219-
}))
220-
.filter((t) => !Number.isNaN(t.id)),
221-
},
222-
};
223-
}
224-
225190
async function buildOrgProjectsMap(
226191
user: Record<string, unknown>,
227192
client: PostHogAPIClient,
@@ -231,35 +196,88 @@ async function buildOrgProjectsMap(
231196
name?: string;
232197
}[];
233198

234-
const entries = await Promise.all(
235-
orgs.map(async (org) => {
236-
const projects = await client.listOrgProjects(org.id).catch((err) => {
237-
log.warn("Failed to fetch projects for org", { orgId: org.id, err });
238-
return null;
239-
});
240-
return { orgId: org.id, orgName: org.name, projects };
241-
}),
242-
);
199+
const map: Record<string, OrgProjects> = {};
200+
for (const org of orgs) {
201+
map[org.id] = {
202+
orgName: org.name ?? "Unknown Organization",
203+
projects: [],
204+
};
205+
}
206+
207+
// Try the first org to check if org-level endpoints are accessible.
208+
// If not (e.g. project-scoped token), skip the rest and fall back to
209+
// the project-scoped endpoint.
210+
if (orgs.length > 0) {
211+
try {
212+
map[orgs[0].id].projects = await client.listOrgProjects(orgs[0].id);
213+
214+
// First org worked, fetch the rest in parallel
215+
if (orgs.length > 1) {
216+
const rest = await Promise.all(
217+
orgs.slice(1).map(async (org) => {
218+
const projects = await client
219+
.listOrgProjects(org.id)
220+
.catch((err) => {
221+
log.warn("Failed to fetch projects for org", {
222+
orgId: org.id,
223+
err,
224+
});
225+
return [];
226+
});
227+
return [org.id, projects] as const;
228+
}),
229+
);
230+
for (const [orgId, projects] of rest) {
231+
map[orgId].projects = projects;
232+
}
233+
}
234+
235+
return map;
236+
} catch (err) {
237+
log.warn(
238+
"Org-level project listing unavailable, falling back to project endpoint",
239+
{ err },
240+
);
241+
}
242+
}
243+
244+
// Fallback: switch into each org and read team from /me.
245+
// Both switchOrganization and getCurrentUser are user-level endpoints
246+
// that work regardless of token scoping.
247+
const currentOrgId = (user?.organization as { id?: string } | undefined)?.id;
248+
249+
for (const org of orgs) {
250+
try {
251+
let orgUser: Record<string, unknown>;
252+
if (org.id === currentOrgId) {
253+
orgUser = user;
254+
} else {
255+
await client.switchOrganization(org.id);
256+
orgUser = await client.getCurrentUser();
257+
}
243258

244-
const allFailed =
245-
entries.length > 0 && entries.every((e) => e.projects === null);
259+
const team = orgUser?.team as { id?: number; name?: string } | undefined;
260+
if (team?.id && map[org.id]) {
261+
map[org.id].projects = [
262+
{ id: team.id, name: team.name ?? `Project ${team.id}` },
263+
];
264+
}
265+
} catch (err) {
266+
log.warn("Failed to fetch project via org switch", {
267+
orgId: org.id,
268+
err,
269+
});
270+
}
271+
}
246272

247-
if (allFailed) {
248-
log.warn(
249-
"All org project calls failed, falling back to user organization teams",
250-
);
251-
return buildOrgProjectsMapFromUser(user);
273+
// Switch back to the original org
274+
if (currentOrgId && orgs.length > 1) {
275+
await client.switchOrganization(currentOrgId).catch((err) => {
276+
log.warn("Failed to switch back to original org", { err });
277+
});
252278
}
253279

254-
return Object.fromEntries(
255-
entries.map((e) => [
256-
e.orgId,
257-
{
258-
orgName: e.orgName ?? "Unknown Organization",
259-
projects: e.projects ?? [],
260-
},
261-
]),
262-
);
280+
return map;
263281
}
264282

265283
export const useAuthStore = create<AuthState>()(

apps/code/src/renderer/features/projects/hooks/useProjects.tsx

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,9 @@ export function groupProjectsByOrg(
3636
export function useProjects() {
3737
const orgProjectsMap = useAuthStore((s) => s.orgProjectsMap);
3838
const currentProjectId = useAuthStore((s) => s.projectId);
39+
const isAuthenticated = useAuthStore((s) => s.isAuthenticated);
3940
const selectProject = useAuthStore((s) => s.selectProject);
41+
const logout = useAuthStore((s) => s.logout);
4042

4143
const groupedProjects = useMemo(
4244
() => groupProjectsByOrg(orgProjectsMap),
@@ -51,6 +53,12 @@ export function useProjects() {
5153
const currentProject = projects.find((p) => p.id === currentProjectId);
5254

5355
useEffect(() => {
56+
const hasOrgData = Object.keys(orgProjectsMap).length > 0;
57+
if (isAuthenticated && hasOrgData && projects.length === 0) {
58+
log.info("No projects available, logging out");
59+
logout();
60+
return;
61+
}
5462
if (projects.length > 0 && !currentProject) {
5563
log.info("Auto-selecting first available project", {
5664
projectId: projects[0].id,
@@ -61,7 +69,15 @@ export function useProjects() {
6169
});
6270
selectProject(projects[0].id);
6371
}
64-
}, [projects, currentProject, currentProjectId, selectProject]);
72+
}, [
73+
isAuthenticated,
74+
projects,
75+
currentProject,
76+
currentProjectId,
77+
selectProject,
78+
logout,
79+
orgProjectsMap,
80+
]);
6581

6682
return {
6783
projects,

0 commit comments

Comments
 (0)