mirror of
https://github.com/kremalicious/metamask-extension.git
synced 2024-12-22 09:23:21 +01:00
Merge branch 'master' into NewUI
This commit is contained in:
commit
5a9257208c
@ -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.
|
||||||
|
|
||||||
|
@ -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",
|
||||||
|
@ -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
|
||||||
|
@ -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
|
|
@ -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)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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",
|
||||||
|
@ -45,13 +45,15 @@ 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 () {
|
||||||
|
@ -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()
|
||||||
|
}
|
||||||
|
})
|
||||||
})
|
})
|
||||||
|
@ -462,9 +462,12 @@ function cancelPersonalMsg (msgData) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function cancelTx (txData) {
|
function cancelTx (txData) {
|
||||||
log.debug(`background.cancelTransaction`)
|
return (dispatch) => {
|
||||||
background.cancelTransaction(txData.id)
|
log.debug(`background.cancelTransaction`)
|
||||||
return actions.completedTx(txData.id)
|
background.cancelTransaction(txData.id, () => {
|
||||||
|
dispatch(actions.completedTx(txData.id))
|
||||||
|
})
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
|
Loading…
Reference in New Issue
Block a user