Skip to content

Commit cd129fb

Browse files
refactor: impersonation routes to use userId instead of usernames (#2455)
* fix/removed createdBy and createdFor for filtering and impersonation collection * renamed userId and impersonatedUserId * removed unecessary imports
1 parent e0d7524 commit cd129fb

File tree

10 files changed

+110
-154
lines changed

10 files changed

+110
-154
lines changed

controllers/impersonationRequests.ts

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -37,14 +37,12 @@ export const createImpersonationRequestController = async (
3737
next: NextFunction
3838
): Promise<ImpersonationRequestResponse | void> => {
3939
try {
40-
const { impersonatedUserId, reason } = req.body as CreateImpersonationRequestBody;
40+
const { createdFor, reason } = req.body as CreateImpersonationRequestBody;
4141
const userId = req.userData?.id;
42-
const createdBy = req.userData?.username;
4342

4443
const impersonationRequest = await createImpersonationRequestService({
45-
userId,
46-
createdBy,
47-
impersonatedUserId,
44+
createdBy: userId,
45+
createdFor,
4846
reason
4947
});
5048

middlewares/validators/impersonationRequests.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -17,9 +17,9 @@ export const createImpersonationRequestValidator = async (
1717
next: NextFunction
1818
): Promise<void> => {
1919
const schema = joi.object().strict().keys({
20-
impersonatedUserId: joi.string().required().messages({
21-
"string.empty": "impersonatedUserId cannot be empty",
22-
"any.required": "impersonatedUserId is required"
20+
createdFor: joi.string().required().messages({
21+
"string.empty": "createdFor cannot be empty",
22+
"any.required": "createdFor is required"
2323
}),
2424
reason: joi.string().required().messages({
2525
"string.empty": "reason cannot be empty",

models/impersonationRequests.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -31,8 +31,8 @@ export const createImpersonationRequest = async (
3131
): Promise<ImpersonationRequest> => {
3232
try {
3333
const reqQuery = impersonationRequestModel
34-
.where("impersonatedUserId", "==", body.impersonatedUserId)
35-
.where("userId", "==", body.userId)
34+
.where("createdFor", "==", body.createdFor)
35+
.where("createdBy", "==", body.createdBy)
3636
.where("status", "in", ["APPROVED", "PENDING"])
3737
.where("isImpersonationFinished", "==", false).orderBy("createdAt", "desc").limit(1);
3838

services/impersonationRequests.ts

Lines changed: 21 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -41,20 +41,17 @@ export const createImpersonationRequestService = async (
4141
body: CreateImpersonationRequestServiceBody
4242
): Promise<ImpersonationRequest> => {
4343
try {
44-
const { userExists, user: impersonatedUser } = await fetchUser({ userId: body.impersonatedUserId });
44+
const { userExists } = await fetchUser({ userId: body.createdFor });
4545
if (!userExists) {
4646
throw new NotFound(TASK_REQUEST_MESSAGES.USER_NOT_FOUND);
4747
}
4848

49-
const { username: createdFor } = impersonatedUser as User;
5049

5150
const impersonationRequest = await createImpersonationRequest({
5251
status: REQUEST_STATE.PENDING,
53-
userId: body.userId,
54-
impersonatedUserId: body.impersonatedUserId,
55-
isImpersonationFinished: false,
5652
createdBy: body.createdBy,
57-
createdFor: createdFor,
53+
createdFor: body.createdFor,
54+
isImpersonationFinished: false,
5855
reason: body.reason,
5956
});
6057

@@ -63,7 +60,7 @@ export const createImpersonationRequestService = async (
6360
meta: {
6461
requestId: impersonationRequest.id,
6562
action: LOG_ACTION.CREATE,
66-
userId: body.userId,
63+
userId: body.createdBy,
6764
createdAt: Date.now(),
6865
},
6966
body: {
@@ -103,7 +100,7 @@ export const updateImpersonationRequestService = async (
103100
throw new NotFound(REQUEST_DOES_NOT_EXIST);
104101
}
105102

106-
if (request.impersonatedUserId !== body.lastModifiedBy || request.status !== REQUEST_STATE.PENDING) {
103+
if (request.createdFor !== body.lastModifiedBy || request.status !== REQUEST_STATE.PENDING) {
107104
throw new Forbidden(OPERATION_NOT_ALLOWED);
108105
}
109106

@@ -156,7 +153,7 @@ export const startImpersonationService = async (
156153
}
157154

158155
if (
159-
body.userId !== impersonationRequest.userId ||
156+
body.userId !== impersonationRequest.createdBy ||
160157
impersonationRequest.status !== REQUEST_STATE.APPROVED ||
161158
impersonationRequest.isImpersonationFinished === true
162159
) {
@@ -218,7 +215,7 @@ export const stopImpersonationService = async (
218215
if (!impersonationRequest) {
219216
throw new NotFound(REQUEST_DOES_NOT_EXIST);
220217
}
221-
if ( body.userId !== impersonationRequest.impersonatedUserId ) {
218+
if ( body.userId !== impersonationRequest.createdFor ) {
222219
throw new Forbidden(OPERATION_NOT_ALLOWED);
223220
}
224221

@@ -267,31 +264,28 @@ export const stopImpersonationService = async (
267264
export const generateImpersonationTokenService = async (
268265
requestId: string,
269266
action: string
270-
): Promise<{ name: string, value: string, options: object }> => {
271-
try {
267+
): Promise<{ name: string; value: string; options: object }> => {
268+
const cookieName = config.get<string>("userToken.cookieName");
269+
const rdsUiUrl = new URL(config.get<string>("services.rdsUi.baseUrl"));
270+
const ttlInSeconds = Number(config.get("userToken.ttl"));
271+
try {
272272
const request = await getImpersonationRequestById(requestId);
273273
if (!request) {
274274
throw new NotFound(REQUEST_DOES_NOT_EXIST);
275275
}
276276

277-
const { userId, impersonatedUserId } = request;
278-
const cookieName = config.get<string>("userToken.cookieName");
279-
const rdsUiUrl = new URL(config.get<string>("services.rdsUi.baseUrl"));
280-
const ttlInSeconds = Number(config.get("userToken.ttl"));
277+
const { createdBy: userId, createdFor: impersonatedUserId } = request;
281278

282-
let token: string;
283-
284-
switch (action) {
285-
case "START":
286-
token = await authService.generateImpersonationAuthToken({ userId, impersonatedUserId });
287-
break;
288279

289-
case "STOP":
290-
token = await authService.generateAuthToken({ userId });
291-
break;
280+
let token: string;
292281

293-
default:
294-
throw new BadRequest(INVALID_ACTION_PARAM);
282+
if (action === "START") {
283+
token = await authService.generateImpersonationAuthToken({
284+
userId,
285+
impersonatedUserId,
286+
});
287+
} else if (action === "STOP") {
288+
token = await authService.generateAuthToken({ userId });
295289
}
296290

297291
return {

test/fixtures/impersonation-requests/impersonationRequests.ts

Lines changed: 13 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -4,64 +4,50 @@ export const impersonationRequestsBodyData = [
44
{
55
status: REQUEST_STATE.PENDING,
66
isImpersonationFinished: false,
7-
createdBy: "superuser-1",
8-
createdFor: "suvidh-kaushik",
9-
userId: "userId123",
7+
createdBy: "userId123",
108
reason: "User assistance required for account debugging.",
11-
impersonatedUserId: "userId345",
9+
createdFor: "userId345",
1210
},
1311
{
1412
status: REQUEST_STATE.PENDING,
1513
isImpersonationFinished: false,
16-
createdBy: "superuser-2",
17-
createdFor: "suvidh-kaushik-2",
18-
userId: "userId124",
14+
createdBy: "userId124",
1915
reason: "User assistance required for account debugging.",
20-
impersonatedUserId: "userId445",
16+
createdFor: "userId445",
2117
},
2218
{
2319
status: REQUEST_STATE.PENDING,
2420
isImpersonationFinished: false,
2521
createdBy: "admin222",
26-
createdFor: "user321",
27-
userId: "admin222",
2822
reason: "Investigating bug in user workflow.",
29-
impersonatedUserId: "user321",
23+
createdFor: "user321",
3024
},
3125
{
3226
status: REQUEST_STATE.PENDING,
3327
isImpersonationFinished: false,
34-
createdBy: "adminUsername",
35-
createdFor: "user322",
36-
userId: "admin2223",
28+
createdBy: "admin2223",
3729
reason: "Verifying permissions for support case.",
38-
impersonatedUserId: "user322",
30+
createdFor: "user322",
3931
},
4032
{
4133
status: REQUEST_STATE.PENDING,
4234
isImpersonationFinished: false,
43-
createdBy: "adminUsername",
44-
createdFor: "user321",
45-
userId: "admin222",
35+
createdBy: "admin222",
4636
reason: "Testing impersonation feature for QA.",
47-
impersonatedUserId: "user321",
37+
createdFor: "user321",
4838
},
4939
{
5040
status: REQUEST_STATE.APPROVED,
5141
isImpersonationFinished: false,
52-
createdBy: "approverUser",
53-
createdFor: "approvedUser",
54-
userId: "approverId",
42+
createdBy: "approverId",
5543
reason: "Approved for troubleshooting session.",
56-
impersonatedUserId: "approvedUserId",
44+
createdFor: "approvedUserId",
5745
},
5846
{
5947
status: REQUEST_STATE.REJECTED,
6048
isImpersonationFinished: false,
61-
createdBy: "reviewerUser",
62-
createdFor: "rejectedUser",
63-
userId: "reviewerId",
49+
createdBy: "reviewerId",
6450
reason: "Request rejected due to insufficient details.",
65-
impersonatedUserId: "rejectedUserId",
51+
createdFor: "rejectedUserId",
6652
}
6753
];

0 commit comments

Comments
 (0)