feat(@desktop/syncing): keypair syncing - added support for keycard pairings

This commit is contained in:
Sale Djenic 2023-06-09 15:15:47 +02:00 committed by saledjenic
parent 7c56dc53d9
commit 241956d537
8 changed files with 52 additions and 53 deletions

View File

@ -54,10 +54,6 @@ proc init*(self: Controller) =
return
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)
self.delegate.onLocalPairingEvent(args.eventType, args.action, args.error)
self.events.on(SIGNAL_LOCAL_PAIRING_STATUS_UPDATE) do(e: Args):
let args = LocalPairingStatus(e)
self.delegate.onLocalPairingStatusUpdate(args)

View File

@ -62,8 +62,5 @@ proc validateConnectionString*(self: AccessInterface, connectionString: string):
method inputConnectionStringForBootstrapping*(self: AccessInterface, connectionString: string): string {.base.} =
raise newException(ValueError, "No implementation available")
method onLocalPairingEvent*(self: AccessInterface, eventType: EventType, action: Action, error: string) {.base.} =
raise newException(ValueError, "No implementation available")
method onLocalPairingStatusUpdate*(self: AccessInterface, status: LocalPairingStatus) {.base.} =
raise newException(ValueError, "No implementation available")

View File

@ -122,8 +122,5 @@ proc validateConnectionString*(self: Module, connectionString: string): string =
method inputConnectionStringForBootstrapping*(self: Module, connectionString: string): string =
return self.controller.inputConnectionStringForBootstrapping(connectionString)
method onLocalPairingEvent*(self: Module, eventType: EventType, action: Action, error: string) =
self.view.onLocalPairingEvent(eventType, action, error)
method onLocalPairingStatusUpdate*(self: Module, status: LocalPairingStatus) =
self.view.onLocalPairingStatusUpdate(status)

View File

@ -105,10 +105,6 @@ QtObject:
read = getLocalPairingError
notify = localPairingStatusChanged
proc localPairingEvent(self: View, eventType: int, action: int, error: string) {.signal.}
proc onLocalPairingEvent*(self: View, eventType: EventType, action: Action, error: string) =
self.localPairingEvent(ord(eventType), ord(action), error)
proc getLocalPairingInstallationId*(self: View): string {.slot.} =
return self.localPairingStatus.installation.id
QtProperty[string] localPairingInstallationId:

View File

@ -400,7 +400,8 @@ proc storeKeycardAccountAndLogin*(self: Controller, storeToKeychain: bool, newKe
self.storeMetadataForNewKeycardUser()
else:
self.syncKeycardBasedOnAppWalletStateAfterLogin()
self.accountsService.setupAccountKeycard(KeycardEvent(), self.tmpDisplayName, useImportedAcc = true)
let (_, flowEvent) = self.keycardService.getLastReceivedKeycardData() # we need this to get the correct instanceUID
self.accountsService.setupAccountKeycard(flowEvent, self.tmpDisplayName, useImportedAcc = true)
self.setupKeychain(storeToKeychain)
else:
error "an error ocurred while importing mnemonic"

View File

@ -4,7 +4,7 @@ import json_serialization, chronicles
import ../../../app/global/global_singleton
import ./dto/accounts as dto_accounts
import ./dto/generated_accounts as dto_generated_accounts
from ../keycard/service import KeycardEvent, KeyDetails
from ../keycard/service import KeycardEvent, KeyDetails
import ../../../backend/general as status_general
import ../../../backend/core as status_core
import ../../../backend/privacy as status_privacy
@ -92,11 +92,11 @@ QtObject:
proc getImportedAccount*(self: Service): GeneratedAccountDto =
return self.importedAccount
proc setKeyStoreDir(self: Service, key: string) =
proc setKeyStoreDir(self: Service, key: string) =
self.keyStoreDir = joinPath(main_constants.ROOTKEYSTOREDIR, key) & main_constants.sep
discard status_general.initKeystore(self.keyStoreDir)
proc getKeyStoreDir*(self: Service): string =
proc getKeyStoreDir*(self: Service): string =
return self.keyStoreDir
proc setDefaultWalletEmoji*(self: Service, emoji: string) =
@ -196,7 +196,7 @@ QtObject:
except Exception as e:
error "error: ", procName="saveAccountAndLogin", errName = e.name, errDesription = e.msg
proc saveKeycardAccountAndLogin(self: Service, chatKey, password: string, account, subaccounts, settings,
proc saveKeycardAccountAndLogin(self: Service, chatKey, password: string, account, subaccounts, settings,
config: JsonNode): AccountDto =
try:
let response = status_account.saveAccountAndLoginWithKeycard(chatKey, password, account, subaccounts, settings, config)
@ -347,11 +347,13 @@ QtObject:
if(main_constants.IS_MACOS and self.getLoggedInAccount.isValid()):
singletonInstance.localAccountSettings.setFileName(self.getLoggedInAccount.name)
proc addKeycardDetails(self: Service, settingsJson: var JsonNode, accountData: var JsonNode) =
proc addKeycardDetails(self: Service, kcInstance: string, settingsJson: var JsonNode, accountData: var JsonNode) =
let keycardPairingJsonString = readFile(main_constants.KEYCARDPAIRINGDATAFILE)
let keycardPairingJsonObj = keycardPairingJsonString.parseJSON
let now = now().toTime().toUnix()
for instanceUid, kcDataObj in keycardPairingJsonObj:
if instanceUid != kcInstance:
continue
if not settingsJson.isNil:
settingsJson["keycard-instance-uid"] = %* instanceUid
settingsJson["keycard-paired-on"] = %* now
@ -377,12 +379,12 @@ QtObject:
let hashedPassword = hashPassword(password)
discard self.storeAccount(accountId, hashedPassword)
discard self.storeDerivedAccounts(accountId, hashedPassword, PATHS)
self.loggedInAccount = self.saveAccountAndLogin(hashedPassword,
self.loggedInAccount = self.saveAccountAndLogin(hashedPassword,
accountDataJson,
subaccountDataJson,
settingsJson,
subaccountDataJson,
settingsJson,
nodeConfigJson)
self.setLocalAccountSettingsFile()
if self.getLoggedInAccount.isValid():
@ -393,7 +395,7 @@ QtObject:
error "error: ", procName="setupAccount", errName = e.name, errDesription = e.msg
return e.msg
proc setupAccountKeycard*(self: Service, keycardData: KeycardEvent, displayName: string, useImportedAcc: bool) =
proc setupAccountKeycard*(self: Service, keycardData: KeycardEvent, displayName: string, useImportedAcc: bool) =
try:
var keyUid = keycardData.keyUid
var address = keycardData.masterKey.address
@ -422,7 +424,7 @@ QtObject:
let installationId = $genUUID()
let alias = generateAliasFromPk(whisperPublicKey)
var accountDataJson = %* {
"name": if displayName == "": alias else: displayName,
"display-name": displayName,
@ -482,19 +484,19 @@ QtObject:
}
}
self.addKeycardDetails(settingsJson, accountDataJson)
self.addKeycardDetails(keycardData.instanceUID, settingsJson, accountDataJson)
if(accountDataJson.isNil or subaccountDataJson.isNil or settingsJson.isNil or
nodeConfigJson.isNil):
let description = "at least one json object is not prepared well"
error "error: ", procName="setupAccountKeycard", errDesription = description
return
self.loggedInAccount = self.saveKeycardAccountAndLogin(chatKey = whisperPrivateKey,
password = encryptionPublicKey,
accountDataJson,
subaccountDataJson,
settingsJson,
self.loggedInAccount = self.saveKeycardAccountAndLogin(chatKey = whisperPrivateKey,
password = encryptionPublicKey,
accountDataJson,
subaccountDataJson,
settingsJson,
nodeConfigJson)
self.setLocalAccountSettingsFile()
except Exception as e:
@ -708,7 +710,7 @@ QtObject:
)
self.threadpool.start(arg)
return
self.doLogin(account, hashedPassword, thumbnailImage, largeImage, nodeCfg)
except Exception as e:
error "error: ", procName="login", errName = e.name, errDesription = e.msg
@ -721,7 +723,7 @@ QtObject:
# Normal login after reencryption
self.doLogin(self.tmpAccount, self.tmpHashedPassword, self.tmpThumbnailImage, self.tmpLargeImage, self.tmpNodeCfg)
# Clear out the temp properties
self.tmpAccount = AccountDto()
self.tmpHashedPassword = ""
@ -729,20 +731,15 @@ QtObject:
self.tmpLargeImage = ""
self.tmpNodeCfg = JsonNode()
proc loginAccountKeycard*(self: Service, accToBeLoggedIn: AccountDto, keycardData: KeycardEvent): string =
proc loginAccountKeycard*(self: Service, accToBeLoggedIn: AccountDto, keycardData: KeycardEvent): string =
try:
self.setKeyStoreDir(keycardData.keyUid)
var accountDataJson = %* {
"name": accToBeLoggedIn.name,
"address": keycardData.masterKey.address,
"key-uid": keycardData.keyUid,
"kdfIterations": KDF_ITERATIONS,
"key-uid": accToBeLoggedIn.keyUid,
}
var settingsJson: JsonNode
self.addKeycardDetails(settingsJson, accountDataJson)
let response = status_account.loginWithKeycard(keycardData.whisperKey.privateKey,
let response = status_account.loginWithKeycard(keycardData.whisperKey.privateKey,
keycardData.encryptionKey.publicKey,
accountDataJson)
@ -753,21 +750,20 @@ QtObject:
debug "Account logged in succesfully"
# this should be fetched later from waku
self.loggedInAccount = accToBeLoggedIn
self.loggedInAccount.keycardPairing = accountDataJson{"keycard-pairing"}.getStr
return
except Exception as e:
error "error: ", procName="loginAccountKeycard", errName = e.name, errDesription = e.msg
return e.msg
proc convertToKeycardAccount*(self: Service, keycardUid, currentPassword: string, newPassword: string) =
proc convertToKeycardAccount*(self: Service, keycardUid, currentPassword: string, newPassword: string) =
var accountDataJson = %* {
"key-uid": self.getLoggedInAccount().keyUid,
"kdfIterations": KDF_ITERATIONS
}
var settingsJson = %* { }
self.addKeycardDetails(settingsJson, accountDataJson)
self.addKeycardDetails(keycardUid, settingsJson, accountDataJson)
if(accountDataJson.isNil or settingsJson.isNil):
let description = "at least one json object is not prepared well"
error "error: ", procName="convertToKeycardAccount", errDesription = description
@ -802,7 +798,7 @@ QtObject:
error "error handilng migrated keypair response", errDesription=e.msg
self.events.emit(SIGNAL_CONVERTING_PROFILE_KEYPAIR, ResultArgs(success: result))
proc convertToRegularAccount*(self: Service, mnemonic: string, currentPassword: string, newPassword: string): string =
proc convertToRegularAccount*(self: Service, mnemonic: string, currentPassword: string, newPassword: string): string =
let hashedPassword = hashPassword(newPassword)
try:
let response = status_account.convertToRegularAccount(mnemonic, currentPassword, hashedPassword)

View File

@ -29,6 +29,7 @@ type
account*: AccountDTO
password*: string
chatKey*: string
keycardPairings*: string
type
LocalPairingEventArgs* = ref object of Args
@ -77,6 +78,7 @@ proc toLocalPairingAccountData*(jsonObj: JsonNode): LocalPairingAccountData =
result = LocalPairingAccountData()
discard jsonObj.getProp("password", result.password)
discard jsonObj.getProp("chatKey", result.chatKey)
discard jsonObj.getProp("keycardPairings", result.keycardPairings)
var accountObj: JsonNode
if(jsonObj.getProp("account", accountObj)):

View File

@ -46,7 +46,6 @@ type
const SIGNAL_UPDATE_DEVICE* = "updateDevice"
const SIGNAL_DEVICES_LOADED* = "devicesLoaded"
const SIGNAL_ERROR_LOADING_DEVICES* = "devicesErrorLoading"
const SIGNAL_LOCAL_PAIRING_EVENT* = "localPairingEvent"
const SIGNAL_LOCAL_PAIRING_STATUS_UPDATE* = "localPairingStatusUpdate"
const SIGNAL_INSTALLATION_NAME_UPDATED* = "installationNameUpdated"
@ -75,10 +74,20 @@ QtObject:
result.localPairingStatus = newLocalPairingStatus()
proc updateLocalPairingStatus(self: Service, data: LocalPairingEventArgs) =
self.events.emit(SIGNAL_LOCAL_PAIRING_EVENT, data)
self.localPairingStatus.update(data)
self.events.emit(SIGNAL_LOCAL_PAIRING_STATUS_UPDATE, self.localPairingStatus)
proc createKeycardPairingFile(data: string) =
var file = open(main_constants.KEYCARDPAIRINGDATAFILE, fmWrite)
if file == nil:
error "failed to open local keycard pairing file"
return
try:
file.write(data)
except:
error "failed to write data to local keycard pairing file"
file.close()
proc doConnect(self: Service) =
self.events.on(SignalType.Message.event) do(e:Args):
let receivedData = MessageSignal(e)
@ -89,6 +98,8 @@ QtObject:
self.events.on(SignalType.LocalPairing.event) do(e:Args):
let signalData = LocalPairingSignal(e)
if not signalData.accountData.isNil and signalData.accountData.keycardPairings.len > 0:
createKeycardPairingFile(signalData.accountData.keycardPairings)
let data = LocalPairingEventArgs(
eventType: signalData.eventType,
action: signalData.action,
@ -179,9 +190,11 @@ QtObject:
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)
var finalPassword = utils.hashPassword(password)
var keycardPairingJsonString = ""
if keycardUser:
finalPassword = password
keycardPairingJsonString = readFile(main_constants.KEYCARDPAIRINGDATAFILE)
let configJSON = %* {
"senderConfig": %* {
@ -190,6 +203,7 @@ QtObject:
"keyUID": keyUid,
"password": finalPassword,
"chatKey": chatKey,
"keycardPairings": keycardPairingJsonString
},
"serverConfig": %* {
"timeout": 5 * 60 * 1000,