// ./server.js const express = require('express') const bodyParser = require('body-parser') const cors = require('cors') const Chatkit = require('pusher-chatkit-server') var libsignal = require('libsignal'); const chatkit = new Chatkit.default({ instanceLocator: 'v1:us1:366480cc-91f1-4cbd-8c04-68dc96e8ccdf', key: '982eaea8-66f5-4bdb-9a2d-14de0fa8b92b:WSgfMJzA8cvZ/fwEqjupJhOpnwQ7qbAEOVze44y+XK0=' }) const app = express() app.use(bodyParser.urlencoded({ extended: false })) app.use(bodyParser.json()) app.use(cors()) //-------- var KeyHelper = libsignal.keyhelper; var sessionPromise = null; function SignalProtocolStore() { this.store = {}; } SignalProtocolStore.prototype = { Direction: { SENDING: 1, RECEIVING: 2, }, getIdentityKeyPair: function () { return Promise.resolve(this.get('identityKey')); }, //umetnuta nova fun getOurIdentity: function () { return Promise.resolve(this.get('identityKey')); }, getLocalRegistrationId: function () { return Promise.resolve(this.get('registrationId')); }, getOurRegistrationId: function () { return Promise.resolve(this.get('identityKey')); }, put: function (key, value) { if (key === undefined || value === undefined || key === null || value === null) throw new Error("Tried to store undefined/null"); this.store[key] = value; }, get: function (key, defaultValue) { if (key === null || key === undefined) throw new Error("Tried to get value for undefined/null key"); if (key in this.store) { return this.store[key]; } else { return defaultValue; } }, remove: function (key) { if (key === null || key === undefined) throw new Error("Tried to remove value for undefined/null key"); delete this.store[key]; }, isTrustedIdentity: function (identifier, identityKey, direction) { if (identifier === null || identifier === undefined) { throw new Error("tried to check identity key for undefined/null key"); } if (!(identityKey instanceof ArrayBuffer)) { identityKey = identityKey.pubKey; //throw new Error("Expected identityKey to be an ArrayBuffer"); } var trusted = this.get('identityKey' + identifier); if (trusted === undefined) { return Promise.resolve(true); } return Promise.resolve(util.toString(identityKey) === util.toString(trusted)); }, loadIdentityKey: function (identifier) { if (identifier === null || identifier === undefined) throw new Error("Tried to get identity key for undefined/null key"); return Promise.resolve(this.get('identityKey' + identifier)); }, saveIdentity: function (identifier, identityKey) { if (identifier === null || identifier === undefined) throw new Error("Tried to put identity key for undefined/null key"); var address = new libsignal.SignalProtocolAddress.fromString(identifier); var existing = this.get('identityKey' + address.getName()); this.put('identityKey' + address.getName(), identityKey) if (existing && util.toString(identityKey) !== util.toString(existing)) { return Promise.resolve(true); } else { return Promise.resolve(false); } }, /* Returns a prekeypair object or undefined */ loadPreKey: function (keyId) { var res = this.get('25519KeypreKey' + keyId); if (res !== undefined) { res = { pubKey: res.pubKey, privKey: res.privKey }; } return Promise.resolve(res); }, storePreKey: function (keyId, keyPair) { return Promise.resolve(this.put('25519KeypreKey' + keyId, keyPair)); }, removePreKey: function (keyId) { return Promise.resolve(this.remove('25519KeypreKey' + keyId)); }, /* Returns aa signed keypair object or undefined */ loadSignedPreKey: function (keyId) { var res = this.get('25519KeysignedKey' + keyId); if (res !== undefined) { res = { pubKey: res.pubKey, privKey: res.privKey }; } return Promise.resolve(res); }, storeSignedPreKey: function (keyId, keyPair) { return Promise.resolve(this.put('25519KeysignedKey' + keyId, keyPair)); }, removeSignedPreKey: function (keyId) { return Promise.resolve(this.remove('25519KeysignedKey' + keyId)); }, loadSession: function (identifier) { return Promise.resolve(this.get('session' + identifier)); }, storeSession: function (identifier, record) { return Promise.resolve(this.put('session' + identifier, record)); }, removeSession: function (identifier) { return Promise.resolve(this.remove('session' + identifier)); }, removeAllSessions: function (identifier) { for (var id in this.store) { if (id.startsWith('session' + identifier)) { delete this.store[id]; } } return Promise.resolve(); } }; var senderStore = new SignalProtocolStore(); var receiverStore = new SignalProtocolStore(); //--------------- function generateIdentity(store) { return Promise.all([ KeyHelper.generateIdentityKeyPair(), KeyHelper.generateRegistrationId(), ]).then(function (result) { store.put('identityKey', result[0]); store.put('registrationId', result[1]); }); } function generatePreKeyBundle(store, preKeyId, signedPreKeyId) { return Promise.all([ store.getIdentityKeyPair(), store.getLocalRegistrationId() ]).then(function (result) { var identity = result[0]; var registrationId = result[1]; return Promise.all([ KeyHelper.generatePreKey(preKeyId), KeyHelper.generateSignedPreKey(identity, signedPreKeyId), ]).then(function (keys) { var preKey = keys[0] var signedPreKey = keys[1]; store.storePreKey(preKeyId, preKey.keyPair); store.storeSignedPreKey(signedPreKeyId, signedPreKey.keyPair); return { identityKey: identity.pubKey, registrationId: registrationId, preKey: { keyId: preKeyId, publicKey: preKey.keyPair.pubKey }, signedPreKey: { keyId: signedPreKeyId, publicKey: signedPreKey.keyPair.pubKey, signature: signedPreKey.signature } }; }); }); } //--------- app.post("/cryptMessage", async (req, res) => { console.log("UĐEEEEEEEEEEEEE"); //sessionPromise=req.body.data.sessionPromise; message = req.body.data.message; //senderStore = req.body.data.senderStore; //RECEIVER_ADDRESS = new libsignal.ProtocolAddress(req.body.data.receiverAdress.id, req.body.data.receiverAdress.deviceId); //---------------- var senderAdress = req.body.data.senderAdress; //"xxxxxxxxx" var receiverAdress = req.body.data.receiverAdress; //""yyyyyyyyyyyyy"" var receiverPreKeyId = req.body.data.receiverPreKeyId; // 1337; var receiverSignedKeyId = req.body.data.receiverSignedKeyId; // 1; var SENDER_ADDRESS = new libsignal.ProtocolAddress(senderAdress, 1); var RECEIVER_ADDRESS = new libsignal.ProtocolAddress(receiverAdress, 1); //var senderStore = new SignalProtocolStore(); //var receiverStore = new SignalProtocolStore(); var receiverSignedKeyId = 1; var Curve = libsignal.Curve; await Promise.all([ generateIdentity(senderStore), generateIdentity(receiverStore), ]).then(function () { return generatePreKeyBundle(receiverStore, receiverPreKeyId, receiverSignedKeyId); }).then(function (preKeyBundle) { var builder = new libsignal.SessionBuilder(senderStore, RECEIVER_ADDRESS); sessionPromise = builder.initOutgoing(preKeyBundle); sessionPromise.then(function () { var originalMessage = Buffer.from(message, 'utf8'); var senderSessionCipher = new libsignal.SessionCipher(senderStore, RECEIVER_ADDRESS); //var receiverSessionCipher = new libsignal.SessionCipher(receiverStore, SENDER_ADDRESS); senderSessionCipher.encrypt(originalMessage).then(function (ciphertext) { console.log("KRI, RECSTORE:", receiverStore); console.log("KRI, RECadress:", SENDER_ADDRESS); res.json({ data: { receiverStore: receiverStore, SENDER_ADDRESS: SENDER_ADDRESS, message: ciphertext.body } }) }); }); }); }); app.post('/deCryptMessage', (req, res) => { message = req.body.data.message; const buf5 = Buffer.from(message.split(',')); //receiverStore = req.body.data.receiverStore; //SENDER_ADDRESS = req.body.data.SENDER_ADDRESS; senderAdress = req.body.data.senderAdress; var SENDER_ADDRESS = new libsignal.ProtocolAddress(senderAdress, 1); console.log("DEKRI, RECSTORE:", receiverStore.store.identityKey.pubKey); console.log("DEKRI, RECSTORE:", SENDER_ADDRESS); //var receiverSessionCipher = new libsignal.SessionCipher(receiverStore, SENDER_ADDRESS); //odavde var receiverSessionCipher = new libsignal.SessionCipher(receiverStore, SENDER_ADDRESS); //ubaceno receiverSessionCipher.decryptPreKeyWhisperMessage(buf5, 'binary').then(function (ciphertext) { poruka = ciphertext.toString(); res.json({ data: { message: poruka } }) }); }); app.post('/users', (req, res) => { const { username } = req.body const user = { name: username, id: username } chatkit .createUser(user) .then(() => { console.log('Created user ', user.name) res.status(201).json(user) }) .catch(error => { if (error.error === 'services/chatkit/user_already_exists') { console.log('User already exists ', user.name) res.status(201).json(user) } else { console.error(error) res.status(error.status).json(error) } }) }) app.listen(3001) console.log('Running on port 3001')