diff options
author | bitpshr <mail@bitpshr.net> | 2018-09-28 02:19:09 +0800 |
---|---|---|
committer | Dan Finlay <542863+danfinlay@users.noreply.github.com> | 2018-11-06 07:07:09 +0800 |
commit | c76c9ca2c86317f902f443db2c5704d4bf6311c0 (patch) | |
tree | e6b182dd8b0eb849d93143ecbd1217640aa8f490 /app/scripts/contentscript.js | |
parent | 2d4ff1dd82252cbe1abe06206fb2664f96905d91 (diff) | |
download | tangerine-wallet-browser-c76c9ca2c86317f902f443db2c5704d4bf6311c0.tar tangerine-wallet-browser-c76c9ca2c86317f902f443db2c5704d4bf6311c0.tar.gz tangerine-wallet-browser-c76c9ca2c86317f902f443db2c5704d4bf6311c0.tar.bz2 tangerine-wallet-browser-c76c9ca2c86317f902f443db2c5704d4bf6311c0.tar.lz tangerine-wallet-browser-c76c9ca2c86317f902f443db2c5704d4bf6311c0.tar.xz tangerine-wallet-browser-c76c9ca2c86317f902f443db2c5704d4bf6311c0.tar.zst tangerine-wallet-browser-c76c9ca2c86317f902f443db2c5704d4bf6311c0.zip |
EIP-1102: updated implementation
Diffstat (limited to 'app/scripts/contentscript.js')
-rw-r--r-- | app/scripts/contentscript.js | 61 |
1 files changed, 51 insertions, 10 deletions
diff --git a/app/scripts/contentscript.js b/app/scripts/contentscript.js index 33523eb46..060343031 100644 --- a/app/scripts/contentscript.js +++ b/app/scripts/contentscript.js @@ -11,6 +11,7 @@ const PortStream = require('extension-port-stream') const inpageContent = fs.readFileSync(path.join(__dirname, '..', '..', 'dist', 'chrome', 'inpage.js')).toString() const inpageSuffix = '//# sourceURL=' + extension.extension.getURL('inpage.js') + '\n' const inpageBundle = inpageContent + inpageSuffix +let originApproved = false // Eventually this streaming injection could be replaced with: // https://developer.mozilla.org/en-US/docs/Mozilla/Tech/XPCOM/Language_Bindings/Components.utils.exportFunction @@ -20,24 +21,24 @@ const inpageBundle = inpageContent + inpageSuffix // MetaMask will be much faster loading and performant on Firefox. if (shouldInjectWeb3()) { - setupInjection() + injectScript(inpageBundle) setupStreams() + listenForProviderRequest() } /** - * Creates a script tag that injects inpage.js + * Injects a script tag into the current document + * + * @param {string} content - Code to be executed in the current document */ -function setupInjection () { +function injectScript (content) { try { - // inject in-page script - var scriptTag = document.createElement('script') - scriptTag.textContent = inpageBundle - scriptTag.onload = function () { this.parentNode.removeChild(this) } - var container = document.head || document.documentElement - // append as first child + const container = document.head || document.documentElement + const scriptTag = document.createElement('script') + scriptTag.textContent = content container.insertBefore(scriptTag, container.children[0]) } catch (e) { - console.error('Metamask injection failed.', e) + console.error('Metamask script injection failed.', e) } } @@ -54,6 +55,16 @@ function setupStreams () { const pluginPort = extension.runtime.connect({ name: 'contentscript' }) const pluginStream = new PortStream(pluginPort) + // Until this origin is approved, cut-off publicConfig stream writes at the content + // script level so malicious sites can't snoop on the currently-selected address + pageStream._write = function (data, encoding, cb) { + if (typeof data === 'object' && data.name && data.name === 'publicConfig' && !originApproved) { + cb() + return + } + LocalMessageDuplexStream.prototype._write.apply(pageStream, arguments) + } + // forward communication plugin->inpage pump( pageStream, @@ -97,6 +108,36 @@ function setupStreams () { mux.ignoreStream('publicConfig') } +/** + * Establishes listeners for requests to fully-enable the provider from the dapp context + * and for full-provider approvals and rejections from the background script context. Dapps + * should not post messages directly and should instead call provider.enable(), which + * handles posting these messages automatically. + */ +function listenForProviderRequest () { + window.addEventListener('message', (event) => { + if (event.source !== window) { return } + if (!event.data || !event.data.type || event.data.type !== 'ETHEREUM_ENABLE_PROVIDER') { return } + extension.runtime.sendMessage({ + action: 'init-provider-request', + origin: event.source.location.hostname, + }) + }) + + extension.runtime.onMessage.addListener(({ action }) => { + if (!action) { return } + switch (action) { + case 'approve-provider-request': + originApproved = true + injectScript(`window.dispatchEvent(new CustomEvent('ethereumprovider', { detail: {}}))`) + break + case 'reject-provider-request': + injectScript(`window.dispatchEvent(new CustomEvent('ethereumprovider', { detail: { error: 'User rejected provider access' }}))`) + break + } + }) +} + /** * Error handler for page to plugin stream disconnections |