mirror of
https://github.com/kremalicious/metamask-extension.git
synced 2024-12-22 09:23:21 +01:00
Connections settings tab (#7013)
* Nix notification for Share Address * Add Connections settings tab in place of privacy mode toggle * Split ProviderApprovalController into two stores * Remove privacyMode feature flag altogether * Add migration to remove privacyMode feature flag
This commit is contained in:
parent
4d9b095dd0
commit
247659ca65
@ -1,10 +1,4 @@
|
||||
{
|
||||
"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"
|
||||
},
|
||||
@ -20,12 +14,6 @@
|
||||
"clearApprovalDataSuccess": {
|
||||
"message": "Schválené údaje webových stránek byly úspěšně zrušeny."
|
||||
},
|
||||
"approvalData": {
|
||||
"message": "Údaje o schválení"
|
||||
},
|
||||
"approvalDataDescription": {
|
||||
"message": "Vymažte schválené údaje webových stránek, aby všechny weby znovu požádaly o schválení."
|
||||
},
|
||||
"clearApprovalData": {
|
||||
"message": "Jasné údaje o schválení"
|
||||
},
|
||||
|
@ -1,10 +1,4 @@
|
||||
{
|
||||
"privacyMode": {
|
||||
"message": "Datenschutzmodus"
|
||||
},
|
||||
"privacyModeDescription": {
|
||||
"message": "Websites müssen Zugriff anfordern, um Ihre Kontoinformationen anzuzeigen."
|
||||
},
|
||||
"exposeAccounts": {
|
||||
"message": "Expose Konten"
|
||||
},
|
||||
@ -20,12 +14,6 @@
|
||||
"clearApprovalDataSuccess": {
|
||||
"message": "Genehmigte Website-Daten wurden erfolgreich gelöscht."
|
||||
},
|
||||
"approvalData": {
|
||||
"message": "Genehmigungsdaten"
|
||||
},
|
||||
"approvalDataDescription": {
|
||||
"message": "Löschen Sie die genehmigten Website-Daten, damit alle Websites erneut eine Genehmigung anfordern müssen."
|
||||
},
|
||||
"clearApprovalData": {
|
||||
"message": "Genehmigungsdaten löschen"
|
||||
},
|
||||
|
@ -1,22 +1,4 @@
|
||||
{
|
||||
"shareAddress": {
|
||||
"message": "Share Address"
|
||||
},
|
||||
"shareAddressToConnect": {
|
||||
"message": "Share your address to connect to $1?"
|
||||
},
|
||||
"shareAddressInfo": {
|
||||
"message": "Sharing your address with $1 will allow you to interact with this dapp. This permission is to protect your privacy by default. You may need to reload the dapp for the change to take effect."
|
||||
},
|
||||
"privacyModeDefault": {
|
||||
"message": "Privacy Mode is now enabled by default"
|
||||
},
|
||||
"privacyMode": {
|
||||
"message": "Privacy Mode"
|
||||
},
|
||||
"privacyModeDescription": {
|
||||
"message": "Websites must request access to view your account information."
|
||||
},
|
||||
"exposeAccounts": {
|
||||
"message": "Expose Accounts"
|
||||
},
|
||||
@ -32,20 +14,35 @@
|
||||
"confirmClear": {
|
||||
"message": "Are you sure you want to clear approved websites?"
|
||||
},
|
||||
"connections": {
|
||||
"message": "Connections"
|
||||
},
|
||||
"connectionsSettingsDescription": {
|
||||
"message": "Sites allowed to read your accounts"
|
||||
},
|
||||
"addSite": {
|
||||
"message": "Add Site"
|
||||
},
|
||||
"addSiteDescription": {
|
||||
"message": "Manually add a site to allow it access to your accounts, useful for older dapps"
|
||||
},
|
||||
"connected": {
|
||||
"message": "Connected"
|
||||
},
|
||||
"connectedDescription": {
|
||||
"message": "The list of sites allowed access to your addresses"
|
||||
},
|
||||
"privacyModeDefault": {
|
||||
"message": "Privacy Mode is now enabled by default"
|
||||
},
|
||||
"contractInteraction": {
|
||||
"message": "Contract Interaction"
|
||||
},
|
||||
"clearApprovalDataSuccess": {
|
||||
"message": "Approved website data cleared successfully."
|
||||
},
|
||||
"approvalData": {
|
||||
"message": "Privacy Data"
|
||||
},
|
||||
"approvalDataDescription": {
|
||||
"message": "Clear privacy data so all websites must request access to view account information again."
|
||||
},
|
||||
"clearApprovalData": {
|
||||
"message": "Clear Privacy Data"
|
||||
"message": "Remove all sites"
|
||||
},
|
||||
"reject": {
|
||||
"message": "Reject"
|
||||
|
@ -1,10 +1,4 @@
|
||||
{
|
||||
"privacyMode": {
|
||||
"message": "Modo privado"
|
||||
},
|
||||
"privacyModeDescription": {
|
||||
"message": "Los sitios web deben solicitar acceso para ver la información de su cuenta."
|
||||
},
|
||||
"exposeAccounts": {
|
||||
"message": "Exponer cuentas"
|
||||
},
|
||||
@ -20,12 +14,6 @@
|
||||
"clearApprovalDataSuccess": {
|
||||
"message": "Los datos aprobados del sitio web se borraron con éxito."
|
||||
},
|
||||
"approvalData": {
|
||||
"message": "Datos de aprobación"
|
||||
},
|
||||
"approvalDataDescription": {
|
||||
"message": "Borrar la información privada de modo que todos los sitios deban volver a requerir acceso para acceder a los datos de la cuenta."
|
||||
},
|
||||
"clearApprovalData": {
|
||||
"message": "Borrar datos de aprobación"
|
||||
},
|
||||
|
@ -1,10 +1,4 @@
|
||||
{
|
||||
"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"
|
||||
},
|
||||
@ -20,12 +14,6 @@
|
||||
"clearApprovalDataSuccess": {
|
||||
"message": "Les données de site Web approuvées ont été supprimées."
|
||||
},
|
||||
"approvalData": {
|
||||
"message": "Données d'approbation"
|
||||
},
|
||||
"approvalDataDescription": {
|
||||
"message": "Effacer les données de site Web approuvées afin que tous les sites doivent à nouveau demander l'approbation."
|
||||
},
|
||||
"clearApprovalData": {
|
||||
"message": "Effacer les données d'approbation"
|
||||
},
|
||||
|
@ -1,10 +1,4 @@
|
||||
{
|
||||
"privacyMode": {
|
||||
"message": "गोपनीयता मोड"
|
||||
},
|
||||
"privacyModeDescription": {
|
||||
"message": "वेबसाइटों को आपकी खाता जानकारी देखने के लिए पहुंच का अनुरोध करना होगा।"
|
||||
},
|
||||
"exposeAccounts": {
|
||||
"message": "खातों का पर्दाफाश करें"
|
||||
},
|
||||
@ -20,12 +14,6 @@
|
||||
"clearApprovalDataSuccess": {
|
||||
"message": "स्वीकृत वेबसाइट डेटा सफलतापूर्वक मंजूरी दे दी।"
|
||||
},
|
||||
"approvalData": {
|
||||
"message": "स्वीकृति डेटा"
|
||||
},
|
||||
"approvalDataDescription": {
|
||||
"message": "अनुमोदित वेबसाइट डेटा साफ़ करें ताकि सभी साइटों को फिर से अनुमोदन का अनुरोध करना होगा।"
|
||||
},
|
||||
"clearApprovalData": {
|
||||
"message": "अनुमोदन डेटा साफ़ करें"
|
||||
},
|
||||
|
@ -1,10 +1,4 @@
|
||||
{
|
||||
"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"
|
||||
},
|
||||
@ -20,12 +14,6 @@
|
||||
"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"
|
||||
},
|
||||
|
@ -1,10 +1,4 @@
|
||||
{
|
||||
"privacyMode": {
|
||||
"message": "Modalità privacy"
|
||||
},
|
||||
"privacyModeDescription": {
|
||||
"message": "I siti Web devono richiedere l'accesso per visualizzare le informazioni del tuo account."
|
||||
},
|
||||
"exposeAccounts": {
|
||||
"message": "Esponi Accounts"
|
||||
},
|
||||
@ -26,12 +20,6 @@
|
||||
"clearApprovalDataSuccess": {
|
||||
"message": "Dati del sito Web approvati cancellati correttamente."
|
||||
},
|
||||
"approvalData": {
|
||||
"message": "Dati di approvazione"
|
||||
},
|
||||
"approvalDataDescription": {
|
||||
"message": "Cancella i dati del sito web approvati, quindi tutti i siti devono richiedere nuovamente l'approvazione."
|
||||
},
|
||||
"clearApprovalData": {
|
||||
"message": "Cancella i dati di approvazione"
|
||||
},
|
||||
|
@ -1,10 +1,4 @@
|
||||
{
|
||||
"privacyMode": {
|
||||
"message": "プライバシーモード"
|
||||
},
|
||||
"privacyModeDescription": {
|
||||
"message": "ウェブサイトはあなたのアカウント情報を閲覧するためのアクセスを要求する必要があります。"
|
||||
},
|
||||
"exposeAccounts": {
|
||||
"message": "アカウントを公開する"
|
||||
},
|
||||
@ -20,12 +14,6 @@
|
||||
"clearApprovalDataSuccess": {
|
||||
"message": "承認されたウェブサイトデータが正常に消去されました。"
|
||||
},
|
||||
"approvalData": {
|
||||
"message": "承認データ"
|
||||
},
|
||||
"approvalDataDescription": {
|
||||
"message": "承認されたウェブサイトのデータをクリアすると、すべてのサイトで承認を再度要求する必要があります"
|
||||
},
|
||||
"clearApprovalData": {
|
||||
"message": "承認データのクリア"
|
||||
},
|
||||
|
@ -1,10 +1,4 @@
|
||||
{
|
||||
"privacyMode": {
|
||||
"message": "개인 정보 보호 모드"
|
||||
},
|
||||
"privacyModeDescription": {
|
||||
"message": "웹 사이트는 계정 정보를 볼 수있는 액세스 권한을 요청해야합니다."
|
||||
},
|
||||
"exposeAccounts": {
|
||||
"message": "계정 노출"
|
||||
},
|
||||
@ -20,12 +14,6 @@
|
||||
"clearApprovalDataSuccess": {
|
||||
"message": "승인 된 웹 사이트 데이터가 성공적으로 삭제되었습니다."
|
||||
},
|
||||
"approvalData": {
|
||||
"message": "승인 데이터"
|
||||
},
|
||||
"approvalDataDescription": {
|
||||
"message": "승인 된 웹 사이트 데이터를 삭제하여 모든 사이트에서 승인을 다시 요청해야합니다."
|
||||
},
|
||||
"clearApprovalData": {
|
||||
"message": "승인 데이터 삭제"
|
||||
},
|
||||
|
@ -1,10 +1,4 @@
|
||||
{
|
||||
"privacyMode": {
|
||||
"message": "Privacy-modus"
|
||||
},
|
||||
"privacyModeDescription": {
|
||||
"message": "Websites moeten toegang vragen om uw accountgegevens te bekijken."
|
||||
},
|
||||
"exposeAccounts": {
|
||||
"message": "Expose Accounts"
|
||||
},
|
||||
@ -20,12 +14,6 @@
|
||||
"clearApprovalDataSuccess": {
|
||||
"message": "Goedgekeurde websitegegevens zijn met succes gewist."
|
||||
},
|
||||
"approvalData": {
|
||||
"message": "Goedkeuringsgegevens"
|
||||
},
|
||||
"approvalDataDescription": {
|
||||
"message": "Goedgekeurde websitegegevens wissen zodat alle sites opnieuw goedkeuring moeten aanvragen."
|
||||
},
|
||||
"clearApprovalData": {
|
||||
"message": "Gegevens over goedkeuring wissen"
|
||||
},
|
||||
|
@ -1,10 +1,4 @@
|
||||
{
|
||||
"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"
|
||||
},
|
||||
@ -20,12 +14,6 @@
|
||||
"clearApprovalDataSuccess": {
|
||||
"message": "Matagumpay na na-clear ang data ng aprubadong website."
|
||||
},
|
||||
"approvalData": {
|
||||
"message": "Data ng Pag-apruba"
|
||||
},
|
||||
"approvalDataDescription": {
|
||||
"message": "I-clear ang naaprubahang data ng website upang ang lahat ng site ay dapat humiling muli ng pag-apruba"
|
||||
},
|
||||
"clearApprovalData": {
|
||||
"message": "Tanggalin ang data ng pag-apruba"
|
||||
},
|
||||
|
@ -1,10 +1,4 @@
|
||||
{
|
||||
"privacyMode": {
|
||||
"message": "Modo de privacidade"
|
||||
},
|
||||
"privacyModeDescription": {
|
||||
"message": "Os sites devem solicitar acesso para visualizar as informações da sua conta."
|
||||
},
|
||||
"exposeAccounts": {
|
||||
"message": "Expor contas"
|
||||
},
|
||||
@ -20,12 +14,6 @@
|
||||
"clearApprovalDataSuccess": {
|
||||
"message": "Dados aprovados do website foram limpos com sucesso."
|
||||
},
|
||||
"approvalData": {
|
||||
"message": "Dados de aprovação"
|
||||
},
|
||||
"approvalDataDescription": {
|
||||
"message": "Limpe os dados aprovados do website para que todos os sites solicitem aprovação novamente."
|
||||
},
|
||||
"clearApprovalData": {
|
||||
"message": "Limpar dados de aprovação"
|
||||
},
|
||||
|
@ -1,10 +1,4 @@
|
||||
{
|
||||
"privacyMode": {
|
||||
"message": "Режим конфиденциальности"
|
||||
},
|
||||
"privacyModeDescription": {
|
||||
"message": "Веб-сайты должны запрашивать доступ для просмотра информации об учетной записи."
|
||||
},
|
||||
"exposeAccounts": {
|
||||
"message": "Открыть счета"
|
||||
},
|
||||
@ -20,12 +14,6 @@
|
||||
"clearApprovalDataSuccess": {
|
||||
"message": "Утвержденные данные веб-сайта успешно удалены."
|
||||
},
|
||||
"approvalData": {
|
||||
"message": "Данные об утверждении"
|
||||
},
|
||||
"approvalDataDescription": {
|
||||
"message": "Очистите утвержденные данные веб-сайта, чтобы все сайты снова запросили подтверждение."
|
||||
},
|
||||
"clearApprovalData": {
|
||||
"message": "Четкие данные об утверждении"
|
||||
},
|
||||
|
@ -1,10 +1,4 @@
|
||||
{
|
||||
"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"
|
||||
},
|
||||
@ -20,12 +14,6 @@
|
||||
"clearApprovalDataSuccess": {
|
||||
"message": "Schválené údaje webových stránek byly úspěšně zrušeny."
|
||||
},
|
||||
"approvalData": {
|
||||
"message": "Údaje o schválení"
|
||||
},
|
||||
"approvalDataDescription": {
|
||||
"message": "Vymažte schválené údaje webových stránek, aby všechny weby znovu požádaly o schválení."
|
||||
},
|
||||
"clearApprovalData": {
|
||||
"message": "Jasné údaje o schválení"
|
||||
},
|
||||
|
@ -1,10 +1,4 @@
|
||||
{
|
||||
"privacyMode": {
|
||||
"message": "Zasebnostni način"
|
||||
},
|
||||
"privacyModeDescription": {
|
||||
"message": "Spletne strani morajo zahtevati dovoljenje za ogled podatkov o vašem računu."
|
||||
},
|
||||
"privacyNotice": {
|
||||
"message": "Obvestilo o zasebnosti"
|
||||
},
|
||||
@ -26,12 +20,6 @@
|
||||
"clearApprovalDataSuccess": {
|
||||
"message": "Odobrene spletne strani uspešno počiščene."
|
||||
},
|
||||
"approvalData": {
|
||||
"message": "Podatki o odobritvi"
|
||||
},
|
||||
"approvalDataDescription": {
|
||||
"message": "Počistite seznam odobrenih spletnih strani, tako da bodo morale ponovno zahtevati odobritev."
|
||||
},
|
||||
"clearApprovalData": {
|
||||
"message": "Počisti podatke o odobritvi"
|
||||
},
|
||||
|
@ -1,10 +1,4 @@
|
||||
{
|
||||
"privacyMode": {
|
||||
"message": "โหมดความเป็นส่วนตัว"
|
||||
},
|
||||
"privacyModeDescription": {
|
||||
"message": "เว็บไซต์ต้องขอเข้าถึงเพื่อดูข้อมูลบัญชีของคุณ"
|
||||
},
|
||||
"exposeAccounts": {
|
||||
"message": "เปิดเผยบัญชี"
|
||||
},
|
||||
@ -20,12 +14,6 @@
|
||||
"clearApprovalDataSuccess": {
|
||||
"message": "อนุมัติข้อมูลเว็บไซต์ที่ได้รับอนุมัติแล้ว"
|
||||
},
|
||||
"approvalData": {
|
||||
"message": "ข้อมูลการอนุมัติ"
|
||||
},
|
||||
"approvalDataDescription": {
|
||||
"message": "ล้างข้อมูลเว็บไซต์ที่ได้รับการอนุมัติเพื่อให้ทุกไซต์ต้องขออนุมัติอีกครั้ง"
|
||||
},
|
||||
"clearApprovalData": {
|
||||
"message": "ล้างข้อมูลการอนุมัติ"
|
||||
},
|
||||
|
@ -1,10 +1,4 @@
|
||||
{
|
||||
"privacyMode": {
|
||||
"message": "தனியுரிமை முறை"
|
||||
},
|
||||
"privacyModeDescription": {
|
||||
"message": "உங்கள் கணக்குத் தகவலை பார்வையிட வலைத்தளங்கள் அணுகலைக் கோர வேண்டும்."
|
||||
},
|
||||
"exposeAccounts": {
|
||||
"message": "கணக்குகளை அம்பலப்படுத்துங்கள்"
|
||||
},
|
||||
@ -20,12 +14,6 @@
|
||||
"clearApprovalDataSuccess": {
|
||||
"message": "அங்கீகரிக்கப்பட்ட வலைத்தள தரவு வெற்றிகரமாக அழிக்கப்பட்டது."
|
||||
},
|
||||
"approvalData": {
|
||||
"message": "ஒப்புதல் தரவு"
|
||||
},
|
||||
"approvalDataDescription": {
|
||||
"message": "அங்கீகரிக்கப்பட்ட வலைத்தள தரவை அழிக்கவும், அனைத்து தளங்களும் ஒப்புதல் மீண்டும் கோர வேண்டும்."
|
||||
},
|
||||
"clearApprovalData": {
|
||||
"message": "ஒப்புதல் தரவை அழி"
|
||||
},
|
||||
|
@ -1,10 +1,4 @@
|
||||
{
|
||||
"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"
|
||||
},
|
||||
@ -20,12 +14,6 @@
|
||||
"clearApprovalDataSuccess": {
|
||||
"message": "Onaylanan web sitesi verileri başarıyla temizlendi."
|
||||
},
|
||||
"approvalData": {
|
||||
"message": "Onay Verileri"
|
||||
},
|
||||
"approvalDataDescription": {
|
||||
"message": "Onaylanan web sitesi verilerini temizle, tüm sitelerin tekrar onay isteğinde bulunması gerekir."
|
||||
},
|
||||
"clearApprovalData": {
|
||||
"message": "Onay verilerini temizle"
|
||||
},
|
||||
|
@ -1,10 +1,4 @@
|
||||
{
|
||||
"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"
|
||||
},
|
||||
@ -20,12 +14,6 @@
|
||||
"clearApprovalDataSuccess": {
|
||||
"message": "Đã xóa thành công dữ liệu trang web được phê duyệt."
|
||||
},
|
||||
"approvalData": {
|
||||
"message": "Dữ liệu phê duyệt"
|
||||
},
|
||||
"approvalDataDescription": {
|
||||
"message": "Xóa dữ liệu trang web được phê duyệt để tất cả các trang web phải yêu cầu phê duyệt lại."
|
||||
},
|
||||
"clearApprovalData": {
|
||||
"message": "Xóa dữ liệu phê duyệt"
|
||||
},
|
||||
|
@ -1,10 +1,4 @@
|
||||
{
|
||||
"privacyMode": {
|
||||
"message": "隐私模式"
|
||||
},
|
||||
"privacyModeDescription": {
|
||||
"message": "网站必须请求访问权限才能查看您的帐户信息。"
|
||||
},
|
||||
"exposeAccounts": {
|
||||
"message": "公开账户"
|
||||
},
|
||||
@ -20,12 +14,6 @@
|
||||
"clearApprovalDataSuccess": {
|
||||
"message": "已批准的网站数据已成功清除。"
|
||||
},
|
||||
"approvalData": {
|
||||
"message": "审批数据"
|
||||
},
|
||||
"approvalDataDescription": {
|
||||
"message": "清除已批准的网站数据,以便所有网站都必须再次申请"
|
||||
},
|
||||
"clearApprovalData": {
|
||||
"message": "清除批准数据"
|
||||
},
|
||||
|
@ -1,10 +1,4 @@
|
||||
{
|
||||
"privacyMode": {
|
||||
"message": "隱私模式"
|
||||
},
|
||||
"privacyModeDescription": {
|
||||
"message": "網站必須請求訪問權限才能查看您的帳戶資訊"
|
||||
},
|
||||
"exposeAccounts": {
|
||||
"message": "公開賬戶"
|
||||
},
|
||||
@ -23,12 +17,6 @@
|
||||
"clearApprovalDataSuccess": {
|
||||
"message": "已批准的網站紀錄已成功清除。"
|
||||
},
|
||||
"approvalData": {
|
||||
"message": "審核紀錄"
|
||||
},
|
||||
"approvalDataDescription": {
|
||||
"message": "清除之前已批准過的網站審核紀錄,所有網站都必須再次申請"
|
||||
},
|
||||
"clearApprovalData": {
|
||||
"message": "清除批准數據"
|
||||
},
|
||||
|
@ -409,7 +409,7 @@ function setupController (initState, initLangCode) {
|
||||
controller.messageManager.on('updateBadge', updateBadge)
|
||||
controller.personalMessageManager.on('updateBadge', updateBadge)
|
||||
controller.typedMessageManager.on('updateBadge', updateBadge)
|
||||
controller.providerApprovalController.store.on('update', updateBadge)
|
||||
controller.providerApprovalController.memStore.on('update', updateBadge)
|
||||
|
||||
/**
|
||||
* Updates the Web Extension's "badge" number, on the little fox in the toolbar.
|
||||
@ -421,7 +421,7 @@ function setupController (initState, initLangCode) {
|
||||
const unapprovedMsgCount = controller.messageManager.unapprovedMsgCount
|
||||
const unapprovedPersonalMsgs = controller.personalMessageManager.unapprovedPersonalMsgCount
|
||||
const unapprovedTypedMsgs = controller.typedMessageManager.unapprovedTypedMessagesCount
|
||||
const pendingProviderRequests = controller.providerApprovalController.store.getState().providerRequests.length
|
||||
const pendingProviderRequests = controller.providerApprovalController.memStore.getState().providerRequests.length
|
||||
const count = unapprovedTxCount + unapprovedMsgCount + unapprovedPersonalMsgs + unapprovedTypedMsgs + pendingProviderRequests
|
||||
if (count) {
|
||||
label = String(count)
|
||||
|
@ -41,7 +41,6 @@ class PreferencesController {
|
||||
// for convenient testing of pre-release features, and should never
|
||||
// perform sensitive operations.
|
||||
featureFlags: {
|
||||
privacyMode: true,
|
||||
},
|
||||
knownMethodData: {},
|
||||
participateInMetaMetrics: null,
|
||||
|
@ -6,27 +6,23 @@ const createAsyncMiddleware = require('json-rpc-engine/src/createAsyncMiddleware
|
||||
* A controller that services user-approved requests for a full Ethereum provider API
|
||||
*/
|
||||
class ProviderApprovalController extends SafeEventEmitter {
|
||||
/**
|
||||
* Determines if caching is enabled
|
||||
*/
|
||||
caching = true
|
||||
|
||||
/**
|
||||
* Creates a ProviderApprovalController
|
||||
*
|
||||
* @param {Object} [config] - Options to configure controller
|
||||
*/
|
||||
constructor ({ closePopup, keyringController, openPopup, preferencesController } = {}) {
|
||||
constructor ({ closePopup, initState, keyringController, openPopup, preferencesController } = {}) {
|
||||
super()
|
||||
this.closePopup = closePopup
|
||||
this.keyringController = keyringController
|
||||
this.openPopup = openPopup
|
||||
this.preferencesController = preferencesController
|
||||
this.store = new ObservableStore({
|
||||
approvedOrigins: {},
|
||||
dismissedOrigins: {},
|
||||
this.memStore = new ObservableStore({
|
||||
providerRequests: [],
|
||||
})
|
||||
|
||||
const defaultState = { approvedOrigins: {} }
|
||||
this.store = new ObservableStore(Object.assign(defaultState, initState))
|
||||
}
|
||||
|
||||
/**
|
||||
@ -65,11 +61,17 @@ class ProviderApprovalController extends SafeEventEmitter {
|
||||
* @param {string} siteImage - The icon of the window requesting full provider access
|
||||
*/
|
||||
_handleProviderRequest (origin, siteTitle, siteImage) {
|
||||
this.store.updateState({ providerRequests: [{ origin, siteTitle, siteImage }] })
|
||||
const { providerRequests } = this.memStore.getState()
|
||||
this.memStore.updateState({
|
||||
providerRequests: [
|
||||
...providerRequests,
|
||||
{ origin, siteTitle, siteImage },
|
||||
],
|
||||
})
|
||||
const isUnlocked = this.keyringController.memStore.getState().isUnlocked
|
||||
const { approvedOrigins, dismissedOrigins } = this.store.getState()
|
||||
const originAlreadyHandled = approvedOrigins[origin] || dismissedOrigins[origin]
|
||||
if (originAlreadyHandled && this.caching && isUnlocked) {
|
||||
const { approvedOrigins } = this.store.getState()
|
||||
const originAlreadyHandled = approvedOrigins[origin]
|
||||
if (originAlreadyHandled && isUnlocked) {
|
||||
return
|
||||
}
|
||||
this.openPopup && this.openPopup()
|
||||
@ -85,23 +87,20 @@ class ProviderApprovalController extends SafeEventEmitter {
|
||||
this.closePopup()
|
||||
}
|
||||
|
||||
const { approvedOrigins, dismissedOrigins, providerRequests } = this.store.getState()
|
||||
|
||||
let _dismissedOrigins = dismissedOrigins
|
||||
if (dismissedOrigins[origin]) {
|
||||
_dismissedOrigins = Object.assign({}, dismissedOrigins)
|
||||
delete _dismissedOrigins[origin]
|
||||
}
|
||||
|
||||
const { approvedOrigins } = this.store.getState()
|
||||
const { providerRequests } = this.memStore.getState()
|
||||
const providerRequest = providerRequests.find((request) => request.origin === origin)
|
||||
const remainingProviderRequests = providerRequests.filter(request => request.origin !== origin)
|
||||
this.store.updateState({
|
||||
approvedOrigins: {
|
||||
...approvedOrigins,
|
||||
[origin]: true,
|
||||
[origin]: {
|
||||
siteTitle: providerRequest ? providerRequest.siteTitle : null,
|
||||
siteImage: providerRequest ? providerRequest.siteImage : null,
|
||||
},
|
||||
},
|
||||
dismissedOrigins: _dismissedOrigins,
|
||||
providerRequests: remainingProviderRequests,
|
||||
})
|
||||
this.memStore.updateState({ providerRequests: remainingProviderRequests })
|
||||
this.emit(`resolvedRequest:${origin}`, { approved: true })
|
||||
}
|
||||
|
||||
@ -115,51 +114,21 @@ class ProviderApprovalController extends SafeEventEmitter {
|
||||
this.closePopup()
|
||||
}
|
||||
|
||||
const { approvedOrigins, providerRequests, dismissedOrigins } = this.store.getState()
|
||||
const { approvedOrigins } = this.store.getState()
|
||||
const { providerRequests } = this.memStore.getState()
|
||||
const remainingProviderRequests = providerRequests.filter(request => request.origin !== origin)
|
||||
|
||||
// We're cloning and deleting keys here because we don't want to keep unneeded keys
|
||||
const _approvedOrigins = Object.assign({}, approvedOrigins)
|
||||
delete _approvedOrigins[origin]
|
||||
|
||||
this.store.putState({
|
||||
approvedOrigins: _approvedOrigins,
|
||||
providerRequests: remainingProviderRequests,
|
||||
dismissedOrigins: {
|
||||
...dismissedOrigins,
|
||||
[origin]: true,
|
||||
},
|
||||
})
|
||||
this.store.putState({ approvedOrigins: _approvedOrigins })
|
||||
this.memStore.putState({ providerRequests: remainingProviderRequests })
|
||||
this.emit(`resolvedRequest:${origin}`, { approved: false })
|
||||
}
|
||||
|
||||
/**
|
||||
* Silently approves access to a full Ethereum provider API for the origin
|
||||
*
|
||||
* @param {string} origin - origin of the domain that had provider access approved
|
||||
*/
|
||||
forceApproveProviderRequestByOrigin (origin) {
|
||||
const { approvedOrigins, dismissedOrigins, providerRequests } = this.store.getState()
|
||||
const remainingProviderRequests = providerRequests.filter(request => request.origin !== origin)
|
||||
|
||||
let _dismissedOrigins = dismissedOrigins
|
||||
if (dismissedOrigins[origin]) {
|
||||
_dismissedOrigins = Object.assign({}, dismissedOrigins)
|
||||
delete _dismissedOrigins[origin]
|
||||
}
|
||||
|
||||
this.store.updateState({
|
||||
approvedOrigins: {
|
||||
...approvedOrigins,
|
||||
[origin]: true,
|
||||
},
|
||||
dismissedOrigins: _dismissedOrigins,
|
||||
providerRequests: remainingProviderRequests,
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* Clears any cached approvals for user-approved origins
|
||||
* Clears any approvals for user-approved origins
|
||||
*/
|
||||
clearApprovedOrigins () {
|
||||
this.store.updateState({
|
||||
@ -174,10 +143,17 @@ class ProviderApprovalController extends SafeEventEmitter {
|
||||
* @returns {boolean} - True if the origin has been approved
|
||||
*/
|
||||
shouldExposeAccounts (origin) {
|
||||
const privacyMode = this.preferencesController.getFeatureFlags().privacyMode
|
||||
return !privacyMode || Boolean(this.store.getState().approvedOrigins[origin])
|
||||
return Boolean(this.store.getState().approvedOrigins[origin])
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a merged state representation
|
||||
* @return {object}
|
||||
* @private
|
||||
*/
|
||||
_getMergedState () {
|
||||
return Object.assign({}, this.memStore.getState(), this.store.getState())
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = ProviderApprovalController
|
||||
|
@ -251,6 +251,7 @@ module.exports = class MetamaskController extends EventEmitter {
|
||||
|
||||
this.providerApprovalController = new ProviderApprovalController({
|
||||
closePopup: opts.closePopup,
|
||||
initState: initState.ProviderApprovalController,
|
||||
keyringController: this.keyringController,
|
||||
openPopup: opts.openPopup,
|
||||
preferencesController: this.preferencesController,
|
||||
@ -268,6 +269,7 @@ module.exports = class MetamaskController extends EventEmitter {
|
||||
InfuraController: this.infuraController.store,
|
||||
CachedBalancesController: this.cachedBalancesController.store,
|
||||
OnboardingController: this.onboardingController.store,
|
||||
ProviderApprovalController: this.providerApprovalController.store,
|
||||
})
|
||||
|
||||
this.memStore = new ComposableObservableStore(null, {
|
||||
@ -288,8 +290,10 @@ module.exports = class MetamaskController extends EventEmitter {
|
||||
CurrencyController: this.currencyRateController,
|
||||
ShapeshiftController: this.shapeshiftController,
|
||||
InfuraController: this.infuraController.store,
|
||||
ProviderApprovalController: this.providerApprovalController.store,
|
||||
OnboardingController: this.onboardingController.store,
|
||||
// ProviderApprovalController
|
||||
ProviderApprovalController: this.providerApprovalController.store,
|
||||
ProviderApprovalControllerMemStore: this.providerApprovalController.memStore,
|
||||
})
|
||||
this.memStore.subscribe(this.sendUpdate.bind(this))
|
||||
}
|
||||
@ -503,7 +507,6 @@ module.exports = class MetamaskController extends EventEmitter {
|
||||
// provider approval
|
||||
approveProviderRequestByOrigin: providerApprovalController.approveProviderRequestByOrigin.bind(providerApprovalController),
|
||||
rejectProviderRequestByOrigin: providerApprovalController.rejectProviderRequestByOrigin.bind(providerApprovalController),
|
||||
forceApproveProviderRequestByOrigin: providerApprovalController.forceApproveProviderRequestByOrigin.bind(providerApprovalController),
|
||||
clearApprovedOrigins: providerApprovalController.clearApprovedOrigins.bind(providerApprovalController),
|
||||
|
||||
// onboarding controller
|
||||
|
30
app/scripts/migrations/036.js
Normal file
30
app/scripts/migrations/036.js
Normal file
@ -0,0 +1,30 @@
|
||||
const version = 36
|
||||
const clone = require('clone')
|
||||
|
||||
/**
|
||||
* The purpose of this migration is to remove the {@code privacyMode} feature flag.
|
||||
*/
|
||||
module.exports = {
|
||||
version,
|
||||
migrate: async function (originalVersionedData) {
|
||||
const versionedData = clone(originalVersionedData)
|
||||
versionedData.meta.version = version
|
||||
const state = versionedData.data
|
||||
versionedData.data = transformState(state)
|
||||
return versionedData
|
||||
},
|
||||
}
|
||||
|
||||
function transformState (state) {
|
||||
const { PreferencesController } = state
|
||||
|
||||
if (PreferencesController) {
|
||||
const featureFlags = PreferencesController.featureFlags || {}
|
||||
|
||||
if (typeof featureFlags.privacyMode !== 'undefined') {
|
||||
delete featureFlags.privacyMode
|
||||
}
|
||||
}
|
||||
|
||||
return state
|
||||
}
|
@ -46,4 +46,5 @@ module.exports = [
|
||||
require('./033'),
|
||||
require('./034'),
|
||||
require('./035'),
|
||||
require('./036'),
|
||||
]
|
||||
|
260
test/unit/app/controllers/provider-approval-test.js
Normal file
260
test/unit/app/controllers/provider-approval-test.js
Normal file
@ -0,0 +1,260 @@
|
||||
const assert = require('assert')
|
||||
const sinon = require('sinon')
|
||||
const ProviderApprovalController = require('../../../../app/scripts/controllers/provider-approval')
|
||||
|
||||
const mockLockedKeyringController = {
|
||||
memStore: {
|
||||
getState: () => ({
|
||||
isUnlocked: false,
|
||||
}),
|
||||
},
|
||||
}
|
||||
|
||||
const mockUnlockedKeyringController = {
|
||||
memStore: {
|
||||
getState: () => ({
|
||||
isUnlocked: true,
|
||||
}),
|
||||
},
|
||||
}
|
||||
|
||||
describe('ProviderApprovalController', () => {
|
||||
describe('#_handleProviderRequest', () => {
|
||||
it('should add a pending provider request when unlocked', () => {
|
||||
const controller = new ProviderApprovalController({
|
||||
keyringController: mockUnlockedKeyringController,
|
||||
})
|
||||
|
||||
controller._handleProviderRequest('example.com', 'Example', 'https://example.com/logo.svg')
|
||||
assert.deepEqual(controller._getMergedState(), {
|
||||
approvedOrigins: {},
|
||||
providerRequests: [{
|
||||
origin: 'example.com',
|
||||
siteTitle: 'Example',
|
||||
siteImage: 'https://example.com/logo.svg',
|
||||
}],
|
||||
})
|
||||
})
|
||||
|
||||
it('should add a pending provider request when locked', () => {
|
||||
const controller = new ProviderApprovalController({
|
||||
keyringController: mockLockedKeyringController,
|
||||
})
|
||||
|
||||
controller._handleProviderRequest('example.com', 'Example', 'https://example.com/logo.svg')
|
||||
assert.deepEqual(controller._getMergedState(), {
|
||||
approvedOrigins: {},
|
||||
providerRequests: [{
|
||||
origin: 'example.com',
|
||||
siteTitle: 'Example',
|
||||
siteImage: 'https://example.com/logo.svg',
|
||||
}],
|
||||
})
|
||||
})
|
||||
|
||||
it('should add a 2nd pending provider request when unlocked', () => {
|
||||
const controller = new ProviderApprovalController({
|
||||
keyringController: mockUnlockedKeyringController,
|
||||
})
|
||||
|
||||
controller._handleProviderRequest('example1.com', 'Example 1', 'https://example1.com/logo.svg')
|
||||
controller._handleProviderRequest('example2.com', 'Example 2', 'https://example2.com/logo.svg')
|
||||
assert.deepEqual(controller._getMergedState(), {
|
||||
approvedOrigins: {},
|
||||
providerRequests: [{
|
||||
origin: 'example1.com',
|
||||
siteTitle: 'Example 1',
|
||||
siteImage: 'https://example1.com/logo.svg',
|
||||
}, {
|
||||
origin: 'example2.com',
|
||||
siteTitle: 'Example 2',
|
||||
siteImage: 'https://example2.com/logo.svg',
|
||||
}],
|
||||
})
|
||||
})
|
||||
|
||||
it('should add a 2nd pending provider request when locked', () => {
|
||||
const controller = new ProviderApprovalController({
|
||||
keyringController: mockLockedKeyringController,
|
||||
})
|
||||
|
||||
controller._handleProviderRequest('example1.com', 'Example 1', 'https://example1.com/logo.svg')
|
||||
controller._handleProviderRequest('example2.com', 'Example 2', 'https://example2.com/logo.svg')
|
||||
assert.deepEqual(controller._getMergedState(), {
|
||||
approvedOrigins: {},
|
||||
providerRequests: [{
|
||||
origin: 'example1.com',
|
||||
siteTitle: 'Example 1',
|
||||
siteImage: 'https://example1.com/logo.svg',
|
||||
}, {
|
||||
origin: 'example2.com',
|
||||
siteTitle: 'Example 2',
|
||||
siteImage: 'https://example2.com/logo.svg',
|
||||
}],
|
||||
})
|
||||
})
|
||||
|
||||
it('should call openPopup when unlocked and when given', () => {
|
||||
const openPopup = sinon.spy()
|
||||
const controller = new ProviderApprovalController({
|
||||
openPopup,
|
||||
keyringController: mockUnlockedKeyringController,
|
||||
})
|
||||
|
||||
controller._handleProviderRequest('example.com', 'Example', 'https://example.com/logo.svg')
|
||||
assert.ok(openPopup.calledOnce)
|
||||
})
|
||||
|
||||
it('should call openPopup when locked and when given', () => {
|
||||
const openPopup = sinon.spy()
|
||||
const controller = new ProviderApprovalController({
|
||||
openPopup,
|
||||
keyringController: mockLockedKeyringController,
|
||||
})
|
||||
|
||||
controller._handleProviderRequest('example.com', 'Example', 'https://example.com/logo.svg')
|
||||
assert.ok(openPopup.calledOnce)
|
||||
})
|
||||
|
||||
it('should NOT call openPopup when unlocked and when the domain has already been approved', () => {
|
||||
const openPopup = sinon.spy()
|
||||
const controller = new ProviderApprovalController({
|
||||
openPopup,
|
||||
keyringController: mockUnlockedKeyringController,
|
||||
})
|
||||
|
||||
controller.store.updateState({
|
||||
approvedOrigins: {
|
||||
'example.com': {
|
||||
siteTitle: 'Example',
|
||||
siteImage: 'https://example.com/logo.svg',
|
||||
},
|
||||
},
|
||||
})
|
||||
controller._handleProviderRequest('example.com', 'Example', 'https://example.com/logo.svg')
|
||||
assert.ok(openPopup.notCalled)
|
||||
})
|
||||
})
|
||||
|
||||
describe('#approveProviderRequestByOrigin', () => {
|
||||
it('should mark the origin as approved and remove the provider request', () => {
|
||||
const controller = new ProviderApprovalController({
|
||||
keyringController: mockUnlockedKeyringController,
|
||||
})
|
||||
|
||||
controller._handleProviderRequest('example.com', 'Example', 'https://example.com/logo.svg')
|
||||
controller.approveProviderRequestByOrigin('example.com')
|
||||
assert.deepEqual(controller._getMergedState(), {
|
||||
providerRequests: [],
|
||||
approvedOrigins: {
|
||||
'example.com': {
|
||||
siteTitle: 'Example',
|
||||
siteImage: 'https://example.com/logo.svg',
|
||||
},
|
||||
},
|
||||
})
|
||||
})
|
||||
|
||||
it('should mark the origin as approved and multiple requests for the same domain', () => {
|
||||
const controller = new ProviderApprovalController({
|
||||
keyringController: mockUnlockedKeyringController,
|
||||
})
|
||||
|
||||
controller._handleProviderRequest('example.com', 'Example', 'https://example.com/logo.svg')
|
||||
controller._handleProviderRequest('example.com', 'Example', 'https://example.com/logo.svg')
|
||||
controller.approveProviderRequestByOrigin('example.com')
|
||||
assert.deepEqual(controller._getMergedState(), {
|
||||
providerRequests: [],
|
||||
approvedOrigins: {
|
||||
'example.com': {
|
||||
siteTitle: 'Example',
|
||||
siteImage: 'https://example.com/logo.svg',
|
||||
},
|
||||
},
|
||||
})
|
||||
})
|
||||
|
||||
it('should mark the origin as approved without a provider request', () => {
|
||||
const controller = new ProviderApprovalController({
|
||||
keyringController: mockUnlockedKeyringController,
|
||||
})
|
||||
|
||||
controller.approveProviderRequestByOrigin('example.com')
|
||||
assert.deepEqual(controller._getMergedState(), {
|
||||
providerRequests: [],
|
||||
approvedOrigins: {
|
||||
'example.com': {
|
||||
siteTitle: null,
|
||||
siteImage: null,
|
||||
},
|
||||
},
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
describe('#rejectProviderRequestByOrigin', () => {
|
||||
it('should remove the origin from approved', () => {
|
||||
const controller = new ProviderApprovalController({
|
||||
keyringController: mockUnlockedKeyringController,
|
||||
})
|
||||
|
||||
controller._handleProviderRequest('example.com', 'Example', 'https://example.com/logo.svg')
|
||||
controller.approveProviderRequestByOrigin('example.com')
|
||||
controller.rejectProviderRequestByOrigin('example.com')
|
||||
assert.deepEqual(controller._getMergedState(), {
|
||||
providerRequests: [],
|
||||
approvedOrigins: {},
|
||||
})
|
||||
})
|
||||
|
||||
it('should reject the origin even without a pending request', () => {
|
||||
const controller = new ProviderApprovalController({
|
||||
keyringController: mockUnlockedKeyringController,
|
||||
})
|
||||
|
||||
controller.rejectProviderRequestByOrigin('example.com')
|
||||
assert.deepEqual(controller._getMergedState(), {
|
||||
providerRequests: [],
|
||||
approvedOrigins: {},
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
describe('#clearApprovedOrigins', () => {
|
||||
it('should clear the approved origins', () => {
|
||||
const controller = new ProviderApprovalController({
|
||||
keyringController: mockUnlockedKeyringController,
|
||||
})
|
||||
|
||||
controller._handleProviderRequest('example.com', 'Example', 'https://example.com/logo.svg')
|
||||
controller.approveProviderRequestByOrigin('example.com')
|
||||
controller.clearApprovedOrigins()
|
||||
assert.deepEqual(controller._getMergedState(), {
|
||||
providerRequests: [],
|
||||
approvedOrigins: {},
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
describe('#shouldExposeAccounts', () => {
|
||||
it('should return true for an approved origin', () => {
|
||||
const controller = new ProviderApprovalController({
|
||||
keyringController: mockUnlockedKeyringController,
|
||||
})
|
||||
|
||||
controller._handleProviderRequest('example.com', 'Example', 'https://example.com/logo.svg')
|
||||
controller.approveProviderRequestByOrigin('example.com')
|
||||
assert.ok(controller.shouldExposeAccounts('example.com'))
|
||||
})
|
||||
|
||||
it('should return false for an origin not yet approved', () => {
|
||||
const controller = new ProviderApprovalController({
|
||||
keyringController: mockUnlockedKeyringController,
|
||||
})
|
||||
|
||||
controller._handleProviderRequest('example.com', 'Example', 'https://example.com/logo.svg')
|
||||
controller.approveProviderRequestByOrigin('example.com')
|
||||
assert.ok(!controller.shouldExposeAccounts('bad.website'))
|
||||
})
|
||||
})
|
||||
})
|
119
test/unit/migrations/036-test.js
Normal file
119
test/unit/migrations/036-test.js
Normal file
@ -0,0 +1,119 @@
|
||||
const assert = require('assert')
|
||||
const migration36 = require('../../../app/scripts/migrations/036')
|
||||
|
||||
describe('migration #36', () => {
|
||||
it('should update the version metadata', (done) => {
|
||||
const oldStorage = {
|
||||
'meta': {
|
||||
'version': 35,
|
||||
},
|
||||
'data': {},
|
||||
}
|
||||
|
||||
migration36.migrate(oldStorage)
|
||||
.then((newStorage) => {
|
||||
assert.deepEqual(newStorage.meta, {
|
||||
'version': 36,
|
||||
})
|
||||
done()
|
||||
})
|
||||
.catch(done)
|
||||
})
|
||||
|
||||
it('should remove privacyMode if featureFlags.privacyMode was false', (done) => {
|
||||
const oldStorage = {
|
||||
'meta': {},
|
||||
'data': {
|
||||
'PreferencesController': {
|
||||
'featureFlags': {
|
||||
'privacyMode': false,
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
migration36.migrate(oldStorage)
|
||||
.then((newStorage) => {
|
||||
assert.deepEqual(newStorage.data.PreferencesController, {
|
||||
'featureFlags': {
|
||||
},
|
||||
})
|
||||
done()
|
||||
})
|
||||
.catch(done)
|
||||
})
|
||||
|
||||
it('should remove privacyMode if featureFlags.privacyMode was true', (done) => {
|
||||
const oldStorage = {
|
||||
'meta': {},
|
||||
'data': {
|
||||
'PreferencesController': {
|
||||
'featureFlags': {
|
||||
'privacyMode': true,
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
migration36.migrate(oldStorage)
|
||||
.then((newStorage) => {
|
||||
assert.deepEqual(newStorage.data.PreferencesController, {
|
||||
'featureFlags': {
|
||||
},
|
||||
})
|
||||
done()
|
||||
})
|
||||
.catch(done)
|
||||
})
|
||||
|
||||
it('should NOT change any state if privacyMode does not exist', (done) => {
|
||||
const oldStorage = {
|
||||
'meta': {},
|
||||
'data': {
|
||||
'PreferencesController': {
|
||||
'migratedPrivacyMode': true,
|
||||
'featureFlags': {
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
migration36.migrate(oldStorage)
|
||||
.then((newStorage) => {
|
||||
assert.deepEqual(newStorage.data, oldStorage.data)
|
||||
done()
|
||||
})
|
||||
.catch(done)
|
||||
})
|
||||
|
||||
it('should NOT change any state if PreferencesController is missing', (done) => {
|
||||
const oldStorage = {
|
||||
'meta': {},
|
||||
'data': {},
|
||||
}
|
||||
|
||||
migration36.migrate(oldStorage)
|
||||
.then((newStorage) => {
|
||||
assert.deepEqual(newStorage.data, oldStorage.data)
|
||||
done()
|
||||
})
|
||||
.catch(done)
|
||||
})
|
||||
|
||||
it('should NOT change any state if featureFlags is missing', (done) => {
|
||||
const oldStorage = {
|
||||
'meta': {},
|
||||
'data': {
|
||||
'PreferencesController': {
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
migration36.migrate(oldStorage)
|
||||
.then((newStorage) => {
|
||||
assert.deepEqual(newStorage.data, oldStorage.data)
|
||||
done()
|
||||
})
|
||||
.catch(done)
|
||||
})
|
||||
})
|
@ -3,6 +3,7 @@ const UNLOCK_ROUTE = '/unlock'
|
||||
const LOCK_ROUTE = '/lock'
|
||||
const SETTINGS_ROUTE = '/settings'
|
||||
const GENERAL_ROUTE = '/settings/general'
|
||||
const CONNECTIONS_ROUTE = '/settings/connections'
|
||||
const ADVANCED_ROUTE = '/settings/advanced'
|
||||
const SECURITY_ROUTE = '/settings/security'
|
||||
const ABOUT_US_ROUTE = '/settings/about-us'
|
||||
@ -82,6 +83,7 @@ module.exports = {
|
||||
ADVANCED_ROUTE,
|
||||
SECURITY_ROUTE,
|
||||
GENERAL_ROUTE,
|
||||
CONNECTIONS_ROUTE,
|
||||
ABOUT_US_ROUTE,
|
||||
CONTACT_LIST_ROUTE,
|
||||
CONTACT_EDIT_ROUTE,
|
||||
@ -93,4 +95,3 @@ module.exports = {
|
||||
NETWORKS_ROUTE,
|
||||
INITIALIZE_BACKUP_SEED_PHRASE_ROUTE,
|
||||
}
|
||||
|
||||
|
@ -21,18 +21,10 @@ export default class Home extends PureComponent {
|
||||
}
|
||||
|
||||
static defaultProps = {
|
||||
activeTab: {},
|
||||
unsetMigratedPrivacyMode: null,
|
||||
forceApproveProviderRequestByOrigin: null,
|
||||
}
|
||||
|
||||
static propTypes = {
|
||||
activeTab: PropTypes.shape({
|
||||
origin: PropTypes.string,
|
||||
protocol: PropTypes.string,
|
||||
title: PropTypes.string,
|
||||
url: PropTypes.string,
|
||||
}),
|
||||
history: PropTypes.object,
|
||||
forgottenPassword: PropTypes.bool,
|
||||
suggestedTokens: PropTypes.object,
|
||||
@ -40,10 +32,7 @@ export default class Home extends PureComponent {
|
||||
providerRequests: PropTypes.array,
|
||||
showPrivacyModeNotification: PropTypes.bool.isRequired,
|
||||
unsetMigratedPrivacyMode: PropTypes.func,
|
||||
viewingUnconnectedDapp: PropTypes.bool.isRequired,
|
||||
forceApproveProviderRequestByOrigin: PropTypes.func,
|
||||
shouldShowSeedPhraseReminder: PropTypes.bool,
|
||||
rejectProviderRequestByOrigin: PropTypes.func,
|
||||
isPopup: PropTypes.bool,
|
||||
}
|
||||
|
||||
@ -73,16 +62,12 @@ export default class Home extends PureComponent {
|
||||
render () {
|
||||
const { t } = this.context
|
||||
const {
|
||||
activeTab,
|
||||
forgottenPassword,
|
||||
providerRequests,
|
||||
history,
|
||||
showPrivacyModeNotification,
|
||||
unsetMigratedPrivacyMode,
|
||||
viewingUnconnectedDapp,
|
||||
forceApproveProviderRequestByOrigin,
|
||||
shouldShowSeedPhraseReminder,
|
||||
rejectProviderRequestByOrigin,
|
||||
isPopup,
|
||||
} = this.props
|
||||
|
||||
@ -120,20 +105,6 @@ export default class Home extends PureComponent {
|
||||
key="home-privacyModeDefault"
|
||||
/>,
|
||||
},
|
||||
{
|
||||
shouldBeRendered: viewingUnconnectedDapp,
|
||||
component: <HomeNotification
|
||||
descriptionText={t('shareAddressToConnect', [activeTab.origin])}
|
||||
acceptText={t('shareAddress')}
|
||||
onAccept={() => {
|
||||
forceApproveProviderRequestByOrigin(activeTab.origin)
|
||||
}}
|
||||
ignoreText={t('dismiss')}
|
||||
onIgnore={() => rejectProviderRequestByOrigin(activeTab.origin)}
|
||||
infoText={t('shareAddressInfo', [activeTab.origin])}
|
||||
key="home-shareAddressToConnect"
|
||||
/>,
|
||||
},
|
||||
{
|
||||
shouldBeRendered: shouldShowSeedPhraseReminder,
|
||||
component: <HomeNotification
|
||||
|
@ -5,39 +5,23 @@ import { withRouter } from 'react-router-dom'
|
||||
import { unconfirmedTransactionsCountSelector } from '../../selectors/confirm-transaction'
|
||||
import { getCurrentEthBalance } from '../../selectors/selectors'
|
||||
import {
|
||||
forceApproveProviderRequestByOrigin,
|
||||
unsetMigratedPrivacyMode,
|
||||
rejectProviderRequestByOrigin,
|
||||
} from '../../store/actions'
|
||||
import { getEnvironmentType } from '../../../../app/scripts/lib/util'
|
||||
import { ENVIRONMENT_TYPE_POPUP } from '../../../../app/scripts/lib/enums'
|
||||
|
||||
const activeTabDappProtocols = ['http:', 'https:', 'dweb:', 'ipfs:', 'ipns:', 'ssb:']
|
||||
|
||||
const mapStateToProps = state => {
|
||||
const { activeTab, metamask, appState } = state
|
||||
const { metamask, appState } = state
|
||||
const {
|
||||
approvedOrigins,
|
||||
dismissedOrigins,
|
||||
suggestedTokens,
|
||||
providerRequests,
|
||||
migratedPrivacyMode,
|
||||
featureFlags: {
|
||||
privacyMode,
|
||||
} = {},
|
||||
seedPhraseBackedUp,
|
||||
tokens,
|
||||
} = metamask
|
||||
const accountBalance = getCurrentEthBalance(state)
|
||||
const { forgottenPassword } = appState
|
||||
|
||||
const isUnconnected = Boolean(
|
||||
activeTab &&
|
||||
activeTabDappProtocols.includes(activeTab.protocol) &&
|
||||
privacyMode &&
|
||||
!approvedOrigins[activeTab.origin] &&
|
||||
!dismissedOrigins[activeTab.origin]
|
||||
)
|
||||
const isPopup = getEnvironmentType(window.location.href) === ENVIRONMENT_TYPE_POPUP
|
||||
|
||||
return {
|
||||
@ -46,8 +30,6 @@ const mapStateToProps = state => {
|
||||
unconfirmedTransactionsCount: unconfirmedTransactionsCountSelector(state),
|
||||
providerRequests,
|
||||
showPrivacyModeNotification: migratedPrivacyMode,
|
||||
activeTab,
|
||||
viewingUnconnectedDapp: isUnconnected && isPopup,
|
||||
shouldShowSeedPhraseReminder: !seedPhraseBackedUp && (parseInt(accountBalance, 16) > 0 || tokens.length > 0),
|
||||
isPopup,
|
||||
}
|
||||
@ -55,8 +37,6 @@ const mapStateToProps = state => {
|
||||
|
||||
const mapDispatchToProps = (dispatch) => ({
|
||||
unsetMigratedPrivacyMode: () => dispatch(unsetMigratedPrivacyMode()),
|
||||
forceApproveProviderRequestByOrigin: (origin) => dispatch(forceApproveProviderRequestByOrigin(origin)),
|
||||
rejectProviderRequestByOrigin: origin => dispatch(rejectProviderRequestByOrigin(origin)),
|
||||
})
|
||||
|
||||
export default compose(
|
||||
|
@ -0,0 +1,31 @@
|
||||
import React, { PureComponent } from 'react'
|
||||
import PropTypes from 'prop-types'
|
||||
|
||||
export default class ConnectedSiteRow extends PureComponent {
|
||||
static defaultProps = {
|
||||
siteTitle: null,
|
||||
siteImage: null,
|
||||
onDelete: () => {},
|
||||
}
|
||||
|
||||
static propTypes = {
|
||||
siteTitle: PropTypes.string,
|
||||
siteImage: PropTypes.string,
|
||||
origin: PropTypes.string.isRequired,
|
||||
onDelete: PropTypes.func,
|
||||
}
|
||||
|
||||
render () {
|
||||
const {
|
||||
origin,
|
||||
onDelete,
|
||||
} = this.props
|
||||
|
||||
return (
|
||||
<div className="connected-site-row">
|
||||
<div className="connected-site-row__origin">{origin}</div>
|
||||
<div className="connected-site-row__delete" onClick={onDelete}><i className="fa fa-trash" /></div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
}
|
@ -0,0 +1 @@
|
||||
export { default } from './connected-site-row.component'
|
@ -0,0 +1,14 @@
|
||||
.connected-site-row {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
|
||||
&__origin {
|
||||
font-family: monospace;
|
||||
}
|
||||
|
||||
&__delete {
|
||||
padding: 8px;
|
||||
}
|
||||
}
|
@ -0,0 +1,133 @@
|
||||
import React, { PureComponent } from 'react'
|
||||
import PropTypes from 'prop-types'
|
||||
import ConnectedSiteEntry from './connected-site-row'
|
||||
import TextField from '../../../components/ui/text-field'
|
||||
import Button from '../../../components/ui/button'
|
||||
|
||||
export default class ConnectionsTab extends PureComponent {
|
||||
static contextTypes = {
|
||||
t: PropTypes.func,
|
||||
metricsEvent: PropTypes.func,
|
||||
}
|
||||
|
||||
static defaultProps = {
|
||||
activeTab: {},
|
||||
}
|
||||
|
||||
static propTypes = {
|
||||
activeTab: PropTypes.object,
|
||||
approvedOrigins: PropTypes.object.isRequired,
|
||||
approveProviderRequestByOrigin: PropTypes.func.isRequired,
|
||||
rejectProviderRequestByOrigin: PropTypes.func.isRequired,
|
||||
showClearApprovalModal: PropTypes.func.isRequired,
|
||||
}
|
||||
|
||||
state = {
|
||||
input: this.props.activeTab.origin || '',
|
||||
}
|
||||
|
||||
handleAddOrigin = () => {
|
||||
const newOrigin = this.state.input
|
||||
this.setState({
|
||||
input: '',
|
||||
}, () => {
|
||||
if (newOrigin && newOrigin.trim()) {
|
||||
this.props.approveProviderRequestByOrigin(newOrigin)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
renderNewOriginInput () {
|
||||
const { t } = this.context
|
||||
|
||||
return (
|
||||
<div className="settings-page__content-row">
|
||||
<div className="settings-page__content-item">
|
||||
<span>{ t('addSite') }</span>
|
||||
<div className="settings-page__content-description">
|
||||
{ t('addSiteDescription') }
|
||||
</div>
|
||||
</div>
|
||||
<div className="settings-page__content-item">
|
||||
<div className="settings-page__content-item-col">
|
||||
<TextField
|
||||
type="text"
|
||||
value={this.state.input}
|
||||
onChange={e => this.setState({ input: e.target.value })}
|
||||
fullWidth
|
||||
margin="dense"
|
||||
min={0}
|
||||
/>
|
||||
<button
|
||||
className="button btn-primary settings-tab__rpc-save-button"
|
||||
onClick={this.handleAddOrigin}
|
||||
>
|
||||
{ t('connect') }
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
renderApprovedOriginsList () {
|
||||
const { t } = this.context
|
||||
const { approvedOrigins, rejectProviderRequestByOrigin, showClearApprovalModal } = this.props
|
||||
const approvedEntries = Object.entries(approvedOrigins)
|
||||
const approvalListEmpty = approvedEntries.length === 0
|
||||
|
||||
return (
|
||||
<div className="settings-page__content-row">
|
||||
<div className="settings-page__content-item">
|
||||
<span>{ t('connected') }</span>
|
||||
<span className="settings-page__content-description">
|
||||
{ t('connectedDescription') }
|
||||
</span>
|
||||
</div>
|
||||
<div className="settings-page__content-item">
|
||||
{
|
||||
approvalListEmpty
|
||||
? <div><i className="fa fa-ban" /></div>
|
||||
: null
|
||||
}
|
||||
{
|
||||
approvedEntries.map(([origin, { siteTitle, siteImage }]) => (
|
||||
<ConnectedSiteEntry
|
||||
key={origin}
|
||||
origin={origin}
|
||||
siteTitle={siteTitle}
|
||||
siteImage={siteImage}
|
||||
onDelete={() => {
|
||||
rejectProviderRequestByOrigin(origin)
|
||||
}}
|
||||
/>
|
||||
))
|
||||
}
|
||||
</div>
|
||||
<div className="settings-page__content-item-col">
|
||||
<Button
|
||||
disabled={approvalListEmpty}
|
||||
type="warning"
|
||||
large
|
||||
className="settings-tab__button--orange"
|
||||
onClick={event => {
|
||||
event.preventDefault()
|
||||
showClearApprovalModal()
|
||||
}}
|
||||
>
|
||||
{ t('clearApprovalData') }
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
render () {
|
||||
return (
|
||||
<div className="settings-page__body">
|
||||
{ this.renderNewOriginInput() }
|
||||
{ this.renderApprovedOriginsList() }
|
||||
</div>
|
||||
)
|
||||
}
|
||||
}
|
@ -0,0 +1,39 @@
|
||||
import ConnectionsTab from './connections-tab.component'
|
||||
import { compose } from 'recompose'
|
||||
import { connect } from 'react-redux'
|
||||
import { withRouter } from 'react-router-dom'
|
||||
import {
|
||||
approveProviderRequestByOrigin,
|
||||
rejectProviderRequestByOrigin,
|
||||
showModal,
|
||||
} from '../../../store/actions'
|
||||
|
||||
export const mapStateToProps = state => {
|
||||
const {
|
||||
activeTab,
|
||||
metamask,
|
||||
} = state
|
||||
const {
|
||||
approvedOrigins,
|
||||
} = metamask
|
||||
|
||||
return {
|
||||
activeTab,
|
||||
approvedOrigins,
|
||||
}
|
||||
}
|
||||
|
||||
export const mapDispatchToProps = dispatch => {
|
||||
return {
|
||||
approveProviderRequestByOrigin: (origin) => dispatch(approveProviderRequestByOrigin(origin)),
|
||||
rejectProviderRequestByOrigin: (origin) => dispatch(rejectProviderRequestByOrigin(origin)),
|
||||
showClearApprovalModal: () => dispatch(showModal({
|
||||
name: 'CLEAR_APPROVED_ORIGINS',
|
||||
})),
|
||||
}
|
||||
}
|
||||
|
||||
export default compose(
|
||||
withRouter,
|
||||
connect(mapStateToProps, mapDispatchToProps)
|
||||
)(ConnectionsTab)
|
1
ui/app/pages/settings/connections-tab/index.js
Normal file
1
ui/app/pages/settings/connections-tab/index.js
Normal file
@ -0,0 +1 @@
|
||||
export { default } from './connections-tab.container'
|
1
ui/app/pages/settings/connections-tab/index.scss
Normal file
1
ui/app/pages/settings/connections-tab/index.scss
Normal file
@ -0,0 +1 @@
|
||||
@import './connected-site-row/index';
|
@ -4,6 +4,8 @@
|
||||
|
||||
@import 'settings-tab/index';
|
||||
|
||||
@import 'connections-tab/index';
|
||||
|
||||
@import 'contact-list-tab/index';
|
||||
|
||||
.settings-page {
|
||||
|
@ -1,6 +1,5 @@
|
||||
import React, { PureComponent } from 'react'
|
||||
import PropTypes from 'prop-types'
|
||||
import { exportAsFile } from '../../../helpers/utils/util'
|
||||
import ToggleButton from '../../../components/ui/toggle-button'
|
||||
import { REVEAL_SEED_ROUTE } from '../../../helpers/constants/routes'
|
||||
import Button from '../../../components/ui/button'
|
||||
@ -12,11 +11,8 @@ export default class SecurityTab extends PureComponent {
|
||||
}
|
||||
|
||||
static propTypes = {
|
||||
setPrivacyMode: PropTypes.func,
|
||||
privacyMode: PropTypes.bool,
|
||||
displayWarning: PropTypes.func,
|
||||
revealSeedConfirmation: PropTypes.func,
|
||||
showClearApprovalModal: PropTypes.func,
|
||||
warning: PropTypes.string,
|
||||
history: PropTypes.object,
|
||||
mobileSync: PropTypes.bool,
|
||||
@ -24,71 +20,6 @@ export default class SecurityTab extends PureComponent {
|
||||
setParticipateInMetaMetrics: PropTypes.func,
|
||||
}
|
||||
|
||||
renderStateLogs () {
|
||||
const { t } = this.context
|
||||
const { displayWarning } = this.props
|
||||
|
||||
return (
|
||||
<div className="settings-page__content-row">
|
||||
<div className="settings-page__content-item">
|
||||
<span>{ t('stateLogs') }</span>
|
||||
<span className="settings-page__content-description">
|
||||
{ t('stateLogsDescription') }
|
||||
</span>
|
||||
</div>
|
||||
<div className="settings-page__content-item">
|
||||
<div className="settings-page__content-item-col">
|
||||
<Button
|
||||
type="secondary"
|
||||
large
|
||||
onClick={() => {
|
||||
window.logStateString((err, result) => {
|
||||
if (err) {
|
||||
displayWarning(t('stateLogError'))
|
||||
} else {
|
||||
exportAsFile('MetaMask State Logs.json', result)
|
||||
}
|
||||
})
|
||||
}}
|
||||
>
|
||||
{ t('downloadStateLogs') }
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
renderClearApproval () {
|
||||
const { t } = this.context
|
||||
const { showClearApprovalModal } = this.props
|
||||
return (
|
||||
<div className="settings-page__content-row">
|
||||
<div className="settings-page__content-item">
|
||||
<span>{ t('approvalData') }</span>
|
||||
<span className="settings-page__content-description">
|
||||
{ t('approvalDataDescription') }
|
||||
</span>
|
||||
</div>
|
||||
<div className="settings-page__content-item">
|
||||
<div className="settings-page__content-item-col">
|
||||
<Button
|
||||
type="warning"
|
||||
large
|
||||
className="settings-tab__button--orange"
|
||||
onClick={event => {
|
||||
event.preventDefault()
|
||||
showClearApprovalModal()
|
||||
}}
|
||||
>
|
||||
{ t('clearApprovalData') }
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
renderSeedWords () {
|
||||
const { t } = this.context
|
||||
const { history } = this.props
|
||||
@ -123,32 +54,6 @@ export default class SecurityTab 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)}
|
||||
offLabel={t('off')}
|
||||
onLabel={t('on')}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
renderMetaMetricsOptIn () {
|
||||
const { t } = this.context
|
||||
const { participateInMetaMetrics, setParticipateInMetaMetrics } = this.props
|
||||
@ -181,8 +86,6 @@ export default class SecurityTab extends PureComponent {
|
||||
return (
|
||||
<div className="settings-page__body">
|
||||
{ warning && <div className="settings-tab__error">{ warning }</div> }
|
||||
{ this.renderPrivacyOptIn() }
|
||||
{ this.renderClearApproval() }
|
||||
{ this.renderSeedWords() }
|
||||
{ this.renderMetaMetricsOptIn() }
|
||||
</div>
|
||||
|
@ -5,23 +5,17 @@ import { withRouter } from 'react-router-dom'
|
||||
import {
|
||||
displayWarning,
|
||||
revealSeedConfirmation,
|
||||
setFeatureFlag,
|
||||
showModal,
|
||||
setParticipateInMetaMetrics,
|
||||
} from '../../../store/actions'
|
||||
|
||||
const mapStateToProps = state => {
|
||||
const { appState: { warning }, metamask } = state
|
||||
const {
|
||||
featureFlags: {
|
||||
privacyMode,
|
||||
} = {},
|
||||
participateInMetaMetrics,
|
||||
} = metamask
|
||||
|
||||
return {
|
||||
warning,
|
||||
privacyMode,
|
||||
participateInMetaMetrics,
|
||||
}
|
||||
}
|
||||
@ -30,8 +24,6 @@ const mapDispatchToProps = dispatch => {
|
||||
return {
|
||||
displayWarning: warning => dispatch(displayWarning(warning)),
|
||||
revealSeedConfirmation: () => dispatch(revealSeedConfirmation()),
|
||||
setPrivacyMode: enabled => dispatch(setFeatureFlag('privacyMode', enabled)),
|
||||
showClearApprovalModal: () => dispatch(showModal({ name: 'CLEAR_APPROVED_ORIGINS' })),
|
||||
setParticipateInMetaMetrics: (val) => dispatch(setParticipateInMetaMetrics(val)),
|
||||
}
|
||||
}
|
||||
|
@ -4,6 +4,7 @@ import { Switch, Route, matchPath, withRouter } from 'react-router-dom'
|
||||
import TabBar from '../../components/app/tab-bar'
|
||||
import c from 'classnames'
|
||||
import SettingsTab from './settings-tab'
|
||||
import ConnectionsTab from './connections-tab'
|
||||
import NetworksTab from './networks-tab'
|
||||
import AdvancedTab from './advanced-tab'
|
||||
import InfoTab from './info-tab'
|
||||
@ -14,6 +15,7 @@ import {
|
||||
ADVANCED_ROUTE,
|
||||
SECURITY_ROUTE,
|
||||
GENERAL_ROUTE,
|
||||
CONNECTIONS_ROUTE,
|
||||
ABOUT_US_ROUTE,
|
||||
SETTINGS_ROUTE,
|
||||
NETWORKS_ROUTE,
|
||||
@ -148,6 +150,7 @@ class SettingsPage extends PureComponent {
|
||||
<TabBar
|
||||
tabs={[
|
||||
{ content: t('general'), description: t('generalSettingsDescription'), key: GENERAL_ROUTE },
|
||||
{ content: t('connections'), description: t('connectionsSettingsDescription'), key: CONNECTIONS_ROUTE },
|
||||
{ content: t('advanced'), description: t('advancedSettingsDescription'), key: ADVANCED_ROUTE },
|
||||
{ content: t('contacts'), description: t('contactsSettingsDescription'), key: CONTACT_LIST_ROUTE },
|
||||
{ content: t('securityAndPrivacy'), description: t('securitySettingsDescription'), key: SECURITY_ROUTE },
|
||||
@ -173,6 +176,11 @@ class SettingsPage extends PureComponent {
|
||||
path={GENERAL_ROUTE}
|
||||
component={SettingsTab}
|
||||
/>
|
||||
<Route
|
||||
exact
|
||||
path={CONNECTIONS_ROUTE}
|
||||
component={ConnectionsTab}
|
||||
/>
|
||||
<Route
|
||||
exact
|
||||
path={ABOUT_US_ROUTE}
|
||||
|
@ -8,6 +8,7 @@ import { ENVIRONMENT_TYPE_POPUP } from '../../../../app/scripts/lib/enums'
|
||||
import { getEnvironmentType } from '../../../../app/scripts/lib/util'
|
||||
|
||||
import {
|
||||
CONNECTIONS_ROUTE,
|
||||
ADVANCED_ROUTE,
|
||||
SECURITY_ROUTE,
|
||||
GENERAL_ROUTE,
|
||||
@ -24,6 +25,7 @@ import {
|
||||
|
||||
const ROUTES_TO_I18N_KEYS = {
|
||||
[GENERAL_ROUTE]: 'general',
|
||||
[CONNECTIONS_ROUTE]: 'connections',
|
||||
[ADVANCED_ROUTE]: 'advanced',
|
||||
[SECURITY_ROUTE]: 'securityAndPrivacy',
|
||||
[ABOUT_US_ROUTE]: 'about',
|
||||
|
@ -349,7 +349,6 @@ var actions = {
|
||||
|
||||
approveProviderRequestByOrigin,
|
||||
rejectProviderRequestByOrigin,
|
||||
forceApproveProviderRequestByOrigin,
|
||||
clearApprovedOrigins,
|
||||
|
||||
setFirstTimeFlowType,
|
||||
@ -2650,12 +2649,6 @@ function approveProviderRequestByOrigin (origin) {
|
||||
}
|
||||
}
|
||||
|
||||
function forceApproveProviderRequestByOrigin (origin) {
|
||||
return () => {
|
||||
background.forceApproveProviderRequestByOrigin(origin)
|
||||
}
|
||||
}
|
||||
|
||||
function rejectProviderRequestByOrigin (origin) {
|
||||
return () => {
|
||||
background.rejectProviderRequestByOrigin(origin)
|
||||
|
Loading…
Reference in New Issue
Block a user