1
0
mirror of https://github.com/kremalicious/metamask-extension.git synced 2024-12-22 17:33:23 +01:00

Merge branch 'master' into NewUI

This commit is contained in:
kumavis 2017-08-03 21:02:01 -07:00 committed by GitHub
commit 5a9257208c
9 changed files with 50 additions and 44 deletions

View File

@ -4,6 +4,10 @@
- Replace account scren with an account drop-down menu. - Replace account scren with an account drop-down menu.
- Replace confusing buttons with an new account-specific drop-down menu. - Replace confusing buttons with an new account-specific drop-down menu.
## 3.9.3 2017-8-03
- Add support for EGO uport token
- Continuously update blacklist for known phishing sites in background. - Continuously update blacklist for known phishing sites in background.
- Automatically detect suspicious URLs too similar to common phishing targets, and blacklist them. - Automatically detect suspicious URLs too similar to common phishing targets, and blacklist them.

View File

@ -1,7 +1,7 @@
{ {
"name": "MetaMask", "name": "MetaMask",
"short_name": "Metamask", "short_name": "Metamask",
"version": "3.9.2", "version": "3.9.3",
"manifest_version": 2, "manifest_version": 2,
"author": "https://metamask.io", "author": "https://metamask.io",
"description": "Ethereum Browser Extension", "description": "Ethereum Browser Extension",

View File

@ -1,13 +1,9 @@
const ObservableStore = require('obs-store') const ObservableStore = require('obs-store')
const extend = require('xtend') const extend = require('xtend')
const communityBlacklistedDomains = require('etheraddresslookup/blacklists/domains.json') const PhishingDetector = require('eth-phishing-detect/src/detector')
const communityWhitelistedDomains = require('etheraddresslookup/whitelists/domains.json')
const checkForPhishing = require('../lib/is-phish')
// compute phishing lists // compute phishing lists
const PHISHING_BLACKLIST = communityBlacklistedDomains.concat(['metamask.com']) const PHISHING_DETECTION_CONFIG = require('eth-phishing-detect/src/config.json')
const PHISHING_WHITELIST = communityWhitelistedDomains.concat(['metamask.io', 'www.metamask.io'])
const PHISHING_FUZZYLIST = ['myetherwallet', 'myetheroll', 'ledgerwallet', 'metamask']
// every ten minutes // every ten minutes
const POLLING_INTERVAL = 10 * 60 * 1000 const POLLING_INTERVAL = 10 * 60 * 1000
@ -15,9 +11,12 @@ class BlacklistController {
constructor (opts = {}) { constructor (opts = {}) {
const initState = extend({ const initState = extend({
phishing: PHISHING_BLACKLIST, phishing: PHISHING_DETECTION_CONFIG,
}, opts.initState) }, opts.initState)
this.store = new ObservableStore(initState) this.store = new ObservableStore(initState)
// phishing detector
this._phishingDetector = null
this._setupPhishingDetector(initState.phishing)
// polling references // polling references
this._phishingUpdateIntervalRef = null this._phishingUpdateIntervalRef = null
} }
@ -28,14 +27,15 @@ class BlacklistController {
checkForPhishing (hostname) { checkForPhishing (hostname) {
if (!hostname) return false if (!hostname) return false
const { blacklist } = this.store.getState() const { result } = this._phishingDetector.check(hostname)
return checkForPhishing({ hostname, blacklist, whitelist: PHISHING_WHITELIST, fuzzylist: PHISHING_FUZZYLIST }) return result
} }
async updatePhishingList () { async updatePhishingList () {
const response = await fetch('https://api.infura.io/v1/blacklist') const response = await fetch('https://api.infura.io/v2/blacklist')
const phishing = await response.json() const phishing = await response.json()
this.store.updateState({ phishing }) this.store.updateState({ phishing })
this._setupPhishingDetector(phishing)
return phishing return phishing
} }
@ -45,6 +45,14 @@ class BlacklistController {
this.updatePhishingList() this.updatePhishingList()
}, POLLING_INTERVAL) }, POLLING_INTERVAL)
} }
//
// PRIVATE METHODS
//
_setupPhishingDetector (config) {
this._phishingDetector = new PhishingDetector(config)
}
} }
module.exports = BlacklistController module.exports = BlacklistController

View File

@ -1,23 +0,0 @@
const levenshtein = require('fast-levenshtein')
const LEVENSHTEIN_TOLERANCE = 4
// credit to @sogoiii and @409H for their help!
// Return a boolean on whether or not a phish is detected.
function isPhish({ hostname, blacklist, whitelist, fuzzylist }) {
// check if the domain is part of the whitelist.
if (whitelist && whitelist.includes(hostname)) return false
// check if the domain is part of the blacklist.
if (blacklist && blacklist.includes(hostname)) return true
// check for similar values.
const levenshteinForm = hostname.replace(/\./g, '')
const levenshteinMatched = fuzzylist.some((element) => {
return levenshtein.get(element, levenshteinForm) <= LEVENSHTEIN_TOLERANCE
})
return levenshteinMatched
}
module.exports = isPhish

View File

@ -1,9 +1,10 @@
const promiseToCallback = require('promise-to-callback') const promiseToCallback = require('promise-to-callback')
module.exports = function(fn, context) { module.exports = function nodeify (fn, context) {
return function(){ return function(){
const args = [].slice.call(arguments) const args = [].slice.call(arguments)
const callback = args.pop() const callback = args.pop()
if (typeof callback !== 'function') throw new Error('callback is not a function')
promiseToCallback(fn.apply(context, args))(callback) promiseToCallback(fn.apply(context, args))(callback)
} }
} }

View File

@ -7,7 +7,7 @@
"start": "npm run dev", "start": "npm run dev",
"dev": "gulp dev --debug", "dev": "gulp dev --debug",
"disc": "gulp disc --debug", "disc": "gulp disc --debug",
"clear": "rm -rf node_modules/eth-contract-metadata && rm -rf node_modules/etheraddresslookup", "clear": "rm -rf node_modules/eth-contract-metadata && rm -rf node_modules/eth-phishing-detect",
"dist": "npm run clear && npm install && gulp dist", "dist": "npm run clear && npm install && gulp dist",
"test": "npm run lint && npm run test-unit && npm run test-integration", "test": "npm run lint && npm run test-unit && npm run test-integration",
"test-unit": "METAMASK_ENV=test mocha --require test/helper.js --recursive \"test/unit/**/*.js\"", "test-unit": "METAMASK_ENV=test mocha --require test/helper.js --recursive \"test/unit/**/*.js\"",
@ -68,11 +68,11 @@
"eth-bin-to-ops": "^1.0.1", "eth-bin-to-ops": "^1.0.1",
"eth-contract-metadata": "^1.1.4", "eth-contract-metadata": "^1.1.4",
"eth-hd-keyring": "^1.1.1", "eth-hd-keyring": "^1.1.1",
"eth-phishing-detect": "^1.1.0",
"eth-query": "^2.1.2", "eth-query": "^2.1.2",
"eth-sig-util": "^1.2.2", "eth-sig-util": "^1.2.2",
"eth-simple-keyring": "^1.1.1", "eth-simple-keyring": "^1.1.1",
"eth-token-tracker": "^1.1.2", "eth-token-tracker": "^1.1.2",
"etheraddresslookup": "github:409H/EtherAddressLookup",
"ethereumjs-tx": "^1.3.0", "ethereumjs-tx": "^1.3.0",
"ethereumjs-util": "ethereumjs/ethereumjs-util#ac5d0908536b447083ea422b435da27f26615de9", "ethereumjs-util": "ethereumjs/ethereumjs-util#ac5d0908536b447083ea422b435da27f26615de9",
"ethereumjs-wallet": "^0.6.0", "ethereumjs-wallet": "^0.6.0",

View File

@ -45,15 +45,17 @@ describe('tx confirmation screen', function () {
before(function (done) { before(function (done) {
actions._setBackgroundConnection({ actions._setBackgroundConnection({
approveTransaction (txId, cb) { cb('An error!') }, approveTransaction (txId, cb) { cb('An error!') },
cancelTransaction (txId) { /* noop */ }, cancelTransaction (txId, cb) { cb() },
clearSeedWordCache (cb) { cb() }, clearSeedWordCache (cb) { cb() },
}) })
const action = actions.cancelTx({value: firstTxId}) actions.cancelTx({value: firstTxId})((action) => {
result = reducers(initialState, action) result = reducers(initialState, action)
done() done()
}) })
})
it('should transition to the account detail view', function () { it('should transition to the account detail view', function () {
assert.equal(result.appState.currentView.name, 'accountDetail') assert.equal(result.appState.currentView.name, 'accountDetail')
}) })

View File

@ -17,4 +17,15 @@ describe('nodeify', function () {
done() done()
}) })
}) })
it('should throw if the last argument is not a function', function (done) {
const nodified = nodeify(obj.promiseFunc, obj)
try {
nodified('baz')
done(new Error('should have thrown if the last argument is not a function'))
} catch (err) {
assert.equal(err.message, 'callback is not a function')
done()
}
})
}) })

View File

@ -462,9 +462,12 @@ function cancelPersonalMsg (msgData) {
} }
function cancelTx (txData) { function cancelTx (txData) {
return (dispatch) => {
log.debug(`background.cancelTransaction`) log.debug(`background.cancelTransaction`)
background.cancelTransaction(txData.id) background.cancelTransaction(txData.id, () => {
return actions.completedTx(txData.id) dispatch(actions.completedTx(txData.id))
})
}
} }
// //