aboutsummaryrefslogtreecommitdiffstats
path: root/lib/sockets.js
diff options
context:
space:
mode:
Diffstat (limited to 'lib/sockets.js')
-rw-r--r--lib/sockets.js93
1 files changed, 41 insertions, 52 deletions
diff --git a/lib/sockets.js b/lib/sockets.js
index c94c29a0..7f655570 100644
--- a/lib/sockets.js
+++ b/lib/sockets.js
@@ -1,49 +1,42 @@
-import store from "$lib/store";
-import config from "$config";
import app from "$app";
+import config from "$config";
+import store from "$lib/store";
import jwt from "jsonwebtoken";
import { v4 } from "uuid";
-import WebSocket from "ws";
-import { differenceInSeconds, subSeconds } from "date-fns";
-import fastifyWs from "@fastify/websocket";
import whitelist from "./whitelist";
import { l, err, warn } from "$lib/logging";
-import { g } from "$lib/redis";
+import { g } from "$lib/db";
+import { pick } from "$lib/utils";
const code = 1000;
-
-const wss = new WebSocket.Server({ clientTracking: false, noServer: true });
-
-const pick = (O, ...K) => K.reduce((o, k) => ((o[k] = O[k]), o), {});
const all = {};
const subscriptions = [];
const lastSeen = {};
+const users = {};
-export const emit = (uuid, type, data) => {
- if (data.uuid !== undefined) data = pick(data, ...whitelist);
-
+export const emit = (uid, type, data) => {
if (type === "payment" && data.amount > 0) {
for (let i = subscriptions.length - 1; i >= 0; i--) {
let s = subscriptions[i];
- if (s.invoice.id === data.invoice_id) {
+ if (s.hash === data.hash) {
s.ws.send(JSON.stringify({ type, data }));
}
}
}
- if (!store.sockets[uuid]) return;
- for (let id in store.sockets[uuid]) {
- const ws = store.sockets[uuid][id];
+ if (!store.sockets[uid]) return;
+ for (let id in store.sockets[uid]) {
+ const ws = store.sockets[uid][id];
ws.send(JSON.stringify({ type, data }));
}
};
export const broadcast = (type, data) => {
const sent = [];
- for (const uuid in store.sockets) {
- for (const id in store.sockets[uuid]) {
- const ws = store.sockets[uuid][id];
+ for (const uid in store.sockets) {
+ for (const id in store.sockets[uid]) {
+ const ws = store.sockets[uid][id];
ws.send(JSON.stringify({ type, data }));
sent.push(ws.id);
}
@@ -54,14 +47,10 @@ export const broadcast = (type, data) => {
});
};
-function subtractSeconds(numOfSeconds, date = new Date()) {
- date.setSeconds(date.getSeconds() - numOfSeconds);
- return date;
-}
+export async function socketServer(app) {
+ let seconds = (n, d = new Date()) => d.setSeconds(d.getSeconds() - n) && d;
-app.register(fastifyWs);
-app.register(async function(app) {
app.get("/ws", { websocket: true }, ({ socket: ws }, req) => {
const id = v4();
ws.id = id;
@@ -85,41 +74,42 @@ app.register(async function(app) {
case "login":
let token = data;
- if (lastSeen[token] > subtractSeconds(5)) return;
+ if (lastSeen[token] > seconds(5)) return;
lastSeen[token] = new Date();
try {
if (!token || token === "null" || !jwt.decode(token))
return ws.close(code, `bad token ${token}`);
- let { id: user_id } = jwt.decode(token);
- if (!user_id) throw new Error("Invalid JWT token");
- let user = await g(`user:${user_id}`);
+ let { id: uid } = jwt.decode(token);
+ if (!uid) throw new Error("Invalid JWT token");
+ let user = await g(`user:${uid}`);
if (!user) throw new Error("User not found");
- user.haspin = !!user.pin;
- if (!store.sockets[user_id]) store.sockets[user_id] = {};
- const existing = Object.keys(store.sockets[user_id]);
+ if (!store.sockets[uid]) store.sockets[uid] = {};
+ const existing = Object.keys(store.sockets[uid]);
if (existing.length > 4) {
- const p = existing.find(sid => sid !== user_id);
- store.sockets[user_id][p].send(JSON.stringify({ type: "logout" }));
+ const p = existing.find(sid => sid !== uid);
+ store.sockets[uid][p].send(
+ JSON.stringify({ type: "logout" })
+ );
setTimeout(() => {
- if (store.sockets[user_id][p])
- store.sockets[user_id][p].close(code, "too many sockets");
+ if (store.sockets[uid][p])
+ store.sockets[uid][p].close(code, "too many sockets");
}, 5000);
}
- store.sockets[user_id][id] = ws;
- names[id] = user_id;
+ store.sockets[uid][id] = ws;
+ users[id] = uid;
ws.user = user;
ws.send(
- JSON.stringify({ type: "login", data: pick(user, ...whitelist) })
+ JSON.stringify({ type: "login", data: pick(user, whitelist) })
);
ws.send(
JSON.stringify({ type: "version", data: config.clientVersion })
);
} catch (e) {
- console.log(e)
+ console.log(e);
err("caught socket error", e.message);
if (e.message.includes("not found"))
ws.send(JSON.stringify({ type: "logout" }));
@@ -146,9 +136,9 @@ app.register(async function(app) {
ws.on("close", function(code, reason) {
try {
- const uuid = names[id];
- if (store.sockets[uuid] && store.sockets[uuid][id]) {
- delete store.sockets[uuid][id];
+ const uid = users[id];
+ if (store.sockets[uid] && store.sockets[uid][id]) {
+ delete store.sockets[uid][id];
}
if (all[id]) delete all[id];
@@ -157,16 +147,15 @@ app.register(async function(app) {
}
});
});
-});
+}
-const names = {};
-setInterval(() => {
- for (const uuid in store.sockets) {
- for (const id in store.sockets[uuid]) {
- let ws = store.sockets[uuid][id];
+export let sendHeartbeat = () => {
+ for (const uid in store.sockets) {
+ for (const id in store.sockets[uid]) {
+ let ws = store.sockets[uid][id];
ws.beats++;
- if (ws.beats > 10) ws.close(code, `${uuid} ${id} lost heartbeat`);
+ if (ws.beats > 10) ws.close(code, `${uid} ${id} lost heartbeat`);
}
}
-}, 2000);
+}