1
0
mirror of https://github.com/kremalicious/metamask-extension.git synced 2024-12-23 09:52:26 +01:00
metamask-extension/app/scripts/controllers/provider-approval.js

163 lines
5.7 KiB
JavaScript
Raw Normal View History

2018-09-27 20:19:09 +02:00
const ObservableStore = require('obs-store')
/**
* A controller that services user-approved requests for a full Ethereum provider API
*/
class ProviderApprovalController {
2018-10-29 23:44:04 +01:00
/**
* Determines if caching is enabled
*/
2018-10-31 10:07:49 +01:00
caching = true
2018-10-29 23:44:04 +01:00
2018-09-27 20:19:09 +02:00
/**
* Creates a ProviderApprovalController
*
* @param {Object} [config] - Options to configure controller
*/
2018-10-29 22:28:59 +01:00
constructor ({ closePopup, keyringController, openPopup, platform, preferencesController, publicConfigStore } = {}) {
this.approvedOrigins = {}
2018-09-27 20:19:09 +02:00
this.closePopup = closePopup
2018-10-29 22:28:59 +01:00
this.keyringController = keyringController
2018-09-27 20:19:09 +02:00
this.openPopup = openPopup
this.platform = platform
2018-10-10 20:52:26 +02:00
this.preferencesController = preferencesController
2018-10-29 22:28:59 +01:00
this.publicConfigStore = publicConfigStore
this.store = new ObservableStore({
providerRequests: [],
})
2018-10-29 22:28:59 +01:00
if (platform && platform.addMessageListener) {
platform.addMessageListener(({ action = '', force, origin, siteTitle, siteImage }, { tab }) => {
switch (action) {
case 'init-provider-request':
this._handleProviderRequest(origin, siteTitle, siteImage, force, tab.id)
break
case 'init-is-approved':
this._handleIsApproved(origin, tab.id)
break
case 'init-is-unlocked':
this._handleIsUnlocked(tab.id)
break
case 'init-privacy-request':
this._handlePrivacyRequest(tab.id)
break
}
})
}
2018-09-27 20:19:09 +02:00
}
/**
* Called when a tab requests access to a full Ethereum provider API
*
* @param {string} origin - Origin of the window requesting full provider access
* @param {string} siteTitle - The title of the document requesting full provider access
* @param {string} siteImage - The icon of the window requesting full provider access
2018-09-27 20:19:09 +02:00
*/
_handleProviderRequest (origin, siteTitle, siteImage, force, tabID) {
this.store.updateState({ providerRequests: [{ origin, siteTitle, siteImage, tabID }] })
const isUnlocked = this.keyringController.memStore.getState().isUnlocked
2018-11-06 20:13:27 +01:00
if (!force && this.approvedOrigins[origin] && this.caching && isUnlocked) {
this.approveProviderRequest(tabID)
2018-09-27 20:19:09 +02:00
return
}
this.openPopup && this.openPopup()
}
/**
2018-10-29 22:28:59 +01:00
* Called by a tab to determine if an origin has been approved in the past
*
2018-10-29 22:28:59 +01:00
* @param {string} origin - Origin of the window
*/
_handleIsApproved (origin, tabID) {
2018-11-06 20:13:27 +01:00
this.platform && this.platform.sendMessage({
action: 'answer-is-approved',
isApproved: this.approvedOrigins[origin] && this.caching,
2018-11-06 20:30:33 +01:00
caching: this.caching,
}, { id: tabID })
2018-10-10 20:52:26 +02:00
}
2018-10-29 22:28:59 +01:00
/**
* Called by a tab to determine if MetaMask is currently locked or unlocked
*/
_handleIsUnlocked (tabID) {
2018-10-18 00:38:31 +02:00
const isUnlocked = this.keyringController.memStore.getState().isUnlocked
this.platform && this.platform.sendMessage({ action: 'answer-is-unlocked', isUnlocked }, { id: tabID })
2018-10-18 00:38:31 +02:00
}
2018-10-29 22:28:59 +01:00
/**
* Called to check privacy mode; if privacy mode is off, this will automatically enable the provider (legacy behavior)
*/
_handlePrivacyRequest (tabID) {
2018-10-10 20:52:26 +02:00
const privacyMode = this.preferencesController.getFeatureFlags().privacyMode
if (!privacyMode) {
this.platform && this.platform.sendMessage({
action: 'approve-legacy-provider-request',
selectedAddress: this.publicConfigStore.getState().selectedAddress,
}, { id: tabID })
2018-10-10 20:52:26 +02:00
this.publicConfigStore.emit('update', this.publicConfigStore.getState())
}
}
2018-09-27 20:19:09 +02:00
/**
* Called when a user approves access to a full Ethereum provider API
*
* @param {string} tabID - ID of the target window that approved provider access
2018-09-27 20:19:09 +02:00
*/
approveProviderRequest (tabID) {
2018-09-27 20:19:09 +02:00
this.closePopup && this.closePopup()
const requests = this.store.getState().providerRequests
const origin = requests.find(request => request.tabID === tabID).origin
this.platform && this.platform.sendMessage({
action: 'approve-provider-request',
selectedAddress: this.publicConfigStore.getState().selectedAddress,
}, { id: tabID })
2018-09-27 20:19:09 +02:00
this.publicConfigStore.emit('update', this.publicConfigStore.getState())
const providerRequests = requests.filter(request => request.tabID !== tabID)
2018-09-27 20:19:09 +02:00
this.store.updateState({ providerRequests })
this.approvedOrigins[origin] = true
}
/**
* Called when a tab rejects access to a full Ethereum provider API
*
* @param {string} tabID - ID of the target window that rejected provider access
2018-09-27 20:19:09 +02:00
*/
rejectProviderRequest (tabID) {
2018-09-27 20:19:09 +02:00
this.closePopup && this.closePopup()
const requests = this.store.getState().providerRequests
const origin = requests.find(request => request.tabID === tabID).origin
this.platform && this.platform.sendMessage({ action: 'reject-provider-request' }, { id: tabID })
const providerRequests = requests.filter(request => request.tabID !== tabID)
2018-09-27 20:19:09 +02:00
this.store.updateState({ providerRequests })
2018-11-06 20:13:27 +01:00
delete this.approvedOrigins[origin]
2018-09-27 20:19:09 +02:00
}
/**
* Clears any cached approvals for user-approved origins
*/
clearApprovedOrigins () {
this.approvedOrigins = {}
}
/**
2018-11-06 20:13:27 +01:00
* Determines if a given origin should have accounts exposed
2018-09-27 20:19:09 +02:00
*
* @param {string} origin - Domain origin to check for approval status
* @returns {boolean} - True if the origin has been approved
*/
2018-11-06 20:13:27 +01:00
shouldExposeAccounts (origin) {
2018-10-10 20:52:26 +02:00
const privacyMode = this.preferencesController.getFeatureFlags().privacyMode
2018-11-04 18:19:47 +01:00
return !privacyMode || this.approvedOrigins[origin]
2018-09-27 20:19:09 +02:00
}
2018-10-29 23:44:04 +01:00
/**
* Tells all tabs that MetaMask is now locked. This is primarily used to set
* internal flags in the contentscript and inpage script.
*/
setLocked () {
this.platform.sendMessage({ action: 'metamask-set-locked' })
}
2018-09-27 20:19:09 +02:00
}
module.exports = ProviderApprovalController