refactor(@desktop/settings-pivacy-security): privacy and security section updated

This commit is contained in:
Sale Djenic 2021-12-30 13:39:47 +01:00
parent 9a82370df0
commit 9b1e794e8f
51 changed files with 521 additions and 583 deletions

View File

@ -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)

View File

@ -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)

View File

@ -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")

View File

@ -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)

View File

@ -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

View File

@ -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")

View File

@ -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)

View File

@ -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)

View File

@ -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()

View File

@ -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)

View File

@ -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")

View File

@ -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")

View File

@ -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"

View File

@ -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

View File

@ -49,4 +49,9 @@ QtObject:
proc getNotificationsModule(self: View): QVariant {.slot.} =
return self.delegate.getNotificationsModule()
QtProperty[QVariant] notificationsModule:
read = getNotificationsModule
read = getNotificationsModule
proc getPrivacyModule(self: View): QVariant {.slot.} =
return self.delegate.getPrivacyModule()
QtProperty[QVariant] privacyModule:
read = getPrivacyModule

View File

@ -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)

View File

@ -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
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

View File

@ -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")

View File

@ -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]

View File

@ -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")

View File

@ -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]

View File

@ -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")

View File

@ -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 = "{}"

View File

@ -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"

View File

@ -23,7 +23,6 @@ Item {
wentNext = true
enterSeedPhraseModal.close()
OnboardingStore.importMnemonic(mnemonic)
removeMnemonicAfterLogin = true
recoverySuccessModal.open()
}
onClosed: function () {

View File

@ -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
}

View File

@ -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")
}
}

View File

@ -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;

View File

@ -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 ? "<font color=\"#FF2D55\">" : "")
+ "At least 6 characters." + (!popup.passwordInputValid ? "</font>" : "")
+ "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;
}
}
]
}

View File

@ -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 = {}
}

View File

@ -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)
}
}

View File

@ -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);

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -33,6 +33,7 @@ Item {
MenuPanel {
id: profileMenu
privacyStore: store.privacyStore
mainMenuItems: store.mainMenuItems
settingsMenuItems: store.settingsMenuItems
extraMenuItems: store.extraMenuItems

View File

@ -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

View File

@ -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

View File

@ -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
}
}
}

View File

@ -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

View File

@ -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
}
}

View File

@ -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 {

View File

@ -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
}
}

View File

@ -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
}
}

View File

@ -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

View File

@ -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 {

View File

@ -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)

View File

@ -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 {