diff --git a/public/locales/en.json b/public/locales/en.json index 7b23443..b8d485e 100644 --- a/public/locales/en.json +++ b/public/locales/en.json @@ -408,6 +408,7 @@ "autoRefreshNamePage": "Auto-refresh name page", "subMenuAdvanced": "Advanced settings", + "modalAuth": "Always prompt for master password with a modal dialog", "alwaysIncludeMined": "Always include mined transactions in transaction listings (may require refresh)", "copyNameSuffixes": "Include suffix when copying names", "addressCopyButtons": "Show copy buttons next to all addresses", diff --git a/src/components/auth/AuthMasterPasswordModal.tsx b/src/components/auth/AuthMasterPasswordModal.tsx new file mode 100644 index 0000000..52470eb --- /dev/null +++ b/src/components/auth/AuthMasterPasswordModal.tsx @@ -0,0 +1,42 @@ +// Copyright (c) 2020-2021 Drew Lemmy +// This file is part of KristWeb 2 under AGPL-3.0. +// Full details: https://github.com/tmpim/KristWeb2/blob/master/LICENSE.txt +import { useRef } from "react"; +import { Modal, Input } from "antd"; + +import { useTFns } from "@utils/i18n"; + +import { useAuthForm } from "./AuthMasterPasswordPopover"; + +interface Props { + visible: boolean; + encrypt?: boolean; + onCancel: () => void; + onSubmit: () => void; +} + +export function AuthMasterPasswordModal({ + visible, + encrypt, + onCancel, + onSubmit +}: Props): JSX.Element { + const { t, tStr } = useTFns("masterPassword."); + const inputRef = useRef(null); + + const { form, submit, reset } = useAuthForm({ encrypt, onSubmit, inputRef }); + + return { reset(); onCancel(); }} + onOk={submit} + > + {form} + ; +} diff --git a/src/components/auth/AuthMasterPasswordPopover.tsx b/src/components/auth/AuthMasterPasswordPopover.tsx index 26c0054..5b7952d 100644 --- a/src/components/auth/AuthMasterPasswordPopover.tsx +++ b/src/components/auth/AuthMasterPasswordPopover.tsx @@ -1,7 +1,7 @@ // Copyright (c) 2020-2021 Drew Lemmy // This file is part of KristWeb 2 under AGPL-3.0. // Full details: https://github.com/tmpim/KristWeb2/blob/master/LICENSE.txt -import { useState, useRef, useCallback, FC, Ref } from "react"; +import { useState, useRef, useMemo, useCallback, FC, Ref } from "react"; import { Popover, Button, Input, Form } from "antd"; import { TooltipPlacement } from "antd/lib/tooltip"; @@ -62,23 +62,54 @@ onSubmit, inputRef }: AuthFormProps): JSX.Element { + const { tStr } = useTFns("masterPassword."); + + const { form, submit } = useAuthForm({ encrypt, onSubmit, inputRef }); + + return <> + {form} + + {/* Submit button */} + + ; +} + +interface AuthFormRes { + form: JSX.Element; + submit: () => Promise; + reset: () => void; +} + +export function useAuthForm({ + encrypt, + onSubmit, + inputRef +}: AuthFormProps): AuthFormRes { const { t, tStr, tKey } = useTFns("masterPassword."); const { salt, tester } = useMasterPassword(); - const [form] = Form.useForm(); + const [form] = Form.useForm(); const [passwordError, setPasswordError] = useState(); - const onFinish = useCallback(async function(values: FormValues) { + const reset = useCallback(() => { + form.resetFields(); + }, [form]); + + const onFinish = useCallback(async function() { + const values = await form.validateFields(); + try { await authMasterPassword(salt, tester, values.masterPassword); onSubmit(); } catch (err) { setPasswordError(translateError(t, err, tKey("errorUnknown"))); } - }, [t, tKey, onSubmit, salt, tester]); + }, [t, tKey, onSubmit, salt, tester, form]); - return <> + const formEl = useMemo(() => <>

{tStr(encrypt ? "popoverDescriptionEncrypt" : "popoverDescription")}

{getMasterPasswordInput({ inputRef, - placeholder: t("masterPassword.passwordPlaceholder"), + placeholder: tStr("passwordPlaceholder"), autoFocus: true })} - {/* Submit button */} - + {/* Fake submit button to allow the enter key to submit in modal */} +