Skip to content
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 3 additions & 5 deletions controllers/impersonationRequests.ts
Original file line number Diff line number Diff line change
Expand Up @@ -37,14 +37,12 @@ export const createImpersonationRequestController = async (
next: NextFunction
): Promise<ImpersonationRequestResponse | void> => {
try {
const { impersonatedUserId, reason } = req.body as CreateImpersonationRequestBody;
const { createdFor, reason } = req.body as CreateImpersonationRequestBody;
const userId = req.userData?.id;
const createdBy = req.userData?.username;

const impersonationRequest = await createImpersonationRequestService({
userId,
createdBy,
impersonatedUserId,
createdBy: userId,
createdFor,
reason
});

Expand Down
6 changes: 3 additions & 3 deletions middlewares/validators/impersonationRequests.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,9 @@ export const createImpersonationRequestValidator = async (
next: NextFunction
): Promise<void> => {
const schema = joi.object().strict().keys({
impersonatedUserId: joi.string().required().messages({
"string.empty": "impersonatedUserId cannot be empty",
"any.required": "impersonatedUserId is required"
createdFor: joi.string().required().messages({
"string.empty": "createdFor cannot be empty",
"any.required": "createdFor is required"
}),
reason: joi.string().required().messages({
"string.empty": "reason cannot be empty",
Expand Down
4 changes: 2 additions & 2 deletions models/impersonationRequests.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,8 +31,8 @@ export const createImpersonationRequest = async (
): Promise<ImpersonationRequest> => {
try {
const reqQuery = impersonationRequestModel
.where("impersonatedUserId", "==", body.impersonatedUserId)
.where("userId", "==", body.userId)
.where("createdFor", "==", body.createdFor)
.where("createdBy", "==", body.createdBy)
.where("status", "in", ["APPROVED", "PENDING"])
.where("isImpersonationFinished", "==", false).orderBy("createdAt", "desc").limit(1);

Expand Down
48 changes: 21 additions & 27 deletions services/impersonationRequests.ts
Original file line number Diff line number Diff line change
Expand Up @@ -41,20 +41,17 @@ export const createImpersonationRequestService = async (
body: CreateImpersonationRequestServiceBody
): Promise<ImpersonationRequest> => {
try {
const { userExists, user: impersonatedUser } = await fetchUser({ userId: body.impersonatedUserId });
const { userExists } = await fetchUser({ userId: body.createdFor });
if (!userExists) {
throw new NotFound(TASK_REQUEST_MESSAGES.USER_NOT_FOUND);
}

const { username: createdFor } = impersonatedUser as User;

const impersonationRequest = await createImpersonationRequest({
status: REQUEST_STATE.PENDING,
userId: body.userId,
impersonatedUserId: body.impersonatedUserId,
isImpersonationFinished: false,
createdBy: body.createdBy,
createdFor: createdFor,
createdFor: body.createdFor,
isImpersonationFinished: false,
reason: body.reason,
});

Expand All @@ -63,7 +60,7 @@ export const createImpersonationRequestService = async (
meta: {
requestId: impersonationRequest.id,
action: LOG_ACTION.CREATE,
userId: body.userId,
userId: body.createdBy,
createdAt: Date.now(),
},
body: {
Expand Down Expand Up @@ -103,7 +100,7 @@ export const updateImpersonationRequestService = async (
throw new NotFound(REQUEST_DOES_NOT_EXIST);
}

if (request.impersonatedUserId !== body.lastModifiedBy || request.status !== REQUEST_STATE.PENDING) {
if (request.createdFor !== body.lastModifiedBy || request.status !== REQUEST_STATE.PENDING) {
throw new Forbidden(OPERATION_NOT_ALLOWED);
}

Expand Down Expand Up @@ -156,7 +153,7 @@ export const startImpersonationService = async (
}

if (
body.userId !== impersonationRequest.userId ||
body.userId !== impersonationRequest.createdBy ||
impersonationRequest.status !== REQUEST_STATE.APPROVED ||
impersonationRequest.isImpersonationFinished === true
) {
Expand Down Expand Up @@ -218,7 +215,7 @@ export const stopImpersonationService = async (
if (!impersonationRequest) {
throw new NotFound(REQUEST_DOES_NOT_EXIST);
}
if ( body.userId !== impersonationRequest.impersonatedUserId ) {
if ( body.userId !== impersonationRequest.createdFor ) {
throw new Forbidden(OPERATION_NOT_ALLOWED);
}

Expand Down Expand Up @@ -267,31 +264,28 @@ export const stopImpersonationService = async (
export const generateImpersonationTokenService = async (
requestId: string,
action: string
): Promise<{ name: string, value: string, options: object }> => {
try {
): Promise<{ name: string; value: string; options: object }> => {
const cookieName = config.get<string>("userToken.cookieName");
const rdsUiUrl = new URL(config.get<string>("services.rdsUi.baseUrl"));
const ttlInSeconds = Number(config.get("userToken.ttl"));
try {
const request = await getImpersonationRequestById(requestId);
if (!request) {
throw new NotFound(REQUEST_DOES_NOT_EXIST);
}

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

let token: string;

switch (action) {
case "START":
token = await authService.generateImpersonationAuthToken({ userId, impersonatedUserId });
break;

case "STOP":
token = await authService.generateAuthToken({ userId });
break;
let token: string;

default:
throw new BadRequest(INVALID_ACTION_PARAM);
if (action === "START") {
token = await authService.generateImpersonationAuthToken({
userId,
impersonatedUserId,
});
} else if (action === "STOP") {
token = await authService.generateAuthToken({ userId });
}

return {
Expand Down
40 changes: 13 additions & 27 deletions test/fixtures/impersonation-requests/impersonationRequests.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,64 +4,50 @@ export const impersonationRequestsBodyData = [
{
status: REQUEST_STATE.PENDING,
isImpersonationFinished: false,
createdBy: "superuser-1",
createdFor: "suvidh-kaushik",
userId: "userId123",
createdBy: "userId123",
reason: "User assistance required for account debugging.",
impersonatedUserId: "userId345",
createdFor: "userId345",
},
{
status: REQUEST_STATE.PENDING,
isImpersonationFinished: false,
createdBy: "superuser-2",
createdFor: "suvidh-kaushik-2",
userId: "userId124",
createdBy: "userId124",
reason: "User assistance required for account debugging.",
impersonatedUserId: "userId445",
createdFor: "userId445",
},
{
status: REQUEST_STATE.PENDING,
isImpersonationFinished: false,
createdBy: "admin222",
createdFor: "user321",
userId: "admin222",
reason: "Investigating bug in user workflow.",
impersonatedUserId: "user321",
createdFor: "user321",
},
{
status: REQUEST_STATE.PENDING,
isImpersonationFinished: false,
createdBy: "adminUsername",
createdFor: "user322",
userId: "admin2223",
createdBy: "admin2223",
reason: "Verifying permissions for support case.",
impersonatedUserId: "user322",
createdFor: "user322",
},
{
status: REQUEST_STATE.PENDING,
isImpersonationFinished: false,
createdBy: "adminUsername",
createdFor: "user321",
userId: "admin222",
createdBy: "admin222",
reason: "Testing impersonation feature for QA.",
impersonatedUserId: "user321",
createdFor: "user321",
},
{
status: REQUEST_STATE.APPROVED,
isImpersonationFinished: false,
createdBy: "approverUser",
createdFor: "approvedUser",
userId: "approverId",
createdBy: "approverId",
reason: "Approved for troubleshooting session.",
impersonatedUserId: "approvedUserId",
createdFor: "approvedUserId",
},
{
status: REQUEST_STATE.REJECTED,
isImpersonationFinished: false,
createdBy: "reviewerUser",
createdFor: "rejectedUser",
userId: "reviewerId",
createdBy: "reviewerId",
reason: "Request rejected due to insufficient details.",
impersonatedUserId: "rejectedUserId",
createdFor: "rejectedUserId",
}
];
Loading
Loading