From 34d9fcaba1d840a8ed3b88e9860ba1e6d4f993f9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?F=C3=A9lix=20Malfait?= Date: Thu, 14 May 2026 08:15:53 +0200 Subject: [PATCH] chore(auth): drop unused workspacePersonalInviteToken from SSO state (#20557) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ## Summary Pure dead-code removal. The Google and Microsoft SSO strategies have been packing `workspacePersonalInviteToken` into the OAuth `state` blob and re-emitting it on `validate()`, but [`signInUpWithSocialSSO`](packages/twenty-server/src/engine/core-modules/auth/services/auth.service.ts) never destructures or reads it from the user object. The SSO flow resolves invitations by the IdP-verified email instead: ```ts const invitation = currentWorkspace && email ? await this.findInvitationForSignInUp({ currentWorkspace, email, // ← matched against appToken.context.email }) : undefined; ``` So the strategy plumbing is write-only and confusing for readers. Removed from: - [`SocialSSOState`](packages/twenty-server/src/engine/core-modules/auth/types/social-sso-state.type.ts) - `GoogleRequest['user']` and `MicrosoftRequest['user']` - The `state` JSON in both strategies' `authenticate()` - The user object in both strategies' `validate()` No frontend change needed — `useAuth.buildRedirectUrl` still sets the `inviteToken` query param when a personal invite token is present (used by other paths), and nothing on the SSO server side was reading it. The token-based invitation lookup is preserved for the password signup flow via `auth.resolver.signUp` → `findInvitationForSignInUp({ currentWorkspace, workspacePersonalInviteToken })`. Unrelated, untouched. ## Test plan - [x] `npx jest engine/core-modules/auth` (twenty-server) — 26 suites / 178 tests pass. - [x] `tsgo -p tsconfig.json --noEmit` — no new errors on the touched files (pre-existing `IS_REST_METADATA_API_NEW_FORMAT_DIRECT` errors on main are unrelated). - [x] `oxlint` + `prettier --check` on touched files — clean. - [ ] Manual smoke: Google sign-in still works (workspace selection / verify flow unaffected since `workspaceInviteHash`, `workspaceId`, `action`, `locale`, `billingCheckoutSessionState`, `returnToPath` still flow correctly). --- .../core-modules/auth/strategies/google.auth.strategy.ts | 3 --- .../core-modules/auth/strategies/microsoft.auth.strategy.ts | 3 --- .../engine/core-modules/auth/types/social-sso-state.type.ts | 1 - 3 files changed, 7 deletions(-) diff --git a/packages/twenty-server/src/engine/core-modules/auth/strategies/google.auth.strategy.ts b/packages/twenty-server/src/engine/core-modules/auth/strategies/google.auth.strategy.ts index 890df81377..7fb5cda439 100644 --- a/packages/twenty-server/src/engine/core-modules/auth/strategies/google.auth.strategy.ts +++ b/packages/twenty-server/src/engine/core-modules/auth/strategies/google.auth.strategy.ts @@ -29,7 +29,6 @@ export type GoogleRequest = Omit< picture: string | null; locale?: keyof typeof APP_LOCALES | null; workspaceInviteHash?: string; - workspacePersonalInviteToken?: string; action: SocialSSOSignInUpActionType; workspaceId?: string; billingCheckoutSessionState?: string; @@ -57,7 +56,6 @@ export class GoogleStrategy extends PassportStrategy(Strategy, 'google') { workspaceInviteHash: req.query.workspaceInviteHash, workspaceId: req.params.workspaceId, billingCheckoutSessionState: req.query.billingCheckoutSessionState, - workspacePersonalInviteToken: req.query.workspacePersonalInviteToken, action: req.query.action, locale: req.query.locale, returnToPath: req.query.returnToPath, @@ -94,7 +92,6 @@ export class GoogleStrategy extends PassportStrategy(Strategy, 'google') { lastName: name?.familyName, picture: photos?.[0]?.value ?? null, workspaceInviteHash: state?.workspaceInviteHash, - workspacePersonalInviteToken: state?.workspacePersonalInviteToken, workspaceId: state?.workspaceId, billingCheckoutSessionState: state?.billingCheckoutSessionState, action: state?.action ?? 'list-available-workspaces', diff --git a/packages/twenty-server/src/engine/core-modules/auth/strategies/microsoft.auth.strategy.ts b/packages/twenty-server/src/engine/core-modules/auth/strategies/microsoft.auth.strategy.ts index a32f5fb5cc..e11a6c3da7 100644 --- a/packages/twenty-server/src/engine/core-modules/auth/strategies/microsoft.auth.strategy.ts +++ b/packages/twenty-server/src/engine/core-modules/auth/strategies/microsoft.auth.strategy.ts @@ -27,7 +27,6 @@ export type MicrosoftRequest = Omit< picture: string | null; locale?: keyof typeof APP_LOCALES | null; workspaceInviteHash?: string; - workspacePersonalInviteToken?: string; workspaceId?: string; billingCheckoutSessionState?: string; action: SocialSSOSignInUpActionType; @@ -57,7 +56,6 @@ export class MicrosoftStrategy extends PassportStrategy(Strategy, 'microsoft') { workspaceId: req.params.workspaceId, locale: req.query.locale, billingCheckoutSessionState: req.query.billingCheckoutSessionState, - workspacePersonalInviteToken: req.query.workspacePersonalInviteToken, action: req.query.action, returnToPath: req.query.returnToPath, oauthRetryCount: req.query.oauthRetryCount @@ -92,7 +90,6 @@ export class MicrosoftStrategy extends PassportStrategy(Strategy, 'microsoft') { lastName: name?.familyName, picture: photos?.[0]?.value ?? null, workspaceInviteHash: state?.workspaceInviteHash, - workspacePersonalInviteToken: state?.workspacePersonalInviteToken, workspaceId: state?.workspaceId, billingCheckoutSessionState: state?.billingCheckoutSessionState, locale: state?.locale, diff --git a/packages/twenty-server/src/engine/core-modules/auth/types/social-sso-state.type.ts b/packages/twenty-server/src/engine/core-modules/auth/types/social-sso-state.type.ts index 0ba9bef42f..af96fc760c 100644 --- a/packages/twenty-server/src/engine/core-modules/auth/types/social-sso-state.type.ts +++ b/packages/twenty-server/src/engine/core-modules/auth/types/social-sso-state.type.ts @@ -6,7 +6,6 @@ export type SocialSSOState = { workspaceInviteHash?: string; workspaceId?: string; billingCheckoutSessionState?: string; - workspacePersonalInviteToken?: string; action?: SocialSSOSignInUpActionType; locale?: keyof typeof APP_LOCALES; returnToPath?: string;