feat(@desktop/syncing): keypair syncing - recovering from another device with Keycard related profile
Closes: #10983
This commit is contained in:
parent
af96345e26
commit
7c56dc53d9
|
@ -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)
|
||||
|
|
|
@ -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")
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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")
|
||||
raise newException(ValueError, "No implementation available")
|
||||
|
|
|
@ -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)
|
||||
self.view.onLocalPairingStatusUpdate(status)
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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.} =
|
||||
|
|
|
@ -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):
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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)):
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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 !== "") {
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in New Issue