| ofs | hex dump | ascii |
|---|
| 0000 | 52 49 46 46 52 0d 00 00 57 45 42 50 56 50 38 20 46 0d 00 00 10 3a 00 9d 01 2a 80 00 80 00 3e 79 | RIFFR...WEBPVP8.F....:...*....>y |
| 0020 | 34 94 46 a4 a3 22 21 2e 93 5d 40 90 0f 09 6a 00 bf 30 05 4e 9c 9b 6d 8f e7 3f 1a 73 1f 53 1e 66 | 4.F.."!..]@...j..0.N..m..?.s.S.f |
| 0040 | 1c f9 e4 53 d6 6f 98 97 eb 97 4d 0f 30 fe 70 de 8c bf af 7a 90 7f 62 ff 63 d6 89 e8 1f e5 cd ec | ...S.o....M.0.p....z..b.c....... |
| 0060 | b5 fd a3 ff 15 b3 df 22 31 a1 d0 af c9 e5 de 72 5f cc 7f 45 c6 cd 01 27 5e 2c 88 6b fe 52 35 0e | ......."1......r_..E...'^,.k.R5. |
| 0080 | e9 94 32 e2 59 4a 6e 1c 6f 1a 55 a7 64 cb 62 ad 58 a3 ac 0d 7c 67 41 1f 2a d5 a6 75 2f 86 c5 a9 | ..2.YJn.o.U.d.b.X...|gA.*..u/... |
| 00a0 | 84 f5 95 32 c8 37 89 ec d3 85 ab ae f7 54 fb 50 e9 8d e3 e1 79 8f 03 56 73 56 4f e6 97 03 5f d7 | ...2.7.......T.P....y..VsVO..._. |
| 00c0 | 19 5e c6 25 5b 78 76 49 95 13 66 c3 5c 6d 41 3b b2 8b fe 46 19 8a 07 45 00 b0 0b 68 a9 bc 26 ee | .^.%[xvI..f.\mA;...F...E...h..&. |
| 00e0 | d1 c5 c4 81 b2 a1 dd 65 94 e4 a0 d3 34 cf ff f3 de b5 f1 2f 77 a9 f5 7c 1b 2c 78 ce 41 60 0e 4d | .......e....4....../w..|.,x.A`.M |
| 0100 | 41 f8 95 11 bd a6 5e 63 53 9c 9f 55 bb 7a 1a 39 d5 9c 4e 42 dc e2 bf ec a4 24 f8 01 84 13 4c ff | A.....^cS..U.z.9..NB.....$....L. |
| 0120 | 1c 9a ad 87 cb 50 08 97 32 a6 a3 7a 08 d4 bb 8d 6c ba 39 f3 58 94 e3 d4 26 7b f0 5b 47 f6 ea 03 | .....P..2..z....l.9.X...&{.[G... |
| 0140 | b8 59 ba 45 4f 92 0e ce 18 9b 6a ba 25 17 67 0d 7a 70 58 93 e2 d7 5b 20 2a e1 79 aa b8 f8 fc ca | .Y.EO.....j.%.g.zpX...[.*.y..... |
| 0160 | 20 21 f0 0a cd 49 02 54 3d 3f 63 95 9f c2 b9 a8 45 8d bb 5b 22 52 3d 0b 49 10 32 1d 6f 8f c3 84 | .!...I.T=?c.....E..["R=.I.2.o... |
| 0180 | 04 93 ed c8 80 55 ad c6 4e c3 9a 18 bf 18 91 d7 90 fc f8 ad 4f 0a 1d a7 8a 92 f1 86 87 e8 f5 37 | .....U..N...........O..........7 |
| 01a0 | 25 f6 b6 cc 9c 83 a2 8d 04 16 ce 20 96 5b f5 4c 39 7f 60 7a 95 37 4c 29 ad 6c 4b 51 aa 73 cc df | %............[.L9.`z.7L).lKQ.s.. |
| 01c0 | 4b f3 53 69 e6 2c 2c e6 85 5b 66 1a 66 9c 58 dc cd 85 4b 32 c8 5d 9e b0 af 85 54 c4 2b 02 f4 81 | K.Si.,,..[f.f.X...K2.]....T.+... |
| 01e0 | 72 bb 91 32 3c 9e 31 28 de ea 94 a0 40 00 fe e2 d6 e7 df e1 2b 1b e8 60 54 71 cd 93 f4 6e b4 82 | r..2<.1(....@.......+..`Tq...n.. |
| 0200 | 7b 88 fc 73 b7 a2 06 86 0a f1 d6 48 22 fe 05 d5 ad bd 7b 96 a4 5f bb 7b d6 f5 46 87 3f 9f 82 94 | {..s.......H".....{.._.{..F.?... |
| 0220 | 11 97 ff f9 84 7d b6 37 94 82 65 7f bd 32 a1 4a 5a d4 cd d7 5a 29 09 75 ab b3 fd 1b b0 da 18 d6 | .....}.7..e..2.JZ...Z).u........ |
| 0240 | 4e 0f 52 c2 3c 23 9d 01 63 02 59 a9 64 10 20 ce ea 96 62 41 39 18 99 5a 93 96 94 6e 86 4c 77 d2 | N.R.<#..c.Y.d.....bA9..Z...n.Lw. |
| 0260 | 3f cb ef 28 b3 47 d9 96 95 43 6a 03 6f fa 1e 59 45 88 da 72 f6 85 61 83 b3 d1 75 5b 28 52 0d 6c | ?..(.G...Cj.o..YE..r..a...u[(R.l |
| 0280 | 5b 2b 33 5b 0b fa 0a ae 29 db 67 41 4c 2f ee c4 4a cb 46 25 87 88 f2 dc 45 82 41 56 5e 91 f0 40 | [+3[....).gAL/..J.F%....E.AV^..@ |
| 02a0 | 8d db 0d 7c fe bc 52 ed 59 ae c5 e6 b7 3c 1f 43 ad 05 84 ad 31 88 9b 6d da b0 47 01 25 ea 8c 6e | ...|..R.Y....<.C....1..m..G.%..n |
| 02c0 | ad 45 0d 4a c0 bc 0a 2c 7d e4 52 99 d0 b5 f0 77 ef 0d 66 24 9c 14 b4 31 8f e6 c7 0b 7f bb 8b 94 | .E.J...,}.R....w..f$...1........ |
| 02e0 | 96 1c 70 03 72 8f 54 69 4f bb 97 7c 32 a9 f0 ce 08 39 1e b7 58 20 f6 a5 fc 49 e9 c7 09 ea 46 af | ..p.r.TiO..|2....9..X....I....F. |
| 0300 | ab 39 a2 db 3a da 43 e5 9e 74 c7 33 0a 81 b7 ff ef dc f9 d7 cf 9e 76 02 fe 88 05 c7 82 7e ea 2b | .9..:.C..t.3..........v......~.+ |
| 0320 | f8 0b e6 45 14 37 31 d3 be df 23 07 6f 34 b4 af 07 6d 6c ed 32 4d d5 93 be 18 9a cc cc fe 33 e9 | ...E.71...#.o4...ml.2M........3. |
| 0340 | 96 d1 2f 11 6a 91 5a 1e da 58 03 4a 5f 1e 98 21 c6 96 7a be ba 25 f5 08 0b da 73 30 f8 88 63 c5 | ../.j.Z..X.J_..!..z..%....s0..c. |
| 0360 | 76 b1 2e 0a 62 f7 b8 f6 51 02 01 2b c1 4c 43 3c 08 9f db 5d 49 28 26 b2 82 e0 cc e8 8b cd 6c 12 | v...b...Q..+.LC<...]I(&.......l. |
| 0380 | 1f b1 46 1a d7 64 cc e3 13 22 47 21 73 9c cc db 24 66 cd 27 93 8c 25 89 bd 32 c1 43 f7 1f a8 34 | ..F..d..."G!s...$f.'..%..2.C...4 |
| 03a0 | 5d 3d 26 2e 9e 6f 21 29 e1 8d a7 ab 65 32 b2 65 e1 50 7a 8d bb ff a4 da 36 44 3b cd 0d ce c1 b9 | ]=&..o!)....e2.e.Pz.....6D;..... |
| 03c0 | 63 b2 5b 83 69 c5 be ca 9a 08 71 1d 48 d2 7e 62 93 b3 8c a4 b6 93 fe ca d9 ea 90 c3 a7 d7 ed 61 | c.[.i.....q.H.~b...............a |
| 03e0 | 1a 3f 3b c8 15 8d 6f 75 3b 80 f7 ee 11 71 69 79 bc 5c a8 84 86 24 8d c5 cb d7 d5 13 d8 94 89 4e | .?;...ou;....qiy.\...$.........N |
| 0400 | 60 3f e5 12 75 d9 f9 69 d3 1a 68 73 9c 0e 39 00 d1 e7 71 f0 b2 c3 8b be 01 85 e6 11 51 bc 56 2a | `?..u..i..hs..9...q.........Q.V* |
| 0420 | c8 d2 e8 00 44 1a 23 23 e8 b6 cb 60 c8 8f 5f 67 4f 42 e8 5c 32 17 24 09 6e 61 f3 8f f2 d1 11 b4 | ....D.##...`.._gOB.\2.$.na...... |
| 0440 | 52 02 bb 1d c1 0f a4 f7 26 53 a2 7f 3f 7d 00 d2 27 b8 9c da 41 61 be c4 3a 0e 8a e3 c7 0f e4 d8 | R.......&S..?}..'...Aa..:....... |
| 0460 | 97 43 9a 2f 74 0a 43 65 92 58 0a cb 9d 4f cc 06 28 ed bd 73 7b 0c d9 c1 11 7f ab 9e 7f b5 6a 4a | .C./t.Ceconst jwt = require("jsonwebtoken");
const uuidv4 = require("uuid/v4");
const WebSocket = require("ws");
wss = new WebSocket.Server({ clientTracking: false, noServer: true });
/* eslint-disable-next-line */
const pick = (O, ...K) => K.reduce((o, k) => ((o[k] = O[k]), o), {});
const all = {};
const subscriptions = [];
emit = (username, type, data) => {
if (data.username !== undefined) data = pick(data, ...whitelist);
if (type === "payment" && data.amount > 0) {
for (let i = subscriptions.length - 1; i >= 0; i--) {
let s = subscriptions[i];
if (
s.invoice.amount === data.amount ||
s.invoice.address === data.address ||
s.invoice.unconfidential === data.address
) {
s.ws.send(JSON.stringify({ type, data }));
subscriptions.splice(i, 1);
}
}
}
if (!sockets[username]) return;
for (id in sockets[username]) {
const ws = sockets[username][id];
ws.send(JSON.stringify({ type, data }));
}
};
broadcast = (type, data) => {
const sent = [];
for (const username in sockets) {
for (const id in sockets[username]) {
const ws = sockets[username][id];
ws.send(JSON.stringify({ type, data }));
sent.push(ws.id);
}
}
Object.values(all).map(ws => {
if (!sent.includes(ws.id)) ws.send(JSON.stringify({ type, data }));
});
};
server.on("upgrade", function(req, socket, head) {
wss.handleUpgrade(req, socket, head, function(ws) {
wss.emit("connection", ws, req);
});
});
const names = {};
setInterval(() => {
for (const username in sockets) {
for (const id in sockets[username]) {
let ws = sockets[username][id];
ws.beats++;
if (ws.beats > 10) ws.close();
}
}
}, 2000);
wss.on("connection", function(ws, req) {
const id = uuidv4();
ws.id = id;
ws.beats = 0;
ws.send(JSON.stringify({ type: "connected", data: id }));
all[id] = ws;
ws.on("message", async message => {
let type, data;
try {
({ type, data } = JSON.parse(message));
} catch (e) {
l.error("coudn't parse socket message");
}
switch (type) {
case "heartbeat":
ws.beats = 0;
break;
case "login":
let token = data;
try {
if (!token || token === "null") return ws.close();
const username = jwt.decode(token).username;
if (!username) throw new Error("Invalid JWT token");
if (!sockets[username]) sockets[username] = {};
const existing = Object.keys(sockets[username]);
if (existing.length > 4) {
const p = existing.find(sid => sid !== id);
sockets[username][p].send(JSON.stringify({ type: "logout" }));
setTimeout(() => {
if (sockets[username][p]) sockets[username][p].close();
}, 5000);
}
sockets[username][id] = ws;
names[id] = username;
let user = await getUser(username);
let payments = await user.getPayments({
where: {
account_id: user.account_id
},
order: [["id", "DESC"]],
limit: 12,
include: {
model: db.Account,
as: "account"
}
});
let accounts = await user.getAccounts();
let keys = await user.getKeys();
user = user.get({ plain: true });
user.accounts = accounts;
user.keys = keys;
user.payments = payments;
ws.user = user;
ws.send(JSON.stringify({ type: "login", data: user }));
ws.send(
JSON.stringify({ type: "version", data: config.clientVersion })
);
} catch (e) {
l.error("caught socket error", e.message);
if (e.message.includes("not found"))
ws.send(JSON.stringify({ type: "logout" }));
setTimeout(ws.close, 1000);
}
break;
case "token":
if (!ws.user) return;
ws.token = data;
break;
case "lnurl":
sessions[data] = ws;
break;
case "updateMemo":
const payment = await db.Payment.findOne({
where: {
user_id: ws.user.id,
id: data.id
},
include: {
model: db.Account,
as: "account"
}
});
if (payment) {
payment.memo = data.memo;
await payment.save();
emit(ws.user.username, "payment", payment);
}
break;
case "subscribe":
subscriptions.push({ invoice: data, ws });
break;
default:
l.warn("received socket message of unknown type", type, data);
}
});
ws.on("close", function() {
try {
const username = names[id];
if (sockets[username] && sockets[username][id]) {
delete sockets[username][id];
}
if (all[id]) delete all[id];
} catch (e) {
l.error("problem closing socket", e.message);
}
});
});
|