diff --git a/src/app/screens/Settings/index.tsx b/src/app/screens/Settings/index.tsx index 3fc69dd9e7..341c0c91de 100644 --- a/src/app/screens/Settings/index.tsx +++ b/src/app/screens/Settings/index.tsx @@ -4,6 +4,7 @@ import LocaleSwitcher from "@components/LocaleSwitcher/LocaleSwitcher"; import PasswordForm from "@components/PasswordForm"; import Setting from "@components/Setting"; import Input from "@components/form/Input"; +import TextField from "@components/form/TextField"; import Select from "@components/form/Select"; import Toggle from "@components/form/Toggle"; import { Html5Qrcode } from "html5-qrcode"; @@ -17,6 +18,7 @@ import { CURRENCIES } from "~/common/constants"; import msg from "~/common/lib/msg"; const initialFormData = { + currentPassword: "", password: "", passwordConfirmation: "", }; @@ -33,11 +35,13 @@ function Settings() { function closeModal() { setModalIsOpen(false); + setFormData(initialFormData); } - async function updateAccountPassword(password: string) { + async function updateAccountPassword() { try { await msg.request("changePassword", { + currentPassword: formData.currentPassword, password: formData.password, }); @@ -46,7 +50,7 @@ function Settings() { } catch (e) { console.error(e); if (e instanceof Error) - toast.error(`An unexpected error occurred: ${e.message}`); + toast.error(e.message); } } @@ -322,9 +326,25 @@ function Settings() {
{ e.preventDefault(); - updateAccountPassword(formData.password); + updateAccountPassword(); }} > +
+ { + setFormData({ + ...formData, + currentPassword: e.target.value, + }); + }} + /> +
+ { +const changePassword = async (message: MessageChangePassword) => { + const { currentPassword, password: newPassword } = message.args; + + if (typeof currentPassword !== "string" || currentPassword === "") { + return { error: "Current password is missing" }; + } + + if (typeof newPassword !== "string" || newPassword === "") { + return { error: "New password is missing" }; + } + const accounts = state.getState().accounts; - const password = await state.getState().password(); - if (!password) return { error: "Password is missing" }; - const newPassword = message.args.password as string; + const accountIds = Object.keys(accounts); + + if (accountIds.length > 0) { + // Verify current password by attempting to decrypt an account config + try { + decryptData(accounts[accountIds[0]].config as string, currentPassword); + } catch (e) { + return { error: "Invalid current password" }; + } + } + const tmpAccounts = { ...accounts }; - for (const accountId in tmpAccounts) { + for (const accountId in accounts) { + tmpAccounts[accountId] = { ...accounts[accountId] }; const accountConfig = decryptData( accounts[accountId].config as string, - password + currentPassword ); tmpAccounts[accountId].config = encryptData(accountConfig, newPassword); @@ -21,7 +40,7 @@ const changePassword = async (message: Message) => { if (accounts[accountId].nostrPrivateKey) { const accountNostrKey = decryptData( accounts[accountId].nostrPrivateKey as string, - password + currentPassword ); tmpAccounts[accountId].nostrPrivateKey = encryptData( accountNostrKey, @@ -33,7 +52,7 @@ const changePassword = async (message: Message) => { if (accounts[accountId].mnemonic) { const accountMnemonic = decryptData( accounts[accountId].mnemonic as string, - password + currentPassword ); tmpAccounts[accountId].mnemonic = encryptData( accountMnemonic, diff --git a/src/i18n/locales/en/translation.json b/src/i18n/locales/en/translation.json index 74640f3334..d055929590 100644 --- a/src/i18n/locales/en/translation.json +++ b/src/i18n/locales/en/translation.json @@ -654,6 +654,9 @@ "title": "Change Unlock Passcode", "subtitle": "", "screen_reader": "Change Unlock Passcode", + "current_password": { + "label": "Current unlock passcode:" + }, "choose_password": { "label": "Enter a new unlock passcode:" }, diff --git a/src/types.ts b/src/types.ts index b5771c3a40..46fb82413b 100644 --- a/src/types.ts +++ b/src/types.ts @@ -441,6 +441,14 @@ export interface MessageSetPassword extends MessageDefault { action: "setPassword"; } +export interface MessageChangePassword extends MessageDefault { + args: { + currentPassword: string; + password: string; + }; + action: "changePassword"; +} + export interface MessageAccountValidate extends MessageDefault { args: { connector: ConnectorType;