Skip to content

Commit 6e8b5be

Browse files
Merge branch 'develop' into feat/add-unverified-role-tracking
2 parents d492a9f + 10bc222 commit 6e8b5be

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

52 files changed

+3065
-95
lines changed

config/custom-environment-variables.js

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,14 @@ module.exports = {
1010
__name: "PORT",
1111
__format: "number",
1212
},
13+
14+
aws: {
15+
region: "AWS_REGION",
16+
access_key: "AWS_ACCESS_KEY",
17+
secret_key: "AWS_SECRET_KEY",
18+
identity_store_id: "IDENTITY_STORE_ID",
19+
},
20+
1321
enableFileLogs: {
1422
__name: "ENABLE_FILE_LOGS",
1523
__format: "boolean",

config/default.js

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,13 @@ module.exports = {
2020
org: "Real-Dev-Squad",
2121
},
2222

23+
aws: {
24+
region: "<aws-region>",
25+
access_key: "<aws-access-key>",
26+
secret_key: "<aws-secret-key>",
27+
identity_store_id: "<identity-store-id>",
28+
},
29+
2330
githubOauth: {
2431
clientId: "<clientId>",
2532
clientSecret: "<clientSecret>",

constants/logs.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ export const logType = {
1616
EXTENSION_REQUESTS: "extensionRequests",
1717
TASK: "task",
1818
TASK_REQUESTS: "taskRequests",
19+
USER_DETAILS_UPDATED: "USER_DETAILS_UPDATED",
1920
...REQUEST_LOG_TYPE,
2021
};
2122

constants/urls.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
export const GITHUB_URL = "https://github.com";
2+
export const PROFILE_SVC_GITHUB_URL = "https://github.com/Real-Dev-Squad/sample-profile-service";
23

34
module.exports = {
45
GITHUB_URL,
6+
PROFILE_SVC_GITHUB_URL,
57
};

constants/userDataLevels.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ const ACCESS_LEVEL = {
77

88
const ROLE_LEVEL = {
99
private: ["super_user"],
10-
internal: ["super_user"],
10+
internal: ["super_user", "cloudfare_worker"],
1111
confidential: ["super_user"],
1212
};
1313

controllers/arts.js

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,10 @@ const getSelfArts = async (req, res) => {
5050
try {
5151
const { id } = req.userData;
5252
const arts = await artsQuery.fetchUserArts(id);
53+
res.set(
54+
"X-Deprecation-Warning",
55+
"WARNING: This endpoint is deprecated and will be removed in the future. Please use /arts/:userId to get the art details."
56+
);
5357
return res.json({
5458
message: "User arts returned successfully!",
5559
arts,
@@ -64,6 +68,11 @@ const getUserArts = async (req, res) => {
6468
try {
6569
const userId = req.params.userId;
6670
const arts = await artsQuery.fetchUserArts(userId);
71+
72+
if (!arts || arts.length === 0) {
73+
return res.status(204).send();
74+
}
75+
6776
return res.json({
6877
message: `User Arts of userId ${userId} returned successfully`,
6978
arts,

controllers/awsAccess.ts

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
import { PROFILE_SVC_GITHUB_URL } from "../constants/urls";
2+
import {addUserToGroup, createUser, fetchAwsUserIdByUsername} from "../utils/awsFunctions";
3+
const dataAccess = require("../services/dataAccessLayer");
4+
const userDataLevels = require('../constants/userDataLevels');
5+
6+
export const addUserToAWSGroup = async (req, res) => {
7+
const { groupId, userId } = req.body;
8+
9+
try {
10+
const userInfoData = await dataAccess.retrieveUsers({ discordId: userId, level: userDataLevels.ACCESS_LEVEL.INTERNAL, role: 'cloudfare_worker'});
11+
if (!userInfoData.userExists) {
12+
return res.status(400).json({ error: "User not found" });
13+
} else if(!userInfoData.user.email) {
14+
return res.status(400).json({ error: `User email is required to create an AWS user. Please update your email by setting up Profile service, url : ${PROFILE_SVC_GITHUB_URL}` });
15+
}
16+
17+
let awsUserId = await fetchAwsUserIdByUsername(userInfoData.user.username);
18+
19+
let userCreationResponse = null;
20+
21+
if (awsUserId === null){
22+
// We need to create the user in AWS before and then fetch its Id
23+
userCreationResponse = await createUser(userInfoData.user.username, userInfoData.user.email);
24+
awsUserId = userCreationResponse.UserId;
25+
}
26+
27+
let userAdditionResponse = await addUserToGroup(groupId, awsUserId)
28+
29+
if (userAdditionResponse){
30+
if (userAdditionResponse.conflict){
31+
return res.status(200).json({
32+
message: `User ${userId} is already part of the AWS group, please try signing in.`
33+
})
34+
} else {
35+
return res.status(200).json({
36+
message: `User ${userId} successfully added to group ${groupId}.`
37+
});
38+
}
39+
}
40+
} catch (error) {
41+
logger.error(`Error in adding user - ${userId} to AWS group - ${groupId} error - ${error}`);
42+
return res.status(500).json({
43+
error: `Something went wrong, please try again`
44+
});
45+
}
46+
};

controllers/discordactions.js

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ const discordRolesModel = require("../models/discordactions");
66
const discordServices = require("../services/discordService");
77
const { fetchAllUsers, fetchUser } = require("../models/users");
88
const { generateCloudFlareHeaders } = require("../utils/discord-actions");
9+
const { addLog } = require("../models/logs");
910
const discordDeveloperRoleId = config.get("discordDeveloperRoleId");
1011
const discordMavenRoleId = config.get("discordMavenRoleId");
1112

@@ -63,6 +64,60 @@ const createGroupRole = async (req, res) => {
6364
}
6465
};
6566

67+
/**
68+
* Controller function to handle the soft deletion of a group role.
69+
*
70+
* @param {Object} req - The request object
71+
* @param {Object} res - The response object
72+
* @returns {Promise<void>}
73+
*/
74+
const deleteGroupRole = async (req, res) => {
75+
const { groupId } = req.params;
76+
77+
try {
78+
const { roleExists, existingRoles } = await discordRolesModel.isGroupRoleExists({ groupId });
79+
80+
if (!roleExists) {
81+
return res.boom.notFound("Group role not found");
82+
}
83+
84+
const roleData = existingRoles.data();
85+
86+
const discordDeletion = await discordServices.deleteGroupRoleFromDiscord(roleData.roleid);
87+
88+
if (!discordDeletion.success) {
89+
return res.boom.badImplementation(discordDeletion.message);
90+
}
91+
92+
const { isSuccess } = await discordRolesModel.deleteGroupRole(groupId, req.userData.id);
93+
94+
if (!isSuccess) {
95+
logger.error(`Role deleted from Discord but failed to delete from database for groupId: ${groupId}`);
96+
return res.boom.badImplementation("Group role deletion failed");
97+
}
98+
99+
const groupDeletionLog = {
100+
type: "group-role-deletion",
101+
meta: {
102+
userId: req.userData.id,
103+
},
104+
body: {
105+
groupId: groupId,
106+
roleName: roleData.rolename,
107+
discordRoleId: roleData.roleid,
108+
action: "delete",
109+
},
110+
};
111+
await addLog(groupDeletionLog.type, groupDeletionLog.meta, groupDeletionLog.body);
112+
return res.status(200).json({
113+
message: "Group role deleted successfully",
114+
});
115+
} catch (error) {
116+
logger.error(`Error while deleting group role: ${error}`);
117+
return res.boom.badImplementation("Internal server error");
118+
}
119+
};
120+
66121
/**
67122
* Gets all group-roles
68123
*
@@ -491,4 +546,5 @@ module.exports = {
491546
setRoleToUsersWith31DaysPlusOnboarding,
492547
getUserDiscordInvite,
493548
generateInviteForUser,
549+
deleteGroupRole,
494550
};

controllers/extensionRequests.js

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -202,12 +202,22 @@ const getSelfExtensionRequests = async (req, res) => {
202202
* @param res {Object} - Express response object
203203
*/
204204
const updateExtensionRequest = async (req, res) => {
205+
const { dev } = req.query;
206+
const isDev = dev === "true";
205207
try {
206208
const extensionRequest = await extensionRequestsQuery.fetchExtensionRequest(req.params.id);
207209
if (!extensionRequest.extensionRequestData) {
208210
return res.boom.notFound("Extension Request not found");
209211
}
210212

213+
if (
214+
isDev &&
215+
!req.userData?.roles.super_user &&
216+
extensionRequest.extensionRequestData.status !== EXTENSION_REQUEST_STATUS.PENDING
217+
) {
218+
return res.boom.badRequest("Only pending extension request can be updated");
219+
}
220+
211221
if (req.body.assignee) {
212222
const { taskData: task } = await tasks.fetchTask(extensionRequest.extensionRequestData.taskId);
213223
if (task.assignee !== (await getUsername(req.body.assignee))) {

controllers/tasks.js

Lines changed: 36 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ const { updateUserStatusOnTaskUpdate, updateStatusOnTaskCompletion } = require("
1313
const dataAccess = require("../services/dataAccessLayer");
1414
const { parseSearchQuery } = require("../utils/tasks");
1515
const { addTaskCreatedAtAndUpdatedAtFields } = require("../services/tasks");
16+
const tasksService = require("../services/tasks");
1617
const { RQLQueryParser } = require("../utils/RQLParser");
1718
const { getMissedProgressUpdatesUsers } = require("../models/discordactions");
1819
const { logType } = require("../constants/logs");
@@ -134,7 +135,19 @@ const fetchPaginatedTasks = async (query) => {
134135

135136
const fetchTasks = async (req, res) => {
136137
try {
137-
const { status, page, size, prev, next, q: queryString, assignee, title, userFeatureFlag } = req.query;
138+
const {
139+
status,
140+
page,
141+
size,
142+
prev,
143+
next,
144+
q: queryString,
145+
assignee,
146+
title,
147+
userFeatureFlag,
148+
orphaned,
149+
dev,
150+
} = req.query;
138151
const transformedQuery = transformQuery(status, size, page, assignee, title);
139152

140153
if (queryString !== undefined) {
@@ -159,6 +172,28 @@ const fetchTasks = async (req, res) => {
159172
});
160173
}
161174

175+
const isOrphaned = orphaned === "true";
176+
const isDev = dev === "true";
177+
if (isOrphaned) {
178+
if (!isDev) {
179+
return res.boom.notFound("Route not found");
180+
}
181+
try {
182+
const orphanedTasks = await tasksService.fetchOrphanedTasks();
183+
if (!orphanedTasks || orphanedTasks.length === 0) {
184+
return res.sendStatus(204);
185+
}
186+
const tasksWithRdsAssigneeInfo = await fetchTasksWithRdsAssigneeInfo(orphanedTasks);
187+
return res.status(200).json({
188+
message: "Orphan tasks fetched successfully",
189+
data: tasksWithRdsAssigneeInfo,
190+
});
191+
} catch (error) {
192+
logger.error("Error in getting tasks which were orphaned", error);
193+
return res.boom.badImplementation(INTERNAL_SERVER_ERROR);
194+
}
195+
}
196+
162197
const paginatedTasks = await fetchPaginatedTasks({ ...transformedQuery, prev, next, userFeatureFlag });
163198
return res.json({
164199
message: "Tasks returned successfully!",

0 commit comments

Comments
 (0)