@nka212bg/backend-utils 0.1.26 → 0.1.28

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (3) hide show
  1. package/misc.js +75 -1
  2. package/package.json +3 -3
  3. package/socket.js +56 -53
package/misc.js CHANGED
@@ -374,6 +374,80 @@ exports.crypto = ({ salt, embedSalt } = {}) => {
374
374
  function byteHex(n) {
375
375
  return ("0" + Number(n).toString(16)).slice(-2);
376
376
  }
377
+
378
+ // TODO
379
+ // NEW CRYPTO
380
+ //
381
+ // --- 1. PRE-COMPUTE THE CRYPTO KEY ONCE ---
382
+ //  async function initializeKey(password) {
383
+ //    const rawKey = await crypto.subtle.digest("SHA-256"
384
+ //    return crypto.subtle.importKey("raw", rawKey, "AES-CTR", false, ["encrypt", "decrypt"]);
385
+ //  }
386
+ //
387
+ //  // --- HELPER: GZIP Compression Streams ---
388
+ //  async function compressText(text) {
389
+ //    const stream = new Response(text).body.
390
+ //    return new Uint8Array(await new Response(stream).arrayBuffer()
391
+ //  }
392
+ //
393
+ //  async function decompressText(bytes) {
394
+ //    const stream = new Response(bytes).body.
395
+ //    return new Response(stream).text();
396
+ //  }
397
+ //
398
+ //  // --- 2. ENCRYPT WITH COMPRESSION ---
399
+ //  async function encrypt(plainText, cryptoKey) {
400
+ //    const iv = crypto.getRandomValues(new Uint8Array(16));
401
+ //
402
+ //    // Compress the text into tiny raw bytes first
403
+ //    const compressedBytes = await compressText(plainText);
404
+ //
405
+ //    // Encrypt the tiny compressed bytes
406
+ //    const buffer = await crypto.subtle.encrypt(
407
+ //      { name: "AES-CTR", counter: iv, length: 64 },
408
+ //      cryptoKey,
409
+ //      compressedBytes
410
+ //    );
411
+ //
412
+ //    const ivBase64 = btoa(String.fromCharCode(...
413
+ //    const cipherBase64 = btoa(String.fromCharCode(...
414
+ //
415
+ //    return `${ivBase64}:${cipherBase64}`;
416
+ //  }
417
+ //
418
+ //  // --- 3. DECRYPT WITH DECOMPRESSION ---
419
+ //  async function decrypt(encryptedString, cryptoKey) {
420
+ //    const [ivBase64, cipherBase64] = encryptedString.split(":");
421
+ //
422
+ //    const iv = Uint8Array.from(atob(ivBase64)
423
+ //    const cipherText = Uint8Array.from(atob(
424
+ //
425
+ //    // Decrypt back to compressed bytes
426
+ //    const decryptedBuffer = await crypto.subtle.decrypt(
427
+ //      { name: "AES-CTR", counter: iv, length: 64 },
428
+ //      cryptoKey,
429
+ //      cipherText
430
+ //    );
431
+ //
432
+ //    // Decompress back to original text string
433
+ //    return await decompressText(new Uint8Array(decryptedBuffer));
434
+ //  }
435
+ //
436
+ //  // --- DEMO RUN ---
437
+ //  async function run() {
438
+ //    const cryptoKey = await initializeKey("sdfg#$%gd
439
+ //
440
+ //    // Compression shines on repetitive texts, paragraphs, or JSON data!
441
+ //    const longText = "Repeat this! Repeat сасдасфд this! Repeat this! Super long paragraph data...";
442
+ //
443
+ //    const encrypted = await encrypt(longText, cryptoKey);
444
+ //    console.log("Compressed & Encrypted String:\n", encrypted);
445
+ //
446
+ //    const decrypted = await decrypt(encrypted, cryptoKey);
447
+ //    console.log("\nDecrypted Output:\n", decrypted);
448
+ //  }
449
+ //
450
+ //  run();
377
451
  };
378
452
 
379
453
  exports.secToTime = (sec) => {
@@ -484,7 +558,7 @@ exports.strToEmailsArray = (emailString) => {
484
558
  String(emailString)
485
559
  .toLowerCase()
486
560
  // .match(/\w[\w\.-]+\w@\w+((\.\w+){1,})+\w+/gi)
487
- .match(/\w[\w\.-]+\w@[\w\.-]+((\.\w+){1,})+\w+/g)
561
+ .match(/\w[\w\.-]+\w@[\w\.-]+((\.\w+){1,})+\w+/g),
488
562
  ),
489
563
  ].sort();
490
564
  };
package/package.json CHANGED
@@ -1,17 +1,17 @@
1
1
  {
2
2
  "name": "@nka212bg/backend-utils",
3
3
  "author": "nka212bg",
4
- "version": "0.1.26",
4
+ "version": "0.1.28",
5
5
  "main": "index.js",
6
6
  "dependencies": {
7
7
  "@maxmind/geoip2-node": "^5.0.0",
8
8
  "systeminformation": "^5.21.24",
9
9
  "adm-zip": "^0.5.16",
10
- "nodemailer": "^6.9.14",
10
+ "nodemailer": "^8.0.8",
11
11
  "os-utils": "^0.0.14",
12
12
  "stripe": "^14.23.0",
13
13
  "mysql2": "^3.11.0",
14
- "sqlite3": "^5.1.7",
14
+ "sqlite3": "^6.0.1",
15
15
  "sharp": "^0.33.5",
16
16
  "ws": "^7.3.0"
17
17
  }
package/socket.js CHANGED
@@ -1,78 +1,81 @@
1
1
  const WebSocket = require("ws");
2
- let socketsCount = 0;
3
- let sockets = [];
4
2
 
5
- exports.socket = (server) => {
6
- const sl = sockets.length;
7
- sockets[sl] = new WebSocket.Server({ server });
8
- sockets[sl].on("connection", (ws, req) => {
3
+ module.exports = (server) => {
4
+ const socket = new WebSocket.Server({ server, noServer: !server });
5
+ socket.on("connection", (ws, req) => {
9
6
  try {
10
7
  ws.params = Object.fromEntries(new URLSearchParams(decodeURIComponent(req.url || "").replace(/^(\/\?|\?|\/)/g, "")));
11
8
  } catch (error) {}
12
9
  });
13
- };
14
10
 
15
- exports.getUsersStatuses = (users) => {
16
- if (typeof users == "string") users = users.split(/[, ]/g);
17
- if (!Array.isArray(users) || !sockets.length) return {};
18
-
19
- const usersObj = {};
20
- users.forEach((u) => {
21
- usersObj[u] = { online: false };
22
-
23
- for (const socket of sockets) {
24
- for (const client of socket.clients) {
25
- if (client.params.userId == u) {
26
- usersObj[u] = { online: true };
27
- return;
28
- }
29
- }
30
- }
31
- });
11
+ socket.broadcast = (data, { skipId, skipToken } = {}) => {
12
+ if (!data) return 0;
13
+ if (typeof data === "object") data = JSON.stringify(data);
32
14
 
33
- return usersObj;
34
- };
15
+ skipId = new Set(String(skipId).split(/[,"' ]/g).filter(Boolean));
16
+ skipToken = new Set(String(skipToken).split(/[,"' ]/g).filter(Boolean));
35
17
 
36
- exports.sendSocketMessage = ({ userId, skipId, skipToken, data, broadcast } = {}) => {
37
- let sentCount = 0;
38
- let tempCount = 0;
18
+ let sentCount = 0;
19
+ for (const client of socket.clients || []) {
20
+ if (skipId.has(client.params.userId)) continue;
21
+ if (skipToken.has(client.params.authToken)) continue;
39
22
 
40
- if ((!userId && !broadcast) || !sockets.length) return;
41
- userId = !Array.isArray(userId) ? [String(userId)] : userId.map((e) => String(e));
23
+ client.send(data);
24
+ sentCount++;
25
+ }
42
26
 
43
- if (skipId) skipId = !Array.isArray(skipId) ? [String(skipId)] : skipId.map((e) => String(e));
44
- if (skipToken && !Array.isArray(skipToken)) skipToken = [String(skipToken)];
27
+ return sentCount;
28
+ };
45
29
 
46
- try {
47
- if (typeof data != "string") data = JSON.stringify(data);
48
- } catch {}
30
+ socket.send = (data, { userId = [], skipId = [], skipToken = [] } = {}) => {
31
+ if (!data) return 0;
32
+ if (typeof data === "object") data = JSON.stringify(data);
49
33
 
50
- sockets.forEach((socket) => {
51
- (socket.clients || []).forEach(manageClient);
52
- });
34
+ userId = new Set(String(userId).split(/[,"' ]/g).filter(Boolean));
35
+ skipId = new Set(String(skipId).split(/[,"' ]/g).filter(Boolean));
36
+ skipToken = new Set(String(skipToken).split(/[,"' ]/g).filter(Boolean));
37
+
38
+ let sentCount = 0;
39
+ for (const client of socket.clients || []) {
40
+ if (!userId.has(client.params.userId)) continue;
41
+ if (skipId.has(client.params.userId)) continue;
42
+ if (skipToken.has(client.params.authToken)) continue;
43
+
44
+ client.send(data);
45
+ sentCount++;
46
+ }
53
47
 
54
- socketsCount = tempCount;
55
- return sentCount;
48
+ return sentCount;
49
+ };
56
50
 
57
- function manageClient(client) {
58
- tempCount += 1;
51
+ socket.getStatuses = (users) => {
52
+ users = new Set(String(users).split(/[,"' ]/g).filter(Boolean));
59
53
 
60
- if (broadcast || userId.includes(client.params.userId)) {
61
- if (skipId && skipId.includes(client.params.userId)) return;
62
- if (skipToken && skipToken.includes(client.params.token)) return;
54
+ const usersObj = {};
55
+ for (const u of users) usersObj[u] = 0;
56
+
57
+ let remaining = users.size;
58
+ for (const client of socket.clients || []) {
59
+ if (!remaining) break;
60
+ if (!users.has(client.params.userId)) continue;
63
61
 
64
- client.send(data);
65
- sentCount += 1;
62
+ usersObj[client.params.userId] = 1;
63
+ remaining--;
66
64
  }
67
- }
68
- };
69
65
 
70
- exports.socketStat = () => {
71
- return {
72
- socketsCount,
66
+ return usersObj;
73
67
  };
68
+
69
+
70
+ return socket;
74
71
  };
75
72
 
73
+
74
+
75
+
76
+
77
+ ////////////////////////////////////////
78
+
76
79
  // "web-push": "^3.2.2", // package.json
77
80
  // const webPush = require("web-push");
78
81
  // const VAPID_KEYS = webPush.generateVAPIDKeys();