@sleep2agi/commhub-server 0.5.0-preview.22 → 0.5.0-preview.23

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.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sleep2agi/commhub-server",
3
- "version": "0.5.0-preview.22",
3
+ "version": "0.5.0-preview.23",
4
4
  "description": "CommHub MCP Server — AI Agent communication hub with SSE push, MCP protocol, and REST API",
5
5
  "type": "module",
6
6
  "main": "src/index.ts",
package/src/auth.ts CHANGED
@@ -139,6 +139,16 @@ export function listTokens(userId: string) {
139
139
  ).all(userId);
140
140
  }
141
141
 
142
+ export function renameNetwork(userId: string, networkId: string, newName: string): { ok: boolean; error?: string } {
143
+ const net = db.query<any, [string]>("SELECT * FROM networks WHERE network_id = ?1").get(networkId);
144
+ if (!net) return { ok: false, error: "network not found" };
145
+ if (net.owner_id !== userId) return { ok: false, error: "not your network" };
146
+ const dup = db.query<any, [string, string]>("SELECT network_id FROM networks WHERE owner_id = ?1 AND network_name = ?2").get(userId, newName);
147
+ if (dup) return { ok: false, error: "name already taken" };
148
+ db.run("UPDATE networks SET network_name = ?1, updated_at = datetime('now') WHERE network_id = ?2", [newName, networkId]);
149
+ return { ok: true };
150
+ }
151
+
142
152
  export function deleteNetwork(userId: string, networkId: string): { ok: boolean; error?: string } {
143
153
  const net = db.query<any, [string]>("SELECT * FROM networks WHERE network_id = ?1").get(networkId);
144
154
  if (!net) return { ok: false, error: "network not found" };
package/src/index.ts CHANGED
@@ -4,7 +4,7 @@ import { z } from "zod/v4";
4
4
  import { registerTools } from "./tools.js";
5
5
  import { db, logTaskEvent, logAudit } from "./db.js";
6
6
  import { createSSEStream, pushEvent, pushBroadcast, getSSEStats } from "./push.js";
7
- import { register, login, resolveToken, getUserNetworks, createNetwork, deleteNetwork, changePassword, listTokens, createToken, revokeToken, type AuthUser } from "./auth.js";
7
+ import { register, login, resolveToken, getUserNetworks, createNetwork, deleteNetwork, renameNetwork, changePassword, listTokens, createToken, revokeToken, type AuthUser } from "./auth.js";
8
8
 
9
9
  const PORT = Number(process.env.PORT) || 9200;
10
10
  const AUTH_TOKEN = process.env.COMMHUB_AUTH_TOKEN;
@@ -410,6 +410,24 @@ Bun.serve({
410
410
  return withCors(req, Response.json(result, { status: result.ok ? 200 : 400 }));
411
411
  }
412
412
 
413
+ if (netDetailMatch && req.method === "PUT") {
414
+ const token = req.headers.get("Authorization")?.replace("Bearer ", "") || url.searchParams.get("token");
415
+ if (!token) return withCors(req, Response.json({ ok: false, error: "auth required" }, { status: 401 }));
416
+ const resolved = resolveToken(token);
417
+ if (!resolved) return withCors(req, Response.json({ ok: false, error: "invalid token" }, { status: 401 }));
418
+ try {
419
+ const body = await req.json() as any;
420
+ if (body.name) {
421
+ const result = renameNetwork(resolved.user.user_id, netDetailMatch[1], body.name);
422
+ if (result.ok) logAudit(resolved.user.user_id, resolved.user.username, "network_renamed", "network", netDetailMatch[1], body.name);
423
+ return withCors(req, Response.json(result, { status: result.ok ? 200 : 400 }));
424
+ }
425
+ return withCors(req, Response.json({ ok: false, error: "name required" }, { status: 400 }));
426
+ } catch (e: any) {
427
+ return withCors(req, Response.json({ ok: false, error: e.message }, { status: 400 }));
428
+ }
429
+ }
430
+
413
431
  // ── REST: health (public, no auth) ──
414
432
  if (url.pathname === "/health") {
415
433
  const count = db.query<{ cnt: number }, []>("SELECT COUNT(*) as cnt FROM sessions").get();