lamassu-server/new-lamassu-admin/src/pages/Authentication/Register.jsx
2025-04-22 13:11:45 +01:00

221 lines
6.2 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import { useQuery, useMutation, gql } from "@apollo/client";
import Grid from '@mui/material/Grid'
import { makeStyles } from '@mui/styles'
import Paper from '@mui/material/Paper'
import { Field, Form, Formik } from 'formik'
import React, { useReducer } from 'react'
import { useLocation, useHistory } from 'react-router-dom'
import { H2, Label3, P } from 'src/components/typography'
import Logo from 'src/styling/icons/menu/logo.svg?react'
import * as Yup from 'yup'
import { Button } from 'src/components/buttons'
import { SecretInput } from 'src/components/inputs/formik'
import styles from './shared.styles'
const QueryParams = () => new URLSearchParams(useLocation().search)
const useStyles = makeStyles(styles)
const VALIDATE_REGISTER_LINK = gql`
query validateRegisterLink($token: String!) {
validateRegisterLink(token: $token) {
username
role
}
}
`
const REGISTER = gql`
mutation register(
$token: String!
$username: String!
$password: String!
$role: String!
) {
register(
token: $token
username: $username
password: $password
role: $role
)
}
`
const PASSWORD_MIN_LENGTH = 8
const validationSchema = Yup.object({
password: Yup.string()
.required('A password is required')
.min(
PASSWORD_MIN_LENGTH,
`Your password must contain at least ${PASSWORD_MIN_LENGTH} characters`
),
confirmPassword: Yup.string()
.required('Please confirm the password')
.oneOf([Yup.ref('password')], 'Passwords must match')
})
const initialValues = {
password: '',
confirmPassword: ''
}
const initialState = {
username: null,
role: null,
result: ''
}
const reducer = (state, action) => {
const { type, payload } = action
return { ...state, ...payload, result: type }
}
const getErrorMsg = (
formikErrors,
formikTouched,
queryError,
mutationError
) => {
if (!formikErrors || !formikTouched) return null
if (queryError || mutationError) return 'Internal server error'
if (formikErrors.password && formikTouched.password)
return formikErrors.password
if (formikErrors.confirmPassword && formikTouched.confirmPassword)
return formikErrors.confirmPassword
return null
}
const Register = () => {
const classes = useStyles()
const history = useHistory()
const token = QueryParams().get('t')
const [state, dispatch] = useReducer(reducer, initialState)
const queryOptions = {
variables: { token: token },
onCompleted: ({ validateRegisterLink: info }) => {
if (!info) {
return dispatch({
type: 'failure'
})
}
dispatch({
type: 'success',
payload: {
username: info.username,
role: info.role
}
})
},
onError: () =>
dispatch({
type: 'failure'
})
}
const { error: queryError, loading } = useQuery(
VALIDATE_REGISTER_LINK,
queryOptions
)
const [register, { error: mutationError }] = useMutation(REGISTER, {
onCompleted: ({ register: success }) => {
if (success) history.push('/wizard', { fromAuthRegister: true })
}
})
return (
<Grid
container
spacing={0}
direction="column"
alignItems="center"
justifyContent="center"
className={classes.welcomeBackground}>
<Grid>
<div>
<Paper elevation={1}>
<div className={classes.wrapper}>
<div className={classes.titleWrapper}>
<Logo className={classes.icon} />
<H2 className={classes.title}>Lamassu Admin</H2>
</div>
{!loading && state.result === 'success' && (
<Formik
validationSchema={validationSchema}
initialValues={initialValues}
onSubmit={values => {
register({
variables: {
token: token,
username: state.username,
password: values.password,
role: state.role
}
})
}}>
{({ errors, touched }) => (
<Form id="register-form">
<Field
name="password"
label="Insert a password"
autoFocus
component={SecretInput}
size="lg"
fullWidth
className={classes.input}
/>
<Field
name="confirmPassword"
label="Confirm your password"
component={SecretInput}
size="lg"
fullWidth
/>
<div className={classes.footer}>
{getErrorMsg(
errors,
touched,
queryError,
mutationError
) && (
<P className={classes.errorMessage}>
{getErrorMsg(
errors,
touched,
queryError,
mutationError
)}
</P>
)}
<Button
type="submit"
form="register-form"
buttonClassName={classes.loginButton}>
Done
</Button>
</div>
</Form>
)}
</Formik>
)}
{!loading && state.result === 'failure' && (
<>
<Label3>Link has expired</Label3>
<Label3>
To obtain a new link, run the command{' '}
<strong>lamassu-register</strong> in your servers terminal.
</Label3>
</>
)}
</div>
</Paper>
</div>
</Grid>
</Grid>
);
}
export default Register