partial: Authentication css migration

This commit is contained in:
Rafael Taranto 2025-04-29 11:43:28 +01:00
parent 7b983d820d
commit 6cca41a5c2
14 changed files with 152 additions and 252 deletions

View file

@ -0,0 +1,73 @@
.welcomeBackground {
background: var(--ghost) url(/wizard-background.svg) no-repeat fixed center center;
background-size: cover;
height: 100vh;
width: 100vw;
position: relative;
left: 50%;
right: 50%;
margin-left: -50vw;
margin-right: -50vw;
min-height: 100vh;
}
.wrapper {
padding: 2.5em 4em;
width: 575px;
display: flex;
flex-direction: column;
}
.titleWrapper {
display: flex;
flex-direction: row;
align-items: center;
margin-bottom: 30px
}
.icon {
transform: scale(1.5);
margin-right: 25px;
}
.title {
padding-top: 8px;
}
.infoWrapper {
margin-bottom: 3vh;
}
.info2 {
text-align: justify;
}
.qrCodeWrapper {
display: flex;
justify-content: center;
margin-bottom: 3vh;
}
.secretWrapper {
display: flex;
justify-content: center;
align-items: center;
}
.secretLabel {
margin-right: 15px;
}
.secret {
margin-right: 35px;
}
.hiddenSecret {
margin-right: 35px;
filter: blur(8px);
}
.confirm2FAInput {
margin-top: 25px;
}

View file

@ -1,5 +1,4 @@
import { useMutation, useLazyQuery, gql } from "@apollo/client";
import { makeStyles } from '@mui/styles'
import { useMutation, useLazyQuery, gql } from '@apollo/client'
import { Form, Formik } from 'formik'
import React, { useContext, useState } from 'react'
import { useHistory } from 'react-router-dom'
@ -9,11 +8,8 @@ import AppContext from 'src/AppContext'
import { Button } from 'src/components/buttons'
import { CodeInput } from 'src/components/inputs/base'
import styles from './shared.styles'
import { STATES } from './states'
const useStyles = makeStyles(styles)
const INPUT_2FA = gql`
mutation input2FA(
$username: String!
@ -41,7 +37,6 @@ const GET_USER_DATA = gql`
`
const Input2FAState = ({ state, dispatch }) => {
const classes = useStyles()
const history = useHistory()
const { setUserData } = useContext(AppContext)
@ -104,9 +99,7 @@ const Input2FAState = ({ state, dispatch }) => {
return (
<>
<TL1 className={classes.info}>
Enter your two-factor authentication code
</TL1>
<TL1 className="mb-8">Enter your two-factor authentication code</TL1>
{/* TODO: refactor the 2FA CodeInput to properly use Formik */}
<Formik onSubmit={() => {}} initialValues={{}}>
<Form>
@ -117,15 +110,14 @@ const Input2FAState = ({ state, dispatch }) => {
numInputs={6}
error={invalidToken}
/>
<button onClick={handleSubmit} className={classes.enterButton} />
<div className="mt-9">
{errorMessage && <P className="text-tomato">{errorMessage}</P>}
<Button onClick={handleSubmit} buttonClassName="w-full">
Login
</Button>
</div>
</Form>
</Formik>
<div className={classes.twofaFooter}>
{errorMessage && <P className={classes.errorMessage}>{errorMessage}</P>}
<Button onClick={handleSubmit} buttonClassName={classes.loginButton}>
Login
</Button>
</div>
</>
)
}

View file

@ -1,5 +1,4 @@
import { useMutation, useLazyQuery, gql } from "@apollo/client";
import { makeStyles } from '@mui/styles'
import { useMutation, useLazyQuery, gql } from '@apollo/client'
import { startAssertion } from '@simplewebauthn/browser'
import { Field, Form, Formik } from 'formik'
import React, { useState, useContext } from 'react'
@ -11,10 +10,6 @@ import AppContext from 'src/AppContext'
import { Button } from 'src/components/buttons'
import { Checkbox, TextInput } from 'src/components/inputs/formik'
import styles from './shared.styles'
const useStyles = makeStyles(styles)
const GET_USER_DATA = gql`
{
userData {
@ -66,7 +61,6 @@ const InputFIDOState = ({ state, strategy }) => {
}
`
const classes = useStyles()
const history = useHistory()
const { setUserData } = useContext(AppContext)
@ -166,32 +160,25 @@ const InputFIDOState = ({ state, strategy }) => {
component={TextInput}
fullWidth
autoFocus
className={classes.input}
className="-mt-4 mb-6"
error={getErrorMsg(errors, touched)}
onKeyUp={() => {
if (invalidUsername) setInvalidUsername(false)
}}
/>
<div className={classes.rememberMeWrapper}>
<div className="mt-9 flex">
<Field
name="localRememberMe"
className={classes.checkbox}
className="-ml-2 transform-[scale(1.5)]"
component={Checkbox}
/>
<Label2 className={classes.inputLabel}>
Keep me logged in
</Label2>
<Label2>Keep me logged in</Label2>
</div>
<div className={classes.twofaFooter}>
<div className="mt-9">
{getErrorMsg(errors, touched) && (
<P className={classes.errorMessage}>
{getErrorMsg(errors, touched)}
</P>
<P className="text-tomato">{getErrorMsg(errors, touched)}</P>
)}
<Button
type="submit"
form="fido-form"
buttonClassName={classes.loginButton}>
<Button type="submit" form="fido-form" buttonClassName="w-full">
Use FIDO
</Button>
</div>
@ -201,14 +188,14 @@ const InputFIDOState = ({ state, strategy }) => {
)}
{strategy === 'FIDO2FA' && (
<>
<H2 className={classes.info}>
<H2 className="mb-8">
Insert your hardware key and follow the instructions
</H2>
<Button
type="button"
form="fido-form"
onClick={() => assertionOptions()}
buttonClassName={classes.loginButton}>
buttonClassName="w-full">
Use FIDO
</Button>
</>

View file

@ -1,15 +1,10 @@
import Grid from '@mui/material/Grid'
import { makeStyles } from '@mui/styles'
import React from 'react'
import LoginCard from './LoginCard'
import styles from './shared.styles'
const useStyles = makeStyles(styles)
import classes from './Authentication.module.css'
const Login = () => {
const classes = useStyles()
return (
<Grid
container
@ -22,7 +17,7 @@ const Login = () => {
<LoginCard />
</Grid>
</Grid>
);
)
}
export default Login

View file

@ -1,5 +1,4 @@
import Paper from '@mui/material/Paper'
import { makeStyles } from '@mui/styles'
import React, { useReducer } from 'react'
import { H5 } from 'src/components/typography'
import Logo from 'src/styling/icons/menu/logo.svg?react'
@ -8,14 +7,12 @@ import Input2FAState from './Input2FAState'
import InputFIDOState from './InputFIDOState'
import LoginState from './LoginState'
import Setup2FAState from './Setup2FAState'
import styles from './shared.styles'
import { STATES } from './states'
import classes from './Authentication.module.css'
// FIDO2FA, FIDOPasswordless or FIDOUsernameless
const AUTHENTICATION_STRATEGY = 'FIDO2FA'
const useStyles = makeStyles(styles)
const initialState = {
twoFAField: '',
clientField: '',
@ -30,8 +27,6 @@ const reducer = (state, action) => {
}
const LoginCard = () => {
const classes = useStyles()
const [state, dispatch] = useReducer(reducer, initialState)
const renderState = () => {

View file

@ -1,5 +1,4 @@
import { useMutation, useLazyQuery, gql } from "@apollo/client";
import { makeStyles } from '@mui/styles'
import { useMutation, useLazyQuery, gql } from '@apollo/client'
import { startAssertion } from '@simplewebauthn/browser'
import { Field, Form, Formik } from 'formik'
import React, { useContext } from 'react'
@ -11,10 +10,6 @@ import AppContext from 'src/AppContext'
import { Button } from 'src/components/buttons'
import { Checkbox, SecretInput, TextInput } from 'src/components/inputs/formik'
import styles from './shared.styles'
const useStyles = makeStyles(styles)
const LOGIN = gql`
mutation login($username: String!, $password: String!) {
login(username: $username, password: $password)
@ -68,7 +63,6 @@ const getErrorMsg = (formikErrors, formikTouched, mutationError) => {
}
const LoginState = ({ state, dispatch, strategy }) => {
const classes = useStyles()
const history = useHistory()
const { setUserData } = useContext(AppContext)
@ -148,7 +142,7 @@ const LoginState = ({ state, dispatch, strategy }) => {
component={TextInput}
fullWidth
autoFocus
className={classes.input}
className="-mt-4 mb-6"
error={getErrorMsg(
errors,
touched,
@ -173,15 +167,16 @@ const LoginState = ({ state, dispatch, strategy }) => {
userDataQueryError
)}
/>
<div className={classes.rememberMeWrapper}>
<div className="mt-9 flex">
<Field
name="rememberMe"
className={classes.checkbox}
className="-ml-2 transform-[scale(1.5)]"
component={Checkbox}
size="medium"
/>
<Label3>Keep me logged in</Label3>
</div>
<div className={classes.footer}>
<div className="mt-15">
{getErrorMsg(
errors,
touched,
@ -190,7 +185,7 @@ const LoginState = ({ state, dispatch, strategy }) => {
assertionQueryError ||
userDataQueryError
) && (
<P className={classes.errorMessage}>
<P className="text-tomato">
{getErrorMsg(
errors,
touched,
@ -214,15 +209,12 @@ const LoginState = ({ state, dispatch, strategy }) => {
payload: {}
})
}}
buttonClassName={classes.loginButton}
className={classes.fidoLoginButtonWrapper}>
buttonClassName="w-full"
className="mb-3">
I have a hardware key
</Button>
)}
<Button
type="submit"
form="login-form"
buttonClassName={classes.loginButton}>
<Button type="submit" form="login-form" buttonClassName="w-full">
Login
</Button>
</div>

View file

@ -1,6 +1,5 @@
import { useQuery, useMutation, gql } from "@apollo/client";
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'
@ -11,11 +10,9 @@ import * as Yup from 'yup'
import { Button } from 'src/components/buttons'
import { SecretInput } from 'src/components/inputs/formik'
import styles from './shared.styles'
import classes from './Authentication.module.css'
const QueryParams = () => new URLSearchParams(useLocation().search)
const useStyles = makeStyles(styles)
const VALIDATE_REGISTER_LINK = gql`
query validateRegisterLink($token: String!) {
@ -87,7 +84,6 @@ const getErrorMsg = (
}
const Register = () => {
const classes = useStyles()
const history = useHistory()
const token = QueryParams().get('t')
@ -165,7 +161,7 @@ const Register = () => {
component={SecretInput}
size="lg"
fullWidth
className={classes.input}
className="-mt-4 mb-6"
/>
<Field
name="confirmPassword"
@ -174,14 +170,14 @@ const Register = () => {
size="lg"
fullWidth
/>
<div className={classes.footer}>
<div className="mt-15">
{getErrorMsg(
errors,
touched,
queryError,
mutationError
) && (
<P className={classes.errorMessage}>
<P className="text-tomato">
{getErrorMsg(
errors,
touched,
@ -193,7 +189,7 @@ const Register = () => {
<Button
type="submit"
form="register-form"
buttonClassName={classes.loginButton}>
buttonClassName="w-full">
Done
</Button>
</div>
@ -215,7 +211,7 @@ const Register = () => {
</div>
</Grid>
</Grid>
);
)
}
export default Register

View file

@ -1,6 +1,5 @@
import { useQuery, useMutation, gql } from "@apollo/client";
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 { Form, Formik } from 'formik'
import { QRCodeSVG as QRCode } from 'qrcode.react'
@ -13,9 +12,7 @@ import { ActionButton, Button } from 'src/components/buttons'
import { CodeInput } from 'src/components/inputs/base'
import { primaryColor } from 'src/styling/variables'
import styles from './shared.styles'
const useStyles = makeStyles(styles)
import classes from './Authentication.module.css'
const VALIDATE_RESET_2FA_LINK = gql`
query validateReset2FALink($token: String!) {
@ -46,7 +43,6 @@ const reducer = (state, action) => {
}
const Reset2FA = () => {
const classes = useStyles()
const history = useHistory()
const QueryParams = () => new URLSearchParams(useLocation().search)
const token = QueryParams().get('t')
@ -177,23 +173,19 @@ const Reset2FA = () => {
numInputs={6}
error={invalidToken}
/>
<button
onClick={handleSubmit}
className={classes.enterButton}
/>
<div className="mt-9">
{getErrorMsg() && (
<P className="text-tomato">{getErrorMsg()}</P>
)}
<Button
onClick={handleSubmit}
buttonClassName="w-full">
Done
</Button>
</div>
</Form>
</Formik>
</div>
<div className={classes.twofaFooter}>
{getErrorMsg() && (
<P className={classes.errorMessage}>{getErrorMsg()}</P>
)}
<Button
onClick={handleSubmit}
buttonClassName={classes.loginButton}>
Done
</Button>
</div>
</>
)}
{!loading && state.result === 'failure' && (
@ -206,7 +198,7 @@ const Reset2FA = () => {
</div>
</Grid>
</Grid>
);
)
}
export default Reset2FA

View file

@ -1,6 +1,5 @@
import { useQuery, useMutation, gql } from "@apollo/client";
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, { useState } from 'react'
@ -12,9 +11,7 @@ import * as Yup from 'yup'
import { Button } from 'src/components/buttons'
import { SecretInput } from 'src/components/inputs/formik/'
import styles from './shared.styles'
const useStyles = makeStyles(styles)
import classes from './Authentication.module.css'
const VALIDATE_RESET_PASSWORD_LINK = gql`
query validateResetPasswordLink($token: String!) {
@ -60,7 +57,6 @@ const getErrorMsg = (formikErrors, formikTouched, mutationError) => {
}
const ResetPassword = () => {
const classes = useStyles()
const history = useHistory()
const QueryParams = () => new URLSearchParams(useLocation().search)
const token = QueryParams().get('t')
@ -129,7 +125,7 @@ const ResetPassword = () => {
component={SecretInput}
label="New password"
fullWidth
className={classes.input}
className="-mt-4 mb-6"
/>
<Field
name="confirmPassword"
@ -138,16 +134,16 @@ const ResetPassword = () => {
label="Confirm your password"
fullWidth
/>
<div className={classes.footer}>
<div className="mt-15">
{getErrorMsg(errors, touched, error) && (
<P className={classes.errorMessage}>
<P className="text-tomato">
{getErrorMsg(errors, touched, error)}
</P>
)}
<Button
type="submit"
form="reset-password"
buttonClassName={classes.loginButton}>
buttonClassName="w-full">
Done
</Button>
</div>
@ -165,7 +161,7 @@ const ResetPassword = () => {
</div>
</Grid>
</Grid>
);
)
}
export default ResetPassword

View file

@ -1,5 +1,4 @@
import { useMutation, useQuery, useLazyQuery, gql } from "@apollo/client";
import { makeStyles } from '@mui/styles'
import { useMutation, useQuery, useLazyQuery, gql } from '@apollo/client'
import { Form, Formik } from 'formik'
import { QRCodeSVG as QRCode } from 'qrcode.react'
import React, { useContext, useState } from 'react'
@ -11,7 +10,7 @@ import { ActionButton, Button } from 'src/components/buttons'
import { CodeInput } from 'src/components/inputs/base'
import { primaryColor } from 'src/styling/variables'
import styles from './shared.styles'
import classes from './Authentication.module.css'
const SETUP_2FA = gql`
mutation setup2FA(
@ -48,10 +47,7 @@ const GET_USER_DATA = gql`
}
`
const useStyles = makeStyles(styles)
const Setup2FAState = ({ state, dispatch }) => {
const classes = useStyles()
const history = useHistory()
const { setUserData } = useContext(AppContext)
@ -159,18 +155,17 @@ const Setup2FAState = ({ state, dispatch }) => {
error={invalidToken}
shouldAutoFocus
/>
<button onClick={handleSubmit} className={classes.enterButton} />
<div className="mt-9">
{getErrorMsg() && (
<P className="text-tomato">{getErrorMsg()}</P>
)}
<Button onClick={handleSubmit} buttonClassName="w-full">
Done
</Button>
</div>
</Form>
</Formik>
</div>
<div className={classes.twofaFooter}>
{getErrorMsg() && (
<P className={classes.errorMessage}>{getErrorMsg()}</P>
)}
<Button onClick={handleSubmit} buttonClassName={classes.loginButton}>
Done
</Button>
</div>
</>
)
)

View file

@ -1,109 +0,0 @@
import { backgroundColor, errorColor } from 'src/styling/variables'
const styles = {
title: {
paddingTop: 8
},
input: {
marginBottom: 25,
marginTop: -15
},
wrapper: {
padding: '2.5em 4em',
width: 575,
display: 'flex',
flexDirection: 'column'
},
titleWrapper: {
display: 'flex',
flexDirection: 'row',
alignItems: 'center',
marginBottom: 30
},
rememberMeWrapper: {
marginTop: 35,
display: 'flex',
flexDirection: 'row'
},
icon: {
transform: 'scale(1.5)',
marginRight: 25
},
checkbox: {
transform: 'scale(1.5)',
marginRight: 5,
marginLeft: -5
},
footer: {
marginTop: '10vh'
},
twofaFooter: {
marginTop: '6vh'
},
fidoLoginButtonWrapper: {
marginBottom: 12
},
loginButton: {
display: 'block',
width: '100%'
},
welcomeBackground: {
background: 'url(/wizard-background.svg) no-repeat center center fixed',
backgroundColor: backgroundColor,
backgroundSize: 'cover',
height: '100vh',
width: '100vw',
position: 'relative',
left: '50%',
right: '50%',
marginLeft: '-50vw',
marginRight: '-50vw',
minHeight: '100vh'
},
info: {
marginBottom: '5vh'
},
info2: {
textAlign: 'justify'
},
infoWrapper: {
marginBottom: '3vh'
},
errorMessage: {
color: errorColor
},
qrCodeWrapper: {
display: 'flex',
justifyContent: 'center',
marginBottom: '3vh'
},
secretWrapper: {
display: 'flex',
justifyContent: 'center',
alignItems: 'center'
},
secretLabel: {
marginRight: 15
},
secret: {
marginRight: 35
},
hiddenSecret: {
marginRight: 35,
filter: 'blur(8px)'
},
confirm2FAInput: {
marginTop: 25
},
confirmPassword: {
marginTop: 25
},
error: {
color: errorColor
},
enterButton: {
display: 'none'
}
}
export default styles

View file

@ -118,9 +118,6 @@ const styles = {
actionButtonWrapper: {
display: 'flex',
gap: 12
},
enterButton: {
display: 'none'
}
}

View file

@ -1,4 +1,4 @@
import { useMutation, gql } from "@apollo/client";
import { useMutation, gql } from '@apollo/client'
import { makeStyles } from '@mui/styles'
import classnames from 'classnames'
import { Field, Form, Formik } from 'formik'
@ -73,7 +73,7 @@ const CreateUserModal = ({ state, dispatch }) => {
const [createUser, { error }] = useMutation(CREATE_USER, {
onCompleted: ({ createRegisterToken: token }) => {
setCreateUserURL(urlResolver(`/register?t${token.token}`))
setCreateUserURL(urlResolver(`/register?t=${token.token}`))
}
})

View file

@ -1,4 +1,4 @@
import { useLazyQuery, gql } from "@apollo/client";
import { useLazyQuery, gql } from '@apollo/client'
import { makeStyles } from '@mui/styles'
import { Form, Formik } from 'formik'
import React, { useState } from 'react'
@ -80,17 +80,16 @@ const Input2FAModal = ({ showModal, handleClose, setConfirmation }) => {
error={invalidCode}
containerStyle={classes.codeContainer}
/>
<button onClick={handleSubmit} className={classes.enterButton} />
{getErrorMsg() && (
<P className={classes.errorMessage}>{getErrorMsg()}</P>
)}
<div className={classes.footer}>
<Button className={classes.submit} onClick={handleSubmit}>
Confirm
</Button>
</div>
</Form>
</Formik>
{getErrorMsg() && (
<P className={classes.errorMessage}>{getErrorMsg()}</P>
)}
<div className={classes.footer}>
<Button className={classes.submit} onClick={handleSubmit}>
Confirm
</Button>
</div>
</Modal>
)
)