Skip to content

Commit bf4d3cd

Browse files
removed unused types and fixed authentication middleware jsdoc
1 parent 7e9af53 commit bf4d3cd

File tree

4 files changed

+37
-40
lines changed

4 files changed

+37
-40
lines changed

constants/requests.ts

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -71,9 +71,6 @@ export const UNAUTHORIZED_TO_UPDATE_REQUEST = "Unauthorized to update request";
7171

7272
export const FEATURE_NOT_IMPLEMENTED = "Feature not implemented";
7373

74-
export const IMPERSONATION_NOT_COMPLETED = "Please complete impersonation before creating a new request";
75-
export const IMPERSONATION_ALREADY_ATTEMPTED = "No active request is available for impersonation";
76-
export const IMPERSONATION_REQUEST_NOT_APPROVED = "Awaiting approval for impersonation request";
7774
export const INVALID_ACTION_PARAM = "Invalid 'action' parameter: must be either 'START' or 'STOP'";
7875

7976

middlewares/addAuthorizationForImpersonation.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ import { INVALID_ACTION_PARAM } from "../constants/requests";
77
/**
88
* Middleware to authorize impersonation based on the 'action' query param.
99
* - START → Requires SUPERUSER role.
10-
* - END → Allows without additional checks.
10+
* - STOP → Allows without additional checks.
1111
* - Invalid or missing action → Responds with 400 Bad Request.
1212
*/
1313
export const addAuthorizationForImpersonation = async (

middlewares/authenticate.js

Lines changed: 35 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,19 @@
11
const authService = require("../services/authService");
22
const dataAccess = require("../services/dataAccessLayer");
3+
const logger = require("../utils/logger");
34

45
/**
5-
* Middleware to check if the authenticated user has restricted permissions.
6+
* Middleware to check if the user is restricted or in an impersonation session.
67
*
7-
* - If the user is impersonating, restrict to only `GET` and `PATCH` requests with `action=STOP`.
8-
* - If the user has a `restricted` role, disallow all non-GET requests.
8+
* - If the user is impersonating, only GET requests and the STOP impersonation route are allowed.
9+
* - If the user is restricted (based on roles), only GET requests are permitted.
910
*
10-
* This middleware must be invoked after successful authentication.
11-
*
12-
* @param {Object} req - Express request object. Expects `userData` and `isImpersonating` to be set.
13-
* @param {Object} res - Express response object.
14-
* @param {Function} next - Express next middleware function.
15-
* @returns {Object|void} Responds with `403 Forbidden` if action is not permitted; otherwise calls `next()`.
11+
* @async
12+
* @function checkRestricted
13+
* @param {import('express').Request} req - Express request object
14+
* @param {import('express').Response} res - Express response object
15+
* @param {Function} next - Express next middleware function
16+
* @returns {void}
1617
*/
1718
const checkRestricted = async (req, res, next) => {
1819
const { roles } = req.userData;
@@ -25,7 +26,7 @@ const checkRestricted = async (req, res, next) => {
2526
req.query.action === "STOP";
2627

2728
if (req.method !== "GET" && !isStopImpersonationRoute) {
28-
return res.boom.forbidden("You are not allowed for this operation at the moment");
29+
return res.boom.forbidden("Only viewing is permitted during impersonation");
2930
}
3031
}
3132

@@ -37,39 +38,38 @@ const checkRestricted = async (req, res, next) => {
3738
};
3839

3940
/**
40-
* Authentication Middleware
41-
*
42-
* 1. Verifies the user's JWT (from cookie or Bearer header in non-production).
43-
* 2. If the token is valid, attaches user info to `req.userData`.
44-
* 3. If impersonation is active, uses the impersonated user for `req.userData`.
45-
* 4. If the JWT is expired but within `refreshTtl`, issues a new token and continues.
46-
* 5. Applies role-based restrictions via `checkRestricted()`.
47-
*
48-
* @todo Add test cases to validate JWT refresh logic by simulating token expiry and TTL.
41+
* Authentication middleware that:
42+
* 1. Verifies JWT token from cookies (or headers in non-production).
43+
* 2. Handles impersonation if applicable.
44+
* 3. Refreshes token if it's expired but still within the refresh TTL window.
45+
* 4. Attaches user data to `req.userData` for downstream use.
4946
*
50-
* @param {Object} req - Express request object.
51-
* @param {Object} res - Express response object.
52-
* @param {Function} next - Express next middleware function.
53-
* @returns {Object|void} - Returns `401 Unauthorized` if the user is unauthenticated; otherwise continues to `checkRestricted`.
47+
* @async
48+
* @function
49+
* @param {import('express').Request} req - Express request object
50+
* @param {import('express').Response} res - Express response object
51+
* @param {Function} next - Express next middleware function
52+
* @returns {Promise<void>} - Calls `next()` on successful authentication or returns an error response.
5453
*/
5554
module.exports = async (req, res, next) => {
5655
try {
5756
let token = req.cookies[config.get("userToken.cookieName")];
5857

59-
// Allow Bearer token in non-production (e.g., for Swagger UI)
58+
/**
59+
* Enable Bearer Token authentication for NON-PRODUCTION environments.
60+
* Useful for Swagger or manual testing where cookies are not easily managed.
61+
*/
6062
if (process.env.NODE_ENV !== "production" && !token) {
6163
token = req.headers.authorization?.split(" ")[1];
6264
}
6365

6466
const { userId, impersonatedUserId } = authService.verifyAuthToken(token);
67+
// `req.isImpersonating` keeps track of the impersonation session
6568
req.isImpersonating = Boolean(impersonatedUserId);
6669

67-
let userData;
68-
if (impersonatedUserId) {
69-
userData = await dataAccess.retrieveUsers({ id: impersonatedUserId });
70-
} else {
71-
userData = await dataAccess.retrieveUsers({ id: userId });
72-
}
70+
const userData = impersonatedUserId
71+
? await dataAccess.retrieveUsers({ id: impersonatedUserId })
72+
: await dataAccess.retrieveUsers({ id: userId });
7373

7474
req.userData = userData.user;
7575
return checkRestricted(req, res, next);
@@ -83,7 +83,7 @@ module.exports = async (req, res, next) => {
8383
const newToken = authService.generateAuthToken({ userId });
8484
const rdsUiUrl = new URL(config.get("services.rdsUi.baseUrl"));
8585

86-
// Refresh token if within allowed refresh window
86+
// add new JWT to the response if it satisfies the refreshTtl time
8787
if (Math.floor(Date.now() / 1000) - iat <= refreshTtl) {
8888
res.cookie(config.get("userToken.cookieName"), newToken, {
8989
domain: rdsUiUrl.hostname,
@@ -93,13 +93,13 @@ module.exports = async (req, res, next) => {
9393
sameSite: "lax",
9494
});
9595

96-
req.userData = await dataAccess.retrieveUsers({ id: userId });
96+
const userData = await dataAccess.retrieveUsers({ id: userId });
97+
req.userData = userData.user;
98+
9799
return checkRestricted(req, res, next);
98-
} else {
99-
return res.boom.unauthorized("Unauthenticated User");
100100
}
101-
} else {
102101
return res.boom.unauthorized("Unauthenticated User");
103102
}
103+
return res.boom.unauthorized("Unauthenticated User");
104104
}
105105
};

types/impersonationRequest.d.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -124,7 +124,7 @@ export type CreateImpersonationRequestServiceBody={
124124
}
125125

126126
export type ImpersonationSessionQuery = RequestQuery & {
127-
dev?:string;
127+
dev:string;
128128
action:"START" | "STOP";
129129
}
130130

0 commit comments

Comments
 (0)