Migrate to a monorepo structure (#2909)
This commit is contained in:
187
packages/twenty-front/src/modules/auth/hooks/useAuth.ts
Normal file
187
packages/twenty-front/src/modules/auth/hooks/useAuth.ts
Normal file
@ -0,0 +1,187 @@
|
||||
import { useCallback } from 'react';
|
||||
import { useApolloClient } from '@apollo/client';
|
||||
import {
|
||||
snapshot_UNSTABLE,
|
||||
useGotoRecoilSnapshot,
|
||||
useRecoilState,
|
||||
useSetRecoilState,
|
||||
} from 'recoil';
|
||||
|
||||
import { currentWorkspaceMemberState } from '@/auth/states/currentWorkspaceMemberState';
|
||||
import { currentWorkspaceState } from '@/auth/states/currentWorkspaceState';
|
||||
import { isVerifyPendingState } from '@/auth/states/isVerifyPendingState';
|
||||
import { ColorScheme } from '@/workspace-member/types/WorkspaceMember';
|
||||
import { REACT_APP_SERVER_AUTH_URL } from '~/config';
|
||||
import {
|
||||
useChallengeMutation,
|
||||
useCheckUserExistsLazyQuery,
|
||||
useSignUpMutation,
|
||||
useVerifyMutation,
|
||||
} from '~/generated/graphql';
|
||||
|
||||
import { currentUserState } from '../states/currentUserState';
|
||||
import { tokenPairState } from '../states/tokenPairState';
|
||||
|
||||
export const useAuth = () => {
|
||||
const [, setTokenPair] = useRecoilState(tokenPairState);
|
||||
const setCurrentUser = useSetRecoilState(currentUserState);
|
||||
const setCurrentWorkspaceMember = useSetRecoilState(
|
||||
currentWorkspaceMemberState,
|
||||
);
|
||||
|
||||
const setCurrentWorkspace = useSetRecoilState(currentWorkspaceState);
|
||||
const setIsVerifyPendingState = useSetRecoilState(isVerifyPendingState);
|
||||
|
||||
const [challenge] = useChallengeMutation();
|
||||
const [signUp] = useSignUpMutation();
|
||||
const [verify] = useVerifyMutation();
|
||||
const [checkUserExistsQuery, { data: checkUserExistsData }] =
|
||||
useCheckUserExistsLazyQuery();
|
||||
|
||||
const client = useApolloClient();
|
||||
|
||||
const goToRecoilSnapshot = useGotoRecoilSnapshot();
|
||||
|
||||
const handleChallenge = useCallback(
|
||||
async (email: string, password: string) => {
|
||||
const challengeResult = await challenge({
|
||||
variables: {
|
||||
email,
|
||||
password,
|
||||
},
|
||||
});
|
||||
|
||||
if (challengeResult.errors) {
|
||||
throw challengeResult.errors;
|
||||
}
|
||||
|
||||
if (!challengeResult.data?.challenge) {
|
||||
throw new Error('No login token');
|
||||
}
|
||||
|
||||
return challengeResult.data.challenge;
|
||||
},
|
||||
[challenge],
|
||||
);
|
||||
|
||||
const handleVerify = useCallback(
|
||||
async (loginToken: string) => {
|
||||
const verifyResult = await verify({
|
||||
variables: { loginToken },
|
||||
});
|
||||
|
||||
if (verifyResult.errors) {
|
||||
throw verifyResult.errors;
|
||||
}
|
||||
|
||||
if (!verifyResult.data?.verify) {
|
||||
throw new Error('No verify result');
|
||||
}
|
||||
|
||||
setTokenPair(verifyResult.data?.verify.tokens);
|
||||
|
||||
const user = verifyResult.data?.verify.user;
|
||||
const workspaceMember = {
|
||||
...user.workspaceMember,
|
||||
colorScheme: user.workspaceMember?.colorScheme as ColorScheme,
|
||||
};
|
||||
const workspace = user.defaultWorkspace ?? null;
|
||||
setCurrentUser(user);
|
||||
setCurrentWorkspaceMember(workspaceMember);
|
||||
setCurrentWorkspace(workspace);
|
||||
return {
|
||||
user,
|
||||
workspaceMember,
|
||||
workspace,
|
||||
tokens: verifyResult.data?.verify.tokens,
|
||||
};
|
||||
},
|
||||
[
|
||||
verify,
|
||||
setTokenPair,
|
||||
setCurrentUser,
|
||||
setCurrentWorkspaceMember,
|
||||
setCurrentWorkspace,
|
||||
],
|
||||
);
|
||||
|
||||
const handleCrendentialsSignIn = useCallback(
|
||||
async (email: string, password: string) => {
|
||||
const { loginToken } = await handleChallenge(email, password);
|
||||
setIsVerifyPendingState(true);
|
||||
|
||||
const { user, workspaceMember, workspace } = await handleVerify(
|
||||
loginToken.token,
|
||||
);
|
||||
|
||||
setIsVerifyPendingState(false);
|
||||
|
||||
return {
|
||||
user,
|
||||
workspaceMember,
|
||||
workspace,
|
||||
};
|
||||
},
|
||||
[handleChallenge, handleVerify, setIsVerifyPendingState],
|
||||
);
|
||||
|
||||
const handleSignOut = useCallback(() => {
|
||||
goToRecoilSnapshot(snapshot_UNSTABLE());
|
||||
setTokenPair(null);
|
||||
setCurrentUser(null);
|
||||
client.clearStore().then(() => {
|
||||
sessionStorage.clear();
|
||||
});
|
||||
}, [goToRecoilSnapshot, setTokenPair, setCurrentUser, client]);
|
||||
|
||||
const handleCredentialsSignUp = useCallback(
|
||||
async (email: string, password: string, workspaceInviteHash?: string) => {
|
||||
setIsVerifyPendingState(true);
|
||||
|
||||
const signUpResult = await signUp({
|
||||
variables: {
|
||||
email,
|
||||
password,
|
||||
workspaceInviteHash,
|
||||
},
|
||||
});
|
||||
|
||||
if (signUpResult.errors) {
|
||||
throw signUpResult.errors;
|
||||
}
|
||||
|
||||
if (!signUpResult.data?.signUp) {
|
||||
throw new Error('No login token');
|
||||
}
|
||||
|
||||
const { user, workspace, workspaceMember } = await handleVerify(
|
||||
signUpResult.data?.signUp.loginToken.token,
|
||||
);
|
||||
|
||||
setIsVerifyPendingState(false);
|
||||
|
||||
return { user, workspaceMember, workspace };
|
||||
},
|
||||
[setIsVerifyPendingState, signUp, handleVerify],
|
||||
);
|
||||
|
||||
const handleGoogleLogin = useCallback((workspaceInviteHash?: string) => {
|
||||
const authServerUrl = REACT_APP_SERVER_AUTH_URL;
|
||||
window.location.href =
|
||||
`${authServerUrl}/google/${
|
||||
workspaceInviteHash ? '?inviteHash=' + workspaceInviteHash : ''
|
||||
}` || '';
|
||||
}, []);
|
||||
|
||||
return {
|
||||
challenge: handleChallenge,
|
||||
verify: handleVerify,
|
||||
|
||||
checkUserExists: { checkUserExistsData, checkUserExistsQuery },
|
||||
|
||||
signOut: handleSignOut,
|
||||
signUpWithCredentials: handleCredentialsSignUp,
|
||||
signInWithCredentials: handleCrendentialsSignIn,
|
||||
signInWithGoogle: handleGoogleLogin,
|
||||
};
|
||||
};
|
||||
12
packages/twenty-front/src/modules/auth/hooks/useIsLogged.ts
Normal file
12
packages/twenty-front/src/modules/auth/hooks/useIsLogged.ts
Normal file
@ -0,0 +1,12 @@
|
||||
import { useRecoilState, useRecoilValue } from 'recoil';
|
||||
|
||||
import { isVerifyPendingState } from '@/auth/states/isVerifyPendingState';
|
||||
|
||||
import { tokenPairState } from '../states/tokenPairState';
|
||||
|
||||
export const useIsLogged = (): boolean => {
|
||||
const [tokenPair] = useRecoilState(tokenPairState);
|
||||
const isVerifyPending = useRecoilValue(isVerifyPendingState);
|
||||
|
||||
return !!tokenPair && !isVerifyPending;
|
||||
};
|
||||
@ -0,0 +1,22 @@
|
||||
import { useRecoilValue } from 'recoil';
|
||||
|
||||
import { currentWorkspaceMemberState } from '@/auth/states/currentWorkspaceMemberState';
|
||||
import { currentWorkspaceState } from '@/auth/states/currentWorkspaceState';
|
||||
|
||||
import { useIsLogged } from '../hooks/useIsLogged';
|
||||
import {
|
||||
getOnboardingStatus,
|
||||
OnboardingStatus,
|
||||
} from '../utils/getOnboardingStatus';
|
||||
|
||||
export const useOnboardingStatus = (): OnboardingStatus | undefined => {
|
||||
const currentWorkspaceMember = useRecoilValue(currentWorkspaceMemberState);
|
||||
const currentWorkspace = useRecoilValue(currentWorkspaceState);
|
||||
const isLoggedIn = useIsLogged();
|
||||
|
||||
return getOnboardingStatus(
|
||||
isLoggedIn,
|
||||
currentWorkspaceMember,
|
||||
currentWorkspace,
|
||||
);
|
||||
};
|
||||
Reference in New Issue
Block a user