improvements; bugfixes

This commit is contained in:
Myzel394 2022-10-31 10:05:37 +01:00
parent 95189474a4
commit 963b9c4976
5 changed files with 100 additions and 24 deletions

View File

@ -2,7 +2,7 @@ import {useContext} from "react"
import {MdLock} from "react-icons/md" import {MdLock} from "react-icons/md"
import {Link as RouterLink} from "react-router-dom" import {Link as RouterLink} from "react-router-dom"
import {Button, Grid, Typography} from "@mui/material" import {Button, Grid, Typography, useTheme} from "@mui/material"
import AuthContext, {EncryptionStatus} from "~/AuthContext/AuthContext" import AuthContext, {EncryptionStatus} from "~/AuthContext/AuthContext"
import LockNavigationContext from "~/LockNavigationContext/LockNavigationContext" import LockNavigationContext from "~/LockNavigationContext/LockNavigationContext"
@ -16,11 +16,19 @@ export default function DecryptionPasswordMissingAlert({
}: WithEncryptionRequiredProps): JSX.Element { }: WithEncryptionRequiredProps): JSX.Element {
const {handleAnchorClick} = useContext(LockNavigationContext) const {handleAnchorClick} = useContext(LockNavigationContext)
const {encryptionStatus} = useContext(AuthContext) const {encryptionStatus} = useContext(AuthContext)
const theme = useTheme()
switch (encryptionStatus) { switch (encryptionStatus) {
case EncryptionStatus.Unavailable: { case EncryptionStatus.Unavailable: {
return ( return (
<Grid container spacing={4}> <Grid
paddingY={2}
bgcolor={theme.palette.background.default}
container
gap={2}
direction="column"
alignItems="center"
>
<Grid item> <Grid item>
<Typography variant="h6" component="h2"> <Typography variant="h6" component="h2">
Encryption required Encryption required
@ -35,7 +43,7 @@ export default function DecryptionPasswordMissingAlert({
<Button <Button
variant="contained" variant="contained"
component={RouterLink} component={RouterLink}
to="/complete-account?setup=true" to={`/auth/complete-account?setup=true&next=${window.location.pathname}`}
startIcon={<MdLock />} startIcon={<MdLock />}
onClick={handleAnchorClick} onClick={handleAnchorClick}
> >
@ -49,8 +57,10 @@ export default function DecryptionPasswordMissingAlert({
case EncryptionStatus.PasswordRequired: { case EncryptionStatus.PasswordRequired: {
return ( return (
<Grid <Grid
paddingY={2}
bgcolor={theme.palette.background.default}
container container
spacing={4} gap={2}
direction="column" direction="column"
alignItems="center" alignItems="center"
> >

View File

@ -8,3 +8,5 @@ export * from "./use-system-preferred-theme"
export {default as useSystemPreferredTheme} from "./use-system-preferred-theme" export {default as useSystemPreferredTheme} from "./use-system-preferred-theme"
export * from "./use-ui-state" export * from "./use-ui-state"
export {default as useUIState} from "./use-ui-state" export {default as useUIState} from "./use-ui-state"
export * from "./use-navigate-to-next"
export {default as useNavigateToNext} from "./use-navigate-to-next"

View File

@ -0,0 +1,27 @@
import {useLocation, useNavigate} from "react-router-dom"
import {useCallback} from "react"
export default function useNavigateToNext(defaultNextUrl = "/"): () => void {
const navigate = useNavigate()
const location = useLocation()
const navigateToNext = useCallback(() => {
const nextUrlSuggested =
new URLSearchParams(location.search).get("next") || ""
const nextUrl = (() => {
if (
nextUrlSuggested.startsWith("/") ||
nextUrlSuggested.startsWith(`https://${window.location.host}`)
) {
return nextUrlSuggested
}
return defaultNextUrl
})()
setTimeout(() => navigate(nextUrl), 0)
}, [location, navigate])
return navigateToNext
}

View File

@ -15,12 +15,15 @@ import {isDev} from "~/constants/development"
import {useSystemPreferredTheme, useUser} from "~/hooks" import {useSystemPreferredTheme, useUser} from "~/hooks"
import {MASTER_PASSWORD_LENGTH} from "~/constants/values" import {MASTER_PASSWORD_LENGTH} from "~/constants/values"
import {AuthenticationDetails, UserNote} from "~/server-types" import {AuthenticationDetails, UserNote} from "~/server-types"
import {AxiosError} from "axios"
import {UpdateAccountData, updateAccount} from "~/apis" import {UpdateAccountData, updateAccount} from "~/apis"
import {encryptUserNote} from "~/utils/encrypt-user-note" import {encryptUserNote} from "~/utils/encrypt-user-note"
import {useNavigate} from "react-router-dom" import {AxiosError} from "axios"
import AuthContext from "~/AuthContext/AuthContext" import AuthContext from "~/AuthContext/AuthContext"
export interface PasswordFormProps {
onDone: () => void
}
interface Form { interface Form {
password: string password: string
passwordConfirmation: string passwordConfirmation: string
@ -35,10 +38,11 @@ const schema = yup.object().shape({
.oneOf([yup.ref("password"), null], "Passwords must match"), .oneOf([yup.ref("password"), null], "Passwords must match"),
}) })
export default function PasswordForm(): ReactElement { export default function PasswordForm({
onDone,
}: PasswordFormProps): ReactElement {
const user = useUser() const user = useUser()
const theme = useSystemPreferredTheme() const theme = useSystemPreferredTheme()
const navigate = useNavigate()
const {_setDecryptionPassword, login} = useContext(AuthContext) const {_setDecryptionPassword, login} = useContext(AuthContext)
@ -60,7 +64,7 @@ export default function PasswordForm(): ReactElement {
>(updateAccount, { >(updateAccount, {
onSuccess: ({user}) => { onSuccess: ({user}) => {
login(user) login(user)
navigate("/") onDone()
}, },
}) })
const formik = useFormik<Form>({ const formik = useFormik<Form>({

View File

@ -1,13 +1,16 @@
import {ReactElement, useState} from "react" import {ReactElement, useContext, useState} from "react"
import {useLocation, useNavigate} from "react-router-dom"
import {Grid, Paper, Typography} from "@mui/material"
import {MultiStepForm} from "~/components" import {MultiStepForm} from "~/components"
import {useNavigateToNext} from "~/hooks"
import AuthContext, {EncryptionStatus} from "~/AuthContext/AuthContext"
import GenerateEmailReportsForm from "~/route-widgets/CompleteAccountRoute/GenerateEmailReportsForm" import GenerateEmailReportsForm from "~/route-widgets/CompleteAccountRoute/GenerateEmailReportsForm"
import PasswordForm from "~/route-widgets/CompleteAccountRoute/PasswordForm" import PasswordForm from "~/route-widgets/CompleteAccountRoute/PasswordForm"
export default function CompleteAccountRoute(): ReactElement { export default function CompleteAccountRoute(): ReactElement {
const navigate = useNavigate() const {encryptionStatus} = useContext(AuthContext)
const location = useLocation() const navigateToNext = useNavigateToNext()
// If query `setup` is `true`, skip directly to the setup // If query `setup` is `true`, skip directly to the setup
const [showGenerationReportForm, setShowGenerationReportForm] = useState( const [showGenerationReportForm, setShowGenerationReportForm] = useState(
@ -17,17 +20,47 @@ export default function CompleteAccountRoute(): ReactElement {
}, },
) )
if (encryptionStatus === EncryptionStatus.Unavailable) {
return (
<MultiStepForm
steps={[
<GenerateEmailReportsForm
key="generate_email_reports"
onYes={() => setShowGenerationReportForm(true)}
onNo={navigateToNext}
/>,
<PasswordForm
onDone={navigateToNext}
key="password_form"
/>,
]}
index={showGenerationReportForm ? 1 : 0}
/>
)
}
return ( return (
<MultiStepForm <Paper>
steps={[ <Grid
<GenerateEmailReportsForm container
key="generate_email_reports" spacing={4}
onYes={() => setShowGenerationReportForm(true)} padding={4}
onNo={() => navigate("/")} alignItems="center"
/>, justifyContent="center"
<PasswordForm key="password_form" />, flexDirection="column"
]} >
index={showGenerationReportForm ? 1 : 0} <Grid item>
/> <Typography variant="h6" component="h1" align="center">
Encryption already enabled
</Typography>
</Grid>
<Grid item>
<Typography variant="body1">
You already have encryption enabled. Changing passwords
is currently not supported.
</Typography>
</Grid>
</Grid>
</Paper>
) )
} }