aboutsummaryrefslogtreecommitdiffstats
path: root/app/scripts/contentscript.js
diff options
context:
space:
mode:
Diffstat (limited to 'app/scripts/contentscript.js')
-rw-r--r--app/scripts/contentscript.js96
1 files changed, 70 insertions, 26 deletions
diff --git a/app/scripts/contentscript.js b/app/scripts/contentscript.js
index 4d7e682d3..2ed7c87b6 100644
--- a/app/scripts/contentscript.js
+++ b/app/scripts/contentscript.js
@@ -1,12 +1,15 @@
+const fs = require('fs')
+const path = require('path')
+const pump = require('pump')
const LocalMessageDuplexStream = require('post-message-stream')
const PongStream = require('ping-pong-stream/pong')
-const PortStream = require('./lib/port-stream.js')
-const ObjectMultiplex = require('./lib/obj-multiplex')
+const ObjectMultiplex = require('obj-multiplex')
const extension = require('extensionizer')
+const PortStream = require('./lib/port-stream.js')
-const fs = require('fs')
-const path = require('path')
-const inpageText = fs.readFileSync(path.join(__dirname, 'inpage.js')).toString()
+const inpageContent = fs.readFileSync(path.join(__dirname, '..', '..', 'dist', 'chrome', 'scripts', 'inpage.js')).toString()
+const inpageSuffix = '//# sourceURL=' + extension.extension.getURL('scripts/inpage.js') + '\n'
+const inpageBundle = inpageContent + inpageSuffix
// Eventually this streaming injection could be replaced with:
// https://developer.mozilla.org/en-US/docs/Mozilla/Tech/XPCOM/Language_Bindings/Components.utils.exportFunction
@@ -24,8 +27,7 @@ function setupInjection () {
try {
// inject in-page script
var scriptTag = document.createElement('script')
- scriptTag.src = extension.extension.getURL('scripts/inpage.js')
- scriptTag.textContent = inpageText
+ scriptTag.textContent = inpageBundle
scriptTag.onload = function () { this.parentNode.removeChild(this) }
var container = document.head || document.documentElement
// append as first child
@@ -37,35 +39,64 @@ function setupInjection () {
function setupStreams () {
// setup communication to page and plugin
- var pageStream = new LocalMessageDuplexStream({
+ const pageStream = new LocalMessageDuplexStream({
name: 'contentscript',
target: 'inpage',
})
- pageStream.on('error', console.error)
- var pluginPort = extension.runtime.connect({name: 'contentscript'})
- var pluginStream = new PortStream(pluginPort)
- pluginStream.on('error', console.error)
+ const pluginPort = extension.runtime.connect({ name: 'contentscript' })
+ const pluginStream = new PortStream(pluginPort)
// forward communication plugin->inpage
- pageStream.pipe(pluginStream).pipe(pageStream)
+ pump(
+ pageStream,
+ pluginStream,
+ pageStream,
+ (err) => logStreamDisconnectWarning('MetaMask Contentscript Forwarding', err)
+ )
// setup local multistream channels
- var mx = ObjectMultiplex()
- mx.on('error', console.error)
- mx.pipe(pageStream).pipe(mx)
+ const mux = new ObjectMultiplex()
+ mux.setMaxListeners(25)
+
+ pump(
+ mux,
+ pageStream,
+ mux,
+ (err) => logStreamDisconnectWarning('MetaMask Inpage', err)
+ )
+ pump(
+ mux,
+ pluginStream,
+ mux,
+ (err) => logStreamDisconnectWarning('MetaMask Background', err)
+ )
// connect ping stream
- var pongStream = new PongStream({ objectMode: true })
- pongStream.pipe(mx.createStream('pingpong')).pipe(pongStream)
+ const pongStream = new PongStream({ objectMode: true })
+ pump(
+ mux,
+ pongStream,
+ mux,
+ (err) => logStreamDisconnectWarning('MetaMask PingPongStream', err)
+ )
+
+ // connect phishing warning stream
+ const phishingStream = mux.createStream('phishing')
+ phishingStream.once('data', redirectToPhishingWarning)
- // ignore unused channels (handled by background)
- mx.ignoreStream('provider')
- mx.ignoreStream('publicConfig')
- mx.ignoreStream('reload')
+ // ignore unused channels (handled by background, inpage)
+ mux.ignoreStream('provider')
+ mux.ignoreStream('publicConfig')
+}
+
+function logStreamDisconnectWarning (remoteLabel, err) {
+ let warningMsg = `MetamaskContentscript - lost connection to ${remoteLabel}`
+ if (err) warningMsg += '\n' + err.stack
+ console.warn(warningMsg)
}
function shouldInjectWeb3 () {
- return doctypeCheck() || suffixCheck()
+ return doctypeCheck() && suffixCheck() && documentElementCheck()
}
function doctypeCheck () {
@@ -73,19 +104,32 @@ function doctypeCheck () {
if (doctype) {
return doctype.name === 'html'
} else {
- return false
+ return true
}
}
-function suffixCheck() {
+function suffixCheck () {
var prohibitedTypes = ['xml', 'pdf']
var currentUrl = window.location.href
var currentRegex
for (let i = 0; i < prohibitedTypes.length; i++) {
- currentRegex = new RegExp(`\.${prohibitedTypes[i]}$`)
+ currentRegex = new RegExp(`\\.${prohibitedTypes[i]}$`)
if (currentRegex.test(currentUrl)) {
return false
}
}
return true
}
+
+function documentElementCheck () {
+ var documentElement = document.documentElement.nodeName
+ if (documentElement) {
+ return documentElement.toLowerCase() === 'html'
+ }
+ return true
+}
+
+function redirectToPhishingWarning () {
+ console.log('MetaMask - redirecting to phishing warning')
+ window.location.href = 'https://metamask.io/phishing.html'
+}