mirror of
https://github.com/kremalicious/metamask-extension.git
synced 2024-12-23 09:52:26 +01:00
Merge pull request #4566 from MetaMask/notice-phishing
Push new notice on recent phishing incidents
This commit is contained in:
commit
3a5089da6f
@ -7,6 +7,7 @@
|
|||||||
- Fix bug where account reset did not work with custom RPC providers.
|
- Fix bug where account reset did not work with custom RPC providers.
|
||||||
- Fix bug where nonce mutex was never released
|
- Fix bug where nonce mutex was never released
|
||||||
- Stop reloading browser page on Ethereum network change
|
- Stop reloading browser page on Ethereum network change
|
||||||
|
- Add phishing notice
|
||||||
|
|
||||||
## 4.7.4 Tue Jun 05 2018
|
## 4.7.4 Tue Jun 05 2018
|
||||||
|
|
||||||
|
@ -189,9 +189,6 @@ module.exports = class MetamaskController extends EventEmitter {
|
|||||||
version,
|
version,
|
||||||
firstVersion: initState.firstTimeInfo.version,
|
firstVersion: initState.firstTimeInfo.version,
|
||||||
})
|
})
|
||||||
this.noticeController.updateNoticesList()
|
|
||||||
// to be uncommented when retrieving notices from a remote server.
|
|
||||||
// this.noticeController.startPolling()
|
|
||||||
|
|
||||||
this.shapeshiftController = new ShapeShiftController({
|
this.shapeshiftController = new ShapeShiftController({
|
||||||
initState: initState.ShapeShiftController,
|
initState: initState.ShapeShiftController,
|
||||||
|
@ -2,7 +2,7 @@ const EventEmitter = require('events').EventEmitter
|
|||||||
const semver = require('semver')
|
const semver = require('semver')
|
||||||
const extend = require('xtend')
|
const extend = require('xtend')
|
||||||
const ObservableStore = require('obs-store')
|
const ObservableStore = require('obs-store')
|
||||||
const hardCodedNotices = require('../../notices/notices.json')
|
const hardCodedNotices = require('../../notices/notices.js')
|
||||||
const uniqBy = require('lodash.uniqby')
|
const uniqBy = require('lodash.uniqby')
|
||||||
|
|
||||||
module.exports = class NoticeController extends EventEmitter {
|
module.exports = class NoticeController extends EventEmitter {
|
||||||
@ -13,11 +13,12 @@ module.exports = class NoticeController extends EventEmitter {
|
|||||||
this.firstVersion = opts.firstVersion
|
this.firstVersion = opts.firstVersion
|
||||||
this.version = opts.version
|
this.version = opts.version
|
||||||
const initState = extend({
|
const initState = extend({
|
||||||
noticesList: [],
|
noticesList: this._filterNotices(hardCodedNotices),
|
||||||
}, opts.initState)
|
}, opts.initState)
|
||||||
this.store = new ObservableStore(initState)
|
this.store = new ObservableStore(initState)
|
||||||
this.memStore = new ObservableStore({})
|
this.memStore = new ObservableStore({})
|
||||||
this.store.subscribe(() => this._updateMemstore())
|
this.store.subscribe(() => this._updateMemstore())
|
||||||
|
this._updateMemstore()
|
||||||
}
|
}
|
||||||
|
|
||||||
getNoticesList () {
|
getNoticesList () {
|
||||||
@ -29,9 +30,9 @@ module.exports = class NoticeController extends EventEmitter {
|
|||||||
return notices.filter((notice) => notice.read === false)
|
return notices.filter((notice) => notice.read === false)
|
||||||
}
|
}
|
||||||
|
|
||||||
getLatestUnreadNotice () {
|
getNextUnreadNotice () {
|
||||||
const unreadNotices = this.getUnreadNotices()
|
const unreadNotices = this.getUnreadNotices()
|
||||||
return unreadNotices[unreadNotices.length - 1]
|
return unreadNotices[0]
|
||||||
}
|
}
|
||||||
|
|
||||||
async setNoticesList (noticesList) {
|
async setNoticesList (noticesList) {
|
||||||
@ -47,7 +48,7 @@ module.exports = class NoticeController extends EventEmitter {
|
|||||||
notices[index].read = true
|
notices[index].read = true
|
||||||
notices[index].body = ''
|
notices[index].body = ''
|
||||||
this.setNoticesList(notices)
|
this.setNoticesList(notices)
|
||||||
const latestNotice = this.getLatestUnreadNotice()
|
const latestNotice = this.getNextUnreadNotice()
|
||||||
cb(null, latestNotice)
|
cb(null, latestNotice)
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
cb(err)
|
cb(err)
|
||||||
@ -64,15 +65,6 @@ module.exports = class NoticeController extends EventEmitter {
|
|||||||
return result
|
return result
|
||||||
}
|
}
|
||||||
|
|
||||||
startPolling () {
|
|
||||||
if (this.noticePoller) {
|
|
||||||
clearInterval(this.noticePoller)
|
|
||||||
}
|
|
||||||
this.noticePoller = setInterval(() => {
|
|
||||||
this.noticeController.updateNoticesList()
|
|
||||||
}, 300000)
|
|
||||||
}
|
|
||||||
|
|
||||||
_mergeNotices (oldNotices, newNotices) {
|
_mergeNotices (oldNotices, newNotices) {
|
||||||
return uniqBy(oldNotices.concat(newNotices), 'id')
|
return uniqBy(oldNotices.concat(newNotices), 'id')
|
||||||
}
|
}
|
||||||
@ -91,19 +83,15 @@ module.exports = class NoticeController extends EventEmitter {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
_mapNoticeIds (notices) {
|
|
||||||
return notices.map((notice) => notice.id)
|
|
||||||
}
|
|
||||||
|
|
||||||
async _retrieveNoticeData () {
|
async _retrieveNoticeData () {
|
||||||
// Placeholder for the API.
|
// Placeholder for the API.
|
||||||
return hardCodedNotices
|
return []
|
||||||
}
|
}
|
||||||
|
|
||||||
_updateMemstore () {
|
_updateMemstore () {
|
||||||
const lastUnreadNotice = this.getLatestUnreadNotice()
|
const nextUnreadNotice = this.getNextUnreadNotice()
|
||||||
const noActiveNotices = !lastUnreadNotice
|
const noActiveNotices = !nextUnreadNotice
|
||||||
this.memStore.updateState({ lastUnreadNotice, noActiveNotices })
|
this.memStore.updateState({ nextUnreadNotice, noActiveNotices })
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -52,7 +52,7 @@
|
|||||||
"conversionRate": 12.7200827,
|
"conversionRate": 12.7200827,
|
||||||
"conversionDate": 1487363041,
|
"conversionDate": 1487363041,
|
||||||
"noActiveNotices": true,
|
"noActiveNotices": true,
|
||||||
"lastUnreadNotice": {
|
"nextUnreadNotice": {
|
||||||
"read": true,
|
"read": true,
|
||||||
"date": "Thu Feb 09 2017",
|
"date": "Thu Feb 09 2017",
|
||||||
"title": "Terms of Use",
|
"title": "Terms of Use",
|
||||||
|
@ -12,7 +12,7 @@
|
|||||||
"conversionRate": 12.7527416,
|
"conversionRate": 12.7527416,
|
||||||
"conversionDate": 1487624341,
|
"conversionDate": 1487624341,
|
||||||
"noActiveNotices": false,
|
"noActiveNotices": false,
|
||||||
"lastUnreadNotice": {
|
"nextUnreadNotice": {
|
||||||
"read": false,
|
"read": false,
|
||||||
"date": "Thu Feb 09 2017",
|
"date": "Thu Feb 09 2017",
|
||||||
"title": "Terms of Use",
|
"title": "Terms of Use",
|
||||||
|
@ -13,7 +13,7 @@
|
|||||||
"conversionRate": 8.3533002,
|
"conversionRate": 8.3533002,
|
||||||
"conversionDate": 1481671082,
|
"conversionDate": 1481671082,
|
||||||
"noActiveNotices": false,
|
"noActiveNotices": false,
|
||||||
"lastUnreadNotice": {
|
"nextUnreadNotice": {
|
||||||
"read": false,
|
"read": false,
|
||||||
"date": "Tue Dec 13 2016",
|
"date": "Tue Dec 13 2016",
|
||||||
"title": "MultiVault Support",
|
"title": "MultiVault Support",
|
||||||
|
@ -14,7 +14,7 @@ import LoadingScreen from './loading-screen'
|
|||||||
class NoticeScreen extends Component {
|
class NoticeScreen extends Component {
|
||||||
static propTypes = {
|
static propTypes = {
|
||||||
address: PropTypes.string.isRequired,
|
address: PropTypes.string.isRequired,
|
||||||
lastUnreadNotice: PropTypes.shape({
|
nextUnreadNotice: PropTypes.shape({
|
||||||
title: PropTypes.string,
|
title: PropTypes.string,
|
||||||
date: PropTypes.string,
|
date: PropTypes.string,
|
||||||
body: PropTypes.string,
|
body: PropTypes.string,
|
||||||
@ -31,7 +31,7 @@ class NoticeScreen extends Component {
|
|||||||
};
|
};
|
||||||
|
|
||||||
static defaultProps = {
|
static defaultProps = {
|
||||||
lastUnreadNotice: {},
|
nextUnreadNotice: {},
|
||||||
};
|
};
|
||||||
|
|
||||||
state = {
|
state = {
|
||||||
@ -47,8 +47,8 @@ class NoticeScreen extends Component {
|
|||||||
}
|
}
|
||||||
|
|
||||||
acceptTerms = () => {
|
acceptTerms = () => {
|
||||||
const { markNoticeRead, lastUnreadNotice, history } = this.props
|
const { markNoticeRead, nextUnreadNotice, history } = this.props
|
||||||
markNoticeRead(lastUnreadNotice)
|
markNoticeRead(nextUnreadNotice)
|
||||||
.then(hasActiveNotices => {
|
.then(hasActiveNotices => {
|
||||||
if (!hasActiveNotices) {
|
if (!hasActiveNotices) {
|
||||||
history.push(INITIALIZE_BACKUP_PHRASE_ROUTE)
|
history.push(INITIALIZE_BACKUP_PHRASE_ROUTE)
|
||||||
@ -72,7 +72,7 @@ class NoticeScreen extends Component {
|
|||||||
render () {
|
render () {
|
||||||
const {
|
const {
|
||||||
address,
|
address,
|
||||||
lastUnreadNotice: { title, body },
|
nextUnreadNotice: { title, body },
|
||||||
isLoading,
|
isLoading,
|
||||||
} = this.props
|
} = this.props
|
||||||
const { atBottom } = this.state
|
const { atBottom } = this.state
|
||||||
@ -113,12 +113,12 @@ class NoticeScreen extends Component {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const mapStateToProps = ({ metamask, appState }) => {
|
const mapStateToProps = ({ metamask, appState }) => {
|
||||||
const { selectedAddress, lastUnreadNotice, noActiveNotices } = metamask
|
const { selectedAddress, nextUnreadNotice, noActiveNotices } = metamask
|
||||||
const { isLoading } = appState
|
const { isLoading } = appState
|
||||||
|
|
||||||
return {
|
return {
|
||||||
address: selectedAddress,
|
address: selectedAddress,
|
||||||
lastUnreadNotice,
|
nextUnreadNotice,
|
||||||
noActiveNotices,
|
noActiveNotices,
|
||||||
isLoading,
|
isLoading,
|
||||||
}
|
}
|
||||||
|
6
notices/archive/notice_4.md
Normal file
6
notices/archive/notice_4.md
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
Dear MetaMask Users,
|
||||||
|
|
||||||
|
There have been several instances of high-profile legitimate websites such as BTC Manager and Games Workshop that have had their websites temporarily compromised. This involves showing a fake MetaMask window on the page asking for user's seed phrases. MetaMask will never open itself in this way and users are encouraged to report these instances immediately to either [our phishing blacklist](https://github.com/MetaMask/eth-phishing-detect/issues) or our support email at [support@metamask.io](support@metamask.io).
|
||||||
|
|
||||||
|
Please read our full article on this ongoing issue at [https://medium.com/metamask/new-phishing-strategy-becoming-common-1b1123837168](https://medium.com/metamask/new-phishing-strategy-becoming-common-1b1123837168).
|
||||||
|
|
@ -1,27 +0,0 @@
|
|||||||
var fs = require('fs')
|
|
||||||
var path = require('path')
|
|
||||||
var prompt = require('prompt')
|
|
||||||
var open = require('open')
|
|
||||||
var extend = require('extend')
|
|
||||||
var notices = require('./notices.json')
|
|
||||||
|
|
||||||
|
|
||||||
console.log('List of Notices')
|
|
||||||
console.log(`ID \t DATE \t\t\t TITLE`)
|
|
||||||
notices.forEach((notice) => {
|
|
||||||
console.log(`${(' ' + notice.id).slice(-2)} \t ${notice.date} \t ${notice.title}`)
|
|
||||||
})
|
|
||||||
prompt.get(['id'], (error, res) => {
|
|
||||||
prompt.start()
|
|
||||||
if (error) {
|
|
||||||
console.log("Exiting...")
|
|
||||||
process.exit()
|
|
||||||
}
|
|
||||||
var index = notices.findIndex((notice) => { return notice.id == res.id})
|
|
||||||
if (index === -1) {
|
|
||||||
console.log('Notice not found. Exiting...')
|
|
||||||
}
|
|
||||||
notices.splice(index, 1)
|
|
||||||
fs.unlink(`notices/archive/notice_${res.id}.md`)
|
|
||||||
fs.writeFile(`notices/notices.json`, JSON.stringify(notices))
|
|
||||||
})
|
|
@ -1,33 +0,0 @@
|
|||||||
var fsp = require('fs-promise')
|
|
||||||
var path = require('path')
|
|
||||||
var prompt = require('prompt')
|
|
||||||
var open = require('open')
|
|
||||||
var extend = require('extend')
|
|
||||||
var notices = require('./notices.json')
|
|
||||||
var id = Number(require('./notice-nonce.json'))
|
|
||||||
|
|
||||||
var date = new Date().toDateString()
|
|
||||||
|
|
||||||
var notice = {
|
|
||||||
read: false,
|
|
||||||
date: date,
|
|
||||||
}
|
|
||||||
|
|
||||||
fsp.writeFile(`notices/archive/notice_${id}.md`,'Message goes here. Please write out your notice and save before proceeding at the command line.')
|
|
||||||
.then(() => {
|
|
||||||
open(`notices/archive/notice_${id}.md`)
|
|
||||||
prompt.start()
|
|
||||||
prompt.get(['title'], (err, result) => {
|
|
||||||
notice.title = result.title
|
|
||||||
fsp.readFile(`notices/archive/notice_${id}.md`)
|
|
||||||
.then((body) => {
|
|
||||||
notice.body = body.toString()
|
|
||||||
notice.id = id
|
|
||||||
notices.push(notice)
|
|
||||||
return fsp.writeFile(`notices/notices.json`, JSON.stringify(notices))
|
|
||||||
}).then((completion) => {
|
|
||||||
id += 1
|
|
||||||
return fsp.writeFile(`notices/notice-nonce.json`, id)
|
|
||||||
})
|
|
||||||
})
|
|
||||||
})
|
|
@ -1 +0,0 @@
|
|||||||
4
|
|
34
notices/notices.js
Normal file
34
notices/notices.js
Normal file
@ -0,0 +1,34 @@
|
|||||||
|
// fs.readFileSync is inlined by browserify transform "brfs"
|
||||||
|
const fs = require('fs')
|
||||||
|
|
||||||
|
module.exports = [
|
||||||
|
{
|
||||||
|
id: 0,
|
||||||
|
read: false,
|
||||||
|
date: 'Thu Feb 09 2017',
|
||||||
|
title: 'Terms of Use',
|
||||||
|
body: fs.readFileSync(__dirname + '/archive/notice_0.md', 'utf8'),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 2,
|
||||||
|
read: false,
|
||||||
|
date: 'Mon May 08 2017',
|
||||||
|
title: 'Privacy Notice',
|
||||||
|
body: fs.readFileSync(__dirname + '/archive/notice_2.md', 'utf8'),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 3,
|
||||||
|
read: false,
|
||||||
|
date: 'Tue Nov 28 2017',
|
||||||
|
title: 'Seed Phrase Alert',
|
||||||
|
firstVersion: '<=3.12.0',
|
||||||
|
body: fs.readFileSync(__dirname + '/archive/notice_3.md', 'utf8'),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 4,
|
||||||
|
read: false,
|
||||||
|
date: 'Wed Jun 13 2018',
|
||||||
|
title: 'Phishing Warning',
|
||||||
|
body: fs.readFileSync(__dirname + '/archive/notice_4.md', 'utf8'),
|
||||||
|
}
|
||||||
|
]
|
File diff suppressed because one or more lines are too long
@ -73,7 +73,7 @@ function mapStateToProps (state) {
|
|||||||
network: state.metamask.network,
|
network: state.metamask.network,
|
||||||
provider: state.metamask.provider,
|
provider: state.metamask.provider,
|
||||||
forgottenPassword: state.appState.forgottenPassword,
|
forgottenPassword: state.appState.forgottenPassword,
|
||||||
lastUnreadNotice: state.metamask.lastUnreadNotice,
|
nextUnreadNotice: state.metamask.nextUnreadNotice,
|
||||||
lostAccounts: state.metamask.lostAccounts,
|
lostAccounts: state.metamask.lostAccounts,
|
||||||
frequentRpcList: state.metamask.frequentRpcList || [],
|
frequentRpcList: state.metamask.frequentRpcList || [],
|
||||||
featureFlags,
|
featureFlags,
|
||||||
@ -460,9 +460,9 @@ App.prototype.renderPrimary = function () {
|
|||||||
}, [
|
}, [
|
||||||
|
|
||||||
h(NoticeScreen, {
|
h(NoticeScreen, {
|
||||||
notice: props.lastUnreadNotice,
|
notice: props.nextUnreadNotice,
|
||||||
key: 'NoticeScreen',
|
key: 'NoticeScreen',
|
||||||
onConfirm: () => props.dispatch(actions.markNoticeRead(props.lastUnreadNotice)),
|
onConfirm: () => props.dispatch(actions.markNoticeRead(props.nextUnreadNotice)),
|
||||||
}),
|
}),
|
||||||
|
|
||||||
!props.isInitialized && h('.flex-row.flex-center.flex-grow', [
|
!props.isInitialized && h('.flex-row.flex-center.flex-grow', [
|
||||||
|
@ -46,8 +46,6 @@
|
|||||||
"disc": "gulp disc --debug",
|
"disc": "gulp disc --debug",
|
||||||
"announce": "node development/announcer.js",
|
"announce": "node development/announcer.js",
|
||||||
"version:bump": "node development/run-version-bump.js",
|
"version:bump": "node development/run-version-bump.js",
|
||||||
"generateNotice": "node notices/notice-generator.js",
|
|
||||||
"deleteNotice": "node notices/notice-delete.js",
|
|
||||||
"storybook": "start-storybook -p 6006 -c .storybook"
|
"storybook": "start-storybook -p 6006 -c .storybook"
|
||||||
},
|
},
|
||||||
"browserify": {
|
"browserify": {
|
||||||
|
@ -134,21 +134,34 @@ describe('Using MetaMask with an existing account', function () {
|
|||||||
await delay(regularDelayMs)
|
await delay(regularDelayMs)
|
||||||
})
|
})
|
||||||
|
|
||||||
it('clicks through the privacy notice', async () => {
|
it('clicks through the ToS', async () => {
|
||||||
const [nextScreen] = await findElements(driver, By.css('.tou button'))
|
// terms of use
|
||||||
await nextScreen.click()
|
|
||||||
await delay(regularDelayMs)
|
|
||||||
|
|
||||||
const canClickThrough = await driver.findElement(By.css('.tou button')).isEnabled()
|
const canClickThrough = await driver.findElement(By.css('.tou button')).isEnabled()
|
||||||
assert.equal(canClickThrough, false, 'disabled continue button')
|
assert.equal(canClickThrough, false, 'disabled continue button')
|
||||||
const element = await findElement(driver, By.linkText('Attributions'))
|
const bottomOfTos = await findElement(driver, By.linkText('Attributions'))
|
||||||
await driver.executeScript('arguments[0].scrollIntoView(true)', element)
|
await driver.executeScript('arguments[0].scrollIntoView(true)', bottomOfTos)
|
||||||
await delay(regularDelayMs)
|
await delay(regularDelayMs)
|
||||||
|
const acceptTos = await findElement(driver, By.css('.tou button'))
|
||||||
const acceptTos = await findElement(driver, By.xpath(`//button[contains(text(), 'Accept')]`))
|
|
||||||
await acceptTos.click()
|
await acceptTos.click()
|
||||||
await delay(regularDelayMs)
|
await delay(regularDelayMs)
|
||||||
})
|
})
|
||||||
|
|
||||||
|
it('clicks through the privacy notice', async () => {
|
||||||
|
// privacy notice
|
||||||
|
const nextScreen = await findElement(driver, By.css('.tou button'))
|
||||||
|
await nextScreen.click()
|
||||||
|
await delay(regularDelayMs)
|
||||||
|
})
|
||||||
|
|
||||||
|
it('clicks through the phishing notice', async () => {
|
||||||
|
// phishing notice
|
||||||
|
const noticeElement = await driver.findElement(By.css('.markdown'))
|
||||||
|
await driver.executeScript('arguments[0].scrollTop = arguments[0].scrollHeight', noticeElement)
|
||||||
|
await delay(regularDelayMs)
|
||||||
|
const nextScreen = await findElement(driver, By.css('.tou button'))
|
||||||
|
await nextScreen.click()
|
||||||
|
await delay(regularDelayMs)
|
||||||
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
describe('Show account information', () => {
|
describe('Show account information', () => {
|
||||||
|
@ -128,22 +128,35 @@ describe('MetaMask', function () {
|
|||||||
await delay(regularDelayMs)
|
await delay(regularDelayMs)
|
||||||
})
|
})
|
||||||
|
|
||||||
it('clicks through the privacy notice', async () => {
|
it('clicks through the ToS', async () => {
|
||||||
const nextScreen = await findElement(driver, By.css('.tou button'))
|
// terms of use
|
||||||
await nextScreen.click()
|
|
||||||
await delay(regularDelayMs)
|
|
||||||
|
|
||||||
const canClickThrough = await driver.findElement(By.css('.tou button')).isEnabled()
|
const canClickThrough = await driver.findElement(By.css('.tou button')).isEnabled()
|
||||||
assert.equal(canClickThrough, false, 'disabled continue button')
|
assert.equal(canClickThrough, false, 'disabled continue button')
|
||||||
const bottomOfTos = await findElement(driver, By.linkText('Attributions'))
|
const bottomOfTos = await findElement(driver, By.linkText('Attributions'))
|
||||||
await driver.executeScript('arguments[0].scrollIntoView(true)', bottomOfTos)
|
await driver.executeScript('arguments[0].scrollIntoView(true)', bottomOfTos)
|
||||||
await delay(regularDelayMs)
|
await delay(regularDelayMs)
|
||||||
|
|
||||||
const acceptTos = await findElement(driver, By.css('.tou button'))
|
const acceptTos = await findElement(driver, By.css('.tou button'))
|
||||||
await acceptTos.click()
|
await acceptTos.click()
|
||||||
await delay(regularDelayMs)
|
await delay(regularDelayMs)
|
||||||
})
|
})
|
||||||
|
|
||||||
|
it('clicks through the privacy notice', async () => {
|
||||||
|
// privacy notice
|
||||||
|
const nextScreen = await findElement(driver, By.css('.tou button'))
|
||||||
|
await nextScreen.click()
|
||||||
|
await delay(regularDelayMs)
|
||||||
|
})
|
||||||
|
|
||||||
|
it('clicks through the phishing notice', async () => {
|
||||||
|
// phishing notice
|
||||||
|
const noticeElement = await driver.findElement(By.css('.markdown'))
|
||||||
|
await driver.executeScript('arguments[0].scrollTop = arguments[0].scrollHeight', noticeElement)
|
||||||
|
await delay(regularDelayMs)
|
||||||
|
const nextScreen = await findElement(driver, By.css('.tou button'))
|
||||||
|
await nextScreen.click()
|
||||||
|
await delay(regularDelayMs)
|
||||||
|
})
|
||||||
|
|
||||||
let seedPhrase
|
let seedPhrase
|
||||||
|
|
||||||
it('reveals the seed phrase', async () => {
|
it('reveals the seed phrase', async () => {
|
||||||
|
@ -71,13 +71,6 @@ describe('Metamask popup page', function () {
|
|||||||
it('matches MetaMask title', async () => {
|
it('matches MetaMask title', async () => {
|
||||||
const title = await driver.getTitle()
|
const title = await driver.getTitle()
|
||||||
assert.equal(title, 'MetaMask', 'title matches MetaMask')
|
assert.equal(title, 'MetaMask', 'title matches MetaMask')
|
||||||
})
|
|
||||||
|
|
||||||
it('shows privacy notice', async () => {
|
|
||||||
await delay(300)
|
|
||||||
const privacy = await driver.findElement(By.css('.terms-header')).getText()
|
|
||||||
assert.equal(privacy, 'PRIVACY NOTICE', 'shows privacy notice')
|
|
||||||
await driver.findElement(By.css('button')).click()
|
|
||||||
await delay(300)
|
await delay(300)
|
||||||
})
|
})
|
||||||
|
|
||||||
@ -100,6 +93,24 @@ describe('Metamask popup page', function () {
|
|||||||
await button.click()
|
await button.click()
|
||||||
})
|
})
|
||||||
|
|
||||||
|
it('shows privacy notice', async () => {
|
||||||
|
const privacy = await driver.findElement(By.css('.terms-header')).getText()
|
||||||
|
assert.equal(privacy, 'PRIVACY NOTICE', 'shows privacy notice')
|
||||||
|
await driver.findElement(By.css('button')).click()
|
||||||
|
await delay(300)
|
||||||
|
})
|
||||||
|
|
||||||
|
it('shows phishing notice', async () => {
|
||||||
|
await delay(300)
|
||||||
|
const noticeHeader = await driver.findElement(By.css('.terms-header')).getText()
|
||||||
|
assert.equal(noticeHeader, 'PHISHING WARNING', 'shows phishing warning')
|
||||||
|
const element = await driver.findElement(By.css('.markdown'))
|
||||||
|
await driver.executeScript('arguments[0].scrollTop = arguments[0].scrollHeight', element)
|
||||||
|
await delay(300)
|
||||||
|
await driver.findElement(By.css('button')).click()
|
||||||
|
await delay(300)
|
||||||
|
})
|
||||||
|
|
||||||
it('accepts password with length of eight', async () => {
|
it('accepts password with length of eight', async () => {
|
||||||
const passwordBox = await driver.findElement(By.id('password-box'))
|
const passwordBox = await driver.findElement(By.id('password-box'))
|
||||||
const passwordBoxConfirm = await driver.findElement(By.id('password-box-confirm'))
|
const passwordBoxConfirm = await driver.findElement(By.id('password-box-confirm'))
|
||||||
|
@ -14,18 +14,6 @@ describe('notice-controller', function () {
|
|||||||
})
|
})
|
||||||
|
|
||||||
describe('notices', function () {
|
describe('notices', function () {
|
||||||
describe('#getNoticesList', function () {
|
|
||||||
it('should return an empty array when new', function (done) {
|
|
||||||
// const testList = [{
|
|
||||||
// id: 0,
|
|
||||||
// read: false,
|
|
||||||
// title: 'Futuristic Notice',
|
|
||||||
// }]
|
|
||||||
var result = noticeController.getNoticesList()
|
|
||||||
assert.equal(result.length, 0)
|
|
||||||
done()
|
|
||||||
})
|
|
||||||
})
|
|
||||||
|
|
||||||
describe('#setNoticesList', function () {
|
describe('#setNoticesList', function () {
|
||||||
it('should set data appropriately', function (done) {
|
it('should set data appropriately', function (done) {
|
||||||
@ -41,36 +29,6 @@ describe('notice-controller', function () {
|
|||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
describe('#updateNoticeslist', function () {
|
|
||||||
it('should integrate the latest changes from the source', function (done) {
|
|
||||||
var testList = [{
|
|
||||||
id: 55,
|
|
||||||
read: false,
|
|
||||||
title: 'Futuristic Notice',
|
|
||||||
}]
|
|
||||||
noticeController.setNoticesList(testList)
|
|
||||||
noticeController.updateNoticesList().then(() => {
|
|
||||||
var newList = noticeController.getNoticesList()
|
|
||||||
assert.ok(newList[0].id === 55)
|
|
||||||
assert.ok(newList[1])
|
|
||||||
done()
|
|
||||||
})
|
|
||||||
})
|
|
||||||
it('should not overwrite any existing fields', function (done) {
|
|
||||||
var testList = [{
|
|
||||||
id: 0,
|
|
||||||
read: false,
|
|
||||||
title: 'Futuristic Notice',
|
|
||||||
}]
|
|
||||||
noticeController.setNoticesList(testList)
|
|
||||||
var newList = noticeController.getNoticesList()
|
|
||||||
assert.equal(newList[0].id, 0)
|
|
||||||
assert.equal(newList[0].title, 'Futuristic Notice')
|
|
||||||
assert.equal(newList.length, 1)
|
|
||||||
done()
|
|
||||||
})
|
|
||||||
})
|
|
||||||
|
|
||||||
describe('#markNoticeRead', function () {
|
describe('#markNoticeRead', function () {
|
||||||
it('should mark a notice as read', function (done) {
|
it('should mark a notice as read', function (done) {
|
||||||
var testList = [{
|
var testList = [{
|
||||||
@ -86,7 +44,7 @@ describe('notice-controller', function () {
|
|||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
describe('#getLatestUnreadNotice', function () {
|
describe('#getNextUnreadNotice', function () {
|
||||||
it('should retrieve the latest unread notice', function (done) {
|
it('should retrieve the latest unread notice', function (done) {
|
||||||
var testList = [
|
var testList = [
|
||||||
{id: 0, read: true, title: 'Past Notice'},
|
{id: 0, read: true, title: 'Past Notice'},
|
||||||
@ -94,8 +52,8 @@ describe('notice-controller', function () {
|
|||||||
{id: 2, read: false, title: 'Future Notice'},
|
{id: 2, read: false, title: 'Future Notice'},
|
||||||
]
|
]
|
||||||
noticeController.setNoticesList(testList)
|
noticeController.setNoticesList(testList)
|
||||||
var latestUnread = noticeController.getLatestUnreadNotice()
|
var latestUnread = noticeController.getNextUnreadNotice()
|
||||||
assert.equal(latestUnread.id, 2)
|
assert.equal(latestUnread.id, 1)
|
||||||
done()
|
done()
|
||||||
})
|
})
|
||||||
it('should return undefined if no unread notices exist.', function (done) {
|
it('should return undefined if no unread notices exist.', function (done) {
|
||||||
@ -105,7 +63,7 @@ describe('notice-controller', function () {
|
|||||||
{id: 2, read: true, title: 'Future Notice'},
|
{id: 2, read: true, title: 'Future Notice'},
|
||||||
]
|
]
|
||||||
noticeController.setNoticesList(testList)
|
noticeController.setNoticesList(testList)
|
||||||
var latestUnread = noticeController.getLatestUnreadNotice()
|
var latestUnread = noticeController.getNextUnreadNotice()
|
||||||
assert.ok(!latestUnread)
|
assert.ok(!latestUnread)
|
||||||
done()
|
done()
|
||||||
})
|
})
|
||||||
|
@ -314,7 +314,7 @@ function mapStateToProps (state) {
|
|||||||
noActiveNotices,
|
noActiveNotices,
|
||||||
seedWords,
|
seedWords,
|
||||||
unapprovedTxs,
|
unapprovedTxs,
|
||||||
lastUnreadNotice,
|
nextUnreadNotice,
|
||||||
lostAccounts,
|
lostAccounts,
|
||||||
unapprovedMsgCount,
|
unapprovedMsgCount,
|
||||||
unapprovedPersonalMsgCount,
|
unapprovedPersonalMsgCount,
|
||||||
@ -348,7 +348,7 @@ function mapStateToProps (state) {
|
|||||||
network: state.metamask.network,
|
network: state.metamask.network,
|
||||||
provider: state.metamask.provider,
|
provider: state.metamask.provider,
|
||||||
forgottenPassword: state.appState.forgottenPassword,
|
forgottenPassword: state.appState.forgottenPassword,
|
||||||
lastUnreadNotice,
|
nextUnreadNotice,
|
||||||
lostAccounts,
|
lostAccounts,
|
||||||
frequentRpcList: state.metamask.frequentRpcList || [],
|
frequentRpcList: state.metamask.frequentRpcList || [],
|
||||||
currentCurrency: state.metamask.currentCurrency,
|
currentCurrency: state.metamask.currentCurrency,
|
||||||
|
@ -86,9 +86,9 @@ class Home extends Component {
|
|||||||
// if (!props.noActiveNotices) {
|
// if (!props.noActiveNotices) {
|
||||||
// log.debug('rendering notice screen for unread notices.')
|
// log.debug('rendering notice screen for unread notices.')
|
||||||
// return h(NoticeScreen, {
|
// return h(NoticeScreen, {
|
||||||
// notice: props.lastUnreadNotice,
|
// notice: props.nextUnreadNotice,
|
||||||
// key: 'NoticeScreen',
|
// key: 'NoticeScreen',
|
||||||
// onConfirm: () => props.dispatch(actions.markNoticeRead(props.lastUnreadNotice)),
|
// onConfirm: () => props.dispatch(actions.markNoticeRead(props.nextUnreadNotice)),
|
||||||
// })
|
// })
|
||||||
// } else if (props.lostAccounts && props.lostAccounts.length > 0) {
|
// } else if (props.lostAccounts && props.lostAccounts.length > 0) {
|
||||||
// log.debug('rendering notice screen for lost accounts view.')
|
// log.debug('rendering notice screen for lost accounts view.')
|
||||||
@ -279,7 +279,7 @@ function mapStateToProps (state) {
|
|||||||
noActiveNotices,
|
noActiveNotices,
|
||||||
seedWords,
|
seedWords,
|
||||||
unapprovedTxs,
|
unapprovedTxs,
|
||||||
lastUnreadNotice,
|
nextUnreadNotice,
|
||||||
lostAccounts,
|
lostAccounts,
|
||||||
unapprovedMsgCount,
|
unapprovedMsgCount,
|
||||||
unapprovedPersonalMsgCount,
|
unapprovedPersonalMsgCount,
|
||||||
@ -313,7 +313,7 @@ function mapStateToProps (state) {
|
|||||||
network: state.metamask.network,
|
network: state.metamask.network,
|
||||||
provider: state.metamask.provider,
|
provider: state.metamask.provider,
|
||||||
forgottenPassword: state.appState.forgottenPassword,
|
forgottenPassword: state.appState.forgottenPassword,
|
||||||
lastUnreadNotice,
|
nextUnreadNotice,
|
||||||
lostAccounts,
|
lostAccounts,
|
||||||
frequentRpcList: state.metamask.frequentRpcList || [],
|
frequentRpcList: state.metamask.frequentRpcList || [],
|
||||||
currentCurrency: state.metamask.currentCurrency,
|
currentCurrency: state.metamask.currentCurrency,
|
||||||
|
@ -154,11 +154,11 @@ class Notice extends Component {
|
|||||||
|
|
||||||
const mapStateToProps = state => {
|
const mapStateToProps = state => {
|
||||||
const { metamask } = state
|
const { metamask } = state
|
||||||
const { noActiveNotices, lastUnreadNotice, lostAccounts } = metamask
|
const { noActiveNotices, nextUnreadNotice, lostAccounts } = metamask
|
||||||
|
|
||||||
return {
|
return {
|
||||||
noActiveNotices,
|
noActiveNotices,
|
||||||
lastUnreadNotice,
|
nextUnreadNotice,
|
||||||
lostAccounts,
|
lostAccounts,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -171,21 +171,21 @@ Notice.propTypes = {
|
|||||||
|
|
||||||
const mapDispatchToProps = dispatch => {
|
const mapDispatchToProps = dispatch => {
|
||||||
return {
|
return {
|
||||||
markNoticeRead: lastUnreadNotice => dispatch(actions.markNoticeRead(lastUnreadNotice)),
|
markNoticeRead: nextUnreadNotice => dispatch(actions.markNoticeRead(nextUnreadNotice)),
|
||||||
markAccountsFound: () => dispatch(actions.markAccountsFound()),
|
markAccountsFound: () => dispatch(actions.markAccountsFound()),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const mergeProps = (stateProps, dispatchProps, ownProps) => {
|
const mergeProps = (stateProps, dispatchProps, ownProps) => {
|
||||||
const { noActiveNotices, lastUnreadNotice, lostAccounts } = stateProps
|
const { noActiveNotices, nextUnreadNotice, lostAccounts } = stateProps
|
||||||
const { markNoticeRead, markAccountsFound } = dispatchProps
|
const { markNoticeRead, markAccountsFound } = dispatchProps
|
||||||
|
|
||||||
let notice
|
let notice
|
||||||
let onConfirm
|
let onConfirm
|
||||||
|
|
||||||
if (!noActiveNotices) {
|
if (!noActiveNotices) {
|
||||||
notice = lastUnreadNotice
|
notice = nextUnreadNotice
|
||||||
onConfirm = () => markNoticeRead(lastUnreadNotice)
|
onConfirm = () => markNoticeRead(nextUnreadNotice)
|
||||||
} else if (lostAccounts && lostAccounts.length > 0) {
|
} else if (lostAccounts && lostAccounts.length > 0) {
|
||||||
notice = generateLostAccountsNotice(lostAccounts)
|
notice = generateLostAccountsNotice(lostAccounts)
|
||||||
onConfirm = () => markAccountsFound()
|
onConfirm = () => markAccountsFound()
|
||||||
|
@ -21,7 +21,7 @@ function reduceMetamask (state, action) {
|
|||||||
identities: {},
|
identities: {},
|
||||||
unapprovedTxs: {},
|
unapprovedTxs: {},
|
||||||
noActiveNotices: true,
|
noActiveNotices: true,
|
||||||
lastUnreadNotice: undefined,
|
nextUnreadNotice: undefined,
|
||||||
frequentRpcList: [],
|
frequentRpcList: [],
|
||||||
addressBook: [],
|
addressBook: [],
|
||||||
selectedTokenAddress: null,
|
selectedTokenAddress: null,
|
||||||
@ -65,7 +65,7 @@ function reduceMetamask (state, action) {
|
|||||||
case actions.SHOW_NOTICE:
|
case actions.SHOW_NOTICE:
|
||||||
return extend(metamaskState, {
|
return extend(metamaskState, {
|
||||||
noActiveNotices: false,
|
noActiveNotices: false,
|
||||||
lastUnreadNotice: action.value,
|
nextUnreadNotice: action.value,
|
||||||
})
|
})
|
||||||
|
|
||||||
case actions.CLEAR_NOTICES:
|
case actions.CLEAR_NOTICES:
|
||||||
|
Loading…
x
Reference in New Issue
Block a user