mirror of
https://github.com/Myzel394/kleckrelay-website.git
synced 2025-06-20 00:05:26 +02:00
current stand
This commit is contained in:
parent
f9f1a1708c
commit
9fd322ec9a
@ -331,6 +331,12 @@
|
||||
"title": "Are you sure you want to leave?",
|
||||
"description": "You have unsaved changes. If you leave, your changes will be lost.",
|
||||
"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"
|
||||
}
|
||||
},
|
||||
|
||||
|
@ -1,17 +1,19 @@
|
||||
import {ReactElement, ReactNode, useCallback, useEffect, useMemo} from "react"
|
||||
import {useLocalStorage} from "react-use"
|
||||
import {ReactElement, ReactNode, useCallback, useEffect, useMemo, useState} from "react"
|
||||
import {useLocalStorage, useSessionStorage} from "react-use"
|
||||
import {AxiosError} from "axios"
|
||||
import {decrypt, readMessage, readPrivateKey} from "openpgp"
|
||||
import {useNavigate} from "react-router-dom"
|
||||
|
||||
import {useMutation} from "@tanstack/react-query"
|
||||
|
||||
import {Dialog} from "@mui/material"
|
||||
import AuthContext, {AuthContextType, EncryptionStatus} from "./AuthContext"
|
||||
|
||||
import {ServerUser, User} from "~/server-types"
|
||||
import {REFRESH_TOKEN_URL, RefreshTokenResult, logout as logoutUser, refreshToken} from "~/apis"
|
||||
import {client} from "~/constants/axios-client"
|
||||
import {decryptString, encryptString} from "~/utils"
|
||||
|
||||
import AuthContext, {AuthContextType, EncryptionStatus} from "./AuthContext"
|
||||
import PasswordShareConfirmationDialog from "~/AuthContext/PasswordShareConfirmationDialog"
|
||||
|
||||
export interface AuthContextProviderProps {
|
||||
children: ReactNode
|
||||
@ -22,6 +24,12 @@ export default function AuthContextProvider({children}: AuthContextProviderProps
|
||||
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>(
|
||||
"_global-context-auth-decryption-password",
|
||||
null,
|
||||
@ -190,5 +198,16 @@ export default function AuthContextProvider({children}: AuthContextProviderProps
|
||||
return () => client.interceptors.response.eject(interceptor)
|
||||
}, [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)}
|
||||
/>
|
||||
</>
|
||||
)
|
||||
}
|
||||
|
69
src/AuthContext/PasswordShareConfirmationDialog.tsx
Normal file
69
src/AuthContext/PasswordShareConfirmationDialog.tsx
Normal 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>
|
||||
)
|
||||
}
|
@ -1,5 +1,6 @@
|
||||
import {ReactElement, useContext} from "react"
|
||||
|
||||
import {useEffectOnce} from "react-use"
|
||||
import AuthContext from "~/AuthContext/AuthContext"
|
||||
|
||||
export default function ExtensionSignalHandler(): ReactElement {
|
||||
@ -7,7 +8,6 @@ export default function ExtensionSignalHandler(): ReactElement {
|
||||
const appDomain = import.meta.env.VITE_SERVER_BASE_URL
|
||||
const instanceData = {
|
||||
appDomain,
|
||||
isAuthenticated: Boolean(user),
|
||||
}
|
||||
|
||||
return (
|
||||
|
Loading…
x
Reference in New Issue
Block a user