@@ -18,13 +18,12 @@ import { accounts as accountsObservable } from '@polkadot/ui-keyring/observable/
18
18
import { assert , isHex , u8aToHex } from '@polkadot/util' ;
19
19
import { keyExtractSuri , mnemonicGenerate , mnemonicValidate } from '@polkadot/util-crypto' ;
20
20
21
+ import chromeStorage from './chromeStorage' ;
21
22
import { POPUP_CREATE_WINDOW_DATA } from './consts' ;
22
23
import { openCenteredWindow } from './helpers' ;
23
24
import State from './State' ;
24
25
import { createSubscription , unsubscribe } from './subscriptions' ;
25
26
26
- type CachedUnlocks = Record < string , number > ;
27
-
28
27
type GetContentPort = ( tabId : number ) => chrome . runtime . Port
29
28
30
29
const SEED_DEFAULT_LENGTH = 12 ;
@@ -40,12 +39,9 @@ function isJsonPayload (value: SignerPayloadJSON | SignerPayloadRaw): value is S
40
39
}
41
40
42
41
export default class Extension {
43
- readonly #cachedUnlocks: CachedUnlocks ;
44
-
45
42
readonly #state: State ;
46
43
47
44
constructor ( state : State ) {
48
- this . #cachedUnlocks = { } ;
49
45
this . #state = state ;
50
46
}
51
47
@@ -137,20 +133,26 @@ export default class Extension {
137
133
return true ;
138
134
}
139
135
140
- private refreshAccountPasswordCache ( pair : KeyringPair ) : number {
136
+ private async refreshAccountPasswordCache ( pair : KeyringPair , options ?: { clearCache ?: boolean } ) : Promise < { remainingTime : number , cachedPassword ?: string } > {
141
137
const { address } = pair ;
142
138
143
- const savedExpiry = this . #cachedUnlocks[ address ] || 0 ;
144
- const remainingTime = savedExpiry - Date . now ( ) ;
139
+ const savedPasswords = await chromeStorage . getItem ( 'password-cache' ) ?? { } ;
140
+ const expiresAt = savedPasswords ?. [ address ] ?. expiresAt ?? 0 ;
141
+ const remainingTime = expiresAt - Date . now ( ) ;
142
+ const cachedPassword = savedPasswords ?. [ address ] ?. password ;
145
143
146
- if ( remainingTime < 0 ) {
147
- this . #cachedUnlocks [ address ] = 0 ;
148
- pair . lock ( ) ;
144
+ if ( remainingTime > 0 && ! options ?. clearCache ) {
145
+ return { remainingTime , cachedPassword } ;
146
+ }
149
147
150
- return 0 ;
148
+ if ( Object . keys ( savedPasswords ) . find ( ( key ) => key === address ) ) {
149
+ delete savedPasswords [ address ] ;
150
+ await chromeStorage . setItem ( 'password-cache' , ( ) => ( savedPasswords ) ) ;
151
151
}
152
152
153
- return remainingTime ;
153
+ pair . lock ( ) ;
154
+
155
+ return { remainingTime : 0 } ;
154
156
}
155
157
156
158
private accountsShow ( { address, isShowing } : RequestAccountShow ) : boolean {
@@ -334,14 +336,18 @@ export default class Extension {
334
336
} ;
335
337
}
336
338
337
- private async signingApprovePassword ( { id, password, savePass } : RequestSigningApprovePassword , getContentPort : GetContentPort ) : Promise < void > {
339
+ private async signingApprovePassword ( { id, password : inputPassword , savePass } : RequestSigningApprovePassword , getContentPort : GetContentPort ) : Promise < void > {
338
340
const queued = await this . #state. getSignRequest ( id ) ;
339
341
340
342
assert ( queued , 'Unable to find request' ) ;
341
343
342
344
const { payload } = queued ;
343
345
const pair = keyring . getPair ( queued . account . address ) ;
344
346
347
+ const { cachedPassword } = await this . refreshAccountPasswordCache ( pair ) ;
348
+
349
+ const password = cachedPassword ?? inputPassword ;
350
+
345
351
if ( ! pair ) {
346
352
const error = new Error ( 'Unable to find pair' ) ;
347
353
@@ -351,10 +357,10 @@ export default class Extension {
351
357
throw error ;
352
358
}
353
359
354
- this . refreshAccountPasswordCache ( pair ) ;
360
+ await this . refreshAccountPasswordCache ( pair ) ;
355
361
356
362
// if the keyring pair is locked, the password is needed
357
- if ( pair . isLocked && ! password ) {
363
+ if ( ! password ) {
358
364
const error = new Error ( 'Password needed to unlock the account' ) ;
359
365
360
366
await this . #state. removeSignRequest ( id ) ;
@@ -408,13 +414,14 @@ export default class Extension {
408
414
. createType ( 'ExtrinsicPayload' , payload , { version : payload . version } )
409
415
. sign ( pair ) ;
410
416
411
- if ( savePass ) {
417
+ if ( savePass && password ) {
412
418
// unlike queued.account.address the following
413
419
// address is encoded with the default prefix
414
420
// which what is used for password caching mapping
415
- this . #cachedUnlocks[ pair . address ] = Date . now ( ) + PASSWORD_EXPIRY_MS ;
421
+
422
+ await chromeStorage . setItem ( 'password-cache' , ( savedPasswords ) => ( { ...savedPasswords , [ pair . address ] : { password, expiresAt : Date . now ( ) + PASSWORD_EXPIRY_MS } } ) ) ;
416
423
} else {
417
- pair . lock ( ) ;
424
+ await this . refreshAccountPasswordCache ( pair , { clearCache : true } ) ;
418
425
}
419
426
420
427
await this . #state. removeSignRequest ( id ) ;
@@ -449,10 +456,9 @@ export default class Extension {
449
456
450
457
assert ( pair , 'Unable to find pair' ) ;
451
458
452
- const remainingTime = this . refreshAccountPasswordCache ( pair ) ;
459
+ const { remainingTime } = await this . refreshAccountPasswordCache ( pair ) ;
453
460
454
461
return {
455
- isLocked : pair . isLocked ,
456
462
remainingTime
457
463
} ;
458
464
}
0 commit comments