Skip to content

Commit 22be838

Browse files
committed
Better organization logic
1 parent a114ce5 commit 22be838

File tree

2 files changed

+78
-18
lines changed

2 files changed

+78
-18
lines changed

packages/cloud/src/AuthService.ts

Lines changed: 27 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -538,23 +538,37 @@ export class AuthService extends EventEmitter<AuthServiceEvents> {
538538

539539
userInfo.picture = userData.image_url
540540

541-
// Fetch organization memberships separately
541+
// Fetch organization info separately - but only populate if user is in organization context
542542
try {
543-
const orgMemberships = await this.clerkGetOrganizationMemberships()
544-
if (orgMemberships && orgMemberships.length > 0) {
545-
// Get the first (or active) organization membership
546-
const primaryOrgMembership = orgMemberships[0]
547-
const organization = primaryOrgMembership?.organization
548-
549-
if (organization) {
550-
userInfo.organizationId = organization.id
551-
userInfo.organizationName = organization.name
552-
userInfo.organizationRole = primaryOrgMembership.role
553-
userInfo.organizationImageUrl = organization.image_url
543+
const storedOrgId = this.getStoredOrganizationId()
544+
545+
if (storedOrgId !== null) {
546+
// User is in organization context - fetch user's memberships and filter
547+
const orgMemberships = await this.clerkGetOrganizationMemberships()
548+
549+
// Find the user's membership in this organization
550+
const userMembership = orgMemberships?.find(
551+
(membership: CloudOrganizationMembership) => membership.organization.id === storedOrgId,
552+
)
553+
554+
if (userMembership) {
555+
userInfo.organizationId = userMembership.organization.id
556+
userInfo.organizationName = userMembership.organization.name
557+
userInfo.organizationRole = userMembership.role
558+
userInfo.organizationImageUrl = userMembership.organization.image_url
559+
this.log("[auth] User in organization context:", {
560+
id: userMembership.organization.id,
561+
name: userMembership.organization.name,
562+
role: userMembership.role,
563+
})
564+
} else {
565+
this.log("[auth] Warning: User not found in stored organization:", storedOrgId)
554566
}
567+
} else {
568+
this.log("[auth] User in personal account context - not setting organization info")
555569
}
556570
} catch (error) {
557-
this.log("[auth] Failed to fetch organization memberships:", error)
571+
this.log("[auth] Failed to fetch organization info:", error)
558572
// Don't throw - organization info is optional
559573
}
560574

packages/cloud/src/__tests__/AuthService.spec.ts

Lines changed: 51 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -633,9 +633,55 @@ describe("AuthService", () => {
633633
expect(authService.getUserInfo()).toBeNull()
634634
})
635635

636-
it("should parse user info correctly", async () => {
637-
// Set up with credentials
638-
const credentials = { clientToken: "test-token", sessionId: "test-session" }
636+
it("should parse user info correctly for personal accounts", async () => {
637+
// Set up with credentials for personal account (no organizationId)
638+
const credentials = { clientToken: "test-token", sessionId: "test-session", organizationId: null }
639+
mockContext.secrets.get.mockResolvedValue(JSON.stringify(credentials))
640+
await authService.initialize()
641+
642+
// Clear previous mock calls
643+
mockFetch.mockClear()
644+
645+
// Mock successful responses
646+
mockFetch
647+
.mockResolvedValueOnce({
648+
ok: true,
649+
json: () => Promise.resolve({ jwt: "jwt-token" }),
650+
})
651+
.mockResolvedValueOnce({
652+
ok: true,
653+
json: () =>
654+
Promise.resolve({
655+
response: {
656+
first_name: "Jane",
657+
last_name: "Smith",
658+
image_url: "https://example.com/jane.jpg",
659+
primary_email_address_id: "email-2",
660+
email_addresses: [
661+
{ id: "email-1", email_address: "[email protected]" },
662+
{ id: "email-2", email_address: "[email protected]" },
663+
],
664+
},
665+
}),
666+
})
667+
668+
const timerCallback = vi.mocked(RefreshTimer).mock.calls[0][0].callback
669+
await timerCallback()
670+
671+
// Wait for async operations to complete
672+
await new Promise((resolve) => setTimeout(resolve, 0))
673+
674+
const userInfo = authService.getUserInfo()
675+
expect(userInfo).toEqual({
676+
name: "Jane Smith",
677+
678+
picture: "https://example.com/jane.jpg",
679+
})
680+
})
681+
682+
it("should parse user info correctly for organization accounts", async () => {
683+
// Set up with credentials for organization account
684+
const credentials = { clientToken: "test-token", sessionId: "test-session", organizationId: "org_1" }
639685
mockContext.secrets.get.mockResolvedValue(JSON.stringify(credentials))
640686
await authService.initialize()
641687

@@ -699,8 +745,8 @@ describe("AuthService", () => {
699745
})
700746

701747
it("should handle missing user info fields", async () => {
702-
// Set up with credentials
703-
const credentials = { clientToken: "test-token", sessionId: "test-session" }
748+
// Set up with credentials for personal account (no organizationId)
749+
const credentials = { clientToken: "test-token", sessionId: "test-session", organizationId: null }
704750
mockContext.secrets.get.mockResolvedValue(JSON.stringify(credentials))
705751
await authService.initialize()
706752

0 commit comments

Comments
 (0)