From ef31cba9832643229ebcde9bf72493f644173411 Mon Sep 17 00:00:00 2001 From: Sosthene Date: Mon, 8 Sep 2025 21:59:08 +0200 Subject: [PATCH] Improve checkConnections to prevent no shared secrets --- src/services/service.ts | 109 +++++++++++++++++++++++++--------------- 1 file changed, 68 insertions(+), 41 deletions(-) diff --git a/src/services/service.ts b/src/services/service.ts index baa0343..c06b700 100755 --- a/src/services/service.ts +++ b/src/services/service.ts @@ -208,12 +208,48 @@ export default class Services { } } - public async checkConnections(members: Member[]): Promise { + // If we're updating a process, we must call that after update especially if roles are part of it + // We will take the roles from the last state, wheter it's commited or not + public async checkConnections(process: Process): Promise { + if (process.states.length < 2) { + throw new Error('Process doesn\'t have any state yet'); + } + let roles = process.states[process.states.length - 2].roles; + if (!roles) { + throw new Error('No roles found'); + } else { + console.log('roles found', roles); + } + let members: Set = new Set(); + for (const role of Object.values(roles!)) { + for (const member of role.members) { + // Check if we know the member that matches this id + const memberAddresses = this.getAddressesForMemberId(member); + if (memberAddresses && memberAddresses.length != 0) { + members.add({ sp_addresses: memberAddresses }); + } + } + } + + if (members.size === 0) { + // This must be a pairing process + // Check if we have a pairedAddresses in the public data + const publicData = process.states[0]?.public_data; + if (!publicData || !publicData['pairedAddresses']) { + throw new Error('Not a pairing process'); + } + const decodedAddresses = this.decodeValue(publicData['pairedAddresses']); + if (decodedAddresses.length === 0) { + throw new Error('Not a pairing process'); + } + members.add({ sp_addresses: decodedAddresses }); + } + // Ensure the amount is available before proceeding await this.getTokensFromFaucet(); - let unconnectedAddresses: Set = new Set(); + let unconnectedAddresses = new Set(); const myAddress = this.getDeviceAddress(); - for (const member of members) { + for (const member of Array.from(members)) { const sp_addresses = member.sp_addresses; if (!sp_addresses || sp_addresses.length === 0) continue; for (const address of sp_addresses) { @@ -226,7 +262,7 @@ export default class Services { } } if (unconnectedAddresses && unconnectedAddresses.size != 0) { - const apiResult = await this.connectAddresses([...unconnectedAddresses]); + const apiResult = await this.connectAddresses(Array.from(unconnectedAddresses)); await this.handleApiReturn(apiResult); } } @@ -374,19 +410,6 @@ export default class Services { console.log('encoded data:', encodedPrivateData); console.log('encoded data:', encodedPublicData); - let members: Set = new Set(); - for (const role of Object.values(roles!)) { - for (const member of role.members) { - // Check if we know the member that matches this id - const memberAddresses = this.getAddressesForMemberId(member); - if (memberAddresses && memberAddresses.length != 0) { - members.add({ sp_addresses: memberAddresses }); - } - } - } - console.log('members:', members); - await this.checkConnections([...members]); - const result = this.sdkClient.create_new_process ( encodedPrivateData, roles, @@ -396,7 +419,12 @@ export default class Services { this.getAllMembers() ); - return(result); + if (result.updated_process) { + await this.checkConnections(result.updated_process); + return(result); + } else { + throw new Error('Empty updated_process in createProcessReturn'); + } } public async updateProcess(process: Process, privateData: Record, publicData: Record, roles: Record | null): Promise { @@ -407,26 +435,6 @@ export default class Services { // We should check that we have the right to change the roles here, or maybe it's better leave it to the wasm console.log('Provided new roles:', JSON.stringify(roles)); } - let members: Set = new Set(); - for (const role of Object.values(roles!)) { - for (const member of role.members) { - members.add(member) - } - } - if (members.size === 0) { - // This must be a pairing process - // Check if we have a pairedAddresses in the public data - const publicData = this.getPublicData(process); - if (!publicData || !publicData['pairedAddresses']) { - throw new Error('Not a pairing process'); - } - const decodedAddresses = this.decodeValue(publicData['pairedAddresses']); - if (decodedAddresses.length === 0) { - throw new Error('Not a pairing process'); - } - members.add({ sp_addresses: decodedAddresses }); - } - await this.checkConnections([...members]); const privateSplitData = this.splitData(privateData); const publicSplitData = this.splitData(publicData); const encodedPrivateData = { @@ -438,7 +446,13 @@ export default class Services { ...this.sdkClient.encode_binary(publicSplitData.binaryData) }; try { - return this.sdkClient.update_process(process, encodedPrivateData, roles, encodedPublicData, this.getAllMembers()); + const result = this.sdkClient.update_process(process, encodedPrivateData, roles, encodedPublicData, this.getAllMembers()); + if (result.updated_process) { + await this.checkConnections(result.updated_process); + return(result); + } else { + throw new Error('Empty updated_process in updateProcessReturn'); + } } catch (e) { throw new Error(`Failed to update process: ${e}`); } @@ -450,7 +464,13 @@ export default class Services { throw new Error('Unknown process'); } try { - return this.sdkClient.create_update_message(process, stateId, this.getAllMembers()); + const result = this.sdkClient.create_update_message(process, stateId, this.getAllMembers()); + if (result.updated_process) { + await this.checkConnections(result.updated_process); + return(result); + } else { + throw new Error('Empty updated_process in createPrdUpdateReturn'); + } } catch (e) { throw new Error(`Failed to create prd update: ${e}`); } @@ -474,7 +494,13 @@ export default class Services { throw new Error('Failed to get process from db'); } try { - return this.sdkClient.validate_state(process, stateId, this.getAllMembers()); + const result = this.sdkClient.validate_state(process, stateId, this.getAllMembers()); + if (result.updated_process) { + await this.checkConnections(result.updated_process); + return(result); + } else { + throw new Error('Empty updated_process in approveChangeReturn'); + } } catch (e) { throw new Error(`Failed to create prd response: ${e}`); } @@ -1215,6 +1241,7 @@ export default class Services { if (!hasAccess) return null; + await this.checkConnections((await this.getProcess(processId))!); // We should have the key, so we're going to ask other members for it await this.requestDataFromPeers(processId, [state.state_id], [state.roles]);