@burdenoff/vibe-agent 1.0.1 → 1.0.2
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/README.md +14 -14
- package/dist/app.d.ts +4 -4
- package/dist/app.d.ts.map +1 -1
- package/dist/app.js +144 -130
- package/dist/app.js.map +1 -1
- package/dist/cli.d.ts +1 -1
- package/dist/cli.js +342 -332
- package/dist/cli.js.map +1 -1
- package/dist/db/schema.d.ts +15 -15
- package/dist/db/schema.d.ts.map +1 -1
- package/dist/db/schema.js +65 -62
- package/dist/db/schema.js.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +18 -18
- package/dist/index.js.map +1 -1
- package/dist/middleware/ModuleAuth.d.ts +2 -2
- package/dist/middleware/ModuleAuth.d.ts.map +1 -1
- package/dist/middleware/ModuleAuth.js +32 -29
- package/dist/middleware/ModuleAuth.js.map +1 -1
- package/dist/middleware/auth.d.ts +1 -1
- package/dist/middleware/auth.d.ts.map +1 -1
- package/dist/middleware/auth.js +4 -4
- package/dist/middleware/auth.js.map +1 -1
- package/dist/migrations/remove-notes-prompts.d.ts.map +1 -1
- package/dist/migrations/remove-notes-prompts.js +26 -26
- package/dist/migrations/remove-notes-prompts.js.map +1 -1
- package/dist/routes/bookmarks.d.ts +1 -1
- package/dist/routes/bookmarks.d.ts.map +1 -1
- package/dist/routes/bookmarks.js +53 -44
- package/dist/routes/bookmarks.js.map +1 -1
- package/dist/routes/config.d.ts +1 -1
- package/dist/routes/config.d.ts.map +1 -1
- package/dist/routes/config.js +29 -27
- package/dist/routes/config.js.map +1 -1
- package/dist/routes/files.d.ts +1 -1
- package/dist/routes/files.d.ts.map +1 -1
- package/dist/routes/files.js +175 -134
- package/dist/routes/files.js.map +1 -1
- package/dist/routes/git.d.ts +1 -1
- package/dist/routes/git.d.ts.map +1 -1
- package/dist/routes/git.js +183 -169
- package/dist/routes/git.js.map +1 -1
- package/dist/routes/moduleRegistry.d.ts +3 -3
- package/dist/routes/moduleRegistry.d.ts.map +1 -1
- package/dist/routes/moduleRegistry.js +58 -58
- package/dist/routes/moduleRegistry.js.map +1 -1
- package/dist/routes/notifications.d.ts +1 -1
- package/dist/routes/notifications.d.ts.map +1 -1
- package/dist/routes/notifications.js +69 -64
- package/dist/routes/notifications.js.map +1 -1
- package/dist/routes/port-forward.d.ts +1 -1
- package/dist/routes/port-forward.d.ts.map +1 -1
- package/dist/routes/port-forward.js +59 -50
- package/dist/routes/port-forward.js.map +1 -1
- package/dist/routes/projects.d.ts +1 -1
- package/dist/routes/projects.d.ts.map +1 -1
- package/dist/routes/projects.js +134 -120
- package/dist/routes/projects.js.map +1 -1
- package/dist/routes/ssh.d.ts +1 -1
- package/dist/routes/ssh.d.ts.map +1 -1
- package/dist/routes/ssh.js +47 -47
- package/dist/routes/ssh.js.map +1 -1
- package/dist/routes/tasks.d.ts +1 -1
- package/dist/routes/tasks.d.ts.map +1 -1
- package/dist/routes/tasks.js +53 -49
- package/dist/routes/tasks.js.map +1 -1
- package/dist/routes/tmux.d.ts +1 -1
- package/dist/routes/tmux.d.ts.map +1 -1
- package/dist/routes/tmux.js +337 -241
- package/dist/routes/tmux.js.map +1 -1
- package/dist/routes/tunnel.d.ts +2 -2
- package/dist/routes/tunnel.d.ts.map +1 -1
- package/dist/routes/tunnel.js +115 -74
- package/dist/routes/tunnel.js.map +1 -1
- package/dist/services/ModulePermissions.d.ts +2 -2
- package/dist/services/ModulePermissions.d.ts.map +1 -1
- package/dist/services/ModulePermissions.js +50 -40
- package/dist/services/ModulePermissions.js.map +1 -1
- package/dist/services/ModuleRegistryService.d.ts +10 -10
- package/dist/services/ModuleRegistryService.d.ts.map +1 -1
- package/dist/services/ModuleRegistryService.js +156 -131
- package/dist/services/ModuleRegistryService.js.map +1 -1
- package/dist/services/agent.service.d.ts.map +1 -1
- package/dist/services/agent.service.js +24 -21
- package/dist/services/agent.service.js.map +1 -1
- package/dist/services/bootstrap.d.ts +1 -1
- package/dist/services/bootstrap.d.ts.map +1 -1
- package/dist/services/bootstrap.js +146 -69
- package/dist/services/bootstrap.js.map +1 -1
- package/dist/services/service-manager.d.ts +2 -2
- package/dist/services/service-manager.d.ts.map +1 -1
- package/dist/services/service-manager.js +75 -63
- package/dist/services/service-manager.js.map +1 -1
- package/package.json +1 -1
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
import { v4 as uuidv4 } from
|
|
1
|
+
import { v4 as uuidv4 } from "uuid";
|
|
2
2
|
export const notificationRoutes = async (fastify) => {
|
|
3
3
|
// Get all notifications
|
|
4
|
-
fastify.get(
|
|
4
|
+
fastify.get("/", async (request, _reply) => {
|
|
5
5
|
const { projectId, status } = request.query;
|
|
6
6
|
let notifications;
|
|
7
|
-
if (status ===
|
|
7
|
+
if (status === "unread") {
|
|
8
8
|
notifications = fastify.db.getUnreadNotifications();
|
|
9
9
|
}
|
|
10
10
|
else if (projectId !== undefined) {
|
|
@@ -16,39 +16,39 @@ export const notificationRoutes = async (fastify) => {
|
|
|
16
16
|
return { notifications };
|
|
17
17
|
});
|
|
18
18
|
// Get notifications for project
|
|
19
|
-
fastify.get(
|
|
19
|
+
fastify.get("/project/:projectId", async (request, _reply) => {
|
|
20
20
|
const { projectId } = request.params;
|
|
21
21
|
const notifications = fastify.db.getNotificationsByProject(projectId);
|
|
22
22
|
return { notifications };
|
|
23
23
|
});
|
|
24
24
|
// Get unread notifications
|
|
25
|
-
fastify.get(
|
|
25
|
+
fastify.get("/unread", async (_request, _reply) => {
|
|
26
26
|
const notifications = fastify.db.getUnreadNotifications();
|
|
27
27
|
return {
|
|
28
28
|
notifications,
|
|
29
|
-
count: notifications.length
|
|
29
|
+
count: notifications.length,
|
|
30
30
|
};
|
|
31
31
|
});
|
|
32
32
|
// Get global notifications (not tied to specific project)
|
|
33
|
-
fastify.get(
|
|
33
|
+
fastify.get("/global", async (_request, _reply) => {
|
|
34
34
|
const notifications = fastify.db.getNotificationsByProject(null);
|
|
35
35
|
return {
|
|
36
36
|
notifications,
|
|
37
|
-
count: notifications.length
|
|
37
|
+
count: notifications.length,
|
|
38
38
|
};
|
|
39
39
|
});
|
|
40
40
|
// Get notification by ID
|
|
41
|
-
fastify.get(
|
|
41
|
+
fastify.get("/:id", async (request, reply) => {
|
|
42
42
|
const { id } = request.params;
|
|
43
43
|
const notification = fastify.db.getNotification(id);
|
|
44
44
|
if (!notification) {
|
|
45
|
-
return reply.code(404).send({ error:
|
|
45
|
+
return reply.code(404).send({ error: "Notification not found" });
|
|
46
46
|
}
|
|
47
47
|
return { notification };
|
|
48
48
|
});
|
|
49
49
|
// Create notification
|
|
50
|
-
fastify.post(
|
|
51
|
-
const { sessionName, projectId, type =
|
|
50
|
+
fastify.post("/", async (request, reply) => {
|
|
51
|
+
const { sessionName, projectId, type = "info", title, message, } = request.body;
|
|
52
52
|
try {
|
|
53
53
|
const notification = fastify.db.createNotification({
|
|
54
54
|
id: uuidv4(),
|
|
@@ -57,128 +57,128 @@ export const notificationRoutes = async (fastify) => {
|
|
|
57
57
|
type,
|
|
58
58
|
title,
|
|
59
59
|
message,
|
|
60
|
-
status:
|
|
60
|
+
status: "unread",
|
|
61
61
|
});
|
|
62
62
|
// Emit notification created event
|
|
63
|
-
fastify.io.emit(
|
|
63
|
+
fastify.io.emit("notification:created", notification);
|
|
64
64
|
// Check if sound is enabled in config
|
|
65
|
-
const soundEnabled = fastify.db.getConfig(
|
|
65
|
+
const soundEnabled = fastify.db.getConfig("notification_sound") === "true";
|
|
66
66
|
if (soundEnabled) {
|
|
67
|
-
fastify.io.emit(
|
|
67
|
+
fastify.io.emit("notification:sound", { type });
|
|
68
68
|
}
|
|
69
69
|
return { notification };
|
|
70
70
|
}
|
|
71
71
|
catch (error) {
|
|
72
72
|
return reply.code(500).send({
|
|
73
|
-
error:
|
|
74
|
-
details: error instanceof Error ? error.message :
|
|
73
|
+
error: "Failed to create notification",
|
|
74
|
+
details: error instanceof Error ? error.message : "Unknown error",
|
|
75
75
|
});
|
|
76
76
|
}
|
|
77
77
|
});
|
|
78
78
|
// Mark notification as read
|
|
79
|
-
fastify.put(
|
|
79
|
+
fastify.put("/:id/read", async (request, reply) => {
|
|
80
80
|
const { id } = request.params;
|
|
81
81
|
try {
|
|
82
82
|
const notification = fastify.db.getNotification(id);
|
|
83
83
|
if (!notification) {
|
|
84
|
-
return reply.code(404).send({ error:
|
|
84
|
+
return reply.code(404).send({ error: "Notification not found" });
|
|
85
85
|
}
|
|
86
|
-
fastify.db.updateNotificationStatus(id,
|
|
86
|
+
fastify.db.updateNotificationStatus(id, "read");
|
|
87
87
|
// Emit notification read event
|
|
88
|
-
fastify.io.emit(
|
|
88
|
+
fastify.io.emit("notification:read", { id });
|
|
89
89
|
return { success: true };
|
|
90
90
|
}
|
|
91
91
|
catch (error) {
|
|
92
92
|
return reply.code(500).send({
|
|
93
|
-
error:
|
|
94
|
-
details: error instanceof Error ? error.message :
|
|
93
|
+
error: "Failed to mark notification as read",
|
|
94
|
+
details: error instanceof Error ? error.message : "Unknown error",
|
|
95
95
|
});
|
|
96
96
|
}
|
|
97
97
|
});
|
|
98
98
|
// Mark notification as unread
|
|
99
|
-
fastify.put(
|
|
99
|
+
fastify.put("/:id/unread", async (request, reply) => {
|
|
100
100
|
const { id } = request.params;
|
|
101
101
|
try {
|
|
102
102
|
const notification = fastify.db.getNotification(id);
|
|
103
103
|
if (!notification) {
|
|
104
|
-
return reply.code(404).send({ error:
|
|
104
|
+
return reply.code(404).send({ error: "Notification not found" });
|
|
105
105
|
}
|
|
106
|
-
fastify.db.updateNotificationStatus(id,
|
|
106
|
+
fastify.db.updateNotificationStatus(id, "unread");
|
|
107
107
|
// Emit notification unread event
|
|
108
|
-
fastify.io.emit(
|
|
108
|
+
fastify.io.emit("notification:unread", { id });
|
|
109
109
|
return { success: true };
|
|
110
110
|
}
|
|
111
111
|
catch (error) {
|
|
112
112
|
return reply.code(500).send({
|
|
113
|
-
error:
|
|
114
|
-
details: error instanceof Error ? error.message :
|
|
113
|
+
error: "Failed to mark notification as unread",
|
|
114
|
+
details: error instanceof Error ? error.message : "Unknown error",
|
|
115
115
|
});
|
|
116
116
|
}
|
|
117
117
|
});
|
|
118
118
|
// Mark all notifications as read
|
|
119
|
-
fastify.put(
|
|
119
|
+
fastify.put("/read-all", async (_request, reply) => {
|
|
120
120
|
try {
|
|
121
121
|
const unreadNotifications = fastify.db.getUnreadNotifications();
|
|
122
122
|
for (const notification of unreadNotifications) {
|
|
123
|
-
fastify.db.updateNotificationStatus(notification.id,
|
|
123
|
+
fastify.db.updateNotificationStatus(notification.id, "read");
|
|
124
124
|
}
|
|
125
125
|
// Emit all read event
|
|
126
|
-
fastify.io.emit(
|
|
126
|
+
fastify.io.emit("notification:all-read", {
|
|
127
127
|
count: unreadNotifications.length,
|
|
128
|
-
ids: unreadNotifications.map(n => n.id)
|
|
128
|
+
ids: unreadNotifications.map((n) => n.id),
|
|
129
129
|
});
|
|
130
130
|
return {
|
|
131
131
|
success: true,
|
|
132
|
-
markedCount: unreadNotifications.length
|
|
132
|
+
markedCount: unreadNotifications.length,
|
|
133
133
|
};
|
|
134
134
|
}
|
|
135
135
|
catch (error) {
|
|
136
136
|
return reply.code(500).send({
|
|
137
|
-
error:
|
|
138
|
-
details: error instanceof Error ? error.message :
|
|
137
|
+
error: "Failed to mark all notifications as read",
|
|
138
|
+
details: error instanceof Error ? error.message : "Unknown error",
|
|
139
139
|
});
|
|
140
140
|
}
|
|
141
141
|
});
|
|
142
142
|
// Delete notification
|
|
143
|
-
fastify.delete(
|
|
143
|
+
fastify.delete("/:id", async (request, reply) => {
|
|
144
144
|
const { id } = request.params;
|
|
145
145
|
try {
|
|
146
146
|
const notification = fastify.db.getNotification(id);
|
|
147
147
|
if (!notification) {
|
|
148
|
-
return reply.code(404).send({ error:
|
|
148
|
+
return reply.code(404).send({ error: "Notification not found" });
|
|
149
149
|
}
|
|
150
150
|
fastify.db.deleteNotification(id);
|
|
151
151
|
// Emit notification deleted event
|
|
152
|
-
fastify.io.emit(
|
|
152
|
+
fastify.io.emit("notification:deleted", { id });
|
|
153
153
|
return { success: true };
|
|
154
154
|
}
|
|
155
155
|
catch (error) {
|
|
156
156
|
return reply.code(500).send({
|
|
157
|
-
error:
|
|
158
|
-
details: error instanceof Error ? error.message :
|
|
157
|
+
error: "Failed to delete notification",
|
|
158
|
+
details: error instanceof Error ? error.message : "Unknown error",
|
|
159
159
|
});
|
|
160
160
|
}
|
|
161
161
|
});
|
|
162
162
|
// Webhook endpoint for external notifications
|
|
163
|
-
fastify.post(
|
|
163
|
+
fastify.post("/webhook/:sessionId", async (request, reply) => {
|
|
164
164
|
const { sessionId } = request.params;
|
|
165
|
-
const { type =
|
|
165
|
+
const { type = "info", title, message, metadata, projectName, } = request.body;
|
|
166
166
|
try {
|
|
167
167
|
// Map task_completed to success for database compatibility
|
|
168
168
|
// Map unknown types to info as fallback
|
|
169
169
|
let mappedType;
|
|
170
170
|
switch (type) {
|
|
171
|
-
case
|
|
172
|
-
mappedType =
|
|
171
|
+
case "task_completed":
|
|
172
|
+
mappedType = "success";
|
|
173
173
|
break;
|
|
174
|
-
case
|
|
175
|
-
case
|
|
176
|
-
case
|
|
177
|
-
case
|
|
174
|
+
case "info":
|
|
175
|
+
case "success":
|
|
176
|
+
case "warning":
|
|
177
|
+
case "error":
|
|
178
178
|
mappedType = type;
|
|
179
179
|
break;
|
|
180
180
|
default:
|
|
181
|
-
mappedType =
|
|
181
|
+
mappedType = "info"; // Default fallback for unknown types
|
|
182
182
|
}
|
|
183
183
|
// Try to find session first, then fall back to project-based notification
|
|
184
184
|
const session = fastify.db.getTmuxSession(sessionId);
|
|
@@ -200,49 +200,54 @@ export const notificationRoutes = async (fastify) => {
|
|
|
200
200
|
projectId,
|
|
201
201
|
type: mappedType,
|
|
202
202
|
title,
|
|
203
|
-
message: metadata
|
|
204
|
-
|
|
203
|
+
message: metadata
|
|
204
|
+
? `${message}\n\nMetadata: ${JSON.stringify(metadata, null, 2)}`
|
|
205
|
+
: message,
|
|
206
|
+
status: "unread",
|
|
205
207
|
});
|
|
206
208
|
// Emit notification with webhook flag
|
|
207
|
-
fastify.io.emit(
|
|
209
|
+
fastify.io.emit("notification:webhook", {
|
|
208
210
|
...notification,
|
|
209
211
|
metadata,
|
|
210
|
-
originalType: type // Include original type for frontend handling
|
|
212
|
+
originalType: type, // Include original type for frontend handling
|
|
211
213
|
});
|
|
212
214
|
// Check if sound is enabled
|
|
213
|
-
const soundEnabled = fastify.db.getConfig(
|
|
215
|
+
const soundEnabled = fastify.db.getConfig("notification_sound") === "true";
|
|
214
216
|
if (soundEnabled) {
|
|
215
|
-
fastify.io.emit(
|
|
217
|
+
fastify.io.emit("notification:sound", {
|
|
218
|
+
type: mappedType,
|
|
219
|
+
webhook: true,
|
|
220
|
+
});
|
|
216
221
|
}
|
|
217
222
|
return {
|
|
218
223
|
notification,
|
|
219
224
|
webhook: true,
|
|
220
225
|
originalType: type,
|
|
221
|
-
mappedType
|
|
226
|
+
mappedType,
|
|
222
227
|
};
|
|
223
228
|
}
|
|
224
229
|
catch (error) {
|
|
225
230
|
return reply.code(500).send({
|
|
226
|
-
error:
|
|
227
|
-
details: error instanceof Error ? error.message :
|
|
231
|
+
error: "Failed to create webhook notification",
|
|
232
|
+
details: error instanceof Error ? error.message : "Unknown error",
|
|
228
233
|
});
|
|
229
234
|
}
|
|
230
235
|
});
|
|
231
236
|
// Clear old notifications
|
|
232
|
-
fastify.delete(
|
|
237
|
+
fastify.delete("/clear/old", async (request, reply) => {
|
|
233
238
|
const { days = 30 } = request.query;
|
|
234
239
|
try {
|
|
235
240
|
// This would need a new database method to delete old notifications
|
|
236
241
|
// For now, we'll just return a placeholder
|
|
237
242
|
return {
|
|
238
243
|
success: true,
|
|
239
|
-
message: `Would clear notifications older than ${days} days
|
|
244
|
+
message: `Would clear notifications older than ${days} days`,
|
|
240
245
|
};
|
|
241
246
|
}
|
|
242
247
|
catch (error) {
|
|
243
248
|
return reply.code(500).send({
|
|
244
|
-
error:
|
|
245
|
-
details: error instanceof Error ? error.message :
|
|
249
|
+
error: "Failed to clear old notifications",
|
|
250
|
+
details: error instanceof Error ? error.message : "Unknown error",
|
|
246
251
|
});
|
|
247
252
|
}
|
|
248
253
|
});
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"notifications.js","sourceRoot":"","sources":["../../src/routes/notifications.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,EAAE,IAAI,MAAM,EAAE,MAAM,MAAM,CAAC;AAkBpC,MAAM,CAAC,MAAM,kBAAkB,GAAuB,KAAK,EAAE,OAAO,EAAE,EAAE;IACtE,wBAAwB;IACxB,OAAO,CAAC,GAAG,CAAC,GAAG,EAAE,KAAK,EAAE,OAAO,EAAE,MAAM,EAAE,EAAE;QACzC,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,
|
|
1
|
+
{"version":3,"file":"notifications.js","sourceRoot":"","sources":["../../src/routes/notifications.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"port-forward.d.ts","sourceRoot":"","sources":["../../src/routes/port-forward.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,kBAAkB,EAAE,MAAM,SAAS,CAAC;AAgB7C,eAAO,MAAM,iBAAiB,EAAE,
|
|
1
|
+
{"version":3,"file":"port-forward.d.ts","sourceRoot":"","sources":["../../src/routes/port-forward.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,kBAAkB,EAAE,MAAM,SAAS,CAAC;AAgB7C,eAAO,MAAM,iBAAiB,EAAE,kBAgQ/B,CAAC"}
|
|
@@ -1,29 +1,30 @@
|
|
|
1
|
-
import { v4 as uuidv4 } from
|
|
2
|
-
import { Client } from
|
|
3
|
-
import { createServer } from
|
|
4
|
-
import { readFileSync } from
|
|
1
|
+
import { v4 as uuidv4 } from "uuid";
|
|
2
|
+
import { Client } from "ssh2";
|
|
3
|
+
import { createServer } from "net";
|
|
4
|
+
import { readFileSync } from "fs";
|
|
5
5
|
// Store active connections and servers
|
|
6
6
|
const activeConnections = new Map();
|
|
7
7
|
export const portForwardRoutes = async (fastify) => {
|
|
8
8
|
// Get all port forwards
|
|
9
|
-
fastify.get(
|
|
9
|
+
fastify.get("/", async (_request, _reply) => {
|
|
10
10
|
const portForwards = fastify.db.getAllPortForwards();
|
|
11
11
|
return { portForwards };
|
|
12
12
|
});
|
|
13
13
|
// Create new port forward
|
|
14
|
-
fastify.post(
|
|
14
|
+
fastify.post("/", async (request, reply) => {
|
|
15
15
|
const { localPort, remoteHost, remotePort, connectionId } = request.body;
|
|
16
16
|
try {
|
|
17
17
|
// Check if port is already in use
|
|
18
|
-
const existing = fastify.db
|
|
19
|
-
.
|
|
18
|
+
const existing = fastify.db
|
|
19
|
+
.getAllPortForwards()
|
|
20
|
+
.find((pf) => pf.localPort === localPort && pf.status === "active");
|
|
20
21
|
if (existing) {
|
|
21
|
-
return reply.code(409).send({ error:
|
|
22
|
+
return reply.code(409).send({ error: "Local port is already in use" });
|
|
22
23
|
}
|
|
23
24
|
// Get SSH connection config
|
|
24
25
|
const connectionConfig = fastify.db.getSSHConnection(connectionId);
|
|
25
26
|
if (!connectionConfig) {
|
|
26
|
-
return reply.code(404).send({ error:
|
|
27
|
+
return reply.code(404).send({ error: "SSH connection not found" });
|
|
27
28
|
}
|
|
28
29
|
const portForward = fastify.db.createPortForward({
|
|
29
30
|
id: uuidv4(),
|
|
@@ -32,82 +33,87 @@ export const portForwardRoutes = async (fastify) => {
|
|
|
32
33
|
remotePort,
|
|
33
34
|
serverName: connectionConfig.serverName, // Keep for backward compatibility
|
|
34
35
|
connectionId,
|
|
35
|
-
status:
|
|
36
|
+
status: "inactive",
|
|
36
37
|
});
|
|
37
38
|
return { portForward };
|
|
38
39
|
}
|
|
39
40
|
catch (error) {
|
|
40
41
|
return reply.code(500).send({
|
|
41
|
-
error:
|
|
42
|
-
details: error instanceof Error ? error.message :
|
|
42
|
+
error: "Failed to create port forward",
|
|
43
|
+
details: error instanceof Error ? error.message : "Unknown error",
|
|
43
44
|
});
|
|
44
45
|
}
|
|
45
46
|
});
|
|
46
47
|
// Start port forwarding
|
|
47
|
-
fastify.post(
|
|
48
|
+
fastify.post("/:id/start", async (request, reply) => {
|
|
48
49
|
const { id } = request.params;
|
|
49
50
|
try {
|
|
50
51
|
const portForward = fastify.db.getPortForward(id);
|
|
51
52
|
if (!portForward) {
|
|
52
|
-
return reply.code(404).send({ error:
|
|
53
|
+
return reply.code(404).send({ error: "Port forward not found" });
|
|
53
54
|
}
|
|
54
|
-
if (portForward.status ===
|
|
55
|
-
return reply
|
|
55
|
+
if (portForward.status === "active") {
|
|
56
|
+
return reply
|
|
57
|
+
.code(400)
|
|
58
|
+
.send({ error: "Port forward is already active" });
|
|
56
59
|
}
|
|
57
60
|
// Get SSH connection config
|
|
58
61
|
const connectionConfig = portForward.connectionId
|
|
59
62
|
? fastify.db.getSSHConnection(portForward.connectionId)
|
|
60
63
|
: fastify.db.getSSHConnectionByName(portForward.serverName);
|
|
61
64
|
if (!connectionConfig) {
|
|
62
|
-
return reply.code(404).send({ error:
|
|
65
|
+
return reply.code(404).send({ error: "SSH connection not found" });
|
|
63
66
|
}
|
|
64
67
|
const sshClient = new Client();
|
|
65
68
|
// Create local server
|
|
66
69
|
const server = createServer((localSocket) => {
|
|
67
|
-
sshClient.forwardOut(
|
|
70
|
+
sshClient.forwardOut("localhost", portForward.localPort, portForward.remoteHost, portForward.remotePort, (err, stream) => {
|
|
68
71
|
if (err) {
|
|
69
72
|
localSocket.end();
|
|
70
|
-
console.error(
|
|
73
|
+
console.error("Forward error:", err);
|
|
71
74
|
return;
|
|
72
75
|
}
|
|
73
76
|
localSocket.pipe(stream).pipe(localSocket);
|
|
74
|
-
localSocket.on(
|
|
77
|
+
localSocket.on("close", () => {
|
|
75
78
|
stream.end();
|
|
76
79
|
});
|
|
77
|
-
stream.on(
|
|
80
|
+
stream.on("close", () => {
|
|
78
81
|
localSocket.end();
|
|
79
82
|
});
|
|
80
83
|
});
|
|
81
84
|
});
|
|
82
85
|
return new Promise((resolve) => {
|
|
83
|
-
sshClient.on(
|
|
86
|
+
sshClient.on("ready", () => {
|
|
84
87
|
server.listen(portForward.localPort, () => {
|
|
85
88
|
// Store active connection
|
|
86
89
|
activeConnections.set(id, { client: sshClient, server });
|
|
87
90
|
// Update database
|
|
88
91
|
fastify.db.updatePortForward(id, {
|
|
89
|
-
status:
|
|
90
|
-
connectionId: id
|
|
92
|
+
status: "active",
|
|
93
|
+
connectionId: id,
|
|
91
94
|
});
|
|
92
95
|
// Emit event
|
|
93
|
-
fastify.io.emit(
|
|
96
|
+
fastify.io.emit("portforward:started", {
|
|
97
|
+
id,
|
|
98
|
+
localPort: portForward.localPort,
|
|
99
|
+
});
|
|
94
100
|
resolve({
|
|
95
101
|
success: true,
|
|
96
|
-
message: `Port forwarding started on localhost:${portForward.localPort}
|
|
102
|
+
message: `Port forwarding started on localhost:${portForward.localPort}`,
|
|
97
103
|
});
|
|
98
104
|
});
|
|
99
|
-
server.on(
|
|
105
|
+
server.on("error", (err) => {
|
|
100
106
|
sshClient.end();
|
|
101
107
|
resolve(reply.code(500).send({
|
|
102
|
-
error:
|
|
103
|
-
details: err.message
|
|
108
|
+
error: "Failed to start local server",
|
|
109
|
+
details: err.message,
|
|
104
110
|
}));
|
|
105
111
|
});
|
|
106
112
|
});
|
|
107
|
-
sshClient.on(
|
|
113
|
+
sshClient.on("error", (err) => {
|
|
108
114
|
resolve(reply.code(500).send({
|
|
109
|
-
error:
|
|
110
|
-
details: err.message
|
|
115
|
+
error: "SSH connection failed",
|
|
116
|
+
details: err.message,
|
|
111
117
|
}));
|
|
112
118
|
});
|
|
113
119
|
// Connect with appropriate auth method
|
|
@@ -127,21 +133,21 @@ export const portForwardRoutes = async (fastify) => {
|
|
|
127
133
|
}
|
|
128
134
|
catch (error) {
|
|
129
135
|
return reply.code(500).send({
|
|
130
|
-
error:
|
|
131
|
-
details: error instanceof Error ? error.message :
|
|
136
|
+
error: "Failed to start port forward",
|
|
137
|
+
details: error instanceof Error ? error.message : "Unknown error",
|
|
132
138
|
});
|
|
133
139
|
}
|
|
134
140
|
});
|
|
135
141
|
// Stop port forwarding
|
|
136
|
-
fastify.post(
|
|
142
|
+
fastify.post("/:id/stop", async (request, reply) => {
|
|
137
143
|
const { id } = request.params;
|
|
138
144
|
try {
|
|
139
145
|
const portForward = fastify.db.getPortForward(id);
|
|
140
146
|
if (!portForward) {
|
|
141
|
-
return reply.code(404).send({ error:
|
|
147
|
+
return reply.code(404).send({ error: "Port forward not found" });
|
|
142
148
|
}
|
|
143
|
-
if (portForward.status !==
|
|
144
|
-
return reply.code(400).send({ error:
|
|
149
|
+
if (portForward.status !== "active") {
|
|
150
|
+
return reply.code(400).send({ error: "Port forward is not active" });
|
|
145
151
|
}
|
|
146
152
|
// Get active connection
|
|
147
153
|
const active = activeConnections.get(id);
|
|
@@ -152,30 +158,33 @@ export const portForwardRoutes = async (fastify) => {
|
|
|
152
158
|
}
|
|
153
159
|
// Update database
|
|
154
160
|
fastify.db.updatePortForward(id, {
|
|
155
|
-
status:
|
|
156
|
-
connectionId: undefined
|
|
161
|
+
status: "inactive",
|
|
162
|
+
connectionId: undefined,
|
|
157
163
|
});
|
|
158
164
|
// Emit event
|
|
159
|
-
fastify.io.emit(
|
|
165
|
+
fastify.io.emit("portforward:stopped", {
|
|
166
|
+
id,
|
|
167
|
+
localPort: portForward.localPort,
|
|
168
|
+
});
|
|
160
169
|
return { success: true };
|
|
161
170
|
}
|
|
162
171
|
catch (error) {
|
|
163
172
|
return reply.code(500).send({
|
|
164
|
-
error:
|
|
165
|
-
details: error instanceof Error ? error.message :
|
|
173
|
+
error: "Failed to stop port forward",
|
|
174
|
+
details: error instanceof Error ? error.message : "Unknown error",
|
|
166
175
|
});
|
|
167
176
|
}
|
|
168
177
|
});
|
|
169
178
|
// Delete port forward
|
|
170
|
-
fastify.delete(
|
|
179
|
+
fastify.delete("/:id", async (request, reply) => {
|
|
171
180
|
const { id } = request.params;
|
|
172
181
|
try {
|
|
173
182
|
const portForward = fastify.db.getPortForward(id);
|
|
174
183
|
if (!portForward) {
|
|
175
|
-
return reply.code(404).send({ error:
|
|
184
|
+
return reply.code(404).send({ error: "Port forward not found" });
|
|
176
185
|
}
|
|
177
186
|
// Stop if active
|
|
178
|
-
if (portForward.status ===
|
|
187
|
+
if (portForward.status === "active") {
|
|
179
188
|
const active = activeConnections.get(id);
|
|
180
189
|
if (active) {
|
|
181
190
|
active.server.close();
|
|
@@ -188,13 +197,13 @@ export const portForwardRoutes = async (fastify) => {
|
|
|
188
197
|
}
|
|
189
198
|
catch (error) {
|
|
190
199
|
return reply.code(500).send({
|
|
191
|
-
error:
|
|
192
|
-
details: error instanceof Error ? error.message :
|
|
200
|
+
error: "Failed to delete port forward",
|
|
201
|
+
details: error instanceof Error ? error.message : "Unknown error",
|
|
193
202
|
});
|
|
194
203
|
}
|
|
195
204
|
});
|
|
196
205
|
// Cleanup on server close
|
|
197
|
-
fastify.addHook(
|
|
206
|
+
fastify.addHook("onClose", async () => {
|
|
198
207
|
for (const [, { client, server }] of activeConnections) {
|
|
199
208
|
server.close();
|
|
200
209
|
client.end();
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"port-forward.js","sourceRoot":"","sources":["../../src/routes/port-forward.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,EAAE,IAAI,MAAM,EAAE,MAAM,MAAM,CAAC;AACpC,OAAO,EAAE,MAAM,EAAE,MAAM,MAAM,CAAC;AAC9B,OAAO,EAAE,YAAY,EAAU,MAAM,KAAK,CAAC;AAC3C,OAAO,EAAE,YAAY,EAAE,MAAM,IAAI,CAAC;AASlC,uCAAuC;AACvC,MAAM,iBAAiB,GAAG,IAAI,GAAG,EAA8C,CAAC;AAEhF,MAAM,CAAC,MAAM,iBAAiB,GAAuB,KAAK,EAAE,OAAO,EAAE,EAAE;IACrE,wBAAwB;IACxB,OAAO,CAAC,GAAG,CAAC,GAAG,EAAE,KAAK,EAAE,QAAQ,EAAE,MAAM,EAAE,EAAE;QAC1C,MAAM,YAAY,GAAG,OAAO,CAAC,EAAE,CAAC,kBAAkB,EAAE,CAAC;QACrD,OAAO,EAAE,YAAY,EAAE,CAAC;IAC1B,CAAC,CAAC,CAAC;IAEH,0BAA0B;IAC1B,OAAO,CAAC,IAAI,CAAC,GAAG,EAAE,KAAK,EAAE,OAAO,EAAE,KAAK,EAAE,EAAE;QACzC,MAAM,EAAE,SAAS,EAAE,UAAU,EAAE,UAAU,EAAE,YAAY,EAAE,
|
|
1
|
+
{"version":3,"file":"port-forward.js","sourceRoot":"","sources":["../../src/routes/port-forward.ts"],"names":[],"mappings":"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"}
|