@meru2802/aux-server 1.0.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.
Files changed (74) hide show
  1. package/README.md +168 -0
  2. package/dist/config/index.d.ts +37 -0
  3. package/dist/config/index.d.ts.map +1 -0
  4. package/dist/config/index.js +76 -0
  5. package/dist/config/swagger.d.ts +2 -0
  6. package/dist/config/swagger.d.ts.map +1 -0
  7. package/dist/config/swagger.js +267 -0
  8. package/dist/controllers/BaseController.d.ts +16 -0
  9. package/dist/controllers/BaseController.d.ts.map +1 -0
  10. package/dist/controllers/BaseController.js +28 -0
  11. package/dist/controllers/apiController.d.ts +8 -0
  12. package/dist/controllers/apiController.d.ts.map +1 -0
  13. package/dist/controllers/apiController.js +60 -0
  14. package/dist/controllers/coreController.d.ts +11 -0
  15. package/dist/controllers/coreController.d.ts.map +1 -0
  16. package/dist/controllers/coreController.js +470 -0
  17. package/dist/controllers/healthController.d.ts +9 -0
  18. package/dist/controllers/healthController.d.ts.map +1 -0
  19. package/dist/controllers/healthController.js +35 -0
  20. package/dist/index.d.ts +13 -0
  21. package/dist/index.d.ts.map +1 -0
  22. package/dist/index.js +97 -0
  23. package/dist/lib/utils/index.d.ts +10 -0
  24. package/dist/lib/utils/index.d.ts.map +1 -0
  25. package/dist/lib/utils/index.js +78 -0
  26. package/dist/lib/utils/index.test.d.ts +3 -0
  27. package/dist/lib/utils/index.test.d.ts.map +1 -0
  28. package/dist/lib/utils/index.test.js +197 -0
  29. package/dist/middleware/BaseMiddleware.d.ts +13 -0
  30. package/dist/middleware/BaseMiddleware.d.ts.map +1 -0
  31. package/dist/middleware/BaseMiddleware.js +22 -0
  32. package/dist/middleware/authMiddleware.d.ts +9 -0
  33. package/dist/middleware/authMiddleware.d.ts.map +1 -0
  34. package/dist/middleware/authMiddleware.js +287 -0
  35. package/dist/middleware/index.d.ts +11 -0
  36. package/dist/middleware/index.d.ts.map +1 -0
  37. package/dist/middleware/index.js +125 -0
  38. package/dist/routes/apiRoutes.d.ts +5 -0
  39. package/dist/routes/apiRoutes.d.ts.map +1 -0
  40. package/dist/routes/apiRoutes.js +46 -0
  41. package/dist/routes/coreRoutes.d.ts +5 -0
  42. package/dist/routes/coreRoutes.d.ts.map +1 -0
  43. package/dist/routes/coreRoutes.js +158 -0
  44. package/dist/routes/healthRoutes.d.ts +4 -0
  45. package/dist/routes/healthRoutes.d.ts.map +1 -0
  46. package/dist/routes/healthRoutes.js +63 -0
  47. package/dist/routes/index.d.ts +3 -0
  48. package/dist/routes/index.d.ts.map +1 -0
  49. package/dist/routes/index.js +31 -0
  50. package/dist/routes/swaggerRoutes.d.ts +3 -0
  51. package/dist/routes/swaggerRoutes.d.ts.map +1 -0
  52. package/dist/routes/swaggerRoutes.js +35 -0
  53. package/dist/services/ApplicationService.d.ts +26 -0
  54. package/dist/services/ApplicationService.d.ts.map +1 -0
  55. package/dist/services/ApplicationService.js +46 -0
  56. package/dist/services/DatabaseService.d.ts +17 -0
  57. package/dist/services/DatabaseService.d.ts.map +1 -0
  58. package/dist/services/DatabaseService.js +38 -0
  59. package/dist/services/HttpServerService.d.ts +29 -0
  60. package/dist/services/HttpServerService.d.ts.map +1 -0
  61. package/dist/services/HttpServerService.js +101 -0
  62. package/dist/services/ServiceContainer.d.ts +26 -0
  63. package/dist/services/ServiceContainer.d.ts.map +1 -0
  64. package/dist/services/ServiceContainer.js +39 -0
  65. package/dist/services/WebSocketService.d.ts +27 -0
  66. package/dist/services/WebSocketService.d.ts.map +1 -0
  67. package/dist/services/WebSocketService.js +180 -0
  68. package/dist/types/index.d.ts +218 -0
  69. package/dist/types/index.d.ts.map +1 -0
  70. package/dist/types/index.js +19 -0
  71. package/dist/types/schemas/index.d.ts +31 -0
  72. package/dist/types/schemas/index.d.ts.map +1 -0
  73. package/dist/types/schemas/index.js +226 -0
  74. package/package.json +55 -0
package/README.md ADDED
@@ -0,0 +1,168 @@
1
+ # Nexus EPM Auxiliary Server
2
+
3
+ Nexus EPM auxiliary server to facilitate additional functionality required by Scogo Iceberg.
4
+
5
+ ## Features
6
+
7
+ - MeshCentral integration for remote device management
8
+ - Device group management
9
+ - Download link generation for mesh agents
10
+ - Connection URL generation for remote access (control, terminal, file system)
11
+ - Health monitoring and status endpoints
12
+ - WebSocket connectivity for real-time communication
13
+ - PostgreSQL database integration
14
+
15
+ ## API Documentation
16
+
17
+ The server includes comprehensive API documentation using Swagger/OpenAPI 3.0.
18
+
19
+ ### Accessing API Documentation
20
+
21
+ Once the server is running, you can access the interactive API documentation at:
22
+
23
+ - **Swagger UI**: `http://localhost:3003/docs`
24
+ - **OpenAPI JSON Spec**: `http://localhost:3003/docs/json`
25
+
26
+ The Swagger UI provides:
27
+ - Interactive API testing
28
+ - Detailed endpoint documentation
29
+ - Request/response schema definitions
30
+ - Example requests and responses
31
+ - Authentication information
32
+
33
+ ### Available Endpoints
34
+
35
+ #### Health Endpoints
36
+ - `GET /health` - Basic health check for load balancers
37
+ - `GET /status` - Detailed service status including connections and uptime
38
+
39
+ #### API Endpoints
40
+ - `POST /api/generate-download-link` - Generate download link for MeshCentral agent
41
+ - `POST /api/generate-connect-urls` - Generate authenticated URLs for device access
42
+
43
+ #### Core Endpoints
44
+ - `POST /core/create-device-group` - Create a new device group in MeshCentral
45
+ - `POST /core/add-user-to-group` - Add multiple users to a device group
46
+
47
+ ## Development
48
+
49
+ ### Prerequisites
50
+
51
+ - Node.js (v18 or higher)
52
+ - pnpm
53
+ - PostgreSQL database
54
+ - MeshCentral server
55
+
56
+ ### Installation
57
+
58
+ ```bash
59
+ # Install dependencies
60
+ pnpm install
61
+
62
+ # Build the project
63
+ pnpm run build
64
+
65
+ # Start the server
66
+ pnpm run start
67
+
68
+ # Development mode with auto-reload
69
+ pnpm run dev:watch
70
+ ```
71
+
72
+ ### Environment Setup
73
+
74
+ Ensure you have the proper configuration in `config.json` with:
75
+ - MeshCentral server credentials and encryption keys
76
+ - Database connection settings
77
+ - Iceberg integration endpoints
78
+ - Logging configuration
79
+
80
+ ### Database Setup
81
+
82
+ Run the schema.sql file against your PostgreSQL database to set up the required tables:
83
+
84
+ ```bash
85
+ pnpm run setup:db
86
+ ```
87
+
88
+ ## Configuration
89
+
90
+ The server uses a JSON configuration file (`config.json`) with the following structure:
91
+
92
+ - `meshcentralConfig`: MeshCentral server connection and encryption settings
93
+ - `dbConfig`: PostgreSQL database connection settings
94
+ - `icebergConfig`: Iceberg integration endpoints
95
+ - `logging`: Logging configuration for file rotation and levels
96
+
97
+ ## Usage
98
+
99
+ ### Getting a Download Link
100
+
101
+ ```bash
102
+ curl -X POST http://localhost:3003/api/generate-download-link \
103
+ -H "Content-Type: application/json" \
104
+ -d '{"deviceGroupName": "production-servers"}'
105
+ ```
106
+
107
+ ### Getting Connection URLs
108
+
109
+ ```bash
110
+ curl -X POST http://localhost:3003/api/generate-connect-urls \
111
+ -H "Content-Type: application/json" \
112
+ -d '{"meshNodeId": "node//abc123", "userId": "john.doe"}'
113
+ ```
114
+
115
+ ### Creating a Device Group
116
+
117
+ ```bash
118
+ curl -X POST http://localhost:3003/core/create-device-group \
119
+ -H "Content-Type: application/json" \
120
+ -d '{"deviceGroupName": "new-group", "description": "My new device group"}'
121
+ ```
122
+
123
+ ### Adding Users to a Device Group
124
+
125
+ ```bash
126
+ curl -X POST http://localhost:3003/core/add-user-to-group \
127
+ -H "Content-Type: application/json" \
128
+ -d '{"deviceGroupName": "production-servers", "users": ["john.doe", "jane.smith"]}'
129
+ ```
130
+
131
+ ## Architecture
132
+
133
+ The server follows a modular architecture with:
134
+
135
+ - **Controllers**: Handle HTTP request/response logic
136
+ - **Services**: Business logic and external integrations
137
+ - **Routes**: API endpoint definitions and middleware
138
+ - **Middleware**: Request processing, error handling, and validation
139
+ - **Types**: TypeScript type definitions
140
+
141
+ ## Health Monitoring
142
+
143
+ The server provides comprehensive health monitoring:
144
+
145
+ - **Basic Health Check**: `/health` - Quick status for load balancers
146
+ - **Detailed Status**: `/status` - Complete service information including:
147
+ - Service version and uptime
148
+ - MeshCentral connection status
149
+ - Database connection status
150
+ - External service connectivity
151
+
152
+ ## Error Handling
153
+
154
+ All endpoints return standardized error responses with:
155
+ - HTTP status codes
156
+ - Error messages
157
+ - Timestamps
158
+ - Request correlation information
159
+
160
+ ## Security
161
+
162
+ The server implements:
163
+ - CORS configuration
164
+ - Helmet security headers
165
+ - Request validation
166
+ - Encrypted cookie handling for MeshCentral integration
167
+ - Database connection pooling with proper error handling
168
+
@@ -0,0 +1,37 @@
1
+ import { Config } from "../types";
2
+ export declare class ConfigManager {
3
+ private static instance;
4
+ private config;
5
+ private constructor();
6
+ static getInstance(): ConfigManager;
7
+ private loadConfig;
8
+ getConfig(): Config;
9
+ getMeshConfig(): {
10
+ user: string;
11
+ password: string;
12
+ server: string;
13
+ loginEncryptionKey: string;
14
+ inviteEncryptionKey: string;
15
+ };
16
+ getDbConfig(): {
17
+ host: string;
18
+ port: number;
19
+ user: string;
20
+ password: string;
21
+ database: string;
22
+ };
23
+ getIcebergConfig(): {
24
+ eventsEndpoint: string;
25
+ introspectEndpoint: string;
26
+ HMAC_SECRET: string;
27
+ };
28
+ getLoggingConfig(): {
29
+ level: string;
30
+ directory: string;
31
+ filename: string;
32
+ datePattern: string;
33
+ maxSize: string;
34
+ maxFiles: string;
35
+ };
36
+ }
37
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/config/index.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,MAAM,EAAE,MAAM,UAAU,CAAC;AAElC,qBAAa,aAAa;IACxB,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAgB;IACvC,OAAO,CAAC,MAAM,CAAS;IAEvB,OAAO;WAIO,WAAW,IAAI,aAAa;IAO1C,OAAO,CAAC,UAAU;IAwDX,SAAS,IAAI,MAAM;IAInB,aAAa;;;;;;;IAIb,WAAW;;;;;;;IAIX,gBAAgB;;;;;IAIhB,gBAAgB;;;;;;;;CAGxB"}
@@ -0,0 +1,76 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.ConfigManager = void 0;
7
+ const fs_1 = __importDefault(require("fs"));
8
+ const path_1 = __importDefault(require("path"));
9
+ class ConfigManager {
10
+ constructor() {
11
+ this.config = this.loadConfig();
12
+ }
13
+ static getInstance() {
14
+ if (!ConfigManager.instance) {
15
+ ConfigManager.instance = new ConfigManager();
16
+ }
17
+ return ConfigManager.instance;
18
+ }
19
+ loadConfig() {
20
+ let configPath;
21
+ const expectedConfigPath = path_1.default.resolve("/rmm/plugins/aux-server/config.json");
22
+ if (fs_1.default.existsSync(expectedConfigPath)) {
23
+ configPath = expectedConfigPath;
24
+ }
25
+ else {
26
+ const findRootDir = (startDir) => {
27
+ let currentDir = startDir;
28
+ while (currentDir !== "/" && currentDir !== "") {
29
+ if (path_1.default.basename(currentDir) === "aux-server" &&
30
+ path_1.default.basename(path_1.default.dirname(currentDir)) === "plugins") {
31
+ return currentDir;
32
+ }
33
+ if (fs_1.default.existsSync(path_1.default.join(currentDir, "config.json"))) {
34
+ return currentDir;
35
+ }
36
+ const parentDir = path_1.default.dirname(currentDir);
37
+ if (parentDir === currentDir) {
38
+ break;
39
+ }
40
+ currentDir = parentDir;
41
+ }
42
+ return process.cwd();
43
+ };
44
+ const rootDir = findRootDir(__dirname);
45
+ configPath = path_1.default.join(rootDir, "config.json");
46
+ }
47
+ console.log(`Looking for config file at: ${configPath}`);
48
+ if (!fs_1.default.existsSync(configPath)) {
49
+ console.error(`Config file not found at ${configPath}. Please ensure config.json exists.`);
50
+ process.exit(1);
51
+ }
52
+ try {
53
+ return JSON.parse(fs_1.default.readFileSync(configPath, "utf8"));
54
+ }
55
+ catch (error) {
56
+ console.error("Error parsing config file:", error);
57
+ process.exit(1);
58
+ }
59
+ }
60
+ getConfig() {
61
+ return this.config;
62
+ }
63
+ getMeshConfig() {
64
+ return this.config.meshcentralConfig;
65
+ }
66
+ getDbConfig() {
67
+ return this.config.dbConfig;
68
+ }
69
+ getIcebergConfig() {
70
+ return this.config.icebergConfig;
71
+ }
72
+ getLoggingConfig() {
73
+ return this.config.logging;
74
+ }
75
+ }
76
+ exports.ConfigManager = ConfigManager;
@@ -0,0 +1,2 @@
1
+ export declare const swaggerSpec: object;
2
+ //# sourceMappingURL=swagger.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"swagger.d.ts","sourceRoot":"","sources":["../../src/config/swagger.ts"],"names":[],"mappings":"AAsQA,eAAO,MAAM,WAAW,QAAwB,CAAC"}
@@ -0,0 +1,267 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.swaggerSpec = void 0;
7
+ const swagger_jsdoc_1 = __importDefault(require("swagger-jsdoc"));
8
+ const options = {
9
+ definition: {
10
+ openapi: "3.0.0",
11
+ info: {
12
+ title: "Aux Server API",
13
+ version: "1.0.0",
14
+ description: "Nexus EPM auxiliary server to facilitate additional functionality required by Scogo Iceberg",
15
+ contact: {
16
+ name: "API Support",
17
+ email: "support@example.com",
18
+ },
19
+ },
20
+ servers: [
21
+ {
22
+ url: "http://localhost:3003",
23
+ description: "Development server",
24
+ },
25
+ ],
26
+ components: {
27
+ schemas: {
28
+ ErrorResponse: {
29
+ type: "object",
30
+ properties: {
31
+ error: {
32
+ type: "string",
33
+ description: "Error message",
34
+ example: "Internal server error",
35
+ },
36
+ timestamp: {
37
+ type: "string",
38
+ format: "date-time",
39
+ description: "Error timestamp",
40
+ example: "2023-12-01T10:30:00.000Z",
41
+ },
42
+ },
43
+ required: ["error"],
44
+ },
45
+ HealthResponse: {
46
+ type: "object",
47
+ properties: {
48
+ status: {
49
+ type: "string",
50
+ description: "Service status",
51
+ example: "healthy",
52
+ },
53
+ timestamp: {
54
+ type: "string",
55
+ format: "date-time",
56
+ description: "Health check timestamp",
57
+ example: "2023-12-01T10:30:00.000Z",
58
+ },
59
+ meshConnection: {
60
+ type: "boolean",
61
+ description: "MeshCentral connection status",
62
+ example: true,
63
+ },
64
+ dbConnection: {
65
+ type: "boolean",
66
+ description: "Database connection status",
67
+ example: true,
68
+ },
69
+ },
70
+ required: ["status", "timestamp", "meshConnection", "dbConnection"],
71
+ },
72
+ StatusResponse: {
73
+ type: "object",
74
+ properties: {
75
+ service: {
76
+ type: "string",
77
+ description: "Service name",
78
+ example: "aux-server",
79
+ },
80
+ version: {
81
+ type: "string",
82
+ description: "Service version",
83
+ example: "1.0.0",
84
+ },
85
+ meshCentral: {
86
+ type: "object",
87
+ properties: {
88
+ connected: {
89
+ type: "boolean",
90
+ description: "MeshCentral connection status",
91
+ example: true,
92
+ },
93
+ server: {
94
+ type: "string",
95
+ description: "MeshCentral server URL",
96
+ example: "meshcentral.example.com",
97
+ },
98
+ },
99
+ required: ["connected", "server"],
100
+ },
101
+ database: {
102
+ type: "object",
103
+ properties: {
104
+ connected: {
105
+ type: "boolean",
106
+ description: "Database connection status",
107
+ example: true,
108
+ },
109
+ host: {
110
+ type: "string",
111
+ description: "Database host",
112
+ example: "localhost",
113
+ },
114
+ },
115
+ required: ["connected", "host"],
116
+ },
117
+ uptime: {
118
+ type: "number",
119
+ description: "Server uptime in seconds",
120
+ example: 3600,
121
+ },
122
+ },
123
+ required: ["service", "version", "meshCentral", "database", "uptime"],
124
+ },
125
+ DownloadLinkRequest: {
126
+ type: "object",
127
+ properties: {
128
+ deviceGroupName: {
129
+ type: "string",
130
+ description: "Name of the device group to get download link for (required if deviceGroupId not provided)",
131
+ example: "production-servers",
132
+ },
133
+ deviceGroupId: {
134
+ type: "string",
135
+ description: "ID of the device group to get download link for (required if deviceGroupName not provided)",
136
+ example: "mesh//abc123def456",
137
+ },
138
+ },
139
+ },
140
+ DownloadLinkResponse: {
141
+ type: "object",
142
+ properties: {
143
+ download_link: {
144
+ type: "string",
145
+ format: "uri",
146
+ description: "Download link for the mesh agent",
147
+ example: "https://meshcentral.example.com/meshagents?id=10006&meshid=abc123&ac=02",
148
+ },
149
+ timestamp: {
150
+ type: "string",
151
+ format: "date-time",
152
+ description: "Response timestamp",
153
+ example: "2023-12-01T10:30:00.000Z",
154
+ },
155
+ },
156
+ required: ["download_link", "timestamp"],
157
+ },
158
+ ConnectUrlsRequest: {
159
+ type: "object",
160
+ properties: {
161
+ meshNodeId: {
162
+ type: "string",
163
+ description: "The mesh node ID to connect to",
164
+ example: "node//abc123def456",
165
+ },
166
+ userId: {
167
+ type: "string",
168
+ description: "The user ID for authentication",
169
+ example: "john.doe",
170
+ },
171
+ },
172
+ required: ["meshNodeId", "userId"],
173
+ },
174
+ ConnectUrlsResponse: {
175
+ type: "object",
176
+ properties: {
177
+ control: {
178
+ type: "string",
179
+ format: "uri",
180
+ description: "URL for remote desktop control access",
181
+ example: "https://meshcentral.example.com/?login=token&gotonode=node123&viewmode=11&hide=31",
182
+ },
183
+ terminal: {
184
+ type: "string",
185
+ format: "uri",
186
+ description: "URL for terminal access",
187
+ example: "https://meshcentral.example.com/?login=token&gotonode=node123&viewmode=12&hide=31",
188
+ },
189
+ file_system: {
190
+ type: "string",
191
+ format: "uri",
192
+ description: "URL for file system access",
193
+ example: "https://meshcentral.example.com/?login=token&gotonode=node123&viewmode=13&hide=31",
194
+ },
195
+ timestamp: {
196
+ type: "string",
197
+ format: "date-time",
198
+ description: "Response timestamp",
199
+ example: "2023-12-01T10:30:00.000Z",
200
+ },
201
+ },
202
+ required: ["control", "terminal", "file_system", "timestamp"],
203
+ },
204
+ },
205
+ responses: {
206
+ BadRequest: {
207
+ description: "Bad request - missing or invalid parameters",
208
+ content: {
209
+ "application/json": {
210
+ schema: {
211
+ $ref: "#/components/schemas/ErrorResponse",
212
+ },
213
+ example: {
214
+ error: "'deviceGroupName' body param is required",
215
+ timestamp: "2023-12-01T10:30:00.000Z",
216
+ },
217
+ },
218
+ },
219
+ },
220
+ InternalServerError: {
221
+ description: "Internal server error",
222
+ content: {
223
+ "application/json": {
224
+ schema: {
225
+ $ref: "#/components/schemas/ErrorResponse",
226
+ },
227
+ example: {
228
+ error: "Internal server error",
229
+ timestamp: "2023-12-01T10:30:00.000Z",
230
+ },
231
+ },
232
+ },
233
+ },
234
+ NotFound: {
235
+ description: "Resource not found",
236
+ content: {
237
+ "application/json": {
238
+ schema: {
239
+ $ref: "#/components/schemas/ErrorResponse",
240
+ },
241
+ example: {
242
+ error: "Endpoint not found",
243
+ timestamp: "2023-12-01T10:30:00.000Z",
244
+ },
245
+ },
246
+ },
247
+ },
248
+ },
249
+ },
250
+ tags: [
251
+ {
252
+ name: "Health",
253
+ description: "Health check and status endpoints",
254
+ },
255
+ {
256
+ name: "API",
257
+ description: "Main API endpoints for MeshCentral integration",
258
+ },
259
+ {
260
+ name: "Core",
261
+ description: "Core functionality endpoints for device group management",
262
+ },
263
+ ],
264
+ },
265
+ apis: ["./src/routes/*.ts", "./src/controllers/*.ts"], // Path to the API files
266
+ };
267
+ exports.swaggerSpec = (0, swagger_jsdoc_1.default)(options);
@@ -0,0 +1,16 @@
1
+ import { Pool } from "pg";
2
+ import WebSocket from "ws";
3
+ import { IServiceContainer } from "../services/ServiceContainer";
4
+ import { Config } from "../types";
5
+ import { IWebSocketService } from "../services/WebSocketService";
6
+ export declare abstract class BaseController {
7
+ protected serviceContainer: IServiceContainer;
8
+ constructor(serviceContainer?: IServiceContainer);
9
+ protected get dbPool(): Pool;
10
+ protected get webSocket(): WebSocket | null;
11
+ protected get WebSocketService(): IWebSocketService;
12
+ protected get config(): Config;
13
+ protected get isWebSocketConnected(): boolean;
14
+ protected get meshServer(): string;
15
+ }
16
+ //# sourceMappingURL=BaseController.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"BaseController.d.ts","sourceRoot":"","sources":["../../src/controllers/BaseController.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,IAAI,CAAC;AAC1B,OAAO,SAAS,MAAM,IAAI,CAAC;AAC3B,OAAO,EAEL,iBAAiB,EAClB,MAAM,8BAA8B,CAAC;AACtC,OAAO,EAAE,MAAM,EAAE,MAAM,UAAU,CAAC;AAClC,OAAO,EAAE,iBAAiB,EAAE,MAAM,8BAA8B,CAAC;AAEjE,8BAAsB,cAAc;IAClC,SAAS,CAAC,gBAAgB,EAAE,iBAAiB,CAAC;gBAElC,gBAAgB,CAAC,EAAE,iBAAiB;IAIhD,SAAS,KAAK,MAAM,IAAI,IAAI,CAE3B;IAED,SAAS,KAAK,SAAS,IAAI,SAAS,GAAG,IAAI,CAE1C;IAED,SAAS,KAAK,gBAAgB,IAAI,iBAAiB,CAElD;IAED,SAAS,KAAK,MAAM,IAAI,MAAM,CAE7B;IAED,SAAS,KAAK,oBAAoB,IAAI,OAAO,CAE5C;IAED,SAAS,KAAK,UAAU,IAAI,MAAM,CAEjC;CACF"}
@@ -0,0 +1,28 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.BaseController = void 0;
4
+ const ServiceContainer_1 = require("../services/ServiceContainer");
5
+ class BaseController {
6
+ constructor(serviceContainer) {
7
+ this.serviceContainer = serviceContainer || ServiceContainer_1.ServiceContainer.getInstance();
8
+ }
9
+ get dbPool() {
10
+ return this.serviceContainer.getDatabaseService().getPool();
11
+ }
12
+ get webSocket() {
13
+ return this.serviceContainer.getWebSocketService().getWebSocket();
14
+ }
15
+ get WebSocketService() {
16
+ return this.serviceContainer.getWebSocketService();
17
+ }
18
+ get config() {
19
+ return this.serviceContainer.getConfig();
20
+ }
21
+ get isWebSocketConnected() {
22
+ return this.serviceContainer.getWebSocketService().isConnected();
23
+ }
24
+ get meshServer() {
25
+ return this.config.meshcentralConfig.server;
26
+ }
27
+ }
28
+ exports.BaseController = BaseController;
@@ -0,0 +1,8 @@
1
+ import { Request, Response } from "express";
2
+ import { BaseController } from "./BaseController";
3
+ import { IServiceContainer } from "../services/ServiceContainer";
4
+ export declare class ApiController extends BaseController {
5
+ constructor(serviceContainer?: IServiceContainer);
6
+ getConnectUrls: (req: Request, res: Response) => Promise<void>;
7
+ }
8
+ //# sourceMappingURL=apiController.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"apiController.d.ts","sourceRoot":"","sources":["../../src/controllers/apiController.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;AAE5C,OAAO,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAClD,OAAO,EAAE,iBAAiB,EAAE,MAAM,8BAA8B,CAAC;AAIjE,qBAAa,aAAc,SAAQ,cAAc;gBACnC,gBAAgB,CAAC,EAAE,iBAAiB;IAIzC,cAAc,GACnB,KAAK,OAAO,EACZ,KAAK,QAAQ,KACZ,OAAO,CAAC,IAAI,CAAC,CAgEd;CACH"}
@@ -0,0 +1,60 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.ApiController = void 0;
4
+ const BaseController_1 = require("./BaseController");
5
+ const utils_1 = require("../lib/utils");
6
+ class ApiController extends BaseController_1.BaseController {
7
+ constructor(serviceContainer) {
8
+ super(serviceContainer);
9
+ this.getConnectUrls = async (req, res) => {
10
+ var _a;
11
+ try {
12
+ const meshNodeId = req.body.meshNodeId;
13
+ const userId = req.body.userId;
14
+ if (!meshNodeId || !userId) {
15
+ const errorResponse = {
16
+ error: "'meshNodeId' or 'userId' are missing in body params",
17
+ timestamp: new Date().toISOString(),
18
+ };
19
+ res.status(400).json(errorResponse);
20
+ return;
21
+ }
22
+ const nexus_epm_user_id_query = "SELECT id FROM accounts_user WHERE username= $1";
23
+ const nexus_epm_user_id = await this.dbPool.query(nexus_epm_user_id_query, [userId]);
24
+ if (nexus_epm_user_id.rows.length === 0) {
25
+ const errorResponse = {
26
+ error: `'${userId}' Not Found`,
27
+ timestamp: new Date().toISOString(),
28
+ };
29
+ res.status(400).json(errorResponse);
30
+ return;
31
+ }
32
+ const meshUser = `user//${userId}___${(_a = nexus_epm_user_id.rows[0]) === null || _a === void 0 ? void 0 : _a.id}`;
33
+ const loginEncryptionKey = (0, utils_1.getBinaryKey)(this.config.meshcentralConfig.loginEncryptionKey);
34
+ const authRelayCookie = (0, utils_1.encodeCookie)({ a: 3, u: meshUser }, loginEncryptionKey);
35
+ const token_param = `login=${authRelayCookie}`;
36
+ const control = `https://${this.config.meshcentralConfig.server}/?${token_param}&gotonode=${meshNodeId}&viewmode=11&hide=31`;
37
+ const terminal = `https://${this.config.meshcentralConfig.server}/?${token_param}&gotonode=${meshNodeId}&viewmode=12&hide=31`;
38
+ const fileSystem = `https://${this.config.meshcentralConfig.server}/?${token_param}&gotonode=${meshNodeId}&viewmode=13&hide=31`;
39
+ const response = {
40
+ control,
41
+ terminal,
42
+ file: fileSystem,
43
+ timestamp: new Date().toISOString(),
44
+ };
45
+ res.status(200).json(response);
46
+ return;
47
+ }
48
+ catch (error) {
49
+ console.error("Error generating connect URLs:", error);
50
+ const errorResponse = {
51
+ error: "Internal server error",
52
+ timestamp: new Date().toISOString(),
53
+ };
54
+ res.status(500).json(errorResponse);
55
+ return;
56
+ }
57
+ };
58
+ }
59
+ }
60
+ exports.ApiController = ApiController;