Skip to content

Commit 86feec2

Browse files
author
Roberts
committed
A0-3946: Fix password saving function not working properly
1 parent 77b1b52 commit 86feec2

File tree

2 files changed

+78
-13
lines changed

2 files changed

+78
-13
lines changed

packages/extension-base/src/background/handlers/Extension.ts

+16-13
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ import type { SubjectInfo } from '@polkadot/ui-keyring/observable/types';
88
import type { KeypairType } from '@polkadot/util-crypto/types';
99
import type { AccountJson, AllowedPath, MessageTypes, RequestAccountChangePassword, RequestAccountCreateHardware, RequestAccountCreateSuri, RequestAccountEdit, RequestAccountExport, RequestAccountForget, RequestAccountShow, RequestAccountTie, RequestAccountValidate, RequestActiveTabUrlUpdate, RequestAuthorizeApprove, RequestAuthorizeReject, RequestBatchRestore, RequestDeriveCreate, RequestDeriveValidate, RequestJsonRestore, RequestMetadataApprove, RequestMetadataReject, RequestSeedCreate, RequestSeedValidate, RequestSigningApprovePassword, RequestSigningApproveSignature, RequestSigningCancel, RequestSigningIsLocked, RequestTypes, RequestUpdateAuthorizedAccounts, ResponseAccountExport, ResponseAuthorizeList, ResponseDeriveValidate, ResponseJsonGetAccountInfo, ResponseSeedCreate, ResponseSeedValidate, ResponseSigningIsLocked } from '../types';
1010

11-
import { ALLOWED_PATH, PASSWORD_EXPIRY_MS } from '@polkadot/extension-base/defaults';
11+
import { ALLOWED_PATH } from '@polkadot/extension-base/defaults';
1212
import { isJsonAuthentic, signJson } from '@polkadot/extension-base/utils/accountJsonIntegrity';
1313
import { metadataExpand } from '@polkadot/extension-chains';
1414
import { wrapBytes } from '@polkadot/extension-dapp';
@@ -18,13 +18,12 @@ import { accounts as accountsObservable } from '@polkadot/ui-keyring/observable/
1818
import { assert, isHex, u8aToHex } from '@polkadot/util';
1919
import { keyExtractSuri, mnemonicGenerate, mnemonicValidate } from '@polkadot/util-crypto';
2020

21+
import chromeStorage from './chromeStorage';
2122
import { POPUP_CREATE_WINDOW_DATA } from './consts';
2223
import { openCenteredWindow } from './helpers';
2324
import State from './State';
2425
import { createSubscription, unsubscribe } from './subscriptions';
2526

26-
type CachedUnlocks = Record<string, number>;
27-
2827
type GetContentPort = (tabId: number) => chrome.runtime.Port
2928

3029
const SEED_DEFAULT_LENGTH = 12;
@@ -40,12 +39,9 @@ function isJsonPayload (value: SignerPayloadJSON | SignerPayloadRaw): value is S
4039
}
4140

4241
export default class Extension {
43-
readonly #cachedUnlocks: CachedUnlocks;
44-
4542
readonly #state: State;
4643

4744
constructor (state: State) {
48-
this.#cachedUnlocks = {};
4945
this.#state = state;
5046
}
5147

@@ -137,14 +133,15 @@ export default class Extension {
137133
return true;
138134
}
139135

140-
private refreshAccountPasswordCache (pair: KeyringPair): number {
136+
private async refreshAccountPasswordCache (pair: KeyringPair): Promise<number> {
141137
const { address } = pair;
142138

143-
const savedExpiry = this.#cachedUnlocks[address] || 0;
139+
const savedExpiry = await chromeStorage.getPasswordExpiry(address);
140+
144141
const remainingTime = savedExpiry - Date.now();
145142

146143
if (remainingTime < 0) {
147-
this.#cachedUnlocks[address] = 0;
144+
await chromeStorage.removePassword(address);
148145
pair.lock();
149146

150147
return 0;
@@ -351,7 +348,7 @@ export default class Extension {
351348
throw error;
352349
}
353350

354-
this.refreshAccountPasswordCache(pair);
351+
await this.refreshAccountPasswordCache(pair);
355352

356353
// if the keyring pair is locked, the password is needed
357354
if (pair.isLocked && !password) {
@@ -412,9 +409,15 @@ export default class Extension {
412409
// unlike queued.account.address the following
413410
// address is encoded with the default prefix
414411
// which what is used for password caching mapping
415-
this.#cachedUnlocks[pair.address] = Date.now() + PASSWORD_EXPIRY_MS;
412+
await chromeStorage.setPassword(pair.address);
416413
} else {
417-
pair.lock();
414+
const savedExpiry = await chromeStorage.getPasswordExpiry(pair.address);
415+
416+
const remainingTime = savedExpiry - Date.now();
417+
418+
if (remainingTime <= 0) {
419+
pair.lock();
420+
}
418421
}
419422

420423
await this.#state.removeSignRequest(id);
@@ -449,7 +452,7 @@ export default class Extension {
449452

450453
assert(pair, 'Unable to find pair');
451454

452-
const remainingTime = this.refreshAccountPasswordCache(pair);
455+
const remainingTime = await this.refreshAccountPasswordCache(pair);
453456

454457
return {
455458
isLocked: pair.isLocked,
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
import { z } from 'zod';
2+
3+
import { PASSWORD_EXPIRY_MS } from '../../defaults';
4+
5+
type PasswordExpiry = {
6+
savePass: {
7+
[key: string]: number
8+
};
9+
}
10+
11+
async function getPasswordExpiry (address: string): Promise<number> {
12+
const addressSchema = z.string();
13+
14+
if (addressSchema.safeParse(address).success) {
15+
const { savePass } = await chrome.storage.session.get('savePass') as PasswordExpiry;
16+
17+
if (savePass?.[address]) {
18+
return savePass[address];
19+
} else {
20+
return 0;
21+
}
22+
} else {
23+
return 0;
24+
}
25+
}
26+
27+
async function setPassword (address: string): Promise<void> {
28+
const addressSchema = z.string();
29+
30+
if (addressSchema.safeParse(address).success) {
31+
const { savePass } = await chrome.storage.session.get('savePass') as PasswordExpiry;
32+
33+
if (savePass) {
34+
await chrome.storage.session.set({ savePass: { ...savePass, [address]: Date.now() + PASSWORD_EXPIRY_MS } });
35+
} else {
36+
await chrome.storage.session.set({ savePass: { [address]: Date.now() + PASSWORD_EXPIRY_MS } });
37+
}
38+
} else {
39+
console.log('error', 'Provided address is incorrect');
40+
}
41+
}
42+
43+
async function removePassword (address: string): Promise<void> {
44+
const addressSchema = z.string();
45+
46+
if (addressSchema.safeParse(address).success) {
47+
const { savePass } = await chrome.storage.session.get('savePass') as PasswordExpiry;
48+
49+
if (savePass) {
50+
delete savePass[address];
51+
await chrome.storage.session.set({ savePass });
52+
}
53+
}
54+
}
55+
56+
const chromeStorage = {
57+
setPassword,
58+
getPasswordExpiry,
59+
removePassword
60+
};
61+
62+
export default chromeStorage;

0 commit comments

Comments
 (0)