1
0
mirror of https://github.com/kremalicious/metamask-extension.git synced 2024-11-22 18:00:18 +01:00

Merge pull request #5797 from MetaMask/trezor-v6

Add Firefox and Brave support for Trezor
This commit is contained in:
Bruno Barbieri 2018-11-21 14:45:55 -05:00 committed by GitHub
commit ae8626eceb
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
12 changed files with 167 additions and 45 deletions

View File

@ -10,6 +10,7 @@ development/states.js
app/scripts/lib/extension-instance.js app/scripts/lib/extension-instance.js
app/scripts/chromereload.js app/scripts/chromereload.js
app/vendor/**
ui/lib/blockies.js ui/lib/blockies.js

View File

@ -52,6 +52,14 @@
], ],
"run_at": "document_start", "run_at": "document_start",
"all_frames": true "all_frames": true
},
{
"matches": [
"*://connect.trezor.io/*/popup.html"
],
"js": [
"vendor/trezor/content-script.js"
]
} }
], ],
"permissions": [ "permissions": [

View File

@ -332,6 +332,10 @@ function setupController (initState, initLangCode) {
[ENVIRONMENT_TYPE_FULLSCREEN]: true, [ENVIRONMENT_TYPE_FULLSCREEN]: true,
} }
const metamaskBlacklistedPorts = [
'trezor-connect',
]
const isClientOpenStatus = () => { const isClientOpenStatus = () => {
return popupIsOpen || Boolean(Object.keys(openMetamaskTabsIDs).length) || notificationIsOpen return popupIsOpen || Boolean(Object.keys(openMetamaskTabsIDs).length) || notificationIsOpen
} }
@ -352,6 +356,10 @@ function setupController (initState, initLangCode) {
const processName = remotePort.name const processName = remotePort.name
const isMetaMaskInternalProcess = metamaskInternalProcessHash[processName] const isMetaMaskInternalProcess = metamaskInternalProcessHash[processName]
if (metamaskBlacklistedPorts.includes(remotePort.name)) {
return false
}
if (isMetaMaskInternalProcess) { if (isMetaMaskInternalProcess) {
const portStream = new PortStream(remotePort) const portStream = new PortStream(remotePort)
// communication with popup // communication with popup

View File

@ -0,0 +1,33 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=Edge" />
<meta name="viewport" content="width=device-width,initial-scale=1.0,maximum-scale=1.0,user-scalable=0" />
<title>TrezorConnect | Trezor</title>
<meta name="description" content="" />
<meta name="keywords" content="" />
<meta name="author" content="Trezor info@trezor.io" />
<meta name="robots" content="noindex, nofollow" />
<meta name="title" content="Trezor Connect" />
<meta name="theme-color" content="#ffffff" />
<meta http-equiv="Pragma" content="no-cache" />
<meta http-equiv="Expires" content="-1" />
<style>
* {
margin: 0;
padding: 0;
}
html, body {
position: relative;
width: 100%;
height: 100%;
min-height: 500px;
min-width: 328px;
}
</style>
</head>
<body>
<iframe id="trezor-usb-permissions" src="https://connect.trezor.io/5/extension-permissions.html" allow="usb" frameborder="0" width="100%" height="100%"></iframe>
<script type="text/javascript" src="./vendor/trezor/usb-permissions.js"></script>
</body>

21
app/vendor/trezor/content-script.js vendored Normal file
View File

@ -0,0 +1,21 @@
/*
Passing messages from background script to popup
*/
let port = chrome.runtime.connect({ name: 'trezor-connect' });
port.onMessage.addListener(message => {
window.postMessage(message, window.location.origin);
});
port.onDisconnect.addListener(d => {
port = null;
});
/*
Passing messages from popup to background script
*/
window.addEventListener('message', event => {
if (port && event.source === window && event.data) {
port.postMessage(event.data);
}
});

50
app/vendor/trezor/usb-permissions.js vendored Normal file
View File

@ -0,0 +1,50 @@
/*
Handling messages from usb permissions iframe
*/
const switchToPopupTab = (event) => {
window.removeEventListener('beforeunload', switchToPopupTab);
if (!event) {
// triggered from 'usb-permissions-close' message
// switch tab to previous index and close current
chrome.tabs.query({
currentWindow: true,
active: true,
}, (current) => {
if (current.length < 0) return;
chrome.tabs.query({
index: current[0].index - 1
}, popup => {
if (popup.length < 0) return;
chrome.tabs.update(popup[0].id, { active: true });
})
chrome.tabs.remove(current[0].id);
});
return;
}
// triggered from 'beforeunload' event
// find tab by popup pattern and switch to it
chrome.tabs.query({
url: "*://connect.trezor.io/*/popup.html"
}, (tabs) => {
if (tabs.length < 0) return;
chrome.tabs.update(tabs[0].id, { active: true });
});
}
window.addEventListener('message', event => {
if (event.data === 'usb-permissions-init') {
const iframe = document.getElementById('trezor-usb-permissions');
iframe.contentWindow.postMessage({
type: 'usb-permissions-init',
extension: chrome.runtime.id,
}, '*');
} else if (event.data === 'usb-permissions-close') {
switchToPopupTab();
}
});
window.addEventListener('beforeunload', switchToPopupTab);

View File

@ -84,6 +84,10 @@ createCopyTasks('fonts', {
source: './app/fonts/', source: './app/fonts/',
destinations: commonPlatforms.map(platform => `./dist/${platform}/fonts`), destinations: commonPlatforms.map(platform => `./dist/${platform}/fonts`),
}) })
createCopyTasks('vendor', {
source: './app/vendor/',
destinations: commonPlatforms.map(platform => `./dist/${platform}/vendor`),
})
createCopyTasks('reload', { createCopyTasks('reload', {
devOnly: true, devOnly: true,
source: './app/scripts/', source: './app/scripts/',

43
package-lock.json generated
View File

@ -9794,6 +9794,16 @@
"requires": { "requires": {
"ethereumjs-abi": "git+https://github.com/ethereumjs/ethereumjs-abi.git#2863c40e0982acfc0b7163f0285d4c56427c7799", "ethereumjs-abi": "git+https://github.com/ethereumjs/ethereumjs-abi.git#2863c40e0982acfc0b7163f0285d4c56427c7799",
"ethereumjs-util": "^5.1.1" "ethereumjs-util": "^5.1.1"
},
"dependencies": {
"ethereumjs-abi": {
"version": "git+https://github.com/ethereumjs/ethereumjs-abi.git#2863c40e0982acfc0b7163f0285d4c56427c7799",
"from": "git+https://github.com/ethereumjs/ethereumjs-abi.git#2863c40e0982acfc0b7163f0285d4c56427c7799",
"requires": {
"bn.js": "^4.10.0",
"ethereumjs-util": "^5.0.0"
}
}
} }
}, },
"ethereum-common": { "ethereum-common": {
@ -10202,15 +10212,15 @@
} }
}, },
"eth-trezor-keyring": { "eth-trezor-keyring": {
"version": "0.1.0", "version": "0.2.0",
"resolved": "https://registry.npmjs.org/eth-trezor-keyring/-/eth-trezor-keyring-0.1.0.tgz", "resolved": "github:MetaMask/eth-trezor-keyring#528840df6785101ac68ec9fc0cc4bc675eba9292",
"integrity": "sha512-7ynDXiXGQOh9CslksJSmGGK726lV9fTnIp2QQnjbZJgR4zJIoSUYQYKvT2wXcxLhVrTUl2hLjwKN9QGqDCMVwA==",
"requires": { "requires": {
"eth-sig-util": "^1.4.2", "eth-sig-util": "^1.4.2",
"ethereumjs-tx": "^1.3.4", "ethereumjs-tx": "^1.3.4",
"ethereumjs-util": "^5.1.5", "ethereumjs-util": "^5.1.5",
"events": "^2.0.0", "events": "^2.0.0",
"hdkey": "0.8.0" "hdkey": "0.8.0",
"trezor-connect": "^6.0.2"
}, },
"dependencies": { "dependencies": {
"eth-sig-util": { "eth-sig-util": {
@ -10229,16 +10239,16 @@
}, },
"ethereumjs-abi": { "ethereumjs-abi": {
"version": "git+https://github.com/ethereumjs/ethereumjs-abi.git#2863c40e0982acfc0b7163f0285d4c56427c7799", "version": "git+https://github.com/ethereumjs/ethereumjs-abi.git#2863c40e0982acfc0b7163f0285d4c56427c7799",
"from": "ethereumjs-abi@git+https://github.com/ethereumjs/ethereumjs-abi.git#2863c40e0982acfc0b7163f0285d4c56427c7799", "from": "git+https://github.com/ethereumjs/ethereumjs-abi.git",
"requires": { "requires": {
"bn.js": "^4.10.0", "bn.js": "^4.10.0",
"ethereumjs-util": "^5.0.0" "ethereumjs-util": "^5.0.0"
} }
}, },
"ethereumjs-tx": { "ethereumjs-tx": {
"version": "1.3.6", "version": "1.3.7",
"resolved": "https://registry.npmjs.org/ethereumjs-tx/-/ethereumjs-tx-1.3.6.tgz", "resolved": "https://registry.npmjs.org/ethereumjs-tx/-/ethereumjs-tx-1.3.7.tgz",
"integrity": "sha512-wzsEs0mCSLqdDjqSDg6AWh1hyL8H3R/pyZxehkcCXq5MJEFXWz+eJ2jSv+3yEaLy6tXrNP7dmqS3Kyb3zAONkg==", "integrity": "sha512-wvLMxzt1RPhAQ9Yi3/HKZTn0FZYpnsmQdbKYfUUpi4j1SEIcbkd9tndVjcPrufY3V7j2IebOpC00Zp2P/Ay2kA==",
"requires": { "requires": {
"ethereum-common": "^0.0.18", "ethereum-common": "^0.0.18",
"ethereumjs-util": "^5.0.0" "ethereumjs-util": "^5.0.0"
@ -36555,6 +36565,23 @@
"resolved": "https://registry.npmjs.org/treeify/-/treeify-1.1.0.tgz", "resolved": "https://registry.npmjs.org/treeify/-/treeify-1.1.0.tgz",
"integrity": "sha512-1m4RA7xVAJrSGrrXGs0L3YTwyvBs2S8PbRHaLZAkFw7JR8oIFwYtysxlBZhYIa7xSyiYJKZ3iGrrk55cGA3i9A==" "integrity": "sha512-1m4RA7xVAJrSGrrXGs0L3YTwyvBs2S8PbRHaLZAkFw7JR8oIFwYtysxlBZhYIa7xSyiYJKZ3iGrrk55cGA3i9A=="
}, },
"trezor-connect": {
"version": "6.0.2",
"resolved": "https://registry.npmjs.org/trezor-connect/-/trezor-connect-6.0.2.tgz",
"integrity": "sha512-oSYTPnQD9ZT3vO2hBRdgealHG7t8Wu3oTZXX/U4eRxJZ0WqdEcXG7Nvqe1BL6Rl3VTuj7ALT9DL1Uq3QFYAc3g==",
"requires": {
"babel-runtime": "^6.26.0",
"events": "^1.1.1",
"whatwg-fetch": "^2.0.4"
},
"dependencies": {
"whatwg-fetch": {
"version": "2.0.4",
"resolved": "http://registry.npmjs.org/whatwg-fetch/-/whatwg-fetch-2.0.4.tgz",
"integrity": "sha512-dcQ1GWpOD/eEQ97k66aiEVpNnapVj90/+R+SXTPYGHpYBBypfKJEQjLrvMZ7YXbKm21gXd4NcuxUTjiv1YtLng=="
}
}
},
"trim": { "trim": {
"version": "0.0.1", "version": "0.0.1",
"resolved": "https://registry.npmjs.org/trim/-/trim-0.0.1.tgz", "resolved": "https://registry.npmjs.org/trim/-/trim-0.0.1.tgz",

View File

@ -125,9 +125,9 @@
"eth-method-registry": "^1.0.0", "eth-method-registry": "^1.0.0",
"eth-phishing-detect": "^1.1.4", "eth-phishing-detect": "^1.1.4",
"eth-query": "^2.1.2", "eth-query": "^2.1.2",
"eth-trezor-keyring": "^0.2.0",
"eth-sig-util": "^2.0.2", "eth-sig-util": "^2.0.2",
"eth-token-tracker": "^1.1.5", "eth-token-tracker": "^1.1.5",
"eth-trezor-keyring": "^0.1.0",
"ethereumjs-abi": "^0.6.4", "ethereumjs-abi": "^0.6.4",
"ethereumjs-tx": "^1.3.0", "ethereumjs-tx": "^1.3.0",
"ethereumjs-util": "github:ethereumjs/ethereumjs-util#ac5d0908536b447083ea422b435da27f26615de9", "ethereumjs-util": "github:ethereumjs/ethereumjs-util#ac5d0908536b447083ea422b435da27f26615de9",
@ -264,7 +264,6 @@
"eslint-plugin-mocha": "^5.0.0", "eslint-plugin-mocha": "^5.0.0",
"eslint-plugin-react": "^7.4.0", "eslint-plugin-react": "^7.4.0",
"eth-json-rpc-middleware": "^3.1.6", "eth-json-rpc-middleware": "^3.1.6",
"eth-keyring-controller": "^3.3.1",
"fetch-mock": "^6.5.2", "fetch-mock": "^6.5.2",
"file-loader": "^1.1.11", "file-loader": "^1.1.11",
"fs-extra": "^6.0.1", "fs-extra": "^6.0.1",

View File

@ -315,36 +315,7 @@ describe('Using MetaMask with an existing account', function () {
await connectButtons[0].click() await connectButtons[0].click()
await delay(regularDelayMs) await delay(regularDelayMs)
const allWindows = await driver.getAllWindowHandles() const allWindows = await driver.getAllWindowHandles()
switch (process.env.SELENIUM_BROWSER) {
case 'chrome':
assert.equal(allWindows.length, 2) assert.equal(allWindows.length, 2)
break
default:
assert.equal(allWindows.length, 1)
}
})
it('should show the "Browser not supported" screen for non Chrome browsers', async () => {
if (process.env.SELENIUM_BROWSER !== 'chrome') {
const title = await findElements(driver, By.xpath(`//h3[contains(text(), 'Your Browser is not supported...')]`))
assert.equal(title.length, 1)
const downloadChromeButtons = await findElements(driver, By.xpath(`//button[contains(text(), 'Download Google Chrome')]`))
assert.equal(downloadChromeButtons.length, 1)
await downloadChromeButtons[0].click()
await delay(regularDelayMs)
const [newUITab, downloadChromeTab] = await driver.getAllWindowHandles()
await driver.switchTo().window(downloadChromeTab)
await delay(regularDelayMs)
const tabUrl = await driver.getCurrentUrl()
assert.equal(tabUrl, 'https://www.google.com/chrome/')
await driver.close()
await delay(regularDelayMs)
await driver.switchTo().window(newUITab)
}
}) })
}) })
}) })

View File

@ -50,9 +50,8 @@ class ConnectHardwareForm extends Component {
} }
connectToHardwareWallet = (device) => { connectToHardwareWallet = (device) => {
// None of the hardware wallets are supported // Ledger hardware wallets are not supported on firefox
// At least for now if (getPlatform() === PLATFORM_FIREFOX && device === 'ledger') {
if (getPlatform() === PLATFORM_FIREFOX) {
this.setState({ browserSupported: false, error: null}) this.setState({ browserSupported: false, error: null})
return null return null
} }
@ -126,7 +125,7 @@ class ConnectHardwareForm extends Component {
.catch(e => { .catch(e => {
if (e === 'Window blocked') { if (e === 'Window blocked') {
this.setState({ browserSupported: false, error: null}) this.setState({ browserSupported: false, error: null})
} else if (e !== 'Window closed') { } else if (e !== 'Window closed' && e !== 'Popup closed') {
this.setState({ error: e.toString() }) this.setState({ error: e.toString() })
} }
}) })

View File

@ -436,6 +436,7 @@
margin-top: 10px; margin-top: 10px;
&__button { &__button {
background: #fff;
height: 19px; height: 19px;
display: flex; display: flex;
color: #33a4e7; color: #33a4e7;