158 lines
4.1 KiB
TypeScript
158 lines
4.1 KiB
TypeScript
import { useCallback } from 'react';
|
|
import { useApolloClient } from '@apollo/client';
|
|
import {
|
|
snapshot_UNSTABLE,
|
|
useGotoRecoilSnapshot,
|
|
useRecoilState,
|
|
} from 'recoil';
|
|
|
|
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] = useRecoilState(currentUserState);
|
|
|
|
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');
|
|
}
|
|
|
|
if (!verifyResult.data?.verify.user.workspaceMember) {
|
|
throw new Error('No workspace member');
|
|
}
|
|
|
|
if (!verifyResult.data?.verify.user.workspaceMember.settings) {
|
|
throw new Error('No settings');
|
|
}
|
|
|
|
setCurrentUser({
|
|
...verifyResult.data?.verify.user,
|
|
workspaceMember: {
|
|
...verifyResult.data?.verify.user.workspaceMember,
|
|
settings: verifyResult.data?.verify.user.workspaceMember.settings,
|
|
},
|
|
});
|
|
setTokenPair(verifyResult.data?.verify.tokens);
|
|
|
|
return verifyResult.data?.verify;
|
|
},
|
|
[setTokenPair, verify, setCurrentUser],
|
|
);
|
|
|
|
const handleCrendentialsSignIn = useCallback(
|
|
async (email: string, password: string) => {
|
|
const { loginToken } = await handleChallenge(email, password);
|
|
|
|
const { user } = await handleVerify(loginToken.token);
|
|
return user;
|
|
},
|
|
[handleChallenge, handleVerify],
|
|
);
|
|
|
|
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) => {
|
|
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 } = await handleVerify(
|
|
signUpResult.data?.signUp.loginToken.token,
|
|
);
|
|
|
|
return user;
|
|
},
|
|
[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,
|
|
};
|
|
};
|