@oas-tools/oas-telemetry 0.7.0-alpha.3 → 0.7.0-alpha.5
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/.env.example +4 -2
- package/README.md +7 -4
- package/dist/cjs/config/config.cjs +7 -5
- package/dist/cjs/routesManager.cjs +36 -48
- package/dist/cjs/telemetry/custom-implementations/exporters/PluginLogExporter.cjs +2 -9
- package/dist/cjs/telemetry/custom-implementations/exporters/PluginMetricExporter.cjs +1 -8
- package/dist/cjs/telemetry/custom-implementations/exporters/PluginSpanExporter.cjs +2 -10
- package/dist/cjs/tlm-auth/authController.cjs +91 -26
- package/dist/cjs/tlm-auth/authMiddleware.cjs +20 -7
- package/dist/cjs/tlm-auth/authRoutes.cjs +3 -2
- package/dist/cjs/tlm-plugin/pluginController.cjs +102 -84
- package/dist/cjs/tlm-plugin/pluginProcess.cjs +108 -0
- package/dist/cjs/tlm-plugin/pluginRoutes.cjs +3 -0
- package/dist/cjs/tlm-plugin/pluginService.cjs +58 -4
- package/dist/esm/config/config.js +4 -2
- package/dist/esm/routesManager.js +37 -49
- package/dist/esm/telemetry/custom-implementations/exporters/PluginLogExporter.js +2 -10
- package/dist/esm/telemetry/custom-implementations/exporters/PluginMetricExporter.js +1 -9
- package/dist/esm/telemetry/custom-implementations/exporters/PluginSpanExporter.js +2 -11
- package/dist/esm/tlm-auth/authController.js +62 -20
- package/dist/esm/tlm-auth/authMiddleware.js +18 -9
- package/dist/esm/tlm-auth/authRoutes.js +4 -3
- package/dist/esm/tlm-plugin/pluginController.js +101 -87
- package/dist/esm/tlm-plugin/pluginProcess.js +101 -0
- package/dist/esm/tlm-plugin/pluginRoutes.js +4 -1
- package/dist/esm/tlm-plugin/pluginService.js +58 -4
- package/dist/types/config/config.d.ts +616 -8
- package/dist/types/tlm-auth/authController.d.ts +2 -1
- package/dist/types/tlm-plugin/pluginController.d.ts +4 -1
- package/dist/types/tlm-plugin/pluginProcess.d.ts +1 -0
- package/dist/types/tlm-plugin/pluginService.d.ts +17 -2
- package/dist/types/types/index.d.ts +14 -5
- package/dist/ui/assets/index-Bgd7fFFH.js +1743 -0
- package/dist/ui/assets/index-Cz3N1n1Q.css +1 -0
- package/dist/ui/index.html +2 -2
- package/package.json +3 -3
- package/dist/ui/assets/index-D9HsRlaQ.js +0 -437
- package/dist/ui/assets/index-DEyIcKBi.css +0 -1
package/.env.example
CHANGED
|
@@ -24,12 +24,14 @@ OASTLM_CONFIG_GENERAL_SPEC_FILE_NAME=
|
|
|
24
24
|
|
|
25
25
|
# Enable authentication | Possible values: "true", "false" | Default: "false"
|
|
26
26
|
OASTLM_CONFIG_AUTH_ENABLED=
|
|
27
|
-
# Maximum age for API keys (ms) | Default: 3600000 (1 hour)
|
|
28
|
-
OASTLM_CONFIG_AUTH_API_KEY_MAX_AGE=
|
|
29
27
|
# Password for authentication | Default: "oas-telemetry-password"
|
|
30
28
|
OASTLM_CONFIG_AUTH_PASSWORD=
|
|
31
29
|
# JWT secret for authentication | Default: "oas-telemetry-secret"
|
|
32
30
|
OASTLM_CONFIG_AUTH_JWT_SECRET=
|
|
31
|
+
# Access token max age (ms) | Default: 300000 (5 minutes)
|
|
32
|
+
OASTLM_CONFIG_AUTH_ACCESS_TOKEN_MAX_AGE=
|
|
33
|
+
# Refresh token max age (ms) | Default: 604800000 (7 days)
|
|
34
|
+
OASTLM_CONFIG_AUTH_REFRESH_TOKEN_MAX_AGE=
|
|
33
35
|
|
|
34
36
|
|
|
35
37
|
# Enable memory exporter for traces | Possible values: "true", "false" | Default: "true"
|
package/README.md
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
# OAS TELEMETRY
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
|
|
4
|
+
**OAS Telemetry** is a library that automatically configures telemetry in your Express application based on OpenAPI, with no extra code required. Simply use the middleware to instantly access endpoints for viewing recent requests, system logs, and metrics—all stored in memory. This allows you to analyze your API’s behavior and debug issues easily, without manual setup or complex integration. OpenTelemetry is used under the hood to collect traces, metrics, and logs.
|
|
4
5
|
|
|
5
6
|
The middleware is highly configurable and supports both **ES Module (ESM)** and **CommonJS (CJS)** formats (ESM targeting **ES2020**). Its functionality can be extended via plugins; see [Telemetry Plugins](#telemetry-plugins) for details.
|
|
6
7
|
|
|
@@ -8,11 +9,13 @@ The middleware is highly configurable and supports both **ES Module (ESM)** and
|
|
|
8
9
|
>
|
|
9
10
|
> **OAS Telemetry** is a functional and working package, but it is currently at version 0 and remains under active development. Features, APIs, and behavior are subject to change at any time. Please review the following current status before use:
|
|
10
11
|
>
|
|
11
|
-
> - **Traces:** Semi-stable. Currently supports HTTP instrumentation.
|
|
12
|
+
> - **Traces:** Semi-stable. Currently supports HTTP instrumentation. We are studying switching to auto-instrumentation, but we need to test memory usage and performance first.
|
|
12
13
|
> - **Logs:** Semi-stable. Supports fast search by message content and Mongo-like search (similar to traces).
|
|
13
|
-
> - **Metrics:**
|
|
14
|
+
> - **Metrics:** Not stable. Currently uses OpenTelemetry host metrics. This area is subject to change to improve memory usage and data handling.
|
|
14
15
|
> - **Configuration:** Semi-stable. All configuration options will be available as parameters at initialization and via environment variables (see the `.env.example` file). The configuration system is under active development and will change significantly in future releases.
|
|
15
|
-
> - **UI:** Not stable. Migration to React is in progress. Most views are placeholders except for the AI agent, which is fully functional and can answer questions about
|
|
16
|
+
> - **UI:** Not stable. Migration to React is in progress. Most views are placeholders except for the AI agent, which is fully functional and can answer questions about traces, and logs (Not yet for metrics). Plugin management page is also functional. Next steps include logs page (almost done) and traces page (subject to change based on instrumentation approach). Metrics page will be the last to be implemented, as we want to support custom metrics in the future.
|
|
17
|
+
>
|
|
18
|
+
> Please if you want to use this package contact us via motero6@us.es
|
|
16
19
|
|
|
17
20
|
## Usage
|
|
18
21
|
|
|
@@ -18,9 +18,10 @@ const loadEnv = () => {
|
|
|
18
18
|
},
|
|
19
19
|
auth: {
|
|
20
20
|
enabled: getParsedEnvVar("OASTLM_CONFIG_AUTH_ENABLED", v => v === "true"),
|
|
21
|
-
apiKeyMaxAge: getParsedEnvVar("OASTLM_CONFIG_AUTH_API_KEY_MAX_AGE", v => parseInt(v, 10)),
|
|
22
21
|
password: getParsedEnvVar("OASTLM_CONFIG_AUTH_PASSWORD"),
|
|
23
|
-
jwtSecret: getParsedEnvVar("OASTLM_CONFIG_AUTH_JWT_SECRET")
|
|
22
|
+
jwtSecret: getParsedEnvVar("OASTLM_CONFIG_AUTH_JWT_SECRET"),
|
|
23
|
+
accessTokenMaxAge: getParsedEnvVar("OASTLM_CONFIG_AUTH_ACCESS_TOKEN_MAX_AGE", v => parseInt(v, 10)),
|
|
24
|
+
refreshTokenMaxAge: getParsedEnvVar("OASTLM_CONFIG_AUTH_REFRESH_TOKEN_MAX_AGE", v => parseInt(v, 10))
|
|
24
25
|
},
|
|
25
26
|
traces: {
|
|
26
27
|
memoryExporter: {
|
|
@@ -70,10 +71,11 @@ const defaultConfig = exports.defaultConfig = {
|
|
|
70
71
|
},
|
|
71
72
|
auth: {
|
|
72
73
|
enabled: false,
|
|
73
|
-
apiKeyMaxAge: 1000 * 60 * 60,
|
|
74
|
-
// 1 hour
|
|
75
74
|
password: "oas-telemetry-password",
|
|
76
|
-
jwtSecret: "oas-telemetry-secret"
|
|
75
|
+
jwtSecret: "oas-telemetry-secret",
|
|
76
|
+
accessTokenMaxAge: 1000 * 60 * 5,
|
|
77
|
+
// 5 minutes
|
|
78
|
+
refreshTokenMaxAge: 1000 * 60 * 60 * 24 * 7 // 7 days
|
|
77
79
|
},
|
|
78
80
|
ai: {
|
|
79
81
|
openAIKey: null,
|
|
@@ -23,13 +23,21 @@ const configureRoutes = (router, oasTlmConfig) => {
|
|
|
23
23
|
if (_bootConfig.bootEnvVariables.OASTLM_BOOT_ENV === 'development') {
|
|
24
24
|
_logger.default.info("Running in development mode, enabling CORS for all origins");
|
|
25
25
|
router.use((0, _cors.default)({
|
|
26
|
-
origin:
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
26
|
+
origin: (origin, callback) => {
|
|
27
|
+
if (!origin || /^http:\/\/localhost:\d+$/.test(origin)) {
|
|
28
|
+
callback(null, true);
|
|
29
|
+
} else {
|
|
30
|
+
callback(new Error('Not allowed by CORS'));
|
|
31
|
+
}
|
|
32
|
+
},
|
|
33
|
+
credentials: true
|
|
30
34
|
}));
|
|
31
35
|
}
|
|
32
|
-
|
|
36
|
+
const telemetryBaseUrl = oasTlmConfig.general.baseUrl;
|
|
37
|
+
// Sub-router for all telemetry endpoints
|
|
38
|
+
const telemetryRouter = (0, _express.Router)();
|
|
39
|
+
// Body parser for JSON requests
|
|
40
|
+
telemetryRouter.use((req, res, next) => {
|
|
33
41
|
if (req.body !== undefined) {
|
|
34
42
|
return next(); // Already parsed, no need to parse again.
|
|
35
43
|
}
|
|
@@ -37,52 +45,32 @@ const configureRoutes = (router, oasTlmConfig) => {
|
|
|
37
45
|
limit: '10mb'
|
|
38
46
|
})(req, res, next);
|
|
39
47
|
});
|
|
40
|
-
|
|
41
|
-
const baseUrl = oasTlmConfig.general.baseUrl;
|
|
42
|
-
router.use(baseUrl, allAuthMiddlewares);
|
|
43
|
-
router.use(baseUrl + "/traces", (0, _traceRoutes.getTraceRoutes)());
|
|
44
|
-
router.use(baseUrl + "/metrics", (0, _metricsRoutes.getMetricsRoutes)());
|
|
45
|
-
router.use(baseUrl + "/logs", (0, _logRoutes.getLogRoutes)());
|
|
46
|
-
router.use(baseUrl + "/ai", getWrappedMiddlewares(() => oasTlmConfig.ai.openAIKey !== null, [(0, _aiRoutes.getAIRoutes)(oasTlmConfig)]));
|
|
47
|
-
// WARNING: This path must be the same as the one used in the UI package App.tsx "oas-telemetry-ui"
|
|
48
|
-
router.use(baseUrl + "/oas-telemetry-ui", (0, _uiRoutes.getUIRoutes)());
|
|
49
|
-
router.use(baseUrl + "/utils", (0, _utilRoutes.getUtilsRoutes)(oasTlmConfig));
|
|
50
|
-
router.use(baseUrl + "/plugins", (0, _pluginRoutes.getPluginRoutes)());
|
|
51
|
-
router.get(baseUrl + '/health', (_req, res) => {
|
|
48
|
+
telemetryRouter.get('/health', (_req, res) => {
|
|
52
49
|
res.status(200).send({
|
|
53
50
|
status: 'OK'
|
|
54
51
|
});
|
|
55
52
|
});
|
|
56
|
-
//
|
|
57
|
-
|
|
58
|
-
res.redirect(
|
|
53
|
+
// Redirect to the UI when accessing the base URL
|
|
54
|
+
telemetryRouter.get('/', (req, res) => {
|
|
55
|
+
res.redirect(`${telemetryBaseUrl}/oas-telemetry-ui/`);
|
|
59
56
|
});
|
|
57
|
+
// WARNING: This path must be the same as the one used in the UI package App.tsx "oas-telemetry-ui"
|
|
58
|
+
telemetryRouter.use("/oas-telemetry-ui", (0, _uiRoutes.getUIRoutes)());
|
|
59
|
+
// Auth routes must be registered. If authentication is not enabled, all requests will be allowed.
|
|
60
|
+
// Frontend will use these endpoints;
|
|
61
|
+
telemetryRouter.use((0, _cookieParser.default)());
|
|
62
|
+
// Refresh token uses /auth/refresh path, careful if you change it
|
|
63
|
+
telemetryRouter.use('/auth', (0, _authRoutes.getAuthRoutes)(oasTlmConfig));
|
|
64
|
+
telemetryRouter.use((0, _authMiddleware.getAuthMiddleware)(oasTlmConfig));
|
|
65
|
+
telemetryRouter.use("/traces", (0, _traceRoutes.getTraceRoutes)());
|
|
66
|
+
telemetryRouter.use("/metrics", (0, _metricsRoutes.getMetricsRoutes)());
|
|
67
|
+
telemetryRouter.use("/logs", (0, _logRoutes.getLogRoutes)());
|
|
68
|
+
if (oasTlmConfig.ai.openAIKey) {
|
|
69
|
+
telemetryRouter.use("/ai", (0, _aiRoutes.getAIRoutes)(oasTlmConfig));
|
|
70
|
+
}
|
|
71
|
+
telemetryRouter.use("/utils", (0, _utilRoutes.getUtilsRoutes)(oasTlmConfig));
|
|
72
|
+
telemetryRouter.use("/plugins", (0, _pluginRoutes.getPluginRoutes)());
|
|
73
|
+
// Mount the telemetryRouter under telemetryBaseUrl
|
|
74
|
+
router.use(telemetryBaseUrl, telemetryRouter);
|
|
60
75
|
};
|
|
61
|
-
|
|
62
|
-
* This function wraps the provided middleware functions with a condition callback.
|
|
63
|
-
* If the condition callback returns true, the middleware/router will be executed.
|
|
64
|
-
* If the condition callback returns false, the middleware/router will be skipped.
|
|
65
|
-
*
|
|
66
|
-
* @callback {function} conditionCallback A callback function that returns a boolean to determine if the middleware should be used.
|
|
67
|
-
* @param {Array} middlewares An array of middleware or routers to be wrapped.
|
|
68
|
-
* @returns {Array} An array of wrapped middleware functions.
|
|
69
|
-
*/
|
|
70
|
-
exports.configureRoutes = configureRoutes;
|
|
71
|
-
function getWrappedMiddlewares(conditionCallback, middlewares) {
|
|
72
|
-
return middlewares.map(middleware => {
|
|
73
|
-
return function (req, res, next) {
|
|
74
|
-
if (conditionCallback()) {
|
|
75
|
-
if (typeof middleware === 'function') {
|
|
76
|
-
// look for handle property, if it exists, it's a router. If not call middleware
|
|
77
|
-
if (middleware.handle) {
|
|
78
|
-
middleware.handle(req, res, next);
|
|
79
|
-
} else {
|
|
80
|
-
middleware(req, res, next);
|
|
81
|
-
}
|
|
82
|
-
}
|
|
83
|
-
} else {
|
|
84
|
-
next();
|
|
85
|
-
}
|
|
86
|
-
};
|
|
87
|
-
});
|
|
88
|
-
}
|
|
76
|
+
exports.configureRoutes = configureRoutes;
|
|
@@ -24,15 +24,8 @@ class PluginLogExporter extends _wrappers.Enabler {
|
|
|
24
24
|
});
|
|
25
25
|
}
|
|
26
26
|
const cleanLogs = logs.map(log => (0, _circular.removeCircularRefs)(log)).map(log => (0, _circular.applyNesting)(log));
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
cleanLogs.forEach(log => {
|
|
30
|
-
_logger.default.debug(`Sending log to plugin (Plugin #${i}) <${pluginResource.name}>`);
|
|
31
|
-
pluginResource.pluginImplementation.newLog(log);
|
|
32
|
-
});
|
|
33
|
-
} else {
|
|
34
|
-
_logger.default.debug(`Plugin <${pluginResource.name}> does not implement newLog method. Skipping log export.`);
|
|
35
|
-
}
|
|
27
|
+
cleanLogs.forEach(log => {
|
|
28
|
+
_pluginService.pluginService.broadcastLog(log);
|
|
36
29
|
});
|
|
37
30
|
setTimeout(() => resultCallback({
|
|
38
31
|
code: _core.ExportResultCode.SUCCESS
|
|
@@ -24,14 +24,7 @@ class PluginMetricExporter extends _wrappers.Enabler {
|
|
|
24
24
|
});
|
|
25
25
|
}
|
|
26
26
|
const cleanMetrics = (0, _circular.applyNesting)((0, _circular.removeCircularRefs)(metrics));
|
|
27
|
-
_pluginService.pluginService.
|
|
28
|
-
if (typeof pluginResource.pluginImplementation.newMetric === 'function') {
|
|
29
|
-
_logger.default.debug(`Sending metric to plugin (Plugin #${i}) <${pluginResource.name}>`);
|
|
30
|
-
pluginResource.pluginImplementation.newMetric(cleanMetrics);
|
|
31
|
-
} else {
|
|
32
|
-
_logger.default.debug(`Plugin <${pluginResource.name}> does not implement newMetric method. Skipping metric export.`);
|
|
33
|
-
}
|
|
34
|
-
});
|
|
27
|
+
_pluginService.pluginService.broadcastMetric(cleanMetrics);
|
|
35
28
|
setTimeout(() => resultCallback({
|
|
36
29
|
code: _core.ExportResultCode.SUCCESS
|
|
37
30
|
}), 0);
|
|
@@ -37,16 +37,8 @@ class PluginSpanExporter extends _wrappers.Enabler {
|
|
|
37
37
|
}
|
|
38
38
|
return true;
|
|
39
39
|
});
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
cleanSpans.forEach(span => {
|
|
43
|
-
_logger.default.debug(`Sending span to plugin (Plugin #${i}) <${pluginResource.name}>`);
|
|
44
|
-
//TODO: This should be called newSpan instead of newTrace
|
|
45
|
-
pluginResource.pluginImplementation.newTrace(span);
|
|
46
|
-
});
|
|
47
|
-
} else {
|
|
48
|
-
_logger.default.debug(`Plugin <${pluginResource.name}> does not implement newTrace method. Skipping span export.`);
|
|
49
|
-
}
|
|
40
|
+
cleanSpans.forEach(span => {
|
|
41
|
+
_pluginService.pluginService.broadcastTrace(span);
|
|
50
42
|
});
|
|
51
43
|
setTimeout(() => resultCallback({
|
|
52
44
|
code: _core.ExportResultCode.SUCCESS
|
|
@@ -3,69 +3,134 @@
|
|
|
3
3
|
Object.defineProperty(exports, "__esModule", {
|
|
4
4
|
value: true
|
|
5
5
|
});
|
|
6
|
-
exports.getLogout = exports.getLogin = exports.
|
|
6
|
+
exports.getRefresh = exports.getLogout = exports.getLogin = exports.getAuthEnabled = void 0;
|
|
7
7
|
var _jsonwebtoken = _interopRequireDefault(require("jsonwebtoken"));
|
|
8
8
|
var _logger = _interopRequireDefault(require("../utils/logger.cjs"));
|
|
9
9
|
function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
|
|
10
|
+
function generateAccessToken(secret, expiresIn) {
|
|
11
|
+
return _jsonwebtoken.default.sign({
|
|
12
|
+
type: "access"
|
|
13
|
+
}, secret, {
|
|
14
|
+
expiresIn: Math.floor(expiresIn / 1000)
|
|
15
|
+
});
|
|
16
|
+
}
|
|
17
|
+
function generateRefreshToken(secret, expiresIn) {
|
|
18
|
+
return _jsonwebtoken.default.sign({
|
|
19
|
+
type: "refresh"
|
|
20
|
+
}, secret, {
|
|
21
|
+
expiresIn: Math.floor(expiresIn / 1000)
|
|
22
|
+
});
|
|
23
|
+
}
|
|
10
24
|
const getLogin = oasTlmConfig => (req, res) => {
|
|
25
|
+
if (!oasTlmConfig.auth.enabled) {
|
|
26
|
+
res.status(200).json({
|
|
27
|
+
valid: true,
|
|
28
|
+
message: "Auth disabled"
|
|
29
|
+
});
|
|
30
|
+
return;
|
|
31
|
+
}
|
|
11
32
|
try {
|
|
12
33
|
const {
|
|
13
34
|
password
|
|
14
35
|
} = req.body;
|
|
15
36
|
if (password === oasTlmConfig.auth.password) {
|
|
16
|
-
const
|
|
17
|
-
|
|
37
|
+
const accessToken = generateAccessToken(oasTlmConfig.auth.jwtSecret, oasTlmConfig.auth.accessTokenMaxAge);
|
|
38
|
+
const refreshToken = generateRefreshToken(oasTlmConfig.auth.jwtSecret, oasTlmConfig.auth.refreshTokenMaxAge);
|
|
39
|
+
res.cookie("accessToken", accessToken, {
|
|
40
|
+
maxAge: oasTlmConfig.auth.accessTokenMaxAge,
|
|
18
41
|
httpOnly: true,
|
|
19
|
-
secure:
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
42
|
+
secure: process.env.NODE_ENV === "production",
|
|
43
|
+
sameSite: "lax",
|
|
44
|
+
path: "/"
|
|
45
|
+
});
|
|
46
|
+
res.cookie("refreshToken", refreshToken, {
|
|
47
|
+
maxAge: oasTlmConfig.auth.refreshTokenMaxAge,
|
|
48
|
+
httpOnly: true,
|
|
49
|
+
secure: process.env.NODE_ENV === "production",
|
|
50
|
+
sameSite: "lax",
|
|
51
|
+
path: oasTlmConfig.general.baseUrl + "/auth/refresh" // <-- cambiado de "/auth/refresh" a oasTlmConfig.general.baseUrl + "/auth/refresh"
|
|
52
|
+
});
|
|
26
53
|
res.status(200).json({
|
|
27
54
|
valid: true,
|
|
28
|
-
message:
|
|
55
|
+
message: "Login successful"
|
|
29
56
|
});
|
|
30
57
|
return;
|
|
31
58
|
}
|
|
32
59
|
res.status(400).json({
|
|
33
60
|
valid: false,
|
|
34
|
-
message:
|
|
61
|
+
message: "Invalid password"
|
|
35
62
|
});
|
|
36
63
|
} catch (error) {
|
|
37
|
-
_logger.default.
|
|
64
|
+
_logger.default.error("Login error: ", error);
|
|
38
65
|
res.status(500).json({
|
|
39
66
|
valid: false,
|
|
40
|
-
message:
|
|
67
|
+
message: "Internal server error"
|
|
41
68
|
});
|
|
42
69
|
}
|
|
43
70
|
};
|
|
44
71
|
exports.getLogin = getLogin;
|
|
45
72
|
const getLogout = oasTlmConfig => (req, res) => {
|
|
46
|
-
|
|
47
|
-
|
|
73
|
+
if (!oasTlmConfig.auth.enabled) {
|
|
74
|
+
res.status(200).json({
|
|
75
|
+
valid: true,
|
|
76
|
+
message: "Auth disabled"
|
|
77
|
+
});
|
|
78
|
+
return;
|
|
79
|
+
}
|
|
80
|
+
res.clearCookie('accessToken', {
|
|
81
|
+
path: '/'
|
|
82
|
+
});
|
|
83
|
+
res.clearCookie('refreshToken', {
|
|
84
|
+
path: oasTlmConfig.general.baseUrl + '/auth/refresh'
|
|
85
|
+
}); // <-- cambiado de "/auth/refresh" a oasTlmConfig.general.baseUrl + "/auth/refresh"
|
|
86
|
+
res.status(200).json({
|
|
87
|
+
valid: true,
|
|
88
|
+
message: "Logged out"
|
|
89
|
+
});
|
|
48
90
|
};
|
|
49
91
|
exports.getLogout = getLogout;
|
|
50
|
-
const
|
|
51
|
-
if (!
|
|
92
|
+
const getRefresh = oasTlmConfig => (req, res) => {
|
|
93
|
+
if (!oasTlmConfig.auth.enabled) {
|
|
52
94
|
res.status(200).json({
|
|
95
|
+
valid: true,
|
|
96
|
+
message: "Auth disabled"
|
|
97
|
+
});
|
|
98
|
+
return;
|
|
99
|
+
}
|
|
100
|
+
const refreshToken = req.cookies.refreshToken;
|
|
101
|
+
if (!refreshToken) {
|
|
102
|
+
res.status(401).json({
|
|
53
103
|
valid: false,
|
|
54
|
-
message:
|
|
104
|
+
message: "No refresh token"
|
|
55
105
|
});
|
|
56
106
|
return;
|
|
57
107
|
}
|
|
58
|
-
|
|
59
|
-
|
|
108
|
+
try {
|
|
109
|
+
const payload = _jsonwebtoken.default.verify(refreshToken, oasTlmConfig.auth.jwtSecret);
|
|
110
|
+
if (payload.type !== "refresh") throw new Error("Invalid token type");
|
|
111
|
+
const accessToken = generateAccessToken(oasTlmConfig.auth.jwtSecret, oasTlmConfig.auth.accessTokenMaxAge);
|
|
112
|
+
res.cookie("accessToken", accessToken, {
|
|
113
|
+
maxAge: oasTlmConfig.auth.accessTokenMaxAge,
|
|
114
|
+
httpOnly: true,
|
|
115
|
+
secure: process.env.NODE_ENV === "production",
|
|
116
|
+
sameSite: "lax",
|
|
117
|
+
path: "/"
|
|
118
|
+
});
|
|
60
119
|
res.status(200).json({
|
|
61
120
|
valid: true,
|
|
62
|
-
message:
|
|
121
|
+
message: "Refreshed"
|
|
122
|
+
});
|
|
123
|
+
} catch (err) {
|
|
124
|
+
res.status(401).json({
|
|
125
|
+
valid: false,
|
|
126
|
+
message: "Invalid refresh token"
|
|
63
127
|
});
|
|
64
|
-
return;
|
|
65
128
|
}
|
|
129
|
+
};
|
|
130
|
+
exports.getRefresh = getRefresh;
|
|
131
|
+
const getAuthEnabled = oasTlmConfig => (req, res) => {
|
|
66
132
|
res.status(200).json({
|
|
67
|
-
|
|
68
|
-
message: 'Invalid API Key'
|
|
133
|
+
enabled: !!oasTlmConfig.auth.enabled
|
|
69
134
|
});
|
|
70
135
|
};
|
|
71
|
-
exports.
|
|
136
|
+
exports.getAuthEnabled = getAuthEnabled;
|
|
@@ -8,13 +8,26 @@ var _jsonwebtoken = _interopRequireDefault(require("jsonwebtoken"));
|
|
|
8
8
|
function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
|
|
9
9
|
function getAuthMiddleware(oasTlmConfig) {
|
|
10
10
|
return function authMiddleware(req, res, next) {
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
11
|
+
if (!oasTlmConfig.auth.enabled) {
|
|
12
|
+
return next();
|
|
13
|
+
}
|
|
14
|
+
const token = req.cookies.accessToken;
|
|
15
|
+
if (!token) {
|
|
16
|
+
res.status(401).json({
|
|
17
|
+
valid: false,
|
|
18
|
+
message: "No access token"
|
|
19
|
+
});
|
|
20
|
+
return;
|
|
21
|
+
}
|
|
22
|
+
try {
|
|
23
|
+
const payload = _jsonwebtoken.default.verify(token, oasTlmConfig.auth.jwtSecret);
|
|
24
|
+
if (payload.type !== "access") throw new Error("Invalid token type");
|
|
25
|
+
return next();
|
|
26
|
+
} catch {
|
|
27
|
+
res.status(401).json({
|
|
28
|
+
valid: false,
|
|
29
|
+
message: "Invalid access token"
|
|
30
|
+
});
|
|
17
31
|
}
|
|
18
|
-
res.status(401).redirect(oasTlmConfig.general.baseUrl + oasTlmConfig.general.uiPath + '/login');
|
|
19
32
|
};
|
|
20
33
|
}
|
|
@@ -9,8 +9,9 @@ var _authController = require("./authController.cjs");
|
|
|
9
9
|
const getAuthRoutes = oasTlmConfig => {
|
|
10
10
|
const router = (0, _express.Router)();
|
|
11
11
|
router.post('/login', (0, _authController.getLogin)(oasTlmConfig));
|
|
12
|
-
router.
|
|
13
|
-
router.
|
|
12
|
+
router.post('/refresh', (0, _authController.getRefresh)(oasTlmConfig));
|
|
13
|
+
router.post('/logout', (0, _authController.getLogout)(oasTlmConfig));
|
|
14
|
+
router.get('/enabled', (0, _authController.getAuthEnabled)(oasTlmConfig));
|
|
14
15
|
return router;
|
|
15
16
|
};
|
|
16
17
|
exports.getAuthRoutes = getAuthRoutes;
|