diff --git a/src/tests/controllers/tribe3Messages.test.ts b/src/tests/controllers/tribe3Messages.test.ts index b04a7d576..b555b4dc3 100644 --- a/src/tests/controllers/tribe3Messages.test.ts +++ b/src/tests/controllers/tribe3Messages.test.ts @@ -9,6 +9,20 @@ import { getCheckNewMsgs, getTribeByUuid, getCheckTribe } from '../utils/get' import nodes from '../nodes' +const emptyNodeConfig = { + alias: '', + pubkey: '', + ip: '', + external_ip: '', + authToken: '', + transportToken: '', + contact_key: '', + privkey: '', + exported_keys: '', + pin: '', + routeHint: '', +} + /* npx ava test-10-tribe3Msgs.js --verbose --serial --timeout=2m */ @@ -18,6 +32,17 @@ test('test-10-tribe3Msgs: create tribe, two nodes join tribe, send messages, 2 n }) export async function tribe3Msgs(t, node1, node2, node3) { + //This is checking if the proxy nodes exist and if they + // do then we'll use them + let useProxyNodes = false + let proxyNode1 = emptyNodeConfig + let proxyNode2 = emptyNodeConfig + if (nodes.length > 4) { + useProxyNodes = true + proxyNode1 = nodes[3] + proxyNode2 = nodes[4] + } + // if running "no-alice" version with local relay const internalTribeHost = node1.ip.includes('host.docker.internal') ? config.tribeHost @@ -27,6 +52,7 @@ export async function tribe3Msgs(t, node1, node2, node3) { t.truthy(node3, 'this test requires three nodes') console.log(`${node1.alias} and ${node2.alias} and ${node3.alias}`) + console.log(`also using proxy ${proxyNode1.alias}, ${proxyNode2.alias}`) //NODE1 CREATES A TRIBE let tribe = await createTribe(t, node1) @@ -42,6 +68,16 @@ export async function tribe3Msgs(t, node1, node2, node3) { let join2 = await joinTribe(t, node3, tribe) t.true(join2, 'node3 should join tribe') + if (useProxyNodes) { + //PROXYNODE1 JOINS TRIBE CREATED BY NODE1 + let joinProxy1 = await joinTribe(t, proxyNode1, tribe) + t.true(joinProxy1, 'proxyNode1 should join tribe') + + //PROXYNODE2 JOINS TRIBE CREATED BY NODE1 + let proxyJoin2 = await joinTribe(t, proxyNode2, tribe) + t.true(proxyJoin2, 'proxyNode2 should join tribe') + } + //NODE1 SENDS A TEXT MESSAGE IN TRIBE const text = randomText() let tribeMessage = await sendTribeMessage(t, node1, tribe, text) @@ -108,6 +144,55 @@ export async function tribe3Msgs(t, node1, node2, node3) { ) t.true(n2check2, 'node2 should have read and decrypted node3 message') + if (useProxyNodes) { + //proxyNode1 SENDS A TEXT MESSAGE IN TRIBE + const text4 = randomText() + let tribeMessage4 = await sendTribeMessage(t, proxyNode2, tribe, text4) + + //CHECK THAT proxyNode1'S DECRYPTED MESSAGE IS SAME AS INPUT From node1's point of view + const n1check3 = await checkMessageDecryption( + t, + node1, + tribeMessage4.uuid, + text4 + ) + t.true( + n1check3, + "node1 should have read and decrypted proxyNode1's message" + ) + + //CHECK THAT NODE2'S DECRYPTED MESSAGE IS SAME AS INPUT + const n4check2 = await checkMessageDecryption( + t, + proxyNode1, + tribeMessage2.uuid, + text2 + ) + t.true(n4check2, 'proxyNode1 should have read and decrypted node2 message') + + //PROXYNODE2 SENDS A TEXT MESSAGE IN TRIBE + const text5 = randomText() + let tribeMessage5 = await sendTribeMessage(t, proxyNode2, tribe, text5) + + //CHECK THAT NODE3'S DECRYPTED MESSAGE IS SAME AS INPUT AS NODE1 + const n5check2 = await checkMessageDecryption( + t, + node1, + tribeMessage5.uuid, + text5 + ) + t.true(n5check2, 'node1 should have read and decrypted node3 message') + + //CHECK THAT NODE2'S DECRYPTED MESSAGE IS SAME AS INPUT + const n5check3 = await checkMessageDecryption( + t, + proxyNode2, + tribeMessage2.uuid, + text2 + ) + t.true(n5check3, 'node2 should have read and decrypted node3 message') + } + /***** Here we want to create a new message channel for a tribe ******/ diff --git a/src/utils/tribes.ts b/src/utils/tribes.ts index 41d124c2a..cbd58e1c7 100644 --- a/src/utils/tribes.ts +++ b/src/utils/tribes.ts @@ -56,68 +56,66 @@ async function initializeClient( host: string, onMessage?: (topic: string, message: Buffer) => void ): Promise { - return new Promise(async (resolve) => { - let connected = false - async function reconnect() { - try { - const pwd = await genSignedTimestamp(pubkey) - if (connected) return - const url = mqttURL(host) - const cl = mqtt.connect(url, { - username: pubkey, - password: pwd, - reconnectPeriod: 0, // dont auto reconnect + let connected = false + async function reconnect() { + try { + const pwd = await genSignedTimestamp(pubkey) + if (connected) return + const url = mqttURL(host) + const cl = mqtt.connect(url, { + username: pubkey, + password: pwd, + reconnectPeriod: 0, // dont auto reconnect + }) + sphinxLogger.info(`try to connect: ${url}`, logging.Tribes) + cl.on('connect', async function () { + // first check if its already connected to this host (in case it takes a long time) + connected = true + if ( + clients[pubkey] && + clients[pubkey][host] && + clients[pubkey][host].connected + ) { + return clients[pubkey][host] + return + } + sphinxLogger.info(`connected!`, logging.Tribes) + if (!clients[pubkey]) clients[pubkey] = {} + clients[pubkey][host] = cl // ADD TO MAIN STATE + cl.on('close', function (e) { + sphinxLogger.info(`CLOSE ${e}`, logging.Tribes) + // setTimeout(() => reconnect(), 2000); + connected = false + if (clients[pubkey] && clients[pubkey][host]) { + delete clients[pubkey][host] + } }) - sphinxLogger.info(`try to connect: ${url}`, logging.Tribes) - cl.on('connect', async function () { - // first check if its already connected to this host (in case it takes a long time) - connected = true - if ( - clients[pubkey] && - clients[pubkey][host] && - clients[pubkey][host].connected - ) { - resolve(clients[pubkey][host]) - return + cl.on('error', function (e) { + sphinxLogger.error(`error: ${e.message}`, logging.Tribes) + }) + cl.on('message', function (topic, message) { + // console.log("============>>>>> GOT A MSG", topic, message) + if (onMessage) onMessage(topic, message) + }) + cl.subscribe(`${pubkey}/#`, function (err) { + if (err) + sphinxLogger.error(`error subscribing ${err}`, logging.Tribes) + else { + sphinxLogger.info(`subscribed! ${pubkey}/#`, logging.Tribes) + return cl } - sphinxLogger.info(`connected!`, logging.Tribes) - if (!clients[pubkey]) clients[pubkey] = {} - clients[pubkey][host] = cl // ADD TO MAIN STATE - cl.on('close', function (e) { - sphinxLogger.info(`CLOSE ${e}`, logging.Tribes) - // setTimeout(() => reconnect(), 2000); - connected = false - if (clients[pubkey] && clients[pubkey][host]) { - delete clients[pubkey][host] - } - }) - cl.on('error', function (e) { - sphinxLogger.error(`error: ${e.message}`, logging.Tribes) - }) - cl.on('message', function (topic, message) { - // console.log("============>>>>> GOT A MSG", topic, message) - if (onMessage) onMessage(topic, message) - }) - cl.subscribe(`${pubkey}/#`, function (err) { - if (err) - sphinxLogger.error(`error subscribing ${err}`, logging.Tribes) - else { - sphinxLogger.info(`subscribed! ${pubkey}/#`, logging.Tribes) - resolve(cl) - } - }) }) - } catch (e) { - sphinxLogger.error(`error initializing ${e}`, logging.Tribes) - } + }) + } catch (e) { + sphinxLogger.error(`error initializing ${e}`, logging.Tribes) } - while (true) { - if (!connected) { - reconnect() - } - await sleep(5000 + Math.round(Math.random() * 8000)) + } + while (true) { + if (!connected) { + reconnect() } - }) + await sleep(5000 + Math.round(Math.random() * 8000)) + } } async function lazyClient(