From 4f3ca4eb7805393d670fc9aa977cde294ca90f9a Mon Sep 17 00:00:00 2001 From: Sale Djenic Date: Fri, 15 Oct 2021 21:47:43 +0200 Subject: [PATCH] login process refactored --- src/app/boot/app_controller.nim | 6 ++-- src/app/modules/startup/controller.nim | 26 ++++++++++++-- src/app/modules/startup/io_interface.nim | 2 +- src/app/modules/startup/login/controller.nim | 28 ++++++++------- .../startup/login/controller_interface.nim | 3 ++ src/app/modules/startup/login/module.nim | 8 ++++- .../module_controller_delegate_interface.nim | 2 ++ .../module_view_delegate_interface.nim | 3 ++ src/app/modules/startup/login/view.nim | 10 +++++- src/app/modules/startup/module.nim | 6 ++-- .../modules/startup/onboarding/controller.nim | 8 ++--- src/app/modules/startup/onboarding/module.nim | 3 -- .../module_controller_delegate_interface.nim | 3 -- src/app/modules/startup/onboarding/view.nim | 4 ++- .../module_controller_delegate_interface.nim | 2 ++ .../module_onboarding_delegate_interface.nim | 3 -- .../service/accounts/dto/accounts.nim | 5 +-- src/app_service/service/accounts/service.nim | 32 +++++++++++++++-- .../service/accounts/service_interface.nim | 4 +++ ui/app/AppLayouts/Chat/ChatLayout.qml | 16 ++------- .../Onboarding/shared/CreatePasswordModal.qml | 4 ++- .../AppLayouts/Onboarding/views/LoginView.qml | 36 +++++++++---------- ui/main.qml | 3 +- 23 files changed, 139 insertions(+), 78 deletions(-) diff --git a/src/app/boot/app_controller.nim b/src/app/boot/app_controller.nim index 516d351876..325ebf3f78 100644 --- a/src/app/boot/app_controller.nim +++ b/src/app/boot/app_controller.nim @@ -42,7 +42,7 @@ proc load*(self: AppController) # Startup Module Delegate Interface proc startupDidLoad*(self: AppController) -proc accountCreated*(self: AppController) +proc userLoggedIn*(self: AppController) # Main Module Delegate Interface proc mainDidLoad*(self: AppController) @@ -114,7 +114,6 @@ proc mainDidLoad*(self: AppController) = # self.appService.status.events.emit("loginCompleted", self.accountArgs) proc start*(self: AppController) = - echo "AppStart" self.accountsService.init() self.startupModule.load() @@ -126,6 +125,5 @@ proc load*(self: AppController) = self.mainModule.load() -proc accountCreated*(self: AppController) = - echo "AppController account created" +proc userLoggedIn*(self: AppController) = self.load() \ No newline at end of file diff --git a/src/app/modules/startup/controller.nim b/src/app/modules/startup/controller.nim index 6040abbbc5..86c50436ee 100644 --- a/src/app/modules/startup/controller.nim +++ b/src/app/modules/startup/controller.nim @@ -1,29 +1,51 @@ -import Tables +import Tables, chronicles import controller_interface import io_interface +import status/[signals] +import ../../../app_service/[main] import ../../../app_service/service/accounts/service_interface as accounts_service export controller_interface +logScope: + topics = "startup-controller" + type Controller* = ref object of controller_interface.AccessInterface delegate: io_interface.AccessInterface + appService: AppService accountsService: accounts_service.ServiceInterface proc newController*(delegate: io_interface.AccessInterface, + appService: AppService, accountsService: accounts_service.ServiceInterface): Controller = result = Controller() result.delegate = delegate + result.appService = appService result.accountsService = accountsService method delete*(self: Controller) = discard method init*(self: Controller) = - discard + self.appService.status.events.on(SignalType.NodeLogin.event) do(e:Args): + let signal = NodeSignal(e) + if signal.event.error == "": + self.delegate.userLoggedIn() + else: + error "error: ", methodName="init", errDesription = "login error " & signal.event.error + + self.appService.status.events.on(SignalType.NodeStopped.event) do(e:Args): + echo "-NEW-EVENT-- NodeStopped: ", repr(e) + #self.status.events.emit("nodeStopped", Args()) + #self.view.onLoggedOut() + + self.appService.status.events.on(SignalType.NodeReady.event) do(e:Args): + echo "-NEW-EVENT-- NodeReady: ", repr(e) + #self.status.events.emit("nodeReady", Args()) method shouldStartWithOnboardingScreen*(self: Controller): bool = return self.accountsService.openedAccounts().len == 0 \ No newline at end of file diff --git a/src/app/modules/startup/io_interface.nim b/src/app/modules/startup/io_interface.nim index 33f2c65652..abd57f2b3e 100644 --- a/src/app/modules/startup/io_interface.nim +++ b/src/app/modules/startup/io_interface.nim @@ -16,4 +16,4 @@ include ./private_interfaces/module_login_delegate_interface type DelegateInterface* = concept c c.startupDidLoad() - c.accountCreated() \ No newline at end of file + c.userLoggedIn() \ No newline at end of file diff --git a/src/app/modules/startup/login/controller.nim b/src/app/modules/startup/login/controller.nim index 3d59a52047..b44a389ca8 100644 --- a/src/app/modules/startup/login/controller.nim +++ b/src/app/modules/startup/login/controller.nim @@ -29,21 +29,25 @@ method delete*(self: Controller) = discard method init*(self: Controller) = - self.appService.status.events.on(SignalType.NodeStopped.event) do(e:Args): - echo "-NEW-LOGIN-- NodeStopped: ", repr(e) - #self.status.events.emit("nodeStopped", Args()) - #self.view.onLoggedOut() - - self.appService.status.events.on(SignalType.NodeReady.event) do(e:Args): - echo "-NEW-LOGIN-- NodeReady: ", repr(e) - #self.status.events.emit("nodeReady", Args()) - self.appService.status.events.on(SignalType.NodeLogin.event) do(e:Args): - echo "-NEW-LOGIN-- NodeLogin: ", repr(e) - #self.handleNodeLogin(NodeSignal(e)) + let signal = NodeSignal(e) + if signal.event.error != "": + self.delegate.loginAccountError(signal.event.error) method getOpenedAccounts*(self: Controller): seq[AccountDto] = return self.accountsService.openedAccounts() method setSelectedAccountKeyUid*(self: Controller, keyUid: string) = - self.selectedAccountKeyUid = keyUid \ No newline at end of file + self.selectedAccountKeyUid = keyUid + +method login*(self: Controller, password: string) = + let openedAccounts = self.getOpenedAccounts() + var selectedAccount: AccountDto + for acc in openedAccounts: + if(acc.keyUid == self.selectedAccountKeyUid): + selectedAccount = acc + break + + let error = self.accountsService.login(selectedAccount, password) + if(error.len > 0): + self.delegate.loginAccountError(error) \ No newline at end of file diff --git a/src/app/modules/startup/login/controller_interface.nim b/src/app/modules/startup/login/controller_interface.nim index a7a17980ac..cffa5f7bb3 100644 --- a/src/app/modules/startup/login/controller_interface.nim +++ b/src/app/modules/startup/login/controller_interface.nim @@ -14,4 +14,7 @@ method getOpenedAccounts*(self: AccessInterface): seq[AccountDto] {.base.} = raise newException(ValueError, "No implementation available") method setSelectedAccountKeyUid*(self: AccessInterface, keyUid: string) {.base.} = + raise newException(ValueError, "No implementation available") + +method login*(self: AccessInterface, password: string) {.base.} = raise newException(ValueError, "No implementation available") \ No newline at end of file diff --git a/src/app/modules/startup/login/module.nim b/src/app/modules/startup/login/module.nim index 94ebd618a6..362d425e36 100644 --- a/src/app/modules/startup/login/module.nim +++ b/src/app/modules/startup/login/module.nim @@ -72,4 +72,10 @@ method viewDidLoad*(self: Module) = method setSelectedAccount*(self: Module, item: Item) = self.controller.setSelectedAccountKeyUid(item.getKeyUid()) - self.view.setSelectedAccount(item) \ No newline at end of file + self.view.setSelectedAccount(item) + +method login*(self: Module, password: string) = + self.controller.login(password) + +method loginAccountError*(self: Module, error: string) = + self.view.loginAccountError(error) \ No newline at end of file diff --git a/src/app/modules/startup/login/private_interfaces/module_controller_delegate_interface.nim b/src/app/modules/startup/login/private_interfaces/module_controller_delegate_interface.nim index e69de29bb2..32562ac920 100644 --- a/src/app/modules/startup/login/private_interfaces/module_controller_delegate_interface.nim +++ b/src/app/modules/startup/login/private_interfaces/module_controller_delegate_interface.nim @@ -0,0 +1,2 @@ +method loginAccountError*(self: AccessInterface, error: string) {.base.} = + raise newException(ValueError, "No implementation available") \ No newline at end of file diff --git a/src/app/modules/startup/login/private_interfaces/module_view_delegate_interface.nim b/src/app/modules/startup/login/private_interfaces/module_view_delegate_interface.nim index 3f6bc59a36..f994a1c00d 100644 --- a/src/app/modules/startup/login/private_interfaces/module_view_delegate_interface.nim +++ b/src/app/modules/startup/login/private_interfaces/module_view_delegate_interface.nim @@ -4,4 +4,7 @@ method viewDidLoad*(self: AccessInterface) {.base.} = raise newException(ValueError, "No implementation available") method setSelectedAccount*(self: AccessInterface, item: Item) {.base.} = + raise newException(ValueError, "No implementation available") + +method login*(self: AccessInterface, password: string) {.base.} = raise newException(ValueError, "No implementation available") \ No newline at end of file diff --git a/src/app/modules/startup/login/view.nim b/src/app/modules/startup/login/view.nim index 5eb3ab7a07..677deabaae 100644 --- a/src/app/modules/startup/login/view.nim +++ b/src/app/modules/startup/login/view.nim @@ -58,4 +58,12 @@ QtObject: QtProperty[QVariant] accountsModel: read = getModel - notify = modelChanged \ No newline at end of file + notify = modelChanged + + proc login*(self: View, password: string) {.slot.} = + self.delegate.login(password) + + proc accountLoginError*(self: View, error: string) {.signal.} + + proc loginAccountError*(self: View, error: string) = + self.accountLoginError(error) \ No newline at end of file diff --git a/src/app/modules/startup/module.nim b/src/app/modules/startup/module.nim index 0cff0ae361..4a0689878e 100644 --- a/src/app/modules/startup/module.nim +++ b/src/app/modules/startup/module.nim @@ -29,7 +29,7 @@ proc newModule*[T](delegate: T, result.delegate = delegate result.view = view.newView(result) result.viewVariant = newQVariant(result.view) - result.controller = controller.newController(result, accountsService) + result.controller = controller.newController(result, appService, accountsService) # Submodules result.onboardingModule = onboarding_module.newModule(result, appService, accountsService) @@ -73,8 +73,8 @@ method onboardingDidLoad*[T](self: Module[T]) = method loginDidLoad*[T](self: Module[T]) = self.checkIfModuleDidLoad() -method accountCreated*[T](self: Module[T]) = - self.delegate.accountCreated() +method userLoggedIn*[T](self: Module[T]) = + self.delegate.userLoggedIn() method moveToAppState*[T](self: Module[T]) = self.view.setAppState(AppState.MainAppState) \ No newline at end of file diff --git a/src/app/modules/startup/onboarding/controller.nim b/src/app/modules/startup/onboarding/controller.nim index d2ddc14111..521c707b23 100644 --- a/src/app/modules/startup/onboarding/controller.nim +++ b/src/app/modules/startup/onboarding/controller.nim @@ -35,12 +35,8 @@ method delete*(self: Controller) = method init*(self: Controller) = self.appService.status.events.on(SignalType.NodeLogin.event) do(e:Args): let signal = NodeSignal(e) - echo "-NEW-ONBOARDING-- OnNodeLoginEvent: ", repr(signal) - if signal.event.error == "": - echo "-NEW-ONBOARDING-- OnNodeLoginEventA: ", repr(signal.event.error) - self.delegate.accountCreated() - else: - error "error: ", methodName="init", errDesription = "onboarding login error " & signal.event.error + if signal.event.error != "": + self.delegate.setupAccountError() method getGeneratedAccounts*(self: Controller): seq[GeneratedAccountDto] = return self.accountsService.generatedAccounts() diff --git a/src/app/modules/startup/onboarding/module.nim b/src/app/modules/startup/onboarding/module.nim index 4ed83bcfe1..92507109de 100644 --- a/src/app/modules/startup/onboarding/module.nim +++ b/src/app/modules/startup/onboarding/module.nim @@ -60,9 +60,6 @@ method setSelectedAccountByIndex*(self: Module, index: int) = method storeSelectedAccountAndLogin*(self: Module, password: string) = self.controller.storeSelectedAccountAndLogin(password) -method accountCreated*(self: Module) = - self.delegate.accountCreated() - method setupAccountError*(self: Module) = self.view.setupAccountError() diff --git a/src/app/modules/startup/onboarding/private_interfaces/module_controller_delegate_interface.nim b/src/app/modules/startup/onboarding/private_interfaces/module_controller_delegate_interface.nim index c91c8335e6..9dbd7c826e 100644 --- a/src/app/modules/startup/onboarding/private_interfaces/module_controller_delegate_interface.nim +++ b/src/app/modules/startup/onboarding/private_interfaces/module_controller_delegate_interface.nim @@ -1,6 +1,3 @@ -method accountCreated*(self: AccessInterface) {.base.} = - raise newException(ValueError, "No implementation available") - method setupAccountError*(self: AccessInterface) {.base.} = raise newException(ValueError, "No implementation available") diff --git a/src/app/modules/startup/onboarding/view.nim b/src/app/modules/startup/onboarding/view.nim index a056d3c0e6..d9fae33e75 100644 --- a/src/app/modules/startup/onboarding/view.nim +++ b/src/app/modules/startup/onboarding/view.nim @@ -80,7 +80,9 @@ QtObject: proc accountImportError*(self: View) {.signal.} proc importAccountError*(self: View) = - self.accountImportError() # In QML we can connect to this signal and notify a user + # In QML we can connect to this signal and notify a user + # before refactoring we didn't have this signal + self.accountImportError() proc importAccountSuccess*(self: View) = self.importedAccountChanged() diff --git a/src/app/modules/startup/private_interfaces/module_controller_delegate_interface.nim b/src/app/modules/startup/private_interfaces/module_controller_delegate_interface.nim index e69de29bb2..58295a2bd4 100644 --- a/src/app/modules/startup/private_interfaces/module_controller_delegate_interface.nim +++ b/src/app/modules/startup/private_interfaces/module_controller_delegate_interface.nim @@ -0,0 +1,2 @@ +method userLoggedIn*(self: AccessInterface) {.base.} = + raise newException(ValueError, "No implementation available") \ No newline at end of file diff --git a/src/app/modules/startup/private_interfaces/module_onboarding_delegate_interface.nim b/src/app/modules/startup/private_interfaces/module_onboarding_delegate_interface.nim index dcd2bc1bcc..818422c1ae 100644 --- a/src/app/modules/startup/private_interfaces/module_onboarding_delegate_interface.nim +++ b/src/app/modules/startup/private_interfaces/module_onboarding_delegate_interface.nim @@ -1,5 +1,2 @@ method onboardingDidLoad*(self: AccessInterface) {.base.} = - raise newException(ValueError, "No implementation available") - -method accountCreated*(self: AccessInterface) {.base.} = raise newException(ValueError, "No implementation available") \ No newline at end of file diff --git a/src/app_service/service/accounts/dto/accounts.nim b/src/app_service/service/accounts/dto/accounts.nim index 47c0c1be0a..68608cefac 100644 --- a/src/app_service/service/accounts/dto/accounts.nim +++ b/src/app_service/service/accounts/dto/accounts.nim @@ -44,5 +44,6 @@ proc toAccountDto*(jsonObj: JsonNode): AccountDto = discard jsonObj.getProp("key-uid", result.keyUid) var imagesObj: JsonNode - if(jsonObj.getProp("images", imagesObj)): - result.images.add(toImage(imagesObj)) \ No newline at end of file + if(jsonObj.getProp("images", imagesObj) and imagesObj.kind == JArray): + for imgObj in imagesObj: + result.images.add(toImage(imgObj)) \ No newline at end of file diff --git a/src/app_service/service/accounts/service.nim b/src/app_service/service/accounts/service.nim index 66755ed557..2221cb19fb 100644 --- a/src/app_service/service/accounts/service.nim +++ b/src/app_service/service/accounts/service.nim @@ -1,4 +1,5 @@ -import Tables, json, sequtils, strutils, strformat, uuids, chronicles +import Tables, json, sequtils, strutils, strformat, uuids +import json_serialization, chronicles import service_interface import ./dto/accounts @@ -282,4 +283,31 @@ method importMnemonic*(self: Service, mnemonic: string): bool = except Exception as e: error "error: ", methodName="importMnemonic", errName = e.name, errDesription = e.msg - return false \ No newline at end of file + return false + +method login*(self: Service, account: AccountDto, password: string): string = + try: + let hashedPassword = hashString(password) + var thumbnailImage: string + var largeImage: string + for img in account.images: + if(img.imgType == "thumbnail"): + thumbnailImage = img.uri + elif(img.imgType == "large"): + largeImage = img.uri + + let response = status_go.login(account.name, account.keyUid, hashedPassword, + account.identicon, thumbnailImage, largeImage) + + var error = "response doesn't contain \"error\"" + if(response.result.contains("error")): + error = response.result["error"].getStr + if error == "": + debug "Account logged in" + self.loggedInAccount = account + + return error + + except Exception as e: + error "error: ", methodName="setupAccount", errName = e.name, errDesription = e.msg + return 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 39d190d4ab..ea2af5d623 100644 --- a/src/app_service/service/accounts/service_interface.nim +++ b/src/app_service/service/accounts/service_interface.nim @@ -44,4 +44,8 @@ method validateMnemonic*(self: ServiceInterface, mnemonic: string): raise newException(ValueError, "No implementation available") method importMnemonic*(self: ServiceInterface, mnemonic: string): bool {.base.} = + raise newException(ValueError, "No implementation available") + +method login*(self: ServiceInterface, account: AccountDto, password: string): + string {.base.} = raise newException(ValueError, "No implementation available") \ No newline at end of file diff --git a/ui/app/AppLayouts/Chat/ChatLayout.qml b/ui/app/AppLayouts/Chat/ChatLayout.qml index 7348d2342f..9d1331bdc9 100644 --- a/ui/app/AppLayouts/Chat/ChatLayout.qml +++ b/ui/app/AppLayouts/Chat/ChatLayout.qml @@ -164,24 +164,14 @@ StatusAppThreePanelLayout { sourceComponent: appSettings.communitiesEnabled && root.rootStore.chatsModelInst.communities.activeCommunity.active ? communtiyColumnComponent : contactsColumnComponent } -// centerPanel: ChatColumn { -// id: chatColumn -// chatGroupsListViewCount: contactColumnLoader.item.chatGroupsListViewCount -// } - - centerPanel: Rectangle { + centerPanel: ChatColumn { id: chatColumn - anchors.fill: parent - color: "green" + chatGroupsListViewCount: contactColumnLoader.item.chatGroupsListViewCount } showRightPanel: (appSettings.expandUsersList && (appSettings.showOnlineUsers || chatsModel.communities.activeCommunity.active) && (chatsModel.channelView.activeChannel.chatType !== Constants.chatTypeOneToOne)) - //rightPanel: appSettings.communitiesEnabled && chatsModel.communities.activeCommunity.active ? communityUserListComponent : userListComponent - rightPanel: Rectangle { - anchors.fill: parent - color: "blue" - } + rightPanel: appSettings.communitiesEnabled && chatsModel.communities.activeCommunity.active ? communityUserListComponent : userListComponent Component { id: communityUserListComponent diff --git a/ui/app/AppLayouts/Onboarding/shared/CreatePasswordModal.qml b/ui/app/AppLayouts/Onboarding/shared/CreatePasswordModal.qml index f926cc990e..5f50fc3bd4 100644 --- a/ui/app/AppLayouts/Onboarding/shared/CreatePasswordModal.qml +++ b/ui/app/AppLayouts/Onboarding/shared/CreatePasswordModal.qml @@ -160,7 +160,9 @@ ModalPopup { if (storingPasswordModal) { accountSettings.storeToKeychain = Constants.storeToKeychainValueStore - loginModel.storePassword(profileModel.profile.username, repeatPasswordField.text) + // NEED TO HANDLE IT + // This part should be done via PrivacyAndSecurity submodule section of ProfileSection module +// loginModel.storePassword(profileModel.profile.username, repeatPasswordField.text) popup.close() } else diff --git a/ui/app/AppLayouts/Onboarding/views/LoginView.qml b/ui/app/AppLayouts/Onboarding/views/LoginView.qml index 8280a00f07..94da9a7da0 100644 --- a/ui/app/AppLayouts/Onboarding/views/LoginView.qml +++ b/ui/app/AppLayouts/Onboarding/views/LoginView.qml @@ -227,25 +227,23 @@ Item { } } - // NEED TO HANDLE IT -// Connections { -// target: LoginStore.loginModelInst -// ignoreUnknownSignals: true -// onLoginResponseChanged: { -// if (error) { -// // SQLITE_NOTADB: "file is not a database" -// if (error === "file is not a database") { -// errMsg.text = errMsg.incorrectPasswordMsg -// } else { -// //% "Login failed: %1" -// errMsg.text = qsTrId("login-failed---1").arg(error.toUpperCase()) -// } -// errMsg.visible = true -// loading = false -// txtPassword.textField.forceActiveFocus() -// } -// } -// } + Connections { + target: LoginStore.loginModul + onAccountLoginError: { + if (error) { + // SQLITE_NOTADB: "file is not a database" + if (error === "file is not a database") { + errMsg.text = errMsg.incorrectPasswordMsg + } else { + //% "Login failed: %1" + errMsg.text = qsTrId("login-failed---1").arg(error.toUpperCase()) + } + errMsg.visible = true + loading = false + txtPassword.textField.forceActiveFocus() + } + } + } StatusQControls.StatusFlatButton { id: generateKeysLinkText diff --git a/ui/main.qml b/ui/main.qml index 92155fe177..725ae64b75 100644 --- a/ui/main.qml +++ b/ui/main.qml @@ -320,7 +320,8 @@ StatusWindow { onConfirmButtonClicked: { accountSettings.storeToKeychain = Constants.storeToKeychainValueStore - loginModel.storePassword(username, password) + // This is need to be handled using KeyChain service via LoginModule +// loginModel.storePassword(username, password) finish() }