Skip to content

Commit c17ef9b

Browse files
authored
Merge branch 'Real-Dev-Squad:develop' into develop
2 parents 7d79dd9 + c31d7db commit c17ef9b

File tree

90 files changed

+4929
-194
lines changed

Some content is hidden

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

90 files changed

+4929
-194
lines changed

config/custom-environment-variables.js

Lines changed: 18 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",
@@ -55,6 +63,16 @@ module.exports = {
5563
},
5664
},
5765

66+
emailServiceConfig: {
67+
email: "RDS_EMAIL",
68+
password: "RDS_EMAIL_PASSWORD",
69+
host: "SMTP_HOST",
70+
port: {
71+
__name: "SMTP_PORT",
72+
__format: "number",
73+
},
74+
},
75+
5876
userToken: {
5977
cookieName: "COOKIE_NAME",
6078
ttl: {

config/default.js

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,11 +20,25 @@ 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>",
2633
},
2734

35+
emailServiceConfig: {
36+
email: "<RDS_EMAIL>",
37+
password: "<EMAIL PASSWORD GENERATED AFTER 2FA>",
38+
host: "<smtp host>",
39+
port: "<number>",
40+
},
41+
2842
firestore: `{
2943
"type": "service_account",
3044
"project_id": "<project-name>",

constants/logs.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,9 +10,13 @@ export const logType = {
1010
TASKS_MISSED_UPDATES_ERRORS: "TASKS_MISSED_UPDATES_ERRORS",
1111
DISCORD_INVITES: "DISCORD_INVITES",
1212
EXTERNAL_SERVICE: "EXTERNAL_SERVICE",
13+
ADD_UNVERIFIED_ROLE: "ADD_UNVERIFIED_ROLE",
14+
REMOVE_ROLE_FROM_USER_SUCCESS: "REMOVE_ROLE_FROM_USER_SUCCESS",
15+
REMOVE_ROLE_FROM_USER_FAILED: "REMOVE_ROLE_FROM_USER_FAILED",
1316
EXTENSION_REQUESTS: "extensionRequests",
1417
TASK: "task",
1518
TASK_REQUESTS: "taskRequests",
19+
USER_DETAILS_UPDATED: "USER_DETAILS_UPDATED",
1620
...REQUEST_LOG_TYPE,
1721
};
1822

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
export const emailRegex = /^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$/;
2+
export const phoneNumberRegex = /^[+]{1}(?:[0-9\-\\(\\)\\/.]\s?){6,15}[0-9]{1}$/;

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: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
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+
25+
if (userCreationResponse.conflict){
26+
return res.status(400).json({
27+
error: `Username or Email is already being used, please use another email / username for creating account in AWS`
28+
})
29+
}
30+
awsUserId = userCreationResponse.UserId;
31+
}
32+
33+
let userAdditionResponse = await addUserToGroup(groupId, awsUserId)
34+
35+
if (userAdditionResponse){
36+
if (userAdditionResponse.conflict){
37+
return res.status(200).json({
38+
message: `User ${userId} is already part of the AWS group, please try signing in.`
39+
})
40+
} else {
41+
return res.status(200).json({
42+
message: `User ${userId} successfully added to group ${groupId}.`
43+
});
44+
}
45+
}
46+
} catch (error) {
47+
logger.error(`Error in adding user - ${userId} to AWS group - ${groupId} error - ${error}`);
48+
return res.status(500).json({
49+
error: `Something went wrong, please try again`
50+
});
51+
}
52+
};

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: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -74,7 +74,7 @@ const createTaskExtensionRequest = async (req, res) => {
7474
type: "extensionRequests",
7575
meta: {
7676
taskId: extensionBody.taskId,
77-
createdBy: req.userData.id,
77+
userId: req.userData.id,
7878
},
7979
body: {
8080
extensionRequestId: extensionRequest.id,
@@ -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))) {

0 commit comments

Comments
 (0)