telegram-ssh-bot 2.0.0 → 2.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.
- package/LICENSE +21 -0
- package/README.md +103 -22
- package/deploy/.env.example +86 -0
- package/dist/config/index.d.ts +68 -0
- package/dist/config/index.d.ts.map +1 -0
- package/dist/config/index.js +315 -0
- package/dist/config/index.js.map +1 -0
- package/dist/config/schema.d.ts +6 -0
- package/dist/config/schema.d.ts.map +1 -0
- package/dist/config/schema.js +50 -0
- package/dist/config/schema.js.map +1 -0
- package/dist/core/Bot.d.ts +91 -0
- package/dist/core/Bot.d.ts.map +1 -0
- package/dist/core/Bot.js +263 -0
- package/dist/core/Bot.js.map +1 -0
- package/dist/core/ConnectionPool.d.ts +125 -0
- package/dist/core/ConnectionPool.d.ts.map +1 -0
- package/dist/core/ConnectionPool.js +397 -0
- package/dist/core/ConnectionPool.js.map +1 -0
- package/dist/core/SSHClient.d.ts +112 -0
- package/dist/core/SSHClient.d.ts.map +1 -0
- package/dist/core/SSHClient.js +367 -0
- package/dist/core/SSHClient.js.map +1 -0
- package/dist/core/ServerManager.d.ts +80 -0
- package/dist/core/ServerManager.d.ts.map +1 -0
- package/dist/core/ServerManager.js +207 -0
- package/dist/core/ServerManager.js.map +1 -0
- package/dist/core/index.d.ts +8 -0
- package/dist/core/index.d.ts.map +1 -0
- package/dist/core/index.js +8 -0
- package/dist/core/index.js.map +1 -0
- package/dist/errors/AuthError.d.ts +30 -0
- package/dist/errors/AuthError.d.ts.map +1 -0
- package/dist/errors/AuthError.js +35 -0
- package/dist/errors/AuthError.js.map +1 -0
- package/dist/errors/BaseError.d.ts +17 -0
- package/dist/errors/BaseError.d.ts.map +1 -0
- package/dist/errors/BaseError.js +34 -0
- package/dist/errors/BaseError.js.map +1 -0
- package/dist/errors/ConfigurationError.d.ts +24 -0
- package/dist/errors/ConfigurationError.d.ts.map +1 -0
- package/dist/errors/ConfigurationError.js +24 -0
- package/dist/errors/ConfigurationError.js.map +1 -0
- package/dist/errors/PoolError.d.ts +21 -0
- package/dist/errors/PoolError.d.ts.map +1 -0
- package/dist/errors/PoolError.js +30 -0
- package/dist/errors/PoolError.js.map +1 -0
- package/dist/errors/SSHError.d.ts +24 -0
- package/dist/errors/SSHError.d.ts.map +1 -0
- package/dist/errors/SSHError.js +38 -0
- package/dist/errors/SSHError.js.map +1 -0
- package/dist/errors/StorageError.d.ts +24 -0
- package/dist/errors/StorageError.d.ts.map +1 -0
- package/dist/errors/StorageError.js +35 -0
- package/dist/errors/StorageError.js.map +1 -0
- package/dist/errors/ValidationError.d.ts +29 -0
- package/dist/errors/ValidationError.d.ts.map +1 -0
- package/dist/errors/ValidationError.js +35 -0
- package/dist/errors/ValidationError.js.map +1 -0
- package/dist/errors/index.d.ts +11 -0
- package/dist/errors/index.d.ts.map +1 -0
- package/dist/errors/index.js +18 -0
- package/dist/errors/index.js.map +1 -0
- package/dist/handlers/BaseHandler.d.ts +50 -0
- package/dist/handlers/BaseHandler.d.ts.map +1 -0
- package/dist/handlers/BaseHandler.js +87 -0
- package/dist/handlers/BaseHandler.js.map +1 -0
- package/dist/handlers/CommandHandler.d.ts +23 -0
- package/dist/handlers/CommandHandler.d.ts.map +1 -0
- package/dist/handlers/CommandHandler.js +99 -0
- package/dist/handlers/CommandHandler.js.map +1 -0
- package/dist/handlers/HealthHandler.d.ts +25 -0
- package/dist/handlers/HealthHandler.d.ts.map +1 -0
- package/dist/handlers/HealthHandler.js +51 -0
- package/dist/handlers/HealthHandler.js.map +1 -0
- package/dist/handlers/HelpHandler.d.ts +32 -0
- package/dist/handlers/HelpHandler.d.ts.map +1 -0
- package/dist/handlers/HelpHandler.js +76 -0
- package/dist/handlers/HelpHandler.js.map +1 -0
- package/dist/handlers/ServerHandler.d.ts +72 -0
- package/dist/handlers/ServerHandler.d.ts.map +1 -0
- package/dist/handlers/ServerHandler.js +272 -0
- package/dist/handlers/ServerHandler.js.map +1 -0
- package/dist/handlers/index.d.ts +9 -0
- package/dist/handlers/index.d.ts.map +1 -0
- package/dist/handlers/index.js +9 -0
- package/dist/handlers/index.js.map +1 -0
- package/dist/index.d.ts +10 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +348 -0
- package/dist/index.js.map +1 -0
- package/dist/middleware/AuthMiddleware.d.ts +28 -0
- package/dist/middleware/AuthMiddleware.d.ts.map +1 -0
- package/dist/middleware/AuthMiddleware.js +49 -0
- package/dist/middleware/AuthMiddleware.js.map +1 -0
- package/dist/middleware/RateLimitMiddleware.d.ts +23 -0
- package/dist/middleware/RateLimitMiddleware.d.ts.map +1 -0
- package/dist/middleware/RateLimitMiddleware.js +34 -0
- package/dist/middleware/RateLimitMiddleware.js.map +1 -0
- package/dist/middleware/index.d.ts +6 -0
- package/dist/middleware/index.d.ts.map +1 -0
- package/dist/middleware/index.js +6 -0
- package/dist/middleware/index.js.map +1 -0
- package/dist/services/BackupService.d.ts +119 -0
- package/dist/services/BackupService.d.ts.map +1 -0
- package/dist/services/BackupService.js +313 -0
- package/dist/services/BackupService.js.map +1 -0
- package/dist/services/CryptoService.d.ts +37 -0
- package/dist/services/CryptoService.d.ts.map +1 -0
- package/dist/services/CryptoService.js +108 -0
- package/dist/services/CryptoService.js.map +1 -0
- package/dist/services/HealthService.d.ts +126 -0
- package/dist/services/HealthService.d.ts.map +1 -0
- package/dist/services/HealthService.js +213 -0
- package/dist/services/HealthService.js.map +1 -0
- package/dist/services/LoggingService.d.ts +115 -0
- package/dist/services/LoggingService.d.ts.map +1 -0
- package/dist/services/LoggingService.js +334 -0
- package/dist/services/LoggingService.js.map +1 -0
- package/dist/services/MonitoringService.d.ts +119 -0
- package/dist/services/MonitoringService.d.ts.map +1 -0
- package/dist/services/MonitoringService.js +267 -0
- package/dist/services/MonitoringService.js.map +1 -0
- package/dist/services/NotificationService.d.ts +132 -0
- package/dist/services/NotificationService.d.ts.map +1 -0
- package/dist/services/NotificationService.js +297 -0
- package/dist/services/NotificationService.js.map +1 -0
- package/dist/services/RateLimiter.d.ts +51 -0
- package/dist/services/RateLimiter.d.ts.map +1 -0
- package/dist/services/RateLimiter.js +141 -0
- package/dist/services/RateLimiter.js.map +1 -0
- package/dist/services/ValidationService.d.ts +49 -0
- package/dist/services/ValidationService.d.ts.map +1 -0
- package/dist/services/ValidationService.js +158 -0
- package/dist/services/ValidationService.js.map +1 -0
- package/dist/services/index.d.ts +12 -0
- package/dist/services/index.d.ts.map +1 -0
- package/dist/services/index.js +12 -0
- package/dist/services/index.js.map +1 -0
- package/dist/types/Bot.d.ts +63 -0
- package/dist/types/Bot.d.ts.map +1 -0
- package/dist/types/Bot.js +5 -0
- package/dist/types/Bot.js.map +1 -0
- package/dist/types/Config.d.ts +57 -0
- package/dist/types/Config.d.ts.map +1 -0
- package/dist/types/Config.js +5 -0
- package/dist/types/Config.js.map +1 -0
- package/dist/types/Errors.d.ts +37 -0
- package/dist/types/Errors.d.ts.map +1 -0
- package/dist/types/Errors.js +34 -0
- package/dist/types/Errors.js.map +1 -0
- package/dist/types/SSH.d.ts +56 -0
- package/dist/types/SSH.d.ts.map +1 -0
- package/dist/types/SSH.js +6 -0
- package/dist/types/SSH.js.map +1 -0
- package/dist/types/Server.d.ts +39 -0
- package/dist/types/Server.d.ts.map +1 -0
- package/dist/types/Server.js +5 -0
- package/dist/types/Server.js.map +1 -0
- package/dist/types/index.d.ts +10 -0
- package/dist/types/index.d.ts.map +1 -0
- package/dist/types/index.js +6 -0
- package/dist/types/index.js.map +1 -0
- package/dist/utils/commandUtils.d.ts +25 -0
- package/dist/utils/commandUtils.d.ts.map +1 -0
- package/dist/utils/commandUtils.js +94 -0
- package/dist/utils/commandUtils.js.map +1 -0
- package/dist/utils/fileUtils.d.ts +40 -0
- package/dist/utils/fileUtils.d.ts.map +1 -0
- package/dist/utils/fileUtils.js +114 -0
- package/dist/utils/fileUtils.js.map +1 -0
- package/dist/utils/index.d.ts +7 -0
- package/dist/utils/index.d.ts.map +1 -0
- package/dist/utils/index.js +7 -0
- package/dist/utils/index.js.map +1 -0
- package/dist/utils/pathUtils.d.ts +40 -0
- package/dist/utils/pathUtils.d.ts.map +1 -0
- package/dist/utils/pathUtils.js +140 -0
- package/dist/utils/pathUtils.js.map +1 -0
- package/package.json +31 -5
- package/scripts/build.sh +20 -0
- package/scripts/postinstall.js +87 -0
- package/scripts/release.sh +22 -0
- package/scripts/setup-env.js +237 -0
|
@@ -0,0 +1,367 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* SSH Client
|
|
3
|
+
* Provides SSH connection management and command execution with timeout and cancellation support
|
|
4
|
+
*/
|
|
5
|
+
import { Client } from "ssh2";
|
|
6
|
+
import { CommandFailedError, ConnectionFailedError, ConnectionTimeoutError, DisconnectedError, } from "../errors/index.js";
|
|
7
|
+
/**
|
|
8
|
+
* Cancellation token for aborting operations
|
|
9
|
+
*/
|
|
10
|
+
export class CancellationToken {
|
|
11
|
+
cancelled = false;
|
|
12
|
+
listeners = [];
|
|
13
|
+
/**
|
|
14
|
+
* Check if cancellation has been requested
|
|
15
|
+
*/
|
|
16
|
+
get isCancelled() {
|
|
17
|
+
return this.cancelled;
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* Request cancellation
|
|
21
|
+
*/
|
|
22
|
+
cancel() {
|
|
23
|
+
if (this.cancelled) {
|
|
24
|
+
return;
|
|
25
|
+
}
|
|
26
|
+
this.cancelled = true;
|
|
27
|
+
for (const listener of this.listeners) {
|
|
28
|
+
try {
|
|
29
|
+
listener();
|
|
30
|
+
}
|
|
31
|
+
catch {
|
|
32
|
+
// Ignore listener errors
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
this.listeners.length = 0;
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* Register a callback for cancellation
|
|
39
|
+
*/
|
|
40
|
+
onCancel(callback) {
|
|
41
|
+
if (this.cancelled) {
|
|
42
|
+
callback();
|
|
43
|
+
}
|
|
44
|
+
else {
|
|
45
|
+
this.listeners.push(callback);
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
/**
|
|
49
|
+
* Throw if cancelled
|
|
50
|
+
*/
|
|
51
|
+
throwIfCancelled() {
|
|
52
|
+
if (this.cancelled) {
|
|
53
|
+
throw new Error("Operation cancelled");
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
/**
|
|
58
|
+
* Cancellation token source for creating tokens
|
|
59
|
+
*/
|
|
60
|
+
export class CancellationTokenSource {
|
|
61
|
+
token;
|
|
62
|
+
constructor() {
|
|
63
|
+
this.token = new CancellationToken();
|
|
64
|
+
}
|
|
65
|
+
/**
|
|
66
|
+
* Cancel the operation
|
|
67
|
+
*/
|
|
68
|
+
cancel() {
|
|
69
|
+
this.token.cancel();
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
/**
|
|
73
|
+
* SSH Client implementation with enhanced timeout and cancellation support
|
|
74
|
+
*/
|
|
75
|
+
export class SSHClient {
|
|
76
|
+
client = null;
|
|
77
|
+
serverId;
|
|
78
|
+
state = { status: "disconnected" };
|
|
79
|
+
connectionTimeout;
|
|
80
|
+
commandTimeout;
|
|
81
|
+
activeExecutions = new Map();
|
|
82
|
+
constructor(options) {
|
|
83
|
+
this.connectionTimeout = options?.connectionTimeout ?? 30000;
|
|
84
|
+
this.commandTimeout = options?.commandTimeout ?? 60000;
|
|
85
|
+
}
|
|
86
|
+
/**
|
|
87
|
+
* Connect to SSH server
|
|
88
|
+
*/
|
|
89
|
+
async connect(config) {
|
|
90
|
+
// Disconnect existing connection
|
|
91
|
+
if (this.isConnected()) {
|
|
92
|
+
await this.disconnect();
|
|
93
|
+
}
|
|
94
|
+
this.state = { status: "connecting" };
|
|
95
|
+
return new Promise((resolve, reject) => {
|
|
96
|
+
const client = new Client();
|
|
97
|
+
const timeoutId = setTimeout(() => {
|
|
98
|
+
client.removeAllListeners();
|
|
99
|
+
client.destroy();
|
|
100
|
+
this.state = {
|
|
101
|
+
status: "error",
|
|
102
|
+
lastError: new Error("Connection timeout"),
|
|
103
|
+
};
|
|
104
|
+
reject(new ConnectionTimeoutError(config.host, this.connectionTimeout));
|
|
105
|
+
}, this.connectionTimeout);
|
|
106
|
+
client.on("ready", () => {
|
|
107
|
+
clearTimeout(timeoutId);
|
|
108
|
+
this.client = client;
|
|
109
|
+
this.state = {
|
|
110
|
+
status: "connected",
|
|
111
|
+
connectedAt: new Date(),
|
|
112
|
+
};
|
|
113
|
+
resolve();
|
|
114
|
+
});
|
|
115
|
+
client.on("error", (err) => {
|
|
116
|
+
clearTimeout(timeoutId);
|
|
117
|
+
this.state = { status: "error", lastError: err };
|
|
118
|
+
reject(new ConnectionFailedError(config.host, err));
|
|
119
|
+
});
|
|
120
|
+
client.on("close", () => {
|
|
121
|
+
this.client = null;
|
|
122
|
+
this.state = { status: "disconnected" };
|
|
123
|
+
// Cancel all active executions
|
|
124
|
+
this.cancelAllExecutions();
|
|
125
|
+
});
|
|
126
|
+
// Build connection options
|
|
127
|
+
const connectOptions = {
|
|
128
|
+
host: config.host,
|
|
129
|
+
port: config.port,
|
|
130
|
+
username: config.username,
|
|
131
|
+
readyTimeout: this.connectionTimeout,
|
|
132
|
+
keepaliveInterval: config.keepaliveInterval ?? 10000,
|
|
133
|
+
};
|
|
134
|
+
if (config.password) {
|
|
135
|
+
connectOptions.password = config.password;
|
|
136
|
+
}
|
|
137
|
+
if (config.privateKey) {
|
|
138
|
+
connectOptions.privateKey = config.privateKey;
|
|
139
|
+
if (config.passphrase) {
|
|
140
|
+
connectOptions.passphrase = config.passphrase;
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
try {
|
|
144
|
+
client.connect(connectOptions);
|
|
145
|
+
}
|
|
146
|
+
catch (err) {
|
|
147
|
+
clearTimeout(timeoutId);
|
|
148
|
+
reject(new ConnectionFailedError(config.host, err instanceof Error ? err : new Error(String(err))));
|
|
149
|
+
}
|
|
150
|
+
});
|
|
151
|
+
}
|
|
152
|
+
/**
|
|
153
|
+
* Disconnect from SSH server
|
|
154
|
+
*/
|
|
155
|
+
async disconnect() {
|
|
156
|
+
// Cancel all active executions first
|
|
157
|
+
this.cancelAllExecutions();
|
|
158
|
+
if (this.client) {
|
|
159
|
+
return new Promise((resolve) => {
|
|
160
|
+
if (this.client) {
|
|
161
|
+
this.client.removeAllListeners();
|
|
162
|
+
this.client.on("close", () => {
|
|
163
|
+
this.client = null;
|
|
164
|
+
this.state = { status: "disconnected" };
|
|
165
|
+
resolve();
|
|
166
|
+
});
|
|
167
|
+
this.client.end();
|
|
168
|
+
}
|
|
169
|
+
else {
|
|
170
|
+
resolve();
|
|
171
|
+
}
|
|
172
|
+
});
|
|
173
|
+
}
|
|
174
|
+
this.state = { status: "disconnected" };
|
|
175
|
+
}
|
|
176
|
+
/**
|
|
177
|
+
* Check if connected to SSH server
|
|
178
|
+
*/
|
|
179
|
+
isConnected() {
|
|
180
|
+
return this.state.status === "connected" && this.client !== null;
|
|
181
|
+
}
|
|
182
|
+
/**
|
|
183
|
+
* Execute a command on the SSH server
|
|
184
|
+
*/
|
|
185
|
+
async execute(command, options) {
|
|
186
|
+
if (!this.isConnected() || !this.client) {
|
|
187
|
+
throw new DisconnectedError("Not connected to SSH server");
|
|
188
|
+
}
|
|
189
|
+
const timeout = options?.timeout ?? this.commandTimeout;
|
|
190
|
+
const cancellationToken = options?.cancellationToken;
|
|
191
|
+
const maxBufferSize = options?.maxBufferSize ?? 10 * 1024 * 1024; // 10MB default
|
|
192
|
+
const chunkCallback = options?.chunkCallback;
|
|
193
|
+
// Check if already cancelled
|
|
194
|
+
if (cancellationToken?.isCancelled) {
|
|
195
|
+
throw new CommandFailedError(command, -1, "Command cancelled before execution");
|
|
196
|
+
}
|
|
197
|
+
const startTime = Date.now();
|
|
198
|
+
const executionId = `exec_${Date.now()}_${Math.random().toString(36).substring(2, 8)}`;
|
|
199
|
+
return new Promise((resolve, reject) => {
|
|
200
|
+
let stdout = "";
|
|
201
|
+
let stderr = "";
|
|
202
|
+
let exitCode = null;
|
|
203
|
+
let signal = null;
|
|
204
|
+
let cancelled = false;
|
|
205
|
+
const timeoutId = setTimeout(() => {
|
|
206
|
+
cleanup();
|
|
207
|
+
reject(new CommandFailedError(command, -1, `Command timeout after ${timeout}ms`));
|
|
208
|
+
}, timeout);
|
|
209
|
+
const cleanup = () => {
|
|
210
|
+
clearTimeout(timeoutId);
|
|
211
|
+
this.activeExecutions.delete(executionId);
|
|
212
|
+
};
|
|
213
|
+
// Handle cancellation
|
|
214
|
+
const cancelHandler = () => {
|
|
215
|
+
cancelled = true;
|
|
216
|
+
cleanup();
|
|
217
|
+
// Close the stream
|
|
218
|
+
const exec = this.activeExecutions.get(executionId);
|
|
219
|
+
if (exec?.stream) {
|
|
220
|
+
try {
|
|
221
|
+
exec.stream.close();
|
|
222
|
+
}
|
|
223
|
+
catch {
|
|
224
|
+
// Ignore close errors
|
|
225
|
+
}
|
|
226
|
+
}
|
|
227
|
+
reject(new CommandFailedError(command, -1, "Command cancelled by user"));
|
|
228
|
+
};
|
|
229
|
+
if (cancellationToken) {
|
|
230
|
+
cancellationToken.onCancel(cancelHandler);
|
|
231
|
+
}
|
|
232
|
+
// Check if cancelled before exec
|
|
233
|
+
if (cancellationToken?.isCancelled) {
|
|
234
|
+
cleanup();
|
|
235
|
+
reject(new CommandFailedError(command, -1, "Command cancelled before execution"));
|
|
236
|
+
return;
|
|
237
|
+
}
|
|
238
|
+
this.client.exec(command, (err, stream) => {
|
|
239
|
+
if (err) {
|
|
240
|
+
cleanup();
|
|
241
|
+
reject(new CommandFailedError(command, 1, err.message));
|
|
242
|
+
return;
|
|
243
|
+
}
|
|
244
|
+
// Store the stream for potential cancellation
|
|
245
|
+
this.activeExecutions.set(executionId, { stream, timeoutId });
|
|
246
|
+
stream.on("close", (code, sig) => {
|
|
247
|
+
if (cancelled) {
|
|
248
|
+
return;
|
|
249
|
+
}
|
|
250
|
+
cleanup();
|
|
251
|
+
exitCode = code;
|
|
252
|
+
signal = sig;
|
|
253
|
+
const duration = Date.now() - startTime;
|
|
254
|
+
resolve({
|
|
255
|
+
stdout,
|
|
256
|
+
stderr,
|
|
257
|
+
exitCode,
|
|
258
|
+
signal,
|
|
259
|
+
duration,
|
|
260
|
+
});
|
|
261
|
+
});
|
|
262
|
+
stream.on("data", (data) => {
|
|
263
|
+
const chunk = data.toString();
|
|
264
|
+
// Check buffer size limit
|
|
265
|
+
if (stdout.length + chunk.length > maxBufferSize) {
|
|
266
|
+
cleanup();
|
|
267
|
+
stream.close();
|
|
268
|
+
reject(new CommandFailedError(command, -1, `Output exceeds maximum buffer size (${maxBufferSize} bytes)`));
|
|
269
|
+
return;
|
|
270
|
+
}
|
|
271
|
+
stdout += chunk;
|
|
272
|
+
// Call chunk callback if provided
|
|
273
|
+
if (chunkCallback) {
|
|
274
|
+
try {
|
|
275
|
+
chunkCallback(chunk, false);
|
|
276
|
+
}
|
|
277
|
+
catch {
|
|
278
|
+
// Ignore callback errors
|
|
279
|
+
}
|
|
280
|
+
}
|
|
281
|
+
});
|
|
282
|
+
stream.stderr.on("data", (data) => {
|
|
283
|
+
const chunk = data.toString();
|
|
284
|
+
// Check buffer size limit for stderr
|
|
285
|
+
if (stderr.length + chunk.length > maxBufferSize) {
|
|
286
|
+
cleanup();
|
|
287
|
+
stream.close();
|
|
288
|
+
reject(new CommandFailedError(command, -1, `Stderr exceeds maximum buffer size (${maxBufferSize} bytes)`));
|
|
289
|
+
return;
|
|
290
|
+
}
|
|
291
|
+
stderr += chunk;
|
|
292
|
+
// Call chunk callback if provided
|
|
293
|
+
if (chunkCallback) {
|
|
294
|
+
try {
|
|
295
|
+
chunkCallback(chunk, true);
|
|
296
|
+
}
|
|
297
|
+
catch {
|
|
298
|
+
// Ignore callback errors
|
|
299
|
+
}
|
|
300
|
+
}
|
|
301
|
+
});
|
|
302
|
+
stream.on("error", (streamErr) => {
|
|
303
|
+
if (cancelled) {
|
|
304
|
+
return;
|
|
305
|
+
}
|
|
306
|
+
cleanup();
|
|
307
|
+
reject(new CommandFailedError(command, 1, streamErr.message));
|
|
308
|
+
});
|
|
309
|
+
});
|
|
310
|
+
});
|
|
311
|
+
}
|
|
312
|
+
/**
|
|
313
|
+
* Execute a command with streaming output
|
|
314
|
+
*/
|
|
315
|
+
async executeStreaming(command, onChunk, options) {
|
|
316
|
+
return this.execute(command, {
|
|
317
|
+
...options,
|
|
318
|
+
chunkCallback: (data, isStderr) => {
|
|
319
|
+
onChunk({
|
|
320
|
+
data,
|
|
321
|
+
isStderr,
|
|
322
|
+
timestamp: new Date(),
|
|
323
|
+
});
|
|
324
|
+
},
|
|
325
|
+
});
|
|
326
|
+
}
|
|
327
|
+
/**
|
|
328
|
+
* Cancel all active executions
|
|
329
|
+
*/
|
|
330
|
+
cancelAllExecutions() {
|
|
331
|
+
for (const [_id, exec] of this.activeExecutions) {
|
|
332
|
+
try {
|
|
333
|
+
clearTimeout(exec.timeoutId);
|
|
334
|
+
exec.stream.close();
|
|
335
|
+
}
|
|
336
|
+
catch {
|
|
337
|
+
// Ignore close errors
|
|
338
|
+
}
|
|
339
|
+
}
|
|
340
|
+
this.activeExecutions.clear();
|
|
341
|
+
}
|
|
342
|
+
/**
|
|
343
|
+
* Get the server ID if connected
|
|
344
|
+
*/
|
|
345
|
+
getServerId() {
|
|
346
|
+
return this.serverId;
|
|
347
|
+
}
|
|
348
|
+
/**
|
|
349
|
+
* Set the server ID
|
|
350
|
+
*/
|
|
351
|
+
setServerId(id) {
|
|
352
|
+
this.serverId = id;
|
|
353
|
+
}
|
|
354
|
+
/**
|
|
355
|
+
* Get current connection state
|
|
356
|
+
*/
|
|
357
|
+
getState() {
|
|
358
|
+
return { ...this.state };
|
|
359
|
+
}
|
|
360
|
+
/**
|
|
361
|
+
* Get active execution count
|
|
362
|
+
*/
|
|
363
|
+
getActiveExecutionCount() {
|
|
364
|
+
return this.activeExecutions.size;
|
|
365
|
+
}
|
|
366
|
+
}
|
|
367
|
+
//# sourceMappingURL=SSHClient.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"SSHClient.js","sourceRoot":"","sources":["../../src/core/SSHClient.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Server Manager
|
|
3
|
+
* Provides CRUD operations for server configurations
|
|
4
|
+
*/
|
|
5
|
+
import { CryptoService } from "../services/CryptoService.js";
|
|
6
|
+
import { LoggingService } from "../services/LoggingService.js";
|
|
7
|
+
import type { Server, ServerConfig } from "../types/index.js";
|
|
8
|
+
/**
|
|
9
|
+
* Server Manager for handling server configurations
|
|
10
|
+
*/
|
|
11
|
+
export declare class ServerManager {
|
|
12
|
+
private servers;
|
|
13
|
+
private currentServer;
|
|
14
|
+
private readonly storageFile;
|
|
15
|
+
private readonly cryptoService;
|
|
16
|
+
private readonly validationService;
|
|
17
|
+
private readonly logger;
|
|
18
|
+
constructor(storageFile: string, cryptoService: CryptoService, logger: LoggingService);
|
|
19
|
+
/**
|
|
20
|
+
* Initialize server manager and load servers from storage
|
|
21
|
+
*/
|
|
22
|
+
initialize(): Promise<void>;
|
|
23
|
+
/**
|
|
24
|
+
* Add a new server
|
|
25
|
+
*/
|
|
26
|
+
add(config: ServerConfig): Promise<Server>;
|
|
27
|
+
/**
|
|
28
|
+
* Remove a server by ID
|
|
29
|
+
*/
|
|
30
|
+
remove(id: string): Promise<void>;
|
|
31
|
+
/**
|
|
32
|
+
* Remove a server by index (1-based for user friendliness)
|
|
33
|
+
*/
|
|
34
|
+
removeByIndex(index: number): Promise<void>;
|
|
35
|
+
/**
|
|
36
|
+
* List all servers
|
|
37
|
+
*/
|
|
38
|
+
list(): Promise<Server[]>;
|
|
39
|
+
/**
|
|
40
|
+
* Get a server by ID
|
|
41
|
+
*/
|
|
42
|
+
get(id: string): Promise<Server | null>;
|
|
43
|
+
/**
|
|
44
|
+
* Get a server by index (1-based)
|
|
45
|
+
*/
|
|
46
|
+
getByIndex(index: number): Promise<Server | null>;
|
|
47
|
+
/**
|
|
48
|
+
* Get current connected server
|
|
49
|
+
*/
|
|
50
|
+
getCurrent(): Server | null;
|
|
51
|
+
/**
|
|
52
|
+
* Set current server
|
|
53
|
+
*/
|
|
54
|
+
setCurrent(server: Server): void;
|
|
55
|
+
/**
|
|
56
|
+
* Clear current server
|
|
57
|
+
*/
|
|
58
|
+
clearCurrent(): void;
|
|
59
|
+
/**
|
|
60
|
+
* Get decrypted credentials for a server
|
|
61
|
+
*/
|
|
62
|
+
getDecryptedCredentials(server: Server): {
|
|
63
|
+
password?: string;
|
|
64
|
+
privateKeyPath?: string;
|
|
65
|
+
passphrase?: string;
|
|
66
|
+
};
|
|
67
|
+
/**
|
|
68
|
+
* Load servers from storage
|
|
69
|
+
*/
|
|
70
|
+
private load;
|
|
71
|
+
/**
|
|
72
|
+
* Save servers to storage
|
|
73
|
+
*/
|
|
74
|
+
private save;
|
|
75
|
+
/**
|
|
76
|
+
* Generate a unique server ID
|
|
77
|
+
*/
|
|
78
|
+
private generateId;
|
|
79
|
+
}
|
|
80
|
+
//# sourceMappingURL=ServerManager.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ServerManager.d.ts","sourceRoot":"","sources":["../../src/core/ServerManager.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAMH,OAAO,EAAE,aAAa,EAAE,MAAM,8BAA8B,CAAC;AAC7D,OAAO,EAAE,cAAc,EAAE,MAAM,+BAA+B,CAAC;AAE/D,OAAO,KAAK,EAAE,MAAM,EAAE,YAAY,EAAiB,MAAM,mBAAmB,CAAC;AAG7E;;GAEG;AACH,qBAAa,aAAa;IACxB,OAAO,CAAC,OAAO,CAAgB;IAC/B,OAAO,CAAC,aAAa,CAAuB;IAC5C,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAS;IACrC,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAgB;IAC9C,OAAO,CAAC,QAAQ,CAAC,iBAAiB,CAAoB;IACtD,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAiB;gBAGtC,WAAW,EAAE,MAAM,EACnB,aAAa,EAAE,aAAa,EAC5B,MAAM,EAAE,cAAc;IAQxB;;OAEG;IACG,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC;IAIjC;;OAEG;IACG,GAAG,CAAC,MAAM,EAAE,YAAY,GAAG,OAAO,CAAC,MAAM,CAAC;IAwDhD;;OAEG;IACG,MAAM,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAoBvC;;OAEG;IACG,aAAa,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAejD;;OAEG;IACG,IAAI,IAAI,OAAO,CAAC,MAAM,EAAE,CAAC;IAI/B;;OAEG;IACG,GAAG,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC;IAI7C;;OAEG;IACG,UAAU,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC;IAQvD;;OAEG;IACH,UAAU,IAAI,MAAM,GAAG,IAAI;IAI3B;;OAEG;IACH,UAAU,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI;IAQhC;;OAEG;IACH,YAAY,IAAI,IAAI;IAKpB;;OAEG;IACH,uBAAuB,CAAC,MAAM,EAAE,MAAM,GAAG;QACvC,QAAQ,CAAC,EAAE,MAAM,CAAC;QAClB,cAAc,CAAC,EAAE,MAAM,CAAC;QACxB,UAAU,CAAC,EAAE,MAAM,CAAC;KACrB;IA0BD;;OAEG;YACW,IAAI;IAqBlB;;OAEG;YACW,IAAI;IAWlB;;OAEG;IACH,OAAO,CAAC,UAAU;CAGnB"}
|
|
@@ -0,0 +1,207 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Server Manager
|
|
3
|
+
* Provides CRUD operations for server configurations
|
|
4
|
+
*/
|
|
5
|
+
import { FileNotFoundError, InvalidServerConfigError, } from "../errors/index.js";
|
|
6
|
+
import { ValidationService } from "../services/ValidationService.js";
|
|
7
|
+
import { fileExists, readJsonFile, writeJsonFile } from "../utils/fileUtils.js";
|
|
8
|
+
/**
|
|
9
|
+
* Server Manager for handling server configurations
|
|
10
|
+
*/
|
|
11
|
+
export class ServerManager {
|
|
12
|
+
servers = [];
|
|
13
|
+
currentServer = null;
|
|
14
|
+
storageFile;
|
|
15
|
+
cryptoService;
|
|
16
|
+
validationService;
|
|
17
|
+
logger;
|
|
18
|
+
constructor(storageFile, cryptoService, logger) {
|
|
19
|
+
this.storageFile = storageFile;
|
|
20
|
+
this.cryptoService = cryptoService;
|
|
21
|
+
this.validationService = new ValidationService();
|
|
22
|
+
this.logger = logger;
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* Initialize server manager and load servers from storage
|
|
26
|
+
*/
|
|
27
|
+
async initialize() {
|
|
28
|
+
await this.load();
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* Add a new server
|
|
32
|
+
*/
|
|
33
|
+
async add(config) {
|
|
34
|
+
// Validate config
|
|
35
|
+
const validation = this.validationService.validateServerConfig(config);
|
|
36
|
+
if (!validation.valid || !validation.data) {
|
|
37
|
+
throw new InvalidServerConfigError(validation.error ?? "Invalid server configuration");
|
|
38
|
+
}
|
|
39
|
+
const validConfig = validation.data;
|
|
40
|
+
// Create server object
|
|
41
|
+
const now = new Date();
|
|
42
|
+
const server = {
|
|
43
|
+
id: this.generateId(),
|
|
44
|
+
host: validConfig.host,
|
|
45
|
+
port: validConfig.port ?? 22,
|
|
46
|
+
username: validConfig.username,
|
|
47
|
+
note: validConfig.note,
|
|
48
|
+
createdAt: now,
|
|
49
|
+
updatedAt: now,
|
|
50
|
+
auth: {
|
|
51
|
+
type: validConfig.privateKeyPath ? "privateKey" : "password",
|
|
52
|
+
},
|
|
53
|
+
};
|
|
54
|
+
// Encrypt and store credentials
|
|
55
|
+
if (validConfig.password) {
|
|
56
|
+
server.auth.password = this.cryptoService.encrypt(validConfig.password);
|
|
57
|
+
}
|
|
58
|
+
if (validConfig.privateKeyPath) {
|
|
59
|
+
// Store path reference (actual key is read at connection time)
|
|
60
|
+
server.auth.privateKey = this.cryptoService.encrypt(validConfig.privateKeyPath);
|
|
61
|
+
}
|
|
62
|
+
if (validConfig.keyPassphrase) {
|
|
63
|
+
server.auth.passphrase = this.cryptoService.encrypt(validConfig.keyPassphrase);
|
|
64
|
+
}
|
|
65
|
+
// Add to list and save
|
|
66
|
+
this.servers.push(server);
|
|
67
|
+
await this.save();
|
|
68
|
+
this.logger.info("Server added", {
|
|
69
|
+
serverId: server.id,
|
|
70
|
+
host: server.host,
|
|
71
|
+
});
|
|
72
|
+
return server;
|
|
73
|
+
}
|
|
74
|
+
/**
|
|
75
|
+
* Remove a server by ID
|
|
76
|
+
*/
|
|
77
|
+
async remove(id) {
|
|
78
|
+
const index = this.servers.findIndex((s) => s.id === id);
|
|
79
|
+
if (index === -1) {
|
|
80
|
+
throw new FileNotFoundError(`Server with ID ${id}`);
|
|
81
|
+
}
|
|
82
|
+
const removed = this.servers.splice(index, 1)[0];
|
|
83
|
+
if (!removed) {
|
|
84
|
+
throw new FileNotFoundError(`Server with ID ${id}`);
|
|
85
|
+
}
|
|
86
|
+
// Clear current server if it was removed
|
|
87
|
+
if (this.currentServer?.id === id) {
|
|
88
|
+
this.currentServer = null;
|
|
89
|
+
}
|
|
90
|
+
await this.save();
|
|
91
|
+
this.logger.info("Server removed", { serverId: id, host: removed.host });
|
|
92
|
+
}
|
|
93
|
+
/**
|
|
94
|
+
* Remove a server by index (1-based for user friendliness)
|
|
95
|
+
*/
|
|
96
|
+
async removeByIndex(index) {
|
|
97
|
+
// BUG-003 FIX: Use parseInt semantics, but index is already a number here
|
|
98
|
+
// The index is 1-based from user input
|
|
99
|
+
const arrayIndex = index - 1;
|
|
100
|
+
if (arrayIndex < 0 || arrayIndex >= this.servers.length) {
|
|
101
|
+
throw new FileNotFoundError(`Server at index ${index}`);
|
|
102
|
+
}
|
|
103
|
+
const server = this.servers[arrayIndex];
|
|
104
|
+
if (server) {
|
|
105
|
+
await this.remove(server.id);
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
/**
|
|
109
|
+
* List all servers
|
|
110
|
+
*/
|
|
111
|
+
async list() {
|
|
112
|
+
return [...this.servers];
|
|
113
|
+
}
|
|
114
|
+
/**
|
|
115
|
+
* Get a server by ID
|
|
116
|
+
*/
|
|
117
|
+
async get(id) {
|
|
118
|
+
return this.servers.find((s) => s.id === id) ?? null;
|
|
119
|
+
}
|
|
120
|
+
/**
|
|
121
|
+
* Get a server by index (1-based)
|
|
122
|
+
*/
|
|
123
|
+
async getByIndex(index) {
|
|
124
|
+
const arrayIndex = index - 1;
|
|
125
|
+
if (arrayIndex < 0 || arrayIndex >= this.servers.length) {
|
|
126
|
+
return null;
|
|
127
|
+
}
|
|
128
|
+
return this.servers[arrayIndex] ?? null;
|
|
129
|
+
}
|
|
130
|
+
/**
|
|
131
|
+
* Get current connected server
|
|
132
|
+
*/
|
|
133
|
+
getCurrent() {
|
|
134
|
+
return this.currentServer;
|
|
135
|
+
}
|
|
136
|
+
/**
|
|
137
|
+
* Set current server
|
|
138
|
+
*/
|
|
139
|
+
setCurrent(server) {
|
|
140
|
+
this.currentServer = server;
|
|
141
|
+
this.logger.info("Current server set", {
|
|
142
|
+
serverId: server.id,
|
|
143
|
+
host: server.host,
|
|
144
|
+
});
|
|
145
|
+
}
|
|
146
|
+
/**
|
|
147
|
+
* Clear current server
|
|
148
|
+
*/
|
|
149
|
+
clearCurrent() {
|
|
150
|
+
this.currentServer = null;
|
|
151
|
+
this.logger.info("Current server cleared");
|
|
152
|
+
}
|
|
153
|
+
/**
|
|
154
|
+
* Get decrypted credentials for a server
|
|
155
|
+
*/
|
|
156
|
+
getDecryptedCredentials(server) {
|
|
157
|
+
const credentials = {};
|
|
158
|
+
if (server.auth.password) {
|
|
159
|
+
credentials.password = this.cryptoService.decrypt(server.auth.password);
|
|
160
|
+
}
|
|
161
|
+
if (server.auth.privateKey) {
|
|
162
|
+
credentials.privateKeyPath = this.cryptoService.decrypt(server.auth.privateKey);
|
|
163
|
+
}
|
|
164
|
+
if (server.auth.passphrase) {
|
|
165
|
+
credentials.passphrase = this.cryptoService.decrypt(server.auth.passphrase);
|
|
166
|
+
}
|
|
167
|
+
return credentials;
|
|
168
|
+
}
|
|
169
|
+
/**
|
|
170
|
+
* Load servers from storage
|
|
171
|
+
*/
|
|
172
|
+
async load() {
|
|
173
|
+
try {
|
|
174
|
+
const exists = await fileExists(this.storageFile);
|
|
175
|
+
if (!exists) {
|
|
176
|
+
this.servers = [];
|
|
177
|
+
return;
|
|
178
|
+
}
|
|
179
|
+
const storage = await readJsonFile(this.storageFile);
|
|
180
|
+
this.servers = storage.servers ?? [];
|
|
181
|
+
this.logger.info("Servers loaded", { count: this.servers.length });
|
|
182
|
+
}
|
|
183
|
+
catch (error) {
|
|
184
|
+
this.logger.error("Failed to load servers", error instanceof Error ? error : new Error(String(error)));
|
|
185
|
+
this.servers = [];
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
/**
|
|
189
|
+
* Save servers to storage
|
|
190
|
+
*/
|
|
191
|
+
async save() {
|
|
192
|
+
const storage = {
|
|
193
|
+
version: 2,
|
|
194
|
+
encryptionVersion: 1,
|
|
195
|
+
servers: this.servers,
|
|
196
|
+
};
|
|
197
|
+
await writeJsonFile(this.storageFile, storage);
|
|
198
|
+
this.logger.debug("Servers saved", { count: this.servers.length });
|
|
199
|
+
}
|
|
200
|
+
/**
|
|
201
|
+
* Generate a unique server ID
|
|
202
|
+
*/
|
|
203
|
+
generateId() {
|
|
204
|
+
return `srv_${Date.now().toString(36)}_${Math.random().toString(36).substring(2, 8)}`;
|
|
205
|
+
}
|
|
206
|
+
}
|
|
207
|
+
//# sourceMappingURL=ServerManager.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ServerManager.js","sourceRoot":"","sources":["../../src/core/ServerManager.ts"],"names":[],"mappings":"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"}
|