Skip to content

Commit

Permalink
refacto(*): remove everything about default workspace (#9157)
Browse files Browse the repository at this point in the history
## Summary
- [x] Remove defaultWorkspace in user
- [x] Remove all occurrence of defaultWorkspace and defaultWorkspaceId
- [x] Improve activate workspace flow
- [x] Improve security on social login
- [x] Add `ImpersonateGuard`
- [x] Allow to use impersonation with couple `User/Workspace`
- [x] Prevent unexpected reload on activate workspace
- [x] Scope login token with workspaceId 

Fix #9033 (comment)
  • Loading branch information
AMoreaux authored Dec 24, 2024
1 parent fe6948b commit cd2946b
Show file tree
Hide file tree
Showing 78 changed files with 1,146 additions and 1,240 deletions.
4 changes: 3 additions & 1 deletion packages/twenty-front/codegen-metadata.cjs
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
module.exports = {
schema: (process.env.REACT_APP_SERVER_BASE_URL ?? 'http://localhost:3000') + '/metadata',
schema:
(process.env.REACT_APP_SERVER_BASE_URL ?? 'http://localhost:3000') +
'/metadata',
documents: [
'./src/modules/databases/graphql/**/*.ts',
'./src/modules/object-metadata/graphql/*.ts',
Expand Down
4 changes: 3 additions & 1 deletion packages/twenty-front/codegen.cjs
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
module.exports = {
schema: (process.env.REACT_APP_SERVER_BASE_URL ?? 'http://localhost:3000') + '/graphql',
schema:
(process.env.REACT_APP_SERVER_BASE_URL ?? 'http://localhost:3000') +
'/graphql',
documents: [
'!./src/modules/databases/**',
'!./src/modules/object-metadata/**',
Expand Down
30 changes: 5 additions & 25 deletions packages/twenty-front/src/generated-metadata/graphql.ts
Original file line number Diff line number Diff line change
Expand Up @@ -176,6 +176,7 @@ export type ClientConfig = {
__typename?: 'ClientConfig';
analyticsEnabled: Scalars['Boolean']['output'];
api: ApiConfig;
authProviders: AuthProviders;
billing: Billing;
captcha: Captcha;
chromeExtensionId?: Maybe<Scalars['String']['output']>;
Expand Down Expand Up @@ -358,13 +359,6 @@ export type EmailPasswordResetLink = {
success: Scalars['Boolean']['output'];
};

export type ExchangeAuthCode = {
__typename?: 'ExchangeAuthCode';
accessToken: AuthToken;
loginToken: AuthToken;
refreshToken: AuthToken;
};

export type ExecuteServerlessFunctionInput = {
/** Id of the serverless function to execute */
id: Scalars['UUID']['input'];
Expand Down Expand Up @@ -581,12 +575,11 @@ export type Mutation = {
editSSOIdentityProvider: EditSsoOutput;
emailPasswordResetLink: EmailPasswordResetLink;
enablePostgresProxy: PostgresCredentials;
exchangeAuthorizationCode: ExchangeAuthCode;
executeOneServerlessFunction: ServerlessFunctionExecutionResult;
generateApiKeyToken: ApiKeyToken;
generateTransientToken: TransientToken;
getAuthorizationUrl: GetAuthorizationUrlOutput;
impersonate: Verify;
impersonate: AuthTokens;
publishServerlessFunction: ServerlessFunction;
renewToken: AuthTokens;
resendWorkspaceInvitation: SendInvitationsOutput;
Expand All @@ -613,7 +606,7 @@ export type Mutation = {
uploadProfilePicture: Scalars['String']['output'];
uploadWorkspaceLogo: Scalars['String']['output'];
userLookupAdminPanel: UserLookup;
verify: Verify;
verify: AuthTokens;
};


Expand Down Expand Up @@ -762,13 +755,6 @@ export type MutationEmailPasswordResetLinkArgs = {
};


export type MutationExchangeAuthorizationCodeArgs = {
authorizationCode: Scalars['String']['input'];
clientSecret?: InputMaybe<Scalars['String']['input']>;
codeVerifier?: InputMaybe<Scalars['String']['input']>;
};


export type MutationExecuteOneServerlessFunctionArgs = {
input: ExecuteServerlessFunctionInput;
};
Expand All @@ -787,6 +773,7 @@ export type MutationGetAuthorizationUrlArgs = {

export type MutationImpersonateArgs = {
userId: Scalars['String']['input'];
workspaceId: Scalars['String']['input'];
};


Expand Down Expand Up @@ -1593,9 +1580,8 @@ export type User = {
analyticsTinybirdJwts?: Maybe<AnalyticsTinybirdJwtMap>;
canImpersonate: Scalars['Boolean']['output'];
createdAt: Scalars['DateTime']['output'];
currentWorkspace?: Maybe<Workspace>;
defaultAvatarUrl?: Maybe<Scalars['String']['output']>;
defaultWorkspace: Workspace;
defaultWorkspaceId: Scalars['String']['output'];
deletedAt?: Maybe<Scalars['DateTime']['output']>;
disabled?: Maybe<Scalars['Boolean']['output']>;
email: Scalars['String']['output'];
Expand Down Expand Up @@ -1681,12 +1667,6 @@ export type ValidatePasswordResetToken = {
id: Scalars['String']['output'];
};

export type Verify = {
__typename?: 'Verify';
tokens: AuthTokenPair;
user: User;
};

export type WorkflowAction = {
__typename?: 'WorkflowAction';
id: Scalars['UUID']['output'];
Expand Down
118 changes: 53 additions & 65 deletions packages/twenty-front/src/generated/graphql.tsx

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
Expand Up @@ -254,10 +254,10 @@ const SettingsAdmin = lazy(() =>
})),
);

const SettingsAdminFeatureFlags = lazy(() =>
import('~/pages/settings/admin-panel/SettingsAdminFeatureFlags').then(
const SettingsAdminContent = lazy(() =>
import('@/settings/admin-panel/components/SettingsAdminContent').then(
(module) => ({
default: module.SettingsAdminFeatureFlags,
default: module.SettingsAdminContent,
}),
),
);
Expand Down Expand Up @@ -402,7 +402,7 @@ export const SettingsRoutes = ({
<Route path={SettingsPath.AdminPanel} element={<SettingsAdmin />} />
<Route
path={SettingsPath.FeatureFlags}
element={<SettingsAdminFeatureFlags />}
element={<SettingsAdminContent />}
/>
</>
)}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,14 @@ import { gql } from '@apollo/client';

// TODO: Fragments should be used instead of duplicating the user fields !
export const IMPERSONATE = gql`
mutation Impersonate($userId: String!) {
impersonate(userId: $userId) {
user {
...UserQueryFragment
mutation Impersonate($userId: String!, $workspaceId: String!) {
impersonate(userId: $userId, workspaceId: $workspaceId) {
workspace {
subdomain
id
}
tokens {
...AuthTokensFragment
loginToken {
...AuthTokenFragment
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,10 @@ export const SIGN_UP = gql`
loginToken {
...AuthTokenFragment
}
workspace {
id
subdomain
}
}
}
`;
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,6 @@ import { gql } from '@apollo/client';
export const VERIFY = gql`
mutation Verify($loginToken: String!) {
verify(loginToken: $loginToken) {
user {
...UserQueryFragment
}
tokens {
...AuthTokensFragment
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ export const CHECK_USER_EXISTS = gql`
__typename
... on UserExists {
exists
defaultWorkspaceId
availableWorkspaces {
id
displayName
Expand Down
29 changes: 21 additions & 8 deletions packages/twenty-front/src/modules/auth/hooks/__mocks__/useAuth.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import {
ChallengeDocument,
GetCurrentUserDocument,
SignUpDocument,
VerifyDocument,
} from '~/generated/graphql';
Expand All @@ -8,6 +9,7 @@ export const queries = {
challenge: ChallengeDocument,
verify: VerifyDocument,
signup: SignUpDocument,
getCurrentUser: GetCurrentUserDocument,
};

export const email = '[email protected]';
Expand All @@ -22,6 +24,7 @@ export const variables = {
},
verify: { loginToken: token },
signup: {},
getCurrentUser: {},
};

export const results = {
Expand All @@ -32,7 +35,14 @@ export const results = {
},
},
verify: {
user: {
tokens: {
accessToken: { token, expiresAt: 'expiresAt' },
refreshToken: { token, expiresAt: 'expiresAt' },
},
},
signUp: { loginToken: { token, expiresAt: 'expiresAt' } },
getCurrentUser: {
currentUser: {
id: 'id',
firstName: 'firstName',
lastName: 'lastName',
Expand All @@ -49,7 +59,7 @@ export const results = {
avatarUrl: 'avatarUrl',
locale: 'locale',
},
defaultWorkspace: {
currentWorkspace: {
id: 'id',
displayName: 'displayName',
logo: 'logo',
Expand All @@ -65,13 +75,7 @@ export const results = {
},
},
},
tokens: {
accessToken: { token, expiresAt: 'expiresAt' },
refreshToken: { token, expiresAt: 'expiresAt' },
},
signup: {},
},
signUp: { loginToken: { token, expiresAt: 'expiresAt' } },
};

export const mocks = [
Expand Down Expand Up @@ -108,4 +112,13 @@ export const mocks = [
},
})),
},
{
request: {
query: queries.getCurrentUser,
variables: variables.getCurrentUser,
},
result: jest.fn(() => ({
data: results.getCurrentUser,
})),
},
];
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
import { useApolloClient } from '@apollo/client';
import { MockedProvider } from '@apollo/client/testing';
import { expect } from '@storybook/test';
import { act, renderHook } from '@testing-library/react';
import { ReactNode } from 'react';
import { ReactNode, act } from 'react';
import { RecoilRoot, useRecoilValue } from 'recoil';
import { iconsState } from 'twenty-ui';

Expand All @@ -15,6 +14,7 @@ import { workspaceAuthProvidersState } from '@/workspace/states/workspaceAuthPro

import { isMultiWorkspaceEnabledState } from '@/client-config/states/isMultiWorkspaceEnabledState';
import { email, mocks, password, results, token } from '../__mocks__/useAuth';
import { renderHook } from '@testing-library/react';

const Wrapper = ({ children }: { children: ReactNode }) => (
<MockedProvider mocks={mocks} addTypename={false}>
Expand Down Expand Up @@ -59,6 +59,7 @@ describe('useAuth', () => {
});

expect(mocks[1].result).toHaveBeenCalled();
expect(mocks[3].result).toHaveBeenCalled();
});

it('should handle credential sign-in', async () => {
Expand Down
Loading

0 comments on commit cd2946b

Please sign in to comment.