@@ -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,39 @@ export default class Extension {
137
133
return true ;
138
134
}
139
135
140
- private refreshAccountPasswordCache ( pair : KeyringPair ) : number {
136
+ private async refreshAccountPasswordCache ( pair : KeyringPair ) : 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 ) {
145
+ return { remainingTime , cachedPassword } ;
146
+ }
149
147
150
- return 0 ;
148
+ if ( address in savedPasswords ) {
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 } ;
156
+ }
157
+
158
+ private async clearPasswordCache ( pair : KeyringPair ) : Promise < void > {
159
+ const { address } = pair ;
160
+
161
+ const savedPasswords = await chromeStorage . getItem ( 'password-cache' ) ?? { } ;
162
+
163
+ if ( address in savedPasswords ) {
164
+ delete savedPasswords [ address ] ;
165
+ await chromeStorage . setItem ( 'password-cache' , ( ) => ( savedPasswords ) ) ;
166
+ }
167
+
168
+ pair . lock ( ) ;
154
169
}
155
170
156
171
private accountsShow ( { address, isShowing } : RequestAccountShow ) : boolean {
@@ -334,7 +349,7 @@ export default class Extension {
334
349
} ;
335
350
}
336
351
337
- private async signingApprovePassword ( { id, password, savePass } : RequestSigningApprovePassword , getContentPort : GetContentPort ) : Promise < void > {
352
+ private async signingApprovePassword ( { id, password : inputPassword , savePass } : RequestSigningApprovePassword , getContentPort : GetContentPort ) : Promise < void > {
338
353
const queued = await this . #state. getSignRequest ( id ) ;
339
354
340
355
assert ( queued , 'Unable to find request' ) ;
@@ -351,10 +366,12 @@ export default class Extension {
351
366
throw error ;
352
367
}
353
368
354
- this . refreshAccountPasswordCache ( pair ) ;
369
+ const { cachedPassword } = await this . refreshAccountPasswordCache ( pair ) ;
370
+
371
+ const password = cachedPassword ?? inputPassword ;
355
372
356
373
// if the keyring pair is locked, the password is needed
357
- if ( pair . isLocked && ! password ) {
374
+ if ( ! password ) {
358
375
const error = new Error ( 'Password needed to unlock the account' ) ;
359
376
360
377
await this . #state. removeSignRequest ( id ) ;
@@ -408,13 +425,16 @@ export default class Extension {
408
425
. createType ( 'ExtrinsicPayload' , payload , { version : payload . version } )
409
426
. sign ( pair ) ;
410
427
411
- if ( savePass ) {
428
+ if ( savePass && password ) {
412
429
// unlike queued.account.address the following
413
430
// address is encoded with the default prefix
414
431
// which what is used for password caching mapping
415
- this . #cachedUnlocks[ pair . address ] = Date . now ( ) + PASSWORD_EXPIRY_MS ;
432
+
433
+ await chromeStorage . setItem ( 'password-cache' , ( savedPasswords ) => (
434
+ { ...savedPasswords , [ pair . address ] : { password, expiresAt : Date . now ( ) + PASSWORD_EXPIRY_MS } }
435
+ ) ) ;
416
436
} else {
417
- pair . lock ( ) ;
437
+ await this . clearPasswordCache ( pair ) ;
418
438
}
419
439
420
440
await this . #state. removeSignRequest ( id ) ;
@@ -449,11 +469,11 @@ export default class Extension {
449
469
450
470
assert ( pair , 'Unable to find pair' ) ;
451
471
452
- const remainingTime = this . refreshAccountPasswordCache ( pair ) ;
472
+ const { remainingTime } = await this . refreshAccountPasswordCache ( pair ) ;
453
473
454
474
return {
455
- isLocked : pair . isLocked ,
456
- remainingTime
475
+ remainingTime ,
476
+ isLocked : pair . isLocked
457
477
} ;
458
478
}
459
479
0 commit comments