I send a request from the client to the server and the server responses back to both the client and the controller with a token. Then, the client receives the token back and sign the token with some extra information (Client IP, time and own blockchain address). After, the client sends the signed information with its own public key. All is good until here.
Now, the controller receives the message with signed information and the public key. Tries to verify this signed information with the coming public key and the message which already has.
Here is Client part code:
var message = token + "," + client.address().address + "," + time + "," + my_public;
var message_buf = Buffer.from(message);
const sign = crypto.createSign('SHA256');
sign.write(message_buf);
sign.end();
const signature = sign.sign(my_private, 'hex');
var sign_pub = signature.toString() + "," + my_public.toString();
var sign_pub_buf = Buffer.from(sign_pub);
console.log("sign_pub = ", sign_pub_buf);
client.send(sign_pub_buf, sdn_port, host, function(error){
if(error){
client.close();
}
else{
console.log('Sign+Public_K has been sent to SDN !!!');
}
Here is Controller part code:
udpsocket_sdn.on('message', function(msg, rinfo) {
console.log('Data received from CLIENT : ' ,msg);
var sig_pub = msg.toString().split(",");
var sig = sig_pub[0];
var pub = sig_pub[1];
console.log("sig = ", sig);
console.log("pub = ", pub);
var message = token + "," + rinfo.address + "," + time + "," + pub;
var message_buf = Buffer.from(message);
const verify = crypto.createVerify('SHA256');
verify.write(message_buf);
verify.end();
var isGood = verify.verify(pub, sig, 'hex');
if(isGood){
console.log('All Good');
}
else {
console.log('Nope !');
}
}
Ok, I fixed it. It is working now.
Here is the Client part code:
const { privateKey, publicKey } = crypto.generateKeyPairSync('rsa', {
modulusLength: 2048,
});
var my_public = publicKey.export({type: 'spki', format: 'pem'});
var my_private = privateKey;
var time = 100;
client.on('message',function(msg, info){
if(data_cnt == 1){
console.log('Random number received from SERVER !');
data_cnt++;
var token_tot = msg.toString().split(",")
usr1_pub_pem = token_tot[0];
token = token_tot[1];
var message = token + "," + ip + "," + time + "," + Buffer.from(my_public);
console.log("Client address = ", ip)
const sign = crypto.createSign('SHA256');
sign.write(message);
sign.end();
const signature = sign.sign(my_private, 'hex');
client.send(signature, sdn_port, host, function(error){
if(error){
client.close();
}
else{
console.log('Signature has been sent to SDN !!!');
client.send(my_public, sdn_port, host, function(error){
if(error){
client.close();
}
else{
console.log('Public Key has been sent to SDN !!!');
}
});
}
});
}
});
Now, the Controller part :
var time = 100;
udpsocket_sdn.on('message', function(msg, rinfo) {
count_sdn = count_sdn + 1;
if(count_sdn == 1){
console.log('Signature data received from CLIENT !!');
sig_pub = msg.toString();
}
else if (count_sdn == 2){
console.log('Public key data received from CLIENT !! ');
pub = msg;
var message = token + "," + rinfo.address + "," + time + "," + pub;
console.log("Client address = ", rinfo.address)
const verify = crypto.createVerify('SHA256');
verify.write(message);
verify.end();
var isGood = verify.verify(pub, sig_pub, 'hex');
if(isGood){
console.log('All Good');
}
else {
console.log('Nope !');
}
}
});
Related
Im working on a chat app, using firebase and javascript. I encountered a problem, when I switch receivers multiple times, the message that I sent fetches a few times while the messages is sent only once to the database.
var select = document.getElementById("odbiorcy");
select.addEventListener("change", function handleChange(event) {
receiver = select.options[select.selectedIndex].text;
console.log("gonna fetch");
document.getElementById("messages").innerHTML = "";
fetchChat = db.ref("messages/" + username + "/" + receiver + "/");
fetchChat.on("child_added", function (snapshot) {
const messages = snapshot.val();
const msg = "<li>" + messages.usr + " : " + messages.msg + "</li>";
document.getElementById("messages").innerHTML += msg;
});
});
Here is how it looks when it fetches, after a switch receivers a few times
As you can see, the first 3 messages that I've sent/received where fine, it was only until I switch the receiver that the message I have sent was duplicated on fetch.
It sounds like you should detach the existing listener when switching receivers in your code.
Something like:
var path, listener;
select.addEventListener("change", function handleChange(event) {
// 👇
if (listener) {
path.off("child_added", listener)
}
receiver = select.options[select.selectedIndex].text;
console.log("gonna fetch");
document.getElementById("messages").innerHTML = "";
fetchChat = db.ref("messages/" + username + "/" + receiver + "/");
// 👇
listener = fetchChat.on("child_added", function (snapshot) {
const messages = snapshot.val();
const msg = "<li>" + messages.usr + " : " + messages.msg + "</li>";
document.getElementById("messages").innerHTML += msg;
});
path = fetchChat; // 👈
});
I am still trying to build my website where people can text each other, send photos etc.
The chat thing works really well until I wanna add the functionality checking whether the second user in the chat is typing.
Here is my code without the typing thing, this works really well ;)
firebase.initializeApp(firebaseConfig);
const db = firebase.database();
// temporary user and receiver's names
const username = prompt("Nickname:");
const receiver = prompt("Receiver's name:");
// sending a message
document.getElementById("send-message").addEventListener("submit", postChat);
function postChat(e)
{
e.preventDefault();
const timestamp = Date.now();
const chatTxt = document.getElementById("chat-txt");
const message = chatTxt.value;
chatTxt.value = "";
db.ref("messages/" + username + "/" + receiver + "/" + timestamp).set({
usr: username,
msg: message,
});
db.ref("messages/" + receiver + "/" + username + "/" + timestamp).set({
usr: username,
msg: message,
});
}
// printing the message
const fetchChat = db.ref("messages/" + username + "/" + receiver + "/");
fetchChat.on("child_added", function (snapshot)
{
const messages = snapshot.val();
const msg = "<li>" + messages.usr + " : " + messages.msg + "</li>";
document.getElementById("messages").innerHTML += msg;
});
The problem appears when I want to check if the second user is typing. When I am adding the code that's below messages just stop to work. There is a random null in the database as a new user who sent a message to another null. The chat between users also stops to work, users don't see same messages, sometimes can't see any of them and always "undefined" types "undefined" when I refresh the website.
At least it correctly shows when someone is typing, but the rest of the functionalities (which used to work) just don't work anymore.
Here is the code of the typing thing, I also tried to check whether the username and receiver's name aren't null but it didn't reallly help.
// showing whether the receiver is typing
function sendTyping(tmp)
{
if(tmp)
{
db.ref("messages/" + username + "/" + receiver).set({
tpg: "yes"
});
}
else
{
db.ref("messages/" + username + "/" + receiver).set({
tpg: "no"
});
}
}
var searchTimeout;
document.getElementById("chat-txt").onkeydown = function() {
if (searchTimeout != undefined)
clearTimeout(searchTimeout);
searchTimeout = setTimeout(callServerScript, 1500);
sendTyping(true);
}
function callServerScript() {
sendTyping(false);
}
let areTheyTyping = db.ref("messages/" + receiver + "/" + username);
areTheyTyping.on("value", function(snapshot) {
const typing = snapshot.val();
const status = typing.tpg;
if(status == "yes")
document.getElementById("writing").innerHTML = "typing...";
else
document.getElementById("writing").innerHTML = "";
});
I mostly wrote this by myself, I will appreciate any kind of help, just please use a straightforward language so I can easily understand the explanation of the problem, I am kind of new.
The function
const fetchChat = db.ref("messages/" + username + "/" + receiver + "/");
fetchChat.on("child_added", function (snapshot)
{
const messages = snapshot.val();
const msg = "<li>" + messages.usr + " : " + messages.msg + "</li>";
document.getElementById("messages").innerHTML += msg;
});
It fetches the chat whenever a child is added to the directory of your messages, so when you store the typing status in "messages/" + username + "/" + receiver + "/" the function .on knows that you've changed/added something, therefore posting a message. It's undefined because the message is in fact empty. You should create a new directory where you store the areTheyTyping status, something like "status/" + username + "/" + receiver + "/" Hope I helped.
My experience showed that firestore has problem with undefined values. You can try adding a default value for undefined or null usernames. Maybe you can add zero (0) as the default value for this matter.
Change the path db.ref("messages/" + receiver + "/" + username) to db.ref("messages/" + username + "/" + receiver) at areTheyTyping. See if it works
function sendTyping(tmp)
{
if(tmp) {
db.ref("messages/" + username + "/" + receiver).set({
tpg: "yes"
});
}
else {
db.ref("messages/" + username + "/" + receiver).set({
tpg: "no"
});
}
}
var searchTimeout;
document.getElementById("chat-txt").onkeydown = function() {
if (searchTimeout !== undefined)
clearTimeout(searchTimeout);
searchTimeout = setTimeout(callServerScript, 1500);
sendTyping(true);
}
function callServerScript() {
sendTyping(false);
}
let areTheyTyping = db.ref("messages/" + username + "/" + receiver);
areTheyTyping.on("value", function(snapshot) {
const typing = snapshot.val();
const status = typing.tpg;
if(status === "yes")
document.getElementById("writing").innerHTML = "typing...";
else
document.getElementById("writing").innerHTML = "";
});
I am now trying out how to use the Google cloud functions as part of my IOT application.
But I am having issues when I send a JSON POST to the trigger endpoint. There are times that it works perfectly and sometimes the payload hex is cut in the middle.
For example the original payloadhex would be "0011029e02ffb1ffd6ffd8ffdaffe0fff500000008" and sometimes get suddenly cut to "0011029e02ffb1" when it is being saved to the database.
How I test the endpoint would be that I would send an HTTP POST using Postman with data below.
{
"DevEUI_uplink": {
"DevEUI": "BC9740FFFE10549E",
"payload_hex": "0011029e02ffb1ffd6ffd8ffdaffe0fff500000008",
}}
And inside the cloud function would be the nodejs12 code:
/**
* Responds to any HTTP request.
*
* #param {!express:Request} req HTTP request context.
* #param {!express:Response} res HTTP response context.
*/
const moment = require("moment");
const mysql = require("mysql");
require("dotenv").config();
exports.saveFunction = (req, res) => {
let now = moment().format('YYYY-MM-DD HH:mm:ss');
let deveui = req.body.DevEUI_uplink.DevEUI;
let payload = req.body.DevEUI_uplink.payload_hex;
function convertTempData(data) {
data = parseInt(data, 16);
if ((data & 0x8000) > 0) {
data = data - 0x10000;
}
return data;
}
// Slice the Request Data
let raw_payload = payload;
let version = parseInt(payload.slice(0, 2), 16);
let gem1 = parseInt(payload.slice(2, 4), 16);
let gem2 = parseInt(payload.slice(4, 6), 16);
let battery = parseInt(payload.slice(6, 8), 16) / 2;
let payload_id = parseInt(payload.slice(8, 10), 16);
let tempNow = convertTempData(payload.slice(10, 14));
let tempVar1 = convertTempData(payload.slice(14, 18));
let tempVar2 = convertTempData(payload.slice(18, 22));
let tempVar3 = convertTempData(payload.slice(22, 26));
let tempVar4 = convertTempData(payload.slice(26, 30));
let tempVar5 = convertTempData(payload.slice(30, 34));
let tempVar6 = convertTempData(payload.slice(34, 38));
let tempVar7 = convertTempData(payload.slice(38, 42));
// Connection String
const conn = mysql.createConnection({
host: process.env.SERVER_HOST,
user: process.env.SERVER_USER,
password: process.env.SERVER_PASS,
database: process.env.SERVER_DB,
port: process.env.SERVER_PORT,
});
conn.connect(function (err) {
if (err) {
return res
.status(404)
.json({ message: "Invalid Request", error: err.message });
}
var sqlcoms =
"UPDATE sd_payload SET payload = '" +
raw_payload +
"' , version='" +
version +
"', gem1='" +
gem1 +
"' , gem2='" +
gem2 +
"' , battery='" +
battery +
"',payload_id='" +
payload_id +
"',tempNow='" +
tempNow +
"',tempVar1='" +
tempVar1 +
"',tempVar2='" +
tempVar2 +
"',tempVar3='" +
tempVar3 +
"',tempVar4='" +
tempVar4 +
"',tempVar5='" +
tempVar5 +
"',tempVar6='" +
tempVar6 +
"',tempVar7='" +
tempVar7 +
"',updated_at='" +
now +
"' WHERE DevEUI = '" +
deveui +
"'";
conn.query(sqlcoms, function (err, result) {
if (err) {
return res
.status(404)
.json({ message: "Invalid Request", error: err.message });
}
return res.status(201).json(result);
});
});
};
I wanted to save the entire payload to the database for checking purposes. Would you be able to advise why the post json body is being cut midway in some inserts and some inserts would be complete?
I would suggest to first console.log(payload) so to verify if it's received in full by the function, or it gets chopped somewhere on the way.
I have a problem when I try to call a service from the following script:
function campMasiva(array, ip, token, tipo, idcampana) {
$.getJSON('https://' + ip + '/host/api_campaing.php?token=' + token + '&action=' + array + '&type_campaing=' + tipo + '&campaing=' + idcampana, function (res)
{
res = JSON.stringify(res);
var status = JSON.parse(res);
});
}
But I don't know how to inactivate the ssl verification.
I am trying to find out all the records that matches a user from a Parse class (namely, UserBeaconTracking). I am able to get correct user object and beacon object to begin with. However, when I use the statement
userBeaconTrackingQuery.equalTo("user", user);
Returned Error 102 with an error message "value is expected instead of map type."
What is it that I am doing wrong?
Here is the code snippet:
var userQuery = new Parse.Query(Parse.User);
userQuery.equalTo("username", username);
userQuery.find().then(function(currentUser) { // get the user who sent the request
user = currentUser;
console.log("User" + JSON.stringify(user) + "Beacon Name :: " + JSON.stringify(visitedBeaconName));
}).then(function () { // get the beacons with which user communicated
var beaconRelation = Parse.Object.extend("Beacon");
var beaconQuery = new Parse.Query(beaconRelation);
beaconQuery.equalTo("name", visitedBeaconName);
return beaconQuery.find();
}).then(function (beacons) { // get user beacon transaction details
console.log("number of beacons " + beacons.length + " " + beacons[0]);
visitedBeacon = beacons[0];
console.log("beacon :: " + visitedBeacon);
var userBeaconTracking = Parse.Object.extend("UserBeaconTracking");
var userBeaconTrackingQuery = new Parse.Query(userBeaconTracking);
userBeaconTrackingQuery.equalTo("user", user);
userBeaconTrackingQuery.equalTo("beacon", visitedBeacon);
userBeaconTrackingQuery.find({
success : function (results) {
visitCounter = results[0].get("count");
console.log ("Visit Counter :: " + visitCounter);
// get the list of stores associated with the beacon
var beaconTable = Parse.Object.extend("Beacon");
var brandsAssociatedWithBeacon = new Parse.Query(beaconTable);
brandsAssociatedWithBeacon.get(visitedBeacon.id).then(function(beacon) {
typeOfBeacon = beacon.get("type");
console.log("Beacon Type ::" + typeOfBeacon);
var beaconBrandRelation = beacon.relation("brand");
var query = beaconBrandRelation.query();
//return query.find();
});
},
error: function(error) {
console.log("Error: " + error.code + " " + error.message);
}
});
});