feat: Add pgp discovery key check from server

This commit is contained in:
Myzel394 2023-04-10 14:54:06 +02:00
parent 510dca0dd2
commit 3adc70f7a1
No known key found for this signature in database
GPG Key ID: 79CC92F37B3E1A2B
4 changed files with 31 additions and 19 deletions

View File

@ -5,7 +5,8 @@
"fields": { "fields": {
"publicKey": { "publicKey": {
"label": "Your public key", "label": "Your public key",
"helperText": "Paste your raw public key in armored format here." "helperText": "Paste your raw public key in armored format here.",
"placeholder": "----BEGIN PGP PUBLIC KEY BLOCK----\n\n...\n----END PGP PUBLIC KEY BLOCK----"
} }
}, },
"continueActionLabel": "Enable PGP encryption" "continueActionLabel": "Enable PGP encryption"

View File

@ -116,6 +116,7 @@ const router = createBrowserRouter([
}, },
{ {
path: "/settings/email-pgp", path: "/settings/email-pgp",
loader: getServerSettings,
element: <SettingsEmailPGPRoute />, element: <SettingsEmailPGPRoute />,
}, },
{ {

View File

@ -1,23 +1,27 @@
import * as yup from "yup" import * as yup from "yup"
import {useLoaderData} from "react-router-dom"
import {ReactElement, useContext, useState} from "react" import {ReactElement, useContext, useState} from "react"
import {useFormik} from "formik" import {useFormik} from "formik"
import {HiSearch} from "react-icons/hi"
import {AxiosError} from "axios"
import {RiLockFill} from "react-icons/ri"
import {useTranslation} from "react-i18next"
import {LoadingButton} from "@mui/lab"
import {useMutation} from "@tanstack/react-query" import {useMutation} from "@tanstack/react-query"
import {Box, FormGroup, FormHelperText, Grid, TextField} from "@mui/material" import {Box, FormGroup, FormHelperText, Grid, TextField} from "@mui/material"
import { import {
FindPublicKeyResponse, FindPublicKeyResponse,
UpdatePreferencesData, UpdatePreferencesData,
findPublicKey, findPublicKey,
updatePreferences, updatePreferences,
} from "~/apis" } from "~/apis"
import {HiSearch} from "react-icons/hi"
import {LoadingButton} from "@mui/lab"
import {parseFastAPIError} from "~/utils" import {parseFastAPIError} from "~/utils"
import {AxiosError} from "axios" import {ServerSettings, SimpleDetailResponse, User} from "~/server-types"
import {RiLockFill} from "react-icons/ri"
import {SimpleDetailResponse, User} from "~/server-types"
import {useTranslation} from "react-i18next"
import {useErrorSuccessSnacks} from "~/hooks" import {useErrorSuccessSnacks} from "~/hooks"
import {AuthContext} from "~/components" import {AuthContext} from "~/components"
import ImportKeyDialog from "./ImportKeyDialog" import ImportKeyDialog from "./ImportKeyDialog"
interface Form { interface Form {
@ -28,12 +32,13 @@ interface Form {
export default function SetupPGPEncryptionForm(): ReactElement { export default function SetupPGPEncryptionForm(): ReactElement {
const {t} = useTranslation(["settings-email-pgp", "common"]) const {t} = useTranslation(["settings-email-pgp", "common"])
const serverSettings = useLoaderData() as ServerSettings
const {showSuccess, showError} = useErrorSuccessSnacks() const {showSuccess, showError} = useErrorSuccessSnacks()
const [publicKeyResult, setPublicKeyResult] = useState<FindPublicKeyResponse | null>(null) const [publicKeyResult, setPublicKeyResult] = useState<FindPublicKeyResponse | null>(null)
const schema = yup.object().shape({ const schema = yup.object().shape({
publicKey: yup.string().label(t("form.publicKey.label")), publicKey: yup.string().label(t("form.publicKey.label")).min(1),
}) })
const {user, _updateUser} = useContext(AuthContext) const {user, _updateUser} = useContext(AuthContext)
@ -88,7 +93,7 @@ export default function SetupPGPEncryptionForm(): ReactElement {
<Grid container spacing={4} direction="column" alignItems="stretch"> <Grid container spacing={4} direction="column" alignItems="stretch">
<Grid item xs={12}> <Grid item xs={12}>
<FormGroup <FormGroup
title={t("form.fields.publicKey.title")} title={t("form.fields.publicKey.label")}
key="publicKey" key="publicKey"
sx={{width: "100%"}} sx={{width: "100%"}}
> >
@ -98,6 +103,7 @@ export default function SetupPGPEncryptionForm(): ReactElement {
minRows={5} minRows={5}
maxRows={15} maxRows={15}
label={t("form.fields.publicKey.label")} label={t("form.fields.publicKey.label")}
placeholder={t("form.fields.publicKey.placeholder")}
name="publicKey" name="publicKey"
value={formik.values.publicKey} value={formik.values.publicKey}
onChange={formik.handleChange} onChange={formik.handleChange}
@ -111,16 +117,18 @@ export default function SetupPGPEncryptionForm(): ReactElement {
{t("form.fields.publicKey.helperText")} {t("form.fields.publicKey.helperText")}
</FormHelperText> </FormHelperText>
</FormGroup> </FormGroup>
{serverSettings.allowPgpKeyDiscovery && (
<Box mt={1}> <Box mt={1}>
<LoadingButton <LoadingButton
loading={isFindingPublicKey} loading={isFindingPublicKey}
type="submit" type="button"
startIcon={<HiSearch />} startIcon={<HiSearch />}
onClick={() => findPublicKeyAsync()} onClick={() => findPublicKeyAsync()}
> >
{t("findPublicKey.label")} {t("findPublicKey.label")}
</LoadingButton> </LoadingButton>
</Box> </Box>
)}
</Grid> </Grid>
<Grid item alignSelf="center"> <Grid item alignSelf="center">
<LoadingButton <LoadingButton
@ -128,6 +136,7 @@ export default function SetupPGPEncryptionForm(): ReactElement {
type="submit" type="submit"
variant="contained" variant="contained"
startIcon={<RiLockFill />} startIcon={<RiLockFill />}
disabled={!formik.isValid}
> >
{t("form.continueActionLabel")} {t("form.continueActionLabel")}
</LoadingButton> </LoadingButton>

View File

@ -88,6 +88,7 @@ export interface ServerSettings {
allowAliasDeletion: boolean allowAliasDeletion: boolean
apiKeyMaxDays: number apiKeyMaxDays: number
allowRegistrations: boolean allowRegistrations: boolean
allowPgpKeyDiscovery: boolean
} }
export interface Alias { export interface Alias {