Skip to content
This repository has been archived by the owner on Dec 11, 2019. It is now read-only.

enabling MetaMask via notification when visiting DApp website #11534

Merged
merged 4 commits into from
Oct 15, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
81 changes: 81 additions & 0 deletions app/browser/reducers/dappReducer.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/. */

'use strict'

const appConstants = require('../../../js/constants/appConstants')
const {makeImmutable} = require('../../common/state/immutableUtil')
const locale = require('../../locale')
const appActions = require('../../../js/actions/appActions')
const {ipcMain} = require('electron')
const messages = require('../../../js/constants/messages')
const settings = require('../../../js/constants/settings')
const getSetting = require('../../../js/settings').getSetting
const tabActions = require('../../common/actions/tabActions')
const tabState = require('../../common/state/tabState')
const config = require('../../../js/constants/config')

const dappReducer = (state, action, immutableAction) => {
action = immutableAction || makeImmutable(action)
switch (action.get('actionType')) {
case appConstants.APP_DAPP_AVAILABLE:
if (!getSetting(settings.METAMASK_PROMPT_DISMISSED) && !getSetting(settings.METAMASK_ENABLED)) {
showDappNotification()
}
break
}
return state
}

const notifications = {
text: {
greeting: locale.translation('updateHello'),
message: locale.translation('dappDetected'),
enable: locale.translation('dappEnableExtension'),
dismiss: locale.translation('dappDismiss')
},
onResponse: (message, buttonIndex) => {
// Index 0 is for dismiss
if (buttonIndex === 0) {
appActions.changeSetting(settings.METAMASK_PROMPT_DISMISSED, true)
}
// Index 1 is for enable
if (buttonIndex === 1) {
appActions.changeSetting(settings.METAMASK_ENABLED, true)
}
appActions.hideNotification(message)
}
}

process.on('extension-ready', (installInfo) => {
if (installInfo.id === config.metamaskExtensionId) {
tabActions.reload(tabState.TAB_ID_ACTIVE, true)
}
})

const showDappNotification = () => {
appActions.showNotification({
greeting: notifications.text.greeting,
message: notifications.text.message,
buttons: [
{text: notifications.text.dismiss},
{text: notifications.text.enable}
],
options: {
persist: false
}
})
}

if (ipcMain) {
ipcMain.on(messages.NOTIFICATION_RESPONSE, (e, message, buttonIndex) => {
switch (message) {
case notifications.text.message:
notifications.onResponse(message, buttonIndex)
break
}
})
}

module.exports = dappReducer
9 changes: 8 additions & 1 deletion app/extensions.js
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,8 @@ let generateBraveManifest = () => {
js: [
'content/scripts/adInsertion.js',
'content/scripts/pageInformation.js',
'content/scripts/flashListener.js'
'content/scripts/flashListener.js',
'content/scripts/dappListener.js'
]
},
{
Expand Down Expand Up @@ -556,6 +557,12 @@ module.exports.init = () => {
disableExtension(config.metamaskExtensionId)
}

if (getSetting(settings.METAMASK_ENABLED)) {
registerComponent(config.metamaskExtensionId, config.metamaskPublicKey)
} else {
disableExtension(config.metamaskExtensionId)
}

if (appStore.getState().getIn(['widevine', 'enabled'])) {
registerComponent(config.widevineComponentId, config.widevineComponentPublicKey)
}
Expand Down
22 changes: 22 additions & 0 deletions app/extensions/brave/content/scripts/dappListener.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/. */

const script =
`if (window.web3) {
if (!window.web3.currentProvider || !window.web3.currentProvider.isMetaMask) {
const meta = document.createElement('meta')
meta.name = 'web3-installed'
document.head.appendChild(meta)
}
}`

executeScript(script)
const isDapp = document.querySelector('meta[name="web3-installed"]')

if (isDapp) {
chrome.ipcRenderer.send('dispatch-action', JSON.stringify([{
actionType: 'app-dapp-available',
location: window.location.href
}]))
}
3 changes: 3 additions & 0 deletions app/extensions/brave/locales/en-US/app.properties
Original file line number Diff line number Diff line change
Expand Up @@ -239,6 +239,9 @@ walletConvertedBackup=Back up your new wallet
walletConvertedDismiss=Later
walletConvertedLearnMore=Learn More
walletConvertedToBat=Your BTC will be converted to BAT and will appear in your Brave wallet within approximately 30 minutes.
dappDetected=This page contains a Dapp, would you like to enable the MetaMask extension?
dappDismiss=No thanks
dappEnableExtension=Install MetaMask
windowCaptionButtonMinimize=Minimize
windowCaptionButtonMaximize=Maximize
windowCaptionButtonRestore=Restore Down
Expand Down
3 changes: 3 additions & 0 deletions app/locale.js
Original file line number Diff line number Diff line change
Expand Up @@ -233,6 +233,9 @@ var rendererIdentifiers = function () {
'walletConvertedDismiss',
'walletConvertedLearnMore',
'walletConvertedToBat',
'dappDetected',
'dappDismiss',
'dappEnableExtension',
// other
'passwordsManager',
'extensionsManager',
Expand Down
6 changes: 6 additions & 0 deletions app/renderer/lib/extensionsUtil.js
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,12 @@ const dummyData = [
name: 'honey',
description: 'honeyDesc',
icon: 'img/extensions/honey-128.png'
},
{
id: metamask,
name: 'MetaMask',
description: 'metamaskDesc',
icon: 'img/extensions/metamask-128.png'
}
// {
// id: metamask,
Expand Down
1 change: 1 addition & 0 deletions js/constants/appConfig.js
Original file line number Diff line number Diff line change
Expand Up @@ -211,6 +211,7 @@ module.exports = {
'extensions.honey.enabled': false,
'extensions.pinterest.enabled': false,
'extensions.metamask.enabled': false,
'extensions.metamask.promptDismissed': false,
'general.bookmarks-toolbar-mode': null,
'general.is-default-browser': null,
'notification-add-funds-timestamp': null,
Expand Down
1 change: 1 addition & 0 deletions js/constants/appConstants.js
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,7 @@ const appConstants = {
APP_ALLOW_FLASH_ONCE: _,
APP_ALLOW_FLASH_ALWAYS: _,
APP_FLASH_PERMISSION_REQUESTED: _,
APP_DAPP_AVAILABLE: _,
APP_SHUTTING_DOWN: _,
APP_CLIPBOARD_TEXT_UPDATED: _,
APP_TAB_TOGGLE_DEV_TOOLS: _,
Expand Down
1 change: 1 addition & 0 deletions js/constants/settings.js
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,7 @@ const settings = {
HONEY_ENABLED: 'extensions.honey.enabled',
PINTEREST_ENABLED: 'extensions.pinterest.enabled',
METAMASK_ENABLED: 'extensions.metamask.enabled',
METAMASK_PROMPT_DISMISSED: 'extensions.metamask.promptDismissed',

// DEPRECATED settings
// DO NOT REMOVE OR CHANGE THESE VALUES
Expand Down
1 change: 1 addition & 0 deletions js/stores/appStore.js
Original file line number Diff line number Diff line change
Expand Up @@ -392,6 +392,7 @@ const handleAppAction = (action) => {
reducers = [
require('../../app/browser/reducers/downloadsReducer'),
require('../../app/browser/reducers/flashReducer'),
require('../../app/browser/reducers/dappReducer'),
require('../../app/browser/reducers/autoplayReducer'),
// tabs, sites and windows reducers need to stay in that order
// until we have a better way to manage dependencies.
Expand Down
37 changes: 37 additions & 0 deletions test/bravery-components/notificationBarTest.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ const Brave = require('../lib/brave')
const {notificationBar, titleBar, urlInput, reloadButton} = require('../lib/selectors')
const {autoplayOption} = require('../../app/common/constants/settingsEnums')
const {AUTOPLAY_MEDIA} = require('../../js/constants/settings')
const settings = require('../../js/constants/settings')

describe('notificationBar permissions', function () {
function * setup (client) {
Expand Down Expand Up @@ -36,6 +37,42 @@ describe('notificationBar permissions', function () {
}).click('button=Deny')
})

describe('Dapps', function () {
it('shows notification bar for Dapps', function * () {
let notificationUrl = Brave.server.url('Dapps.html')
yield this.app.client
.tabByIndex(0)
.loadUrl(notificationUrl)
.windowByUrl(Brave.browserWindowUrl)
.waitForExist(notificationBar)
.waitUntil(function () {
return this.getText(notificationBar).then((val) => {
return val.includes('Dapp')
})
}).click('button=No thanks')
})

it('does not show when prompt is dismissed', function * () {
let notificationUrl = Brave.server.url('Dapps.html')
yield this.app.client
.changeSetting(settings.METAMASK_PROMPT_DISMISSED, true)
.tabByIndex(0)
.loadUrl(notificationUrl)
.windowByUrl(Brave.browserWindowUrl)
.waitForElementCount(notificationBar, 0)
})

it('does not show when MetaMask is enabled', function * () {
let notificationUrl = Brave.server.url('Dapps.html')
yield this.app.client
.changeSetting(settings.METAMASK_ENABLED, true)
.tabByIndex(0)
.loadUrl(notificationUrl)
.windowByUrl(Brave.browserWindowUrl)
.waitForElementCount(notificationBar, 0)
})
})

it('can deny permission request', function * () {
yield this.app.client
.tabByIndex(0)
Expand Down
13 changes: 13 additions & 0 deletions test/fixtures/Dapps.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
<html>
<head>
<meta charset="utf-8">
<title>Dapps</title>
</head>
<body>
This page exposes a web3 object.
<div id="result"></div>
<script type="text/javascript">
window.web3 = {}
</script>
</body>
</html>