fix(auth): handle missing invitation during sign-up (#9572)

Add validation to throw an exception when a sign-up is attempted without
a valid invitation. Updated the test suite to cover this case and ensure
proper error handling with appropriate exceptions.

Fix https://github.com/twentyhq/twenty/issues/9566
https://github.com/twentyhq/twenty/issues/9564
This commit is contained in:
Antoine Moreaux
2025-01-15 15:26:51 +01:00
committed by GitHub
parent f828e75b72
commit 4fdea61f1d
21 changed files with 949 additions and 976 deletions

View File

@ -7,6 +7,7 @@ export const SIGN_UP = gql`
$workspaceInviteHash: String
$workspacePersonalInviteToken: String = null
$captchaToken: String
$workspaceId: String
) {
signUp(
email: $email
@ -14,6 +15,7 @@ export const SIGN_UP = gql`
workspaceInviteHash: $workspaceInviteHash
workspacePersonalInviteToken: $workspacePersonalInviteToken
captchaToken: $captchaToken
workspaceId: $workspaceId
) {
loginToken {
...AuthTokenFragment

View File

@ -8,6 +8,7 @@ import {
useSetRecoilState,
} from 'recoil';
import { iconsState } from 'twenty-ui';
import { AppPath } from '@/types/AppPath';
import { currentWorkspaceMemberState } from '@/auth/states/currentWorkspaceMemberState';
import { currentWorkspaceState } from '@/auth/states/currentWorkspaceState';
@ -47,13 +48,12 @@ import { BillingCheckoutSession } from '@/auth/types/billingCheckoutSession.type
import { isMultiWorkspaceEnabledState } from '@/client-config/states/isMultiWorkspaceEnabledState';
import { useIsCurrentLocationOnAWorkspaceSubdomain } from '@/domain-manager/hooks/useIsCurrentLocationOnAWorkspaceSubdomain';
import { useLastAuthenticatedWorkspaceDomain } from '@/domain-manager/hooks/useLastAuthenticatedWorkspaceDomain';
import { useReadWorkspaceSubdomainFromCurrentLocation } from '@/domain-manager/hooks/useReadWorkspaceSubdomainFromCurrentLocation';
import { useRedirect } from '@/domain-manager/hooks/useRedirect';
import { useRedirectToWorkspaceDomain } from '@/domain-manager/hooks/useRedirectToWorkspaceDomain';
import { domainConfigurationState } from '@/domain-manager/states/domainConfigurationState';
import { isAppWaitingForFreshObjectMetadataState } from '@/object-metadata/states/isAppWaitingForFreshObjectMetadataState';
import { AppPath } from '@/types/AppPath';
import { workspaceAuthProvidersState } from '@/workspace/states/workspaceAuthProvidersState';
import { workspacePublicDataState } from '@/auth/states/workspacePublicDataState';
export const useAuth = () => {
const setTokenPair = useSetRecoilState(tokenPairState);
@ -82,7 +82,8 @@ export const useAuth = () => {
const { isOnAWorkspaceSubdomain } =
useIsCurrentLocationOnAWorkspaceSubdomain();
const { workspaceSubdomain } = useReadWorkspaceSubdomainFromCurrentLocation();
const workspacePublicData = useRecoilValue(workspacePublicDataState);
const { setLastAuthenticateWorkspaceDomain } =
useLastAuthenticatedWorkspaceDomain();
@ -328,6 +329,9 @@ export const useAuth = () => {
workspaceInviteHash,
workspacePersonalInviteToken,
captchaToken,
...(workspacePublicData?.id
? { workspaceId: workspacePublicData.id }
: {}),
},
});
@ -354,6 +358,7 @@ export const useAuth = () => {
[
setIsVerifyPendingState,
signUp,
workspacePublicData,
isMultiWorkspaceEnabled,
handleVerify,
redirectToWorkspaceDomain,
@ -386,13 +391,13 @@ export const useAuth = () => {
);
}
if (isDefined(workspaceSubdomain)) {
url.searchParams.set('workspaceSubdomain', workspaceSubdomain);
if (isDefined(workspacePublicData)) {
url.searchParams.set('workspaceId', workspacePublicData.id);
}
return url.toString();
},
[workspaceSubdomain],
[workspacePublicData],
);
const handleGoogleLogin = useCallback(