-
Notifications
You must be signed in to change notification settings - Fork 2.5k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
refacto(*): remove everything about default workspace #9157
base: main
Are you sure you want to change the base?
refacto(*): remove everything about default workspace #9157
Conversation
Replaced `Verify` and `CurrentUserOutput` dto usages with direct use of `AuthTokens` and `User` entities, respectively. Simplified related GraphQL queries, mutations, and services to reflect the updated data model. Enhanced code readability and reduced redundancy by removing unnecessary intermediate representations.
…hing-about-defaultWorkspaceId # Conflicts: # packages/twenty-server/test/integration/metadata/suites/object-metadata/rename-custom-object.integration-spec.ts
Removed `ActivateWorkspaceOutput` in favor of directly returning `Workspace` for cleaner API responses. Consolidated workspace fetching logic into `getWorkspaceByOriginOrDefaultWorkspace` to reduce duplication and improve maintainability. Updated related queries, mutations, and frontend logic to reflect these changes.
TODOs/FIXMEs:
|
Unifies impersonation functionality and feature flag management under a single admin panel component. Replaces the standalone impersonation component and integrates updated GraphQL types and APIs, improving handling of login tokens and workspace redirections.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
PR Summary
This PR implements a significant architectural change by removing the concept of default workspaces and improving workspace activation flows. The changes span across both frontend and backend codebases.
Key changes:
- Removes
defaultWorkspaceId
from User entity and all related references throughout the codebase - Introduces new
ImpersonateGuard
with workspace-specific impersonation requiring both userId and workspaceId - Replaces
defaultWorkspace
withcurrentWorkspace
in user-related components and services - Adds domain manager service with improved workspace lookup and validation
- Simplifies workspace activation flow by removing automatic workspace assignment and login token generation
Potential issues:
- Migration's down function adds NOT NULL constraint without handling existing data
- Some impersonation security checks may be incomplete (workspace-level permissions)
- Removal of OAuthService needs careful testing of authentication flows
72 file(s) reviewed, 29 comment(s)
Edit PR Review Bot Settings | Greptile
packages/twenty-front/src/modules/app/components/SettingsRoutes.tsx
Outdated
Show resolved
Hide resolved
if (!user) { | ||
throw new Error('No current user result'); | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
style: this error should include more context about why the current user result is missing to help with debugging
if (isMultiWorkspaceEnabled) { | ||
return redirectToWorkspaceDomain( | ||
signUpResult.data.signUp.workspace.subdomain, | ||
AppPath.Verify, | ||
{ | ||
loginToken: signUpResult.data.signUp.loginToken.token, | ||
}, | ||
); | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
logic: no error handling for failed workspace domain redirects - should catch and handle redirect failures
if (isDefined(queryData.currentUser.currentWorkspace)) { | ||
setCurrentWorkspace(queryData.currentUser.currentWorkspace); | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
style: consider handling the case where currentWorkspace is undefined - may need to select first available workspace or show workspace selector
if (isDefined(result.errors)) { | ||
throw result.errors ?? new Error('Unknown error'); | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
logic: Error handling logic is incorrect - result.errors check should come before loadCurrentUser() call to prevent executing it when there are errors
await this.workspaceRepository.update(workspace.id, { | ||
activationStatus: WorkspaceActivationStatus.ONGOING_CREATION, | ||
}); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
style: Consider wrapping workspace status updates and initialization in a transaction to ensure atomicity
workspace, | ||
loginToken, | ||
}; | ||
workspaceValidator.assertIsDefinedOrThrow(workspace); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
style: should pass a WorkspaceException like on line 194 to provide better error handling
const request = ctx.getContext().req; | ||
|
||
return request.user.canImpersonate === true; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
logic: Missing null check on request.user could cause runtime error if authentication fails
const ctx = GqlExecutionContext.create(context); | ||
const request = ctx.getContext().req; | ||
|
||
return request.user.canImpersonate === true; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
logic: Should also check workspace.allowImpersonation before allowing impersonation
exceptionToThrowCustom: AuthException = new AuthException( | ||
`${provider} auth is not enabled for this workspace`, | ||
AuthExceptionCode.OAUTH_ACCESS_DENIED, | ||
), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
style: Default exception message includes template literal that could expose internal details. Consider using a static message instead.
Renamed `SettingsAdminFeatureFlags` to `SettingsAdminContent` for clarity and updated associated routes. Enhanced impersonation checks by adding a condition to ensure the workspace allows impersonation. This improves code readability and adds stricter validation for impersonation actions.
Moved SettingsAdminContent to a more appropriate module directory for improved project structure and maintainability. Updated all import paths to reflect the new location.
The guard no longer checks for `workspace.allowImpersonation` as it is unnecessary. Impersonation access is now solely determined by the user's permissions. This simplifies the logic and avoids potential misconfigurations.
Added allowImpersonation property to workspace entities in both front-end and back-end. This enables tracking of whether impersonation is allowed for each workspace in user lookup operations.
Enhance login token generation by including workspace ID, ensuring tokens are tied to specific workspaces. Updated `verifyLoginToken` to validate workspace ID, adding stricter access control. Adjusted all relevant controllers and services to support this feature.
Added support for passing the workspace ID when generating login tokens. This enhances token specificity and aligns with multi-workspace authentication requirements. Adjusted controller and token service to handle the additional parameter.
Removed the defaultWorkspaceId column and its associated constraints from database migrations. Additionally, added an import in workspace.entity.ts to address circular dependency issues.
Added an explanatory comment detailing the specific circular dependency path to improve code readability and maintenance. This change does not affect functionality but aims to assist future developers in understanding the issue
Summary
ImpersonateGuard
User/Workspace