Skip to content

Commit

Permalink
Fix Lock and Unlock system (#247)
Browse files Browse the repository at this point in the history
* Fix and simplify lock unlock system

* rename to lockWallet

* Don't show lock and unlock if wallet is not imported

* Ask for encryption before syncing

* Review fix
  • Loading branch information
panleone authored Nov 8, 2023
1 parent 325e2a4 commit d0d57c8
Show file tree
Hide file tree
Showing 4 changed files with 64 additions and 52 deletions.
68 changes: 42 additions & 26 deletions scripts/dashboard/Dashboard.vue
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ import { guiAddContactPrompt } from '../contacts-book';
import { scanQRCode } from '../scanner';
const isImported = ref(wallet.isLoaded());
const isViewOnly = ref(wallet.isViewOnly());
const activity = ref(null);
const needsToEncrypt = ref(true);
const showTransferMenu = ref(false);
Expand Down Expand Up @@ -180,43 +181,33 @@ async function importWallet({ type, secret, password = '' }) {
} else {
needsToEncrypt.value = false;
}
if (needsToEncrypt.value) showEncryptModal.value = true;
isViewOnly.value = wallet.isViewOnly();
await mempool.loadFromDisk();
await getNetwork().walletFullSync();
getEventEmitter().emit('wallet-import');
if (needsToEncrypt.value) showEncryptModal.value = true;
return true;
}
return false;
}
async function decryptWallet(strPassword) {
// Check if there's any encrypted WIF available
const database = await Database.getInstance();
const { encWif: strEncWIF } = await database.getAccount();
if (!strEncWIF || strEncWIF.length < 1) return false;
const strDecWIF = await decrypt(strEncWIF, strPassword);
if (!strDecWIF) {
return createAlert('warning', ALERTS.INCORRECT_PASSWORD, 6000);
} else {
await importWallet({
secret: strDecWIF,
});
return true;
}
}
/**
* Encrypt wallet
* @param {string} password - Password to encrypt wallet with
* @param {string} [currentPassword] - Current password with which the wallet is encrypted with, if any
*/
async function encryptWallet(password, currentPassword = '') {
if (await hasEncryptedWallet()) {
if (!(await decryptWallet(currentPassword))) return;
if (!(await wallet.checkDecryptPassword(currentPassword))) {
createAlert('warning', ALERTS.INCORRECT_PASSWORD, 6000);
return false;
}
}
const res = await wallet.encryptWallet(password);
const res = await wallet.encrypt(password);
if (res) {
createAlert('success', ALERTS.NEW_PASSWORD_SUCCESS, 5500);
}
Expand Down Expand Up @@ -269,6 +260,28 @@ async function restoreWallet(strReason) {
}
}
/**
* Lock the wallet by deleting masterkey private data
*/
async function lockWallet() {
const isEncrypted = await hasEncryptedWallet();
const title = isEncrypted
? translation.popupWalletLock
: translation.popupWalletWipe;
const html = isEncrypted
? translation.popupWalletLockNote
: translation.popupWalletWipeNote;
if (
await confirmPopup({
title,
html,
})
) {
wallet.wipePrivateData();
isViewOnly.value = wallet.isViewOnly();
}
}
/**
* Sends a transaction
* @param {string} address - Address or contact to send to
Expand Down Expand Up @@ -481,7 +494,10 @@ defineExpose({
<br />
<!-- Unlock wallet -->
<div class="col-12 p-0" id="guiRestoreWallet" hidden>
<div
class="col-12 p-0"
v-if="isViewOnly && !needsToEncrypt && isImported"
>
<center>
<div
class="dcWallet-warningMessage"
Expand Down Expand Up @@ -513,12 +529,12 @@ defineExpose({
<!-- // Unlock Wallet -->
<!-- Lock wallet -->
<div class="col-12" id="guiWipeWallet" hidden>
<div
class="col-12"
v-if="!isViewOnly && !needsToEncrypt && isImported"
>
<center>
<div
class="dcWallet-warningMessage"
onclick="MPW.wipePrivateData()"
>
<div class="dcWallet-warningMessage" @click="lockWallet()">
<div class="shieldLogo">
<div class="shieldBackground">
<span
Expand Down
24 changes: 0 additions & 24 deletions scripts/global.js
Original file line number Diff line number Diff line change
Expand Up @@ -174,8 +174,6 @@ export async function start() {
domMnemonicModalPassphrase: document.getElementById(
'ModalMnemonicPassphrase'
),
domWipeWallet: document.getElementById('guiWipeWallet'),
domRestoreWallet: document.getElementById('guiRestoreWallet'),
domRedeemTitle: document.getElementById('redeemCodeModalTitle'),
domRedeemCodeUse: document.getElementById('redeemCodeUse'),
domRedeemCodeCreate: document.getElementById('redeemCodeCreate'),
Expand Down Expand Up @@ -1054,28 +1052,6 @@ export async function guiSetColdStakingAddress() {
}
}

export async function wipePrivateData() {
const isEncrypted = await hasEncryptedWallet();
const title = isEncrypted
? translation.popupWalletLock
: translation.popupWalletWipe;
const html = isEncrypted
? translation.popupWalletLockNote
: translation.popupWalletWipeNote;
if (
await confirmPopup({
title,
html,
})
) {
wallet.wipePrivateData();
doms.domWipeWallet.hidden = true;
if (isEncrypted) {
doms.domRestoreWallet.hidden = false;
}
}
}

/**
* Prompt the user in the GUI to unlock their wallet
* @param {string} strReason - An optional reason for the unlock
Expand Down
1 change: 0 additions & 1 deletion scripts/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@ export {
accessOrImportWallet,
guiSetColdStakingAddress,
toClipboard,
wipePrivateData,
restoreWallet,
refreshChainData,
playMusic,
Expand Down
23 changes: 22 additions & 1 deletion scripts/wallet.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { validateMnemonic } from 'bip39';
import { decrypt } from './aes-gcm.js';
import { beforeUnloadListener } from './global.js';
import { getNetwork } from './network.js';
import { MAX_ACCOUNT_GAP } from './chain_params.js';
Expand Down Expand Up @@ -250,7 +251,27 @@ export class Wallet {
return !!this.#masterKey;
}

async encryptWallet(strPassword) {
/**
* Check if the current encrypted keyToBackup can be decrypted with the given password
* @param {string} strPassword
* @return {Promise<boolean>}
*/
async checkDecryptPassword(strPassword) {
// Check if there's any encrypted WIF available
const database = await Database.getInstance();
const { encWif: strEncWIF } = await database.getAccount();
if (!strEncWIF || strEncWIF.length < 1) return false;

const strDecWIF = await decrypt(strEncWIF, strPassword);
return !!strDecWIF;
}

/**
* Encrypt the keyToBackup with a given password
* @param {string} strPassword
* @returns {Promise<boolean}
*/
async encrypt(strPassword) {
// Encrypt the wallet WIF with AES-GCM and a user-chosen password - suitable for browser storage
let strEncWIF = await encrypt(this.#masterKey.keyToBackup, strPassword);
if (!strEncWIF) return false;
Expand Down

0 comments on commit d0d57c8

Please sign in to comment.