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 @@
|
|
|
1
|
+
{"version":3,"file":"schema.d.ts","sourceRoot":"","sources":["../../src/config/schema.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,GAAG,MAAM,KAAK,CAAC;AAEtB,eAAO,MAAM,YAAY,uBAkDZ,CAAC"}
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Configuration validation schema using Joi
|
|
3
|
+
*/
|
|
4
|
+
import Joi from "joi";
|
|
5
|
+
export const configSchema = Joi.object({
|
|
6
|
+
telegram: Joi.object({
|
|
7
|
+
token: Joi.string().required(),
|
|
8
|
+
chatId: Joi.string().required(),
|
|
9
|
+
ownerIds: Joi.array().items(Joi.string()).min(1).required(),
|
|
10
|
+
polling: Joi.boolean().default(true),
|
|
11
|
+
}).required(),
|
|
12
|
+
security: Joi.object({
|
|
13
|
+
encryptionKey: Joi.string().length(64).required(), // 32 bytes hex
|
|
14
|
+
rateLimit: Joi.object({
|
|
15
|
+
enabled: Joi.boolean().default(true),
|
|
16
|
+
windowMs: Joi.number().min(1000).max(3600000).default(60000),
|
|
17
|
+
maxRequests: Joi.number().min(1).max(1000).default(30),
|
|
18
|
+
skipFailedRequests: Joi.boolean().default(false),
|
|
19
|
+
}).required(),
|
|
20
|
+
allowedCommands: Joi.array().items(Joi.string()).optional(),
|
|
21
|
+
blockedCommands: Joi.array().items(Joi.string()).optional(),
|
|
22
|
+
}).required(),
|
|
23
|
+
ssh: Joi.object({
|
|
24
|
+
defaultPrivateKeyPath: Joi.string().required(),
|
|
25
|
+
defaultPort: Joi.number().min(1).max(65535).default(22),
|
|
26
|
+
connectionTimeout: Joi.number().min(1000).max(120000).default(30000),
|
|
27
|
+
keepaliveInterval: Joi.number().min(1000).max(60000).default(10000),
|
|
28
|
+
maxConnections: Joi.number().min(1).max(20).default(5),
|
|
29
|
+
commandTimeout: Joi.number().min(1000).max(300000).default(60000),
|
|
30
|
+
}).required(),
|
|
31
|
+
logging: Joi.object({
|
|
32
|
+
level: Joi.string().valid("debug", "info", "warn", "error").default("info"),
|
|
33
|
+
format: Joi.string().valid("json", "pretty").default("json"),
|
|
34
|
+
file: Joi.string().optional(),
|
|
35
|
+
}).required(),
|
|
36
|
+
storage: Joi.object({
|
|
37
|
+
serversFile: Joi.string().required(),
|
|
38
|
+
encryptionEnabled: Joi.boolean().default(true),
|
|
39
|
+
}).required(),
|
|
40
|
+
backup: Joi.object({
|
|
41
|
+
enabled: Joi.boolean().default(true),
|
|
42
|
+
intervalMs: Joi.number().min(60000).max(86400000).default(3600000),
|
|
43
|
+
maxCount: Joi.number().min(1).max(100).default(10),
|
|
44
|
+
}).required(),
|
|
45
|
+
monitoring: Joi.object({
|
|
46
|
+
enabled: Joi.boolean().default(true),
|
|
47
|
+
intervalMs: Joi.number().min(10000).max(3600000).default(300000),
|
|
48
|
+
}).required(),
|
|
49
|
+
}).required();
|
|
50
|
+
//# sourceMappingURL=schema.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"schema.js","sourceRoot":"","sources":["../../src/config/schema.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Telegram Bot Core
|
|
3
|
+
* Provides bot lifecycle management and command routing
|
|
4
|
+
*/
|
|
5
|
+
import TelegramBot from "node-telegram-bot-api";
|
|
6
|
+
import { LoggingService } from "../services/LoggingService.js";
|
|
7
|
+
import type { IBot, ICommandHandler, IMiddleware, MessageOptions } from "../types/index.js";
|
|
8
|
+
/**
|
|
9
|
+
* Bot configuration
|
|
10
|
+
*/
|
|
11
|
+
interface BotConfig {
|
|
12
|
+
token: string;
|
|
13
|
+
ownerIds: string[];
|
|
14
|
+
polling: boolean;
|
|
15
|
+
/** Optional custom API URL for Telegram Bot API proxies */
|
|
16
|
+
apiUrl?: string;
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* Telegram Bot implementation
|
|
20
|
+
*/
|
|
21
|
+
export declare class Bot implements IBot {
|
|
22
|
+
private readonly bot;
|
|
23
|
+
private readonly ownerIds;
|
|
24
|
+
private readonly logger;
|
|
25
|
+
private readonly commands;
|
|
26
|
+
private readonly middlewares;
|
|
27
|
+
private started;
|
|
28
|
+
constructor(config: BotConfig, logger: LoggingService);
|
|
29
|
+
/**
|
|
30
|
+
* Start the bot
|
|
31
|
+
*/
|
|
32
|
+
start(): Promise<void>;
|
|
33
|
+
/**
|
|
34
|
+
* Stop the bot
|
|
35
|
+
*/
|
|
36
|
+
stop(): Promise<void>;
|
|
37
|
+
/**
|
|
38
|
+
* Register a command handler
|
|
39
|
+
*/
|
|
40
|
+
registerCommand(handler: ICommandHandler): void;
|
|
41
|
+
/**
|
|
42
|
+
* Add middleware
|
|
43
|
+
*/
|
|
44
|
+
use(middleware: IMiddleware): void;
|
|
45
|
+
/**
|
|
46
|
+
* Send a message
|
|
47
|
+
*/
|
|
48
|
+
sendMessage(chatId: number, message: string, options?: MessageOptions): Promise<void>;
|
|
49
|
+
/**
|
|
50
|
+
* Check if user is owner
|
|
51
|
+
*/
|
|
52
|
+
isOwner(userId: number): boolean;
|
|
53
|
+
/**
|
|
54
|
+
* Get the underlying TelegramBot instance
|
|
55
|
+
*/
|
|
56
|
+
getTelegramBot(): TelegramBot;
|
|
57
|
+
/**
|
|
58
|
+
* Setup message and command handlers
|
|
59
|
+
*/
|
|
60
|
+
private setupHandlers;
|
|
61
|
+
/**
|
|
62
|
+
* Handle incoming message
|
|
63
|
+
*/
|
|
64
|
+
private handleMessage;
|
|
65
|
+
/**
|
|
66
|
+
* Handle command message
|
|
67
|
+
*/
|
|
68
|
+
private handleCommand;
|
|
69
|
+
/**
|
|
70
|
+
* Handle regular (non-command) message
|
|
71
|
+
*/
|
|
72
|
+
private handleRegularMessage;
|
|
73
|
+
/**
|
|
74
|
+
* Execute middleware stack
|
|
75
|
+
*/
|
|
76
|
+
private executeMiddleware;
|
|
77
|
+
/**
|
|
78
|
+
* Create message context from Telegram message
|
|
79
|
+
*/
|
|
80
|
+
private createMessageContext;
|
|
81
|
+
/**
|
|
82
|
+
* Handle error and send user-friendly message
|
|
83
|
+
*/
|
|
84
|
+
private handleError;
|
|
85
|
+
/**
|
|
86
|
+
* Set bot commands in Telegram
|
|
87
|
+
*/
|
|
88
|
+
private setCommands;
|
|
89
|
+
}
|
|
90
|
+
export {};
|
|
91
|
+
//# sourceMappingURL=Bot.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Bot.d.ts","sourceRoot":"","sources":["../../src/core/Bot.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,WAAW,MAAM,uBAAuB,CAAC;AAEhD,OAAO,EAAE,cAAc,EAAE,MAAM,+BAA+B,CAAC;AAC/D,OAAO,KAAK,EAGV,IAAI,EACJ,eAAe,EACf,WAAW,EAEX,cAAc,EACf,MAAM,mBAAmB,CAAC;AAE3B;;GAEG;AACH,UAAU,SAAS;IACjB,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,MAAM,EAAE,CAAC;IACnB,OAAO,EAAE,OAAO,CAAC;IACjB,2DAA2D;IAC3D,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAQD;;GAEG;AACH,qBAAa,GAAI,YAAW,IAAI;IAC9B,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAc;IAClC,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAc;IACvC,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAiB;IACxC,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAA2C;IACpE,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAqB;IACjD,OAAO,CAAC,OAAO,CAAS;gBAEZ,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,cAAc;IAUrD;;OAEG;IACG,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IAe5B;;OAEG;IACG,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;IAa3B;;OAEG;IACH,eAAe,CAAC,OAAO,EAAE,eAAe,GAAG,IAAI;IAK/C;;OAEG;IACH,GAAG,CAAC,UAAU,EAAE,WAAW,GAAG,IAAI;IAKlC;;OAEG;IACG,WAAW,CACf,MAAM,EAAE,MAAM,EACd,OAAO,EAAE,MAAM,EACf,OAAO,CAAC,EAAE,cAAc,GACvB,OAAO,CAAC,IAAI,CAAC;IAkBhB;;OAEG;IACH,OAAO,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO;IAIhC;;OAEG;IACH,cAAc,IAAI,WAAW;IAI7B;;OAEG;IACH,OAAO,CAAC,aAAa;IAsBrB;;OAEG;YACW,aAAa;IAY3B;;OAEG;YACW,aAAa;IA8C3B;;OAEG;YACW,oBAAoB;IAsBlC;;OAEG;YACW,iBAAiB;IAyB/B;;OAEG;IACH,OAAO,CAAC,oBAAoB;IAW5B;;OAEG;YACW,WAAW;IAsBzB;;OAEG;YACW,WAAW;CAiB1B"}
|
package/dist/core/Bot.js
ADDED
|
@@ -0,0 +1,263 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Telegram Bot Core
|
|
3
|
+
* Provides bot lifecycle management and command routing
|
|
4
|
+
*/
|
|
5
|
+
import TelegramBot from "node-telegram-bot-api";
|
|
6
|
+
import { UnauthorizedError } from "../errors/index.js";
|
|
7
|
+
/**
|
|
8
|
+
* Pre-compiled command regex pattern
|
|
9
|
+
* Matches: /command[@bot_username] [args]
|
|
10
|
+
*/
|
|
11
|
+
const COMMAND_REGEX = /^\/(\w+)(?:@\w+)?(?:\s+(.*))?$/;
|
|
12
|
+
/**
|
|
13
|
+
* Telegram Bot implementation
|
|
14
|
+
*/
|
|
15
|
+
export class Bot {
|
|
16
|
+
bot;
|
|
17
|
+
ownerIds;
|
|
18
|
+
logger;
|
|
19
|
+
commands = new Map();
|
|
20
|
+
middlewares = [];
|
|
21
|
+
started = false;
|
|
22
|
+
constructor(config, logger) {
|
|
23
|
+
const options = { polling: config.polling };
|
|
24
|
+
if (config.apiUrl) {
|
|
25
|
+
options.baseApiUrl = config.apiUrl;
|
|
26
|
+
}
|
|
27
|
+
this.bot = new TelegramBot(config.token, options);
|
|
28
|
+
this.ownerIds = new Set(config.ownerIds);
|
|
29
|
+
this.logger = logger;
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* Start the bot
|
|
33
|
+
*/
|
|
34
|
+
async start() {
|
|
35
|
+
if (this.started) {
|
|
36
|
+
return;
|
|
37
|
+
}
|
|
38
|
+
// Register command handlers
|
|
39
|
+
this.setupHandlers();
|
|
40
|
+
// Set bot commands
|
|
41
|
+
await this.setCommands();
|
|
42
|
+
this.started = true;
|
|
43
|
+
this.logger.info("Bot started");
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* Stop the bot
|
|
47
|
+
*/
|
|
48
|
+
async stop() {
|
|
49
|
+
if (!this.started) {
|
|
50
|
+
return;
|
|
51
|
+
}
|
|
52
|
+
if (this.bot.isPolling()) {
|
|
53
|
+
await this.bot.stopPolling();
|
|
54
|
+
}
|
|
55
|
+
this.started = false;
|
|
56
|
+
this.logger.info("Bot stopped");
|
|
57
|
+
}
|
|
58
|
+
/**
|
|
59
|
+
* Register a command handler
|
|
60
|
+
*/
|
|
61
|
+
registerCommand(handler) {
|
|
62
|
+
this.commands.set(handler.name, handler);
|
|
63
|
+
this.logger.debug("Command registered", { command: handler.name });
|
|
64
|
+
}
|
|
65
|
+
/**
|
|
66
|
+
* Add middleware
|
|
67
|
+
*/
|
|
68
|
+
use(middleware) {
|
|
69
|
+
this.middlewares.push(middleware);
|
|
70
|
+
this.logger.debug("Middleware added");
|
|
71
|
+
}
|
|
72
|
+
/**
|
|
73
|
+
* Send a message
|
|
74
|
+
*/
|
|
75
|
+
async sendMessage(chatId, message, options) {
|
|
76
|
+
const sendOptions = {};
|
|
77
|
+
if (options?.parseMode) {
|
|
78
|
+
sendOptions.parse_mode = options.parseMode;
|
|
79
|
+
}
|
|
80
|
+
if (options?.disableWebPagePreview) {
|
|
81
|
+
sendOptions.disable_web_page_preview = options.disableWebPagePreview;
|
|
82
|
+
}
|
|
83
|
+
if (options?.protectContent) {
|
|
84
|
+
sendOptions.protect_content = options.protectContent;
|
|
85
|
+
}
|
|
86
|
+
await this.bot.sendMessage(chatId, message, sendOptions);
|
|
87
|
+
}
|
|
88
|
+
/**
|
|
89
|
+
* Check if user is owner
|
|
90
|
+
*/
|
|
91
|
+
isOwner(userId) {
|
|
92
|
+
return this.ownerIds.has(String(userId));
|
|
93
|
+
}
|
|
94
|
+
/**
|
|
95
|
+
* Get the underlying TelegramBot instance
|
|
96
|
+
*/
|
|
97
|
+
getTelegramBot() {
|
|
98
|
+
return this.bot;
|
|
99
|
+
}
|
|
100
|
+
/**
|
|
101
|
+
* Setup message and command handlers
|
|
102
|
+
*/
|
|
103
|
+
setupHandlers() {
|
|
104
|
+
// Handle all messages
|
|
105
|
+
this.bot.on("message", async (msg) => {
|
|
106
|
+
try {
|
|
107
|
+
await this.handleMessage(msg);
|
|
108
|
+
}
|
|
109
|
+
catch (error) {
|
|
110
|
+
this.logger.error("Error handling message", error instanceof Error ? error : new Error(String(error)), {
|
|
111
|
+
chatId: msg.chat.id,
|
|
112
|
+
});
|
|
113
|
+
}
|
|
114
|
+
});
|
|
115
|
+
// Handle polling errors
|
|
116
|
+
this.bot.on("polling_error", (error) => {
|
|
117
|
+
this.logger.error("Polling error", error);
|
|
118
|
+
});
|
|
119
|
+
}
|
|
120
|
+
/**
|
|
121
|
+
* Handle incoming message
|
|
122
|
+
*/
|
|
123
|
+
async handleMessage(msg) {
|
|
124
|
+
const context = this.createMessageContext(msg);
|
|
125
|
+
// Check if it's a command
|
|
126
|
+
if (msg.text?.startsWith("/")) {
|
|
127
|
+
await this.handleCommand(msg, context);
|
|
128
|
+
}
|
|
129
|
+
else {
|
|
130
|
+
// Handle as regular message (SSH command if connected)
|
|
131
|
+
await this.handleRegularMessage(msg, context);
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
/**
|
|
135
|
+
* Handle command message
|
|
136
|
+
*/
|
|
137
|
+
async handleCommand(msg, context) {
|
|
138
|
+
const text = msg.text;
|
|
139
|
+
if (!text) {
|
|
140
|
+
return;
|
|
141
|
+
}
|
|
142
|
+
// Parse command using pre-compiled regex
|
|
143
|
+
const match = text.match(COMMAND_REGEX);
|
|
144
|
+
if (!match) {
|
|
145
|
+
return;
|
|
146
|
+
}
|
|
147
|
+
const commandName = match[1] ?? "";
|
|
148
|
+
const args = match[2] ?? "";
|
|
149
|
+
// Find handler
|
|
150
|
+
const handler = this.commands.get(commandName);
|
|
151
|
+
if (!handler) {
|
|
152
|
+
await this.sendMessage(context.chatId, `Unknown command: /${commandName}`);
|
|
153
|
+
return;
|
|
154
|
+
}
|
|
155
|
+
// Create command context
|
|
156
|
+
const commandContext = {
|
|
157
|
+
...context,
|
|
158
|
+
command: commandName,
|
|
159
|
+
args,
|
|
160
|
+
match,
|
|
161
|
+
};
|
|
162
|
+
// Execute middleware stack
|
|
163
|
+
try {
|
|
164
|
+
await this.executeMiddleware(commandContext, async () => {
|
|
165
|
+
await handler.execute(commandContext);
|
|
166
|
+
});
|
|
167
|
+
}
|
|
168
|
+
catch (error) {
|
|
169
|
+
await this.handleError(context.chatId, error);
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
/**
|
|
173
|
+
* Handle regular (non-command) message
|
|
174
|
+
*/
|
|
175
|
+
async handleRegularMessage(msg, context) {
|
|
176
|
+
// Find a default handler for regular messages
|
|
177
|
+
const defaultHandler = this.commands.get("_message");
|
|
178
|
+
if (defaultHandler) {
|
|
179
|
+
try {
|
|
180
|
+
await this.executeMiddleware(context, async () => {
|
|
181
|
+
await defaultHandler.execute({
|
|
182
|
+
...context,
|
|
183
|
+
command: "_message",
|
|
184
|
+
args: msg.text ?? "",
|
|
185
|
+
match: [],
|
|
186
|
+
});
|
|
187
|
+
});
|
|
188
|
+
}
|
|
189
|
+
catch (error) {
|
|
190
|
+
await this.handleError(context.chatId, error);
|
|
191
|
+
}
|
|
192
|
+
}
|
|
193
|
+
}
|
|
194
|
+
/**
|
|
195
|
+
* Execute middleware stack
|
|
196
|
+
*/
|
|
197
|
+
async executeMiddleware(context, final) {
|
|
198
|
+
let index = 0;
|
|
199
|
+
const next = async () => {
|
|
200
|
+
if (index < this.middlewares.length) {
|
|
201
|
+
const middleware = this.middlewares[index];
|
|
202
|
+
if (middleware) {
|
|
203
|
+
index++;
|
|
204
|
+
await middleware.execute({
|
|
205
|
+
...context,
|
|
206
|
+
next,
|
|
207
|
+
state: {},
|
|
208
|
+
});
|
|
209
|
+
}
|
|
210
|
+
}
|
|
211
|
+
else {
|
|
212
|
+
await final();
|
|
213
|
+
}
|
|
214
|
+
};
|
|
215
|
+
await next();
|
|
216
|
+
}
|
|
217
|
+
/**
|
|
218
|
+
* Create message context from Telegram message
|
|
219
|
+
*/
|
|
220
|
+
createMessageContext(msg) {
|
|
221
|
+
return {
|
|
222
|
+
message: msg,
|
|
223
|
+
chatId: msg.chat.id,
|
|
224
|
+
userId: msg.from?.id ?? 0,
|
|
225
|
+
text: msg.text,
|
|
226
|
+
isOwner: this.isOwner(msg.from?.id ?? 0),
|
|
227
|
+
timestamp: new Date(),
|
|
228
|
+
};
|
|
229
|
+
}
|
|
230
|
+
/**
|
|
231
|
+
* Handle error and send user-friendly message
|
|
232
|
+
*/
|
|
233
|
+
async handleError(chatId, error) {
|
|
234
|
+
if (error instanceof UnauthorizedError) {
|
|
235
|
+
await this.sendMessage(chatId, "⛔ Unauthorized: You are not allowed to use this bot.");
|
|
236
|
+
return;
|
|
237
|
+
}
|
|
238
|
+
const message = error instanceof Error ? error.message : "An unexpected error occurred";
|
|
239
|
+
await this.sendMessage(chatId, `❌ Error: ${message}`);
|
|
240
|
+
this.logger.error("Command error", error instanceof Error ? error : new Error(String(error)), {
|
|
241
|
+
chatId,
|
|
242
|
+
});
|
|
243
|
+
}
|
|
244
|
+
/**
|
|
245
|
+
* Set bot commands in Telegram
|
|
246
|
+
*/
|
|
247
|
+
async setCommands() {
|
|
248
|
+
const commands = [];
|
|
249
|
+
for (const [, handler] of this.commands) {
|
|
250
|
+
if (handler.name !== "_message") {
|
|
251
|
+
commands.push({
|
|
252
|
+
command: handler.name,
|
|
253
|
+
description: handler.description,
|
|
254
|
+
});
|
|
255
|
+
}
|
|
256
|
+
}
|
|
257
|
+
if (commands.length > 0) {
|
|
258
|
+
await this.bot.setMyCommands(commands);
|
|
259
|
+
this.logger.debug("Bot commands set", { count: commands.length });
|
|
260
|
+
}
|
|
261
|
+
}
|
|
262
|
+
}
|
|
263
|
+
//# sourceMappingURL=Bot.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Bot.js","sourceRoot":"","sources":["../../src/core/Bot.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Connection Pool
|
|
3
|
+
* Manages multiple SSH connections with pooling, timeout, and health monitoring
|
|
4
|
+
*/
|
|
5
|
+
import { EventEmitter } from "events";
|
|
6
|
+
import { LoggingService } from "../services/LoggingService.js";
|
|
7
|
+
import type { CommandResult, SSHConnectionConfig } from "../types/index.js";
|
|
8
|
+
import { SSHClient } from "./SSHClient.js";
|
|
9
|
+
/**
|
|
10
|
+
* Pooled connection wrapper
|
|
11
|
+
*/
|
|
12
|
+
interface PooledConnection {
|
|
13
|
+
id: string;
|
|
14
|
+
serverId: string;
|
|
15
|
+
client: SSHClient;
|
|
16
|
+
createdAt: Date;
|
|
17
|
+
lastUsedAt: Date;
|
|
18
|
+
inUse: boolean;
|
|
19
|
+
healthCheckFailures: number;
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* Connection pool options
|
|
23
|
+
*/
|
|
24
|
+
export interface ConnectionPoolOptions {
|
|
25
|
+
maxConnections: number;
|
|
26
|
+
connectionTimeout: number;
|
|
27
|
+
commandTimeout: number;
|
|
28
|
+
idleTimeout: number;
|
|
29
|
+
healthCheckInterval: number;
|
|
30
|
+
maxHealthCheckFailures: number;
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* Pool statistics
|
|
34
|
+
*/
|
|
35
|
+
export interface PoolStats {
|
|
36
|
+
totalConnections: number;
|
|
37
|
+
activeConnections: number;
|
|
38
|
+
idleConnections: number;
|
|
39
|
+
waitingRequests: number;
|
|
40
|
+
totalRequestsServed: number;
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* Connection pool for managing multiple SSH connections
|
|
44
|
+
*/
|
|
45
|
+
export declare class ConnectionPool extends EventEmitter {
|
|
46
|
+
private readonly connections;
|
|
47
|
+
private readonly waitingQueue;
|
|
48
|
+
private readonly options;
|
|
49
|
+
private readonly logger;
|
|
50
|
+
private healthCheckTimer;
|
|
51
|
+
private idleCheckTimer;
|
|
52
|
+
private totalRequestsServed;
|
|
53
|
+
private isDraining;
|
|
54
|
+
constructor(options: Partial<ConnectionPoolOptions>, logger: LoggingService);
|
|
55
|
+
/**
|
|
56
|
+
* Initialize the connection pool
|
|
57
|
+
*/
|
|
58
|
+
initialize(): Promise<void>;
|
|
59
|
+
/**
|
|
60
|
+
* Acquire a connection from the pool
|
|
61
|
+
*/
|
|
62
|
+
acquire(serverId: string, config: SSHConnectionConfig): Promise<PooledConnection>;
|
|
63
|
+
/**
|
|
64
|
+
* Release a connection back to the pool
|
|
65
|
+
*/
|
|
66
|
+
release(connection: PooledConnection): void;
|
|
67
|
+
/**
|
|
68
|
+
* Remove a connection from the pool
|
|
69
|
+
*/
|
|
70
|
+
remove(connectionId: string): Promise<void>;
|
|
71
|
+
/**
|
|
72
|
+
* Drain all connections and shutdown pool
|
|
73
|
+
*/
|
|
74
|
+
drain(): Promise<void>;
|
|
75
|
+
/**
|
|
76
|
+
* Get pool statistics
|
|
77
|
+
*/
|
|
78
|
+
getStats(): PoolStats;
|
|
79
|
+
/**
|
|
80
|
+
* Get active connection count
|
|
81
|
+
*/
|
|
82
|
+
getActiveCount(): number;
|
|
83
|
+
/**
|
|
84
|
+
* Execute a command on a pooled connection
|
|
85
|
+
*/
|
|
86
|
+
executeCommand(serverId: string, config: SSHConnectionConfig, command: string): Promise<CommandResult>;
|
|
87
|
+
/**
|
|
88
|
+
* Find an idle connection for the given server
|
|
89
|
+
*/
|
|
90
|
+
private findIdleConnection;
|
|
91
|
+
/**
|
|
92
|
+
* Create a new connection
|
|
93
|
+
*/
|
|
94
|
+
private createConnection;
|
|
95
|
+
/**
|
|
96
|
+
* Wait for a connection to become available
|
|
97
|
+
*/
|
|
98
|
+
private waitForConnection;
|
|
99
|
+
/**
|
|
100
|
+
* Process waiting queue when connections become available
|
|
101
|
+
*/
|
|
102
|
+
private processWaitingQueue;
|
|
103
|
+
/**
|
|
104
|
+
* Start health check timer
|
|
105
|
+
*/
|
|
106
|
+
private startHealthCheck;
|
|
107
|
+
/**
|
|
108
|
+
* Perform health check on all connections
|
|
109
|
+
*/
|
|
110
|
+
private performHealthCheck;
|
|
111
|
+
/**
|
|
112
|
+
* Start idle connection check timer
|
|
113
|
+
*/
|
|
114
|
+
private startIdleCheck;
|
|
115
|
+
/**
|
|
116
|
+
* Remove idle connections that have exceeded idle timeout
|
|
117
|
+
*/
|
|
118
|
+
private removeIdleConnections;
|
|
119
|
+
/**
|
|
120
|
+
* Generate unique connection ID
|
|
121
|
+
*/
|
|
122
|
+
private generateConnectionId;
|
|
123
|
+
}
|
|
124
|
+
export {};
|
|
125
|
+
//# sourceMappingURL=ConnectionPool.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ConnectionPool.d.ts","sourceRoot":"","sources":["../../src/core/ConnectionPool.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,YAAY,EAAE,MAAM,QAAQ,CAAC;AAMtC,OAAO,EAAE,cAAc,EAAE,MAAM,+BAA+B,CAAC;AAC/D,OAAO,KAAK,EAAE,aAAa,EAAE,mBAAmB,EAAE,MAAM,mBAAmB,CAAC;AAC5E,OAAO,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAE3C;;GAEG;AACH,UAAU,gBAAgB;IACxB,EAAE,EAAE,MAAM,CAAC;IACX,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,SAAS,CAAC;IAClB,SAAS,EAAE,IAAI,CAAC;IAChB,UAAU,EAAE,IAAI,CAAC;IACjB,KAAK,EAAE,OAAO,CAAC;IACf,mBAAmB,EAAE,MAAM,CAAC;CAC7B;AAED;;GAEG;AACH,MAAM,WAAW,qBAAqB;IACpC,cAAc,EAAE,MAAM,CAAC;IACvB,iBAAiB,EAAE,MAAM,CAAC;IAC1B,cAAc,EAAE,MAAM,CAAC;IACvB,WAAW,EAAE,MAAM,CAAC;IACpB,mBAAmB,EAAE,MAAM,CAAC;IAC5B,sBAAsB,EAAE,MAAM,CAAC;CAChC;AAED;;GAEG;AACH,MAAM,WAAW,SAAS;IACxB,gBAAgB,EAAE,MAAM,CAAC;IACzB,iBAAiB,EAAE,MAAM,CAAC;IAC1B,eAAe,EAAE,MAAM,CAAC;IACxB,eAAe,EAAE,MAAM,CAAC;IACxB,mBAAmB,EAAE,MAAM,CAAC;CAC7B;AAcD;;GAEG;AACH,qBAAa,cAAe,SAAQ,YAAY;IAC9C,OAAO,CAAC,QAAQ,CAAC,WAAW,CAA4C;IACxE,OAAO,CAAC,QAAQ,CAAC,YAAY,CAA2B;IACxD,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAwB;IAChD,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAiB;IACxC,OAAO,CAAC,gBAAgB,CAA+B;IACvD,OAAO,CAAC,cAAc,CAA+B;IACrD,OAAO,CAAC,mBAAmB,CAAK;IAChC,OAAO,CAAC,UAAU,CAAS;gBAEf,OAAO,EAAE,OAAO,CAAC,qBAAqB,CAAC,EAAE,MAAM,EAAE,cAAc;IAa3E;;OAEG;IACG,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC;IAQjC;;OAEG;IACG,OAAO,CACX,QAAQ,EAAE,MAAM,EAChB,MAAM,EAAE,mBAAmB,GAC1B,OAAO,CAAC,gBAAgB,CAAC;IA2B5B;;OAEG;IACH,OAAO,CAAC,UAAU,EAAE,gBAAgB,GAAG,IAAI;IAkB3C;;OAEG;IACG,MAAM,CAAC,YAAY,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAqBjD;;OAEG;IACG,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IAwC5B;;OAEG;IACH,QAAQ,IAAI,SAAS;IAqBrB;;OAEG;IACH,cAAc,IAAI,MAAM;IAUxB;;OAEG;IACG,cAAc,CAClB,QAAQ,EAAE,MAAM,EAChB,MAAM,EAAE,mBAAmB,EAC3B,OAAO,EAAE,MAAM,GACd,OAAO,CAAC,aAAa,CAAC;IAWzB;;OAEG;IACH,OAAO,CAAC,kBAAkB;IAS1B;;OAEG;YACW,gBAAgB;IA+C9B;;OAEG;IACH,OAAO,CAAC,iBAAiB;IAiEzB;;OAEG;IACH,OAAO,CAAC,mBAAmB;IAkC3B;;OAEG;IACH,OAAO,CAAC,gBAAgB;IAMxB;;OAEG;YACW,kBAAkB;IAiChC;;OAEG;IACH,OAAO,CAAC,cAAc;IAMtB;;OAEG;YACW,qBAAqB;IAoBnC;;OAEG;IACH,OAAO,CAAC,oBAAoB;CAG7B"}
|