current stand

This commit is contained in:
Myzel394 2022-11-24 14:33:26 +01:00
parent f9f1a1708c
commit 9fd322ec9a
4 changed files with 100 additions and 6 deletions

View File

@ -331,6 +331,12 @@
"title": "Are you sure you want to leave?", "title": "Are you sure you want to leave?",
"description": "You have unsaved changes. If you leave, your changes will be lost.", "description": "You have unsaved changes. If you leave, your changes will be lost.",
"continueLabel": "Leave" "continueLabel": "Leave"
},
"passwordShareConfirmationDialog": {
"title": "Share Password?",
"description": "An extension is asking for your password. Do you want to share it? Only continue if you initiated this action.",
"warning": "THIS WILL SHARE YOUR PASSWORD WITH THE EXTENSION. ALL YOUR DATA CAN BE DECRYPTED USING IT. ONLY CONTINUE IF YOU TRUST THE EXTENSION AND IF YOU INITIATED THE REQUEST.",
"continueAction": "Share Password"
} }
}, },

View File

@ -1,17 +1,19 @@
import {ReactElement, ReactNode, useCallback, useEffect, useMemo} from "react" import {ReactElement, ReactNode, useCallback, useEffect, useMemo, useState} from "react"
import {useLocalStorage} from "react-use" import {useLocalStorage, useSessionStorage} from "react-use"
import {AxiosError} from "axios" import {AxiosError} from "axios"
import {decrypt, readMessage, readPrivateKey} from "openpgp" import {decrypt, readMessage, readPrivateKey} from "openpgp"
import {useNavigate} from "react-router-dom" import {useNavigate} from "react-router-dom"
import {useMutation} from "@tanstack/react-query" import {useMutation} from "@tanstack/react-query"
import {Dialog} from "@mui/material"
import AuthContext, {AuthContextType, EncryptionStatus} from "./AuthContext"
import {ServerUser, User} from "~/server-types" import {ServerUser, User} from "~/server-types"
import {REFRESH_TOKEN_URL, RefreshTokenResult, logout as logoutUser, refreshToken} from "~/apis" import {REFRESH_TOKEN_URL, RefreshTokenResult, logout as logoutUser, refreshToken} from "~/apis"
import {client} from "~/constants/axios-client" import {client} from "~/constants/axios-client"
import {decryptString, encryptString} from "~/utils" import {decryptString, encryptString} from "~/utils"
import PasswordShareConfirmationDialog from "~/AuthContext/PasswordShareConfirmationDialog"
import AuthContext, {AuthContextType, EncryptionStatus} from "./AuthContext"
export interface AuthContextProviderProps { export interface AuthContextProviderProps {
children: ReactNode children: ReactNode
@ -22,6 +24,12 @@ export default function AuthContextProvider({children}: AuthContextProviderProps
onError: () => logout(false), onError: () => logout(false),
}) })
const [askForPassword, setAskForPassword] = useState<boolean>(false)
const [doNotAskForPassword, setDoNotAskForPassword] = useSessionStorage<boolean>(
"do-not-ask-again-for-password",
false,
)
const [decryptionPassword, setDecryptionPassword] = useLocalStorage<string | null>( const [decryptionPassword, setDecryptionPassword] = useLocalStorage<string | null>(
"_global-context-auth-decryption-password", "_global-context-auth-decryption-password",
null, null,
@ -190,5 +198,16 @@ export default function AuthContextProvider({children}: AuthContextProviderProps
return () => client.interceptors.response.eject(interceptor) return () => client.interceptors.response.eject(interceptor)
}, [logout, refresh]) }, [logout, refresh])
return <AuthContext.Provider value={value}>{children}</AuthContext.Provider> // Handle extension password request
return (
<>
<AuthContext.Provider value={value}>{children}</AuthContext.Provider>
<PasswordShareConfirmationDialog
open={askForPassword}
onShare={}
onClose={() => setAskForPassword(false)}
/>
</>
)
} }

View File

@ -0,0 +1,69 @@
import {ReactElement, useMemo, useState} from "react"
import {useTranslation} from "react-i18next"
import {TiCancel} from "react-icons/ti"
import {
Alert,
Button,
Checkbox,
Dialog,
DialogActions,
DialogContent,
DialogContentText,
DialogTitle,
FormControlLabel,
} from "@mui/material"
export interface PasswordShareConfirmationDialogProps {
open: boolean
onShare: (doNotAskAgain: boolean) => void
onClose: () => void
}
export default function PasswordShareConfirmationDialog({
open,
onShare,
onClose,
}: PasswordShareConfirmationDialogProps): ReactElement {
const [doNotAskAgain, setDoNotAskAgain] = useState<boolean>(false)
const askAmount = useMemo<number>(
() => Number(sessionStorage.getItem("password-share-ask-amount") || 0) + 1,
[],
)
const {t} = useTranslation()
return (
<Dialog open={open} onClose={onClose}>
<DialogTitle>{t("components.passwordShareConfirmationDialog.title")}</DialogTitle>
<DialogContent>
<DialogContentText>
{t("components.passwordShareConfirmationDialog.description")}
</DialogContentText>
<Alert severity="warning">
{t("components.passwordShareConfirmationDialog.warning")}
</Alert>
{askAmount > 1 && (
<FormControlLabel
control={
<Checkbox
value={doNotAskAgain}
onChange={event =>
setDoNotAskAgain(event.target.value as any as boolean)
}
/>
}
label={t("components.passwordShareConfirmationDialog.doNotAskAgain")}
/>
)}
</DialogContent>
<DialogActions>
<Button startIcon={<TiCancel />} onClick={onClose}>
{t("components.general.cancelLabel")}
</Button>
<Button onClick={() => onShare(doNotAskAgain)}>
{t("components.passwordShareConfirmationDialog.continueAction")}
</Button>
</DialogActions>
</Dialog>
)
}

View File

@ -1,5 +1,6 @@
import {ReactElement, useContext} from "react" import {ReactElement, useContext} from "react"
import {useEffectOnce} from "react-use"
import AuthContext from "~/AuthContext/AuthContext" import AuthContext from "~/AuthContext/AuthContext"
export default function ExtensionSignalHandler(): ReactElement { export default function ExtensionSignalHandler(): ReactElement {
@ -7,7 +8,6 @@ export default function ExtensionSignalHandler(): ReactElement {
const appDomain = import.meta.env.VITE_SERVER_BASE_URL const appDomain = import.meta.env.VITE_SERVER_BASE_URL
const instanceData = { const instanceData = {
appDomain, appDomain,
isAuthenticated: Boolean(user),
} }
return ( return (