Open notification UI when eth_requestAccounts waits for unlock (#8508)

feature/default_network_editable
Erik Marks 5 years ago committed by GitHub
parent e00982aa58
commit 79d9209473
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 3
      app/scripts/background.js
  2. 27
      app/scripts/controllers/app-state.js
  3. 6
      app/scripts/controllers/permissions/index.js
  4. 1
      app/scripts/metamask-controller.js
  5. 2
      test/unit/app/controllers/permissions/mocks.js

@ -236,7 +236,8 @@ function setupController (initState, initLangCode) {
showUnconfirmedMessage: triggerUi, showUnconfirmedMessage: triggerUi,
showUnapprovedTx: triggerUi, showUnapprovedTx: triggerUi,
showPermissionRequest: triggerUi, showPermissionRequest: triggerUi,
openPopup: openPopup, showUnlockRequest: triggerUi,
openPopup,
// initial state // initial state
initState, initState,
// initial locale code // initial locale code

@ -12,6 +12,7 @@ class AppStateController extends EventEmitter {
isUnlocked, isUnlocked,
initState, initState,
onInactiveTimeout, onInactiveTimeout,
showUnlockRequest,
preferencesStore, preferencesStore,
} = opts } = opts
const { preferences } = preferencesStore.getState() const { preferences } = preferencesStore.getState()
@ -29,6 +30,8 @@ class AppStateController extends EventEmitter {
this.waitingForUnlock = [] this.waitingForUnlock = []
addUnlockListener(this.handleUnlock.bind(this)) addUnlockListener(this.handleUnlock.bind(this))
this._showUnlockRequest = showUnlockRequest
preferencesStore.subscribe((state) => { preferencesStore.subscribe((state) => {
this._setInactiveTimeout(state.preferences.autoLockTimeLimit) this._setInactiveTimeout(state.preferences.autoLockTimeLimit)
}) })
@ -40,20 +43,38 @@ class AppStateController extends EventEmitter {
* Get a Promise that resolves when the extension is unlocked. * Get a Promise that resolves when the extension is unlocked.
* This Promise will never reject. * This Promise will never reject.
* *
* @param {boolean} shouldShowUnlockRequest - Whether the extension notification
* popup should be opened.
* @returns {Promise<void>} A promise that resolves when the extension is * @returns {Promise<void>} A promise that resolves when the extension is
* unlocked, or immediately if the extension is already unlocked. * unlocked, or immediately if the extension is already unlocked.
*/ */
getUnlockPromise () { getUnlockPromise (shouldShowUnlockRequest) {
return new Promise((resolve) => { return new Promise((resolve) => {
if (this.isUnlocked()) { if (this.isUnlocked()) {
resolve() resolve()
} else { } else {
this.waitingForUnlock.push({ resolve }) this.waitForUnlock(resolve, shouldShowUnlockRequest)
this.emit('updateBadge')
} }
}) })
} }
/**
* Adds a Promise's resolve function to the waitingForUnlock queue.
* Also opens the extension popup if specified.
*
* @param {Promise.resolve} resolve - A Promise's resolve function that will
* be called when the extension is unlocked.
* @param {boolean} shouldShowUnlockRequest - Whether the extension notification
* popup should be opened.
*/
waitForUnlock (resolve, shouldShowUnlockRequest) {
this.waitingForUnlock.push({ resolve })
this.emit('updateBadge')
if (shouldShowUnlockRequest) {
this._showUnlockRequest()
}
}
/** /**
* Drains the waitingForUnlock queue, resolving all the related Promises. * Drains the waitingForUnlock queue, resolving all the related Promises.
*/ */

@ -42,7 +42,7 @@ export class PermissionsController {
}) })
this.getKeyringAccounts = getKeyringAccounts this.getKeyringAccounts = getKeyringAccounts
this.getUnlockPromise = getUnlockPromise this._getUnlockPromise = getUnlockPromise
this._notifyDomain = notifyDomain this._notifyDomain = notifyDomain
this.notifyAllDomains = notifyAllDomains this.notifyAllDomains = notifyAllDomains
this._showPermissionRequest = showPermissionRequest this._showPermissionRequest = showPermissionRequest
@ -92,7 +92,7 @@ export class PermissionsController {
store: this.store, store: this.store,
storeKey: METADATA_STORE_KEY, storeKey: METADATA_STORE_KEY,
getAccounts: this.getAccounts.bind(this, origin), getAccounts: this.getAccounts.bind(this, origin),
getUnlockPromise: this.getUnlockPromise, getUnlockPromise: () => this._getUnlockPromise(true),
hasPermission: this.hasPermission.bind(this, origin), hasPermission: this.hasPermission.bind(this, origin),
requestAccountsPermission: this._requestPermissions.bind( requestAccountsPermission: this._requestPermissions.bind(
this, origin, { eth_accounts: {} } this, origin, { eth_accounts: {} }
@ -602,7 +602,7 @@ export class PermissionsController {
this.pendingApprovals.has(id) this.pendingApprovals.has(id)
) { ) {
throw new Error( throw new Error(
`Pending approval with id ${id} or origin ${origin} already exists.` `Pending approval with id '${id}' or origin '${origin}' already exists.`
) )
} }

@ -125,6 +125,7 @@ export default class MetamaskController extends EventEmitter {
isUnlocked: this.isUnlocked.bind(this), isUnlocked: this.isUnlocked.bind(this),
initState: initState.AppStateController, initState: initState.AppStateController,
onInactiveTimeout: () => this.setLocked(), onInactiveTimeout: () => this.setLocked(),
showUnlockRequest: opts.showUnlockRequest,
preferencesStore: this.preferencesController.store, preferencesStore: this.preferencesController.store,
}) })

@ -437,7 +437,7 @@ export const getters = deepFreeze({
pendingApprovals: { pendingApprovals: {
duplicateOriginOrId: (id, origin) => { duplicateOriginOrId: (id, origin) => {
return { return {
message: `Pending approval with id ${id} or origin ${origin} already exists.`, message: `Pending approval with id '${id}' or origin '${origin}' already exists.`,
} }
}, },
requestAlreadyPending: () => { requestAlreadyPending: () => {

Loading…
Cancel
Save