mirror of
https://github.com/kremalicious/metamask-extension.git
synced 2024-12-23 09:52:26 +01:00
EIP-1102: add user privacy option
This commit is contained in:
parent
bfcb73ad53
commit
226601a956
@ -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"
|
||||
},
|
||||
|
@ -1,4 +1,10 @@
|
||||
{
|
||||
"privacyMode": {
|
||||
"message": "Datenschutzmodus"
|
||||
},
|
||||
"privacyModeDescription": {
|
||||
"message": "Websites müssen Zugriff anfordern, um Ihre Kontoinformationen anzuzeigen."
|
||||
},
|
||||
"exposeAccounts": {
|
||||
"message": "Expose Konten"
|
||||
},
|
||||
|
@ -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"
|
||||
|
@ -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"
|
||||
},
|
||||
|
@ -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"
|
||||
},
|
||||
|
@ -1,4 +1,10 @@
|
||||
{
|
||||
"privacyMode": {
|
||||
"message": "गोपनीयता मोड"
|
||||
},
|
||||
"privacyModeDescription": {
|
||||
"message": "वेबसाइटों को आपकी खाता जानकारी देखने के लिए पहुंच का अनुरोध करना होगा।"
|
||||
},
|
||||
"exposeAccounts": {
|
||||
"message": "खातों का पर्दाफाश करें"
|
||||
},
|
||||
|
@ -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"
|
||||
},
|
||||
|
@ -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"
|
||||
},
|
||||
|
@ -1,4 +1,10 @@
|
||||
{
|
||||
"privacyMode": {
|
||||
"message": "プライバシーモード"
|
||||
},
|
||||
"privacyModeDescription": {
|
||||
"message": "ウェブサイトはあなたのアカウント情報を閲覧するためのアクセスを要求する必要があります。"
|
||||
},
|
||||
"exposeAccounts": {
|
||||
"message": "アカウントを公開する"
|
||||
},
|
||||
|
@ -1,4 +1,10 @@
|
||||
{
|
||||
"privacyMode": {
|
||||
"message": "개인 정보 보호 모드"
|
||||
},
|
||||
"privacyModeDescription": {
|
||||
"message": "웹 사이트는 계정 정보를 볼 수있는 액세스 권한을 요청해야합니다."
|
||||
},
|
||||
"exposeAccounts": {
|
||||
"message": "계정 노출"
|
||||
},
|
||||
|
@ -1,4 +1,10 @@
|
||||
{
|
||||
"privacyMode": {
|
||||
"message": "Privacy-modus"
|
||||
},
|
||||
"privacyModeDescription": {
|
||||
"message": "Websites moeten toegang vragen om uw accountgegevens te bekijken."
|
||||
},
|
||||
"exposeAccounts": {
|
||||
"message": "Expose Accounts"
|
||||
},
|
||||
|
@ -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"
|
||||
},
|
||||
|
@ -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"
|
||||
},
|
||||
|
@ -1,4 +1,10 @@
|
||||
{
|
||||
"privacyMode": {
|
||||
"message": "Режим конфиденциальности"
|
||||
},
|
||||
"privacyModeDescription": {
|
||||
"message": "Веб-сайты должны запрашивать доступ для просмотра информации об учетной записи."
|
||||
},
|
||||
"exposeAccounts": {
|
||||
"message": "Открыть счета"
|
||||
},
|
||||
|
@ -1,4 +1,10 @@
|
||||
{
|
||||
"privacyMode": {
|
||||
"message": "โหมดความเป็นส่วนตัว"
|
||||
},
|
||||
"privacyModeDescription": {
|
||||
"message": "เว็บไซต์ต้องขอเข้าถึงเพื่อดูข้อมูลบัญชีของคุณ"
|
||||
},
|
||||
"exposeAccounts": {
|
||||
"message": "เปิดเผยบัญชี"
|
||||
},
|
||||
|
@ -1,4 +1,10 @@
|
||||
{
|
||||
"privacyMode": {
|
||||
"message": "தனியுரிமை முறை"
|
||||
},
|
||||
"privacyModeDescription": {
|
||||
"message": "உங்கள் கணக்குத் தகவலை பார்வையிட வலைத்தளங்கள் அணுகலைக் கோர வேண்டும்."
|
||||
},
|
||||
"exposeAccounts": {
|
||||
"message": "கணக்குகளை அம்பலப்படுத்துங்கள்"
|
||||
},
|
||||
|
@ -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"
|
||||
},
|
||||
|
@ -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"
|
||||
},
|
||||
|
@ -1,4 +1,10 @@
|
||||
{
|
||||
"privacyMode": {
|
||||
"message": "隐私模式"
|
||||
},
|
||||
"privacyModeDescription": {
|
||||
"message": "网站必须请求访问权限才能查看您的帐户信息。"
|
||||
},
|
||||
"exposeAccounts": {
|
||||
"message": "公开账户"
|
||||
},
|
||||
|
@ -1,4 +1,10 @@
|
||||
{
|
||||
"privacyMode": {
|
||||
"message": "隱私模式"
|
||||
},
|
||||
"privacyModeDescription": {
|
||||
"message": "網站必須請求訪問權限才能查看您的帳戶信息。"
|
||||
},
|
||||
"exposeAccounts": {
|
||||
"message": "公開賬戶"
|
||||
},
|
||||
|
@ -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' })
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -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]
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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' }, '*')
|
||||
})
|
||||
}
|
||||
|
||||
|
@ -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),
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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'),
|
||||
|
@ -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()
|
||||
|
@ -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
|
||||
}
|
||||
|
||||
})
|
||||
})
|
@ -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()
|
||||
}
|
||||
}
|
||||
|
@ -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>
|
||||
)
|
||||
}
|
||||
}
|
@ -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)
|
@ -1 +0,0 @@
|
||||
export { default } from './force-injection.container'
|
@ -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, {
|
||||
|
@ -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>
|
||||
)
|
||||
}
|
||||
|
@ -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' })),
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user