Files
twenty/front/src/modules/auth/hooks/useAuth.ts
T
Charles Bochet aa2596c572 Update Seeds while pre-fi
lling a new workspace
2023-11-17 21:54:32 +01:00

218 lines
6.2 KiB
TypeScript

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 { CREATE_ONE_WORKSPACE_MEMBER_V2 } from '@/object-record/graphql/mutation/createOneWorkspaceMember';
import { FIND_ONE_WORKSPACE_MEMBER_V2 } from '@/object-record/graphql/queries/findOneWorkspaceMember';
import { REACT_APP_SERVER_AUTH_URL } from '~/config';
import {
useChallengeMutation,
useCheckUserExistsLazyQuery,
useGetCurrentWorkspaceLazyQuery,
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 [getCurrentWorkspaceQuery] = useGetCurrentWorkspaceLazyQuery();
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 workspaceMember = await client.query({
query: FIND_ONE_WORKSPACE_MEMBER_V2,
variables: {
filter: {
userId: { eq: verifyResult.data?.verify.user.id },
},
},
});
const currentWorkspace = await getCurrentWorkspaceQuery();
setCurrentUser(verifyResult.data?.verify.user);
setCurrentWorkspaceMember(workspaceMember.data?.findMany);
setCurrentWorkspace(currentWorkspace.data?.currentWorkspace ?? null);
return {
user: verifyResult.data?.verify.user,
workspaceMember: workspaceMember.data?.findMany,
workspace: currentWorkspace.data?.currentWorkspace,
tokens: verifyResult.data?.verify.tokens,
};
},
[
verify,
setTokenPair,
client,
getCurrentWorkspaceQuery,
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 } = await handleVerify(
signUpResult.data?.signUp.loginToken.token,
);
const workspaceMember = await client.mutate({
mutation: CREATE_ONE_WORKSPACE_MEMBER_V2,
variables: {
input: {
name: {
firstName: user.firstName ?? '',
lastName: user.lastName ?? '',
},
colorScheme: 'Light',
userId: user.id,
allowImpersonation: true,
locale: 'en',
},
},
});
setCurrentWorkspaceMember(workspaceMember.data?.createWorkspaceMemberV2);
setIsVerifyPendingState(false);
return { user, workspaceMember, workspace };
},
[
setIsVerifyPendingState,
signUp,
handleVerify,
client,
setCurrentWorkspaceMember,
],
);
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,
};
};