feat: use create access token api endpoint instead of login mutation

This commit is contained in:
kasia.oczkowska
2024-07-18 13:05:59 +01:00
parent f63cc80383
commit d051275e54
9 changed files with 66 additions and 63 deletions

View File

@@ -31,7 +31,6 @@ import verifyConnection from './mutations/verify-connection.js';
// Converted mutations // Converted mutations
import deleteUser from './mutations/delete-user.ee.js'; import deleteUser from './mutations/delete-user.ee.js';
import login from './mutations/login.js';
const mutationResolvers = { const mutationResolvers = {
createAppAuthClient, createAppAuthClient,
@@ -50,7 +49,6 @@ const mutationResolvers = {
duplicateFlow, duplicateFlow,
executeFlow, executeFlow,
generateAuthUrl, generateAuthUrl,
login,
registerUser, registerUser,
resetConnection, resetConnection,
updateAppAuthClient, updateAppAuthClient,

View File

@@ -1,17 +0,0 @@
import User from '../../models/user.js';
import createAuthTokenByUserId from '../../helpers/create-auth-token-by-user-id.js';
const login = async (_parent, params) => {
const user = await User.query().findOne({
email: params.input.email.toLowerCase(),
});
if (user && (await user.login(params.input.password))) {
const token = await createAuthTokenByUserId(user.id);
return { token, user };
}
throw new Error('User could not be found.');
};
export default login;

View File

@@ -18,7 +18,6 @@ type Mutation {
duplicateFlow(input: DuplicateFlowInput): Flow duplicateFlow(input: DuplicateFlowInput): Flow
executeFlow(input: ExecuteFlowInput): executeFlowType executeFlow(input: ExecuteFlowInput): executeFlowType
generateAuthUrl(input: GenerateAuthUrlInput): AuthLink generateAuthUrl(input: GenerateAuthUrlInput): AuthLink
login(input: LoginInput): Auth
registerUser(input: RegisterUserInput): User registerUser(input: RegisterUserInput): User
resetConnection(input: ResetConnectionInput): Connection resetConnection(input: ResetConnectionInput): Connection
updateAppAuthClient(input: UpdateAppAuthClientInput): AppAuthClient updateAppAuthClient(input: UpdateAppAuthClientInput): AppAuthClient
@@ -152,11 +151,6 @@ enum ArgumentEnumType {
string string
} }
type Auth {
user: User
token: String
}
type AuthenticationStep { type AuthenticationStep {
type: String type: String
name: String name: String
@@ -403,11 +397,6 @@ input UpdateCurrentUserInput {
fullName: String fullName: String
} }
input LoginInput {
email: String!
password: String!
}
input PermissionInput { input PermissionInput {
action: String! action: String!
subject: String! subject: String!

View File

@@ -53,7 +53,6 @@ const isAuthenticatedRule = rule()(isAuthenticated);
export const authenticationRules = { export const authenticationRules = {
Mutation: { Mutation: {
'*': isAuthenticatedRule, '*': isAuthenticatedRule,
login: allow,
registerUser: allow, registerUser: allow,
}, },
}; };

View File

@@ -1,6 +1,5 @@
import * as React from 'react'; import * as React from 'react';
import { useNavigate, Link as RouterLink } from 'react-router-dom'; import { useNavigate, Link as RouterLink } from 'react-router-dom';
import { useMutation } from '@apollo/client';
import Paper from '@mui/material/Paper'; import Paper from '@mui/material/Paper';
import Link from '@mui/material/Link'; import Link from '@mui/material/Link';
import Typography from '@mui/material/Typography'; import Typography from '@mui/material/Typography';
@@ -8,17 +7,20 @@ import LoadingButton from '@mui/lab/LoadingButton';
import useAuthentication from 'hooks/useAuthentication'; import useAuthentication from 'hooks/useAuthentication';
import useCloud from 'hooks/useCloud'; import useCloud from 'hooks/useCloud';
import * as URLS from 'config/urls'; import * as URLS from 'config/urls';
import { LOGIN } from 'graphql/mutations/login';
import Form from 'components/Form'; import Form from 'components/Form';
import TextField from 'components/TextField'; import TextField from 'components/TextField';
import useFormatMessage from 'hooks/useFormatMessage'; import useFormatMessage from 'hooks/useFormatMessage';
import useCreateAccessToken from 'hooks/useCreateAccessToken';
import useEnqueueSnackbar from 'hooks/useEnqueueSnackbar';
function LoginForm() { function LoginForm() {
const isCloud = useCloud(); const isCloud = useCloud();
const navigate = useNavigate(); const navigate = useNavigate();
const formatMessage = useFormatMessage(); const formatMessage = useFormatMessage();
const enqueueSnackbar = useEnqueueSnackbar();
const authentication = useAuthentication(); const authentication = useAuthentication();
const [login, { loading }] = useMutation(LOGIN); const { mutateAsync: createAccessToken, isPending: loading } =
useCreateAccessToken();
React.useEffect(() => { React.useEffect(() => {
if (authentication.isAuthenticated) { if (authentication.isAuthenticated) {
@@ -27,13 +29,19 @@ function LoginForm() {
}, [authentication.isAuthenticated]); }, [authentication.isAuthenticated]);
const handleSubmit = async (values) => { const handleSubmit = async (values) => {
const { data } = await login({ try {
variables: { const { email, password } = values;
input: values, const { data } = await createAccessToken({
}, email,
}); password,
const { token } = data.login; });
authentication.updateToken(token); const { token } = data;
authentication.updateToken(token);
} catch (error) {
enqueueSnackbar(error?.message || formatMessage('loginForm.error'), {
variant: 'error',
});
}
}; };
return ( return (

View File

@@ -11,8 +11,10 @@ import * as URLS from 'config/urls';
import { REGISTER_USER } from 'graphql/mutations/register-user.ee'; import { REGISTER_USER } from 'graphql/mutations/register-user.ee';
import Form from 'components/Form'; import Form from 'components/Form';
import TextField from 'components/TextField'; import TextField from 'components/TextField';
import { LOGIN } from 'graphql/mutations/login';
import useFormatMessage from 'hooks/useFormatMessage'; import useFormatMessage from 'hooks/useFormatMessage';
import useCreateAccessToken from 'hooks/useCreateAccessToken';
import useEnqueueSnackbar from 'hooks/useEnqueueSnackbar';
const validationSchema = yup.object().shape({ const validationSchema = yup.object().shape({
fullName: yup.string().trim().required('signupForm.mandatoryInput'), fullName: yup.string().trim().required('signupForm.mandatoryInput'),
email: yup email: yup
@@ -26,39 +28,57 @@ const validationSchema = yup.object().shape({
.required('signupForm.mandatoryInput') .required('signupForm.mandatoryInput')
.oneOf([yup.ref('password')], 'signupForm.passwordsMustMatch'), .oneOf([yup.ref('password')], 'signupForm.passwordsMustMatch'),
}); });
const initialValues = { const initialValues = {
fullName: '', fullName: '',
email: '', email: '',
password: '', password: '',
confirmPassword: '', confirmPassword: '',
}; };
function SignUpForm() { function SignUpForm() {
const navigate = useNavigate(); const navigate = useNavigate();
const authentication = useAuthentication(); const authentication = useAuthentication();
const formatMessage = useFormatMessage(); const formatMessage = useFormatMessage();
const enqueueSnackbar = useEnqueueSnackbar();
const [registerUser, { loading: registerUserLoading }] = const [registerUser, { loading: registerUserLoading }] =
useMutation(REGISTER_USER); useMutation(REGISTER_USER);
const [login, { loading: loginLoading }] = useMutation(LOGIN); const { mutateAsync: createAccessToken, isPending: loginLoading } =
useCreateAccessToken();
React.useEffect(() => { React.useEffect(() => {
if (authentication.isAuthenticated) { if (authentication.isAuthenticated) {
navigate(URLS.DASHBOARD); navigate(URLS.DASHBOARD);
} }
}, [authentication.isAuthenticated]); }, [authentication.isAuthenticated]);
const handleSubmit = async (values) => { const handleSubmit = async (values) => {
const { fullName, email, password } = values; const { fullName, email, password } = values;
await registerUser({ await registerUser({
variables: { variables: {
input: { fullName, email, password }, input: {
fullName,
email,
password,
},
}, },
}); });
const { data } = await login({
variables: { try {
input: { email, password }, const { data } = await createAccessToken({
}, email,
}); password,
const { token } = data.login; });
authentication.updateToken(token); const { token } = data;
authentication.updateToken(token);
} catch (error) {
enqueueSnackbar(error?.message || formatMessage('signupForm.error'), {
variant: 'error',
});
}
}; };
return ( return (
<Paper sx={{ px: 2, py: 4 }}> <Paper sx={{ px: 2, py: 4 }}>
<Typography <Typography
@@ -168,4 +188,5 @@ function SignUpForm() {
</Paper> </Paper>
); );
} }
export default SignUpForm; export default SignUpForm;

View File

@@ -1,12 +0,0 @@
import { gql } from '@apollo/client';
export const LOGIN = gql`
mutation Login($input: LoginInput) {
login(input: $input) {
token
user {
id
email
}
}
}
`;

View File

@@ -0,0 +1,15 @@
import { useMutation } from '@tanstack/react-query';
import api from 'helpers/api';
export default function useCreateAccessToken() {
const query = useMutation({
mutationFn: async ({ email, password }) => {
const { data } = await api.post('/v1/access-tokens', { email, password });
return data;
},
});
return query;
}

View File

@@ -144,6 +144,7 @@
"signupForm.validateEmail": "Email must be valid.", "signupForm.validateEmail": "Email must be valid.",
"signupForm.passwordsMustMatch": "Passwords must match.", "signupForm.passwordsMustMatch": "Passwords must match.",
"signupForm.mandatoryInput": "{inputName} is required.", "signupForm.mandatoryInput": "{inputName} is required.",
"signupForm.error": "Something went wrong. Please try again.",
"loginForm.title": "Login", "loginForm.title": "Login",
"loginForm.emailFieldLabel": "Email", "loginForm.emailFieldLabel": "Email",
"loginForm.passwordFieldLabel": "Password", "loginForm.passwordFieldLabel": "Password",
@@ -152,6 +153,7 @@
"loginForm.noAccount": "Don't have an Automatisch account yet?", "loginForm.noAccount": "Don't have an Automatisch account yet?",
"loginForm.signUp": "Sign up", "loginForm.signUp": "Sign up",
"loginPage.divider": "OR", "loginPage.divider": "OR",
"loginForm.error": "Something went wrong. Please try again.",
"ssoProviders.loginWithProvider": "Login with {providerName}", "ssoProviders.loginWithProvider": "Login with {providerName}",
"forgotPasswordForm.title": "Forgot password", "forgotPasswordForm.title": "Forgot password",
"forgotPasswordForm.submit": "Send reset instructions", "forgotPasswordForm.submit": "Send reset instructions",