From 8de85eea613230a773c84e7ed433cc69a7e9f349 Mon Sep 17 00:00:00 2001 From: Antoine Moreaux Date: Fri, 23 May 2025 18:01:36 +0200 Subject: [PATCH] fix(): remove originHeader decorator (#12245) Fix https://github.com/twentyhq/core-team-issues/issues/858#issuecomment-2891213392 Fix #11966 Fix #12175 --- packages/twenty-front/codegen-metadata.cjs | 2 + packages/twenty-front/codegen.cjs | 2 + .../src/generated-metadata/graphql.ts | 9 ++++ .../twenty-front/src/generated/graphql.tsx | 42 ++++++++++++++----- .../mutations/getAuthTokensFromLoginToken.ts | 4 +- .../mutations/getLoginTokenFromCredentials.ts | 2 + ...getLoginTokenFromEmailVerificationToken.ts | 2 + .../mutations/resendEmailVerificationToken.ts | 4 +- .../queries/getPublicWorkspaceDataByDomain.ts | 4 +- .../modules/auth/hooks/__mocks__/useAuth.ts | 4 +- .../src/modules/auth/hooks/useAuth.ts | 14 +++++-- .../useHandleResendEmailVerificationToken.ts | 9 +++- .../useGetPublicWorkspaceDataByDomain.ts | 5 +++ .../modules/domain-manager/hooks/useOrigin.ts | 7 ++++ .../engine/core-modules/auth/auth.resolver.ts | 7 ++-- .../email-verification.resolver.ts | 3 +- .../engine/core-modules/user/user.resolver.ts | 11 +---- .../workspace/workspace.resolver.ts | 14 ++----- .../auth/origin-header.decorator.ts | 11 ----- .../graphql/suites/auth.integration-spec.ts | 4 +- 20 files changed, 98 insertions(+), 62 deletions(-) create mode 100644 packages/twenty-front/src/modules/domain-manager/hooks/useOrigin.ts delete mode 100644 packages/twenty-server/src/engine/decorators/auth/origin-header.decorator.ts diff --git a/packages/twenty-front/codegen-metadata.cjs b/packages/twenty-front/codegen-metadata.cjs index 53429715c..9f3aeb4bf 100644 --- a/packages/twenty-front/codegen-metadata.cjs +++ b/packages/twenty-front/codegen-metadata.cjs @@ -1,3 +1,5 @@ +process.env.NODE_TLS_REJECT_UNAUTHORIZED = '0'; + module.exports = { schema: (process.env.REACT_APP_SERVER_BASE_URL ?? 'http://localhost:3000') + diff --git a/packages/twenty-front/codegen.cjs b/packages/twenty-front/codegen.cjs index f24c09648..1c2ecc86e 100644 --- a/packages/twenty-front/codegen.cjs +++ b/packages/twenty-front/codegen.cjs @@ -1,3 +1,5 @@ +process.env.NODE_TLS_REJECT_UNAUTHORIZED = '0'; + module.exports = { schema: (process.env.REACT_APP_SERVER_BASE_URL ?? 'http://localhost:3000') + diff --git a/packages/twenty-front/src/generated-metadata/graphql.ts b/packages/twenty-front/src/generated-metadata/graphql.ts index 73dc89395..d089ceeed 100644 --- a/packages/twenty-front/src/generated-metadata/graphql.ts +++ b/packages/twenty-front/src/generated-metadata/graphql.ts @@ -1235,6 +1235,7 @@ export type MutationGenerateApiKeyTokenArgs = { export type MutationGetAuthTokensFromLoginTokenArgs = { loginToken: Scalars['String']['input']; + origin: Scalars['String']['input']; }; @@ -1246,6 +1247,7 @@ export type MutationGetAuthorizationUrlForSsoArgs = { export type MutationGetLoginTokenFromCredentialsArgs = { captchaToken?: InputMaybe; email: Scalars['String']['input']; + origin: Scalars['String']['input']; password: Scalars['String']['input']; }; @@ -1253,6 +1255,7 @@ export type MutationGetLoginTokenFromCredentialsArgs = { export type MutationGetLoginTokenFromEmailVerificationTokenArgs = { captchaToken?: InputMaybe; emailVerificationToken: Scalars['String']['input']; + origin: Scalars['String']['input']; }; @@ -1274,6 +1277,7 @@ export type MutationRenewTokenArgs = { export type MutationResendEmailVerificationTokenArgs = { email: Scalars['String']['input']; + origin: Scalars['String']['input']; }; @@ -1761,6 +1765,11 @@ export type QueryGetIndicatorHealthStatusArgs = { }; +export type QueryGetPublicWorkspaceDataByDomainArgs = { + origin: Scalars['String']['input']; +}; + + export type QueryGetQueueMetricsArgs = { queueName: Scalars['String']['input']; timeRange?: InputMaybe; diff --git a/packages/twenty-front/src/generated/graphql.tsx b/packages/twenty-front/src/generated/graphql.tsx index 893f5c9a8..b60ca9fa0 100644 --- a/packages/twenty-front/src/generated/graphql.tsx +++ b/packages/twenty-front/src/generated/graphql.tsx @@ -1110,6 +1110,7 @@ export type MutationGenerateApiKeyTokenArgs = { export type MutationGetAuthTokensFromLoginTokenArgs = { loginToken: Scalars['String']; + origin: Scalars['String']; }; @@ -1121,6 +1122,7 @@ export type MutationGetAuthorizationUrlForSsoArgs = { export type MutationGetLoginTokenFromCredentialsArgs = { captchaToken?: InputMaybe; email: Scalars['String']; + origin: Scalars['String']; password: Scalars['String']; }; @@ -1128,6 +1130,7 @@ export type MutationGetLoginTokenFromCredentialsArgs = { export type MutationGetLoginTokenFromEmailVerificationTokenArgs = { captchaToken?: InputMaybe; emailVerificationToken: Scalars['String']; + origin: Scalars['String']; }; @@ -1149,6 +1152,7 @@ export type MutationRenewTokenArgs = { export type MutationResendEmailVerificationTokenArgs = { email: Scalars['String']; + origin: Scalars['String']; }; @@ -1586,6 +1590,11 @@ export type QueryGetIndicatorHealthStatusArgs = { }; +export type QueryGetPublicWorkspaceDataByDomainArgs = { + origin: Scalars['String']; +}; + + export type QueryGetQueueMetricsArgs = { queueName: Scalars['String']; timeRange?: InputMaybe; @@ -2592,6 +2601,7 @@ export type GenerateTransientTokenMutation = { __typename?: 'Mutation', generate export type GetAuthTokensFromLoginTokenMutationVariables = Exact<{ loginToken: Scalars['String']; + origin: Scalars['String']; }>; @@ -2608,6 +2618,7 @@ export type GetLoginTokenFromCredentialsMutationVariables = Exact<{ email: Scalars['String']; password: Scalars['String']; captchaToken?: InputMaybe; + origin: Scalars['String']; }>; @@ -2616,6 +2627,7 @@ export type GetLoginTokenFromCredentialsMutation = { __typename?: 'Mutation', ge export type GetLoginTokenFromEmailVerificationTokenMutationVariables = Exact<{ emailVerificationToken: Scalars['String']; captchaToken?: InputMaybe; + origin: Scalars['String']; }>; @@ -2638,6 +2650,7 @@ export type RenewTokenMutation = { __typename?: 'Mutation', renewToken: { __type export type ResendEmailVerificationTokenMutationVariables = Exact<{ email: Scalars['String']; + origin: Scalars['String']; }>; @@ -2677,7 +2690,9 @@ export type CheckUserExistsQueryVariables = Exact<{ export type CheckUserExistsQuery = { __typename?: 'Query', checkUserExists: { __typename: 'UserExists', exists: boolean, isEmailVerified: boolean, availableWorkspaces: Array<{ __typename?: 'AvailableWorkspaceOutput', id: string, displayName?: string | null, logo?: string | null, workspaceUrls: { __typename?: 'WorkspaceUrls', subdomainUrl: string, customUrl?: string | null }, sso: Array<{ __typename?: 'SSOConnection', type: IdentityProviderType, id: string, issuer: string, name: string, status: SsoIdentityProviderStatus }> }> } | { __typename: 'UserNotExists', exists: boolean } }; -export type GetPublicWorkspaceDataByDomainQueryVariables = Exact<{ [key: string]: never; }>; +export type GetPublicWorkspaceDataByDomainQueryVariables = Exact<{ + origin: Scalars['String']; +}>; export type GetPublicWorkspaceDataByDomainQuery = { __typename?: 'Query', getPublicWorkspaceDataByDomain: { __typename?: 'PublicWorkspaceDataOutput', id: string, logo?: string | null, displayName?: string | null, workspaceUrls: { __typename?: 'WorkspaceUrls', subdomainUrl: string, customUrl?: string | null }, authProviders: { __typename?: 'AuthProviders', google: boolean, magicLink: boolean, password: boolean, microsoft: boolean, sso: Array<{ __typename?: 'SSOIdentityProvider', id: string, name: string, type: IdentityProviderType, status: SsoIdentityProviderStatus, issuer: string }> } } }; @@ -3756,8 +3771,8 @@ export type GenerateTransientTokenMutationHookResult = ReturnType; export type GenerateTransientTokenMutationOptions = Apollo.BaseMutationOptions; export const GetAuthTokensFromLoginTokenDocument = gql` - mutation GetAuthTokensFromLoginToken($loginToken: String!) { - getAuthTokensFromLoginToken(loginToken: $loginToken) { + mutation GetAuthTokensFromLoginToken($loginToken: String!, $origin: String!) { + getAuthTokensFromLoginToken(loginToken: $loginToken, origin: $origin) { tokens { ...AuthTokensFragment } @@ -3780,6 +3795,7 @@ export type GetAuthTokensFromLoginTokenMutationFn = Apollo.MutationFunction; export type GetAuthorizationUrlForSsoMutationOptions = Apollo.BaseMutationOptions; export const GetLoginTokenFromCredentialsDocument = gql` - mutation GetLoginTokenFromCredentials($email: String!, $password: String!, $captchaToken: String) { + mutation GetLoginTokenFromCredentials($email: String!, $password: String!, $captchaToken: String, $origin: String!) { getLoginTokenFromCredentials( email: $email password: $password captchaToken: $captchaToken + origin: $origin ) { loginToken { ...AuthTokenFragment @@ -3856,6 +3873,7 @@ export type GetLoginTokenFromCredentialsMutationFn = Apollo.MutationFunction; export type GetLoginTokenFromCredentialsMutationOptions = Apollo.BaseMutationOptions; export const GetLoginTokenFromEmailVerificationTokenDocument = gql` - mutation GetLoginTokenFromEmailVerificationToken($emailVerificationToken: String!, $captchaToken: String) { + mutation GetLoginTokenFromEmailVerificationToken($emailVerificationToken: String!, $captchaToken: String, $origin: String!) { getLoginTokenFromEmailVerificationToken( emailVerificationToken: $emailVerificationToken captchaToken: $captchaToken + origin: $origin ) { loginToken { ...AuthTokenFragment @@ -3899,6 +3918,7 @@ export type GetLoginTokenFromEmailVerificationTokenMutationFn = Apollo.MutationF * variables: { * emailVerificationToken: // value for 'emailVerificationToken' * captchaToken: // value for 'captchaToken' + * origin: // value for 'origin' * }, * }); */ @@ -3988,8 +4008,8 @@ export type RenewTokenMutationHookResult = ReturnType; export type RenewTokenMutationOptions = Apollo.BaseMutationOptions; export const ResendEmailVerificationTokenDocument = gql` - mutation ResendEmailVerificationToken($email: String!) { - resendEmailVerificationToken(email: $email) { + mutation ResendEmailVerificationToken($email: String!, $origin: String!) { + resendEmailVerificationToken(email: $email, origin: $origin) { success } } @@ -4010,6 +4030,7 @@ export type ResendEmailVerificationTokenMutationFn = Apollo.MutationFunction; export type CheckUserExistsQueryResult = Apollo.QueryResult; export const GetPublicWorkspaceDataByDomainDocument = gql` - query GetPublicWorkspaceDataByDomain { - getPublicWorkspaceDataByDomain { + query GetPublicWorkspaceDataByDomain($origin: String!) { + getPublicWorkspaceDataByDomain(origin: $origin) { id logo displayName @@ -4252,10 +4273,11 @@ export const GetPublicWorkspaceDataByDomainDocument = gql` * @example * const { data, loading, error } = useGetPublicWorkspaceDataByDomainQuery({ * variables: { + * origin: // value for 'origin' * }, * }); */ -export function useGetPublicWorkspaceDataByDomainQuery(baseOptions?: Apollo.QueryHookOptions) { +export function useGetPublicWorkspaceDataByDomainQuery(baseOptions: Apollo.QueryHookOptions) { const options = {...defaultOptions, ...baseOptions} return Apollo.useQuery(GetPublicWorkspaceDataByDomainDocument, options); } diff --git a/packages/twenty-front/src/modules/auth/graphql/mutations/getAuthTokensFromLoginToken.ts b/packages/twenty-front/src/modules/auth/graphql/mutations/getAuthTokensFromLoginToken.ts index 7ea0270c7..8d01b4615 100644 --- a/packages/twenty-front/src/modules/auth/graphql/mutations/getAuthTokensFromLoginToken.ts +++ b/packages/twenty-front/src/modules/auth/graphql/mutations/getAuthTokensFromLoginToken.ts @@ -1,8 +1,8 @@ import { gql } from '@apollo/client'; export const GET_AUTH_TOKENS_FROM_LOGIN_TOKEN = gql` - mutation GetAuthTokensFromLoginToken($loginToken: String!) { - getAuthTokensFromLoginToken(loginToken: $loginToken) { + mutation GetAuthTokensFromLoginToken($loginToken: String!, $origin: String!) { + getAuthTokensFromLoginToken(loginToken: $loginToken, origin: $origin) { tokens { ...AuthTokensFragment } diff --git a/packages/twenty-front/src/modules/auth/graphql/mutations/getLoginTokenFromCredentials.ts b/packages/twenty-front/src/modules/auth/graphql/mutations/getLoginTokenFromCredentials.ts index 2bf0316b0..51781eb64 100644 --- a/packages/twenty-front/src/modules/auth/graphql/mutations/getLoginTokenFromCredentials.ts +++ b/packages/twenty-front/src/modules/auth/graphql/mutations/getLoginTokenFromCredentials.ts @@ -5,11 +5,13 @@ export const GET_LOGIN_TOKEN_FROM_CREDENTIALS = gql` $email: String! $password: String! $captchaToken: String + $origin: String! ) { getLoginTokenFromCredentials( email: $email password: $password captchaToken: $captchaToken + origin: $origin ) { loginToken { ...AuthTokenFragment diff --git a/packages/twenty-front/src/modules/auth/graphql/mutations/getLoginTokenFromEmailVerificationToken.ts b/packages/twenty-front/src/modules/auth/graphql/mutations/getLoginTokenFromEmailVerificationToken.ts index 028493638..a3a4f2e2e 100644 --- a/packages/twenty-front/src/modules/auth/graphql/mutations/getLoginTokenFromEmailVerificationToken.ts +++ b/packages/twenty-front/src/modules/auth/graphql/mutations/getLoginTokenFromEmailVerificationToken.ts @@ -4,10 +4,12 @@ export const GET_LOGIN_TOKEN_FROM_EMAIL_VERIFICATION_TOKEN = gql` mutation GetLoginTokenFromEmailVerificationToken( $emailVerificationToken: String! $captchaToken: String + $origin: String! ) { getLoginTokenFromEmailVerificationToken( emailVerificationToken: $emailVerificationToken captchaToken: $captchaToken + origin: $origin ) { loginToken { ...AuthTokenFragment diff --git a/packages/twenty-front/src/modules/auth/graphql/mutations/resendEmailVerificationToken.ts b/packages/twenty-front/src/modules/auth/graphql/mutations/resendEmailVerificationToken.ts index 7040fd2e2..50315ca3e 100644 --- a/packages/twenty-front/src/modules/auth/graphql/mutations/resendEmailVerificationToken.ts +++ b/packages/twenty-front/src/modules/auth/graphql/mutations/resendEmailVerificationToken.ts @@ -1,8 +1,8 @@ import { gql } from '@apollo/client'; export const RESEND_EMAIL_VERIFICATION_TOKEN = gql` - mutation ResendEmailVerificationToken($email: String!) { - resendEmailVerificationToken(email: $email) { + mutation ResendEmailVerificationToken($email: String!, $origin: String!) { + resendEmailVerificationToken(email: $email, origin: $origin) { success } } diff --git a/packages/twenty-front/src/modules/auth/graphql/queries/getPublicWorkspaceDataByDomain.ts b/packages/twenty-front/src/modules/auth/graphql/queries/getPublicWorkspaceDataByDomain.ts index 986c4f59e..b499f432d 100644 --- a/packages/twenty-front/src/modules/auth/graphql/queries/getPublicWorkspaceDataByDomain.ts +++ b/packages/twenty-front/src/modules/auth/graphql/queries/getPublicWorkspaceDataByDomain.ts @@ -1,8 +1,8 @@ import { gql } from '@apollo/client'; export const GET_PUBLIC_WORKSPACE_DATA_BY_DOMAIN = gql` - query GetPublicWorkspaceDataByDomain { - getPublicWorkspaceDataByDomain { + query GetPublicWorkspaceDataByDomain($origin: String!) { + getPublicWorkspaceDataByDomain(origin: $origin) { id logo displayName diff --git a/packages/twenty-front/src/modules/auth/hooks/__mocks__/useAuth.ts b/packages/twenty-front/src/modules/auth/hooks/__mocks__/useAuth.ts index 4407c9ac3..ff3d0f344 100644 --- a/packages/twenty-front/src/modules/auth/hooks/__mocks__/useAuth.ts +++ b/packages/twenty-front/src/modules/auth/hooks/__mocks__/useAuth.ts @@ -14,6 +14,7 @@ export const queries = { export const email = 'test@test.com'; export const password = 'testing'; +export const origin = 'http://localhost'; export const token = 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c'; @@ -21,8 +22,9 @@ export const variables = { getLoginTokenFromCredentials: { email, password, + origin, }, - getAuthTokensFromLoginToken: { loginToken: token }, + getAuthTokensFromLoginToken: { loginToken: token, origin }, signup: { email, password, diff --git a/packages/twenty-front/src/modules/auth/hooks/useAuth.ts b/packages/twenty-front/src/modules/auth/hooks/useAuth.ts index b841b01c0..4ffc49c5a 100644 --- a/packages/twenty-front/src/modules/auth/hooks/useAuth.ts +++ b/packages/twenty-front/src/modules/auth/hooks/useAuth.ts @@ -53,6 +53,7 @@ import { isEmailVerificationRequiredState } from '@/client-config/states/isEmail import { isMultiWorkspaceEnabledState } from '@/client-config/states/isMultiWorkspaceEnabledState'; import { useIsCurrentLocationOnAWorkspace } from '@/domain-manager/hooks/useIsCurrentLocationOnAWorkspace'; import { useLastAuthenticatedWorkspaceDomain } from '@/domain-manager/hooks/useLastAuthenticatedWorkspaceDomain'; +import { useOrigin } from '@/domain-manager/hooks/useOrigin'; import { useRedirect } from '@/domain-manager/hooks/useRedirect'; import { useRedirectToWorkspaceDomain } from '@/domain-manager/hooks/useRedirectToWorkspaceDomain'; import { domainConfigurationState } from '@/domain-manager/states/domainConfigurationState'; @@ -74,6 +75,7 @@ export const useAuth = () => { currentWorkspaceMemberState, ); const setCurrentUserWorkspace = useSetRecoilState(currentUserWorkspaceState); + const { origin } = useOrigin(); const setCurrentWorkspaceMembers = useSetRecoilState( currentWorkspaceMembersState, @@ -179,6 +181,7 @@ export const useAuth = () => { email, password, captchaToken, + origin, }, }); if (isDefined(getLoginTokenResult.errors)) { @@ -203,7 +206,7 @@ export const useAuth = () => { throw error; } }, - [getLoginTokenFromCredentials, setSearchParams, setSignInUpStep], + [getLoginTokenFromCredentials, setSearchParams, setSignInUpStep, origin], ); const handleGetLoginTokenFromEmailVerificationToken = useCallback( @@ -212,6 +215,7 @@ export const useAuth = () => { variables: { emailVerificationToken, captchaToken, + origin, }, }); @@ -225,7 +229,7 @@ export const useAuth = () => { return loginTokenResult.data.getLoginTokenFromEmailVerificationToken; }, - [getLoginTokenFromEmailVerificationToken], + [getLoginTokenFromEmailVerificationToken, origin], ); const loadCurrentUser = useCallback(async () => { @@ -335,7 +339,10 @@ export const useAuth = () => { const handleGetAuthTokensFromLoginToken = useCallback( async (loginToken: string) => { const getAuthTokensResult = await getAuthTokensFromLoginToken({ - variables: { loginToken }, + variables: { + loginToken, + origin, + }, }); if (isDefined(getAuthTokensResult.errors)) { @@ -364,6 +371,7 @@ export const useAuth = () => { setTokenPair, refreshObjectMetadataItems, loadCurrentUser, + origin, ], ); diff --git a/packages/twenty-front/src/modules/auth/sign-in-up/hooks/useHandleResendEmailVerificationToken.ts b/packages/twenty-front/src/modules/auth/sign-in-up/hooks/useHandleResendEmailVerificationToken.ts index 8051552c0..6b50d85ec 100644 --- a/packages/twenty-front/src/modules/auth/sign-in-up/hooks/useHandleResendEmailVerificationToken.ts +++ b/packages/twenty-front/src/modules/auth/sign-in-up/hooks/useHandleResendEmailVerificationToken.ts @@ -1,5 +1,6 @@ import { useCallback } from 'react'; +import { useOrigin } from '@/domain-manager/hooks/useOrigin'; import { SnackBarVariant } from '@/ui/feedback/snack-bar-manager/components/SnackBar'; import { useSnackBar } from '@/ui/feedback/snack-bar-manager/hooks/useSnackBar'; import { t } from '@lingui/core/macro'; @@ -9,6 +10,7 @@ export const useHandleResendEmailVerificationToken = () => { const { enqueueSnackBar } = useSnackBar(); const [resendEmailVerificationToken, { loading }] = useResendEmailVerificationTokenMutation(); + const { origin } = useOrigin(); const handleResendEmailVerificationToken = useCallback( (email: string | null) => { @@ -22,7 +24,10 @@ export const useHandleResendEmailVerificationToken = () => { try { const { data } = await resendEmailVerificationToken({ - variables: { email }, + variables: { + email, + origin, + }, }); if (data?.resendEmailVerificationToken?.success === true) { @@ -41,7 +46,7 @@ export const useHandleResendEmailVerificationToken = () => { } }; }, - [enqueueSnackBar, resendEmailVerificationToken], + [enqueueSnackBar, resendEmailVerificationToken, origin], ); return { handleResendEmailVerificationToken, loading }; diff --git a/packages/twenty-front/src/modules/domain-manager/hooks/useGetPublicWorkspaceDataByDomain.ts b/packages/twenty-front/src/modules/domain-manager/hooks/useGetPublicWorkspaceDataByDomain.ts index c5caecb90..b543d3ebe 100644 --- a/packages/twenty-front/src/modules/domain-manager/hooks/useGetPublicWorkspaceDataByDomain.ts +++ b/packages/twenty-front/src/modules/domain-manager/hooks/useGetPublicWorkspaceDataByDomain.ts @@ -1,6 +1,7 @@ import { workspacePublicDataState } from '@/auth/states/workspacePublicDataState'; import { isMultiWorkspaceEnabledState } from '@/client-config/states/isMultiWorkspaceEnabledState'; import { useIsCurrentLocationOnDefaultDomain } from '@/domain-manager/hooks/useIsCurrentLocationOnDefaultDomain'; +import { useOrigin } from '@/domain-manager/hooks/useOrigin'; import { useRedirectToDefaultDomain } from '@/domain-manager/hooks/useRedirectToDefaultDomain'; import { workspaceAuthProvidersState } from '@/workspace/states/workspaceAuthProvidersState'; import { useRecoilValue, useSetRecoilState } from 'recoil'; @@ -10,6 +11,7 @@ import { isDefined } from 'twenty-shared/utils'; export const useGetPublicWorkspaceDataByDomain = () => { const { isDefaultDomain } = useIsCurrentLocationOnDefaultDomain(); const isMultiWorkspaceEnabled = useRecoilValue(isMultiWorkspaceEnabledState); + const { origin } = useOrigin(); const setWorkspaceAuthProviders = useSetRecoilState( workspaceAuthProvidersState, ); @@ -20,6 +22,9 @@ export const useGetPublicWorkspaceDataByDomain = () => { ); const { loading, data, error } = useGetPublicWorkspaceDataByDomainQuery({ + variables: { + origin, + }, skip: (isMultiWorkspaceEnabled && isDefaultDomain) || isDefined(workspacePublicData), diff --git a/packages/twenty-front/src/modules/domain-manager/hooks/useOrigin.ts b/packages/twenty-front/src/modules/domain-manager/hooks/useOrigin.ts new file mode 100644 index 000000000..b646d28bb --- /dev/null +++ b/packages/twenty-front/src/modules/domain-manager/hooks/useOrigin.ts @@ -0,0 +1,7 @@ +import { useMemo } from 'react'; + +export const useOrigin = () => { + const origin = useMemo(() => window.location.origin, []); + + return { origin }; +}; diff --git a/packages/twenty-server/src/engine/core-modules/auth/auth.resolver.ts b/packages/twenty-server/src/engine/core-modules/auth/auth.resolver.ts index 2d2e71965..0831dbd3d 100644 --- a/packages/twenty-server/src/engine/core-modules/auth/auth.resolver.ts +++ b/packages/twenty-server/src/engine/core-modules/auth/auth.resolver.ts @@ -48,7 +48,6 @@ import { Workspace } from 'src/engine/core-modules/workspace/workspace.entity'; import { workspaceValidator } from 'src/engine/core-modules/workspace/workspace.validate'; import { AuthUser } from 'src/engine/decorators/auth/auth-user.decorator'; import { AuthWorkspace } from 'src/engine/decorators/auth/auth-workspace.decorator'; -import { OriginHeader } from 'src/engine/decorators/auth/origin-header.decorator'; import { SettingsPermissionsGuard } from 'src/engine/guards/settings-permissions.guard'; import { UserAuthGuard } from 'src/engine/guards/user-auth.guard'; import { WorkspaceAuthGuard } from 'src/engine/guards/workspace-auth.guard'; @@ -135,7 +134,7 @@ export class AuthResolver { async getLoginTokenFromCredentials( @Args() getLoginTokenFromCredentialsInput: GetLoginTokenFromCredentialsInput, - @OriginHeader() origin: string, + @Args('origin') origin: string, ): Promise { const workspace = await this.domainManagerService.getWorkspaceByOriginOrDefaultWorkspace( @@ -167,7 +166,7 @@ export class AuthResolver { async getLoginTokenFromEmailVerificationToken( @Args() getLoginTokenFromEmailVerificationTokenInput: GetLoginTokenFromEmailVerificationTokenInput, - @OriginHeader() origin: string, + @Args('origin') origin: string, ) { const user = await this.emailVerificationTokenService.validateEmailVerificationTokenOrThrow( @@ -320,7 +319,7 @@ export class AuthResolver { @Mutation(() => AuthTokens) async getAuthTokensFromLoginToken( @Args() getAuthTokensFromLoginTokenInput: GetAuthTokensFromLoginTokenInput, - @OriginHeader() origin: string, + @Args('origin') origin: string, ): Promise { const workspace = await this.domainManagerService.getWorkspaceByOriginOrDefaultWorkspace( diff --git a/packages/twenty-server/src/engine/core-modules/email-verification/email-verification.resolver.ts b/packages/twenty-server/src/engine/core-modules/email-verification/email-verification.resolver.ts index 5509d3d3b..5f08b1168 100644 --- a/packages/twenty-server/src/engine/core-modules/email-verification/email-verification.resolver.ts +++ b/packages/twenty-server/src/engine/core-modules/email-verification/email-verification.resolver.ts @@ -9,7 +9,6 @@ import { ResendEmailVerificationTokenOutput } from 'src/engine/core-modules/emai import { EmailVerificationExceptionFilter } from 'src/engine/core-modules/email-verification/email-verification-exception-filter.util'; import { EmailVerificationService } from 'src/engine/core-modules/email-verification/services/email-verification.service'; import { I18nContext } from 'src/engine/core-modules/i18n/types/i18n-context.type'; -import { OriginHeader } from 'src/engine/decorators/auth/origin-header.decorator'; @Resolver() @UseFilters(EmailVerificationExceptionFilter) @@ -23,7 +22,7 @@ export class EmailVerificationResolver { async resendEmailVerificationToken( @Args() resendEmailVerificationTokenInput: ResendEmailVerificationTokenInput, - @OriginHeader() origin: string, + @Args('origin') origin: string, @Context() context: I18nContext, ): Promise { const workspace = diff --git a/packages/twenty-server/src/engine/core-modules/user/user.resolver.ts b/packages/twenty-server/src/engine/core-modules/user/user.resolver.ts index 2e865cd71..3783a778d 100644 --- a/packages/twenty-server/src/engine/core-modules/user/user.resolver.ts +++ b/packages/twenty-server/src/engine/core-modules/user/user.resolver.ts @@ -42,10 +42,8 @@ import { UserVarsService } from 'src/engine/core-modules/user/user-vars/services import { User } from 'src/engine/core-modules/user/user.entity'; import { userValidator } from 'src/engine/core-modules/user/user.validate'; import { Workspace } from 'src/engine/core-modules/workspace/workspace.entity'; -import { workspaceValidator } from 'src/engine/core-modules/workspace/workspace.validate'; import { AuthUser } from 'src/engine/decorators/auth/auth-user.decorator'; import { AuthWorkspace } from 'src/engine/decorators/auth/auth-workspace.decorator'; -import { OriginHeader } from 'src/engine/decorators/auth/origin-header.decorator'; import { WorkspaceAuthGuard } from 'src/engine/guards/workspace-auth.guard'; import { SettingPermissionType } from 'src/engine/metadata-modules/permissions/constants/setting-permission-type.constants'; import { PermissionsService } from 'src/engine/metadata-modules/permissions/permissions.service'; @@ -355,15 +353,8 @@ export class UserResolver { @ResolveField(() => OnboardingStatus) async onboardingStatus( @Parent() user: User, - @OriginHeader() origin: string, + @AuthWorkspace() workspace: Workspace, ): Promise { - const workspace = - await this.domainManagerService.getWorkspaceByOriginOrDefaultWorkspace( - origin, - ); - - workspaceValidator.assertIsDefinedOrThrow(workspace); - return this.onboardingService.getOnboardingStatus(user, workspace); } diff --git a/packages/twenty-server/src/engine/core-modules/workspace/workspace.resolver.ts b/packages/twenty-server/src/engine/core-modules/workspace/workspace.resolver.ts index 4a6549776..32681242e 100644 --- a/packages/twenty-server/src/engine/core-modules/workspace/workspace.resolver.ts +++ b/packages/twenty-server/src/engine/core-modules/workspace/workspace.resolver.ts @@ -43,7 +43,6 @@ import { AuthApiKey } from 'src/engine/decorators/auth/auth-api-key.decorator'; import { AuthUserWorkspaceId } from 'src/engine/decorators/auth/auth-user-workspace-id.decorator'; import { AuthUser } from 'src/engine/decorators/auth/auth-user.decorator'; import { AuthWorkspace } from 'src/engine/decorators/auth/auth-workspace.decorator'; -import { OriginHeader } from 'src/engine/decorators/auth/origin-header.decorator'; import { SettingsPermissionsGuard } from 'src/engine/guards/settings-permissions.guard'; import { UserAuthGuard } from 'src/engine/guards/user-auth.guard'; import { WorkspaceAuthGuard } from 'src/engine/guards/workspace-auth.guard'; @@ -89,19 +88,12 @@ export class WorkspaceResolver { } @Mutation(() => Workspace) - @UseGuards(UserAuthGuard) + @UseGuards(UserAuthGuard, WorkspaceAuthGuard) async activateWorkspace( @Args('data') data: ActivateWorkspaceInput, @AuthUser() user: User, - @OriginHeader() origin: string, + @AuthWorkspace() workspace: Workspace, ) { - const workspace = - await this.domainManagerService.getWorkspaceByOriginOrDefaultWorkspace( - origin, - ); - - workspaceValidator.assertIsDefinedOrThrow(workspace); - return await this.workspaceService.activateWorkspace(user, workspace, data); } @@ -292,7 +284,7 @@ export class WorkspaceResolver { @Query(() => PublicWorkspaceDataOutput) async getPublicWorkspaceDataByDomain( - @OriginHeader() origin: string, + @Args('origin') origin: string, ): Promise { try { const workspace = diff --git a/packages/twenty-server/src/engine/decorators/auth/origin-header.decorator.ts b/packages/twenty-server/src/engine/decorators/auth/origin-header.decorator.ts deleted file mode 100644 index eda5286c5..000000000 --- a/packages/twenty-server/src/engine/decorators/auth/origin-header.decorator.ts +++ /dev/null @@ -1,11 +0,0 @@ -import { createParamDecorator, ExecutionContext } from '@nestjs/common'; - -import { getRequest } from 'src/utils/extract-request'; - -export const OriginHeader = createParamDecorator( - (data: unknown, ctx: ExecutionContext) => { - const request = getRequest(ctx); - - return request.headers['origin']; - }, -); diff --git a/packages/twenty-server/test/integration/graphql/suites/auth.integration-spec.ts b/packages/twenty-server/test/integration/graphql/suites/auth.integration-spec.ts index ed8dbda31..fca06b007 100644 --- a/packages/twenty-server/test/integration/graphql/suites/auth.integration-spec.ts +++ b/packages/twenty-server/test/integration/graphql/suites/auth.integration-spec.ts @@ -23,7 +23,7 @@ describe('AuthResolve (integration)', () => { const queryData = { query: ` mutation GetLoginTokenFromCredentials { - getLoginTokenFromCredentials(email: "${auth.email}", password: "${auth.password}") { + getLoginTokenFromCredentials(email: "${auth.email}", password: "${auth.password}", origin: "http://localhost") { loginToken { token expiresAt @@ -56,7 +56,7 @@ describe('AuthResolve (integration)', () => { const queryData = { query: ` mutation GetAuthTokensFromLoginToken { - getAuthTokensFromLoginToken(loginToken: "${loginToken}") { + getAuthTokensFromLoginToken(loginToken: "${loginToken}", origin: "http://localhost") { tokens { accessToken { token