Conversation
Bugbot couldn't run - usage limit reachedBugbot is counted against Cursor usage for this user or team, and this run hit a usage or spend limit. A user or team admin can review and increase usage limits in the Cursor dashboard. (requestId: serverGenReqId_887855d8-7a16-478c-b3bb-af85781da512) |
There was a problem hiding this comment.
Code Review
This pull request introduces support for the DOS.Me Organization and Teams hierarchy, including JIT token claims, by updating the OAuth provider, authentication interfaces, and documentation. The review feedback suggests improving TypeScript type safety and IDE autocompletion for team roles by using the (string & {}) idiom instead of a raw string union. Additionally, it recommends using optional chaining when parsing the OAuth payload to prevent potential runtime errors if the payload or its metadata is undefined.
| organizations?: Array<{ id: string; name: string; role?: 'OWNER' | 'ADMIN' | 'MEMBER' }>; | ||
| active_org_id?: string; | ||
| organizations?: Array<{ id: string; name: string; slug?: string; role?: 'OWNER' | 'ADMIN' | 'MEMBER' | 'SUPERADMIN' }>; | ||
| teams?: Array<{ id: string; org_id: string; name: string; slug: string; role?: 'LEAD' | 'MEMBER' | string }>; |
There was a problem hiding this comment.
In TypeScript, unioning specific string literal types (like 'LEAD' | 'MEMBER') with the generic string type causes the entire union to collapse into string. This defeats type safety and autocompletion for the specific roles. To preserve IDE autocompletion for 'LEAD' and 'MEMBER' while still allowing any custom string, use the (string & {}) idiom.
| teams?: Array<{ id: string; org_id: string; name: string; slug: string; role?: 'LEAD' | 'MEMBER' | string }>; | |
| teams?: Array<{ id: string; org_id: string; name: string; slug: string; role?: 'LEAD' | 'MEMBER' | (string & {}) }>; |
| organizations?: Array<{ id: string; name: string; role?: 'OWNER' | 'ADMIN' | 'MEMBER' }>; | ||
| active_org_id?: string; | ||
| organizations?: Array<{ id: string; name: string; slug?: string; role?: 'OWNER' | 'ADMIN' | 'MEMBER' | 'SUPERADMIN' }>; | ||
| teams?: Array<{ id: string; org_id: string; name: string; slug: string; role?: 'LEAD' | 'MEMBER' | string }>; |
There was a problem hiding this comment.
In TypeScript, unioning specific string literal types (like 'LEAD' | 'MEMBER') with the generic string type causes the entire union to collapse into string. This defeats type safety and autocompletion for the specific roles. To preserve IDE autocompletion for 'LEAD' and 'MEMBER' while still allowing any custom string, use the (string & {}) idiom.
| teams?: Array<{ id: string; org_id: string; name: string; slug: string; role?: 'LEAD' | 'MEMBER' | string }>; | |
| teams?: Array<{ id: string; org_id: string; name: string; slug: string; role?: 'LEAD' | 'MEMBER' | (string & {}) }>; |
| id: payload.sub || payload.id, | ||
| name: payload.name || payload.full_name || payload.user_metadata?.name || payload.user_metadata?.full_name, | ||
| picture: payload.picture || payload.avatar_url || payload.user_metadata?.picture || payload.user_metadata?.avatar_url, | ||
| active_org_id: payload.active_org_id || payload.user_metadata?.active_org_id, |
There was a problem hiding this comment.
To prevent potential runtime TypeError exceptions if payload or payload.user_metadata is null or undefined, use optional chaining (payload?.active_org_id and payload?.user_metadata?.active_org_id).
| active_org_id: payload.active_org_id || payload.user_metadata?.active_org_id, | |
| active_org_id: payload?.active_org_id || payload?.user_metadata?.active_org_id, |
| picture: payload.picture || payload.avatar_url || payload.user_metadata?.picture || payload.user_metadata?.avatar_url, | ||
| active_org_id: payload.active_org_id || payload.user_metadata?.active_org_id, | ||
| organizations: payload.organizations || payload.user_metadata?.organizations || [], | ||
| teams: payload.teams || payload.user_metadata?.teams || [], |
There was a problem hiding this comment.
To prevent potential runtime TypeError exceptions if payload or payload.user_metadata is null or undefined, use optional chaining (payload?.teams and payload?.user_metadata?.teams).
| teams: payload.teams || payload.user_metadata?.teams || [], | |
| teams: payload?.teams || payload?.user_metadata?.teams || [], |
What kind of change does this PR introduce?
Release:
v2.24.0- Full ecosystem synchronization, DOS.Me Organization & Teams JIT token claims support, and production stability enhancements.Why was this change needed?
To release Crove Post
v2.24.0incorporating:teamsscope,active_org_id,teams: [{ id, org_id, name, slug, role }]).AuthService.checkExists()and canonicalorgIdpassing.build.mjs).Technical Details & Scope
apps/backend/src/services/auth/providers/oauth.provider.ts:teamsscope (openid profile email organizations teams offline_access).active_org_idandteamsingetUser().apps/backend/src/services/auth/auth.service.ts:syncUserOrganizations()and added it tocheckExists().libraries/nestjs-libraries/src/database/prisma/schema.prisma:providercolumn (@default("stripe")) toSubscriptionmodel for multi-provider billing.docs/sso-architecture.md&CHANGELOG.md:v2.24.0.Verification & Testing
pnpm --filter ./apps/backend run build,pnpm --filter ./apps/orchestrator run build.pnpm --filter @crove/sso test(31/31 passed).pnpm dlx tsx scripts/branding-guard.ts(100% passed).https://post.crove.com/api/health&https://beta-post.crove.com/api/health.QA
post.crove.com/authJOY,DOS,Crove) and teams are loaded/api/healthendpoint returns200 OKChecklist:
pnpm run build).Note
Medium Risk
Changes login authorization scopes and identity claim parsing on the auth path; mis-parsed claims could affect workspace context for returning SSO users.
Overview
v2.24.0 extends DOS.Me SSO so Crove Post requests the
teamsscope and surfaces richer UserInfo/JIT claims on login.The generic OAuth provider and
AuthProviderAbstractnow includeactive_org_id, organization entries with optionalslugandSUPERADMIN, and ateamsarray (id,org_id,name,slug,role).OauthProvider.generateLink()defaults scopes toopenid profile email organizations teams offline_access, andgetUser()maps those fields from the token payload (includinguser_metadatafallbacks).docs/sso-architecture.mddocuments the unified org/teams JWT contract for zero-latency JIT provisioning across Crove apps.CHANGELOG.mdrecords the broader v2.24.0 release (auth sync fixes, OpenAI gateway envs, extension build, subscriptionprovidercolumn, upstream merge) even though this diff is mainly the OAuth contract and docs.Reviewed by Cursor Bugbot for commit 2643e24. Configure here.