Rename Unintuitive Function Names in Authentication Flow (#9706)
Resolves #9623 ## Description This PR renames the following functions to better reflect their purpose. - Backend: - Verify → GetAuthTokensFromLoginToken - Challenge → GetLoginTokenFromCredentials - Frontend: - challenge → getLoginTokenFromCredentials - verify → getAuthTokensFromLoginToken ## Testing _Sign in works as expected:_ https://github.com/user-attachments/assets/7e8f73c7-2c7d-4cd2-9965-5ad9f5334cd3 _Sign up works as expected:_ https://github.com/user-attachments/assets/d1794ee4-8b59-4934-84df-d819eabd5224 --------- Co-authored-by: Charles Bochet <charles@twenty.com>
This commit is contained in:
@ -21,7 +21,7 @@ export const VerifyEffect = () => {
|
||||
const isLogged = useIsLogged();
|
||||
const navigate = useNavigateApp();
|
||||
|
||||
const { verify } = useAuth();
|
||||
const { getAuthTokensFromLoginToken } = useAuth();
|
||||
|
||||
const setIsAppWaitingForFreshObjectMetadata = useSetRecoilState(
|
||||
isAppWaitingForFreshObjectMetadataState,
|
||||
@ -30,14 +30,14 @@ export const VerifyEffect = () => {
|
||||
useEffect(() => {
|
||||
if (isDefined(errorMessage)) {
|
||||
enqueueSnackBar(errorMessage, {
|
||||
dedupeKey: 'verify-failed-dedupe-key',
|
||||
dedupeKey: 'get-auth-tokens-from-login-token-failed-dedupe-key',
|
||||
variant: SnackBarVariant.Error,
|
||||
});
|
||||
}
|
||||
|
||||
if (isDefined(loginToken)) {
|
||||
setIsAppWaitingForFreshObjectMetadata(true);
|
||||
verify(loginToken);
|
||||
getAuthTokensFromLoginToken(loginToken);
|
||||
} else if (!isLogged) {
|
||||
navigate(AppPath.SignInUp);
|
||||
}
|
||||
|
||||
@ -1,15 +0,0 @@
|
||||
import { gql } from '@apollo/client';
|
||||
|
||||
export const CHALLENGE = gql`
|
||||
mutation Challenge(
|
||||
$email: String!
|
||||
$password: String!
|
||||
$captchaToken: String
|
||||
) {
|
||||
challenge(email: $email, password: $password, captchaToken: $captchaToken) {
|
||||
loginToken {
|
||||
...AuthTokenFragment
|
||||
}
|
||||
}
|
||||
}
|
||||
`;
|
||||
@ -0,0 +1,11 @@
|
||||
import { gql } from '@apollo/client';
|
||||
|
||||
export const GET_AUTH_TOKENS_FROM_LOGIN_TOKEN = gql`
|
||||
mutation GetAuthTokensFromLoginToken($loginToken: String!) {
|
||||
getAuthTokensFromLoginToken(loginToken: $loginToken) {
|
||||
tokens {
|
||||
...AuthTokensFragment
|
||||
}
|
||||
}
|
||||
}
|
||||
`;
|
||||
@ -0,0 +1,19 @@
|
||||
import { gql } from '@apollo/client';
|
||||
|
||||
export const GET_LOGIN_TOKEN_FROM_CREDENTIALS = gql`
|
||||
mutation GetLoginTokenFromCredentials(
|
||||
$email: String!
|
||||
$password: String!
|
||||
$captchaToken: String
|
||||
) {
|
||||
getLoginTokenFromCredentials(
|
||||
email: $email
|
||||
password: $password
|
||||
captchaToken: $captchaToken
|
||||
) {
|
||||
loginToken {
|
||||
...AuthTokenFragment
|
||||
}
|
||||
}
|
||||
}
|
||||
`;
|
||||
@ -1,11 +0,0 @@
|
||||
import { gql } from '@apollo/client';
|
||||
|
||||
export const VERIFY = gql`
|
||||
mutation Verify($loginToken: String!) {
|
||||
verify(loginToken: $loginToken) {
|
||||
tokens {
|
||||
...AuthTokensFragment
|
||||
}
|
||||
}
|
||||
}
|
||||
`;
|
||||
@ -1,13 +1,13 @@
|
||||
import {
|
||||
ChallengeDocument,
|
||||
GetAuthTokensFromLoginTokenDocument,
|
||||
GetCurrentUserDocument,
|
||||
GetLoginTokenFromCredentialsDocument,
|
||||
SignUpDocument,
|
||||
VerifyDocument,
|
||||
} from '~/generated/graphql';
|
||||
|
||||
export const queries = {
|
||||
challenge: ChallengeDocument,
|
||||
verify: VerifyDocument,
|
||||
getLoginTokenFromCredentials: GetLoginTokenFromCredentialsDocument,
|
||||
getAuthTokensFromLoginToken: GetAuthTokensFromLoginTokenDocument,
|
||||
signup: SignUpDocument,
|
||||
getCurrentUser: GetCurrentUserDocument,
|
||||
};
|
||||
@ -18,23 +18,23 @@ export const token =
|
||||
'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c';
|
||||
|
||||
export const variables = {
|
||||
challenge: {
|
||||
getLoginTokenFromCredentials: {
|
||||
email,
|
||||
password,
|
||||
},
|
||||
verify: { loginToken: token },
|
||||
getAuthTokensFromLoginToken: { loginToken: token },
|
||||
signup: {},
|
||||
getCurrentUser: {},
|
||||
};
|
||||
|
||||
export const results = {
|
||||
challenge: {
|
||||
getLoginTokenFromCredentials: {
|
||||
loginToken: {
|
||||
token,
|
||||
expiresAt: '2022-01-01',
|
||||
},
|
||||
},
|
||||
verify: {
|
||||
getAuthTokensFromLoginToken: {
|
||||
tokens: {
|
||||
accessToken: { token, expiresAt: 'expiresAt' },
|
||||
refreshToken: { token, expiresAt: 'expiresAt' },
|
||||
@ -81,30 +81,30 @@ export const results = {
|
||||
export const mocks = [
|
||||
{
|
||||
request: {
|
||||
query: queries.challenge,
|
||||
variables: variables.challenge,
|
||||
query: queries.getLoginTokenFromCredentials,
|
||||
variables: variables.getLoginTokenFromCredentials,
|
||||
},
|
||||
result: jest.fn(() => ({
|
||||
data: {
|
||||
challenge: results.challenge,
|
||||
getLoginTokenFromCredentials: results.getLoginTokenFromCredentials,
|
||||
},
|
||||
})),
|
||||
},
|
||||
{
|
||||
request: {
|
||||
query: queries.verify,
|
||||
variables: variables.verify,
|
||||
query: queries.getAuthTokensFromLoginToken,
|
||||
variables: variables.getAuthTokensFromLoginToken,
|
||||
},
|
||||
result: jest.fn(() => ({
|
||||
data: {
|
||||
verify: results.verify,
|
||||
getAuthTokensFromLoginToken: results.getAuthTokensFromLoginToken,
|
||||
},
|
||||
})),
|
||||
},
|
||||
{
|
||||
request: {
|
||||
query: queries.signup,
|
||||
variables: variables.challenge,
|
||||
variables: variables.getLoginTokenFromCredentials,
|
||||
},
|
||||
result: jest.fn(() => ({
|
||||
data: {
|
||||
|
||||
@ -42,13 +42,13 @@ describe('useAuth', () => {
|
||||
jest.clearAllMocks();
|
||||
});
|
||||
|
||||
it('should return challenge object', async () => {
|
||||
it('should return login token object', async () => {
|
||||
const { result } = renderHooks();
|
||||
|
||||
await act(async () => {
|
||||
expect(await result.current.challenge(email, password)).toStrictEqual(
|
||||
results.challenge,
|
||||
);
|
||||
expect(
|
||||
await result.current.getLoginTokenFromCredentials(email, password),
|
||||
).toStrictEqual(results.getLoginTokenFromCredentials);
|
||||
});
|
||||
|
||||
expect(mocks[0].result).toHaveBeenCalled();
|
||||
@ -58,7 +58,7 @@ describe('useAuth', () => {
|
||||
const { result } = renderHooks();
|
||||
|
||||
await act(async () => {
|
||||
await result.current.verify(token);
|
||||
await result.current.getAuthTokensFromLoginToken(token);
|
||||
});
|
||||
|
||||
expect(mocks[1].result).toHaveBeenCalled();
|
||||
|
||||
@ -22,12 +22,12 @@ import { supportChatState } from '@/client-config/states/supportChatState';
|
||||
import { ColorScheme } from '@/workspace-member/types/WorkspaceMember';
|
||||
import { REACT_APP_SERVER_BASE_URL } from '~/config';
|
||||
import {
|
||||
useChallengeMutation,
|
||||
useCheckUserExistsLazyQuery,
|
||||
useGetAuthTokensFromLoginTokenMutation,
|
||||
useGetCurrentUserLazyQuery,
|
||||
useGetLoginTokenFromCredentialsMutation,
|
||||
useGetLoginTokenFromEmailVerificationTokenMutation,
|
||||
useSignUpMutation,
|
||||
useVerifyMutation,
|
||||
} from '~/generated/graphql';
|
||||
import { isDefined } from '~/utils/isDefined';
|
||||
|
||||
@ -87,9 +87,11 @@ export const useAuth = () => {
|
||||
const { redirect } = useRedirect();
|
||||
const { redirectToWorkspaceDomain } = useRedirectToWorkspaceDomain();
|
||||
|
||||
const [challenge] = useChallengeMutation();
|
||||
const [getLoginTokenFromCredentials] =
|
||||
useGetLoginTokenFromCredentialsMutation();
|
||||
const [signUp] = useSignUpMutation();
|
||||
const [verify] = useVerifyMutation();
|
||||
const [getAuthTokensFromLoginToken] =
|
||||
useGetAuthTokensFromLoginTokenMutation();
|
||||
const [getLoginTokenFromEmailVerificationToken] =
|
||||
useGetLoginTokenFromEmailVerificationTokenMutation();
|
||||
const [getCurrentUser] = useGetCurrentUserLazyQuery();
|
||||
@ -166,25 +168,25 @@ export const useAuth = () => {
|
||||
[client, goToRecoilSnapshot, setLastAuthenticateWorkspaceDomain],
|
||||
);
|
||||
|
||||
const handleChallenge = useCallback(
|
||||
const handleGetLoginTokenFromCredentials = useCallback(
|
||||
async (email: string, password: string, captchaToken?: string) => {
|
||||
try {
|
||||
const challengeResult = await challenge({
|
||||
const getLoginTokenResult = await getLoginTokenFromCredentials({
|
||||
variables: {
|
||||
email,
|
||||
password,
|
||||
captchaToken,
|
||||
},
|
||||
});
|
||||
if (isDefined(challengeResult.errors)) {
|
||||
throw challengeResult.errors;
|
||||
if (isDefined(getLoginTokenResult.errors)) {
|
||||
throw getLoginTokenResult.errors;
|
||||
}
|
||||
|
||||
if (!challengeResult.data?.challenge) {
|
||||
if (!getLoginTokenResult.data?.getLoginTokenFromCredentials) {
|
||||
throw new Error('No login token');
|
||||
}
|
||||
|
||||
return challengeResult.data.challenge;
|
||||
return getLoginTokenResult.data.getLoginTokenFromCredentials;
|
||||
} catch (error) {
|
||||
// TODO: Get intellisense for graphql error extensions code (codegen?)
|
||||
if (
|
||||
@ -198,7 +200,7 @@ export const useAuth = () => {
|
||||
throw error;
|
||||
}
|
||||
},
|
||||
[challenge, setSearchParams, setSignInUpStep],
|
||||
[getLoginTokenFromCredentials, setSearchParams, setSignInUpStep],
|
||||
);
|
||||
|
||||
const handleGetLoginTokenFromEmailVerificationToken = useCallback(
|
||||
@ -322,41 +324,48 @@ export const useAuth = () => {
|
||||
setWorkspaces,
|
||||
]);
|
||||
|
||||
const handleVerify = useCallback(
|
||||
const handleGetAuthTokensFromLoginToken = useCallback(
|
||||
async (loginToken: string) => {
|
||||
setIsVerifyPendingState(true);
|
||||
|
||||
const verifyResult = await verify({
|
||||
const getAuthTokensResult = await getAuthTokensFromLoginToken({
|
||||
variables: { loginToken },
|
||||
});
|
||||
|
||||
if (isDefined(verifyResult.errors)) {
|
||||
throw verifyResult.errors;
|
||||
if (isDefined(getAuthTokensResult.errors)) {
|
||||
throw getAuthTokensResult.errors;
|
||||
}
|
||||
|
||||
if (!verifyResult.data?.verify) {
|
||||
throw new Error('No verify result');
|
||||
if (!getAuthTokensResult.data?.getAuthTokensFromLoginToken) {
|
||||
throw new Error('No getAuthTokensFromLoginToken result');
|
||||
}
|
||||
|
||||
setTokenPair(verifyResult.data?.verify.tokens);
|
||||
setTokenPair(
|
||||
getAuthTokensResult.data?.getAuthTokensFromLoginToken.tokens,
|
||||
);
|
||||
|
||||
await loadCurrentUser();
|
||||
|
||||
setIsVerifyPendingState(false);
|
||||
},
|
||||
[setIsVerifyPendingState, verify, setTokenPair, loadCurrentUser],
|
||||
[
|
||||
setIsVerifyPendingState,
|
||||
getAuthTokensFromLoginToken,
|
||||
setTokenPair,
|
||||
loadCurrentUser,
|
||||
],
|
||||
);
|
||||
|
||||
const handleCredentialsSignIn = useCallback(
|
||||
async (email: string, password: string, captchaToken?: string) => {
|
||||
const { loginToken } = await handleChallenge(
|
||||
const { loginToken } = await handleGetLoginTokenFromCredentials(
|
||||
email,
|
||||
password,
|
||||
captchaToken,
|
||||
);
|
||||
await handleVerify(loginToken.token);
|
||||
await handleGetAuthTokensFromLoginToken(loginToken.token);
|
||||
},
|
||||
[handleChallenge, handleVerify],
|
||||
[handleGetLoginTokenFromCredentials, handleGetAuthTokensFromLoginToken],
|
||||
);
|
||||
|
||||
const handleSignOut = useCallback(async () => {
|
||||
@ -413,14 +422,16 @@ export const useAuth = () => {
|
||||
);
|
||||
}
|
||||
|
||||
await handleVerify(signUpResult.data?.signUp.loginToken.token);
|
||||
await handleGetAuthTokensFromLoginToken(
|
||||
signUpResult.data?.signUp.loginToken.token,
|
||||
);
|
||||
},
|
||||
[
|
||||
setIsVerifyPendingState,
|
||||
signUp,
|
||||
workspacePublicData,
|
||||
isMultiWorkspaceEnabled,
|
||||
handleVerify,
|
||||
handleGetAuthTokensFromLoginToken,
|
||||
setSignInUpStep,
|
||||
setSearchParams,
|
||||
isEmailVerificationRequired,
|
||||
@ -486,10 +497,10 @@ export const useAuth = () => {
|
||||
);
|
||||
|
||||
return {
|
||||
challenge: handleChallenge,
|
||||
getLoginTokenFromCredentials: handleGetLoginTokenFromCredentials,
|
||||
getLoginTokenFromEmailVerificationToken:
|
||||
handleGetLoginTokenFromEmailVerificationToken,
|
||||
verify: handleVerify,
|
||||
getAuthTokensFromLoginToken: handleGetAuthTokensFromLoginToken,
|
||||
|
||||
loadCurrentUser,
|
||||
|
||||
|
||||
@ -1,13 +1,13 @@
|
||||
import { useAuth } from '@/auth/hooks/useAuth';
|
||||
import { currentUserState } from '@/auth/states/currentUserState';
|
||||
import { currentWorkspaceState } from '@/auth/states/currentWorkspaceState';
|
||||
import { useRedirectToWorkspaceDomain } from '@/domain-manager/hooks/useRedirectToWorkspaceDomain';
|
||||
import { isAppWaitingForFreshObjectMetadataState } from '@/object-metadata/states/isAppWaitingForFreshObjectMetadataState';
|
||||
import { AppPath } from '@/types/AppPath';
|
||||
import { useState } from 'react';
|
||||
import { useRecoilState, useRecoilValue, useSetRecoilState } from 'recoil';
|
||||
import { useImpersonateMutation } from '~/generated/graphql';
|
||||
import { isDefined } from '~/utils/isDefined';
|
||||
import { useRedirectToWorkspaceDomain } from '@/domain-manager/hooks/useRedirectToWorkspaceDomain';
|
||||
import { useAuth } from '@/auth/hooks/useAuth';
|
||||
import { currentWorkspaceState } from '@/auth/states/currentWorkspaceState';
|
||||
import { isAppWaitingForFreshObjectMetadataState } from '@/object-metadata/states/isAppWaitingForFreshObjectMetadataState';
|
||||
|
||||
export const useImpersonate = () => {
|
||||
const [currentUser] = useRecoilState(currentUserState);
|
||||
@ -16,7 +16,7 @@ export const useImpersonate = () => {
|
||||
isAppWaitingForFreshObjectMetadataState,
|
||||
);
|
||||
|
||||
const { verify } = useAuth();
|
||||
const { getAuthTokensFromLoginToken } = useAuth();
|
||||
|
||||
const [impersonate] = useImpersonateMutation();
|
||||
const { redirectToWorkspaceDomain } = useRedirectToWorkspaceDomain();
|
||||
@ -50,7 +50,7 @@ export const useImpersonate = () => {
|
||||
|
||||
if (workspace.id === currentWorkspace?.id) {
|
||||
setIsAppWaitingForFreshObjectMetadata(true);
|
||||
await verify(loginToken.token);
|
||||
await getAuthTokensFromLoginToken(loginToken.token);
|
||||
setIsAppWaitingForFreshObjectMetadata(false);
|
||||
return;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user