From 9b1e794e8fff61f9a62c5393d0bca67486e227a6 Mon Sep 17 00:00:00 2001 From: Sale Djenic Date: Thu, 30 Dec 2021 13:39:47 +0100 Subject: [PATCH] refactor(@desktop/settings-pivacy-security): privacy and security section updated --- src/app/boot/app_controller.nim | 24 ++- src/app/modules/main/module.nim | 8 +- .../main/profile_section/io_interface.nim | 3 + .../profile_section/mnemonic/controller.nim | 34 ---- .../mnemonic/controller_interface.nim | 27 --- .../profile_section/mnemonic/io_interface.nim | 30 --- .../main/profile_section/mnemonic/module.nim | 53 ------ .../main/profile_section/mnemonic/view.nim | 42 ---- .../modules/main/profile_section/module.nim | 20 +- .../profile_section/privacy/controller.nim | 48 ++++- .../privacy/controller_interface.nim | 25 ++- .../profile_section/privacy/io_interface.nim | 38 +++- .../main/profile_section/privacy/module.nim | 48 ++++- .../main/profile_section/privacy/view.nim | 40 +++- src/app/modules/main/profile_section/view.nim | 7 +- src/app_service/common/utils.nim | 5 +- src/app_service/service/accounts/service.nim | 16 +- .../service/accounts/service_interface.nim | 3 + src/app_service/service/mnemonic/dto.nim | 0 src/app_service/service/mnemonic/service.nim | 49 ----- .../service/mnemonic/service_interface.nim | 25 --- src/app_service/service/privacy/dto.nim | 0 src/app_service/service/privacy/service.nim | 153 +++++++++++---- .../service/privacy/service_interface.nim | 19 -- src/app_service/service/provider/service.nim | 4 +- .../service/wallet_account/service.nim | 14 +- .../Onboarding/views/ExistingKeyView.qml | 1 - ui/app/AppLayouts/Profile/ProfileLayout.qml | 4 +- .../AppLayouts/Profile/panels/MenuPanel.qml | 3 +- .../Profile/popups/BackupSeedModal.qml | 10 +- .../Profile/popups/ChangePasswordModal.qml | 180 +++++++----------- .../Profile/popups/ChatLinksPreviewModal.qml | 7 +- .../Profile/stores/PrivacyStore.qml | 32 ++++ ...{RootStore.qml => ProfileSectionStore.qml} | 12 +- .../AppLayouts/Profile/views/AdvancedView.qml | 3 +- .../Profile/views/AppearanceView.qml | 3 +- .../AppLayouts/Profile/views/DevicesView.qml | 4 +- .../AppLayouts/Profile/views/LanguageView.qml | 3 +- .../AppLayouts/Profile/views/LeftTabView.qml | 1 + .../Profile/views/MyProfileView.qml | 3 +- .../Profile/views/NotificationsView.qml | 3 +- .../AppLayouts/Profile/views/PrivacyView.qml | 25 +-- ui/app/AppLayouts/Profile/views/SyncView.qml | 4 +- .../Wallet/panels/SeedPhraseBackupWarning.qml | 6 +- ui/app/AppLayouts/WalletV2/WalletV2Layout.qml | 3 +- .../panels/SeedPhraseBackupWarningPanel.qml | 8 +- .../WalletV2/views/SettingsTabView.qml | 9 +- ui/app/AppLayouts/stores/RootStore.qml | 9 +- ui/app/AppMain.qml | 24 +-- ui/imports/utils/Global.qml | 1 + ui/main.qml | 11 -- 51 files changed, 521 insertions(+), 583 deletions(-) delete mode 100644 src/app/modules/main/profile_section/mnemonic/controller.nim delete mode 100644 src/app/modules/main/profile_section/mnemonic/controller_interface.nim delete mode 100644 src/app/modules/main/profile_section/mnemonic/io_interface.nim delete mode 100644 src/app/modules/main/profile_section/mnemonic/module.nim delete mode 100644 src/app/modules/main/profile_section/mnemonic/view.nim delete mode 100644 src/app_service/service/mnemonic/dto.nim delete mode 100644 src/app_service/service/mnemonic/service.nim delete mode 100644 src/app_service/service/mnemonic/service_interface.nim delete mode 100644 src/app_service/service/privacy/dto.nim delete mode 100644 src/app_service/service/privacy/service_interface.nim create mode 100644 ui/app/AppLayouts/Profile/stores/PrivacyStore.qml rename ui/app/AppLayouts/Profile/stores/{RootStore.qml => ProfileSectionStore.qml} (96%) diff --git a/src/app/boot/app_controller.nim b/src/app/boot/app_controller.nim index e2c20ab9b3..af2f370b2e 100644 --- a/src/app/boot/app_controller.nim +++ b/src/app/boot/app_controller.nim @@ -15,7 +15,6 @@ import ../../app_service/service/collectible/service as collectible_service import ../../app_service/service/wallet_account/service as wallet_account_service import ../../app_service/service/bookmarks/service as bookmark_service import ../../app_service/service/dapp_permissions/service as dapp_permissions_service -import ../../app_service/service/mnemonic/service as mnemonic_service import ../../app_service/service/privacy/service as privacy_service import ../../app_service/service/provider/service as provider_service import ../../app_service/service/profile/service as profile_service @@ -70,7 +69,7 @@ type networkService: network_service.Service activityCenterService: activity_center_service.Service languageService: language_service.Service - mnemonicService: mnemonic_service.Service + # mnemonicService: mnemonic_service.Service privacyService: privacy_service.Service nodeConfigurationService: node_configuration_service.Service savedAddressService: saved_address_service.Service @@ -130,7 +129,7 @@ proc newAppController*(statusFoundation: StatusFoundation): AppController = result.settingsService) result.collectibleService = collectible_service.newService(result.settingsService) result.walletAccountService = wallet_account_service.newService(statusFoundation.status.events, result.settingsService, - result.tokenService) + result.accountsService, result.tokenService) result.transactionService = transaction_service.newService(statusFoundation.status.events, statusFoundation.threadpool, result.walletAccountService) result.bookmarkService = bookmark_service.newService() @@ -149,8 +148,9 @@ proc newAppController*(statusFoundation: StatusFoundation): AppController = result.settingsService) result.dappPermissionsService = dapp_permissions_service.newService() result.languageService = language_service.newService() - result.mnemonicService = mnemonic_service.newService() - result.privacyService = privacy_service.newService() + # result.mnemonicService = mnemonic_service.newService() + result.privacyService = privacy_service.newService(statusFoundation.status.events, result.settingsService, + result.accountsService) result.providerService = provider_service.newService(result.dappPermissionsService, result.settingsService) result.savedAddressService = saved_address_service.newService(statusFoundation.status.events) result.devicesService = devices_service.newService(statusFoundation.status.events, result.settingsService) @@ -183,7 +183,7 @@ proc newAppController*(statusFoundation: StatusFoundation): AppController = result.aboutService, result.dappPermissionsService, result.languageService, - result.mnemonicService, + # result.mnemonicService, result.privacyService, result.providerService, result.stickersService, @@ -199,9 +199,8 @@ proc newAppController*(statusFoundation: StatusFoundation): AppController = proc delete*(self: AppController) = self.osNotificationService.delete + self.keychainService.delete self.contactsService.delete - self.chatService.delete - self.communityService.delete self.bookmarkService.delete self.startupModule.delete self.mainModule.delete @@ -232,6 +231,9 @@ proc delete*(self: AppController) = self.savedAddressService.delete self.devicesService.delete self.mailserversService.delete + self.messageService.delete + self.privacyService.delete + self.profileService.delete proc startupDidLoad*(self: AppController) = singletonInstance.engine.setRootContextProperty("localAppSettings", self.localAppSettingsVariant) @@ -296,6 +298,12 @@ proc userLoggedIn*(self: AppController) = self.statusFoundation.status.startMessenger() self.load() + # Once user is logged in and main module is loaded we need to check if it gets here importing mnemonic or not + # and delete mnemonic in the first case. + let importedAccount = self.accountsService.getImportedAccount() + if(importedAccount.isValid()): + self.privacyService.removeMnemonic() + proc buildAndRegisterLocalAccountSensitiveSettings(self: AppController) = var pubKey = self.settingsService.getPublicKey() singletonInstance.localAccountSensitiveSettings.setFileName(pubKey) diff --git a/src/app/modules/main/module.nim b/src/app/modules/main/module.nim index fcade7d441..b12645e72f 100644 --- a/src/app/modules/main/module.nim +++ b/src/app/modules/main/module.nim @@ -31,7 +31,6 @@ import ../../../app_service/service/settings/service_interface as settings_servi import ../../../app_service/service/contacts/service as contacts_service import ../../../app_service/service/about/service as about_service import ../../../app_service/service/language/service_interface as language_service -import ../../../app_service/service/mnemonic/service as mnemonic_service import ../../../app_service/service/privacy/service as privacy_service import ../../../app_service/service/stickers/service as stickers_service import ../../../app_service/service/activity_center/service as activity_center_service @@ -80,8 +79,7 @@ proc newModule*[T]( aboutService: about_service.Service, dappPermissionsService: dapp_permissions_service.ServiceInterface, languageService: language_service.ServiceInterface, - mnemonicService: mnemonic_service.ServiceInterface, - privacyService: privacy_service.ServiceInterface, + privacyService: privacy_service.Service, providerService: provider_service.ServiceInterface, stickersService: stickers_service.Service, activityCenterService: activity_center_service.Service, @@ -119,8 +117,8 @@ proc newModule*[T]( result.browserSectionModule = browser_section_module.newModule(result, bookmarkService, settingsService, dappPermissionsService, providerService) result.profileSectionModule = profile_section_module.newModule(result, events, accountsService, settingsService, - profileService, contactsService, aboutService, languageService, mnemonicService, privacyService, - nodeConfigurationService, devicesService, mailserversService, chatService) + profileService, contactsService, aboutService, languageService, privacyService, nodeConfigurationService, + devicesService, mailserversService, chatService) result.stickersModule = stickers_module.newModule(result, events, stickersService) result.activityCenterModule = activity_center_module.newModule(result, events, activityCenterService, contactsService) result.communitiesModule = communities_module.newModule(result, events, communityService) diff --git a/src/app/modules/main/profile_section/io_interface.nim b/src/app/modules/main/profile_section/io_interface.nim index 271207571a..c115b11ed5 100644 --- a/src/app/modules/main/profile_section/io_interface.nim +++ b/src/app/modules/main/profile_section/io_interface.nim @@ -41,6 +41,9 @@ method mnemonicModuleDidLoad*(self: AccessInterface) {.base.} = method privacyModuleDidLoad*(self: AccessInterface) {.base.} = raise newException(ValueError, "No implementation available") +method getPrivacyModule*(self: AccessInterface): QVariant {.base.} = + raise newException(ValueError, "No implementation available") + method aboutModuleDidLoad*(self: AccessInterface) {.base.} = raise newException(ValueError, "No implementation available") diff --git a/src/app/modules/main/profile_section/mnemonic/controller.nim b/src/app/modules/main/profile_section/mnemonic/controller.nim deleted file mode 100644 index fa3f1d220c..0000000000 --- a/src/app/modules/main/profile_section/mnemonic/controller.nim +++ /dev/null @@ -1,34 +0,0 @@ -import ./controller_interface -import io_interface -import ../../../../../app_service/service/mnemonic/service as mnemonic_service - -export controller_interface - -type - Controller* = ref object of controller_interface.AccessInterface - delegate: io_interface.AccessInterface - mnemonicService: mnemonic_service.ServiceInterface - -proc newController*(delegate: io_interface.AccessInterface, mnemonicService: mnemonic_service.ServiceInterface): - Controller = - result = Controller() - result.delegate = delegate - result.mnemonicService = mnemonicService - -method delete*(self: Controller) = - discard - -method init*(self: Controller) = - discard - -method isBackedUp*(self: Controller): bool = - return self.mnemonicService.isBackedUp() - -method getMnemonic*(self: Controller): string = - return self.mnemonicService.getMnemonic() - -method remove*(self: Controller) = - self.mnemonicService.remove() - -method getWord*(self: Controller, index: int): string = - return self.mnemonicService.getWord(index) diff --git a/src/app/modules/main/profile_section/mnemonic/controller_interface.nim b/src/app/modules/main/profile_section/mnemonic/controller_interface.nim deleted file mode 100644 index 7ea0cf1c70..0000000000 --- a/src/app/modules/main/profile_section/mnemonic/controller_interface.nim +++ /dev/null @@ -1,27 +0,0 @@ - -type - AccessInterface* {.pure inheritable.} = ref object of RootObj - ## Abstract class for any input/interaction with this module. - -method delete*(self: AccessInterface) {.base.} = - raise newException(ValueError, "No implementation available") - -method init*(self: AccessInterface) {.base.} = - raise newException(ValueError, "No implementation available") - -method isBackedUp*(self: AccessInterface): bool {.base.} = - raise newException(ValueError, "No implementation available") - -method getMnemonic*(self: AccessInterface): string {.base.} = - raise newException(ValueError, "No implementation available") - -method remove*(self: AccessInterface) {.base.} = - raise newException(ValueError, "No implementation available") - -method getWord*(self: AccessInterface, index: int): string {.base.} = - raise newException(ValueError, "No implementation available") - -type - ## Abstract class (concept) which must be implemented by object/s used in this - ## module. - DelegateInterface* = concept c diff --git a/src/app/modules/main/profile_section/mnemonic/io_interface.nim b/src/app/modules/main/profile_section/mnemonic/io_interface.nim deleted file mode 100644 index 0fa6b9274f..0000000000 --- a/src/app/modules/main/profile_section/mnemonic/io_interface.nim +++ /dev/null @@ -1,30 +0,0 @@ -type - AccessInterface* {.pure inheritable.} = ref object of RootObj - ## Abstract class for any input/interaction with this module. - -method delete*(self: AccessInterface) {.base.} = - raise newException(ValueError, "No implementation available") - -method load*(self: AccessInterface) {.base.} = - raise newException(ValueError, "No implementation available") - -method isLoaded*(self: AccessInterface): bool {.base.} = - raise newException(ValueError, "No implementation available") - -method isBackedUp*(self: AccessInterface): bool {.base.} = - raise newException(ValueError, "No implementation available") - -method getMnemonic*(self: AccessInterface): string {.base.} = - raise newException(ValueError, "No implementation available") - -method remove*(self: AccessInterface) {.base.} = - raise newException(ValueError, "No implementation available") - -method getWord*(self: AccessInterface, index: int): string {.base.} = - raise newException(ValueError, "No implementation available") - -# View Delegate Interface -# Delegate for the view must be declared here due to use of QtObject and multi -# inheritance, which is not well supported in Nim. -method viewDidLoad*(self: AccessInterface) {.base.} = - raise newException(ValueError, "No implementation available") diff --git a/src/app/modules/main/profile_section/mnemonic/module.nim b/src/app/modules/main/profile_section/mnemonic/module.nim deleted file mode 100644 index c7d7e8ec3c..0000000000 --- a/src/app/modules/main/profile_section/mnemonic/module.nim +++ /dev/null @@ -1,53 +0,0 @@ -import NimQml, Tables - -import ./io_interface, ./view, ./controller -import ../io_interface as delegate_interface -import ../../../../global/global_singleton - -import ../../../../../app_service/service/mnemonic/service as mnemonic_service - -export io_interface - -type - Module* = ref object of io_interface.AccessInterface - delegate: delegate_interface.AccessInterface - controller: controller.AccessInterface - view: View - viewVariant: QVariant - moduleLoaded: bool - -proc newModule*(delegate: delegate_interface.AccessInterface, mnemonicService: mnemonic_service.ServiceInterface): Module = - result = Module() - result.delegate = delegate - result.view = newView(result) - result.viewVariant = newQVariant(result.view) - result.controller = controller.newController(result, mnemonicService) - result.moduleLoaded = false - - singletonInstance.engine.setRootContextProperty("mnemonicModule", result.viewVariant) - -method delete*(self: Module) = - self.view.delete - -method load*(self: Module) = - self.controller.init() - self.view.load() - -method isLoaded*(self: Module): bool = - return self.moduleLoaded - -method viewDidLoad*(self: Module) = - self.moduleLoaded = true - self.delegate.mnemonicModuleDidLoad() - -method isBackedUp*(self: Module): bool = - return self.controller.isBackedup() - -method getMnemonic*(self: Module): string = - return self.controller.getMnemonic() - -method remove*(self: Module) = - self.controller.remove() - -method getWord*(self: Module, index: int): string = - return self.controller.getWord(index) diff --git a/src/app/modules/main/profile_section/mnemonic/view.nim b/src/app/modules/main/profile_section/mnemonic/view.nim deleted file mode 100644 index 7fc9c7ba97..0000000000 --- a/src/app/modules/main/profile_section/mnemonic/view.nim +++ /dev/null @@ -1,42 +0,0 @@ -import NimQml - -import ./io_interface - -QtObject: - type - View* = ref object of QObject - delegate: io_interface.AccessInterface - - proc delete*(self: View) = - self.QObject.delete - - proc newView*(delegate: io_interface.AccessInterface): View = - new(result, delete) - result.QObject.setup - result.delegate = delegate - - proc load*(self: View) = - self.delegate.viewDidLoad() - - proc isBackedUp*(self: View): bool {.slot.} = - return self.delegate.isBackedup() - - proc seedPhraseRemoved*(self: View) {.signal.} - - QtProperty[bool] isBackedUp: - read = isBackedUp - notify = seedPhraseRemoved - - proc getMnemonic*(self: View): QVariant {.slot.} = - return newQVariant(self.delegate.getMnemonic()) - - QtProperty[QVariant] get: - read = getMnemonic - notify = seedPhraseRemoved - - proc remove*(self: View) {.slot.} = - self.delegate.remove() - self.seedPhraseRemoved() - - proc getWord*(self: View, index: int): string {.slot.} = - return self.delegate.getWord(index) diff --git a/src/app/modules/main/profile_section/module.nim b/src/app/modules/main/profile_section/module.nim index bc6109ad53..a212e79d84 100644 --- a/src/app/modules/main/profile_section/module.nim +++ b/src/app/modules/main/profile_section/module.nim @@ -8,7 +8,6 @@ import ../../../../app_service/service/settings/service_interface as settings_se import ../../../../app_service/service/contacts/service as contacts_service import ../../../../app_service/service/about/service as about_service import ../../../../app_service/service/language/service_interface as language_service -import ../../../../app_service/service/mnemonic/service as mnemonic_service import ../../../../app_service/service/privacy/service as privacy_service import ../../../../app_service/service/node_configuration/service_interface as node_configuration_service import ../../../../app_service/service/devices/service as devices_service @@ -18,7 +17,6 @@ import ../../../../app_service/service/chat/service as chat_service import ./profile/module as profile_module import ./contacts/module as contacts_module import ./language/module as language_module -import ./mnemonic/module as mnemonic_module import ./privacy/module as privacy_module import ./about/module as about_module import ./advanced/module as advanced_module @@ -41,7 +39,6 @@ type profileModule: profile_module.AccessInterface languageModule: language_module.AccessInterface contactsModule: contacts_module.AccessInterface - mnemonicModule: mnemonic_module.AccessInterface privacyModule: privacy_module.AccessInterface aboutModule: about_module.AccessInterface advancedModule: advanced_module.AccessInterface @@ -57,8 +54,7 @@ proc newModule*[T](delegate: T, contactsService: contacts_service.Service, aboutService: about_service.Service, languageService: language_service.ServiceInterface, - mnemonicService: mnemonic_service.ServiceInterface, - privacyService: privacy_service.ServiceInterface, + privacyService: privacy_service.Service, nodeConfigurationService: node_configuration_service.ServiceInterface, devicesService: devices_service.Service, mailserversService: mailservers_service.Service, @@ -75,8 +71,7 @@ proc newModule*[T](delegate: T, result.profileModule = profile_module.newModule(result, profileService) result.contactsModule = contacts_module.newModule(result, events, contactsService, accountsService) result.languageModule = language_module.newModule(result, languageService) - result.mnemonicModule = mnemonic_module.newModule(result, mnemonicService) - result.privacyModule = privacy_module.newModule(result, privacyService, accountsService) + result.privacyModule = privacy_module.newModule(result, events, settingsService, privacyService) result.aboutModule = about_module.newModule(result, events, aboutService) result.advancedModule = advanced_module.newModule(result, events, settingsService, nodeConfigurationService) result.devicesModule = devices_module.newModule(result, events, settingsService, devicesService) @@ -89,7 +84,6 @@ method delete*[T](self: Module[T]) = self.profileModule.delete self.contactsModule.delete self.languageModule.delete - self.mnemonicModule.delete self.privacyModule.delete self.aboutModule.delete self.advancedModule.delete @@ -105,7 +99,6 @@ method load*[T](self: Module[T]) = self.profileModule.load() self.contactsModule.load() self.languageModule.load() - self.mnemonicModule.load() self.privacyModule.load() self.aboutModule.load() self.advancedModule.load() @@ -126,9 +119,6 @@ proc checkIfModuleDidLoad[T](self: Module[T]) = if(not self.languageModule.isLoaded()): return - if(not self.mnemonicModule.isLoaded()): - return - if(not self.privacyModule.isLoaded()): return @@ -168,12 +158,12 @@ method languageModuleDidLoad*[T](self: Module[T]) = method getLanguageModule*[T](self: Module[T]): QVariant = self.languageModule.getModuleAsVariant() -method mnemonicModuleDidLoad*[T](self: Module[T]) = - self.checkIfModuleDidLoad() - method privacyModuleDidLoad*[T](self: Module[T]) = self.checkIfModuleDidLoad() +method getPrivacyModule*[T](self: Module[T]): QVariant = + self.privacyModule.getModuleAsVariant() + method aboutModuleDidLoad*[T](self: Module[T]) = self.checkIfModuleDidLoad() diff --git a/src/app/modules/main/profile_section/privacy/controller.nim b/src/app/modules/main/profile_section/privacy/controller.nim index faf5edb0e6..96f26a538d 100644 --- a/src/app/modules/main/profile_section/privacy/controller.nim +++ b/src/app/modules/main/profile_section/privacy/controller.nim @@ -1,32 +1,60 @@ import ./controller_interface import io_interface -import ../../../../../app_service/service/accounts/service as accounts_service + +import ../../../../../app_service/service/settings/service_interface as settings_service import ../../../../../app_service/service/privacy/service as privacy_service +import eventemitter + export controller_interface type Controller* = ref object of controller_interface.AccessInterface delegate: io_interface.AccessInterface - accountsService: accounts_service.ServiceInterface - privacyService: privacy_service.ServiceInterface + events: EventEmitter + settingsService: settings_service.ServiceInterface + privacyService: privacy_service.Service -proc newController*(delegate: io_interface.AccessInterface, privacyService: privacy_service.ServiceInterface, - accountsService: accounts_service.ServiceInterface): Controller = +proc newController*(delegate: io_interface.AccessInterface, events: EventEmitter, + settingsService: settings_service.ServiceInterface, + privacyService: privacy_service.Service): Controller = result = Controller() result.delegate = delegate - result.accountsService = accountsService + result.events = events + result.settingsService = settingsService result.privacyService = privacyService method delete*(self: Controller) = discard method init*(self: Controller) = - discard + self.events.on(SIGNAL_MNEMONIC_REMOVAL) do(e: Args): + self.delegate.onMnemonicUpdated() + + self.events.on(SIGNAL_PASSWORD_CHANGED) do(e: Args): + var args = OperationSuccessArgs(e) + self.delegate.onPasswordChanged(args.success) + +method isMnemonicBackedUp*(self: Controller): bool = + return self.privacyService.isMnemonicBackedUp() method getLinkPreviewWhitelist*(self: Controller): string = return self.privacyService.getLinkPreviewWhitelist() -method changePassword*(self: Controller, password: string, newPassword: string): bool = - let loggedInAccount = self.accountsService.getLoggedInAccount() - return self.privacyService.changePassword(loggedInAccount.keyUid, password, newPassword) +method changePassword*(self: Controller, password: string, newPassword: string) = + self.privacyService.changePassword(password, newPassword) + +method getMnemonic*(self: Controller): string = + return self.privacyService.getMnemonic() + +method removeMnemonic*(self: Controller) = + self.privacyService.removeMnemonic() + +method getMnemonicWordAtIndex*(self: Controller, index: int): string = + return self.privacyService.getMnemonicWordAtIndex(index) + +method getMessagesFromContactsOnly*(self: Controller): bool = + return self.settingsService.getMessagesFromContactsOnly() + +method setMessagesFromContactsOnly*(self: Controller, value: bool): bool = + return self.settingsService.saveMessagesFromContactsOnly(value) \ No newline at end of file diff --git a/src/app/modules/main/profile_section/privacy/controller_interface.nim b/src/app/modules/main/profile_section/privacy/controller_interface.nim index 9d672e45b2..cfdc632339 100644 --- a/src/app/modules/main/profile_section/privacy/controller_interface.nim +++ b/src/app/modules/main/profile_section/privacy/controller_interface.nim @@ -1,5 +1,3 @@ -# import ../../../../../app_service/service/profile/service as profile_service - type AccessInterface* {.pure inheritable.} = ref object of RootObj ## Abstract class for any input/interaction with this module. @@ -10,13 +8,26 @@ method delete*(self: AccessInterface) {.base.} = method init*(self: AccessInterface) {.base.} = raise newException(ValueError, "No implementation available") +method isMnemonicBackedUp*(self: AccessInterface): bool {.base.} = + raise newException(ValueError, "No implementation available") + method getLinkPreviewWhitelist*(self: AccessInterface): string {.base.} = raise newException(ValueError, "No implementation available") -method changePassword*(self: AccessInterface, password: string, newPassword: string): bool {.base.} = +method changePassword*(self: AccessInterface, password: string, newPassword: string) {.base.} = raise newException(ValueError, "No implementation available") -type - ## Abstract class (concept) which must be implemented by object/s used in this - ## module. - DelegateInterface* = concept c +method getMnemonic*(self: AccessInterface): string {.base.} = + raise newException(ValueError, "No implementation available") + +method removeMnemonic*(self: AccessInterface) {.base.} = + raise newException(ValueError, "No implementation available") + +method getMnemonicWordAtIndex*(self: AccessInterface, index: int): string {.base.} = + raise newException(ValueError, "No implementation available") + +method getMessagesFromContactsOnly*(self: AccessInterface): bool {.base.} = + raise newException(ValueError, "No implementation available") + +method setMessagesFromContactsOnly*(self: AccessInterface, value: bool): bool {.base.} = + raise newException(ValueError, "No implementation available") \ No newline at end of file diff --git a/src/app/modules/main/profile_section/privacy/io_interface.nim b/src/app/modules/main/profile_section/privacy/io_interface.nim index 829c6c07f3..b52cacc44c 100644 --- a/src/app/modules/main/profile_section/privacy/io_interface.nim +++ b/src/app/modules/main/profile_section/privacy/io_interface.nim @@ -1,3 +1,5 @@ +import NimQml + type AccessInterface* {.pure inheritable.} = ref object of RootObj ## Abstract class for any input/interaction with this module. @@ -11,10 +13,7 @@ method load*(self: AccessInterface) {.base.} = method isLoaded*(self: AccessInterface): bool {.base.} = raise newException(ValueError, "No implementation available") -method getLinkPreviewWhitelist*(self: AccessInterface): string {.base.} = - raise newException(ValueError, "No implementation available") - -method changePassword*(self: AccessInterface, password: string, newPassword: string): bool {.base.} = +method getModuleAsVariant*(self: AccessInterface): QVariant {.base.} = raise newException(ValueError, "No implementation available") # View Delegate Interface @@ -22,3 +21,34 @@ method changePassword*(self: AccessInterface, password: string, newPassword: str # inheritance, which is not well supported in Nim. method viewDidLoad*(self: AccessInterface) {.base.} = raise newException(ValueError, "No implementation available") + +method isMnemonicBackedUp*(self: AccessInterface): bool {.base.} = + raise newException(ValueError, "No implementation available") + +method getLinkPreviewWhitelist*(self: AccessInterface): string {.base.} = + raise newException(ValueError, "No implementation available") + +method changePassword*(self: AccessInterface, password: string, newPassword: string) {.base.} = + raise newException(ValueError, "No implementation available") + +method getMnemonic*(self: AccessInterface): string {.base.} = + raise newException(ValueError, "No implementation available") + +method removeMnemonic*(self: AccessInterface) {.base.} = + raise newException(ValueError, "No implementation available") + +method getMnemonicWordAtIndex*(self: AccessInterface, index: int): string {.base.} = + raise newException(ValueError, "No implementation available") + +# Controller Delegate Interface +method onMnemonicUpdated*(self: AccessInterface) {.base.} = + raise newException(ValueError, "No implementation available") + +method onPasswordChanged*(self: AccessInterface, success: bool) {.base.} = + raise newException(ValueError, "No implementation available") + +method getMessagesFromContactsOnly*(self: AccessInterface): bool {.base.} = + raise newException(ValueError, "No implementation available") + +method setMessagesFromContactsOnly*(self: AccessInterface, value: bool) {.base.} = + raise newException(ValueError, "No implementation available") \ No newline at end of file diff --git a/src/app/modules/main/profile_section/privacy/module.nim b/src/app/modules/main/profile_section/privacy/module.nim index be61150fce..cdf628cb70 100644 --- a/src/app/modules/main/profile_section/privacy/module.nim +++ b/src/app/modules/main/profile_section/privacy/module.nim @@ -1,12 +1,13 @@ -import NimQml, Tables +import NimQml, chronicles import ./io_interface, ./view, ./controller import ../io_interface as delegate_interface -import ../../../../global/global_singleton -import ../../../../../app_service/service/accounts/service as accounts_service +import ../../../../../app_service/service/settings/service_interface as settings_service import ../../../../../app_service/service/privacy/service as privacy_service +import eventemitter + export io_interface type @@ -17,16 +18,17 @@ type viewVariant: QVariant moduleLoaded: bool -proc newModule*(delegate: delegate_interface.AccessInterface, privacyService: privacy_service.ServiceInterface, accountsService: accounts_service.ServiceInterface): Module = +proc newModule*(delegate: delegate_interface.AccessInterface, events: EventEmitter, + settingsService: settings_service.ServiceInterface, + privacyService: privacy_service.Service): + Module = result = Module() result.delegate = delegate result.view = newView(result) result.viewVariant = newQVariant(result.view) - result.controller = controller.newController(result, privacyService, accountsService) + result.controller = controller.newController(result, events, settingsService, privacyService) result.moduleLoaded = false - singletonInstance.engine.setRootContextProperty("privacyModule", result.viewVariant) - method delete*(self: Module) = self.view.delete @@ -41,8 +43,36 @@ method viewDidLoad*(self: Module) = self.moduleLoaded = true self.delegate.privacyModuleDidLoad() +method getModuleAsVariant*(self: Module): QVariant = + return self.viewVariant + method getLinkPreviewWhitelist*(self: Module): string = return self.controller.getLinkPreviewWhitelist() -method changePassword*(self: Module, password: string, newPassword: string): bool = - return self.controller.changePassword(password, newPassword) +method changePassword*(self: Module, password: string, newPassword: string) = + self.controller.changePassword(password, newPassword) + +method isMnemonicBackedUp*(self: Module): bool = + return self.controller.isMnemonicBackedUp() + +method onMnemonicUpdated*(self: Module) = + self.view.emitMnemonicBackedUpSignal() + +method onPasswordChanged*(self: Module, success: bool) = + self.view.emitPasswordChangedSignal(success) + +method getMnemonic*(self: Module): string = + self.controller.getMnemonic() + +method removeMnemonic*(self: Module) = + self.controller.removeMnemonic() + +method getMnemonicWordAtIndex*(self: Module, index: int): string = + return self.controller.getMnemonicWordAtIndex(index) + +method getMessagesFromContactsOnly*(self: Module): bool = + return self.controller.getMessagesFromContactsOnly() + +method setMessagesFromContactsOnly*(self: Module, value: bool) = + if(not self.controller.setMessagesFromContactsOnly(value)): + error "an error occurred while saving messages from contacts only flag" \ No newline at end of file diff --git a/src/app/modules/main/profile_section/privacy/view.nim b/src/app/modules/main/profile_section/privacy/view.nim index 8e7a43f247..57b26e0424 100644 --- a/src/app/modules/main/profile_section/privacy/view.nim +++ b/src/app/modules/main/profile_section/privacy/view.nim @@ -1,6 +1,5 @@ import NimQml -# import ./controller_interface import ./io_interface QtObject: @@ -22,5 +21,40 @@ QtObject: proc getLinkPreviewWhitelist*(self: View): string {.slot.} = return self.delegate.getLinkPreviewWhitelist() - proc changePassword*(self: View, password: string, newPassword: string): bool {.slot.} = - return self.delegate.changePassword(password, newPassword) + proc changePassword*(self: View, password: string, newPassword: string) {.slot.} = + self.delegate.changePassword(password, newPassword) + + proc passwordChanged(self: View, success: bool) {.signal.} + proc emitPasswordChangedSignal*(self: View, success: bool) = + self.passwordChanged(success) + + proc mnemonicBackedUpChanged(self: View) {.signal.} + proc isMnemonicBackedUp(self: View): bool {.slot.} = + return self.delegate.isMnemonicBackedUp() + QtProperty[bool] mnemonicBackedUp: + read = isMnemonicBackedUp + notify = mnemonicBackedUpChanged + + proc emitMnemonicBackedUpSignal*(self: View) = + self.mnemonicBackedUpChanged() + + proc getMnemonic*(self: View): string {.slot.} = + return self.delegate.getMnemonic() + + proc removeMnemonic*(self: View) {.slot.} = + self.delegate.removeMnemonic() + + proc getMnemonicWordAtIndex*(self: View, index: int): string {.slot.} = + return self.delegate.getMnemonicWordAtIndex(index) + + proc messagesFromContactsOnlyChanged(self: View) {.signal.} + proc getMessagesFromContactsOnly(self: View): bool {.slot.} = + return self.delegate.getMessagesFromContactsOnly() + proc setMessagesFromContactsOnly(self: View, value: bool) {.slot.} = + self.delegate.setMessagesFromContactsOnly(value) + self.messagesFromContactsOnlyChanged() + QtProperty[bool] messagesFromContactsOnly: + read = getMessagesFromContactsOnly + write = setMessagesFromContactsOnly + notify = messagesFromContactsOnlyChanged + \ No newline at end of file diff --git a/src/app/modules/main/profile_section/view.nim b/src/app/modules/main/profile_section/view.nim index f1a40860c1..ebf2c99153 100644 --- a/src/app/modules/main/profile_section/view.nim +++ b/src/app/modules/main/profile_section/view.nim @@ -49,4 +49,9 @@ QtObject: proc getNotificationsModule(self: View): QVariant {.slot.} = return self.delegate.getNotificationsModule() QtProperty[QVariant] notificationsModule: - read = getNotificationsModule \ No newline at end of file + read = getNotificationsModule + + proc getPrivacyModule(self: View): QVariant {.slot.} = + return self.delegate.getPrivacyModule() + QtProperty[QVariant] privacyModule: + read = getPrivacyModule \ No newline at end of file diff --git a/src/app_service/common/utils.nim b/src/app_service/common/utils.nim index 8563625c83..32b382f54e 100644 --- a/src/app_service/common/utils.nim +++ b/src/app_service/common/utils.nim @@ -1,7 +1,10 @@ import json, random, times, strutils, os - +import nimcrypto import signing_phrases +proc hashPassword*(password: string): string = + result = "0x" & $keccak_256.digest(password) + proc generateSigningPhrase*(count: int): string = let now = getTime() var rng = initRand(now.toUnix * 1000000000 + now.nanosecond) diff --git a/src/app_service/service/accounts/service.nim b/src/app_service/service/accounts/service.nim index e9d5265708..3e5c7d2ed1 100644 --- a/src/app_service/service/accounts/service.nim +++ b/src/app_service/service/accounts/service.nim @@ -10,6 +10,7 @@ import status/statusgo_backend_new/general as status_general import ../../../app/core/fleets/fleet_configuration import ../../common/[account_constants, network_constants, utils, string_utils] import ../../../constants as main_constants + export service_interface logScope: @@ -311,4 +312,17 @@ method login*(self: Service, account: AccountDto, password: string): string = except Exception as e: error "error: ", methodName="setupAccount", errName = e.name, errDesription = e.msg - return e.msg \ No newline at end of file + return e.msg + +method verifyAccountPassword*(self: Service, account: string, password: string): bool = + try: + let response = status_account.verifyAccountPassword(account, password, main_constants.KEYSTOREDIR) + if(response.result.contains("error")): + let errMsg = response.result["error"].getStr + if(errMsg.len == 0): + return true + else: + error "error: ", methodName="verifyAccountPassword", errDesription = errMsg + return false + except Exception as e: + error "error: ", methodName="verifyAccountPassword", errName = e.name, errDesription = e.msg \ No newline at end of file diff --git a/src/app_service/service/accounts/service_interface.nim b/src/app_service/service/accounts/service_interface.nim index 03e2133346..369ea57bbd 100644 --- a/src/app_service/service/accounts/service_interface.nim +++ b/src/app_service/service/accounts/service_interface.nim @@ -46,3 +46,6 @@ method clear*(self: ServiceInterface) {.base.} = method generateAlias*(self: ServiceInterface, publicKey: string): string {.base.} = raise newException(ValueError, "No implementation available") + +method verifyAccountPassword*(self: ServiceInterface, account: string, password: string): bool {.base.} = + raise newException(ValueError, "No implementation available") diff --git a/src/app_service/service/mnemonic/dto.nim b/src/app_service/service/mnemonic/dto.nim deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/src/app_service/service/mnemonic/service.nim b/src/app_service/service/mnemonic/service.nim deleted file mode 100644 index abc22f9bc2..0000000000 --- a/src/app_service/service/mnemonic/service.nim +++ /dev/null @@ -1,49 +0,0 @@ -import json, json_serialization, sequtils, chronicles, strutils -import options - -import status/statusgo_backend/settings as status_go_settings -import status/statusgo_backend/accounts as status_accounts -from status/types/setting import Setting - -import ./service_interface, ./dto - -export service_interface - -logScope: - topics = "settings-service" - -type - Service* = ref object of ServiceInterface - isMnemonicBackedUp: Option[bool] - -method delete*(self: Service) = - discard - -proc newService*(): Service = - result = Service() - -method init*(self: Service) = - try: - echo "init" - - except Exception as e: - let errDesription = e.msg - error "error: ", errDesription - return - -method isBackedUp*(self: Service): bool = - if self.isMnemonicBackedUp.isNone: - self.isMnemonicBackedUp = some(status_go_settings.getSetting[string](Setting.Mnemonic, "") == "") - self.isMnemonicBackedUp.get() - -method getMnemonic*(self: Service): string = - let mnemonic = status_go_settings.getSetting[string](Setting.Mnemonic, "") - return mnemonic - -method remove*(self: Service) = - discard status_go_settings.saveSetting(Setting.Mnemonic, "") - self.isMnemonicBackedUp = some(true) - -method getWord*(self: Service, index: int): string = - let mnemonics = status_go_settings.getSetting[string](Setting.Mnemonic, "").split(" ") - return mnemonics[index] diff --git a/src/app_service/service/mnemonic/service_interface.nim b/src/app_service/service/mnemonic/service_interface.nim deleted file mode 100644 index 7a5604a248..0000000000 --- a/src/app_service/service/mnemonic/service_interface.nim +++ /dev/null @@ -1,25 +0,0 @@ -import dto - -export dto - -type - ServiceInterface* {.pure inheritable.} = ref object of RootObj - ## Abstract class for this service access. - -method delete*(self: ServiceInterface) {.base.} = - raise newException(ValueError, "No implementation available") - -method init*(self: ServiceInterface) {.base.} = - raise newException(ValueError, "No implementation available") - -method isBackedUp*(self: ServiceInterface): bool {.base.} = - raise newException(ValueError, "No implementation available") - -method getMnemonic*(self: ServiceInterface): string {.base.} = - raise newException(ValueError, "No implementation available") - -method remove*(self: ServiceInterface) {.base.} = - raise newException(ValueError, "No implementation available") - -method getWord*(self: ServiceInterface, index: int): string {.base.} = - raise newException(ValueError, "No implementation available") diff --git a/src/app_service/service/privacy/dto.nim b/src/app_service/service/privacy/dto.nim deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/src/app_service/service/privacy/service.nim b/src/app_service/service/privacy/service.nim index 7e4874548f..ec26744b84 100644 --- a/src/app_service/service/privacy/service.nim +++ b/src/app_service/service/privacy/service.nim @@ -1,52 +1,131 @@ -import json, json_serialization, sequtils, chronicles -import status/statusgo_backend/eth as eth -import status/statusgo_backend/settings as status_go_settings -import status/statusgo_backend/accounts as status_go_accounts +import NimQml, json, strutils, chronicles -import ../../../constants +import ../settings/service_interface as settings_service +import ../accounts/service_interface as accounts_service -import ./service_interface, ./dto +import status/statusgo_backend_new/accounts as status_account +import status/statusgo_backend_new/eth as status_eth +import status/statusgo_backend_new/privacy as status_privacy -export service_interface +import eventemitter logScope: topics = "privacy-service" -type - Service* = ref object of ServiceInterface - # profile: Dto +const SIGNAL_MNEMONIC_REMOVAL* = "menmonicRemoval" +const SIGNAL_PASSWORD_CHANGED* = "passwordChanged" -method delete*(self: Service) = - discard +type + OperationSuccessArgs* = ref object of Args + success*: bool + +QtObject: + type Service* = ref object of QObject + events: EventEmitter + settingsService: settings_service.ServiceInterface + accountsService: accounts_service.ServiceInterface -proc newService*(): Service = - result = Service() + proc delete*(self: Service) = + self.QObject.delete -method init*(self: Service) = - try: - echo "init" + proc newService*(events: EventEmitter, settingsService: settings_service.ServiceInterface, + accountsService: accounts_service.ServiceInterface): Service = + new(result, delete) + result.QObject.setup + result.events = events + result.settingsService = settingsService + result.accountsService = accountsService - except Exception as e: - let errDesription = e.msg - error "error: ", errDesription - return + proc init*(self: Service) = + discard -method getLinkPreviewWhitelist*(self: Service): string = - return $(status_go_settings.getLinkPreviewWhitelist()) + proc getLinkPreviewWhitelist*(self: Service): string = + try: + let response = status_privacy.getLinkPreviewWhitelist() + + if(response.result.kind != JArray): + var errMsg = "response is not an array" + if(response.result.contains("error")): + errMsg = response.result["error"].getStr + error "error: ", methodName="getLinkPreviewWhitelist", errDesription = errMsg + return -method changePassword*(self: Service, address: string, password: string, newPassword: string): bool = - let - defaultAccount = eth.getDefaultAccount() - isPasswordOk = status_go_accounts.verifyAccountPassword(defaultAccount, password, KEYSTOREDIR) - if not isPasswordOk: - return false + return $(response.result) + except Exception as e: + error "error: ", methodName="removeReaction", errName = e.name, errDesription = e.msg - return changeDatabasePassword(address, password, newPassword) + proc getDefaultAccount(self: Service): string = + try: + let response = status_eth.getEthAccounts() -proc changeDatabasePassword(keyUID: string, password: string, newPassword: string): bool = - try: - if not status_go_accounts.changeDatabasePassword(keyUID, password, newPassword): - return false - except: - return false - return true + if(response.result.kind != JArray): + error "error: ", methodName="getDefaultAccount", errDesription = "response is not an array" + return + + for acc in response.result: + # the first account is considered as the default one + return acc.getStr + + return "" + except Exception as e: + error "error: ", methodName="getDefaultAccount", errName = e.name, errDesription = e.msg + + proc changePassword*(self: Service, password: string, newPassword: string) = + try: + var data = OperationSuccessArgs(success: false) + + let defaultAccount = self.getDefaultAccount() + if(defaultAccount.len == 0): + error "error: ", methodName="changePassword", errDesription = "default eth account is empty" + self.events.emit(SIGNAL_PASSWORD_CHANGED, data) + return + + let isPasswordOk = self.accountsService.verifyAccountPassword(defaultAccount, password) + if not isPasswordOk: + error "error: ", methodName="changePassword", errDesription = "password cannnot be verified" + self.events.emit(SIGNAL_PASSWORD_CHANGED, data) + return + + let loggedInAccount = self.accountsService.getLoggedInAccount() + let response = status_privacy.changeDatabasePassword(loggedInAccount.keyUid, password, newPassword) + + if(response.result.contains("error")): + let errMsg = response.result["error"].getStr + if(errMsg.len == 0): + data.success = true + else: + error "error: ", methodName="changePassword", errDesription = errMsg + + self.events.emit(SIGNAL_PASSWORD_CHANGED, data) + + except Exception as e: + error "error: ", methodName="changePassword", errName = e.name, errDesription = e.msg + + proc isMnemonicBackedUp*(self: Service): bool = + return self.settingsService.getMnemonic().len == 0 + + proc getMnemonic*(self: Service): string = + return self.settingsService.getMnemonic() + + proc removeMnemonic*(self: Service) = + var data = OperationSuccessArgs(success: true) + if(not self.settingsService.saveMnemonic("")): + data.success = false + error "error: ", methodName="removeMnemonic", errDesription = "an error occurred removing mnemonic" + + self.events.emit(SIGNAL_MNEMONIC_REMOVAL, data) + + proc getMnemonicWordAtIndex*(self: Service, index: int): string = + let mnemonic = self.settingsService.getMnemonic() + if(mnemonic.len == 0): + let msg = "tyring to get a word on index " & $(index) & " from an empty mnemonic" + error "error: ", methodName="getMnemonicWordAtIndex", errDesription = msg + return + + let mnemonics = mnemonic.split(" ") + if(index < 0 or index >= mnemonics.len): + let msg = "tyring to get a word on index " & $(index) & " but mnemonic contains " & $(mnemonics.len) & " words" + error "error: ", methodName="getMnemonicWordAtIndex", errDesription = msg + return + + return mnemonics[index] \ No newline at end of file diff --git a/src/app_service/service/privacy/service_interface.nim b/src/app_service/service/privacy/service_interface.nim deleted file mode 100644 index 20ef0621ff..0000000000 --- a/src/app_service/service/privacy/service_interface.nim +++ /dev/null @@ -1,19 +0,0 @@ -import dto - -export dto - -type - ServiceInterface* {.pure inheritable.} = ref object of RootObj - ## Abstract class for this service access. - -method delete*(self: ServiceInterface) {.base.} = - raise newException(ValueError, "No implementation available") - -method init*(self: ServiceInterface) {.base.} = - raise newException(ValueError, "No implementation available") - -method getLinkPreviewWhitelist*(self: ServiceInterface): string {.base.} = - raise newException(ValueError, "No implementation available") - -method changePassword*(self: ServiceInterface, address: string, password: string, newPassword: string): bool {.base.} = - raise newException(ValueError, "No implementation available") diff --git a/src/app_service/service/provider/service.nim b/src/app_service/service/provider/service.nim index 71ff1bf51d..d7c675a772 100644 --- a/src/app_service/service/provider/service.nim +++ b/src/app_service/service/provider/service.nim @@ -8,8 +8,8 @@ import ../settings/service_interface as settings_service import ../ens/utils as ens_utils import service_interface import status/statusgo_backend_new/permissions as status_go_permissions -import status/statusgo_backend_new/accounts as status_go_accounts import status/statusgo_backend_new/core as status_go_core +import ../../common/utils as status_utils from stew/base32 import nil from stew/base58 import nil import stew/byteutils @@ -201,7 +201,7 @@ proc process(self: Service, data: Web3SendAsyncReadOnly): string = try: let request = data.request.parseJson var params = request["params"] - let password = hashPassword(request["password"].getStr()) + let password = status_utils.hashPassword(request["password"].getStr()) let dappAddress = self.settingsService.getDappsAddress() var rpcResult = "{}" diff --git a/src/app_service/service/wallet_account/service.nim b/src/app_service/service/wallet_account/service.nim index 0613bd0c14..184e31dcdb 100644 --- a/src/app_service/service/wallet_account/service.nim +++ b/src/app_service/service/wallet_account/service.nim @@ -3,9 +3,9 @@ import web3/[ethtypes, conversions] import eventemitter import ../settings/service_interface as settings_service +import ../accounts/service_interface as accounts_service import ../token/service as token_service import ../../common/account_constants -import ../../../constants import ./service_interface, ./dto import status/statusgo_backend_new/accounts as status_go_accounts @@ -102,6 +102,7 @@ type Service* = ref object of service_interface.ServiceInterface events: EventEmitter settingsService: settings_service.ServiceInterface + accountsService: accounts_service.ServiceInterface tokenService: token_service.Service accounts: OrderedTable[string, WalletAccountDto] @@ -109,11 +110,14 @@ method delete*(self: Service) = discard proc newService*( - events: EventEmitter, settingsService: settings_service.ServiceInterface, tokenService: token_service.Service): + events: EventEmitter, settingsService: settings_service.ServiceInterface, + accountsService: accounts_service.ServiceInterface, + tokenService: token_service.Service): Service = result = Service() result.events = events result.settingsService = settingsService + result.accountsService = accountsService result.tokenService = tokenService result.accounts = initOrderedTable[string, WalletAccountDto]() @@ -240,7 +244,7 @@ method generateNewAccount*(self: Service, password: string, accountName: string, walletRootAddress = self.settingsService.getWalletRootAddress() walletIndex = self.settingsService.getLatestDerivedPath() + 1 defaultAccount = self.getDefaultAccount() - isPasswordOk = status_go_accounts.verifyAccountPassword(defaultAccount, password, KEYSTOREDIR) + isPasswordOk = self.accountsService.verifyAccountPassword(defaultAccount, password) if not isPasswordOk: return "Error generating new account: invalid password" @@ -270,7 +274,7 @@ method addAccountsFromPrivateKey*(self: Service, privateKey: string, password: s let accountResponse = status_go_accounts.multiAccountImportPrivateKey(privateKey) defaultAccount = self.getDefaultAccount() - isPasswordOk = status_go_accounts.verifyAccountPassword(defaultAccount, password, KEYSTOREDIR) + isPasswordOk = self.accountsService.verifyAccountPassword(defaultAccount, password) if not isPasswordOk: return "Error generating new account: invalid password" @@ -296,7 +300,7 @@ method addAccountsFromSeed*(self: Service, seedPhrase: string, password: string, let defaultAccount = self.getDefaultAccount() - isPasswordOk = status_go_accounts.verifyAccountPassword(defaultAccount, password, KEYSTOREDIR) + isPasswordOk = self.accountsService.verifyAccountPassword(defaultAccount, password) if not isPasswordOk: return "Error generating new account: invalid password" diff --git a/ui/app/AppLayouts/Onboarding/views/ExistingKeyView.qml b/ui/app/AppLayouts/Onboarding/views/ExistingKeyView.qml index be7389036c..c30509783c 100644 --- a/ui/app/AppLayouts/Onboarding/views/ExistingKeyView.qml +++ b/ui/app/AppLayouts/Onboarding/views/ExistingKeyView.qml @@ -23,7 +23,6 @@ Item { wentNext = true enterSeedPhraseModal.close() OnboardingStore.importMnemonic(mnemonic) - removeMnemonicAfterLogin = true recoverySuccessModal.open() } onClosed: function () { diff --git a/ui/app/AppLayouts/Profile/ProfileLayout.qml b/ui/app/AppLayouts/Profile/ProfileLayout.qml index b37f816c11..805b4ae758 100644 --- a/ui/app/AppLayouts/Profile/ProfileLayout.qml +++ b/ui/app/AppLayouts/Profile/ProfileLayout.qml @@ -14,7 +14,7 @@ import StatusQ.Layout 0.1 StatusAppTwoPanelLayout { id: profileView - property RootStore store: RootStore { } + property ProfileSectionStore store property var globalStore property var systemPalette @@ -62,7 +62,7 @@ StatusAppTwoPanelLayout { } PrivacyView { - store: profileView.store + privacyStore: profileView.store.privacyStore profileContentWidth: _internal.profileContentWidth } diff --git a/ui/app/AppLayouts/Profile/panels/MenuPanel.qml b/ui/app/AppLayouts/Profile/panels/MenuPanel.qml index 7a71bc9026..685f62a59e 100644 --- a/ui/app/AppLayouts/Profile/panels/MenuPanel.qml +++ b/ui/app/AppLayouts/Profile/panels/MenuPanel.qml @@ -10,6 +10,7 @@ Column { id: root spacing: 4 + property var privacyStore property alias mainMenuItems: mainMenuItems.model property alias settingsMenuItems: settingsMenuItems.model property alias extraMenuItems: extraMenuItems.model @@ -40,7 +41,7 @@ Column { selected: Global.currentMenuTab === model.menu_id onClicked: root.menuItemClicked(model) visible: model.ifEnabled !== "browser" || root.browserMenuItemEnabled - badge.value: !mnemonicModule.isBackedUp && settingsMenuDelegate.title === qsTr("Privacy and security") + badge.value: !root.privacyStore.mnemonicBackedUp && settingsMenuDelegate.title === qsTr("Privacy and security") } } diff --git a/ui/app/AppLayouts/Profile/popups/BackupSeedModal.qml b/ui/app/AppLayouts/Profile/popups/BackupSeedModal.qml index f0ca4bf8fc..3d3b93113b 100644 --- a/ui/app/AppLayouts/Profile/popups/BackupSeedModal.qml +++ b/ui/app/AppLayouts/Profile/popups/BackupSeedModal.qml @@ -12,6 +12,8 @@ import StatusQ.Controls 0.1 // TODO: replace with StatusModal ModalPopup { id: popup + + property var privacyStore property bool showWarning: true property int seedWord1Idx: -1; @@ -74,7 +76,7 @@ ModalPopup { Repeater { id: mnemonicRepeater - model: mnemonicModule.get.split(" ") + model: popup.privacyStore.getMnemonic().split(" ") Rectangle { id: word height: 40 @@ -208,7 +210,7 @@ ModalPopup { //% "You will not be able to see the whole seed phrase again" confirmationText: qsTrId("are-you-sure-description") onConfirmButtonClicked: { - mnemonicModule.remove() + popup.privacyStore.removeMnemonic() popup.close(); confirmPopup.close(); } @@ -261,7 +263,7 @@ ModalPopup { seedWord1Idx = Math.floor(Math.random() * 12); } else { if(seedWord2Idx == -1){ - if(mnemonicModule.getWord(seedWord1Idx) !== txtFieldWord.text){ + if(popup.privacyStore.getMnemonicWordAtIndex(seedWord1Idx) !== txtFieldWord.text){ //% "Wrong word" validationError = qsTrId("wrong-word"); return; @@ -274,7 +276,7 @@ ModalPopup { seedWord2Idx = Math.floor(Math.random() * 12); } while(seedWord2Idx == seedWord1Idx); } else { - if(mnemonicModule.getWord(seedWord2Idx) !== txtFieldWord.text){ + if(popup.privacyStore.getMnemonicWordAtIndex(seedWord2Idx) !== txtFieldWord.text){ //% "Wrong word" validationError = qsTrId("wrong-word"); return; diff --git a/ui/app/AppLayouts/Profile/popups/ChangePasswordModal.qml b/ui/app/AppLayouts/Profile/popups/ChangePasswordModal.qml index 04bf578143..cc190fd2da 100644 --- a/ui/app/AppLayouts/Profile/popups/ChangePasswordModal.qml +++ b/ui/app/AppLayouts/Profile/popups/ChangePasswordModal.qml @@ -12,138 +12,94 @@ import StatusQ.Popups 0.1 import StatusQ.Controls 0.1 StatusModal { - id: root - - signal passwordChanged() - + id: popup width: 480 height: 510 closePolicy: Popup.NoAutoClose header.title: qsTr("Change password") - onOpened: d.reset() + onOpened: { + reset(); + } - QtObject { - id: d + property var privacyStore - function lengthValidator(text) { - return text.length >= 6 ? "" : qsTr("At least 6 characters") + property var successPopup + property string indicationText: "" + property bool passwordInputValid + property bool currPasswordInputValid + property string currPasswordValidationError: "" + + function reset() { + passwordInput.text = ""; + currentPasswordInput.text = ""; + currentPasswordInput.forceActiveFocus(Qt.MouseFocusReason); + popup.indicationText = "At least 6 characters. Your password protects your keys. You need it to unlock Status and transact."; + popup.currPasswordValidationError = ""; + passwordInput.validationError = ""; + popup.passwordInputValid = false; + popup.currPasswordInputValid = false; + } + + function onChangePasswordResponse(success) { + if (success) { + popup.successPopup.open(); + submitBtn.enabled = false; + } else { + reset(); + passwordInput.validationError = " "; + popup.currPasswordValidationError = qsTr("Incorrect password"); } + submitBtn.loading = false; + } - function reset() { - currentPasswordInput.state = "init" - passwordInput.state = "init" - confirmPasswordInput.state = "init" - currentPasswordInput.forceActiveFocus(Qt.MouseFocusReason) - } + Connections { + target: popup.privacyStore.privacyModule + onPasswordChanged: onChangePasswordResponse(success) } contentItem: ColumnLayout { id: contentItem anchors.fill: parent anchors { - topMargin: Style.current.xlPadding + root.topPadding + topMargin: (Style.current.xlPadding + popup.topPadding) leftMargin: Style.current.xlPadding rightMargin: Style.current.xlPadding - bottomMargin: Style.current.xlPadding + root.bottomPadding + bottomMargin: (Style.current.xlPadding + popup.bottomPadding) } spacing: Style.current.padding - // TODO replace with StatusInput as soon as it supports password + //TODO replace with StatusInput as soon as it supports password Input { id: currentPasswordInput - - readonly property bool ready: state == "typing" && validationError == "" - anchors.left: undefined anchors.right: undefined Layout.fillWidth: true - label: qsTr("Current password") - - textField.echoMode: TextInput.Password - keepHeight: true placeholderText: "" - state: "init" - - onTextChanged: if (text != "" && state != "typing") state = "typing" - onStateChanged: if (state == "init") resetInternal() - - states: [ - State { - name: "init" - }, - State { - name: "typing" - PropertyChanges { target: currentPasswordInput; validationError: d.lengthValidator(text) } - }, - State { - name: "incorrect" - PropertyChanges { target: currentPasswordInput; validationError: qsTr("Incorrect password") } - } - ] + label: qsTr("Current password") + textField.echoMode: TextInput.Password + onTextChanged: { + popup.currPasswordInputValid = (currentPasswordInput.text.length >= 6); + } } - // TODO replace with StatusInput as soon as it supports password + //TODO replace with StatusInput as soon as it supports password Input { id: passwordInput - - readonly property bool ready: state == "typing" && validationError == "" - anchors.left: undefined anchors.right: undefined Layout.fillWidth: true - label: qsTr("New password") - - textField.echoMode: TextInput.Password - keepHeight: true placeholderText: "" - state: "init" - - onTextChanged: if (text != "" && state != "typing") state = "typing" - onStateChanged: if (state == "init") resetInternal() - - states: [ - State { - name: "init" - }, - State { - name: "typing" - PropertyChanges { target: passwordInput; validationError: d.lengthValidator(text) } - } - ] - } - - // TODO replace with StatusInput as soon as it supports password - Input { - id: confirmPasswordInput - - readonly property bool ready: state == "typing" && validationError == "" - - anchors.left: undefined - anchors.right: undefined - Layout.fillWidth: true - label: qsTr("Confirm new password") - + label: qsTrId("new-password...") textField.echoMode: TextInput.Password - keepHeight: true - placeholderText: "" - state: "init" - - onTextChanged: if (text != "" && state != "typing") state = "typing" - onStateChanged: if (state == "init") resetInternal() - - states: [ - State { - name: "init" - }, - State { - name: "typing" - PropertyChanges { - target: confirmPasswordInput; - validationError: confirmPasswordInput.text != passwordInput.text ? qsTr("Password does not match") : "" - } - } - ] + onTextChanged: { + popup.passwordInputValid = ((passwordInput.text !== "") && (passwordInput.text.length >= 6)); + //setting validationError so that input becomes red + passwordInput.validationError = (!popup.passwordInputValid) ? " " : ""; + popup.indicationText = (!popup.passwordInputValid ? "" : "") + + "At least 6 characters." + (!popup.passwordInputValid ? "" : "") + + "Your password protects your keys. You need it to unlock Status and transact." + } } Item { @@ -151,7 +107,18 @@ StatusModal { } StyledText { - text: qsTr("Your password protects your keys. You need it to unlock Status and transact.") + id: validationError + Layout.preferredWidth: parent.width + Layout.alignment: Qt.AlignHCenter + horizontalAlignment: Text.AlignHCenter + visible: (text !== "") + font.pixelSize: Style.current.tertiaryTextFontSize + color: Style.current.danger + text: popup.currPasswordValidationError + } + + StyledText { + text: qsTr(indicationText) wrapMode: Text.WordWrap Layout.preferredWidth: 340 Layout.alignment: Qt.AlignHCenter @@ -164,16 +131,14 @@ StatusModal { rightButtons: [ StatusButton { id: submitBtn - text: qsTr("Change password") - enabled: !submitBtn.loading && currentPasswordInput.ready && - passwordInput.ready && confirmPasswordInput.ready + enabled: (popup.passwordInputValid && popup.currPasswordInputValid && !submitBtn.loading) property Timer sim: Timer { id: pause interval: 20 onTriggered: { - submitBtn.changePasswordBegin(); + popup.privacyStore.changePassword(currentPasswordInput.text, passwordInput.text) } } @@ -184,17 +149,6 @@ StatusModal { //small pause (timer) in order to get the desired behavior pause.start(); } - - function changePasswordBegin() { - if (privacyModule.changePassword(currentPasswordInput.text, passwordInput.text)) { - passwordChanged() - submitBtn.enabled = false; - } else { - currentPasswordInput.state = "incorrect" - currentPasswordInput.forceActiveFocus(Qt.MouseFocusReason) - } - submitBtn.loading = false; - } } ] } diff --git a/ui/app/AppLayouts/Profile/popups/ChatLinksPreviewModal.qml b/ui/app/AppLayouts/Profile/popups/ChatLinksPreviewModal.qml index 849f452d9f..d2bd2d1ea5 100644 --- a/ui/app/AppLayouts/Profile/popups/ChatLinksPreviewModal.qml +++ b/ui/app/AppLayouts/Profile/popups/ChatLinksPreviewModal.qml @@ -15,6 +15,8 @@ import utils 1.0 ModalPopup { id: popup + property var privacyStore + //% "Chat link previews" title: qsTrId("chat-link-previews") @@ -23,7 +25,10 @@ ModalPopup { } function populatePreviewableSites() { - let whitelist = JSON.parse(privacyModule.getLinkPreviewWhitelist()) + let whitelistAsString = popup.privacyStore.getLinkPreviewWhitelist() + if(whitelistAsString == "") + return + let whitelist = JSON.parse(whitelistAsString) if (!localAccountSensitiveSettings.whitelistedUnfurlingSites) { localAccountSensitiveSettings.whitelistedUnfurlingSites = {} } diff --git a/ui/app/AppLayouts/Profile/stores/PrivacyStore.qml b/ui/app/AppLayouts/Profile/stores/PrivacyStore.qml new file mode 100644 index 0000000000..d1229f257a --- /dev/null +++ b/ui/app/AppLayouts/Profile/stores/PrivacyStore.qml @@ -0,0 +1,32 @@ +import QtQuick 2.13 +import utils 1.0 + +QtObject { + id: root + + property var privacyModule + + // Module Properties + property bool mnemonicBackedUp: privacyModule.mnemonicBackedUp + property bool messagesFromContactsOnly: privacyModule.messagesFromContactsOnly + + function getLinkPreviewWhitelist() { + return root.privacyModule.getLinkPreviewWhitelist() + } + + function changePassword(password, newPassword) { + root.privacyModule.changePassword(password, newPassword) + } + + function getMnemonic() { + return root.privacyModule.getMnemonic() + } + + function removeMnemonic() { + root.privacyModule.removeMnemonic() + } + + function getMnemonicWordAtIndex(index) { + return root.privacyModule.getMnemonicWordAtIndex(index) + } +} diff --git a/ui/app/AppLayouts/Profile/stores/RootStore.qml b/ui/app/AppLayouts/Profile/stores/ProfileSectionStore.qml similarity index 96% rename from ui/app/AppLayouts/Profile/stores/RootStore.qml rename to ui/app/AppLayouts/Profile/stores/ProfileSectionStore.qml index cabdc950ec..8b1ccf2eae 100644 --- a/ui/app/AppLayouts/Profile/stores/RootStore.qml +++ b/ui/app/AppLayouts/Profile/stores/ProfileSectionStore.qml @@ -6,7 +6,6 @@ QtObject { property var contactsModuleInst: contactsModule property var aboutModuleInst: aboutModule - property var mnemonicModuleInst: mnemonicModule property var profileSectionModuleInst: profileSectionModule @@ -37,6 +36,10 @@ QtObject { profileModule: profileSectionModuleInst.profileModule } + property PrivacyStore privacyStore: PrivacyStore { + privacyModule: profileSectionModuleInst.privacyModule + } + // Not Refactored Yet // property var chatsModelInst: chatsModel // Not Refactored Yet @@ -64,8 +67,6 @@ QtObject { // Not Refactored Yet // property string preferredUsername: userProfile.preferredName // was: profileModelInst.ens.preferredUsername // property string firstEnsUsername: userProfile.firstEnsName // was: profileModelInst.ens.firstEnsUsername - property bool mnemonicBackedUp: mnemonicModuleInst.isBackedUp - property bool messagesFromContactsOnly: false //profile.messagesFromContactsOnly property int profile_id: 0 property int contacts_id: 1 @@ -328,11 +329,6 @@ QtObject { // return profileModelInst.ens.setPubKey(username, address, gasLimit, gasPrice, password) } - function setMessagesFromContactsOnly(checked) { - // Not Refactored Yet -// profileModelInst.setMessagesFromContactsOnly(checked) - } - function userNameOrAlias(pk) { // Not Refactored Yet // return chatsModelInst.userNameOrAlias(pk); diff --git a/ui/app/AppLayouts/Profile/views/AdvancedView.qml b/ui/app/AppLayouts/Profile/views/AdvancedView.qml index 6f8dd4e48c..378150f903 100644 --- a/ui/app/AppLayouts/Profile/views/AdvancedView.qml +++ b/ui/app/AppLayouts/Profile/views/AdvancedView.qml @@ -9,6 +9,7 @@ import shared.panels 1.0 import shared.popups 1.0 import shared.status 1.0 +import "../stores" import "../controls" import "../popups" import "../panels" @@ -23,7 +24,7 @@ ScrollView { contentHeight: advancedContainer.height + 100 clip: true - property var advancedStore + property AdvancedStore advancedStore Item { id: advancedContainer diff --git a/ui/app/AppLayouts/Profile/views/AppearanceView.qml b/ui/app/AppLayouts/Profile/views/AppearanceView.qml index a1fd5e21a7..7b634ba2fa 100644 --- a/ui/app/AppLayouts/Profile/views/AppearanceView.qml +++ b/ui/app/AppLayouts/Profile/views/AppearanceView.qml @@ -14,6 +14,7 @@ import StatusQ.Core.Theme 0.1 import StatusQ.Controls 0.1 as StatusQ import "../popups" +import "../stores" ScrollView { id: appearanceView @@ -22,7 +23,7 @@ ScrollView { contentHeight: appearanceContainer.height clip: true - property var appearanceStore + property AppearanceStore appearanceStore property var systemPalette property int profileContentWidth diff --git a/ui/app/AppLayouts/Profile/views/DevicesView.qml b/ui/app/AppLayouts/Profile/views/DevicesView.qml index 961e72b44c..1512c4ef58 100644 --- a/ui/app/AppLayouts/Profile/views/DevicesView.qml +++ b/ui/app/AppLayouts/Profile/views/DevicesView.qml @@ -12,10 +12,12 @@ import utils 1.0 import shared.panels 1.0 import shared.controls 1.0 +import "../stores" + Item { id: root - property var devicesStore + property DevicesStore devicesStore property bool isSyncing: false diff --git a/ui/app/AppLayouts/Profile/views/LanguageView.qml b/ui/app/AppLayouts/Profile/views/LanguageView.qml index c5606448c2..b757fac348 100644 --- a/ui/app/AppLayouts/Profile/views/LanguageView.qml +++ b/ui/app/AppLayouts/Profile/views/LanguageView.qml @@ -9,6 +9,7 @@ import StatusQ.Core.Theme 0.1 import StatusQ.Components 0.1 import "../popups" +import "../stores" Item { id: languageContainer @@ -16,7 +17,7 @@ Item { Layout.fillWidth: true clip: true - property var languageStore + property LanguageStore languageStore property int profileContentWidth property Component languagePopup: LanguageModal { languageStore: languageContainer.languageStore diff --git a/ui/app/AppLayouts/Profile/views/LeftTabView.qml b/ui/app/AppLayouts/Profile/views/LeftTabView.qml index c6422b5940..0df6006ca1 100644 --- a/ui/app/AppLayouts/Profile/views/LeftTabView.qml +++ b/ui/app/AppLayouts/Profile/views/LeftTabView.qml @@ -33,6 +33,7 @@ Item { MenuPanel { id: profileMenu + privacyStore: store.privacyStore mainMenuItems: store.mainMenuItems settingsMenuItems: store.settingsMenuItems extraMenuItems: store.extraMenuItems diff --git a/ui/app/AppLayouts/Profile/views/MyProfileView.qml b/ui/app/AppLayouts/Profile/views/MyProfileView.qml index 33e2f2af0a..5eb556fe2b 100644 --- a/ui/app/AppLayouts/Profile/views/MyProfileView.qml +++ b/ui/app/AppLayouts/Profile/views/MyProfileView.qml @@ -8,6 +8,7 @@ import shared.panels 1.0 import shared.popups 1.0 import "../popups" +import "../stores" import StatusQ.Core 0.1 import StatusQ.Core.Theme 0.1 @@ -17,7 +18,7 @@ import StatusQ.Controls 0.1 Item { id: root - property var profileStore + property ProfileStore profileStore property int profileContentWidth diff --git a/ui/app/AppLayouts/Profile/views/NotificationsView.qml b/ui/app/AppLayouts/Profile/views/NotificationsView.qml index 4b32cda239..3ae5a08fec 100644 --- a/ui/app/AppLayouts/Profile/views/NotificationsView.qml +++ b/ui/app/AppLayouts/Profile/views/NotificationsView.qml @@ -12,6 +12,7 @@ import shared.panels 1.0 import shared.status 1.0 import shared.controls 1.0 +import "../stores" import "../popups" import "../panels" import "./" @@ -19,7 +20,7 @@ import "./" ScrollView { id: root - property var notificationsStore + property NotificationsStore notificationsStore property int profileContentWidth diff --git a/ui/app/AppLayouts/Profile/views/PrivacyView.qml b/ui/app/AppLayouts/Profile/views/PrivacyView.qml index 98bb5118a6..dfa47b2239 100644 --- a/ui/app/AppLayouts/Profile/views/PrivacyView.qml +++ b/ui/app/AppLayouts/Profile/views/PrivacyView.qml @@ -13,6 +13,7 @@ import StatusQ.Components 0.1 import StatusQ.Controls 0.1 as StatusQControls import "../popups" +import "../stores" Item { id: root @@ -20,7 +21,8 @@ Item { Layout.fillWidth: true clip: true - property var store + property PrivacyStore privacyStore + property int profileContentWidth Column { @@ -46,12 +48,12 @@ Item { anchors.rightMargin: -Style.current.padding //% "Backup Seed Phrase" title: qsTrId("backup-seed-phrase") - enabled: !root.store.mnemonicBackedUp + enabled: !root.privacyStore.mnemonicBackedUp implicitHeight: 52 components: [ StatusBadge { - value: !root.store.mnemonicBackedUp - visible: !root.store.mnemonicBackedUp + value: !root.privacyStore.mnemonicBackedUp + visible: !root.privacyStore.mnemonicBackedUp anchors.verticalCenter: parent.verticalCenter }, StatusIcon { @@ -60,7 +62,7 @@ Item { color: Theme.palette.baseColor1 } ] - sensor.onClicked: backupSeedModal.open() + sensor.onClicked: Global.openBackUpSeedPopup() } StatusListItem { @@ -113,12 +115,9 @@ Item { } } - BackupSeedModal { - id: backupSeedModal - } - ChangePasswordModal { id: changePasswordModal + privacyStore: root.privacyStore anchors.centerIn: parent successPopup: successPopup } @@ -215,7 +214,9 @@ Item { Component { id: chatLinksPreviewModal - ChatLinksPreviewModal {} + ChatLinksPreviewModal { + privacyStore: root.privacyStore + } } Component { @@ -254,11 +255,11 @@ Item { components: [ StatusQControls.StatusSwitch { id: switch3 - checked: !root.store.messagesFromContactsOnly + checked: !root.privacyStore.messagesFromContactsOnly } ] sensor.onClicked: { - root.store.setMessagesFromContactsOnly(!switch3.checked) + switch3.checked = root.privacyStore.messagesFromContactsOnly = !switch3.checked } } } diff --git a/ui/app/AppLayouts/Profile/views/SyncView.qml b/ui/app/AppLayouts/Profile/views/SyncView.qml index 6756294b1c..0197254a61 100644 --- a/ui/app/AppLayouts/Profile/views/SyncView.qml +++ b/ui/app/AppLayouts/Profile/views/SyncView.qml @@ -11,10 +11,12 @@ import utils 1.0 import shared.popups 1.0 import shared.controls 1.0 +import "../stores" + Item { id: root - property var syncStore + property SyncStore syncStore property int profileContentWidth diff --git a/ui/app/AppLayouts/Wallet/panels/SeedPhraseBackupWarning.qml b/ui/app/AppLayouts/Wallet/panels/SeedPhraseBackupWarning.qml index 17359b1d69..88ffe3fb08 100644 --- a/ui/app/AppLayouts/Wallet/panels/SeedPhraseBackupWarning.qml +++ b/ui/app/AppLayouts/Wallet/panels/SeedPhraseBackupWarning.qml @@ -6,7 +6,6 @@ import QtGraphicalEffects 1.13 import utils 1.0 import shared 1.0 import shared.panels 1.0 -import "../../Profile/popups" import "../stores" Rectangle { @@ -56,7 +55,7 @@ Rectangle { MouseArea { cursorShape: Qt.PointingHandCursor anchors.fill: parent - onClicked: backupSeedModal.open() + onClicked: Global.openBackUpSeedPopup() } } } @@ -85,7 +84,4 @@ Rectangle { PropertyAnimation { target: root; property: "y"; to: -1 * root.height } } } - BackupSeedModal { - id: backupSeedModal - } } diff --git a/ui/app/AppLayouts/WalletV2/WalletV2Layout.qml b/ui/app/AppLayouts/WalletV2/WalletV2Layout.qml index bf05eb8e54..24b84b4df8 100644 --- a/ui/app/AppLayouts/WalletV2/WalletV2Layout.qml +++ b/ui/app/AppLayouts/WalletV2/WalletV2Layout.qml @@ -45,7 +45,8 @@ Item { id: seedPhraseWarning width: parent.width anchors.top: parent.top - visible: !mnemonicModule.isBackedUp + // Not Refactored Yet (there is no wallet 2 is `base_bc`) +// visible: !mnemonicModule.isBackedUp } StatusAppTwoPanelLayout { diff --git a/ui/app/AppLayouts/WalletV2/panels/SeedPhraseBackupWarningPanel.qml b/ui/app/AppLayouts/WalletV2/panels/SeedPhraseBackupWarningPanel.qml index d25e6ce190..d91ba3f449 100644 --- a/ui/app/AppLayouts/WalletV2/panels/SeedPhraseBackupWarningPanel.qml +++ b/ui/app/AppLayouts/WalletV2/panels/SeedPhraseBackupWarningPanel.qml @@ -6,7 +6,6 @@ import QtGraphicalEffects 1.13 import utils 1.0 import shared 1.0 import shared.panels 1.0 -import "../../Profile/popups" import "." Rectangle { @@ -54,7 +53,7 @@ Rectangle { MouseArea { cursorShape: Qt.PointingHandCursor anchors.fill: parent - onClicked: { backupSeedModal.open(); } + onClicked: { Global.openBackUpSeedPopup() } } } } @@ -83,9 +82,4 @@ Rectangle { PropertyAnimation { target: root; property: "y"; to: -1 * root.height } } } - - - BackupSeedModal { - id: backupSeedModal - } } diff --git a/ui/app/AppLayouts/WalletV2/views/SettingsTabView.qml b/ui/app/AppLayouts/WalletV2/views/SettingsTabView.qml index 0e8796a9fb..c38bfaf997 100644 --- a/ui/app/AppLayouts/WalletV2/views/SettingsTabView.qml +++ b/ui/app/AppLayouts/WalletV2/views/SettingsTabView.qml @@ -36,8 +36,9 @@ Item { primaryText: qsTr("Back up seed phrase") secondaryText: qsTr("Back up your seed phrase now to secure this account") button.text: qsTr("Back up seed phrase") - button.enabled: !mnemonicModule.isBackedUp - button.onClicked: backupSeedModal.open() + // Not Refactored Yet (there is no wallet 2 is `base_bc`) +// button.enabled: !mnemonicModule.isBackedUp + button.onClicked: Global.openBackUpSeedPopup() } StatusExpandableItem { @@ -163,8 +164,4 @@ Item { } } } - - BackupSeedModal { - id: backupSeedModal - } } diff --git a/ui/app/AppLayouts/stores/RootStore.qml b/ui/app/AppLayouts/stores/RootStore.qml index cf3c31563a..6b1fb88695 100644 --- a/ui/app/AppLayouts/stores/RootStore.qml +++ b/ui/app/AppLayouts/stores/RootStore.qml @@ -1,16 +1,15 @@ import QtQuick 2.13 -import "../Profile/stores" as ProfileStores - +import "../Profile/stores" QtObject { id: root - - readonly property ProfileStores.RootStore profileStore: ProfileStores.RootStore {} - property var mainModuleInst: mainModule property var aboutModuleInst: aboutModule + property ProfileSectionStore profileSectionStore: ProfileSectionStore { + } + // Not Refactored Yet // property var chatsModelInst: chatsModel // Not Refactored Yet diff --git a/ui/app/AppMain.qml b/ui/app/AppMain.qml index 5ff43995ea..778792161d 100644 --- a/ui/app/AppMain.qml +++ b/ui/app/AppMain.qml @@ -15,6 +15,7 @@ import "./AppLayouts/WalletV2" import "./AppLayouts/Chat/popups" import "./AppLayouts/Chat/popups/community" import "./AppLayouts/Profile/Sections" +import "./AppLayouts/Profile/popups" import "./AppLayouts/stores" import Qt.labs.platform 1.1 @@ -79,6 +80,10 @@ Item { popup.openPopup(userProfile.pubKey !== fromAuthorParam, userNameParam, fromAuthorParam, identiconParam, textParam, nicknameParam); Global.profilePopupOpened = true; } + onOpenBackUpSeedPopup : { + var popup = backupSeedModalComponent.createObject(appMain) + popup.open() + } } function changeAppSectionBySectionId(sectionId) { @@ -125,6 +130,11 @@ Item { return "" } + property Component backupSeedModalComponent: BackupSeedModal { + id: backupSeedModal + privacyStore: appMain.rootStore.profileSectionStore.privacyStore + } + Component { id: downloadModalComponent DownloadModal { @@ -476,6 +486,8 @@ Item { Layout.fillWidth: true Layout.alignment: Qt.AlignLeft | Qt.AlignTop Layout.fillHeight: true + + store: appMain.rootStore.profileSectionStore globalStore: appMain.rootStore systemPalette: appMain.sysPalette } @@ -557,18 +569,6 @@ Item { // } // } -// Connections { -// target: profileModel -// ignoreUnknownSignals: true -// enabled: removeMnemonicAfterLogin -// onInitialized: { -// mnemonicModule.remove() -// } -// } -// Global.settingsLoaded() -// } -// } - Connections { diff --git a/ui/imports/utils/Global.qml b/ui/imports/utils/Global.qml index 04e77c108d..c0c8d341f8 100644 --- a/ui/imports/utils/Global.qml +++ b/ui/imports/utils/Global.qml @@ -26,6 +26,7 @@ QtObject { signal openPopupRequested(var popupComponent, var params) signal openDownloadModalRequested() signal settingsLoaded() + signal openBackUpSeedPopup() signal openProfilePopupRequested(string userNameParam, string fromAuthorParam, string identiconParam, string textParam, string nicknameParam, var parentPopup) diff --git a/ui/main.qml b/ui/main.qml index 33cb8a5059..adf8b6f18c 100644 --- a/ui/main.qml +++ b/ui/main.qml @@ -21,7 +21,6 @@ import "./app" StatusWindow { property bool hasAccounts: startupModule.appState !== Constants.appState.onboarding - property bool removeMnemonicAfterLogin: false property alias dragAndDrop: dragTarget property bool displayBeforeGetStartedModal: !hasAccounts @@ -167,15 +166,6 @@ StatusWindow { } } -// Connections { -// target: profileModel -// ignoreUnknownSignals: true -// enabled: removeMnemonicAfterLogin -// onInitialized: { -// mnemonicModule.remove() -// } -// } - // The easiest way to get current system theme (is it light or dark) without using // OS native methods is to check lightness (0 - 1.0) of the window color. // If it's too high (0.85+) means light theme is an active. @@ -522,7 +512,6 @@ StatusWindow { id: existingKey ExistingKeyView { onClosed: function () { - removeMnemonicAfterLogin = false if (hasAccounts) { applicationWindow.navigateTo("InitialState") } else {