diff --git a/src/app/modules/main/controller.nim b/src/app/modules/main/controller.nim index ee9ad750e1..537dcb1000 100644 --- a/src/app/modules/main/controller.nim +++ b/src/app/modules/main/controller.nim @@ -390,7 +390,8 @@ proc init*(self: Controller) = password: args.password, pin: args.pin, keyUid: args.keyUid, - keycardUid: args.keycardUid) + keycardUid: args.keycardUid, + additinalPathsDetails: args.additinalPathsDetails) self.authenticateUserFlowRequestedBy = "" self.events.emit(SIGNAL_SHARED_KEYCARD_MODULE_USER_AUTHENTICATED, data) @@ -404,7 +405,7 @@ proc init*(self: Controller) = self.events.on(SIGNAL_SHARED_KEYCARD_MODULE_AUTHENTICATE_USER) do(e: Args): let args = SharedKeycarModuleAuthenticationArgs(e) self.authenticateUserFlowRequestedBy = args.uniqueIdentifier - self.delegate.runAuthenticationPopup(args.keyUid) + self.delegate.runAuthenticationPopup(args.keyUid, args.additionalBip44Paths) self.events.on(SIGNAL_SHARED_KEYCARD_MODULE_TRY_KEYCARD_SYNC) do(e: Args): let args = SharedKeycarModuleArgs(e) diff --git a/src/app/modules/main/io_interface.nim b/src/app/modules/main/io_interface.nim index c7f7716554..6edd807055 100644 --- a/src/app/modules/main/io_interface.nim +++ b/src/app/modules/main/io_interface.nim @@ -185,11 +185,11 @@ method osNotificationClicked*(self: AccessInterface, details: NotificationDetail method displayWindowsOsNotification*(self: AccessInterface, title: string, message: string) {.base.} = raise newException(ValueError, "No implementation available") -method displayEphemeralNotification*(self: AccessInterface, title: string, subTitle: string, details: NotificationDetails) +method displayEphemeralNotification*(self: AccessInterface, title: string, subTitle: string, details: NotificationDetails) {.base.} = raise newException(ValueError, "No implementation available") -method displayEphemeralNotification*(self: AccessInterface, title: string, subTitle: string, icon: string, loading: bool, +method displayEphemeralNotification*(self: AccessInterface, title: string, subTitle: string, icon: string, loading: bool, ephNotifType: int, url: string, details = NotificationDetails()) {.base.} = raise newException(ValueError, "No implementation available") @@ -257,7 +257,7 @@ method switchTo*(self: AccessInterface, sectionId, chatId: string) {.base.} = method isConnected*(self: AccessInterface): bool {.base.} = raise newException(ValueError, "No implementation available") -method onStatusUrlRequested*(self: AccessInterface, action: StatusUrlAction, communityId: string, chatId: string, +method onStatusUrlRequested*(self: AccessInterface, action: StatusUrlAction, communityId: string, chatId: string, url: string, userId: string) {.base.} = raise newException(ValueError, "No implementation available") @@ -269,13 +269,13 @@ method getKeycardSharedModule*(self: AccessInterface): QVariant {.base.} = method onDisplayKeycardSharedModuleFlow*(self: AccessInterface) {.base.} = raise newException(ValueError, "No implementation available") - + method onSharedKeycarModuleFlowTerminated*(self: AccessInterface, lastStepInTheCurrentFlow: bool) {.base.} = raise newException(ValueError, "No implementation available") -method runAuthenticationPopup*(self: AccessInterface, keyUid: string) {.base.} = +method runAuthenticationPopup*(self: AccessInterface, keyUid: string, bip44Paths: seq[string] = @[]) {.base.} = raise newException(ValueError, "No implementation available") - + method onMyRequestAdded*(self: AccessInterface) {.base.} = raise newException(ValueError, "No implementation available") diff --git a/src/app/modules/main/module.nim b/src/app/modules/main/module.nim index 7ed212b0ca..8b42edb037 100644 --- a/src/app/modules/main/module.nim +++ b/src/app/modules/main/module.nim @@ -578,7 +578,7 @@ method onChannelGroupsLoaded*[T]( self.view.model().addItem(channelGroupItem) if activeSectionId == channelGroupItem.id: activeSection = channelGroupItem - + self.channelGroupModules[channelGroup.id].load(channelGroup, events, settingsService, nodeConfigurationService, contactsService, chatService, communityService, messageService, gifService, mailserversService) @@ -983,7 +983,7 @@ method resolvedENS*[T](self: Module[T], publicKey: string, address: string, uuid if(reason.len > 0 and publicKey.len == 0): self.displayEphemeralNotification("Unexisting contact", "Wrong public key or ens name", "", false, EphemeralNotificationType.Default.int, "") return - + if(reason == STATUS_URL_ENS_RESOLVE_REASON & $StatusUrlAction.DisplayUserProfile): self.view.emitDisplayUserProfileSignal(publicKey) else: @@ -1084,7 +1084,7 @@ method newCommunityMembershipRequestReceived*[T](self: Module[T], membershipRequ method meMentionedCountChanged*[T](self: Module[T], allMentions: int) = singletonInstance.globalEvents.meMentionedIconBadgeNotification(allMentions) -method displayEphemeralNotification*[T](self: Module[T], title: string, subTitle: string, icon: string, loading: bool, +method displayEphemeralNotification*[T](self: Module[T], title: string, subTitle: string, icon: string, loading: bool, ephNotifType: int, url: string, details = NotificationDetails()) = let now = getTime() let id = now.toUnix * 1000000000 + now.nanosecond @@ -1096,7 +1096,7 @@ method displayEphemeralNotification*[T](self: Module[T], title: string, subTitle self.view.ephemeralNotificationModel().addItem(item) method displayEphemeralNotification*[T](self: Module[T], title: string, subTitle: string, details: NotificationDetails) = - if(details.notificationType == NotificationType.NewMessage or + if(details.notificationType == NotificationType.NewMessage or details.notificationType == NotificationType.NewMessageWithPersonalMention or details.notificationType == NotificationType.CommunityTokenPermissionCreated or details.notificationType == NotificationType.CommunityTokenPermissionUpdated or @@ -1106,8 +1106,8 @@ method displayEphemeralNotification*[T](self: Module[T], title: string, subTitle details.notificationType == NotificationType.CommunityTokenPermissionDeletionFailed or details.notificationType == NotificationType.NewMessageWithGlobalMention): self.displayEphemeralNotification(title, subTitle, "", false, EphemeralNotificationType.Default.int, "", details) - - elif(details.notificationType == NotificationType.NewContactRequest or + + elif(details.notificationType == NotificationType.NewContactRequest or details.notificationType == NotificationType.IdentityVerificationRequest): self.displayEphemeralNotification(title, subTitle, "contact", false, EphemeralNotificationType.Default.int, "", details) @@ -1121,7 +1121,7 @@ method ephemeralNotificationClicked*[T](self: Module[T], id: int64) = let item = self.view.ephemeralNotificationModel().getItemWithId(id) if(item.details.isEmpty()): return - if(item.details.notificationType == NotificationType.NewMessage or + if(item.details.notificationType == NotificationType.NewMessage or item.details.notificationType == NotificationType.NewMessageWithPersonalMention or item.details.notificationType == NotificationType.NewMessageWithGlobalMention): self.controller.switchTo(item.details.sectionId, item.details.chatId, item.details.messageId) @@ -1135,9 +1135,9 @@ proc getCommunityIdFromFullChatId(fullChatId: string): string = const communityIdLength = 68 return fullChatId.substr(0, communityIdLength-1) -method onStatusUrlRequested*[T](self: Module[T], action: StatusUrlAction, communityId: string, chatId: string, +method onStatusUrlRequested*[T](self: Module[T], action: StatusUrlAction, communityId: string, chatId: string, url: string, userId: string) = - + if(action == StatusUrlAction.DisplayUserProfile): self.resolveENS(userId, "", STATUS_URL_ENS_RESOLVE_REASON & $StatusUrlAction.DisplayUserProfile) @@ -1181,8 +1181,8 @@ method getKeycardSharedModule*[T](self: Module[T]): QVariant = return self.keycardSharedModule.getModuleAsVariant() proc createSharedKeycardModule[T](self: Module[T]) = - self.keycardSharedModule = keycard_shared_module.newModule[Module[T]](self, UNIQUE_MAIN_MODULE_IDENTIFIER, - self.events, self.keycardService, self.settingsService, self.networkService, self.privacyService, self.accountsService, + self.keycardSharedModule = keycard_shared_module.newModule[Module[T]](self, UNIQUE_MAIN_MODULE_IDENTIFIER, + self.events, self.keycardService, self.settingsService, self.networkService, self.privacyService, self.accountsService, self.walletAccountService, self.keychainService) method onSharedKeycarModuleFlowTerminated*[T](self: Module[T], lastStepInTheCurrentFlow: bool) = @@ -1191,11 +1191,11 @@ method onSharedKeycarModuleFlowTerminated*[T](self: Module[T], lastStepInTheCurr self.keycardSharedModule.delete self.keycardSharedModule = nil -method runAuthenticationPopup*[T](self: Module[T], keyUid: string) = +method runAuthenticationPopup*[T](self: Module[T], keyUid: string, bip44Paths: seq[string] = @[]) = self.createSharedKeycardModule() if self.keycardSharedModule.isNil: return - self.keycardSharedModule.runFlow(keycard_shared_module.FlowType.Authentication, keyUid) + self.keycardSharedModule.runFlow(keycard_shared_module.FlowType.Authentication, keyUid, bip44Paths) method onSharedKeycarModuleKeycardSyncPurposeTerminated*[T](self: Module[T], lastStepInTheCurrentFlow: bool) = if not self.keycardSharedModuleKeycardSyncPurpose.isNil: @@ -1203,8 +1203,8 @@ method onSharedKeycarModuleKeycardSyncPurposeTerminated*[T](self: Module[T], las self.keycardSharedModuleKeycardSyncPurpose = nil method tryKeycardSync*[T](self: Module[T], keyUid: string, pin: string) = - self.keycardSharedModuleKeycardSyncPurpose = keycard_shared_module.newModule[Module[T]](self, UNIQUE_MAIN_MODULE_KEYCARD_SYNC_IDENTIFIER, - self.events, self.keycardService, self.settingsService, self.networkService, self.privacyService, self.accountsService, + self.keycardSharedModuleKeycardSyncPurpose = keycard_shared_module.newModule[Module[T]](self, UNIQUE_MAIN_MODULE_KEYCARD_SYNC_IDENTIFIER, + self.events, self.keycardService, self.settingsService, self.networkService, self.privacyService, self.accountsService, self.walletAccountService, self.keychainService) if self.keycardSharedModuleKeycardSyncPurpose.isNil: return diff --git a/src/app/modules/main/profile_section/devices/controller.nim b/src/app/modules/main/profile_section/devices/controller.nim index 67bf196ada..f47b912d69 100644 --- a/src/app/modules/main/profile_section/devices/controller.nim +++ b/src/app/modules/main/profile_section/devices/controller.nim @@ -1,13 +1,13 @@ import Tables, chronicles import io_interface -import ../../../../core/eventemitter -import ../../../../../app_service/service/settings/service as settings_service -import ../../../../../app_service/service/devices/service as devices_service +import app/core/eventemitter +import app_service/service/settings/service as settings_service +import app_service/service/devices/service as devices_service -import ../../../shared_modules/keycard_popup/io_interface as keycard_shared_module +import app/modules/shared_modules/keycard_popup/io_interface as keycard_shared_module -const UNIQUE_SYNCING_SECTION_ACCOUNTS_MODULE_AUTH_IDENTIFIER* = "SyncingSection-AccountsModule-Authentication" +const UNIQUE_SYNCING_LOGGED_IN_USER_AUTHENTICATION_IDENTIFIER* = "Syncing-LoggedInUser-Authentication" logScope: topics = "profile-section-devices-module-controller" @@ -43,16 +43,16 @@ proc init*(self: Controller) = self.events.on(SIGNAL_UPDATE_DEVICE) do(e: Args): let args = UpdateInstallationArgs(e) self.delegate.updateOrAddDevice(args.installation) - + self.events.on(SIGNAL_INSTALLATION_NAME_UPDATED) do(e: Args): let args = UpdateInstallationNameArgs(e) self.delegate.updateInstallationName(args.installationId, args.name) - + self.events.on(SIGNAL_SHARED_KEYCARD_MODULE_USER_AUTHENTICATED) do(e: Args): let args = SharedKeycarModuleArgs(e) - if args.uniqueIdentifier != UNIQUE_SYNCING_SECTION_ACCOUNTS_MODULE_AUTH_IDENTIFIER: + if args.uniqueIdentifier != UNIQUE_SYNCING_LOGGED_IN_USER_AUTHENTICATION_IDENTIFIER: return - self.delegate.onUserAuthenticated(args.pin, args.password, args.keyUid) + self.delegate.onLoggedInUserAuthenticated(args.pin, args.password, args.keyUid, args.additinalPathsDetails) self.events.on(SIGNAL_LOCAL_PAIRING_EVENT) do(e: Args): let args = LocalPairingEventArgs(e) @@ -91,10 +91,11 @@ proc enableDevice*(self: Controller, deviceId: string, enable: bool) = # Pairing status # -proc authenticateUser*(self: Controller, keyUid: string) = - let data = SharedKeycarModuleAuthenticationArgs( - uniqueIdentifier: UNIQUE_SYNCING_SECTION_ACCOUNTS_MODULE_AUTH_IDENTIFIER, - keyUid: keyUid) +proc authenticateLoggedInUser*(self: Controller, additionalBip44Paths: seq[string] = @[]) = + var data = SharedKeycarModuleAuthenticationArgs( + uniqueIdentifier: UNIQUE_SYNCING_LOGGED_IN_USER_AUTHENTICATION_IDENTIFIER, + additionalBip44Paths: additionalBip44Paths + ) self.events.emit(SIGNAL_SHARED_KEYCARD_MODULE_AUTHENTICATE_USER, data) # @@ -104,8 +105,8 @@ proc authenticateUser*(self: Controller, keyUid: string) = proc validateConnectionString*(self: Controller, connectionString: string): string = return self.devicesService.validateConnectionString(connectionString) -proc getConnectionStringForBootstrappingAnotherDevice*(self: Controller, keyUid: string, password: string): string = - return self.devicesService.getConnectionStringForBootstrappingAnotherDevice(keyUid, password) +proc getConnectionStringForBootstrappingAnotherDevice*(self: Controller, password, chatKey: string): string = + return self.devicesService.getConnectionStringForBootstrappingAnotherDevice(password, chatKey) proc inputConnectionStringForBootstrapping*(self: Controller, connectionString: string): string = return self.devicesService.inputConnectionStringForBootstrapping(connectionString) diff --git a/src/app/modules/main/profile_section/devices/io_interface.nim b/src/app/modules/main/profile_section/devices/io_interface.nim index 6ed3c347c4..e1039cdcf5 100644 --- a/src/app/modules/main/profile_section/devices/io_interface.nim +++ b/src/app/modules/main/profile_section/devices/io_interface.nim @@ -1,6 +1,6 @@ -import NimQml -import ../../../../../app_service/service/devices/service - +import NimQml, tables +import app_service/service/devices/service +from app_service/service/keycard/service import KeyDetails type AccessInterface* {.pure inheritable.} = ref object of RootObj @@ -50,18 +50,15 @@ method advertise*(self: AccessInterface) {.base.} = method enableDevice*(self: AccessInterface, installationId: string, enable: bool) {.base.} = raise newException(ValueError, "No implementation available") -method authenticateUser*(self: AccessInterface, keyUid: string) {.base.} = +method authenticateLoggedInUser*(self: AccessInterface) {.base.} = raise newException(ValueError, "No implementation available") -method onUserAuthenticated*(self: AccessInterface, pin: string, password: string, keyUid: string) {.base.} = +method onLoggedInUserAuthenticated*(self: AccessInterface, pin: string, password: string, keyUid: string, additinalPathsDetails: Table[string, KeyDetails]) {.base.} = raise newException(ValueError, "No implementation available") proc validateConnectionString*(self: AccessInterface, connectionString: string): string = raise newException(ValueError, "No implementation available") -method getConnectionStringForBootstrappingAnotherDevice*(self: AccessInterface, keyUid: string, password: string): string {.base.} = - raise newException(ValueError, "No implementation available") - method inputConnectionStringForBootstrapping*(self: AccessInterface, connectionString: string): string {.base.} = raise newException(ValueError, "No implementation available") @@ -69,4 +66,4 @@ method onLocalPairingEvent*(self: AccessInterface, eventType: EventType, action: raise newException(ValueError, "No implementation available") method onLocalPairingStatusUpdate*(self: AccessInterface, status: LocalPairingStatus) {.base.} = - raise newException(ValueError, "No implementation available") \ No newline at end of file + raise newException(ValueError, "No implementation available") diff --git a/src/app/modules/main/profile_section/devices/module.nim b/src/app/modules/main/profile_section/devices/module.nim index 551fa77945..57824e5c31 100644 --- a/src/app/modules/main/profile_section/devices/module.nim +++ b/src/app/modules/main/profile_section/devices/module.nim @@ -1,12 +1,15 @@ -import NimQml, chronicles +import NimQml, tables, strutils, chronicles import io_interface import ../io_interface as delegate_interface import view, controller, model, item import logging -import ../../../../core/eventemitter -import ../../../../../app_service/service/settings/service as settings_service -import ../../../../../app_service/service/devices/service as devices_service +import app/global/global_singleton +import app/core/eventemitter +import app_service/common/account_constants +import app_service/service/settings/service as settings_service +import app_service/service/devices/service as devices_service +from app_service/service/keycard/service import KeyDetails export io_interface @@ -77,7 +80,7 @@ method getModuleAsVariant*(self: Module): QVariant = method setInstallationName*(self: Module, installationId: string, name: string) = self.controller.setInstallationName(installationId, name) - + method syncAllDevices*(self: Module) = self.controller.syncAllDevices() @@ -97,18 +100,25 @@ method updateOrAddDevice*(self: Module, installation: InstallationDto) = method updateInstallationName*(self: Module, installationId: string, name: string) = self.view.model().updateItemName(installationId, name) -method authenticateUser*(self: Module, keyUid: string) = - self.controller.authenticateUser(keyUid) +method authenticateLoggedInUser*(self: Module) = + var additionalBip44Paths: seq[string] + if singletonInstance.userProfile.getIsKeycardUser(): + additionalBip44Paths.add(account_constants.PATH_WHISPER) + self.controller.authenticateLoggedInUser(additionalBip44Paths) -method onUserAuthenticated*(self: Module, pin: string, password: string, keyUid: string) = - self.view.emitUserAuthenticated(pin, password, keyUid) +method onLoggedInUserAuthenticated*(self: Module, pin: string, password: string, keyUid: string, additinalPathsDetails: Table[string, KeyDetails]) = + var chatKey = "" + if singletonInstance.userProfile.getIsKeycardUser() and + additinalPathsDetails.contains(account_constants.PATH_WHISPER): + chatKey = additinalPathsDetails[account_constants.PATH_WHISPER].privateKey + if chatKey.startsWith("0x"): + chatKey = chatKey[2..^1] + let connectionString = self.controller.getConnectionStringForBootstrappingAnotherDevice(password, chatKey) + self.view.openPopupWithConnectionString(connectionString) proc validateConnectionString*(self: Module, connectionString: string): string = return self.controller.validateConnectionString(connectionString) -method getConnectionStringForBootstrappingAnotherDevice*(self: Module, keyUid: string, password: string): string = - return self.controller.getConnectionStringForBootstrappingAnotherDevice(keyUid, password) - method inputConnectionStringForBootstrapping*(self: Module, connectionString: string): string = return self.controller.inputConnectionStringForBootstrapping(connectionString) @@ -116,4 +126,4 @@ method onLocalPairingEvent*(self: Module, eventType: EventType, action: Action, self.view.onLocalPairingEvent(eventType, action, error) method onLocalPairingStatusUpdate*(self: Module, status: LocalPairingStatus) = - self.view.onLocalPairingStatusUpdate(status) \ No newline at end of file + self.view.onLocalPairingStatusUpdate(status) diff --git a/src/app/modules/main/profile_section/devices/view.nim b/src/app/modules/main/profile_section/devices/view.nim index 8b85521418..ee8613ce18 100644 --- a/src/app/modules/main/profile_section/devices/view.nim +++ b/src/app/modules/main/profile_section/devices/view.nim @@ -133,17 +133,15 @@ QtObject: # LocalPairing actions - proc userAuthenticated*(self: View, pin: string, password: string, keyUid: string) {.signal.} - proc emitUserAuthenticated*(self: View, pin: string, password: string, keyUid: string) = - self.userAuthenticated(pin, password, keyUid) - proc authenticateUser*(self: View, keyUid: string) {.slot.} = - self.delegate.authenticateUser(keyUid) + proc openPopupWithConnectionStringSignal*(self: View, rawConnectionString: string) {.signal.} + proc openPopupWithConnectionString*(self: View, rawConnectionString: string) = + self.openPopupWithConnectionStringSignal(rawConnectionString) + + proc authenticateLoggedInUser*(self: View) {.slot.} = + self.delegate.authenticateLoggedInUser() proc validateConnectionString*(self: View, connectionString: string): string {.slot.} = return self.delegate.validateConnectionString(connectionString) - proc getConnectionStringForBootstrappingAnotherDevice*(self: View, keyUid: string, password: string): string {.slot.} = - return self.delegate.getConnectionStringForBootstrappingAnotherDevice(keyUid, password) - proc inputConnectionStringForBootstrapping*(self: View, connectionString: string): string {.slot.} = return self.delegate.inputConnectionStringForBootstrapping(connectionString) diff --git a/src/app/modules/shared_modules/keycard_popup/controller.nim b/src/app/modules/shared_modules/keycard_popup/controller.nim index e29b07ff9e..b6f00a198a 100644 --- a/src/app/modules/shared_modules/keycard_popup/controller.nim +++ b/src/app/modules/shared_modules/keycard_popup/controller.nim @@ -1,4 +1,4 @@ -import chronicles, strutils, os, sequtils, sugar +import chronicles, tables, strutils, os, sequtils, sugar import uuids import io_interface @@ -66,6 +66,7 @@ type tmpKeycardCopyDestinationKeycardUid: string tmpKeycardSyncingInProgress: bool tmpFlowData: SharedKeycarModuleFlowTerminatedArgs + tmpRequestedPathsAlongWithAuthentication: seq[string] tmpUnlockUsingSeedPhrase: bool # true - sp, false - puk proc newController*(delegate: io_interface.AccessInterface, @@ -182,7 +183,7 @@ proc init*(self: Controller, fullConnect = true) = self.tmpAddingMigratedKeypairSuccess = args.success self.delegate.onSecondaryActionClicked() self.connectionIds.add(handlerId) - + handlerId = self.events.onWithUUID(SIGNAL_CONVERTING_PROFILE_KEYPAIR) do(e: Args): let args = ResultArgs(e) self.tmpConvertingProfileSuccess = args.success @@ -445,8 +446,8 @@ proc cancelCurrentFlow*(self: Controller) = if not serviceApplicable(self.keycardService): return self.keycardService.cancelCurrentFlow() - # in most cases we're running another flow after canceling the current one, - # this way we're giving to the keycard some time to cancel the current flow + # in most cases we're running another flow after canceling the current one, + # this way we're giving to the keycard some time to cancel the current flow sleep(200) proc runGetAppInfoFlow*(self: Controller, factoryReset = false) = @@ -497,9 +498,9 @@ proc runDeriveAccountFlow*(self: Controller, bip44Paths: seq[string], pin: strin self.cancelCurrentFlow() self.keycardService.startExportPublicFlow(bip44Paths, exportMasterAddr=true, exportPrivateAddr=false, pin) -proc runAuthenticationFlow*(self: Controller, keyUid = "") = - ## For signing a transaction we need to provide a key uid of a keypair that an account we want to sign a transaction - ## for belongs to. If we're just doing an authentication for a logged in user, then default key uid is always the key +proc runAuthenticationFlow*(self: Controller, keyUid = "", bip44Paths: seq[string] = @[]) = + ## For signing a transaction we need to provide a key uid of a keypair that an account we want to sign a transaction + ## for belongs to. If we're just doing an authentication for a logged in user, then default key uid is always the key ## uid of the logged in user. if not serviceApplicable(self.keycardService): return @@ -507,7 +508,11 @@ proc runAuthenticationFlow*(self: Controller, keyUid = "") = if self.tmpKeyUidWhichIsBeingAuthenticating.len == 0: self.tmpKeyUidWhichIsBeingAuthenticating = singletonInstance.userProfile.getKeyUid() self.cancelCurrentFlow() - self.keycardService.startExportPublicFlow(path = account_constants.PATH_ENCRYPTION) + self.tmpRequestedPathsAlongWithAuthentication = @[account_constants.PATH_ENCRYPTION] #order is important, when reading keycard response + if bip44Paths.len > 0: + self.tmpRequestedPathsAlongWithAuthentication.add(bip44Paths) + self.tmpRequestedPathsAlongWithAuthentication = self.tmpRequestedPathsAlongWithAuthentication.deduplicate() + self.keycardService.startExportPublicFlow(self.tmpRequestedPathsAlongWithAuthentication, exportMasterAddr = false, exportPrivateAddr = true) proc runLoadAccountFlow*(self: Controller, seedPhraseLength = 0, seedPhrase = "", pin = "", puk = "", factoryReset = false) = if not serviceApplicable(self.keycardService): @@ -577,12 +582,21 @@ proc terminateCurrentFlow*(self: Controller, lastStepInTheCurrentFlow: bool) = self.tmpFlowData = SharedKeycarModuleFlowTerminatedArgs(uniqueIdentifier: self.uniqueIdentifier, lastStepInTheCurrentFlow: lastStepInTheCurrentFlow) if lastStepInTheCurrentFlow: - let exportedEncryptionPubKey = flowEvent.generatedWalletAccount.publicKey - if exportedEncryptionPubKey.len > 0: - self.tmpFlowData.password = exportedEncryptionPubKey - self.tmpFlowData.pin = self.getPin() - self.tmpFlowData.keyUid = flowEvent.keyUid - self.tmpFlowData.keycardUid = flowEvent.instanceUID + var exportedEncryptionPubKey: string + if flowEvent.generatedWalletAccounts.len > 0: + exportedEncryptionPubKey = flowEvent.generatedWalletAccounts[0].publicKey # encryption key is at position 0 + if exportedEncryptionPubKey.len > 0: + self.tmpFlowData.password = exportedEncryptionPubKey + self.tmpFlowData.pin = self.getPin() + self.tmpFlowData.keyUid = flowEvent.keyUid + self.tmpFlowData.keycardUid = flowEvent.instanceUID + for i in 0..< self.tmpRequestedPathsAlongWithAuthentication.len: + var path = self.tmpRequestedPathsAlongWithAuthentication[i] + self.tmpFlowData.additinalPathsDetails[path] = KeyDetails( + address: flowEvent.generatedWalletAccounts[i].address, + publicKey: flowEvent.generatedWalletAccounts[i].publicKey, + privateKey: flowEvent.generatedWalletAccounts[i].privateKey + ) else: self.tmpFlowData.password = self.getPassword() self.tmpFlowData.keyUid = singletonInstance.userProfile.getKeyUid() @@ -592,9 +606,9 @@ proc terminateCurrentFlow*(self: Controller, lastStepInTheCurrentFlow: bool) = ## - the keycard syncing is not already in progress ## - the flow which is terminating is one of the flows which we need to perform a sync process for ## - the pin is known - if self.uniqueIdentifier != startup_io.UNIQUE_STARTUP_MODULE_IDENTIFIER and - not self.keycardSyncingInProgress() and - not utils.arrayContains(FlowsWeShouldNotTryAKeycardSyncFor, flowType) and + if self.uniqueIdentifier != startup_io.UNIQUE_STARTUP_MODULE_IDENTIFIER and + not self.keycardSyncingInProgress() and + not utils.arrayContains(FlowsWeShouldNotTryAKeycardSyncFor, flowType) and self.getPin().len == PINLengthForStatusApp and flowEvent.keyUid.len > 0: let dataForKeycardToSync = SharedKeycarModuleArgs(pin: self.getPin(), keyUid: flowEvent.keyUid) @@ -602,7 +616,7 @@ proc terminateCurrentFlow*(self: Controller, lastStepInTheCurrentFlow: bool) = self.connectKeycardSyncSignal() self.events.emit(SIGNAL_SHARED_KEYCARD_MODULE_TRY_KEYCARD_SYNC, dataForKeycardToSync) return - self.finishFlowTermination() + self.finishFlowTermination() proc authenticateUser*(self: Controller, keyUid = "") = self.disconnectKeycardReponseSignal() @@ -695,16 +709,16 @@ proc updateKeycardUid*(self: Controller, keyUid: string, keycardUid: string) = proc addWalletAccount*(self: Controller, name, address, path, publicKey, keyUid, accountType, colorId, emoji: string): bool = if not serviceApplicable(self.walletAccountService): return false - let err = self.walletAccountService.addWalletAccount(password = "", doPasswordHashing = false, name, address, path, + let err = self.walletAccountService.addWalletAccount(password = "", doPasswordHashing = false, name, address, path, publicKey, keyUid, accountType, colorId, emoji) if err.len > 0: info "adding wallet account failed", name=name, path=path return false return true -proc addNewSeedPhraseKeypair*(self: Controller, seedPhrase, keyUid, keypairName, rootWalletMasterKey: string, +proc addNewSeedPhraseKeypair*(self: Controller, seedPhrase, keyUid, keypairName, rootWalletMasterKey: string, accounts: seq[WalletAccountDto]): bool = - let err = self.walletAccountService.addNewSeedPhraseKeypair(seedPhrase, password = "", doPasswordHashing = false, keyUid, + let err = self.walletAccountService.addNewSeedPhraseKeypair(seedPhrase, password = "", doPasswordHashing = false, keyUid, keypairName, rootWalletMasterKey, accounts) if err.len > 0: info "adding new keypair from seed phrase failed", keypairName=keypairName, keyUid=keyUid diff --git a/src/app/modules/shared_modules/keycard_popup/io_interface.nim b/src/app/modules/shared_modules/keycard_popup/io_interface.nim index 668856d103..e915099a38 100644 --- a/src/app/modules/shared_modules/keycard_popup/io_interface.nim +++ b/src/app/modules/shared_modules/keycard_popup/io_interface.nim @@ -1,8 +1,8 @@ import NimQml, tables -import ../../../../app/core/eventemitter -from ../../../../app_service/service/keycard/service import KeycardEvent, CardMetadata, KeyDetails -from ../../../../app_service/service/wallet_account/service as wallet_account_service import WalletTokenDto -import ../../shared_models/keypair_item +import app/core/eventemitter +from app_service/service/keycard/service import KeycardEvent, CardMetadata, KeyDetails +from app_service/service/wallet_account/service as wallet_account_service import WalletTokenDto +import app/modules/shared_models/keypair_item const SIGNAL_SHARED_KEYCARD_MODULE_DISPLAY_POPUP* = "sharedKeycarModuleDisplayPopup" const SIGNAL_SHARED_KEYCARD_MODULE_FLOW_TERMINATED* = "sharedKeycarModuleFlowTerminated" @@ -11,15 +11,15 @@ const SIGNAL_SHARED_KEYCARD_MODULE_USER_AUTHENTICATED* = "sharedKeycarModuleUser const SIGNAL_SHARED_KEYCARD_MODULE_TRY_KEYCARD_SYNC* = "sharedKeycarModuleTryKeycardSync" const SIGNAL_SHARED_KEYCARD_MODULE_KEYCARD_SYNC_TERMINATED* = "sharedKeycarModuleKeycardSyncTerminated" -## Authentication in the app is a global thing and may be used from any part of the app. How to achieve that... it's enough just to send +## Authentication in the app is a global thing and may be used from any part of the app. How to achieve that... it's enough just to send ## `SIGNAL_SHARED_KEYCARD_MODULE_AUTHENTICATE_USER` signal with properly set `SharedKeycarModuleAuthenticationArgs` and props there: -## -- `uniqueIdentifier` - some unique string, for the readability usually name of the module which needs authentication, -## -- in case of non keycard user (regular) user that's enough, -## -- in case of keycard user we want to authenticate it with a card that his profile is migrated to, that means apart of `uniqueIdentifier` -## we need to set `keyUid` as well, -## -## `SIGNAL_SHARED_KEYCARD_MODULE_AUTHENTICATE_USER` will be handled in the `mainModule` (shared keycard popup module will be run) and as a -## result, when authentication gets done `SIGNAL_SHARED_KEYCARD_MODULE_USER_AUTHENTICATED` signal with properly set `SharedKeycarModuleArgs` +## -- `uniqueIdentifier` - some unique string, for the readability usually name of the module which needs authentication, +## -- in case of non keycard user (regular) user that's enough, +## -- in case of keycard user we want to authenticate it with a card that his profile is migrated to, that means apart of `uniqueIdentifier` +## we need to set `keyUid` as well, +## +## `SIGNAL_SHARED_KEYCARD_MODULE_AUTHENTICATE_USER` will be handled in the `mainModule` (shared keycard popup module will be run) and as a +## result, when authentication gets done `SIGNAL_SHARED_KEYCARD_MODULE_USER_AUTHENTICATED` signal with properly set `SharedKeycarModuleArgs` ## and props there will be emitted: ## -- `uniqueIdentifier` - will be the same as one used for running authentication process ## -- in case of success of a regular user authentication `keyUid`, `password` will be sent, otherwise it will be empty @@ -27,7 +27,7 @@ const SIGNAL_SHARED_KEYCARD_MODULE_KEYCARD_SYNC_TERMINATED* = "sharedKeycarModul ## ## TLDR: when you need to authenticate user, from the module where it's needed you have to send `SIGNAL_SHARED_KEYCARD_MODULE_AUTHENTICATE_USER` ## signal to run authentication process and connect to `SIGNAL_SHARED_KEYCARD_MODULE_USER_AUTHENTICATED` signal to get the results of it. - + type SharedKeycarModuleBaseArgs* = ref object of Args uniqueIdentifier*: string @@ -38,6 +38,7 @@ type pin*: string # this is used in case we need to run another keycard flow which requires pin, after we successfully authenticated logged in user keyUid*: string keycardUid*: string + additinalPathsDetails*: Table[string, KeyDetails] # [path, KeyDetails] type SharedKeycarModuleFlowTerminatedArgs* = ref object of SharedKeycarModuleArgs @@ -46,7 +47,7 @@ type type SharedKeycarModuleAuthenticationArgs* = ref object of SharedKeycarModuleBaseArgs keyUid*: string - + additionalBip44Paths*: seq[string] # can be used in authentication flow to export additinal paths if needed except encryption path type FlowType* {.pure.} = enum General = "General" @@ -66,13 +67,13 @@ type FlowType* {.pure.} = enum # For the following flows we don't run card syncing. const FlowsWeShouldNotTryAKeycardSyncFor* = @[ - FlowType.General, + FlowType.General, FlowType.FactoryReset, FlowType.UnlockKeycard, - FlowType.SetupNewKeycard, + FlowType.SetupNewKeycard, FlowType.SetupNewKeycardNewSeedPhrase, - FlowType.SetupNewKeycardOldSeedPhrase, - FlowType.ImportFromKeycard, + FlowType.SetupNewKeycardOldSeedPhrase, + FlowType.ImportFromKeycard, FlowType.Authentication ] @@ -99,7 +100,7 @@ method setRemainingAttempts*(self: AccessInterface, value: int) {.base.} = method onBackActionClicked*(self: AccessInterface) {.base.} = raise newException(ValueError, "No implementation available") - + method onPrimaryActionClicked*(self: AccessInterface) {.base.} = raise newException(ValueError, "No implementation available") @@ -112,7 +113,7 @@ method onCancelActionClicked*(self: AccessInterface) {.base.} = method onKeycardResponse*(self: AccessInterface, keycardFlowType: string, keycardEvent: KeycardEvent) {.base.} = raise newException(ValueError, "No implementation available") -method runFlow*(self: AccessInterface, flowToRun: FlowType, keyUid = "", bip44Path = "", txHash = "") {.base.} = +method runFlow*(self: AccessInterface, flowToRun: FlowType, keyUid = "", bip44Paths: seq[string] = @[], txHash = "") {.base.} = raise newException(ValueError, "No implementation available") method setPin*(self: AccessInterface, value: string) {.base.} = diff --git a/src/app/modules/shared_modules/keycard_popup/module.nim b/src/app/modules/shared_modules/keycard_popup/module.nim index bf03448195..88540215ef 100644 --- a/src/app/modules/shared_modules/keycard_popup/module.nim +++ b/src/app/modules/shared_modules/keycard_popup/module.nim @@ -111,7 +111,7 @@ method checkRepeatedKeycardPinWhileTyping*[T](self: Module[T], pin: string): boo if pin[i] != storedPin[i]: return false return true - else: + else: let match = pin == storedPin self.controller.setPinMatch(match) return match @@ -126,7 +126,7 @@ method checkRepeatedKeycardPukWhileTyping*[T](self: Module[T], puk: string): boo if puk[i] != storedPuk[i]: return false return true - else: + else: let match = puk == storedPuk self.controller.setPukMatch(match) return match @@ -210,7 +210,7 @@ proc reEvaluateKeyPairForProcessing[T](self: Module[T], currFlowType: FlowType, currFlowType == FlowType.ChangeKeycardPuk or currFlowType == FlowType.ChangePairingCode or currFlowType == FlowType.CreateCopyOfAKeycard: - if currStateType != StateType.PluginReader and + if currStateType != StateType.PluginReader and currStateType != StateType.ReadingKeycard: return let (_, flowEvent) = self.controller.getLastReceivedKeycardData() @@ -258,7 +258,7 @@ proc handleKeycardSyncing[T](self: Module[T]) = found = true break if found and index > -1: - # if account address which is present in the wallet is still present in accounts addresses of a keycard, + # if account address which is present in the wallet is still present in accounts addresses of a keycard, # then it needs to be present in `keypairs` table in db, so remove it from the list accountsToRemove.delete(index) else: @@ -327,7 +327,7 @@ method onCancelActionClicked*[T](self: Module[T]) = debug "sm_cancel_action", currFlow=currStateObj.flowType(), currState=currStateObj.stateType() self.preActionActivities(currStateObj.flowType(), currStateObj.stateType()) currStateObj.executeCancelCommand(self.controller) - + method onPrimaryActionClicked*[T](self: Module[T]) = let currStateObj = self.view.currentStateObj() if currStateObj.isNil: @@ -394,7 +394,7 @@ method onKeycardResponse*[T](self: Module[T], keycardFlowType: string, keycardEv proc prepareKeyPairItemForAuthentication[T](self: Module[T], keyUid: string) = var item = newKeyPairItem() - let items = keypairs.buildKeyPairsList(self.controller.getKeypairs(), self.controller.getAllKnownKeycardsGroupedByKeyUid(), + let items = keypairs.buildKeyPairsList(self.controller.getKeypairs(), self.controller.getAllKnownKeycardsGroupedByKeyUid(), excludeAlreadyMigratedPairs = false, excludePrivateKeyKeypairs = false) for it in items: if it.getKeyUid() == keyUid: @@ -416,7 +416,7 @@ method setKeyPairForProcessing*[T](self: Module[T], item: KeyPairItem) = method prepareKeyPairForProcessing*[T](self: Module[T], keyUid: string, keycardUid = "") = var item = newKeyPairItem() - let items = keypairs.buildKeyPairsList(self.controller.getKeypairs(), self.controller.getAllKnownKeycardsGroupedByKeyUid(), + let items = keypairs.buildKeyPairsList(self.controller.getKeypairs(), self.controller.getAllKnownKeycardsGroupedByKeyUid(), excludeAlreadyMigratedPairs = false, excludePrivateKeyKeypairs = false) for it in items: if it.getKeyUid() == keyUid: @@ -433,9 +433,9 @@ method prepareKeyPairForProcessing*[T](self: Module[T], keyUid: string, keycardU item.setIcon("keycard") self.view.setKeyPairForProcessing(item) -method runFlow*[T](self: Module[T], flowToRun: FlowType, keyUid = "", bip44Path = "", txHash = "") = - ## In case of `Authentication` if we're signing a transaction we need to provide a key uid of a keypair that an account - ## we want to sign a transaction for belongs to. If we're just doing an authentication for a logged in user, then +method runFlow*[T](self: Module[T], flowToRun: FlowType, keyUid = "", bip44Paths: seq[string] = @[], txHash = "") = + ## In case of `Authentication` if we're signing a transaction we need to provide a key uid of a keypair that an account + ## we want to sign a transaction for belongs to. If we're just doing an authentication for a logged in user, then ## default key uid is always the key uid of the logged in user. if flowToRun == FlowType.General: self.controller.terminateCurrentFlow(lastStepInTheCurrentFlow = false) @@ -459,7 +459,7 @@ method runFlow*[T](self: Module[T], flowToRun: FlowType, keyUid = "", bip44Path if singletonInstance.userProfile.getIsKeycardUser(): self.prepareKeyPairItemForAuthentication(singletonInstance.userProfile.getKeyUid()) self.tmpLocalState = newReadingKeycardState(flowToRun, nil) - self.controller.runAuthenticationFlow(singletonInstance.userProfile.getKeyUid()) + self.controller.runAuthenticationFlow(singletonInstance.userProfile.getKeyUid(), bip44Paths) return if singletonInstance.userProfile.getUsingBiometricLogin(): self.controller.tryToObtainDataFromKeychain() @@ -471,8 +471,8 @@ method runFlow*[T](self: Module[T], flowToRun: FlowType, keyUid = "", bip44Path else: self.prepareKeyPairItemForAuthentication(keyUid) self.tmpLocalState = newReadingKeycardState(flowToRun, nil) - self.controller.runAuthenticationFlow(keyUid) - return + self.controller.runAuthenticationFlow(keyUid, bip44Paths) + return if flowToRun == FlowType.UnlockKeycard: ## since we can run unlock keycard flow from an already running flow, in order to avoid changing displayed keypair ## (locked keypair) we have to set keycard uid of a keycard used in the flow we're jumping from to `UnlockKeycard` flow. @@ -557,7 +557,7 @@ method onTokensRebuilt*[T](self: Module[T], accountsTokens: OrderedTable[string, let balance = tokens.map(t => t.getCurrencyBalance(chainIds, currency)).foldl(a + b, 0.0) self.getKeyPairForProcessing().setBalanceForAddress(address, balance) -proc buildKeyPairItemBasedOnCardMetadata[T](self: Module[T], cardMetadata: CardMetadata): +proc buildKeyPairItemBasedOnCardMetadata[T](self: Module[T], cardMetadata: CardMetadata): tuple[item: KeyPairItem, knownKeyPair: bool] = result.item = newKeyPairItem(keyUid = "", pubKey = "", @@ -578,7 +578,7 @@ proc buildKeyPairItemBasedOnCardMetadata[T](self: Module[T], cardMetadata: CardM result.knownKeyPair = false unknonwAccountNumber.inc let name = atc.KEYCARD_ACCOUNT_NAME_OF_UNKNOWN_WALLET_ACCOUNT & $unknonwAccountNumber - result.item.addAccount(newKeyPairAccountItem(name, wa.path, wa.address, pubKey = wa.publicKey, emoji = "", + result.item.addAccount(newKeyPairAccountItem(name, wa.path, wa.address, pubKey = wa.publicKey, emoji = "", colorId = "", icon = "undefined", balance, balanceFetched)) method updateKeyPairForProcessing*[T](self: Module[T], cardMetadata: CardMetadata) = @@ -599,8 +599,8 @@ method onUserAuthenticated*[T](self: Module[T], password: string, pin: string) = method keychainObtainedDataFailure*[T](self: Module[T], errorDescription: string, errorType: string) = let currStateObj = self.view.currentStateObj() - if currStateObj.isNil or - currStateObj.stateType() == StateType.EnterPassword or + if currStateObj.isNil or + currStateObj.stateType() == StateType.EnterPassword or currStateObj.stateType() == StateType.WrongPassword or currStateObj.stateType() == StateType.BiometricsPasswordFailed: self.view.setCurrentState(newBiometricsPasswordFailedState(FlowType.Authentication, nil)) @@ -613,8 +613,8 @@ method keychainObtainedDataFailure*[T](self: Module[T], errorDescription: string method keychainObtainedDataSuccess*[T](self: Module[T], data: string) = let currStateObj = self.view.currentStateObj() - if currStateObj.isNil or - currStateObj.stateType() == StateType.EnterPassword or + if currStateObj.isNil or + currStateObj.stateType() == StateType.EnterPassword or currStateObj.stateType() == StateType.WrongPassword or currStateObj.stateType() == StateType.BiometricsPasswordFailed: if self.controller.verifyPassword(data): diff --git a/src/app/modules/startup/controller.nim b/src/app/modules/startup/controller.nim index 13a11d073d..4a35979ae6 100644 --- a/src/app/modules/startup/controller.nim +++ b/src/app/modules/startup/controller.nim @@ -454,7 +454,13 @@ proc login*(self: Controller) = proc loginLocalPairingAccount*(self: Controller) = self.delegate.moveToLoadingAppState() - self.accountsService.login(self.localPairingStatus.account, self.localPairingStatus.password) + if self.localPairingStatus.chatKey.len == 0: + self.accountsService.login(self.localPairingStatus.account, self.localPairingStatus.password) + else: + var kcEvent = KeycardEvent() + kcEvent.whisperKey.privateKey = self.localPairingStatus.chatKey + kcEvent.encryptionKey.publicKey = self.localPairingStatus.password + discard self.accountsService.loginAccountKeycard(self.localPairingStatus.account, kcEvent) proc loginAccountKeycard*(self: Controller, storeToKeychainValue: string, syncWalletAfterLogin = false) = if syncWalletAfterLogin: diff --git a/src/app_service/service/devices/dto/local_pairing_event.nim b/src/app_service/service/devices/dto/local_pairing_event.nim index 81c9cc1c47..894bf211f5 100644 --- a/src/app_service/service/devices/dto/local_pairing_event.nim +++ b/src/app_service/service/devices/dto/local_pairing_event.nim @@ -4,7 +4,7 @@ import ../../../../app/core/eventemitter import ../../accounts/dto/accounts import installation -type +type EventType* {.pure.} = enum EventUnknown = -1, EventConnectionError = 0, @@ -16,7 +16,7 @@ type EventProcessSuccess = 6, EventProcessError = 7 -type +type Action* {.pure.} = enum ActionUnknown = 0 ActionConnect = 1, @@ -28,6 +28,7 @@ type LocalPairingAccountData* = ref object account*: AccountDTO password*: string + chatKey*: string type LocalPairingEventArgs* = ref object of Args @@ -75,6 +76,7 @@ proc parse*(self: int): Action = proc toLocalPairingAccountData*(jsonObj: JsonNode): LocalPairingAccountData = result = LocalPairingAccountData() discard jsonObj.getProp("password", result.password) + discard jsonObj.getProp("chatKey", result.chatKey) var accountObj: JsonNode if(jsonObj.getProp("account", accountObj)): diff --git a/src/app_service/service/devices/dto/local_pairing_status.nim b/src/app_service/service/devices/dto/local_pairing_status.nim index a203a2d60b..9da67ed48a 100644 --- a/src/app_service/service/devices/dto/local_pairing_status.nim +++ b/src/app_service/service/devices/dto/local_pairing_status.nim @@ -20,8 +20,9 @@ type LocalPairingStatus* = ref object of Args mode*: LocalPairingMode state*: LocalPairingState - account*: AccountDTO + account*: AccountDto password*: string + chatKey*: string installation*: InstallationDto error*: string @@ -42,7 +43,7 @@ proc newLocalPairingStatus*(): LocalPairingStatus = result.setup() proc update*(self: LocalPairingStatus, data: LocalPairingEventArgs) = - + self.error = data.error # process any incoming data @@ -50,6 +51,7 @@ proc update*(self: LocalPairingStatus, data: LocalPairingEventArgs) = of EventReceivedAccount: self.account = data.accountData.account self.password = data.accountData.password + self.chatKey = data.accountData.chatKey of EventReceivedInstallation: self.installation = data.installation of EventConnectionError: @@ -65,7 +67,7 @@ proc update*(self: LocalPairingStatus, data: LocalPairingEventArgs) = return # Detect finished state - if (self.mode == LocalPairingMode.Sender and + if (self.mode == LocalPairingMode.Sender and data.eventType == EventProcessSuccess and data.action == ActionPairingInstallation): self.state = LocalPairingState.Finished diff --git a/src/app_service/service/devices/service.nim b/src/app_service/service/devices/service.nim index c17cb53905..5e042c8acc 100644 --- a/src/app_service/service/devices/service.nim +++ b/src/app_service/service/devices/service.nim @@ -6,17 +6,17 @@ import ./dto/installation as Installation_dto import ./dto/local_pairing_event import ./dto/local_pairing_status -import ../settings/service as settings_service -import ../accounts/service as accounts_service +import app_service/service/settings/service as settings_service +import app_service/service/accounts/service as accounts_service -import ../../../app/global/global_singleton -import ../../../app/core/[main] -import ../../../app/core/signals/types -import ../../../app/core/eventemitter -import ../../../app/core/tasks/[qt, threadpool] -import ../../../backend/installations as status_installations -import ../../common/utils as utils -import ../../../constants as main_constants +import app/global/global_singleton +import app/core/[main] +import app/core/signals/types +import app/core/eventemitter +import app/core/tasks/[qt, threadpool] +import backend/installations as status_installations +import app_service/common/utils as utils +import constants as main_constants import status_go @@ -62,7 +62,7 @@ QtObject: self.QObject.delete self.localPairingStatus.delete - proc newService*(events: EventEmitter, + proc newService*(events: EventEmitter, threadpool: ThreadPool, settingsService: settings_service.Service, accountsService: accounts_service.Service): Service = @@ -176,13 +176,20 @@ QtObject: proc validateConnectionString*(self: Service, connectionString: string): string = return status_go.validateConnectionString(connectionString) - proc getConnectionStringForBootstrappingAnotherDevice*(self: Service, keyUid: string, password: string): string = + proc getConnectionStringForBootstrappingAnotherDevice*(self: Service, password: string, chatKey: string): string = + let keyUid = singletonInstance.userProfile.getKeyUid() + let keycardUser = singletonInstance.userProfile.getIsKeycardUser() + var finalPassword = password + if not keycardUser: + finalPassword = utils.hashPassword(password) + let configJSON = %* { "senderConfig": %* { "keystorePath": joinPath(main_constants.ROOTKEYSTOREDIR, keyUid), "deviceType": hostOs, "keyUID": keyUid, - "password": utils.hashPassword(password), + "password": finalPassword, + "chatKey": chatKey, }, "serverConfig": %* { "timeout": 5 * 60 * 1000, diff --git a/ui/app/AppLayouts/Profile/popups/SetupSyncingPopup.qml b/ui/app/AppLayouts/Profile/popups/SetupSyncingPopup.qml index eff86d8faf..c9ee365603 100644 --- a/ui/app/AppLayouts/Profile/popups/SetupSyncingPopup.qml +++ b/ui/app/AppLayouts/Profile/popups/SetupSyncingPopup.qml @@ -22,8 +22,7 @@ import "../stores" StatusDialog { id: root - property string password - property string keyUid + required property string rawConnectionString property DevicesStore devicesStore property ProfileStore profileStore @@ -53,13 +52,11 @@ StatusDialog { d.connectionString = "" d.errorMessage = "" - const result = root.devicesStore.getConnectionStringForBootstrappingAnotherDevice(root.keyUid, root.password) - try { - const json = JSON.parse(result) + const json = JSON.parse(root.rawConnectionString) d.errorMessage = json.error } catch (e) { - d.connectionString = result + d.connectionString = root.rawConnectionString } if (d.errorMessage !== "") { diff --git a/ui/app/AppLayouts/Profile/stores/DevicesStore.qml b/ui/app/AppLayouts/Profile/stores/DevicesStore.qml index e7530fe253..116f3eb4b5 100644 --- a/ui/app/AppLayouts/Profile/stores/DevicesStore.qml +++ b/ui/app/AppLayouts/Profile/stores/DevicesStore.qml @@ -37,19 +37,14 @@ QtObject { root.devicesModule.enableDevice(installationId, enable) } - function authenticateUser() { - const keyUid = "" // TODO: Support Keycard - root.devicesModule.authenticateUser(keyUid) + function authenticateLoggedInUser() { + root.devicesModule.authenticateLoggedInUser() } function validateConnectionString(connectionString) { return root.devicesModule.validateConnectionString(connectionString) } - function getConnectionStringForBootstrappingAnotherDevice(keyUid, password) { - return root.devicesModule.getConnectionStringForBootstrappingAnotherDevice(keyUid, password) - } - function inputConnectionStringForBootstrapping(connectionString) { return root.devicesModule.inputConnectionStringForBootstrapping(connectionString) } diff --git a/ui/app/AppLayouts/Profile/views/SyncingView.qml b/ui/app/AppLayouts/Profile/views/SyncingView.qml index c9daa64911..c6eecb44ea 100644 --- a/ui/app/AppLayouts/Profile/views/SyncingView.qml +++ b/ui/app/AppLayouts/Profile/views/SyncingView.qml @@ -54,8 +54,7 @@ SettingsContentBase { } function setupSyncing() { - const keyUid = root.profileStore.isKeycardUser ? root.profileStore.keyUid : "" - root.devicesStore.authenticateUser(keyUid) + root.devicesStore.authenticateLoggedInUser() } } @@ -63,16 +62,9 @@ SettingsContentBase { Connections { target: devicesStore.devicesModule - function onUserAuthenticated(pin, password, keyUid) { - if (!password) - return - // Authentication flow returns empty keyUid for non-keycard user. - const effectiveKeyUid = root.profileStore.isKeycardUser - ? keyUid - : root.profileStore.keyUid + function onOpenPopupWithConnectionStringSignal(rawConnectionString) { Global.openPopup(setupSyncingPopup, { - password, - keyUid: effectiveKeyUid + rawConnectionString: rawConnectionString, }) } } @@ -135,7 +127,7 @@ SettingsContentBase { timestamp: model.timestamp isCurrentDevice: model.isCurrentDevice onSetupSyncingButtonClicked: { - d.setupSyncing(SetupSyncingPopup.GenerateSyncCode) + d.setupSyncing() } onClicked: { if (deviceEnabled) diff --git a/ui/app/AppLayouts/Wallet/stores/RootStore.qml b/ui/app/AppLayouts/Wallet/stores/RootStore.qml index 8818e959d5..6def42d338 100644 --- a/ui/app/AppLayouts/Wallet/stores/RootStore.qml +++ b/ui/app/AppLayouts/Wallet/stores/RootStore.qml @@ -14,8 +14,6 @@ QtObject { readonly property string defaultSelectedKeyUid: userProfile.keyUid readonly property bool defaultSelectedKeyUidMigratedToKeycard: userProfile.isKeycardUser - property bool loggedInUserAuthenticated: false - property string backButtonName: "" property var overview: walletSectionOverview property var assets: walletSectionAssets.assets