@jetstart/core 1.1.4 → 1.2.0

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.
@@ -17,7 +17,7 @@ export declare class WebSocketHandler {
17
17
  sendBuildStart(sessionId: string): void;
18
18
  sendBuildComplete(sessionId: string, apkUrl: string): void;
19
19
  /**
20
- * Send UI update (DSL-based hot reload)
20
+ * Send UI update (DSL-based hot reload) - SECURE, session-isolated
21
21
  */
22
22
  sendUIUpdate(sessionId: string, dslContent: string, screens?: string[]): void;
23
23
  private generateHash;
@@ -1 +1 @@
1
- {"version":3,"file":"handler.d.ts","sourceRoot":"","sources":["../../src/websocket/handler.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAUH,OAAO,EAAE,iBAAiB,EAAE,MAAM,WAAW,CAAC;AAG9C,qBAAa,gBAAgB;IAIzB,OAAO,CAAC,iBAAiB;IAH3B,OAAO,CAAC,iBAAiB,CAAC,CAA8B;gBAG9C,iBAAiB,EAAE,iBAAiB,EAC5C,OAAO,CAAC,EAAE;QAAE,iBAAiB,CAAC,EAAE,CAAC,SAAS,EAAE,MAAM,KAAK,IAAI,CAAA;KAAE;IAK/D,aAAa,CAAC,QAAQ,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,IAAI;IAenD,OAAO,CAAC,eAAe;IAIvB,OAAO,CAAC,mBAAmB;IAoB3B,OAAO,CAAC,aAAa;IAoBrB,OAAO,CAAC,gBAAgB;IAKxB,cAAc,CAAC,SAAS,EAAE,MAAM,GAAG,IAAI;IAUvC,iBAAiB,CAAC,SAAS,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,IAAI;IAqB1D;;OAEG;IACH,YAAY,CAAC,SAAS,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,MAAM,EAAE,GAAG,IAAI;IAe7E,OAAO,CAAC,YAAY;CAUrB"}
1
+ {"version":3,"file":"handler.d.ts","sourceRoot":"","sources":["../../src/websocket/handler.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAUH,OAAO,EAAE,iBAAiB,EAAE,MAAM,WAAW,CAAC;AAG9C,qBAAa,gBAAgB;IAIzB,OAAO,CAAC,iBAAiB;IAH3B,OAAO,CAAC,iBAAiB,CAAC,CAA8B;gBAG9C,iBAAiB,EAAE,iBAAiB,EAC5C,OAAO,CAAC,EAAE;QAAE,iBAAiB,CAAC,EAAE,CAAC,SAAS,EAAE,MAAM,KAAK,IAAI,CAAA;KAAE;IAK/D,aAAa,CAAC,QAAQ,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,IAAI;IAenD,OAAO,CAAC,eAAe;IAIvB,OAAO,CAAC,mBAAmB;IAoB3B,OAAO,CAAC,aAAa;IAuBrB,OAAO,CAAC,gBAAgB;IAKxB,cAAc,CAAC,SAAS,EAAE,MAAM,GAAG,IAAI;IAUvC,iBAAiB,CAAC,SAAS,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,IAAI;IAqB1D;;OAEG;IACH,YAAY,CAAC,SAAS,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,MAAM,EAAE,GAAG,IAAI;IAe7E,OAAO,CAAC,YAAY;CAUrB"}
@@ -50,6 +50,8 @@ class WebSocketHandler {
50
50
  }
51
51
  handleConnect(clientId, message) {
52
52
  (0, logger_1.log)(`Client connecting with session: ${message.sessionId}`);
53
+ // Associate this client with the session for isolation
54
+ this.connectionManager.setClientSession(clientId, message.sessionId);
53
55
  // Send connected confirmation
54
56
  const response = {
55
57
  type: 'core:connected',
@@ -74,7 +76,7 @@ class WebSocketHandler {
74
76
  timestamp: Date.now(),
75
77
  sessionId,
76
78
  };
77
- this.connectionManager.broadcast(message);
79
+ this.connectionManager.broadcastToSession(sessionId, message);
78
80
  }
79
81
  sendBuildComplete(sessionId, apkUrl) {
80
82
  const message = {
@@ -93,10 +95,10 @@ class WebSocketHandler {
93
95
  },
94
96
  downloadUrl: apkUrl,
95
97
  };
96
- this.connectionManager.broadcast(message);
98
+ this.connectionManager.broadcastToSession(sessionId, message);
97
99
  }
98
100
  /**
99
- * Send UI update (DSL-based hot reload)
101
+ * Send UI update (DSL-based hot reload) - SECURE, session-isolated
100
102
  */
101
103
  sendUIUpdate(sessionId, dslContent, screens) {
102
104
  const message = {
@@ -107,9 +109,9 @@ class WebSocketHandler {
107
109
  screens,
108
110
  hash: this.generateHash(dslContent),
109
111
  };
110
- (0, logger_1.log)(`Sending UI update: ${dslContent.length} bytes`);
112
+ (0, logger_1.log)(`Sending UI update to session ${sessionId}: ${dslContent.length} bytes`);
111
113
  (0, logger_1.log)(`DSL Content: ${dslContent}`);
112
- this.connectionManager.broadcast(message);
114
+ this.connectionManager.broadcastToSession(sessionId, message);
113
115
  }
114
116
  generateHash(content) {
115
117
  // Simple hash for caching (in production, use crypto.createHash)
@@ -1 +1 @@
1
- {"version":3,"file":"handler.js","sourceRoot":"","sources":["../../src/websocket/handler.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"handler.js","sourceRoot":"","sources":["../../src/websocket/handler.ts"],"names":[],"mappings":";AAAA;;;GAGG;;;AAWH,4CAAyD;AAEzD,MAAa,gBAAgB;IAIjB;IAHF,iBAAiB,CAA+B;IAExD,YACU,iBAAoC,EAC5C,OAA6D;QADrD,sBAAiB,GAAjB,iBAAiB,CAAmB;QAG5C,IAAI,CAAC,iBAAiB,GAAG,OAAO,EAAE,iBAAiB,CAAC;IACtD,CAAC;IAED,aAAa,CAAC,QAAgB,EAAE,IAAY;QAC1C,IAAI,CAAC;YACH,MAAM,OAAO,GAAc,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,QAAQ,EAAE,CAAC,CAAC;YACvD,IAAA,YAAG,EAAC,yBAAyB,QAAQ,KAAK,OAAO,CAAC,IAAI,EAAE,CAAC,CAAC;YAE1D,8BAA8B;YAC9B,IAAI,IAAI,CAAC,eAAe,CAAC,OAAO,CAAC,EAAE,CAAC;gBAClC,IAAI,CAAC,mBAAmB,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;YAC9C,CAAC;QAEH,CAAC;QAAC,OAAO,GAAQ,EAAE,CAAC;YAClB,IAAA,cAAQ,EAAC,gCAAgC,QAAQ,KAAK,GAAG,CAAC,OAAO,EAAE,CAAC,CAAC;QACvE,CAAC;IACH,CAAC;IAEO,eAAe,CAAC,OAAkB;QACxC,OAAO,OAAO,CAAC,IAAI,CAAC,UAAU,CAAC,SAAS,CAAC,CAAC;IAC5C,CAAC;IAEO,mBAAmB,CAAC,QAAgB,EAAE,OAAsB;QAClE,QAAQ,OAAO,CAAC,IAAI,EAAE,CAAC;YACrB,KAAK,gBAAgB;gBACnB,IAAI,CAAC,aAAa,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;gBACtC,MAAM;YACR,KAAK,eAAe;gBAClB,IAAA,YAAG,EAAC,UAAU,QAAQ,YAAY,OAAO,CAAC,MAAM,EAAE,CAAC,CAAC;gBACpD,MAAM;YACR,KAAK,YAAY;gBACf,0BAA0B;gBAC1B,MAAM;YACR,KAAK,kBAAkB;gBACrB,uBAAuB;gBACvB,MAAM;YACR,KAAK,mBAAmB;gBACtB,IAAI,CAAC,gBAAgB,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;gBACzC,MAAM;QACV,CAAC;IACH,CAAC;IAEO,aAAa,CAAC,QAAgB,EAAE,OAAmD;QACzF,IAAA,YAAG,EAAC,mCAAmC,OAAO,CAAC,SAAS,EAAE,CAAC,CAAC;QAE5D,uDAAuD;QACvD,IAAI,CAAC,iBAAiB,CAAC,gBAAgB,CAAC,QAAQ,EAAE,OAAO,CAAC,SAAS,CAAC,CAAC;QAErE,8BAA8B;QAC9B,MAAM,QAAQ,GAAyB;YACrC,IAAI,EAAE,gBAAgB;YACtB,SAAS,EAAE,IAAI,CAAC,GAAG,EAAE;YACrB,SAAS,EAAE,OAAO,CAAC,SAAS;YAC5B,WAAW,EAAE,aAAa,EAAE,2CAA2C;SACxE,CAAC;QAEF,IAAI,CAAC,iBAAiB,CAAC,YAAY,CAAC,QAAQ,EAAE,QAAQ,CAAC,CAAC;QAExD,uCAAuC;QACvC,IAAI,IAAI,CAAC,iBAAiB,EAAE,CAAC;YAC3B,IAAA,YAAG,EAAC,yCAAyC,OAAO,CAAC,SAAS,EAAE,CAAC,CAAC;YAClE,IAAI,CAAC,iBAAiB,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC;QAC5C,CAAC;IACH,CAAC;IAEO,gBAAgB,CAAC,QAAgB,EAAE,OAAsD;QAC/F,IAAA,YAAG,EAAC,yBAAyB,OAAO,CAAC,MAAM,IAAI,oBAAoB,EAAE,CAAC,CAAC;IACzE,CAAC;IAED,2BAA2B;IAC3B,cAAc,CAAC,SAAiB;QAC9B,MAAM,OAAO,GAA0B;YACrC,IAAI,EAAE,kBAAkB;YACxB,SAAS,EAAE,IAAI,CAAC,GAAG,EAAE;YACrB,SAAS;SACV,CAAC;QAEF,IAAI,CAAC,iBAAiB,CAAC,kBAAkB,CAAC,SAAS,EAAE,OAAO,CAAC,CAAC;IAChE,CAAC;IAED,iBAAiB,CAAC,SAAiB,EAAE,MAAc;QACjD,MAAM,OAAO,GAA6B;YACxC,IAAI,EAAE,qBAAqB;YAC3B,SAAS,EAAE,IAAI,CAAC,GAAG,EAAE;YACrB,SAAS;YACT,OAAO,EAAE;gBACP,IAAI,EAAE,kBAAkB;gBACxB,IAAI,EAAE,OAAO;gBACb,IAAI,EAAE,QAAQ;gBACd,WAAW,EAAE,CAAC;gBACd,WAAW,EAAE,OAAO;gBACpB,aAAa,EAAE,EAAE;gBACjB,gBAAgB,EAAE,EAAE;gBACpB,aAAa,EAAE,iBAAiB;aACjC;YACD,WAAW,EAAE,MAAM;SACpB,CAAC;QAEF,IAAI,CAAC,iBAAiB,CAAC,kBAAkB,CAAC,SAAS,EAAE,OAAO,CAAC,CAAC;IAChE,CAAC;IAED;;OAEG;IACH,YAAY,CAAC,SAAiB,EAAE,UAAkB,EAAE,OAAkB;QACpE,MAAM,OAAO,GAAwB;YACnC,IAAI,EAAE,gBAAgB;YACtB,SAAS,EAAE,IAAI,CAAC,GAAG,EAAE;YACrB,SAAS;YACT,UAAU;YACV,OAAO;YACP,IAAI,EAAE,IAAI,CAAC,YAAY,CAAC,UAAU,CAAC;SACpC,CAAC;QAEF,IAAA,YAAG,EAAC,gCAAgC,SAAS,KAAK,UAAU,CAAC,MAAM,QAAQ,CAAC,CAAC;QAC7E,IAAA,YAAG,EAAC,gBAAgB,UAAU,EAAE,CAAC,CAAC;QAClC,IAAI,CAAC,iBAAiB,CAAC,kBAAkB,CAAC,SAAS,EAAE,OAAO,CAAC,CAAC;IAChE,CAAC;IAEO,YAAY,CAAC,OAAe;QAClC,iEAAiE;QACjE,IAAI,IAAI,GAAG,CAAC,CAAC;QACb,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;YACxC,MAAM,IAAI,GAAG,OAAO,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC;YACnC,IAAI,GAAG,CAAC,CAAC,IAAI,IAAI,CAAC,CAAC,GAAG,IAAI,CAAC,GAAG,IAAI,CAAC;YACnC,IAAI,GAAG,IAAI,GAAG,IAAI,CAAC,CAAC,2BAA2B;QACjD,CAAC;QACD,OAAO,IAAI,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC;IAC3B,CAAC;CACF;AAxID,4CAwIC"}
@@ -1,6 +1,6 @@
1
1
  /**
2
2
  * Connection Manager
3
- * Manages WebSocket connections
3
+ * Manages WebSocket connections with session isolation
4
4
  */
5
5
  import { WebSocket } from 'ws';
6
6
  import { CoreMessage } from '@jetstart/shared';
@@ -9,8 +9,24 @@ export declare class ConnectionManager {
9
9
  addConnection(ws: WebSocket): string;
10
10
  removeConnection(id: string): void;
11
11
  getConnection(id: string): WebSocket | undefined;
12
+ /**
13
+ * Associate a client with a session for isolation
14
+ */
15
+ setClientSession(clientId: string, sessionId: string): void;
12
16
  sendToClient(clientId: string, message: CoreMessage): boolean;
17
+ /**
18
+ * Broadcast to all clients (UNSAFE - use broadcastToSession instead)
19
+ * @deprecated Use broadcastToSession for session isolation
20
+ */
13
21
  broadcast(message: CoreMessage): void;
22
+ /**
23
+ * Broadcast to all clients in a specific session (SECURE)
24
+ */
25
+ broadcastToSession(sessionId: string, message: CoreMessage): void;
26
+ /**
27
+ * Broadcast to ALL clients regardless of session (use with caution)
28
+ */
29
+ private broadcastToAll;
14
30
  getConnectionCount(): number;
15
31
  }
16
32
  //# sourceMappingURL=manager.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"manager.d.ts","sourceRoot":"","sources":["../../src/websocket/manager.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,SAAS,EAAE,MAAM,IAAI,CAAC;AAE/B,OAAO,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAE/C,qBAAa,iBAAiB;IAC5B,OAAO,CAAC,WAAW,CAAqC;IAExD,aAAa,CAAC,EAAE,EAAE,SAAS,GAAG,MAAM;IAMpC,gBAAgB,CAAC,EAAE,EAAE,MAAM,GAAG,IAAI;IAIlC,aAAa,CAAC,EAAE,EAAE,MAAM,GAAG,SAAS,GAAG,SAAS;IAIhD,YAAY,CAAC,QAAQ,EAAE,MAAM,EAAE,OAAO,EAAE,WAAW,GAAG,OAAO;IAgB7D,SAAS,CAAC,OAAO,EAAE,WAAW,GAAG,IAAI;IAiBrC,kBAAkB,IAAI,MAAM;CAG7B"}
1
+ {"version":3,"file":"manager.d.ts","sourceRoot":"","sources":["../../src/websocket/manager.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,SAAS,EAAE,MAAM,IAAI,CAAC;AAE/B,OAAO,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAO/C,qBAAa,iBAAiB;IAC5B,OAAO,CAAC,WAAW,CAA4C;IAE/D,aAAa,CAAC,EAAE,EAAE,SAAS,GAAG,MAAM;IAMpC,gBAAgB,CAAC,EAAE,EAAE,MAAM,GAAG,IAAI;IAIlC,aAAa,CAAC,EAAE,EAAE,MAAM,GAAG,SAAS,GAAG,SAAS;IAIhD;;OAEG;IACH,gBAAgB,CAAC,QAAQ,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,IAAI;IAQ3D,YAAY,CAAC,QAAQ,EAAE,MAAM,EAAE,OAAO,EAAE,WAAW,GAAG,OAAO;IAgB7D;;;OAGG;IACH,SAAS,CAAC,OAAO,EAAE,WAAW,GAAG,IAAI;IAKrC;;OAEG;IACH,kBAAkB,CAAC,SAAS,EAAE,MAAM,EAAE,OAAO,EAAE,WAAW,GAAG,IAAI;IAoBjE;;OAEG;IACH,OAAO,CAAC,cAAc;IAiBtB,kBAAkB,IAAI,MAAM;CAG7B"}
@@ -1,7 +1,7 @@
1
1
  "use strict";
2
2
  /**
3
3
  * Connection Manager
4
- * Manages WebSocket connections
4
+ * Manages WebSocket connections with session isolation
5
5
  */
6
6
  Object.defineProperty(exports, "__esModule", { value: true });
7
7
  exports.ConnectionManager = void 0;
@@ -11,22 +11,32 @@ class ConnectionManager {
11
11
  connections = new Map();
12
12
  addConnection(ws) {
13
13
  const id = (0, uuid_1.v4)();
14
- this.connections.set(id, ws);
14
+ this.connections.set(id, { ws, sessionId: undefined });
15
15
  return id;
16
16
  }
17
17
  removeConnection(id) {
18
18
  this.connections.delete(id);
19
19
  }
20
20
  getConnection(id) {
21
- return this.connections.get(id);
21
+ return this.connections.get(id)?.ws;
22
+ }
23
+ /**
24
+ * Associate a client with a session for isolation
25
+ */
26
+ setClientSession(clientId, sessionId) {
27
+ const connection = this.connections.get(clientId);
28
+ if (connection) {
29
+ connection.sessionId = sessionId;
30
+ console.log(`[ConnectionManager] Client ${clientId} joined session ${sessionId}`);
31
+ }
22
32
  }
23
33
  sendToClient(clientId, message) {
24
- const ws = this.connections.get(clientId);
25
- if (!ws || ws.readyState !== ws_1.WebSocket.OPEN) {
34
+ const connection = this.connections.get(clientId);
35
+ if (!connection || connection.ws.readyState !== ws_1.WebSocket.OPEN) {
26
36
  return false;
27
37
  }
28
38
  try {
29
- ws.send(JSON.stringify(message));
39
+ connection.ws.send(JSON.stringify(message));
30
40
  return true;
31
41
  }
32
42
  catch (err) {
@@ -34,14 +44,46 @@ class ConnectionManager {
34
44
  return false;
35
45
  }
36
46
  }
47
+ /**
48
+ * Broadcast to all clients (UNSAFE - use broadcastToSession instead)
49
+ * @deprecated Use broadcastToSession for session isolation
50
+ */
37
51
  broadcast(message) {
52
+ console.warn('[ConnectionManager] WARNING: Using unsafe broadcast() - use broadcastToSession() instead');
53
+ this.broadcastToAll(message);
54
+ }
55
+ /**
56
+ * Broadcast to all clients in a specific session (SECURE)
57
+ */
58
+ broadcastToSession(sessionId, message) {
59
+ const data = JSON.stringify(message);
60
+ let sentCount = 0;
61
+ this.connections.forEach((connection, clientId) => {
62
+ // Only send to clients in the same session
63
+ if (connection.sessionId === sessionId && connection.ws.readyState === ws_1.WebSocket.OPEN) {
64
+ try {
65
+ connection.ws.send(data);
66
+ sentCount++;
67
+ console.log(`[ConnectionManager] Sent ${message.type} to client ${clientId} in session ${sessionId}`);
68
+ }
69
+ catch (err) {
70
+ console.error(`Failed to send to ${clientId}:`, err);
71
+ }
72
+ }
73
+ });
74
+ console.log(`[ConnectionManager] Broadcasted ${message.type} to ${sentCount} clients in session ${sessionId}`);
75
+ }
76
+ /**
77
+ * Broadcast to ALL clients regardless of session (use with caution)
78
+ */
79
+ broadcastToAll(message) {
38
80
  const data = JSON.stringify(message);
39
- const connectionCount = Array.from(this.connections.values()).filter(ws => ws.readyState === ws_1.WebSocket.OPEN).length;
81
+ const connectionCount = Array.from(this.connections.values()).filter(c => c.ws.readyState === ws_1.WebSocket.OPEN).length;
40
82
  console.log(`[ConnectionManager] Broadcasting ${message.type} to ${connectionCount} connected clients`);
41
- this.connections.forEach((ws, clientId) => {
42
- if (ws.readyState === ws_1.WebSocket.OPEN) {
83
+ this.connections.forEach((connection, clientId) => {
84
+ if (connection.ws.readyState === ws_1.WebSocket.OPEN) {
43
85
  try {
44
- ws.send(data);
86
+ connection.ws.send(data);
45
87
  console.log(`[ConnectionManager] Sent ${message.type} to client ${clientId}`);
46
88
  }
47
89
  catch (err) {
@@ -1 +1 @@
1
- {"version":3,"file":"manager.js","sourceRoot":"","sources":["../../src/websocket/manager.ts"],"names":[],"mappings":";AAAA;;;GAGG;;;AAEH,2BAA+B;AAC/B,+BAAoC;AAGpC,MAAa,iBAAiB;IACpB,WAAW,GAA2B,IAAI,GAAG,EAAE,CAAC;IAExD,aAAa,CAAC,EAAa;QACzB,MAAM,EAAE,GAAG,IAAA,SAAM,GAAE,CAAC;QACpB,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC;QAC7B,OAAO,EAAE,CAAC;IACZ,CAAC;IAED,gBAAgB,CAAC,EAAU;QACzB,IAAI,CAAC,WAAW,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;IAC9B,CAAC;IAED,aAAa,CAAC,EAAU;QACtB,OAAO,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;IAClC,CAAC;IAED,YAAY,CAAC,QAAgB,EAAE,OAAoB;QACjD,MAAM,EAAE,GAAG,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;QAE1C,IAAI,CAAC,EAAE,IAAI,EAAE,CAAC,UAAU,KAAK,cAAS,CAAC,IAAI,EAAE,CAAC;YAC5C,OAAO,KAAK,CAAC;QACf,CAAC;QAED,IAAI,CAAC;YACH,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC,CAAC;YACjC,OAAO,IAAI,CAAC;QACd,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,OAAO,CAAC,KAAK,CAAC,6BAA6B,QAAQ,GAAG,EAAE,GAAG,CAAC,CAAC;YAC7D,OAAO,KAAK,CAAC;QACf,CAAC;IACH,CAAC;IAED,SAAS,CAAC,OAAoB;QAC5B,MAAM,IAAI,GAAG,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC;QACrC,MAAM,eAAe,GAAG,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,WAAW,CAAC,MAAM,EAAE,CAAC,CAAC,MAAM,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,UAAU,KAAK,cAAS,CAAC,IAAI,CAAC,CAAC,MAAM,CAAC;QACpH,OAAO,CAAC,GAAG,CAAC,oCAAoC,OAAO,CAAC,IAAI,OAAO,eAAe,oBAAoB,CAAC,CAAC;QAExG,IAAI,CAAC,WAAW,CAAC,OAAO,CAAC,CAAC,EAAE,EAAE,QAAQ,EAAE,EAAE;YACxC,IAAI,EAAE,CAAC,UAAU,KAAK,cAAS,CAAC,IAAI,EAAE,CAAC;gBACrC,IAAI,CAAC;oBACH,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;oBACd,OAAO,CAAC,GAAG,CAAC,4BAA4B,OAAO,CAAC,IAAI,cAAc,QAAQ,EAAE,CAAC,CAAC;gBAChF,CAAC;gBAAC,OAAO,GAAG,EAAE,CAAC;oBACb,OAAO,CAAC,KAAK,CAAC,0BAA0B,QAAQ,GAAG,EAAE,GAAG,CAAC,CAAC;gBAC5D,CAAC;YACH,CAAC;QACH,CAAC,CAAC,CAAC;IACL,CAAC;IAED,kBAAkB;QAChB,OAAO,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC;IAC/B,CAAC;CACF;AArDD,8CAqDC"}
1
+ {"version":3,"file":"manager.js","sourceRoot":"","sources":["../../src/websocket/manager.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@jetstart/core",
3
- "version": "1.1.4",
3
+ "version": "1.2.0",
4
4
  "description": "Build server and orchestration for JetStart",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
@@ -33,7 +33,7 @@
33
33
  },
34
34
  "homepage": "https://github.com/dev-phantom/jetstart#readme",
35
35
  "dependencies": {
36
- "@jetstart/shared": "^1.1.4",
36
+ "@jetstart/shared": "^1.2.0",
37
37
  "express": "^4.18.2",
38
38
  "ws": "^8.14.2",
39
39
  "chokidar": "^3.5.3",
@@ -66,6 +66,9 @@ export class WebSocketHandler {
66
66
  private handleConnect(clientId: string, message: ClientMessage & { type: 'client:connect' }): void {
67
67
  log(`Client connecting with session: ${message.sessionId}`);
68
68
 
69
+ // Associate this client with the session for isolation
70
+ this.connectionManager.setClientSession(clientId, message.sessionId);
71
+
69
72
  // Send connected confirmation
70
73
  const response: CoreConnectedMessage = {
71
74
  type: 'core:connected',
@@ -95,7 +98,7 @@ export class WebSocketHandler {
95
98
  sessionId,
96
99
  };
97
100
 
98
- this.connectionManager.broadcast(message);
101
+ this.connectionManager.broadcastToSession(sessionId, message);
99
102
  }
100
103
 
101
104
  sendBuildComplete(sessionId: string, apkUrl: string): void {
@@ -116,11 +119,11 @@ export class WebSocketHandler {
116
119
  downloadUrl: apkUrl,
117
120
  };
118
121
 
119
- this.connectionManager.broadcast(message);
122
+ this.connectionManager.broadcastToSession(sessionId, message);
120
123
  }
121
124
 
122
125
  /**
123
- * Send UI update (DSL-based hot reload)
126
+ * Send UI update (DSL-based hot reload) - SECURE, session-isolated
124
127
  */
125
128
  sendUIUpdate(sessionId: string, dslContent: string, screens?: string[]): void {
126
129
  const message: CoreUIUpdateMessage = {
@@ -132,9 +135,9 @@ export class WebSocketHandler {
132
135
  hash: this.generateHash(dslContent),
133
136
  };
134
137
 
135
- log(`Sending UI update: ${dslContent.length} bytes`);
138
+ log(`Sending UI update to session ${sessionId}: ${dslContent.length} bytes`);
136
139
  log(`DSL Content: ${dslContent}`);
137
- this.connectionManager.broadcast(message);
140
+ this.connectionManager.broadcastToSession(sessionId, message);
138
141
  }
139
142
 
140
143
  private generateHash(content: string): string {
@@ -1,18 +1,23 @@
1
1
  /**
2
2
  * Connection Manager
3
- * Manages WebSocket connections
3
+ * Manages WebSocket connections with session isolation
4
4
  */
5
5
 
6
6
  import { WebSocket } from 'ws';
7
7
  import { v4 as uuidv4 } from 'uuid';
8
8
  import { CoreMessage } from '@jetstart/shared';
9
9
 
10
+ interface ClientConnection {
11
+ ws: WebSocket;
12
+ sessionId?: string; // Session ID for isolation
13
+ }
14
+
10
15
  export class ConnectionManager {
11
- private connections: Map<string, WebSocket> = new Map();
16
+ private connections: Map<string, ClientConnection> = new Map();
12
17
 
13
18
  addConnection(ws: WebSocket): string {
14
19
  const id = uuidv4();
15
- this.connections.set(id, ws);
20
+ this.connections.set(id, { ws, sessionId: undefined });
16
21
  return id;
17
22
  }
18
23
 
@@ -21,18 +26,29 @@ export class ConnectionManager {
21
26
  }
22
27
 
23
28
  getConnection(id: string): WebSocket | undefined {
24
- return this.connections.get(id);
29
+ return this.connections.get(id)?.ws;
30
+ }
31
+
32
+ /**
33
+ * Associate a client with a session for isolation
34
+ */
35
+ setClientSession(clientId: string, sessionId: string): void {
36
+ const connection = this.connections.get(clientId);
37
+ if (connection) {
38
+ connection.sessionId = sessionId;
39
+ console.log(`[ConnectionManager] Client ${clientId} joined session ${sessionId}`);
40
+ }
25
41
  }
26
42
 
27
43
  sendToClient(clientId: string, message: CoreMessage): boolean {
28
- const ws = this.connections.get(clientId);
29
-
30
- if (!ws || ws.readyState !== WebSocket.OPEN) {
44
+ const connection = this.connections.get(clientId);
45
+
46
+ if (!connection || connection.ws.readyState !== WebSocket.OPEN) {
31
47
  return false;
32
48
  }
33
49
 
34
50
  try {
35
- ws.send(JSON.stringify(message));
51
+ connection.ws.send(JSON.stringify(message));
36
52
  return true;
37
53
  } catch (err) {
38
54
  console.error(`Failed to send message to ${clientId}:`, err);
@@ -40,15 +56,50 @@ export class ConnectionManager {
40
56
  }
41
57
  }
42
58
 
59
+ /**
60
+ * Broadcast to all clients (UNSAFE - use broadcastToSession instead)
61
+ * @deprecated Use broadcastToSession for session isolation
62
+ */
43
63
  broadcast(message: CoreMessage): void {
64
+ console.warn('[ConnectionManager] WARNING: Using unsafe broadcast() - use broadcastToSession() instead');
65
+ this.broadcastToAll(message);
66
+ }
67
+
68
+ /**
69
+ * Broadcast to all clients in a specific session (SECURE)
70
+ */
71
+ broadcastToSession(sessionId: string, message: CoreMessage): void {
72
+ const data = JSON.stringify(message);
73
+ let sentCount = 0;
74
+
75
+ this.connections.forEach((connection, clientId) => {
76
+ // Only send to clients in the same session
77
+ if (connection.sessionId === sessionId && connection.ws.readyState === WebSocket.OPEN) {
78
+ try {
79
+ connection.ws.send(data);
80
+ sentCount++;
81
+ console.log(`[ConnectionManager] Sent ${message.type} to client ${clientId} in session ${sessionId}`);
82
+ } catch (err) {
83
+ console.error(`Failed to send to ${clientId}:`, err);
84
+ }
85
+ }
86
+ });
87
+
88
+ console.log(`[ConnectionManager] Broadcasted ${message.type} to ${sentCount} clients in session ${sessionId}`);
89
+ }
90
+
91
+ /**
92
+ * Broadcast to ALL clients regardless of session (use with caution)
93
+ */
94
+ private broadcastToAll(message: CoreMessage): void {
44
95
  const data = JSON.stringify(message);
45
- const connectionCount = Array.from(this.connections.values()).filter(ws => ws.readyState === WebSocket.OPEN).length;
96
+ const connectionCount = Array.from(this.connections.values()).filter(c => c.ws.readyState === WebSocket.OPEN).length;
46
97
  console.log(`[ConnectionManager] Broadcasting ${message.type} to ${connectionCount} connected clients`);
47
98
 
48
- this.connections.forEach((ws, clientId) => {
49
- if (ws.readyState === WebSocket.OPEN) {
99
+ this.connections.forEach((connection, clientId) => {
100
+ if (connection.ws.readyState === WebSocket.OPEN) {
50
101
  try {
51
- ws.send(data);
102
+ connection.ws.send(data);
52
103
  console.log(`[ConnectionManager] Sent ${message.type} to client ${clientId}`);
53
104
  } catch (err) {
54
105
  console.error(`Failed to broadcast to ${clientId}:`, err);