aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorbitpshr <mail@bitpshr.net>2018-10-11 02:52:26 +0800
committerDan Finlay <542863+danfinlay@users.noreply.github.com>2018-11-06 07:07:09 +0800
commit226601a956594d00817cdb1fa5214242aae7936c (patch)
treeca3b8a64b685599ef8ef26d4bf3396170949d122
parentbfcb73ad533b7c2acea012a586c2a391811faf03 (diff)
downloadtangerine-wallet-browser-226601a956594d00817cdb1fa5214242aae7936c.tar
tangerine-wallet-browser-226601a956594d00817cdb1fa5214242aae7936c.tar.gz
tangerine-wallet-browser-226601a956594d00817cdb1fa5214242aae7936c.tar.bz2
tangerine-wallet-browser-226601a956594d00817cdb1fa5214242aae7936c.tar.lz
tangerine-wallet-browser-226601a956594d00817cdb1fa5214242aae7936c.tar.xz
tangerine-wallet-browser-226601a956594d00817cdb1fa5214242aae7936c.tar.zst
tangerine-wallet-browser-226601a956594d00817cdb1fa5214242aae7936c.zip
EIP-1102: add user privacy option
-rw-r--r--app/_locales/cs/messages.json6
-rw-r--r--app/_locales/de/messages.json6
-rw-r--r--app/_locales/en/messages.json12
-rw-r--r--app/_locales/es/messages.json6
-rw-r--r--app/_locales/fr/messages.json12
-rw-r--r--app/_locales/hn/messages.json6
-rw-r--r--app/_locales/ht/messages.json39
-rw-r--r--app/_locales/it/messages.json6
-rw-r--r--app/_locales/ja/messages.json6
-rw-r--r--app/_locales/ko/messages.json6
-rw-r--r--app/_locales/nl/messages.json6
-rw-r--r--app/_locales/ph/messages.json6
-rw-r--r--app/_locales/pt/messages.json6
-rw-r--r--app/_locales/ru/messages.json6
-rw-r--r--app/_locales/th/messages.json6
-rw-r--r--app/_locales/tml/messages.json6
-rw-r--r--app/_locales/tr/messages.json6
-rw-r--r--app/_locales/vi/messages.json6
-rw-r--r--app/_locales/zh_CN/messages.json6
-rw-r--r--app/_locales/zh_TW/messages.json6
-rw-r--r--app/scripts/contentscript.js27
-rw-r--r--app/scripts/controllers/provider-approval.js41
-rw-r--r--app/scripts/inpage.js4
-rw-r--r--app/scripts/metamask-controller.js4
-rw-r--r--old-ui/app/config.js16
-rw-r--r--test/e2e/beta/metamask-beta-ui.spec.js16
-rw-r--r--test/e2e/metamask.spec.js33
-rw-r--r--ui/app/actions.js7
-rw-r--r--ui/app/components/modals/force-injection/force-injection.component.js39
-rw-r--r--ui/app/components/modals/force-injection/force-injection.container.js16
-rw-r--r--ui/app/components/modals/force-injection/index.js1
-rw-r--r--ui/app/components/modals/modal.js14
-rw-r--r--ui/app/components/pages/settings/settings-tab/settings-tab.component.js65
-rw-r--r--ui/app/components/pages/settings/settings-tab/settings-tab.container.js8
34 files changed, 256 insertions, 200 deletions
diff --git a/app/_locales/cs/messages.json b/app/_locales/cs/messages.json
index caae14b5d..fde553c9e 100644
--- a/app/_locales/cs/messages.json
+++ b/app/_locales/cs/messages.json
@@ -1,4 +1,10 @@
{
+ "privacyMode": {
+ "message": "Režim súkromia"
+ },
+ "privacyModeDescription": {
+ "message": "Webové stránky musia požiadať o prístup k zobrazeniu informácií o vašom účte."
+ },
"exposeAccounts": {
"message": "Vystavte účty"
},
diff --git a/app/_locales/de/messages.json b/app/_locales/de/messages.json
index 00ef2cc23..9404a9824 100644
--- a/app/_locales/de/messages.json
+++ b/app/_locales/de/messages.json
@@ -1,4 +1,10 @@
{
+ "privacyMode": {
+ "message": "Datenschutzmodus"
+ },
+ "privacyModeDescription": {
+ "message": "Websites müssen Zugriff anfordern, um Ihre Kontoinformationen anzuzeigen."
+ },
"exposeAccounts": {
"message": "Expose Konten"
},
diff --git a/app/_locales/en/messages.json b/app/_locales/en/messages.json
index de5d71758..f34a22bd5 100644
--- a/app/_locales/en/messages.json
+++ b/app/_locales/en/messages.json
@@ -1,4 +1,10 @@
{
+ "privacyMode": {
+ "message": "Privacy Mode"
+ },
+ "privacyModeDescription": {
+ "message": "Websites must request access to view your account information."
+ },
"exposeAccounts": {
"message": "Expose Accounts"
},
@@ -15,13 +21,13 @@
"message": "Approved website data cleared successfully."
},
"approvalData": {
- "message": "Approval Data"
+ "message": "Privacy Data"
},
"approvalDataDescription": {
- "message": "Clear approved website data so all sites must request approval again."
+ "message": "Clear privacy data so all websites must request access to view account information again."
},
"clearApprovalData": {
- "message": "Clear Approval Data"
+ "message": "Clear Privacy Data"
},
"reject": {
"message": "Reject"
diff --git a/app/_locales/es/messages.json b/app/_locales/es/messages.json
index 01cd2bf94..55276e1ec 100644
--- a/app/_locales/es/messages.json
+++ b/app/_locales/es/messages.json
@@ -1,4 +1,10 @@
{
+ "privacyMode": {
+ "message": "Modo privado"
+ },
+ "privacyModeDescription": {
+ "message": "Los sitios web deben solicitar acceso para ver la información de su cuenta."
+ },
"exposeAccounts": {
"message": "Exponer cuentas"
},
diff --git a/app/_locales/fr/messages.json b/app/_locales/fr/messages.json
index 474df09af..17306d0f2 100644
--- a/app/_locales/fr/messages.json
+++ b/app/_locales/fr/messages.json
@@ -1,4 +1,10 @@
{
+ "privacyMode": {
+ "message": "Les sites Web doivent demander un accès pour afficher les informations de votre compte."
+ },
+ "privacyModeDescription": {
+ "message": "Les sites Web doivent demander un accès pour afficher les informations de votre compte."
+ },
"exposeAccounts": {
"message": "Exposer les comptes"
},
@@ -23,12 +29,6 @@
"clearApprovalData": {
"message": "Effacer les données d'approbation"
},
- "approve": {
- "message": "Approuver"
- },
- "reject": {
- "message": "Rejeter"
- },
"providerAPIRequest": {
"message": "Demande d'API Web3"
},
diff --git a/app/_locales/hn/messages.json b/app/_locales/hn/messages.json
index ff60e4951..8e2281418 100644
--- a/app/_locales/hn/messages.json
+++ b/app/_locales/hn/messages.json
@@ -1,4 +1,10 @@
{
+ "privacyMode": {
+ "message": "गोपनीयता मोड"
+ },
+ "privacyModeDescription": {
+ "message": "वेबसाइटों को आपकी खाता जानकारी देखने के लिए पहुंच का अनुरोध करना होगा।"
+ },
"exposeAccounts": {
"message": "खातों का पर्दाफाश करें"
},
diff --git a/app/_locales/ht/messages.json b/app/_locales/ht/messages.json
index 81ce18018..ff44af903 100644
--- a/app/_locales/ht/messages.json
+++ b/app/_locales/ht/messages.json
@@ -1,4 +1,43 @@
{
+ "privacyMode": {
+ "message": "Mòd Privacy"
+ },
+ "privacyModeDescription": {
+ "message": "Sou sit entènèt yo dwe mande aksè pou wè enfòmasyon kont ou."
+ },
+ "exposeAccounts": {
+ "message": "Ekspoze Kont"
+ },
+ "exposeDescription": {
+ "message": "Ekspoze kont sou sitwèb aktyèl la. Itil pou dapps eritaj."
+ },
+ "confirmExpose": {
+ "message": "Èske ou sèten ou vle ekspoze kont ou sou sit entènèt aktyèl la?"
+ },
+ "confirmClear": {
+ "message": "Èske ou sèten ou vle klè sitwèb apwouve?"
+ },
+ "clearApprovalDataSuccess": {
+ "message": "Done sou sit wèb apwouve yo te klarifye avèk siksè."
+ },
+ "approvalData": {
+ "message": "Done sou vi prive"
+ },
+ "approvalDataDescription": {
+ "message": "Done sou vi prive klè pou tout sit entènèt yo dwe mande aksè pou wè enfòmasyon kont ankò."
+ },
+ "clearApprovalData": {
+ "message": "Klè Done sou vi prive"
+ },
+ "providerAPIRequest": {
+ "message": "Ethereum API Mande"
+ },
+ "reviewProviderRequest": {
+ "message": "Tanpri revize sa API demann Ethereum."
+ },
+ "providerRequestInfo": {
+ "message": "Domèn ki nan lis anba a ap mande pou jwenn aksè a blòkchou Ethereum ak pou wè kont ou ye kounye a. Toujou double tcheke ke ou sou sit ki kòrèk la anvan apwouve aksè."
+ },
"accept": {
"message": "Aksepte"
},
diff --git a/app/_locales/it/messages.json b/app/_locales/it/messages.json
index 2bd1c9c7a..83ecf0e85 100644
--- a/app/_locales/it/messages.json
+++ b/app/_locales/it/messages.json
@@ -1,4 +1,10 @@
{
+ "privacyMode": {
+ "message": "Modalità di privacy"
+ },
+ "privacyModeDescription": {
+ "message": "I siti Web devono richiedere l'accesso per visualizzare le informazioni del tuo account."
+ },
"exposeAccounts": {
"message": "Expose Accounts"
},
diff --git a/app/_locales/ja/messages.json b/app/_locales/ja/messages.json
index 4700ff722..8ae363030 100644
--- a/app/_locales/ja/messages.json
+++ b/app/_locales/ja/messages.json
@@ -1,4 +1,10 @@
{
+ "privacyMode": {
+ "message": "プライバシーモード"
+ },
+ "privacyModeDescription": {
+ "message": "ウェブサイトはあなたのアカウント情報を閲覧するためのアクセスを要求する必要があります。"
+ },
"exposeAccounts": {
"message": "アカウントを公開する"
},
diff --git a/app/_locales/ko/messages.json b/app/_locales/ko/messages.json
index 05ea020ae..b41a3326f 100644
--- a/app/_locales/ko/messages.json
+++ b/app/_locales/ko/messages.json
@@ -1,4 +1,10 @@
{
+ "privacyMode": {
+ "message": "개인 정보 보호 모드"
+ },
+ "privacyModeDescription": {
+ "message": "웹 사이트는 계정 정보를 볼 수있는 액세스 권한을 요청해야합니다."
+ },
"exposeAccounts": {
"message": "계정 노출"
},
diff --git a/app/_locales/nl/messages.json b/app/_locales/nl/messages.json
index 55b6a9e00..5d9f1f3ab 100644
--- a/app/_locales/nl/messages.json
+++ b/app/_locales/nl/messages.json
@@ -1,4 +1,10 @@
{
+ "privacyMode": {
+ "message": "Privacy-modus"
+ },
+ "privacyModeDescription": {
+ "message": "Websites moeten toegang vragen om uw accountgegevens te bekijken."
+ },
"exposeAccounts": {
"message": "Expose Accounts"
},
diff --git a/app/_locales/ph/messages.json b/app/_locales/ph/messages.json
index 1ae4f1e63..cef686868 100644
--- a/app/_locales/ph/messages.json
+++ b/app/_locales/ph/messages.json
@@ -1,4 +1,10 @@
{
+ "privacyMode": {
+ "message": "Mode ng Privacy"
+ },
+ "privacyModeDescription": {
+ "message": "Dapat humiling ng access ang mga website upang tingnan ang impormasyon ng iyong account."
+ },
"exposeAccounts": {
"message": "Ilantad ang Mga Account"
},
diff --git a/app/_locales/pt/messages.json b/app/_locales/pt/messages.json
index c36242c0b..8e07aaef5 100644
--- a/app/_locales/pt/messages.json
+++ b/app/_locales/pt/messages.json
@@ -1,4 +1,10 @@
{
+ "privacyMode": {
+ "message": "Modo de privacidade"
+ },
+ "privacyModeDescription": {
+ "message": "Os sites devem solicitar acesso para visualizar as informações da sua conta."
+ },
"exposeAccounts": {
"message": "Expor contas"
},
diff --git a/app/_locales/ru/messages.json b/app/_locales/ru/messages.json
index b657d569e..917b2b615 100644
--- a/app/_locales/ru/messages.json
+++ b/app/_locales/ru/messages.json
@@ -1,4 +1,10 @@
{
+ "privacyMode": {
+ "message": "Режим конфиденциальности"
+ },
+ "privacyModeDescription": {
+ "message": "Веб-сайты должны запрашивать доступ для просмотра информации об учетной записи."
+ },
"exposeAccounts": {
"message": "Открыть счета"
},
diff --git a/app/_locales/th/messages.json b/app/_locales/th/messages.json
index 5bcddaace..7fabe4eac 100644
--- a/app/_locales/th/messages.json
+++ b/app/_locales/th/messages.json
@@ -1,4 +1,10 @@
{
+ "privacyMode": {
+ "message": "โหมดความเป็นส่วนตัว"
+ },
+ "privacyModeDescription": {
+ "message": "เว็บไซต์ต้องขอเข้าถึงเพื่อดูข้อมูลบัญชีของคุณ"
+ },
"exposeAccounts": {
"message": "เปิดเผยบัญชี"
},
diff --git a/app/_locales/tml/messages.json b/app/_locales/tml/messages.json
index 3037554f2..0643ce205 100644
--- a/app/_locales/tml/messages.json
+++ b/app/_locales/tml/messages.json
@@ -1,4 +1,10 @@
{
+ "privacyMode": {
+ "message": "தனியுரிமை முறை"
+ },
+ "privacyModeDescription": {
+ "message": "உங்கள் கணக்குத் தகவலை பார்வையிட வலைத்தளங்கள் அணுகலைக் கோர வேண்டும்."
+ },
"exposeAccounts": {
"message": "கணக்குகளை அம்பலப்படுத்துங்கள்"
},
diff --git a/app/_locales/tr/messages.json b/app/_locales/tr/messages.json
index 60418b650..1bb149eaa 100644
--- a/app/_locales/tr/messages.json
+++ b/app/_locales/tr/messages.json
@@ -1,4 +1,10 @@
{
+ "privacyMode": {
+ "message": "Gizlilik modu"
+ },
+ "privacyModeDescription": {
+ "message": "Web siteleri, hesap bilgilerinizi görmek için erişim istemek zorundadır."
+ },
"exposeAccounts": {
"message": "Hesapları Açığa Çıkar"
},
diff --git a/app/_locales/vi/messages.json b/app/_locales/vi/messages.json
index 67c2da52e..f0837ba98 100644
--- a/app/_locales/vi/messages.json
+++ b/app/_locales/vi/messages.json
@@ -1,4 +1,10 @@
{
+ "privacyMode": {
+ "message": "Chế độ riêng tư"
+ },
+ "privacyModeDescription": {
+ "message": "Trang web phải yêu cầu quyền truy cập để xem thông tin tài khoản của bạn."
+ },
"exposeAccounts": {
"message": "Hiển thị tài khoản"
},
diff --git a/app/_locales/zh_CN/messages.json b/app/_locales/zh_CN/messages.json
index 5fdfe961e..911ddf476 100644
--- a/app/_locales/zh_CN/messages.json
+++ b/app/_locales/zh_CN/messages.json
@@ -1,4 +1,10 @@
{
+ "privacyMode": {
+ "message": "隐私模式"
+ },
+ "privacyModeDescription": {
+ "message": "网站必须请求访问权限才能查看您的帐户信息。"
+ },
"exposeAccounts": {
"message": "公开账户"
},
diff --git a/app/_locales/zh_TW/messages.json b/app/_locales/zh_TW/messages.json
index 6167c2c33..3b048fd91 100644
--- a/app/_locales/zh_TW/messages.json
+++ b/app/_locales/zh_TW/messages.json
@@ -1,4 +1,10 @@
{
+ "privacyMode": {
+ "message": "隱私模式"
+ },
+ "privacyModeDescription": {
+ "message": "網站必須請求訪問權限才能查看您的帳戶信息。"
+ },
"exposeAccounts": {
"message": "公開賬戶"
},
diff --git a/app/scripts/contentscript.js b/app/scripts/contentscript.js
index b1c1e9a0d..29fa3f5c7 100644
--- a/app/scripts/contentscript.js
+++ b/app/scripts/contentscript.js
@@ -24,7 +24,7 @@ if (shouldInjectWeb3()) {
injectScript(inpageBundle)
setupStreams()
listenForProviderRequest()
- checkForcedInjection()
+ checkPrivacyMode()
}
/**
@@ -125,9 +125,9 @@ function listenForProviderRequest () {
origin: source.location.hostname,
})
break
- case 'ETHEREUM_PROVIDER_STATUS':
+ case 'ETHEREUM_QUERY_STATUS':
extension.runtime.sendMessage({
- action: 'provider-status-request',
+ action: 'init-status-request',
origin: source.location.hostname,
})
break
@@ -144,14 +144,7 @@ function listenForProviderRequest () {
case 'reject-provider-request':
injectScript(`window.dispatchEvent(new CustomEvent('ethereumprovider', { detail: { error: 'User rejected provider access' }}))`)
break
- case 'force-injection':
- extension.storage.local.get(['forcedOrigins'], ({ forcedOrigins = [] }) => {
- extension.storage.local.set({ forcedOrigins: [ ...forcedOrigins, window.location.hostname ] }, () => {
- injectScript(`window.location.reload()`)
- })
- })
- break
- case 'provider-status':
+ case 'answer-status-request':
injectScript(`window.dispatchEvent(new CustomEvent('ethereumproviderstatus', { detail: { isEnabled: ${isEnabled}}}))`)
break
}
@@ -159,15 +152,11 @@ function listenForProviderRequest () {
}
/**
- * Checks the current origin to see if it exists in the extension's locally-stored list
- * off user-whitelisted dapp origins. If it is, this origin will be marked as approved,
- * meaning the publicConfig stream will be enabled. This is only meant to ease the transition
- * to 1102 and will be removed in the future.
+ * Checks if MetaMask is currently operating in "privacy mode", meaning
+ * dapps must call ethereum.enable in order to access user accounts
*/
-function checkForcedInjection () {
- extension.storage.local.get(['forcedOrigins'], ({ forcedOrigins = [] }) => {
- originApproved = forcedOrigins.indexOf(window.location.hostname) > -1
- })
+function checkPrivacyMode () {
+ extension.runtime.sendMessage({ action: 'init-privacy-request' })
}
/**
diff --git a/app/scripts/controllers/provider-approval.js b/app/scripts/controllers/provider-approval.js
index 918fc8ad0..a44d2b3ab 100644
--- a/app/scripts/controllers/provider-approval.js
+++ b/app/scripts/controllers/provider-approval.js
@@ -1,5 +1,4 @@
const ObservableStore = require('obs-store')
-const extension = require('extensionizer')
/**
* A controller that services user-approved requests for a full Ethereum provider API
@@ -10,22 +9,25 @@ class ProviderApprovalController {
*
* @param {Object} [config] - Options to configure controller
*/
- constructor ({ closePopup, openPopup, platform, publicConfigStore } = {}) {
+ constructor ({ closePopup, openPopup, platform, preferencesController, publicConfigStore } = {}) {
this.store = new ObservableStore()
this.closePopup = closePopup
this.openPopup = openPopup
this.platform = platform
this.publicConfigStore = publicConfigStore
this.approvedOrigins = {}
+ this.preferencesController = preferencesController
platform && platform.addMessageListener && platform.addMessageListener(({ action, origin }) => {
if (!action) { return }
switch (action) {
case 'init-provider-request':
this.handleProviderRequest(origin)
break
- case 'provider-status-request':
+ case 'init-status-request':
this.handleProviderStatusRequest(origin)
break
+ case 'init-privacy-request':
+ this.handlePrivacyStatusRequest()
}
})
}
@@ -35,9 +37,9 @@ class ProviderApprovalController {
*
* @param {string} origin - Origin of the window requesting full provider access
*/
- async handleProviderRequest (origin) {
+ handleProviderRequest (origin) {
this.store.updateState({ providerRequests: [{ origin }] })
- if (await this.isApproved(origin)) {
+ if (this.isApproved(origin)) {
this.approveProviderRequest(origin)
return
}
@@ -45,13 +47,21 @@ class ProviderApprovalController {
}
/**
- * Called by a tab to detemrine if a full Ethereum provider API is exposed
+ * Called by a tab to determine if a full Ethereum provider API is exposed
*
* @param {string} origin - Origin of the window requesting provider status
*/
async handleProviderStatusRequest (origin) {
- const isEnabled = await this.isApproved(origin)
- this.platform && this.platform.sendMessage({ action: 'provider-status', isEnabled }, { active: true })
+ const isEnabled = this.isApproved(origin)
+ this.platform && this.platform.sendMessage({ action: 'answer-status-request', isEnabled }, { active: true })
+ }
+
+ handlePrivacyStatusRequest () {
+ const privacyMode = this.preferencesController.getFeatureFlags().privacyMode
+ if (!privacyMode) {
+ this.platform && this.platform.sendMessage({ action: 'approve-provider-request' }, { active: true })
+ this.publicConfigStore.emit('update', this.publicConfigStore.getState())
+ }
}
/**
@@ -87,7 +97,6 @@ class ProviderApprovalController {
*/
clearApprovedOrigins () {
this.approvedOrigins = {}
- extension.storage.local.set({ forcedOrigins: [] })
}
/**
@@ -97,18 +106,8 @@ class ProviderApprovalController {
* @returns {boolean} - True if the origin has been approved
*/
isApproved (origin) {
- return new Promise(resolve => {
- extension.storage.local.get(['forcedOrigins'], ({ forcedOrigins = [] }) => {
- resolve(this.approvedOrigins[origin] || forcedOrigins.indexOf(origin) > -1)
- })
- })
- }
-
- /**
- * Called when a user forces the exposure of a full Ethereum provider API
- */
- forceInjection () {
- this.platform.sendMessage({ action: 'force-injection' }, { active: true })
+ const privacyMode = this.preferencesController.getFeatureFlags().privacyMode
+ return !privacyMode || this.approvedOrigins[origin]
}
}
diff --git a/app/scripts/inpage.js b/app/scripts/inpage.js
index c5f4ee4c9..c5cbcc120 100644
--- a/app/scripts/inpage.js
+++ b/app/scripts/inpage.js
@@ -56,10 +56,10 @@ inpageProvider.isEnabled = function () {
if (typeof detail.error !== 'undefined') {
reject(detail.error)
} else {
- resolve(detail.isEnabled)
+ resolve(!!detail.isEnabled)
}
})
- window.postMessage({ type: 'ETHEREUM_PROVIDER_STATUS' }, '*')
+ window.postMessage({ type: 'ETHEREUM_QUERY_STATUS' }, '*')
})
}
diff --git a/app/scripts/metamask-controller.js b/app/scripts/metamask-controller.js
index d8f8a4602..2265838fb 100644
--- a/app/scripts/metamask-controller.js
+++ b/app/scripts/metamask-controller.js
@@ -224,6 +224,7 @@ module.exports = class MetamaskController extends EventEmitter {
closePopup: opts.closePopup,
openPopup: opts.openPopup,
platform: opts.platform,
+ preferencesController: this.preferencesController,
publicConfigStore: this.publicConfigStore,
})
@@ -275,7 +276,7 @@ module.exports = class MetamaskController extends EventEmitter {
getAccounts: async ({ origin }) => {
// Expose no accounts if this origin has not been approved, preventing
// account-requring RPC methods from completing successfully
- const isApproved = await this.providerApprovalController.isApproved(origin)
+ const isApproved = this.providerApprovalController.isApproved(origin)
if (origin !== 'MetaMask' && !isApproved) { return [] }
const isUnlocked = this.keyringController.memStore.getState().isUnlocked
const selectedAddress = this.preferencesController.getSelectedAddress()
@@ -455,7 +456,6 @@ module.exports = class MetamaskController extends EventEmitter {
approveProviderRequest: providerApprovalController.approveProviderRequest.bind(providerApprovalController),
clearApprovedOrigins: providerApprovalController.clearApprovedOrigins.bind(providerApprovalController),
rejectProviderRequest: providerApprovalController.rejectProviderRequest.bind(providerApprovalController),
- forceInjection: providerApprovalController.forceInjection.bind(providerApprovalController),
}
}
diff --git a/old-ui/app/config.js b/old-ui/app/config.js
index 15b0294e6..2a0643919 100644
--- a/old-ui/app/config.js
+++ b/old-ui/app/config.js
@@ -210,7 +210,7 @@ ConfigScreen.prototype.render = function () {
fontFamily: 'Montserrat Light',
fontSize: '13px',
},
- }, 'Clear approved website data so all sites must request approval again.'),
+ }, 'Clear privacy data so all websites must request access to view account information again.'),
h('br'),
h('button', {
style: {
@@ -220,7 +220,7 @@ ConfigScreen.prototype.render = function () {
event.preventDefault()
state.dispatch(actions.clearApprovedOrigins())
},
- }, 'Clear approval data'),
+ }, 'Clear privacy data'),
]),
h('hr.horizontal-line'),
@@ -235,7 +235,10 @@ ConfigScreen.prototype.render = function () {
fontFamily: 'Montserrat Light',
fontSize: '13px',
},
- }, 'Expose accounts to the current website. This is useful for legacy dapps.'),
+ }, metamaskState.featureFlags.privacyMode ?
+ 'Websites will be able to view your account information.' :
+ 'Websites must request access to view your account information.'
+ ),
h('br'),
h('button', {
style: {
@@ -243,9 +246,12 @@ ConfigScreen.prototype.render = function () {
},
onClick (event) {
event.preventDefault()
- state.dispatch(actions.forceInjection())
+ state.dispatch(actions.setFeatureFlag('privacyMode', !metamaskState.featureFlags.privacyMode))
},
- }, 'Expose accounts'),
+ }, metamaskState.featureFlags.privacyMode ?
+ 'Disable privacy mode' :
+ 'Enable privacy mode'
+ ),
]),
h('hr.horizontal-line'),
diff --git a/test/e2e/beta/metamask-beta-ui.spec.js b/test/e2e/beta/metamask-beta-ui.spec.js
index 5acc00e25..3285939e7 100644
--- a/test/e2e/beta/metamask-beta-ui.spec.js
+++ b/test/e2e/beta/metamask-beta-ui.spec.js
@@ -284,6 +284,22 @@ describe('MetaMask', function () {
})
})
+ describe('Enable privacy mode', () => {
+ it('enables privacy mode', async () => {
+ const networkDropdown = await findElement(driver, By.css('.network-name'))
+ await networkDropdown.click()
+ await delay(regularDelayMs)
+
+ const customRpcButton = await findElement(driver, By.xpath(`//span[contains(text(), 'Custom RPC')]`))
+ await customRpcButton.click()
+ await delay(regularDelayMs)
+
+ const privacyToggle = await findElement(driver, By.css('.settings-page__content-row:nth-of-type(9) .settings-page__content-item-col > div'))
+ await privacyToggle.click()
+ await delay(largeDelayMs * 2)
+ })
+ })
+
describe('Log out an log back in', () => {
it('logs out of the account', async () => {
await driver.findElement(By.css('.account-menu__icon')).click()
diff --git a/test/e2e/metamask.spec.js b/test/e2e/metamask.spec.js
index 4fee40af9..980113007 100644
--- a/test/e2e/metamask.spec.js
+++ b/test/e2e/metamask.spec.js
@@ -2,11 +2,6 @@ const path = require('path')
const assert = require('assert')
const { By, Key, until } = require('selenium-webdriver')
const { delay, createModifiedTestBuild, setupBrowserAndExtension, verboseReportOnFailure } = require('./func')
-const {
- closeAllWindowHandlesExcept,
- switchToWindowWithTitle,
- switchToWindowWithUrlThatMatches,
-} = require('./beta/helpers')
describe('Metamask popup page', function () {
const browser = process.env.SELENIUM_BROWSER
@@ -188,7 +183,6 @@ describe('Metamask popup page', function () {
})
it('restores from seed phrase', async function () {
- await delay(1000)
const restoreSeedLink = await driver.findElement(By.css('#app-content > div > div.app-primary.from-left > div > div.flex-row.flex-center.flex-grow > p'))
assert.equal(await restoreSeedLink.getText(), 'Restore from seed phrase')
await restoreSeedLink.click()
@@ -207,10 +201,10 @@ describe('Metamask popup page', function () {
})
it('balance renders', async function () {
- await delay(1000)
+ await delay(500)
const balance = await driver.findElement(By.css('#app-content > div > div.app-primary.from-right > div > div > div.flex-row > div.ether-balance.ether-balance-amount > div > div > div:nth-child(1) > div:nth-child(1)'))
assert.equal(await balance.getText(), '100.000')
- await delay(1000)
+ await delay(200)
})
it('sends transaction', async function () {
@@ -248,31 +242,12 @@ describe('Metamask popup page', function () {
})
describe('Token Factory', function () {
- let windowHandles
- let extension
- let dapp
it('navigates to token factory', async function () {
- await driver.get('http://token-factory-1102.now.sh')
- await delay(7000)
- windowHandles = await driver.getAllWindowHandles()
-
- dapp = await switchToWindowWithTitle(driver, 'Token Factory', windowHandles)
- await delay(400)
- extension = await switchToWindowWithUrlThatMatches(driver, /notification.html/, windowHandles)
- await delay(400)
-
- await closeAllWindowHandlesExcept(driver, [extension, dapp])
- await switchToWindowWithUrlThatMatches(driver, /notification.html/, [extension, dapp])
- const approveButton = await driver.wait(until.elementLocated(By.xpath(`//button[contains(text(), 'APPROVE')]`)), 10000)
- await approveButton.click()
+ await driver.get('http://tokenfactory.surge.sh/')
})
it('navigates to create token contract link', async function () {
- await delay(400)
- await switchToWindowWithTitle(driver, 'Token Factory', windowHandles)
- await delay(400)
-
const createToken = await driver.findElement(By.css('#bs-example-navbar-collapse-1 > ul > li:nth-child(3) > a'))
await createToken.click()
})
@@ -374,4 +349,4 @@ describe('Metamask popup page', function () {
return matchedErrorObjects
}
-})
+}) \ No newline at end of file
diff --git a/ui/app/actions.js b/ui/app/actions.js
index 2430b8217..501fef76d 100644
--- a/ui/app/actions.js
+++ b/ui/app/actions.js
@@ -328,7 +328,6 @@ var actions = {
approveProviderRequest,
rejectProviderRequest,
clearApprovedOrigins,
- forceInjection,
}
module.exports = actions
@@ -2506,9 +2505,3 @@ function clearApprovedOrigins () {
background.clearApprovedOrigins()
}
}
-
-function forceInjection () {
- return (dispatch) => {
- background.forceInjection()
- }
-}
diff --git a/ui/app/components/modals/force-injection/force-injection.component.js b/ui/app/components/modals/force-injection/force-injection.component.js
deleted file mode 100644
index 1ea08b5ee..000000000
--- a/ui/app/components/modals/force-injection/force-injection.component.js
+++ /dev/null
@@ -1,39 +0,0 @@
-import React, { PureComponent } from 'react'
-import PropTypes from 'prop-types'
-import Modal, { ModalContent } from '../../modal'
-
-export default class ForceInjection extends PureComponent {
- static propTypes = {
- hideModal: PropTypes.func.isRequired,
- forceInjection: PropTypes.func.isRequired,
- }
-
- static contextTypes = {
- t: PropTypes.func,
- }
-
- handleForce = () => {
- const { forceInjection, hideModal } = this.props
- forceInjection()
- hideModal()
- }
-
- render () {
- const { t } = this.context
-
- return (
- <Modal
- onSubmit={this.handleForce}
- onCancel={() => this.props.hideModal()}
- submitText={t('ok')}
- cancelText={t('nevermind')}
- submitType="secondary"
- >
- <ModalContent
- title={t('exposeAccounts')}
- description={t('confirmExpose')}
- />
- </Modal>
- )
- }
-}
diff --git a/ui/app/components/modals/force-injection/force-injection.container.js b/ui/app/components/modals/force-injection/force-injection.container.js
deleted file mode 100644
index fa0a325c3..000000000
--- a/ui/app/components/modals/force-injection/force-injection.container.js
+++ /dev/null
@@ -1,16 +0,0 @@
-import { connect } from 'react-redux'
-import { compose } from 'recompose'
-import withModalProps from '../../../higher-order-components/with-modal-props'
-import ForceInjectionComponent from './force-injection.component'
-import { forceInjection } from '../../../actions'
-
-const mapDispatchToProps = dispatch => {
- return {
- forceInjection: () => dispatch(forceInjection()),
- }
-}
-
-export default compose(
- withModalProps,
- connect(null, mapDispatchToProps)
-)(ForceInjectionComponent)
diff --git a/ui/app/components/modals/force-injection/index.js b/ui/app/components/modals/force-injection/index.js
deleted file mode 100644
index 4ea4dc695..000000000
--- a/ui/app/components/modals/force-injection/index.js
+++ /dev/null
@@ -1 +0,0 @@
-export { default } from './force-injection.container'
diff --git a/ui/app/components/modals/modal.js b/ui/app/components/modals/modal.js
index bdf8e4b9e..5aff4f5e1 100644
--- a/ui/app/components/modals/modal.js
+++ b/ui/app/components/modals/modal.js
@@ -29,7 +29,6 @@ import CancelTransaction from './cancel-transaction'
import WelcomeBeta from './welcome-beta'
import RejectTransactions from './reject-transactions'
import ClearApprovedOrigins from './clear-approved-origins'
-import ForceInjection from './force-injection'
const modalContainerBaseStyle = {
transform: 'translate3d(-50%, 0, 0px)',
@@ -227,19 +226,6 @@ const MODALS = {
},
},
- FORCE_INJECTION: {
- contents: h(ForceInjection),
- mobileModalStyle: {
- ...modalContainerMobileStyle,
- },
- laptopModalStyle: {
- ...modalContainerLaptopStyle,
- },
- contentStyle: {
- borderRadius: '8px',
- },
- },
-
OLD_UI_NOTIFICATION_MODAL: {
contents: [
h(NotifcationModal, {
diff --git a/ui/app/components/pages/settings/settings-tab/settings-tab.component.js b/ui/app/components/pages/settings/settings-tab/settings-tab.component.js
index 95a18d28b..a0a8ed47e 100644
--- a/ui/app/components/pages/settings/settings-tab/settings-tab.component.js
+++ b/ui/app/components/pages/settings/settings-tab/settings-tab.component.js
@@ -39,6 +39,8 @@ export default class SettingsTab extends PureComponent {
metamask: PropTypes.object,
setUseBlockie: PropTypes.func,
setHexDataFeatureFlag: PropTypes.func,
+ setPrivacyMode: PropTypes.func,
+ privacyMode: PropTypes.bool,
setCurrentCurrency: PropTypes.func,
setRpcTarget: PropTypes.func,
delRpcTarget: PropTypes.func,
@@ -46,7 +48,6 @@ export default class SettingsTab extends PureComponent {
revealSeedConfirmation: PropTypes.func,
setFeatureFlagToBeta: PropTypes.func,
showClearApprovalModal: PropTypes.func,
- showForceInjectionModal: PropTypes.func,
showResetAccountConfirmationModal: PropTypes.func,
warning: PropTypes.string,
history: PropTypes.object,
@@ -308,36 +309,6 @@ export default class SettingsTab extends PureComponent {
)
}
- renderForceInjection () {
- const { t } = this.context
- const { showForceInjectionModal } = this.props
- return (
- <div className="settings-page__content-row">
- <div className="settings-page__content-item">
- <span>{ t('exposeAccounts') }</span>
- <span className="settings-page__content-description">
- { t('exposeDescription') }
- </span>
- </div>
- <div className="settings-page__content-item">
- <div className="settings-page__content-item-col">
- <Button
- type="secondary"
- large
- className="settings-tab__button--orange"
- onClick={event => {
- event.preventDefault()
- showForceInjectionModal()
- }}
- >
- { t('exposeAccounts') }
- </Button>
- </div>
- </div>
- </div>
- )
- }
-
renderSeedWords () {
const { t } = this.context
const { history } = this.props
@@ -523,6 +494,32 @@ export default class SettingsTab extends PureComponent {
)
}
+ renderPrivacyOptIn () {
+ const { t } = this.context
+ const { privacyMode, setPrivacyMode } = this.props
+
+ return (
+ <div className="settings-page__content-row">
+ <div className="settings-page__content-item">
+ <span>{ t('privacyMode') }</span>
+ <div className="settings-page__content-description">
+ { t('privacyModeDescription') }
+ </div>
+ </div>
+ <div className="settings-page__content-item">
+ <div className="settings-page__content-item-col">
+ <ToggleButton
+ value={privacyMode}
+ onToggle={value => setPrivacyMode(!value)}
+ activeLabel=""
+ inactiveLabel=""
+ />
+ </div>
+ </div>
+ </div>
+ )
+ }
+
render () {
const { warning, isMascara } = this.props
@@ -535,12 +532,12 @@ export default class SettingsTab extends PureComponent {
{ this.renderNewRpcUrl() }
{ this.renderStateLogs() }
{ this.renderSeedWords() }
- { this.renderClearApproval() }
- { this.renderForceInjection() }
{ !isMascara && this.renderOldUI() }
{ this.renderResetAccount() }
- { this.renderBlockieOptIn() }
+ { this.renderClearApproval() }
+ { this.renderPrivacyOptIn() }
{ this.renderHexDataOptIn() }
+ { this.renderBlockieOptIn() }
</div>
)
}
diff --git a/ui/app/components/pages/settings/settings-tab/settings-tab.container.js b/ui/app/components/pages/settings/settings-tab/settings-tab.container.js
index 0af62e135..b6c33a5b2 100644
--- a/ui/app/components/pages/settings/settings-tab/settings-tab.container.js
+++ b/ui/app/components/pages/settings/settings-tab/settings-tab.container.js
@@ -22,7 +22,10 @@ const mapStateToProps = state => {
conversionDate,
nativeCurrency,
useBlockie,
- featureFlags: { sendHexData } = {},
+ featureFlags: {
+ sendHexData,
+ privacyMode,
+ } = {},
provider = {},
isMascara,
currentLocale,
@@ -38,6 +41,7 @@ const mapStateToProps = state => {
nativeCurrency,
useBlockie,
sendHexData,
+ privacyMode,
provider,
useNativeCurrencyAsPrimaryCurrency,
}
@@ -55,12 +59,12 @@ const mapDispatchToProps = dispatch => {
return dispatch(setFeatureFlag('betaUI', false, 'OLD_UI_NOTIFICATION_MODAL'))
},
setHexDataFeatureFlag: shouldShow => dispatch(setFeatureFlag('sendHexData', shouldShow)),
+ setPrivacyMode: enabled => dispatch(setFeatureFlag('privacyMode', enabled)),
showResetAccountConfirmationModal: () => dispatch(showModal({ name: 'CONFIRM_RESET_ACCOUNT' })),
setUseNativeCurrencyAsPrimaryCurrencyPreference: value => {
return dispatch(setUseNativeCurrencyAsPrimaryCurrencyPreference(value))
},
showClearApprovalModal: () => dispatch(showModal({ name: 'CLEAR_APPROVED_ORIGINS' })),
- showForceInjectionModal: () => dispatch(showModal({ name: 'FORCE_INJECTION' })),
}
}