instbyte 1.6.2 → 1.6.3

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 (2) hide show
  1. package/package.json +4 -3
  2. package/server/server.js +39 -9
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "instbyte",
3
- "version": "1.6.2",
3
+ "version": "1.6.3",
4
4
  "description": "A self-hosted LAN sharing utility for fast, frictionless file, link, and snippet exchange across devices — no cloud required.",
5
5
  "main": "server/server.js",
6
6
  "bin": {
@@ -26,7 +26,7 @@
26
26
  "socket-io",
27
27
  "sqlite"
28
28
  ],
29
- "author": "your name",
29
+ "author": "Mohit Gauniyal",
30
30
  "license": "MIT",
31
31
  "repository": {
32
32
  "type": "git",
@@ -39,9 +39,10 @@
39
39
  "cookie-parser": "^1.4.6",
40
40
  "express": "^4.18.2",
41
41
  "express-rate-limit": "^7.1.5",
42
+ "helmet": "^8.1.0",
42
43
  "multer": "^2.0.2",
43
44
  "sharp": "^0.33.2",
44
45
  "socket.io": "^4.6.1",
45
46
  "sqlite3": "^5.1.6"
46
47
  }
47
- }
48
+ }
package/server/server.js CHANGED
@@ -4,6 +4,7 @@ const os = require("os");
4
4
  const net = require("net");
5
5
  const cookieParser = require("cookie-parser");
6
6
  const rateLimit = require("express-rate-limit");
7
+ const helmet = require("helmet");
7
8
 
8
9
  let sharp = null;
9
10
  try { sharp = require("sharp"); } catch (e) { }
@@ -26,6 +27,10 @@ const app = express();
26
27
  const server = http.createServer(app);
27
28
  const io = new Server(server, { cors: { origin: "*" } });
28
29
 
30
+ app.use(helmet({
31
+ contentSecurityPolicy: false // disable CSP for now — it would block CDN scripts
32
+ }));
33
+
29
34
  app.use(express.json());
30
35
  app.use(cookieParser());
31
36
  app.use(requireAuth);
@@ -121,7 +126,7 @@ function requireAuth(req, res, next) {
121
126
  if (!config.auth.passphrase) return next(); // no passphrase set, skip
122
127
 
123
128
  // Allow the login route itself through
124
- if (req.path === "/login" || req.path === "/info") return next();
129
+ if (req.path === "/login" || req.path === "/info" || req.path === "/health") return next();
125
130
 
126
131
 
127
132
  // Check cookie
@@ -411,19 +416,27 @@ app.post("/channels", (req, res) => {
411
416
  const { name } = req.body;
412
417
  if (!name) return res.status(400).json({ error: "Name required" });
413
418
 
419
+ const trimmed = name.trim();
420
+ if (trimmed.length < 1 || trimmed.length > 32) {
421
+ return res.status(400).json({ error: "Channel name must be 1–32 characters" });
422
+ }
423
+ if (!/^[a-zA-Z0-9 _\-]+$/.test(trimmed)) {
424
+ return res.status(400).json({ error: "Only letters, numbers, spaces, hyphens, and underscores allowed" });
425
+ }
426
+
414
427
  db.get("SELECT COUNT(*) as count FROM channels", (err, row) => {
415
428
 
416
429
  if (row.count >= 10) {
417
430
  return res.status(400).json({ error: "Max 10 channels allowed" });
418
431
  }
419
432
 
420
- db.run("INSERT INTO channels (name) VALUES (?)", [name], function (err) {
433
+ db.run("INSERT INTO channels (name) VALUES (?)", [trimmed], function (err) {
421
434
 
422
435
  if (err) {
423
436
  return res.status(400).json({ error: "Channel exists" });
424
437
  }
425
- io.emit("channel-added", { id: this.lastID, name });
426
- res.json({ id: this.lastID, name });
438
+ io.emit("channel-added", { id: this.lastID, trimmed });
439
+ res.json({ id: this.lastID, name: trimmed });
427
440
 
428
441
  });
429
442
 
@@ -485,18 +498,25 @@ app.patch("/item/:id/move", (req, res) => {
485
498
  app.patch("/channels/:name", (req, res) => {
486
499
  const oldName = req.params.name;
487
500
  const { name: newName } = req.body;
488
-
489
501
  if (!newName) return res.status(400).json({ error: "Name required" });
490
502
 
503
+ const trimmed = newName.trim();
504
+ if (trimmed.length < 1 || trimmed.length > 32) {
505
+ return res.status(400).json({ error: "Channel name must be 1–32 characters" });
506
+ }
507
+ if (!/^[a-zA-Z0-9 _\-]+$/.test(trimmed)) {
508
+ return res.status(400).json({ error: "Only letters, numbers, spaces, hyphens, and underscores allowed" });
509
+ }
510
+
491
511
  db.get("SELECT * FROM channels WHERE name=?", [oldName], (err, row) => {
492
512
  if (!row) return res.status(404).json({ error: "Channel not found" });
493
513
 
494
- db.run("UPDATE channels SET name=? WHERE name=?", [newName, oldName], (err) => {
514
+ db.run("UPDATE channels SET name=? WHERE name=?", [trimmed, oldName], (err) => {
495
515
  if (err) return res.status(400).json({ error: "Channel name already exists" });
496
516
 
497
- db.run("UPDATE items SET channel=? WHERE channel=?", [newName, oldName], () => {
498
- io.emit("channel-renamed", { oldName, newName });
499
- res.json({ oldName, newName });
517
+ db.run("UPDATE items SET channel=? WHERE channel=?", [trimmed, oldName], () => {
518
+ io.emit("channel-renamed", { oldName, newName: trimmed });
519
+ res.json({ oldName, newName: trimmed });
500
520
  });
501
521
  });
502
522
  });
@@ -539,6 +559,15 @@ app.get("/branding", (req, res) => {
539
559
  });
540
560
  });
541
561
 
562
+ /* HEALTH MONITOR */
563
+ app.get("/health", (req, res) => {
564
+ res.json({
565
+ status: "ok",
566
+ uptime: Math.floor(process.uptime()),
567
+ version: require("../package.json").version
568
+ });
569
+ });
570
+
542
571
 
543
572
  /* FAVICON */
544
573
  app.get("/favicon-dynamic.png", async (req, res) => {
@@ -570,6 +599,7 @@ app.get("/favicon-dynamic.png", async (req, res) => {
570
599
  });
571
600
 
572
601
 
602
+
573
603
  /* LOGO */
574
604
  app.get("/logo-dynamic.png", (req, res) => {
575
605
  const b = config.branding;