Skip to content
Open
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 23 additions & 3 deletions src/app/screens/Settings/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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";
Expand All @@ -17,6 +18,7 @@ import { CURRENCIES } from "~/common/constants";
import msg from "~/common/lib/msg";

const initialFormData = {
currentPassword: "",
Comment thread
coderabbitai[bot] marked this conversation as resolved.
password: "",
passwordConfirmation: "",
};
Expand All @@ -35,18 +37,20 @@ function Settings() {
setModalIsOpen(false);
}

async function updateAccountPassword(password: string) {
async function updateAccountPassword() {
try {
await msg.request("changePassword", {
currentPassword: formData.currentPassword,
password: formData.password,
});

toast.success(t("change_password.success"));
closeModal();
setFormData(initialFormData);
} catch (e) {
console.error(e);
if (e instanceof Error)
toast.error(`An unexpected error occurred: ${e.message}`);
toast.error(e.message);
Comment thread
coderabbitai[bot] marked this conversation as resolved.
}
}

Expand Down Expand Up @@ -322,9 +326,24 @@ function Settings() {
<form
onSubmit={(e: FormEvent) => {
e.preventDefault();
updateAccountPassword(formData.password);
updateAccountPassword();
}}
>
<div className="w-full mt-8">
<TextField
id="currentPassword"
type="password"
label={t("change_password.current_password.label")}
required
onChange={(e) => {
setFormData({
...formData,
currentPassword: e.target.value.trim(),
});
}}
/>
</div>

<PasswordForm
i18nKeyPrefix="settings.change_password"
formData={formData}
Expand All @@ -337,6 +356,7 @@ function Settings() {
type="submit"
primary
disabled={
!formData.currentPassword ||
!formData.password ||
formData.password !== formData.passwordConfirmation
}
Expand Down
34 changes: 26 additions & 8 deletions src/extension/background-script/actions/settings/changePassword.ts
Original file line number Diff line number Diff line change
@@ -1,27 +1,45 @@
import { decryptData, encryptData } from "~/common/lib/crypto";
import type { Message } from "~/types";
import type { MessageChangePassword } from "~/types";

import state from "../../state";

const changePassword = async (message: Message) => {
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) {
const accountConfig = decryptData(
accounts[accountId].config as string,
password
currentPassword
);
tmpAccounts[accountId].config = encryptData(accountConfig, newPassword);
Comment thread
coderabbitai[bot] marked this conversation as resolved.

// Re-encrypt nostr key with the new password
if (accounts[accountId].nostrPrivateKey) {
const accountNostrKey = decryptData(
accounts[accountId].nostrPrivateKey as string,
password
currentPassword
);
tmpAccounts[accountId].nostrPrivateKey = encryptData(
accountNostrKey,
Expand All @@ -33,7 +51,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,
Expand Down
3 changes: 3 additions & 0 deletions src/i18n/locales/en/translation.json
Original file line number Diff line number Diff line change
Expand Up @@ -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:"
},
Expand Down
8 changes: 8 additions & 0 deletions src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down