mirror of
https://github.com/status-im/status-desktop.git
synced 2025-01-09 05:52:41 +00:00
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,
|
password: args.password,
|
||||||
pin: args.pin,
|
pin: args.pin,
|
||||||
keyUid: args.keyUid,
|
keyUid: args.keyUid,
|
||||||
keycardUid: args.keycardUid)
|
keycardUid: args.keycardUid,
|
||||||
|
additinalPathsDetails: args.additinalPathsDetails)
|
||||||
self.authenticateUserFlowRequestedBy = ""
|
self.authenticateUserFlowRequestedBy = ""
|
||||||
self.events.emit(SIGNAL_SHARED_KEYCARD_MODULE_USER_AUTHENTICATED, data)
|
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):
|
self.events.on(SIGNAL_SHARED_KEYCARD_MODULE_AUTHENTICATE_USER) do(e: Args):
|
||||||
let args = SharedKeycarModuleAuthenticationArgs(e)
|
let args = SharedKeycarModuleAuthenticationArgs(e)
|
||||||
self.authenticateUserFlowRequestedBy = args.uniqueIdentifier
|
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):
|
self.events.on(SIGNAL_SHARED_KEYCARD_MODULE_TRY_KEYCARD_SYNC) do(e: Args):
|
||||||
let args = SharedKeycarModuleArgs(e)
|
let args = SharedKeycarModuleArgs(e)
|
||||||
|
@ -273,7 +273,7 @@ method onDisplayKeycardSharedModuleFlow*(self: AccessInterface) {.base.} =
|
|||||||
method onSharedKeycarModuleFlowTerminated*(self: AccessInterface, lastStepInTheCurrentFlow: bool) {.base.} =
|
method onSharedKeycarModuleFlowTerminated*(self: AccessInterface, lastStepInTheCurrentFlow: bool) {.base.} =
|
||||||
raise newException(ValueError, "No implementation available")
|
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")
|
raise newException(ValueError, "No implementation available")
|
||||||
|
|
||||||
method onMyRequestAdded*(self: AccessInterface) {.base.} =
|
method onMyRequestAdded*(self: AccessInterface) {.base.} =
|
||||||
|
@ -1191,11 +1191,11 @@ method onSharedKeycarModuleFlowTerminated*[T](self: Module[T], lastStepInTheCurr
|
|||||||
self.keycardSharedModule.delete
|
self.keycardSharedModule.delete
|
||||||
self.keycardSharedModule = nil
|
self.keycardSharedModule = nil
|
||||||
|
|
||||||
method runAuthenticationPopup*[T](self: Module[T], keyUid: string) =
|
method runAuthenticationPopup*[T](self: Module[T], keyUid: string, bip44Paths: seq[string] = @[]) =
|
||||||
self.createSharedKeycardModule()
|
self.createSharedKeycardModule()
|
||||||
if self.keycardSharedModule.isNil:
|
if self.keycardSharedModule.isNil:
|
||||||
return
|
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) =
|
method onSharedKeycarModuleKeycardSyncPurposeTerminated*[T](self: Module[T], lastStepInTheCurrentFlow: bool) =
|
||||||
if not self.keycardSharedModuleKeycardSyncPurpose.isNil:
|
if not self.keycardSharedModuleKeycardSyncPurpose.isNil:
|
||||||
|
@ -1,13 +1,13 @@
|
|||||||
import Tables, chronicles
|
import Tables, chronicles
|
||||||
import io_interface
|
import io_interface
|
||||||
|
|
||||||
import ../../../../core/eventemitter
|
import app/core/eventemitter
|
||||||
import ../../../../../app_service/service/settings/service as settings_service
|
import app_service/service/settings/service as settings_service
|
||||||
import ../../../../../app_service/service/devices/service as devices_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:
|
logScope:
|
||||||
topics = "profile-section-devices-module-controller"
|
topics = "profile-section-devices-module-controller"
|
||||||
@ -50,9 +50,9 @@ proc init*(self: Controller) =
|
|||||||
|
|
||||||
self.events.on(SIGNAL_SHARED_KEYCARD_MODULE_USER_AUTHENTICATED) do(e: Args):
|
self.events.on(SIGNAL_SHARED_KEYCARD_MODULE_USER_AUTHENTICATED) do(e: Args):
|
||||||
let args = SharedKeycarModuleArgs(e)
|
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
|
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):
|
self.events.on(SIGNAL_LOCAL_PAIRING_EVENT) do(e: Args):
|
||||||
let args = LocalPairingEventArgs(e)
|
let args = LocalPairingEventArgs(e)
|
||||||
@ -91,10 +91,11 @@ proc enableDevice*(self: Controller, deviceId: string, enable: bool) =
|
|||||||
# Pairing status
|
# Pairing status
|
||||||
#
|
#
|
||||||
|
|
||||||
proc authenticateUser*(self: Controller, keyUid: string) =
|
proc authenticateLoggedInUser*(self: Controller, additionalBip44Paths: seq[string] = @[]) =
|
||||||
let data = SharedKeycarModuleAuthenticationArgs(
|
var data = SharedKeycarModuleAuthenticationArgs(
|
||||||
uniqueIdentifier: UNIQUE_SYNCING_SECTION_ACCOUNTS_MODULE_AUTH_IDENTIFIER,
|
uniqueIdentifier: UNIQUE_SYNCING_LOGGED_IN_USER_AUTHENTICATION_IDENTIFIER,
|
||||||
keyUid: keyUid)
|
additionalBip44Paths: additionalBip44Paths
|
||||||
|
)
|
||||||
self.events.emit(SIGNAL_SHARED_KEYCARD_MODULE_AUTHENTICATE_USER, data)
|
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 =
|
proc validateConnectionString*(self: Controller, connectionString: string): string =
|
||||||
return self.devicesService.validateConnectionString(connectionString)
|
return self.devicesService.validateConnectionString(connectionString)
|
||||||
|
|
||||||
proc getConnectionStringForBootstrappingAnotherDevice*(self: Controller, keyUid: string, password: string): string =
|
proc getConnectionStringForBootstrappingAnotherDevice*(self: Controller, password, chatKey: string): string =
|
||||||
return self.devicesService.getConnectionStringForBootstrappingAnotherDevice(keyUid, password)
|
return self.devicesService.getConnectionStringForBootstrappingAnotherDevice(password, chatKey)
|
||||||
|
|
||||||
proc inputConnectionStringForBootstrapping*(self: Controller, connectionString: string): string =
|
proc inputConnectionStringForBootstrapping*(self: Controller, connectionString: string): string =
|
||||||
return self.devicesService.inputConnectionStringForBootstrapping(connectionString)
|
return self.devicesService.inputConnectionStringForBootstrapping(connectionString)
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
import NimQml
|
import NimQml, tables
|
||||||
import ../../../../../app_service/service/devices/service
|
import app_service/service/devices/service
|
||||||
|
from app_service/service/keycard/service import KeyDetails
|
||||||
|
|
||||||
type
|
type
|
||||||
AccessInterface* {.pure inheritable.} = ref object of RootObj
|
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.} =
|
method enableDevice*(self: AccessInterface, installationId: string, enable: bool) {.base.} =
|
||||||
raise newException(ValueError, "No implementation available")
|
raise newException(ValueError, "No implementation available")
|
||||||
|
|
||||||
method authenticateUser*(self: AccessInterface, keyUid: string) {.base.} =
|
method authenticateLoggedInUser*(self: AccessInterface) {.base.} =
|
||||||
raise newException(ValueError, "No implementation available")
|
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")
|
raise newException(ValueError, "No implementation available")
|
||||||
|
|
||||||
proc validateConnectionString*(self: AccessInterface, connectionString: string): string =
|
proc validateConnectionString*(self: AccessInterface, connectionString: string): string =
|
||||||
raise newException(ValueError, "No implementation available")
|
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.} =
|
method inputConnectionStringForBootstrapping*(self: AccessInterface, connectionString: string): string {.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
|
||||||
import ../io_interface as delegate_interface
|
import ../io_interface as delegate_interface
|
||||||
import view, controller, model, item
|
import view, controller, model, item
|
||||||
import logging
|
import logging
|
||||||
|
|
||||||
import ../../../../core/eventemitter
|
import app/global/global_singleton
|
||||||
import ../../../../../app_service/service/settings/service as settings_service
|
import app/core/eventemitter
|
||||||
import ../../../../../app_service/service/devices/service as devices_service
|
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
|
export io_interface
|
||||||
|
|
||||||
@ -97,18 +100,25 @@ method updateOrAddDevice*(self: Module, installation: InstallationDto) =
|
|||||||
method updateInstallationName*(self: Module, installationId: string, name: string) =
|
method updateInstallationName*(self: Module, installationId: string, name: string) =
|
||||||
self.view.model().updateItemName(installationId, name)
|
self.view.model().updateItemName(installationId, name)
|
||||||
|
|
||||||
method authenticateUser*(self: Module, keyUid: string) =
|
method authenticateLoggedInUser*(self: Module) =
|
||||||
self.controller.authenticateUser(keyUid)
|
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) =
|
method onLoggedInUserAuthenticated*(self: Module, pin: string, password: string, keyUid: string, additinalPathsDetails: Table[string, KeyDetails]) =
|
||||||
self.view.emitUserAuthenticated(pin, password, keyUid)
|
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 =
|
proc validateConnectionString*(self: Module, connectionString: string): string =
|
||||||
return self.controller.validateConnectionString(connectionString)
|
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 =
|
method inputConnectionStringForBootstrapping*(self: Module, connectionString: string): string =
|
||||||
return self.controller.inputConnectionStringForBootstrapping(connectionString)
|
return self.controller.inputConnectionStringForBootstrapping(connectionString)
|
||||||
|
|
||||||
|
@ -133,17 +133,15 @@ QtObject:
|
|||||||
|
|
||||||
# LocalPairing actions
|
# LocalPairing actions
|
||||||
|
|
||||||
proc userAuthenticated*(self: View, pin: string, password: string, keyUid: string) {.signal.}
|
proc openPopupWithConnectionStringSignal*(self: View, rawConnectionString: string) {.signal.}
|
||||||
proc emitUserAuthenticated*(self: View, pin: string, password: string, keyUid: string) =
|
proc openPopupWithConnectionString*(self: View, rawConnectionString: string) =
|
||||||
self.userAuthenticated(pin, password, keyUid)
|
self.openPopupWithConnectionStringSignal(rawConnectionString)
|
||||||
proc authenticateUser*(self: View, keyUid: string) {.slot.} =
|
|
||||||
self.delegate.authenticateUser(keyUid)
|
proc authenticateLoggedInUser*(self: View) {.slot.} =
|
||||||
|
self.delegate.authenticateLoggedInUser()
|
||||||
|
|
||||||
proc validateConnectionString*(self: View, connectionString: string): string {.slot.} =
|
proc validateConnectionString*(self: View, connectionString: string): string {.slot.} =
|
||||||
return self.delegate.validateConnectionString(connectionString)
|
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.} =
|
proc inputConnectionStringForBootstrapping*(self: View, connectionString: string): string {.slot.} =
|
||||||
return self.delegate.inputConnectionStringForBootstrapping(connectionString)
|
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 uuids
|
||||||
import io_interface
|
import io_interface
|
||||||
|
|
||||||
@ -66,6 +66,7 @@ type
|
|||||||
tmpKeycardCopyDestinationKeycardUid: string
|
tmpKeycardCopyDestinationKeycardUid: string
|
||||||
tmpKeycardSyncingInProgress: bool
|
tmpKeycardSyncingInProgress: bool
|
||||||
tmpFlowData: SharedKeycarModuleFlowTerminatedArgs
|
tmpFlowData: SharedKeycarModuleFlowTerminatedArgs
|
||||||
|
tmpRequestedPathsAlongWithAuthentication: seq[string]
|
||||||
tmpUnlockUsingSeedPhrase: bool # true - sp, false - puk
|
tmpUnlockUsingSeedPhrase: bool # true - sp, false - puk
|
||||||
|
|
||||||
proc newController*(delegate: io_interface.AccessInterface,
|
proc newController*(delegate: io_interface.AccessInterface,
|
||||||
@ -497,7 +498,7 @@ proc runDeriveAccountFlow*(self: Controller, bip44Paths: seq[string], pin: strin
|
|||||||
self.cancelCurrentFlow()
|
self.cancelCurrentFlow()
|
||||||
self.keycardService.startExportPublicFlow(bip44Paths, exportMasterAddr=true, exportPrivateAddr=false, pin)
|
self.keycardService.startExportPublicFlow(bip44Paths, exportMasterAddr=true, exportPrivateAddr=false, pin)
|
||||||
|
|
||||||
proc runAuthenticationFlow*(self: Controller, keyUid = "") =
|
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 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
|
## 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.
|
## uid of the logged in user.
|
||||||
@ -507,7 +508,11 @@ proc runAuthenticationFlow*(self: Controller, keyUid = "") =
|
|||||||
if self.tmpKeyUidWhichIsBeingAuthenticating.len == 0:
|
if self.tmpKeyUidWhichIsBeingAuthenticating.len == 0:
|
||||||
self.tmpKeyUidWhichIsBeingAuthenticating = singletonInstance.userProfile.getKeyUid()
|
self.tmpKeyUidWhichIsBeingAuthenticating = singletonInstance.userProfile.getKeyUid()
|
||||||
self.cancelCurrentFlow()
|
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) =
|
proc runLoadAccountFlow*(self: Controller, seedPhraseLength = 0, seedPhrase = "", pin = "", puk = "", factoryReset = false) =
|
||||||
if not serviceApplicable(self.keycardService):
|
if not serviceApplicable(self.keycardService):
|
||||||
@ -577,12 +582,21 @@ proc terminateCurrentFlow*(self: Controller, lastStepInTheCurrentFlow: bool) =
|
|||||||
self.tmpFlowData = SharedKeycarModuleFlowTerminatedArgs(uniqueIdentifier: self.uniqueIdentifier,
|
self.tmpFlowData = SharedKeycarModuleFlowTerminatedArgs(uniqueIdentifier: self.uniqueIdentifier,
|
||||||
lastStepInTheCurrentFlow: lastStepInTheCurrentFlow)
|
lastStepInTheCurrentFlow: lastStepInTheCurrentFlow)
|
||||||
if lastStepInTheCurrentFlow:
|
if lastStepInTheCurrentFlow:
|
||||||
let exportedEncryptionPubKey = flowEvent.generatedWalletAccount.publicKey
|
var exportedEncryptionPubKey: string
|
||||||
|
if flowEvent.generatedWalletAccounts.len > 0:
|
||||||
|
exportedEncryptionPubKey = flowEvent.generatedWalletAccounts[0].publicKey # encryption key is at position 0
|
||||||
if exportedEncryptionPubKey.len > 0:
|
if exportedEncryptionPubKey.len > 0:
|
||||||
self.tmpFlowData.password = exportedEncryptionPubKey
|
self.tmpFlowData.password = exportedEncryptionPubKey
|
||||||
self.tmpFlowData.pin = self.getPin()
|
self.tmpFlowData.pin = self.getPin()
|
||||||
self.tmpFlowData.keyUid = flowEvent.keyUid
|
self.tmpFlowData.keyUid = flowEvent.keyUid
|
||||||
self.tmpFlowData.keycardUid = flowEvent.instanceUID
|
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:
|
else:
|
||||||
self.tmpFlowData.password = self.getPassword()
|
self.tmpFlowData.password = self.getPassword()
|
||||||
self.tmpFlowData.keyUid = singletonInstance.userProfile.getKeyUid()
|
self.tmpFlowData.keyUid = singletonInstance.userProfile.getKeyUid()
|
||||||
|
@ -1,8 +1,8 @@
|
|||||||
import NimQml, tables
|
import NimQml, tables
|
||||||
import ../../../../app/core/eventemitter
|
import app/core/eventemitter
|
||||||
from ../../../../app_service/service/keycard/service import KeycardEvent, CardMetadata, KeyDetails
|
from app_service/service/keycard/service import KeycardEvent, CardMetadata, KeyDetails
|
||||||
from ../../../../app_service/service/wallet_account/service as wallet_account_service import WalletTokenDto
|
from app_service/service/wallet_account/service as wallet_account_service import WalletTokenDto
|
||||||
import ../../shared_models/keypair_item
|
import app/modules/shared_models/keypair_item
|
||||||
|
|
||||||
const SIGNAL_SHARED_KEYCARD_MODULE_DISPLAY_POPUP* = "sharedKeycarModuleDisplayPopup"
|
const SIGNAL_SHARED_KEYCARD_MODULE_DISPLAY_POPUP* = "sharedKeycarModuleDisplayPopup"
|
||||||
const SIGNAL_SHARED_KEYCARD_MODULE_FLOW_TERMINATED* = "sharedKeycarModuleFlowTerminated"
|
const SIGNAL_SHARED_KEYCARD_MODULE_FLOW_TERMINATED* = "sharedKeycarModuleFlowTerminated"
|
||||||
@ -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
|
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
|
keyUid*: string
|
||||||
keycardUid*: string
|
keycardUid*: string
|
||||||
|
additinalPathsDetails*: Table[string, KeyDetails] # [path, KeyDetails]
|
||||||
|
|
||||||
type
|
type
|
||||||
SharedKeycarModuleFlowTerminatedArgs* = ref object of SharedKeycarModuleArgs
|
SharedKeycarModuleFlowTerminatedArgs* = ref object of SharedKeycarModuleArgs
|
||||||
@ -46,7 +47,7 @@ type
|
|||||||
type
|
type
|
||||||
SharedKeycarModuleAuthenticationArgs* = ref object of SharedKeycarModuleBaseArgs
|
SharedKeycarModuleAuthenticationArgs* = ref object of SharedKeycarModuleBaseArgs
|
||||||
keyUid*: string
|
keyUid*: string
|
||||||
|
additionalBip44Paths*: seq[string] # can be used in authentication flow to export additinal paths if needed except encryption path
|
||||||
|
|
||||||
type FlowType* {.pure.} = enum
|
type FlowType* {.pure.} = enum
|
||||||
General = "General"
|
General = "General"
|
||||||
@ -112,7 +113,7 @@ method onCancelActionClicked*(self: AccessInterface) {.base.} =
|
|||||||
method onKeycardResponse*(self: AccessInterface, keycardFlowType: string, keycardEvent: KeycardEvent) {.base.} =
|
method onKeycardResponse*(self: AccessInterface, keycardFlowType: string, keycardEvent: KeycardEvent) {.base.} =
|
||||||
raise newException(ValueError, "No implementation available")
|
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")
|
raise newException(ValueError, "No implementation available")
|
||||||
|
|
||||||
method setPin*(self: AccessInterface, value: string) {.base.} =
|
method setPin*(self: AccessInterface, value: string) {.base.} =
|
||||||
|
@ -433,7 +433,7 @@ method prepareKeyPairForProcessing*[T](self: Module[T], keyUid: string, keycardU
|
|||||||
item.setIcon("keycard")
|
item.setIcon("keycard")
|
||||||
self.view.setKeyPairForProcessing(item)
|
self.view.setKeyPairForProcessing(item)
|
||||||
|
|
||||||
method runFlow*[T](self: Module[T], flowToRun: FlowType, keyUid = "", bip44Path = "", txHash = "") =
|
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
|
## 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
|
## 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.
|
## default key uid is always the key uid of the logged in user.
|
||||||
@ -459,7 +459,7 @@ method runFlow*[T](self: Module[T], flowToRun: FlowType, keyUid = "", bip44Path
|
|||||||
if singletonInstance.userProfile.getIsKeycardUser():
|
if singletonInstance.userProfile.getIsKeycardUser():
|
||||||
self.prepareKeyPairItemForAuthentication(singletonInstance.userProfile.getKeyUid())
|
self.prepareKeyPairItemForAuthentication(singletonInstance.userProfile.getKeyUid())
|
||||||
self.tmpLocalState = newReadingKeycardState(flowToRun, nil)
|
self.tmpLocalState = newReadingKeycardState(flowToRun, nil)
|
||||||
self.controller.runAuthenticationFlow(singletonInstance.userProfile.getKeyUid())
|
self.controller.runAuthenticationFlow(singletonInstance.userProfile.getKeyUid(), bip44Paths)
|
||||||
return
|
return
|
||||||
if singletonInstance.userProfile.getUsingBiometricLogin():
|
if singletonInstance.userProfile.getUsingBiometricLogin():
|
||||||
self.controller.tryToObtainDataFromKeychain()
|
self.controller.tryToObtainDataFromKeychain()
|
||||||
@ -471,7 +471,7 @@ method runFlow*[T](self: Module[T], flowToRun: FlowType, keyUid = "", bip44Path
|
|||||||
else:
|
else:
|
||||||
self.prepareKeyPairItemForAuthentication(keyUid)
|
self.prepareKeyPairItemForAuthentication(keyUid)
|
||||||
self.tmpLocalState = newReadingKeycardState(flowToRun, nil)
|
self.tmpLocalState = newReadingKeycardState(flowToRun, nil)
|
||||||
self.controller.runAuthenticationFlow(keyUid)
|
self.controller.runAuthenticationFlow(keyUid, bip44Paths)
|
||||||
return
|
return
|
||||||
if flowToRun == FlowType.UnlockKeycard:
|
if flowToRun == FlowType.UnlockKeycard:
|
||||||
## since we can run unlock keycard flow from an already running flow, in order to avoid changing displayed keypair
|
## since we can run unlock keycard flow from an already running flow, in order to avoid changing displayed keypair
|
||||||
|
@ -454,7 +454,13 @@ proc login*(self: Controller) =
|
|||||||
|
|
||||||
proc loginLocalPairingAccount*(self: Controller) =
|
proc loginLocalPairingAccount*(self: Controller) =
|
||||||
self.delegate.moveToLoadingAppState()
|
self.delegate.moveToLoadingAppState()
|
||||||
|
if self.localPairingStatus.chatKey.len == 0:
|
||||||
self.accountsService.login(self.localPairingStatus.account, self.localPairingStatus.password)
|
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) =
|
proc loginAccountKeycard*(self: Controller, storeToKeychainValue: string, syncWalletAfterLogin = false) =
|
||||||
if syncWalletAfterLogin:
|
if syncWalletAfterLogin:
|
||||||
|
@ -28,6 +28,7 @@ type
|
|||||||
LocalPairingAccountData* = ref object
|
LocalPairingAccountData* = ref object
|
||||||
account*: AccountDTO
|
account*: AccountDTO
|
||||||
password*: string
|
password*: string
|
||||||
|
chatKey*: string
|
||||||
|
|
||||||
type
|
type
|
||||||
LocalPairingEventArgs* = ref object of Args
|
LocalPairingEventArgs* = ref object of Args
|
||||||
@ -75,6 +76,7 @@ proc parse*(self: int): Action =
|
|||||||
proc toLocalPairingAccountData*(jsonObj: JsonNode): LocalPairingAccountData =
|
proc toLocalPairingAccountData*(jsonObj: JsonNode): LocalPairingAccountData =
|
||||||
result = LocalPairingAccountData()
|
result = LocalPairingAccountData()
|
||||||
discard jsonObj.getProp("password", result.password)
|
discard jsonObj.getProp("password", result.password)
|
||||||
|
discard jsonObj.getProp("chatKey", result.chatKey)
|
||||||
|
|
||||||
var accountObj: JsonNode
|
var accountObj: JsonNode
|
||||||
if(jsonObj.getProp("account", accountObj)):
|
if(jsonObj.getProp("account", accountObj)):
|
||||||
|
@ -20,8 +20,9 @@ type
|
|||||||
LocalPairingStatus* = ref object of Args
|
LocalPairingStatus* = ref object of Args
|
||||||
mode*: LocalPairingMode
|
mode*: LocalPairingMode
|
||||||
state*: LocalPairingState
|
state*: LocalPairingState
|
||||||
account*: AccountDTO
|
account*: AccountDto
|
||||||
password*: string
|
password*: string
|
||||||
|
chatKey*: string
|
||||||
installation*: InstallationDto
|
installation*: InstallationDto
|
||||||
error*: string
|
error*: string
|
||||||
|
|
||||||
@ -50,6 +51,7 @@ proc update*(self: LocalPairingStatus, data: LocalPairingEventArgs) =
|
|||||||
of EventReceivedAccount:
|
of EventReceivedAccount:
|
||||||
self.account = data.accountData.account
|
self.account = data.accountData.account
|
||||||
self.password = data.accountData.password
|
self.password = data.accountData.password
|
||||||
|
self.chatKey = data.accountData.chatKey
|
||||||
of EventReceivedInstallation:
|
of EventReceivedInstallation:
|
||||||
self.installation = data.installation
|
self.installation = data.installation
|
||||||
of EventConnectionError:
|
of EventConnectionError:
|
||||||
|
@ -6,17 +6,17 @@ import ./dto/installation as Installation_dto
|
|||||||
import ./dto/local_pairing_event
|
import ./dto/local_pairing_event
|
||||||
import ./dto/local_pairing_status
|
import ./dto/local_pairing_status
|
||||||
|
|
||||||
import ../settings/service as settings_service
|
import app_service/service/settings/service as settings_service
|
||||||
import ../accounts/service as accounts_service
|
import app_service/service/accounts/service as accounts_service
|
||||||
|
|
||||||
import ../../../app/global/global_singleton
|
import app/global/global_singleton
|
||||||
import ../../../app/core/[main]
|
import app/core/[main]
|
||||||
import ../../../app/core/signals/types
|
import app/core/signals/types
|
||||||
import ../../../app/core/eventemitter
|
import app/core/eventemitter
|
||||||
import ../../../app/core/tasks/[qt, threadpool]
|
import app/core/tasks/[qt, threadpool]
|
||||||
import ../../../backend/installations as status_installations
|
import backend/installations as status_installations
|
||||||
import ../../common/utils as utils
|
import app_service/common/utils as utils
|
||||||
import ../../../constants as main_constants
|
import constants as main_constants
|
||||||
|
|
||||||
import status_go
|
import status_go
|
||||||
|
|
||||||
@ -176,13 +176,20 @@ QtObject:
|
|||||||
proc validateConnectionString*(self: Service, connectionString: string): string =
|
proc validateConnectionString*(self: Service, connectionString: string): string =
|
||||||
return status_go.validateConnectionString(connectionString)
|
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 = %* {
|
let configJSON = %* {
|
||||||
"senderConfig": %* {
|
"senderConfig": %* {
|
||||||
"keystorePath": joinPath(main_constants.ROOTKEYSTOREDIR, keyUid),
|
"keystorePath": joinPath(main_constants.ROOTKEYSTOREDIR, keyUid),
|
||||||
"deviceType": hostOs,
|
"deviceType": hostOs,
|
||||||
"keyUID": keyUid,
|
"keyUID": keyUid,
|
||||||
"password": utils.hashPassword(password),
|
"password": finalPassword,
|
||||||
|
"chatKey": chatKey,
|
||||||
},
|
},
|
||||||
"serverConfig": %* {
|
"serverConfig": %* {
|
||||||
"timeout": 5 * 60 * 1000,
|
"timeout": 5 * 60 * 1000,
|
||||||
|
@ -22,8 +22,7 @@ import "../stores"
|
|||||||
StatusDialog {
|
StatusDialog {
|
||||||
id: root
|
id: root
|
||||||
|
|
||||||
property string password
|
required property string rawConnectionString
|
||||||
property string keyUid
|
|
||||||
|
|
||||||
property DevicesStore devicesStore
|
property DevicesStore devicesStore
|
||||||
property ProfileStore profileStore
|
property ProfileStore profileStore
|
||||||
@ -53,13 +52,11 @@ StatusDialog {
|
|||||||
d.connectionString = ""
|
d.connectionString = ""
|
||||||
d.errorMessage = ""
|
d.errorMessage = ""
|
||||||
|
|
||||||
const result = root.devicesStore.getConnectionStringForBootstrappingAnotherDevice(root.keyUid, root.password)
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const json = JSON.parse(result)
|
const json = JSON.parse(root.rawConnectionString)
|
||||||
d.errorMessage = json.error
|
d.errorMessage = json.error
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
d.connectionString = result
|
d.connectionString = root.rawConnectionString
|
||||||
}
|
}
|
||||||
|
|
||||||
if (d.errorMessage !== "") {
|
if (d.errorMessage !== "") {
|
||||||
|
@ -37,19 +37,14 @@ QtObject {
|
|||||||
root.devicesModule.enableDevice(installationId, enable)
|
root.devicesModule.enableDevice(installationId, enable)
|
||||||
}
|
}
|
||||||
|
|
||||||
function authenticateUser() {
|
function authenticateLoggedInUser() {
|
||||||
const keyUid = "" // TODO: Support Keycard
|
root.devicesModule.authenticateLoggedInUser()
|
||||||
root.devicesModule.authenticateUser(keyUid)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function validateConnectionString(connectionString) {
|
function validateConnectionString(connectionString) {
|
||||||
return root.devicesModule.validateConnectionString(connectionString)
|
return root.devicesModule.validateConnectionString(connectionString)
|
||||||
}
|
}
|
||||||
|
|
||||||
function getConnectionStringForBootstrappingAnotherDevice(keyUid, password) {
|
|
||||||
return root.devicesModule.getConnectionStringForBootstrappingAnotherDevice(keyUid, password)
|
|
||||||
}
|
|
||||||
|
|
||||||
function inputConnectionStringForBootstrapping(connectionString) {
|
function inputConnectionStringForBootstrapping(connectionString) {
|
||||||
return root.devicesModule.inputConnectionStringForBootstrapping(connectionString)
|
return root.devicesModule.inputConnectionStringForBootstrapping(connectionString)
|
||||||
}
|
}
|
||||||
|
@ -54,8 +54,7 @@ SettingsContentBase {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function setupSyncing() {
|
function setupSyncing() {
|
||||||
const keyUid = root.profileStore.isKeycardUser ? root.profileStore.keyUid : ""
|
root.devicesStore.authenticateLoggedInUser()
|
||||||
root.devicesStore.authenticateUser(keyUid)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -63,16 +62,9 @@ SettingsContentBase {
|
|||||||
Connections {
|
Connections {
|
||||||
target: devicesStore.devicesModule
|
target: devicesStore.devicesModule
|
||||||
|
|
||||||
function onUserAuthenticated(pin, password, keyUid) {
|
function onOpenPopupWithConnectionStringSignal(rawConnectionString) {
|
||||||
if (!password)
|
|
||||||
return
|
|
||||||
// Authentication flow returns empty keyUid for non-keycard user.
|
|
||||||
const effectiveKeyUid = root.profileStore.isKeycardUser
|
|
||||||
? keyUid
|
|
||||||
: root.profileStore.keyUid
|
|
||||||
Global.openPopup(setupSyncingPopup, {
|
Global.openPopup(setupSyncingPopup, {
|
||||||
password,
|
rawConnectionString: rawConnectionString,
|
||||||
keyUid: effectiveKeyUid
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -135,7 +127,7 @@ SettingsContentBase {
|
|||||||
timestamp: model.timestamp
|
timestamp: model.timestamp
|
||||||
isCurrentDevice: model.isCurrentDevice
|
isCurrentDevice: model.isCurrentDevice
|
||||||
onSetupSyncingButtonClicked: {
|
onSetupSyncingButtonClicked: {
|
||||||
d.setupSyncing(SetupSyncingPopup.GenerateSyncCode)
|
d.setupSyncing()
|
||||||
}
|
}
|
||||||
onClicked: {
|
onClicked: {
|
||||||
if (deviceEnabled)
|
if (deviceEnabled)
|
||||||
|
@ -14,8 +14,6 @@ QtObject {
|
|||||||
readonly property string defaultSelectedKeyUid: userProfile.keyUid
|
readonly property string defaultSelectedKeyUid: userProfile.keyUid
|
||||||
readonly property bool defaultSelectedKeyUidMigratedToKeycard: userProfile.isKeycardUser
|
readonly property bool defaultSelectedKeyUidMigratedToKeycard: userProfile.isKeycardUser
|
||||||
|
|
||||||
property bool loggedInUserAuthenticated: false
|
|
||||||
|
|
||||||
property string backButtonName: ""
|
property string backButtonName: ""
|
||||||
property var overview: walletSectionOverview
|
property var overview: walletSectionOverview
|
||||||
property var assets: walletSectionAssets.assets
|
property var assets: walletSectionAssets.assets
|
||||||
|
Loading…
x
Reference in New Issue
Block a user