Assign `tabId` to middleware request, if provided (#7695)

The `tabId` of the message sender is now added to the middleware
request object. This step is omitted if the `tabId` is not provided.
This is done early in the middleware stack, so the `tabId` should be
available for any subsequent middleware to use.

The Onboarding Middleware has also been modified to get the `tabId`
from the request object, rather than expecting it as a parameter upon
creation.

This refactor will enable further uses of the `tabId`.
feature/default_network_editable
Dan J Miller 5 years ago committed by GitHub
parent ef98e876a7
commit 1d2c57a2f3
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 8
      app/scripts/lib/createOnboardingMiddleware.js
  2. 14
      app/scripts/lib/createTabIdMiddleware.js
  3. 6
      app/scripts/metamask-controller.js
  4. 83
      test/unit/app/controllers/metamask-controller-test.js

@ -3,18 +3,18 @@ import extension from 'extensionizer'
/**
* Returns a middleware that intercepts `wallet_registerOnboarding` messages
* @param {{ location: string, tabId: number, registerOnboarding: Function }} opts - The middleware options
* @param {{ location: string, registerOnboarding: Function }} opts - The middleware options
* @returns {(req: any, res: any, next: Function, end: Function) => void}
*/
function createOnboardingMiddleware ({ location, tabId, registerOnboarding }) {
function createOnboardingMiddleware ({ location, registerOnboarding }) {
return async function originMiddleware (req, res, next, end) {
try {
if (req.method !== 'wallet_registerOnboarding') {
next()
return
}
if (tabId && tabId !== extension.tabs.TAB_ID_NONE) {
await registerOnboarding(location, tabId)
if (req.tabId && req.tabId !== extension.tabs.TAB_ID_NONE) {
await registerOnboarding(location, req.tabId)
} else {
log.debug(`'wallet_registerOnboarding' message from ${location} ignored due to missing tabId`)
}

@ -0,0 +1,14 @@
module.exports = createTabIdMiddleware
/**
* Returns a middleware that appends the DApp TabId to the request
* @param {{ tabId: number }} opts - The middleware options
* @returns {Function}
*/
function createTabIdMiddleware (opts) {
return function tabIdMiddleware (/** @type {any} */ req, /** @type {any} */ _, /** @type {Function} */ next) {
req.tabId = opts.tabId
next()
}
}

@ -20,6 +20,7 @@ import createFilterMiddleware from 'eth-json-rpc-filters'
import createSubscriptionManager from 'eth-json-rpc-filters/subscriptionManager'
import createLoggerMiddleware from './lib/createLoggerMiddleware'
import createOriginMiddleware from './lib/createOriginMiddleware'
import createTabIdMiddleware from './lib/createTabIdMiddleware'
import createOnboardingMiddleware from './lib/createOnboardingMiddleware'
import providerAsMiddleware from 'eth-json-rpc-middleware/providerAsMiddleware'
import { setupMultiplex } from './lib/stream-utils.js'
@ -1627,11 +1628,14 @@ export default class MetamaskController extends EventEmitter {
// append origin to each request
engine.push(createOriginMiddleware({ origin }))
// append tabId to each request if it exists
if (tabId) {
engine.push(createTabIdMiddleware({ tabId }))
}
// logging
engine.push(createLoggerMiddleware({ origin }))
engine.push(createOnboardingMiddleware({
location,
tabId,
registerOnboarding: this.onboardingController.registerOnboarding,
}))
// filter and subscription polyfills

@ -102,6 +102,7 @@ describe('MetaMaskController', function () {
// add sinon method spies
sandbox.spy(metamaskController.keyringController, 'createNewVaultAndKeychain')
sandbox.spy(metamaskController.keyringController, 'createNewVaultAndRestore')
sandbox.spy(metamaskController.txController, 'newUnapprovedTransaction')
})
afterEach(function () {
@ -791,6 +792,88 @@ describe('MetaMaskController', function () {
await promise
streamTest.end()
})
it('adds a tabId and origin to requests', function (done) {
const messageSender = {
url: 'http://mycrypto.com',
tab: { id: 456 },
}
const streamTest = createThoughStream((chunk, _, cb) => {
if (chunk.data && chunk.data.method) {
cb(null, chunk)
} else {
cb()
}
})
metamaskController.setupUntrustedCommunication(streamTest, messageSender)
const message = {
id: 1999133338649204,
jsonrpc: '2.0',
params: ['mock tx params'],
method: 'eth_sendTransaction',
}
streamTest.write({
name: 'provider',
data: message,
}, null, () => {
setTimeout(() => {
assert.deepStrictEqual(
metamaskController.txController.newUnapprovedTransaction.getCall(0).args,
[
'mock tx params',
{
...message,
origin: 'mycrypto.com',
tabId: 456,
},
]
)
done()
})
})
})
it('should add only origin to request if tabId not provided', function (done) {
const messageSender = {
url: 'http://mycrypto.com',
}
const streamTest = createThoughStream((chunk, _, cb) => {
if (chunk.data && chunk.data.method) {
cb(null, chunk)
} else {
cb()
}
})
metamaskController.setupUntrustedCommunication(streamTest, messageSender)
const message = {
id: 1999133338649204,
jsonrpc: '2.0',
params: ['mock tx params'],
method: 'eth_sendTransaction',
}
streamTest.write({
name: 'provider',
data: message,
}, null, () => {
setTimeout(() => {
assert.deepStrictEqual(
metamaskController.txController.newUnapprovedTransaction.getCall(0).args,
[
'mock tx params',
{
...message,
origin: 'mycrypto.com',
},
]
)
done()
})
})
})
})
describe('#setupTrustedCommunication', function () {

Loading…
Cancel
Save