UNPKG

@needle-tools/networking

Version:
157 lines (137 loc) 5.23 kB
(() => { const Storage = require("./storage"); module.exports.loadState = async function (roomName) { const res = await Storage.loadRoomState(roomName); if ("state" in res) { return res.state; } return {}; }; module.exports.saveState = async function (roomName, state) { if (!roomName || !state) { console.warn("Invalid room or state, can not persist data"); return; } await Storage.saveRoomState(roomName, state); return; }; // notification event that someone joined their room module.exports.sendUpdate_UserJoinedRoom = function (ws, data) { if (!ws || ws.readyState !== ws.OPEN) return; ws.send(JSON.stringify({ key: "user-joined-room", data: data })); }; // notification event that someone left their room module.exports.sendUpdate_UserLeftRoom = function (ws, data) { if (!ws || ws.readyState !== ws.OPEN) return; ws.send(JSON.stringify({ key: "user-left-room", data: data })); }; // notification event that current user (you) joined room module.exports.sendUpdate_JoinedRoom = function (ws, roomName, inRoomIds, viewId, allowEditing) { if (!ws || ws.readyState !== ws.OPEN) return; console.log("send joined room", roomName); ws.send( JSON.stringify({ key: "joined-room", room: roomName, inRoom: inRoomIds, viewId: viewId, allowEditing: allowEditing }) ); }; // notification event that user (you) left a room module.exports.sendUpdate_LeftRoom = function (ws, roomName) { if (!ws || ws.readyState !== ws.OPEN) return; ws.send(JSON.stringify({ key: "left-room", room: roomName })); }; module.exports.sendUpdate_RoomStateSent = function (ws, roomName) { if (!ws || ws.readyState !== ws.OPEN) return; ws.send( JSON.stringify({ key: "room-state-sent", room: roomName }) ); }; module.exports.sendUpdate_GainedOwnershipBroadcast = function ( ws, ownerId, guid ) { if (!ws || ws.readyState !== ws.OPEN) return; ws.send( JSON.stringify({ key: "gained-ownership-broadcast", data: { guid: guid, owner: ownerId }, }) ); }; module.exports.sendUpdate_LostOwnershipBroadcast = function ( ws, prevOwner, guid ) { if (!ws || ws.readyState !== ws.OPEN) return; ws.send( JSON.stringify({ key: "lost-ownership-broadcast", data: { guid: guid, owner: prevOwner }, }) ); }; module.exports.sendUpdate_LostOwnership = function (ws, guid) { if (!ws || ws.readyState !== ws.OPEN) return; console.log(`User ${ws.id} lost ownership ${guid}`); ws.send(JSON.stringify({ key: "lost-ownership", data: guid })); }; module.exports.sendUpdate_GainedOwnership = function (ws, guid) { if (!ws || ws.readyState !== ws.OPEN) return; console.log(ws.id + " gained ownership " + guid); ws.send(JSON.stringify({ key: "gained-ownership", data: guid })); }; module.exports.sendUpdate_IsOwner = function (ws, guid, bool) { if (!ws || ws.readyState !== ws.OPEN) return; ws.send( JSON.stringify({ key: "response-is-owner", data: { guid: guid, value: bool }, }) ); }; module.exports.sendUpdate_HasOwner = function (ws, guid, bool) { if (!ws || ws.readyState !== ws.OPEN) return; ws.send( JSON.stringify({ key: "response-has-owner", data: { guid: guid, value: bool }, }) ); }; module.exports.getUniqueID = function () { function s4() { return Math.floor((1 + Math.random()) * 0x10000) .toString(16) .substring(1); } return s4() + s4() + "-" + s4(); }; // this is used to generate view-only guid from room id and secret // we also need to decrypt to get the original room name from the generated id // this is necessary so a viewer can also open a room and the server knows which room to open/load from this id const crypto = require("crypto"); // make buffer constant so it doesnt change when server reloads (instead of 16 random bytes) const iv = Buffer.from([0xe6, 0x4d, 0xf7, 0x25, 0x4d, 0x50, 0xbe, 0x5b, 0xf8, 0x79, 0x0b, 0xf6, 0x16, 0x07, 0x71, 0x82]); const algorithm = 'aes-256-ctr'; const fallbackKey = "40edb098f15eac40920111a4e50b0d15"; module.exports.getUniqueIDWithSalt = function (key) { let salt = process.env.VIEW_ONLY_SALT; if (!salt) { console.error("Missing VIEW_ONLY_SALT environment variable"); salt = fallbackKey; } const cipher = crypto.createCipheriv(algorithm, salt, iv); const encrypted = Buffer.concat([cipher.update(key), cipher.final()]); return encrypted.toString("hex"); }; module.exports.decryptID = function (id) { let salt = process.env.VIEW_ONLY_SALT; if (!salt) { console.error("Missing VIEW_ONLY_SALT environment variable"); salt = fallbackKey; } const decipher = crypto.createDecipheriv(algorithm, salt, iv); const decrpyted = Buffer.concat([decipher.update(Buffer.from(id, 'hex')), decipher.final()]); return decrpyted.toString(); } })();