Skip to content

Commit

Permalink
Build nonmediated connection from oob msg
Browse files Browse the repository at this point in the history
Signed-off-by: Miroslav Kovar <miroslav.kovar@absa.africa>
  • Loading branch information
mirgee committed Jan 24, 2023
1 parent 74bc762 commit 332fe81
Show file tree
Hide file tree
Showing 16 changed files with 158 additions and 631 deletions.
4 changes: 2 additions & 2 deletions agents/node/vcxagent-core/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@
"demo:faber:mysql": "node demo/faber.js --mysql",
"demo:alice:sign": "node demo/alice-signature.js",
"demo:faber:verify": "node demo/faber-verify-signature.js",
"test:integration": "npm run test:integration:issue-verify && npm run test:integration:signing && npm run test:integration:messaging && npm run test:integration:tails && npm run test:integration:trustping && npm run test:integration:feature-discovery && npm run test:integration:public-invite && npm run test:integration:out-of-band && npm run test:integration:nonmediation",
"test:integration": "npm run test:integration:issue-verify && npm run test:integration:signing && npm run test:integration:messaging && npm run test:integration:tails && npm run test:integration:trustping && npm run test:integration:feature-discovery && npm run test:integration:public-invite && npm run test:integration:out-of-band && npm run test:integration:nonmediation && test:integration:nonmediated-connection",
"test:integration:issue-verify": "jest --forceExit --env=node --runInBand test/issue-verify.spec.js",
"test:integration:signing": "jest --forceExit --env=node --runInBand test/sign-verify.spec.js",
"test:integration:messaging": "jest --forceExit --env=node --runInBand test/messaging.spec.js",
Expand All @@ -44,7 +44,7 @@
"test:integration:feature-discovery": "jest --forceExit --env=node --runInBand test/feature-discovery.spec.js",
"test:integration:public-invite": "jest --forceExit --env=node --runInBand test/public-invite.spec.js",
"test:integration:out-of-band": "jest --forceExit --env=node --runInBand test/out-of-band.spec.js",
"test:integration:nonmediation": "jest --forceExit --env=node --runInBand test/nonmediated-endpoint.spec.js",
"test:integration:nonmediated-endpoint": "jest --forceExit --env=node --runInBand test/nonmediated-endpoint.spec.js",
"test:integration:nonmediated-connection": "jest --forceExit --env=node --runInBand test/nonmediated-connection.spec.js"
},
"dependencies": {
Expand Down
4 changes: 3 additions & 1 deletion agents/node/vcxagent-core/src/agent.js
Original file line number Diff line number Diff line change
Expand Up @@ -138,7 +138,9 @@ async function createVcxAgent({ agentName, genesisPath, agencyUrl, seed, walletE
const serviceOutOfBand = createServiceOutOfBand({
logger,
saveConnection: storageService.saveConnection,
loadConnection: storageService.loadConnection
loadConnection: storageService.loadConnection,
saveNonmediatedConnection: storageService.saveNonmediatedConnection,
endpointInfo
})

return {
Expand Down
13 changes: 12 additions & 1 deletion agents/node/vcxagent-core/src/services/service-out-of-band.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
const { OutOfBandSender, OutOfBandReceiver } = require('@hyperledger/node-vcx-wrapper')
const assert = require('assert')

module.exports.createServiceOutOfBand = function createServiceOutOfBand ({ logger, saveConnection, loadConnection, saveNonmediatedConnection, endpointInfo }) {
assert(endpointInfo.serviceEndpoint)
assert(endpointInfo.routingKeys)

module.exports.createServiceOutOfBand = function createServiceOutOfBand ({ logger, saveConnection, loadConnection }) {
function _createOobSender (message, label) {
const oob = OutOfBandSender.create({ label })
if (message) {
Expand All @@ -27,6 +31,12 @@ module.exports.createServiceOutOfBand = function createServiceOutOfBand ({ logge
await saveConnection(connectionId, connection)
}

async function createNonmediatedConnectionFromOobMsg (connectionId, oobMsg) {
const oob = OutOfBandReceiver.createWithMessage(oobMsg)
const connection = await oob.buildNonmediatedConnection(endpointInfo)
await saveNonmediatedConnection(connectionId, connection)
}

async function reuseConnectionFromOobMsg (connectionId, oobMsg) {
const connection = await loadConnection(connectionId)
await connection.sendHandshakeReuse(oobMsg)
Expand All @@ -51,6 +61,7 @@ module.exports.createServiceOutOfBand = function createServiceOutOfBand ({ logge
return {
createOobMessageWithDid,
createConnectionFromOobMsg,
createNonmediatedConnectionFromOobMsg,
connectionExists,
reuseConnectionFromOobMsg
}
Expand Down
66 changes: 65 additions & 1 deletion agents/node/vcxagent-core/test/nonmediated-connection.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,6 @@ describe('test establishing and exchanging messages via nonmediated connections'

await alice.nonmediatedConnectionSendMessage('Hello Faber')
const { message: msgFaber } = await faber.unpackMsg(faberEncryptedMsg)
console.log(`msgFaber = ${msgFaber}`)
expect(JSON.parse(msgFaber).content).toBe('Hello Faber')

await faber.nonmediatedConnectionSendMessage('Hello Alice')
Expand Down Expand Up @@ -122,6 +121,71 @@ describe('test establishing and exchanging messages via nonmediated connections'
const { message: ack } = await faber.unpackMsg(faberEncryptedMsg)
await faber.nonmediatedConnectionProcessAck(ack)

await alice.nonmediatedConnectionSendMessage('Hello Faber')
const { message: msgFaber } = await faber.unpackMsg(faberEncryptedMsg)
expect(JSON.parse(msgFaber).content).toBe('Hello Faber')

await faber.nonmediatedConnectionSendMessage('Hello Alice')
const { message: msgAlice } = await alice.unpackMsg(aliceEncryptedMsg)
expect(JSON.parse(msgAlice).content).toBe('Hello Alice')

} catch (err) {
console.error(`err = ${err.message} stack = ${err.stack}`)
throw Error(err)
} finally {
if (faberServer) {
faberServer.close()
}
if (aliceServer) {
aliceServer.close()
}
await sleep(2000)
}
})

it('Establish nonmediated connection via public endpoint using OOB invite, exchange messages', async () => {
let faberServer
try {
const path = '/msg'
const faberPort = 5404
const faberEndpoint = `http://127.0.0.1:${faberPort}${path}`

let faberEncryptedMsg
const faberApp = express()
faberApp.use(bodyParser.raw({ type: '*/*' }))
faberApp.post(path, (req, res) => {
faberEncryptedMsg = req.body
res.status(200).send()
})
faberServer = faberApp.listen(faberPort)

const alicePort = 5405
const aliceEndpoint = `http://127.0.0.1:${alicePort}${path}`

let aliceEncryptedMsg
const aliceApp = express()
aliceApp.use(bodyParser.raw({ type: '*/*' }))
aliceApp.post(path, (req, res) => {
aliceEncryptedMsg = req.body
res.status(200).send()
})
aliceServer = aliceApp.listen(alicePort)

const { alice, faber } = await createAliceAndFaber({ aliceEndpoint, faberEndpoint })

const pwInfo = await faber.publishService(faberEndpoint)
const msg = await faber.createOobMessageWithDid()
await alice.createNonmediatedConnectionUsingOobMessage(msg)

const { message: request } = await faber.unpackMsg(faberEncryptedMsg)
await faber.createNonmediatedConnectionFromRequest(request, pwInfo)

const { message: response } = await alice.unpackMsg(aliceEncryptedMsg)
await alice.nonmediatedConnectionProcessResponse(response)

const { message: ack } = await faber.unpackMsg(faberEncryptedMsg)
await faber.nonmediatedConnectionProcessAck(ack)

await alice.nonmediatedConnectionSendMessage('Hello Faber')
const { message: msgFaber } = await faber.unpackMsg(faberEncryptedMsg)
console.log(`msgFaber = ${msgFaber}`)
Expand Down
11 changes: 11 additions & 0 deletions agents/node/vcxagent-core/test/utils/alice.js
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,16 @@ module.exports.createAlice = async function createAlice (serviceEndpoint = 'http
await vcxAgent.agentShutdownVcx()
}

async function createNonmediatedConnectionUsingOobMessage (oobMsg) {
logger.info('createNonmediatedConnectionUsingOobMessage >> Alice going to create connection using oob message')
logger.debug(`createNonmediatedConnectionUsingOobMessage >> oobMsg = ${oobMsg}`)
await vcxAgent.agentInitVcx()

await vcxAgent.serviceOutOfBand.createNonmediatedConnectionFromOobMsg(connectionId, oobMsg)

await vcxAgent.agentShutdownVcx()
}

async function createOrReuseConnectionUsingOobMsg (oobMsg) {
logger.info('createOrReuseConnectionUsingOobMsg >> Alice going to create or reuse connection using oob message')
logger.debug(`createOrReuseConnectionUsingOobMsg >> oobMsg = ${oobMsg}`)
Expand Down Expand Up @@ -255,6 +265,7 @@ module.exports.createAlice = async function createAlice (serviceEndpoint = 'http
createNonmediatedConnectionFromInvite,
nonmediatedConnectionProcessResponse,
createConnectionUsingOobMessage,
createNonmediatedConnectionUsingOobMessage,
createOrReuseConnectionUsingOobMsg,
acceptOobCredentialOffer,
updateConnection,
Expand Down
6 changes: 3 additions & 3 deletions aries_vcx/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,8 @@ doctest = false
[features]
test_utils = [ "messages/test_utils" ]
pool_tests = [ "test_utils" ]
agency_pool_tests = ["test_utils" ]
general_test = ["test_utils", "messages/general_test" ]
agency_pool_tests = [ "test_utils" ]
general_test = [ "test_utils", "messages/general_test" ]
fatal_warnings = []
warnlog_fetched_messages = []
mysql_test = ["test_utils" ]
Expand Down Expand Up @@ -54,7 +54,7 @@ indy-credx = { git = "https://github.com/anonyome/indy-shared-rs.git", rev = "73
# ----------------------
futures = { version = "0.3", default-features = false }
libloading = "0.5.0"
uuid = { version = "0.8", default-features = false, features = ["v4"]}
uuid = { version = "0.8", default-features = false, features = ["v4"] }
strum = "0.16.0"
strum_macros = "0.16.0"
agency_client = { path = "../agency_client" }
Expand Down
16 changes: 16 additions & 0 deletions aries_vcx/src/handlers/out_of_band/receiver.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ use agency_client::agency_client::AgencyClient;
use crate::common::ledger::transactions::resolve_service;
use crate::core::profile::profile::Profile;
use crate::errors::error::prelude::*;
use crate::handlers::connection::connection::Connection;
use crate::handlers::connection::mediated_connection::MediatedConnection;
use messages::a2a::A2AMessage;
use messages::concepts::attachment::AttachmentId;
Expand Down Expand Up @@ -157,6 +158,21 @@ impl OutOfBandReceiver {
.await
}

pub async fn build_nonmediated_connection(
&self,
profile: &Arc<dyn Profile>,
did_doc: AriesDidDoc,
service_endpoint: String,
routing_keys: Vec<String>,
) -> VcxResult<Connection> {
trace!("OutOfBandReceiver::build_nonmediated_connection >>>",);
Connection::create_invitee(profile, did_doc)
.await?
.process_invite(Invitation::OutOfBand(self.oob.clone()))?
.send_request(profile, service_endpoint, routing_keys, None)
.await
}

pub fn to_a2a_message(&self) -> A2AMessage {
self.oob.to_a2a_message()
}
Expand Down
17 changes: 17 additions & 0 deletions libvcx/src/api_vcx/api_handle/out_of_band.rs
Original file line number Diff line number Diff line change
Expand Up @@ -176,6 +176,7 @@ pub async fn connection_exists(handle: u32, conn_handles: &Vec<u32>) -> LibvcxRe
}

pub async fn build_connection(handle: u32) -> LibvcxResult<String> {
trace!("build_connection >>> handle: {}", handle);
let oob = OUT_OF_BAND_RECEIVER_MAP.get_cloned(handle)?;
let invitation = Invitation::OutOfBand(oob.oob.clone());
let profile = get_main_profile()?;
Expand All @@ -186,6 +187,22 @@ pub async fn build_connection(handle: u32) -> LibvcxResult<String> {
.map_err(|err| err.into())
}

pub async fn build_nonmediated_connection(
handle: u32,
service_endpoint: String,
routing_keys: Vec<String>,
) -> LibvcxResult<String> {
trace!("build_nonmediated_connection >>> handle: {}", handle);
let oob = OUT_OF_BAND_RECEIVER_MAP.get_cloned(handle)?;
let invitation = Invitation::OutOfBand(oob.oob.clone());
let profile = get_main_profile()?;
let ddo = into_did_doc(&profile, &invitation).await?;
oob.build_nonmediated_connection(&profile, ddo, service_endpoint, routing_keys)
.await?
.to_string()
.map_err(|err| err.into())
}

pub fn get_thread_id_sender(handle: u32) -> LibvcxResult<String> {
trace!("get_thread_id_sender >>> handle: {}", handle);
OUT_OF_BAND_SENDER_MAP.get(handle, |oob| Ok(oob.get_id()))
Expand Down
11 changes: 11 additions & 0 deletions wrappers/node/src/api/out-of-band-receiver.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import { IOOBSerializedData } from './out-of-band-sender';
import { Connection } from './mediated-connection';
import { VcxBase } from './vcx-base';
import { ISerializedData } from './common';
import { IEndpointInfo, NonmediatedConnection } from './connection';

export class OutOfBandReceiver extends VcxBase<IOOBSerializedData> {
public static createWithMessage(msg: string): OutOfBandReceiver {
Expand Down Expand Up @@ -52,6 +53,16 @@ export class OutOfBandReceiver extends VcxBase<IOOBSerializedData> {
}
}

public async buildNonmediatedConnection(endpointInfo: IEndpointInfo): Promise<NonmediatedConnection> {
try {
const { serviceEndpoint, routingKeys } = endpointInfo;
const connection = await ffi.outOfBandReceiverBuildNonmediatedConnection(this.handle, serviceEndpoint, routingKeys);
return NonmediatedConnection.deserialize({ data: connection, version: '1.0', source_id: '' });
} catch (err: any) {
throw new VCXInternalError(err);
}
}

public getThreadId(): string {
try {
return ffi.outOfBandReceiverGetThreadId(this.handle);
Expand Down
10 changes: 4 additions & 6 deletions wrappers/vcx-napi-rs/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,11 +1,9 @@
[package]
name = "vcx-napi-rs"
version = "1.0.0"
edition = "2021"
# version.workspace = true
# authors.workspace = true
# license.workspace = true
# edition.workspace = true
version.workspace = true
authors.workspace = true
license.workspace = true
edition.workspace = true

[lib]
name = "vcx_napi_rs"
Expand Down
Loading

0 comments on commit 332fe81

Please sign in to comment.