device.js
function sendPreparedMessageToConnectedHub(ws, recipient_device_pubkey, message_hash, json, callbacks){
	network.sendRequest(ws, 'hub/get_temp_pubkey', recipient_device_pubkey, false, function(ws, request, response){
		function handleError(error){
			callbacks.ifError(error);
			db.query("UPDATE outbox SET last_error=? WHERE message_hash=?", [error, message_hash], function(){});
		}
		if (response.error)
			return handleError(response.error);
		var objTempPubkey = response;
		if (!objTempPubkey.temp_pubkey || !objTempPubkey.pubkey || !objTempPubkey.signature)
			return handleError("missing fields in hub response");
		if (objTempPubkey.pubkey !== recipient_device_pubkey)
			return handleError("temp pubkey signed by wrong permanent pubkey");
		if (!ecdsaSig.verify(objectHash.getDeviceMessageHashToSign(objTempPubkey), objTempPubkey.signature, objTempPubkey.pubkey))
			return handleError("wrong sig under temp pubkey");
		var objEncryptedPackage = createEncryptedPackage(json, objTempPubkey.temp_pubkey);
		var recipient_device_address = objectHash.getDeviceAddress(recipient_device_pubkey);
		var objDeviceMessage = {
			encrypted_package: objEncryptedPackage,
			to: recipient_device_address,
			pubkey: objMyPermanentDeviceKey.pub_b64 // who signs. Essentially, the from again. 
		};
		objDeviceMessage.signature = ecdsaSig.sign(objectHash.getDeviceMessageHashToSign(objDeviceMessage), objMyPermanentDeviceKey.priv);
		network.sendRequest(ws, 'hub/deliver', objDeviceMessage, false, function(ws, request, response){
			if (response === "accepted"){
				db.query("DELETE FROM outbox WHERE message_hash=?", [message_hash], function(){
					callbacks.ifOk();
				});
			}
			else
				handleError( response.error || ("unrecognized response: "+JSON.stringify(response)) );
		});
	});
}
function sendPreparedMessageToConnectedHub(ws, recipient_device_pubkey, message_hash, json, callbacks){
	network.sendRequest(ws, 'hub/get_temp_pubkey', recipient_device_pubkey, false, function(ws, request, response){
		function handleError(error){
			callbacks.ifError(error);
			db.query("UPDATE outbox SET last_error=? WHERE message_hash=?", [error, message_hash], function(){});
		}
		if (response.error)
			return handleError(response.error);
		var objTempPubkey = response;
		if (!objTempPubkey.temp_pubkey || !objTempPubkey.pubkey || !objTempPubkey.signature)
			return handleError("missing fields in hub response");
		if (objTempPubkey.pubkey !== recipient_device_pubkey)
			return handleError("temp pubkey signed by wrong permanent pubkey");
		if (!ecdsaSig.verify(objectHash.getDeviceMessageHashToSign(objTempPubkey), objTempPubkey.signature, objTempPubkey.pubkey))
			return handleError("wrong sig under temp pubkey");
		var objEncryptedPackage = createEncryptedPackage(json, objTempPubkey.temp_pubkey);
		var recipient_device_address = objectHash.getDeviceAddress(recipient_device_pubkey);
		var objDeviceMessage = {
			encrypted_package: objEncryptedPackage,
			to: recipient_device_address,
			pubkey: objMyPermanentDeviceKey.pub_b64 // who signs. Essentially, the from again. 
		};
		objDeviceMessage.signature = ecdsaSig.sign(objectHash.getDeviceMessageHashToSign(objDeviceMessage), objMyPermanentDeviceKey.priv);
		network.sendRequest(ws, 'hub/deliver', objDeviceMessage, false, function(ws, request, response){
			if (response === "accepted"){
				db.query("DELETE FROM outbox WHERE message_hash=?", [message_hash], function(){
					callbacks.ifOk();
				});
			}
			else
				handleError( response.error || ("unrecognized response: "+JSON.stringify(response)) );
		});
	});
}
function sendPreparedMessageToConnectedHub ( ws , recipient_device_pubkey , message_hash , json , callbacks ) { network . sendRequest ( ws , 'hub/get_temp_pubkey' , recipient_device_pubkey , false , function ( ws , request , response ) { function handleError ( error ) { callbacks . ifError ( error ) ; db . query ( "UPDATE outbox SET last_error=? WHERE message_hash=?" , [ error , message_hash ] , function ( ) { } ) ; } if ( response . error ) return handleError ( response . error ) ; var objTempPubkey = response ; if ( ! objTempPubkey . temp_pubkey || ! objTempPubkey . pubkey || ! objTempPubkey . signature ) return handleError ( "missing fields in hub response" ) ; if ( objTempPubkey . pubkey !== recipient_device_pubkey ) return handleError ( "temp pubkey signed by wrong permanent pubkey" ) ; if ( ! ecdsaSig . verify ( objectHash . getDeviceMessageHashToSign ( objTempPubkey ) , objTempPubkey . signature , objTempPubkey . pubkey ) ) return handleError ( "wrong sig under temp pubkey" ) ; var objEncryptedPackage = createEncryptedPackage ( json , objTempPubkey . temp_pubkey ) ; var recipient_device_address = objectHash . getDeviceAddress ( recipient_device_pubkey ) ; var objDeviceMessage = { encrypted_package : objEncryptedPackage , to : recipient_device_address , pubkey : objMyPermanentDeviceKey . pub_b64 // who signs. Essentially, the from again.  } ; objDeviceMessage . signature = ecdsaSig . sign ( objectHash . getDeviceMessageHashToSign ( objDeviceMessage ) , objMyPermanentDeviceKey . priv ) ; network . sendRequest ( ws , 'hub/deliver' , objDeviceMessage , false , function ( ws , request , response ) { if ( response === "accepted" ) { db . query ( "DELETE FROM outbox WHERE message_hash=?" , [ message_hash ] , function ( ) { callbacks . ifOk ( ) ; } ) ; } else handleError ( response . error || ( "unrecognized response: " + JSON . stringify ( response ) ) ) ; } ) ; } ) ; }
first param is WebSocket only
first param is WebSocket only