@oas-tools/oas-telemetry 0.3.0 → 0.5.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 +0 -0
- package/README.md +151 -133
- package/dist/client.cjs +14 -0
- package/dist/config.cjs +27 -0
- package/dist/controllers/pluginController.cjs +118 -0
- package/dist/controllers/telemetryController.cjs +92 -0
- package/dist/controllers/uiController.cjs +78 -0
- package/dist/exporters/InMemoryDbExporter.cjs +45 -42
- package/dist/exporters/consoleExporter.cjs +52 -0
- package/dist/exporters/dynamicExporter.cjs +64 -0
- package/dist/index.cjs +61 -248
- package/dist/middleware/auth.cjs +17 -0
- package/dist/middleware/authMiddleware.cjs +19 -0
- package/dist/openTelemetry.cjs +20 -0
- package/dist/routes/authRoutes.cjs +79 -0
- package/dist/routes/telemetryRoutes.cjs +31 -0
- package/{src/ui.js → dist/services/uiService.cjs} +1140 -813
- package/dist/telemetry.cjs +0 -0
- package/dist/types/exporters/InMemoryDbExporter.d.ts +16 -0
- package/dist/types/index.d.ts +1 -0
- package/dist/types/telemetry.d.ts +2 -0
- package/dist/types/ui.d.ts +4 -0
- package/dist/ui.cjs +0 -0
- package/package.json +75 -71
- package/src/config.js +19 -0
- package/src/controllers/pluginController.js +115 -0
- package/src/controllers/telemetryController.js +68 -0
- package/src/controllers/uiController.js +69 -0
- package/src/dev/ui/login.html +32 -0
- package/src/exporters/InMemoryDbExporter.js +180 -175
- package/src/exporters/consoleExporter.js +47 -0
- package/src/exporters/dynamicExporter.js +62 -0
- package/src/index.js +85 -307
- package/src/middleware/authMiddleware.js +14 -0
- package/src/openTelemetry.js +22 -0
- package/src/routes/authRoutes.js +53 -0
- package/src/routes/telemetryRoutes.js +38 -0
- package/src/services/uiService.js +1520 -0
- package/src/telemetry.js +0 -25
package/src/index.js
CHANGED
|
@@ -1,307 +1,85 @@
|
|
|
1
|
-
|
|
2
|
-
import {
|
|
3
|
-
import
|
|
4
|
-
import
|
|
5
|
-
import {
|
|
6
|
-
import
|
|
7
|
-
import
|
|
8
|
-
import
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
if (
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
router.
|
|
58
|
-
router.
|
|
59
|
-
router.
|
|
60
|
-
router.
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
router
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
}
|
|
87
|
-
|
|
88
|
-
const mainPage = (req, res) => {
|
|
89
|
-
res.set('Content-Type', 'text/html');
|
|
90
|
-
res.send(ui().main);
|
|
91
|
-
}
|
|
92
|
-
const detailPage = (req, res) => {
|
|
93
|
-
res.set('Content-Type', 'text/html');
|
|
94
|
-
res.send(ui().detail);
|
|
95
|
-
}
|
|
96
|
-
|
|
97
|
-
const specLoader = (req, res) => {
|
|
98
|
-
if (telemetryConfig.specFileName) {
|
|
99
|
-
try {
|
|
100
|
-
const data = readFileSync(telemetryConfig.specFileName,
|
|
101
|
-
{ encoding: 'utf8', flag: 'r' });
|
|
102
|
-
|
|
103
|
-
const extension = path.extname(telemetryConfig.specFileName);
|
|
104
|
-
|
|
105
|
-
let json = data;
|
|
106
|
-
|
|
107
|
-
if (extension == yaml)
|
|
108
|
-
json = JSON.stringify(yaml.SafeLoad(data), null, 2);
|
|
109
|
-
|
|
110
|
-
res.setHeader('Content-Type', 'application/json');
|
|
111
|
-
res.send(json);
|
|
112
|
-
|
|
113
|
-
} catch (e) {
|
|
114
|
-
console.error(`ERROR loading spec file ${telemetryConfig.specFileName}: ${e}`)
|
|
115
|
-
}
|
|
116
|
-
} else {
|
|
117
|
-
if (telemetryConfig.spec) {
|
|
118
|
-
let spec = false;
|
|
119
|
-
|
|
120
|
-
try {
|
|
121
|
-
spec = JSON.parse(telemetryConfig.spec);
|
|
122
|
-
} catch (ej) {
|
|
123
|
-
try {
|
|
124
|
-
spec = JSON.stringify(yaml.load(telemetryConfig.spec), null, 2);
|
|
125
|
-
} catch (ey) {
|
|
126
|
-
console.error(`Error parsing spec: ${ej} - ${ey}`);
|
|
127
|
-
}
|
|
128
|
-
}
|
|
129
|
-
|
|
130
|
-
if (!spec) {
|
|
131
|
-
res.status(404);
|
|
132
|
-
} else {
|
|
133
|
-
res.setHeader('Content-Type', 'application/json');
|
|
134
|
-
res.send(spec);
|
|
135
|
-
}
|
|
136
|
-
|
|
137
|
-
}
|
|
138
|
-
}
|
|
139
|
-
}
|
|
140
|
-
|
|
141
|
-
const startTelemetry = (req, res) => {
|
|
142
|
-
telemetryConfig.exporter.start();
|
|
143
|
-
res.send('Telemetry started');
|
|
144
|
-
}
|
|
145
|
-
const stopTelemetry = (req, res) => {
|
|
146
|
-
telemetryConfig.exporter.stop();
|
|
147
|
-
|
|
148
|
-
res.send('Telemetry stopped');
|
|
149
|
-
}
|
|
150
|
-
const statusTelemetry = (req, res) => {
|
|
151
|
-
const status = !telemetryConfig.exporter._stopped || false;
|
|
152
|
-
res.send({ active: status });
|
|
153
|
-
}
|
|
154
|
-
|
|
155
|
-
const resetTelemetry = (req, res) => {
|
|
156
|
-
telemetryConfig.exporter.reset();
|
|
157
|
-
res.send('Telemetry reset');
|
|
158
|
-
}
|
|
159
|
-
const listTelemetry = (req, res) => {
|
|
160
|
-
const spansDB = telemetryConfig.exporter.getFinishedSpans();
|
|
161
|
-
spansDB.find({}, (err, docs) => {
|
|
162
|
-
if (err) {
|
|
163
|
-
console.error(err);
|
|
164
|
-
return;
|
|
165
|
-
}
|
|
166
|
-
const spans = docs;
|
|
167
|
-
res.send({ spansCount: spans.length, spans: spans });
|
|
168
|
-
});
|
|
169
|
-
}
|
|
170
|
-
|
|
171
|
-
const heapStats = (req, res) => {
|
|
172
|
-
var heapStats = v8.getHeapStatistics();
|
|
173
|
-
|
|
174
|
-
// Round stats to MB
|
|
175
|
-
var roundedHeapStats = Object.getOwnPropertyNames(heapStats).reduce(function (map, stat) {
|
|
176
|
-
map[stat] = Math.round((heapStats[stat] / 1024 / 1024) * 1000) / 1000;
|
|
177
|
-
return map;
|
|
178
|
-
}, {});
|
|
179
|
-
roundedHeapStats['units'] = 'MB';
|
|
180
|
-
|
|
181
|
-
res.send(roundedHeapStats);
|
|
182
|
-
}
|
|
183
|
-
|
|
184
|
-
const findTelemetry = (req, res) => {
|
|
185
|
-
const spansDB = telemetryConfig.exporter.getFinishedSpans();
|
|
186
|
-
const body = req.body;
|
|
187
|
-
const search = body?.search ? body.search : {};
|
|
188
|
-
if (body?.flags?.containsRegex) {
|
|
189
|
-
try {
|
|
190
|
-
body.config?.regexIds?.forEach(regexId => {
|
|
191
|
-
search[regexId] = new RegExp(search[regexId]);
|
|
192
|
-
});
|
|
193
|
-
} catch (e) {
|
|
194
|
-
console.error(e);
|
|
195
|
-
res.status(404).send({ spansCount: 0, spans: [], error: e });
|
|
196
|
-
return;
|
|
197
|
-
}
|
|
198
|
-
spansDB.find(search, (err, docs) => {
|
|
199
|
-
if (err) {
|
|
200
|
-
console.error(err);
|
|
201
|
-
res.status(404).send({ spansCount: 0, spans: [], error: err });
|
|
202
|
-
return;
|
|
203
|
-
}
|
|
204
|
-
|
|
205
|
-
const spans = docs;
|
|
206
|
-
res.send({ spansCount: spans.length, spans: spans });
|
|
207
|
-
});
|
|
208
|
-
}
|
|
209
|
-
}
|
|
210
|
-
|
|
211
|
-
const listPlugins = (req, res) => {
|
|
212
|
-
res.send(plugins.map((p) => {
|
|
213
|
-
return {
|
|
214
|
-
id: p.id,
|
|
215
|
-
url: p.url,
|
|
216
|
-
active: p.active
|
|
217
|
-
};
|
|
218
|
-
}));
|
|
219
|
-
}
|
|
220
|
-
|
|
221
|
-
const registerPlugin = async (req, res) => {
|
|
222
|
-
let pluginResource = req.body;
|
|
223
|
-
dbglog(`Plugin Registration Request: = ${JSON.stringify(req.body, null, 2)}...`);
|
|
224
|
-
dbglog(`Getting plugin at ${pluginResource.url}...`);
|
|
225
|
-
let pluginCode;
|
|
226
|
-
if (!pluginResource.url && !pluginResource.code) {
|
|
227
|
-
res.status(400).send(`Plugin code or URL must be provided`);
|
|
228
|
-
return;
|
|
229
|
-
}
|
|
230
|
-
|
|
231
|
-
let module;
|
|
232
|
-
try {
|
|
233
|
-
if (pluginResource.code) {
|
|
234
|
-
pluginCode = pluginResource.code
|
|
235
|
-
} else {
|
|
236
|
-
const response = await axios.get(pluginResource.url);
|
|
237
|
-
pluginCode = response.data;
|
|
238
|
-
}
|
|
239
|
-
if (!pluginCode) {
|
|
240
|
-
res.status(400).send(`Plugin code could not be loaded`);
|
|
241
|
-
return;
|
|
242
|
-
}
|
|
243
|
-
//install dependencies if any
|
|
244
|
-
if (pluginResource.install) {
|
|
245
|
-
const dependenciesStatus = await installDependencies(pluginResource.install);
|
|
246
|
-
if (!dependenciesStatus.success) {
|
|
247
|
-
if (pluginResource.install.ignoreErrors === true) {
|
|
248
|
-
console.warn(`Warning: Error installing dependencies: ${JSON.stringify(dependenciesStatus.details)}`);
|
|
249
|
-
} else {
|
|
250
|
-
res.status(400).send(`Error installing dependencies: ${JSON.stringify(dependenciesStatus.details)}`);
|
|
251
|
-
return;
|
|
252
|
-
}
|
|
253
|
-
}
|
|
254
|
-
}
|
|
255
|
-
|
|
256
|
-
dbglog("Plugin size: " + pluginCode?.length);
|
|
257
|
-
if (pluginResource?.moduleFormat && pluginResource.moduleFormat.toUpperCase() == "ESM") {
|
|
258
|
-
console.log("ESM detected")
|
|
259
|
-
module = await importFromString(pluginCode)
|
|
260
|
-
} else {
|
|
261
|
-
console.log("CJS detected (default)")
|
|
262
|
-
module = await requireFromString(pluginCode)
|
|
263
|
-
console.log(module)
|
|
264
|
-
}
|
|
265
|
-
} catch (error) {
|
|
266
|
-
console.error(`Error loading plugin: ${error}`);
|
|
267
|
-
res.status(400).send(`Error loading plugin: ${error}`);
|
|
268
|
-
return;
|
|
269
|
-
}
|
|
270
|
-
|
|
271
|
-
if (module.plugin == undefined) {
|
|
272
|
-
res.status(400).send(`Plugin code should export a "plugin" object`);
|
|
273
|
-
console.log("Error in plugin code: no plugin object exported")
|
|
274
|
-
return;
|
|
275
|
-
}
|
|
276
|
-
for (let requiredFunction of ["load", "getName", "isConfigured"]) {
|
|
277
|
-
if (module.plugin[requiredFunction] == undefined) {
|
|
278
|
-
res.status(400).send(`The plugin code exports a "plugin" object, however it should have a "${requiredFunction}" method`);
|
|
279
|
-
console.log("Error in plugin code: some required functions are missing")
|
|
280
|
-
return;
|
|
281
|
-
}
|
|
282
|
-
}
|
|
283
|
-
|
|
284
|
-
let plugin = module.plugin
|
|
285
|
-
try {
|
|
286
|
-
await plugin.load(pluginResource.config);
|
|
287
|
-
} catch (error) {
|
|
288
|
-
console.error(`Error loading plugin configuration: ${error}`);
|
|
289
|
-
res.status(400).send(`Error loading plugin configuration: ${error}`);
|
|
290
|
-
return;
|
|
291
|
-
}
|
|
292
|
-
if (plugin.isConfigured()) {
|
|
293
|
-
dbglog(`Loaded plugin <${plugin.getName()}>`);
|
|
294
|
-
pluginResource.plugin = plugin;
|
|
295
|
-
pluginResource.name = plugin.getName();
|
|
296
|
-
pluginResource.active = true;
|
|
297
|
-
plugins.push(pluginResource);
|
|
298
|
-
inMemoryExporter.activatePlugin(pluginResource.plugin);
|
|
299
|
-
res.status(201).send(`Plugin registered`);
|
|
300
|
-
} else {
|
|
301
|
-
console.error(`Plugin <${plugin.getName()}> can not be configured`);
|
|
302
|
-
res.status(400).send(`Plugin configuration problem`);
|
|
303
|
-
}
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
}
|
|
307
|
-
|
|
1
|
+
import './openTelemetry.js';
|
|
2
|
+
import { globalOasTlmConfig } from './config.js';
|
|
3
|
+
import cookieParser from 'cookie-parser';
|
|
4
|
+
import { Router, json } from 'express';
|
|
5
|
+
import { authMiddleware } from './middleware/authMiddleware.js';
|
|
6
|
+
import authRoutes from './routes/authRoutes.js';
|
|
7
|
+
import { telemetryRoutes } from './routes/telemetryRoutes.js';
|
|
8
|
+
import { InMemoryExporter } from './exporters/InMemoryDbExporter.js';
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
let dbglog = () => { };
|
|
12
|
+
|
|
13
|
+
if (process.env.OTDEBUG == "true")
|
|
14
|
+
dbglog = console.log;
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* Returns the Oas Telemetry middleware. The parameters are the same as `globalOasTlmConfig`.
|
|
18
|
+
* All parameters are optional. However, either `spec` or `specFileName` must be provided to enable endpoint filtering.
|
|
19
|
+
*
|
|
20
|
+
* @param {Object} OasTlmConfig Configuration object.
|
|
21
|
+
* @param {string} [OasTlmConfig.baseURL="/telemetry"] The base URL for the telemetry routes.
|
|
22
|
+
* @param {Object} [OasTlmConfig.spec] The OpenAPI spec object.
|
|
23
|
+
* @param {string} [OasTlmConfig.specFileName] Alternative to `spec`: the path to the OpenAPI spec file.
|
|
24
|
+
* @param {boolean} [OasTlmConfig.autoActivate=true] Whether to start telemetry automatically on load.
|
|
25
|
+
* @param {number} [OasTlmConfig.apiKeyMaxAge=1800000] The maximum age of the API key in milliseconds.
|
|
26
|
+
* @param {string} [OasTlmConfig.defaultApiKey] The default API key to use.
|
|
27
|
+
* @param {OasTlmExporter} [OasTlmConfig.exporter=InMemoryExporter] The exporter to use. Must implement the `OasTlmExporter` interface.
|
|
28
|
+
* @returns {Router} The middleware router for Oas Telemetry.
|
|
29
|
+
*/
|
|
30
|
+
export default function oasTelemetry(OasTlmConfig) {
|
|
31
|
+
const router = Router();
|
|
32
|
+
if (process.env.OASTLM_MODULE_DISABLED === 'true') {
|
|
33
|
+
return router;
|
|
34
|
+
};
|
|
35
|
+
if (OasTlmConfig) {
|
|
36
|
+
console.log("User provided config");
|
|
37
|
+
// Global = user-provided || default, for each key
|
|
38
|
+
for (const key in globalOasTlmConfig) {
|
|
39
|
+
globalOasTlmConfig[key] = OasTlmConfig[key] ?? globalOasTlmConfig[key];
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
console.log("baseURL: ", globalOasTlmConfig.baseURL);
|
|
43
|
+
globalOasTlmConfig.dynamicExporter.changeExporter( OasTlmConfig.exporter ?? new InMemoryExporter() );
|
|
44
|
+
|
|
45
|
+
if (globalOasTlmConfig.spec)
|
|
46
|
+
dbglog(`Spec content provided`);
|
|
47
|
+
else {
|
|
48
|
+
if (globalOasTlmConfig.specFileName != "")
|
|
49
|
+
dbglog(`Spec file used for telemetry: ${globalOasTlmConfig.specFileName}`);
|
|
50
|
+
else {
|
|
51
|
+
console.error("No spec available !");
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
router.use(cookieParser());
|
|
56
|
+
const baseURL = globalOasTlmConfig.baseURL;
|
|
57
|
+
router.use(json());
|
|
58
|
+
router.use(baseURL, authRoutes);
|
|
59
|
+
router.use(baseURL, authMiddleware); // Add the auth middleware
|
|
60
|
+
router.use(baseURL, telemetryRoutes);
|
|
61
|
+
|
|
62
|
+
if (globalOasTlmConfig.autoActivate) {
|
|
63
|
+
globalOasTlmConfig.dynamicExporter.exporter?.start();
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
return router;
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
|
|
70
|
+
|
|
71
|
+
/**
|
|
72
|
+
* @typedef OasTlmExporter
|
|
73
|
+
* Represents an exporter that processes and manages telemetry data.
|
|
74
|
+
* Any custom exporter must implement these methods.
|
|
75
|
+
*
|
|
76
|
+
* @method {void} start() Starts the exporter, allowing it to process data.
|
|
77
|
+
* @method {void} stop() Stops the exporter and halts data processing.
|
|
78
|
+
* @method {void} reset() Resets the internal state of the exporter (e.g., clears buffers or data stores).
|
|
79
|
+
* @method {boolean} isRunning() Returns whether the exporter is actively processing data.
|
|
80
|
+
* @method {Array} getFinishedSpans() Retrieves the collected spans from the exporter.
|
|
81
|
+
* @method {any} export(ReadableSpan, SpanExporterResultCallback) Exports spans.
|
|
82
|
+
* @method {Promise<void>} shutdown() Gracefully shuts down the exporter, flushing data if necessary.
|
|
83
|
+
* @method {Promise<void>} forceFlush() Exports any pending data that has not yet been processed.
|
|
84
|
+
* @property {Array} plugins An array of plugins that can be activated by the exporter.
|
|
85
|
+
*/
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { globalOasTlmConfig } from "../config.js";
|
|
2
|
+
import jwt from 'jsonwebtoken';
|
|
3
|
+
|
|
4
|
+
export function authMiddleware(req, res, next) {
|
|
5
|
+
const apiKey = req.cookies.apiKey;
|
|
6
|
+
if (apiKey) {
|
|
7
|
+
const decoded = jwt.verify(apiKey, globalOasTlmConfig.jwtSecret);
|
|
8
|
+
if (decoded.password === globalOasTlmConfig.password) {
|
|
9
|
+
return next();
|
|
10
|
+
}
|
|
11
|
+
}
|
|
12
|
+
res.status(401).redirect(globalOasTlmConfig.baseURL + '/login');
|
|
13
|
+
|
|
14
|
+
}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
|
|
2
|
+
import { NodeSDK } from '@opentelemetry/sdk-node';
|
|
3
|
+
// import { getNodeAutoInstrumentations } from '@opentelemetry/auto-instrumentations-node';
|
|
4
|
+
import { Resource } from '@opentelemetry/resources';
|
|
5
|
+
import { HttpInstrumentation } from '@opentelemetry/instrumentation-http';
|
|
6
|
+
import { globalOasTlmConfig } from './config.js';
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
// DynamicExporter allows changing to any exporter at runtime;
|
|
10
|
+
const traceExporter = globalOasTlmConfig.dynamicExporter;
|
|
11
|
+
|
|
12
|
+
const sdk = new NodeSDK({
|
|
13
|
+
resource: new Resource({
|
|
14
|
+
service: 'oas-telemetry-service'
|
|
15
|
+
}),
|
|
16
|
+
traceExporter,
|
|
17
|
+
instrumentations: [new HttpInstrumentation()]
|
|
18
|
+
});
|
|
19
|
+
|
|
20
|
+
if (process.env.OASTLM_MODULE_DISABLED !== 'true') {
|
|
21
|
+
sdk.start()
|
|
22
|
+
}
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import { globalOasTlmConfig } from '../config.js';
|
|
2
|
+
import { Router } from 'express';
|
|
3
|
+
import { serialize } from 'cookie';
|
|
4
|
+
import ui from '../services/uiService.js';
|
|
5
|
+
import jwt from 'jsonwebtoken';
|
|
6
|
+
|
|
7
|
+
const router = Router();
|
|
8
|
+
|
|
9
|
+
router.post('/login', (req, res) => {
|
|
10
|
+
try {
|
|
11
|
+
const { password } = req.body;
|
|
12
|
+
if (password === globalOasTlmConfig.password) {
|
|
13
|
+
let options = {
|
|
14
|
+
maxAge: globalOasTlmConfig.apiKeyMaxAge,
|
|
15
|
+
httpOnly: true, // The cookie only accessible by the web server
|
|
16
|
+
secure: true, // Only sends cookie over https
|
|
17
|
+
signed: false // Indicates if the cookie should be signed
|
|
18
|
+
}
|
|
19
|
+
const apiKey = jwt.sign({ password: globalOasTlmConfig.password }, globalOasTlmConfig.jwtSecret);
|
|
20
|
+
res.cookie('apiKey', apiKey, options);
|
|
21
|
+
return res.status(200).json({ valid: true, message: 'API Key is valid' });
|
|
22
|
+
}
|
|
23
|
+
res.status(400).json({ valid: false, message: 'Invalid API Key' });
|
|
24
|
+
|
|
25
|
+
} catch (error) {
|
|
26
|
+
console.log("Error: ", error);
|
|
27
|
+
res.status(500).json({ valid: false, message: 'Internal server error' });
|
|
28
|
+
}
|
|
29
|
+
});
|
|
30
|
+
|
|
31
|
+
router.get('/logout', (req, res) => {
|
|
32
|
+
res.clearCookie('apiKey');
|
|
33
|
+
res.redirect(globalOasTlmConfig.baseURL + '/login');
|
|
34
|
+
});
|
|
35
|
+
|
|
36
|
+
//check is used in the UI (http polling) to validate the Cookies to redirect to the login page if needed
|
|
37
|
+
router.get('/check', (req, res) => {
|
|
38
|
+
if (!req.cookies.apiKey) {
|
|
39
|
+
return res.status(200).json({ valid: false, message: 'API Key is invalid' });
|
|
40
|
+
}
|
|
41
|
+
const decoded = jwt.verify(req.cookies.apiKey, globalOasTlmConfig.jwtSecret);
|
|
42
|
+
if (decoded.password === globalOasTlmConfig.password) {
|
|
43
|
+
return res.status(200).json({ valid: true, message: 'API Key is valid' });
|
|
44
|
+
}
|
|
45
|
+
res.status(200).json({ valid: false, message: 'Invalid API Key' });
|
|
46
|
+
});
|
|
47
|
+
|
|
48
|
+
router.get('/login', (req, res) => {
|
|
49
|
+
const baseURL = globalOasTlmConfig.baseURL;
|
|
50
|
+
res.send(ui(baseURL).login);
|
|
51
|
+
});
|
|
52
|
+
|
|
53
|
+
export default router;
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import { Router } from 'express';
|
|
2
|
+
import { mainPage, detailPage , specLoader, apiPage} from '../controllers/uiController.js';
|
|
3
|
+
import {
|
|
4
|
+
startTelemetry,
|
|
5
|
+
stopTelemetry,
|
|
6
|
+
statusTelemetry,
|
|
7
|
+
resetTelemetry,
|
|
8
|
+
listTelemetry,
|
|
9
|
+
heapStats,
|
|
10
|
+
findTelemetry
|
|
11
|
+
} from '../controllers/telemetryController.js';
|
|
12
|
+
import { listPlugins, registerPlugin } from '../controllers/pluginController.js';
|
|
13
|
+
|
|
14
|
+
export const telemetryRoutes = Router();
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
// Main Pages
|
|
20
|
+
telemetryRoutes.get('/', mainPage);
|
|
21
|
+
telemetryRoutes.get('/detail/*', detailPage);
|
|
22
|
+
telemetryRoutes.get('/spec', specLoader);
|
|
23
|
+
telemetryRoutes.get('/api', apiPage);
|
|
24
|
+
|
|
25
|
+
// Telemetry Control
|
|
26
|
+
telemetryRoutes.get('/start', startTelemetry);
|
|
27
|
+
telemetryRoutes.get('/stop', stopTelemetry);
|
|
28
|
+
telemetryRoutes.get('/status', statusTelemetry);
|
|
29
|
+
telemetryRoutes.get('/reset', resetTelemetry);
|
|
30
|
+
telemetryRoutes.get('/list', listTelemetry);
|
|
31
|
+
telemetryRoutes.post('/find', findTelemetry);
|
|
32
|
+
telemetryRoutes.get('/heapStats', heapStats);
|
|
33
|
+
|
|
34
|
+
// Plugins
|
|
35
|
+
telemetryRoutes.get('/plugins', listPlugins);
|
|
36
|
+
telemetryRoutes.post('/plugins', registerPlugin);
|
|
37
|
+
|
|
38
|
+
export default telemetryRoutes;
|