Skip to content

Commit 4d0f239

Browse files
committed
Merge branch 'develop' into feat/progress-api-tests
2 parents bc5badc + 3451f24 commit 4d0f239

22 files changed

+635
-25
lines changed

config/custom-environment-variables.js

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,10 @@ module.exports = {
4242
authRedirection: "SERVICES_RDSUI_ROUTES_AUTH_REDIRECTION",
4343
},
4444
},
45+
46+
discordBot: {
47+
baseUrl: "DISCORD_BASE_URL",
48+
},
4549
},
4650

4751
userToken: {
@@ -62,6 +66,11 @@ module.exports = {
6266
botPublicKey: "BOT_PUBLIC_KEY",
6367
},
6468

69+
rdsServerlessBot: {
70+
rdsServerLessPrivateKey: "RDS_SERVERLESS_PRIVATE_KEY",
71+
ttl: "RDS_SERVERLESS_TTL",
72+
},
73+
6574
cloudinary: {
6675
cloud_name: "CLOUDINARY_CLOUD_NAME",
6776
api_key: "CLOUDINARY_API_KEY",

config/default.js

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,11 @@ module.exports = {
7878
CLOUDFLARE_X_AUTH_EMAIL: "Cloudflare_User_Email",
7979
},
8080

81+
rdsServerlessBot: {
82+
rdsServerLessPrivateKey: "RDS_SERVERLESS_PRIVATE_KEY",
83+
ttl: 60,
84+
},
85+
8186
integrations: {
8287
newrelic: {
8388
appName: "RDS_API_production",

config/test.js

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,9 @@ module.exports = {
3030
rdsApi: {
3131
baseUrl: `http://localhost:${port}`,
3232
},
33+
discordBot: {
34+
baseUrl: "DISCORD_BASE_URL",
35+
},
3336
},
3437

3538
cors: {
@@ -102,4 +105,10 @@ module.exports = {
102105
"Ba+XMCP64pXPC3r1llhKRwIl+6UFn+QlpbxtgQjhbULnSbc7fw==\n" +
103106
"-----END RSA PRIVATE KEY-----",
104107
},
108+
109+
rdsServerlessBot: {
110+
rdsServerLessPublicKey: "RSA PUBLIC KEY",
111+
rdsServerLessPrivateKey: "RSA PRIVATE KEY",
112+
ttl: 60,
113+
},
105114
};

controllers/discordactions.js

Lines changed: 129 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,129 @@
1+
const { INTERNAL_SERVER_ERROR } = require("../constants/errorMessages");
2+
const admin = require("firebase-admin");
3+
const config = require("config");
4+
const jwt = require("jsonwebtoken");
5+
const discordRolesModel = require("../models/discordactions");
6+
7+
/**
8+
* Creates a role
9+
*
10+
* @param req {Object} - Express request object
11+
* @param res {Object} - Express response object
12+
*/
13+
14+
const DISCORD_BASE_URL = config.get("services.discordBot.baseUrl");
15+
16+
const createGroupRole = async (req, res) => {
17+
try {
18+
const rolename = `group-${req.body.rolename}`;
19+
20+
const { wasSuccess } = await discordRolesModel.isGroupRoleExists(rolename);
21+
22+
if (!wasSuccess) {
23+
return res.status(400).json({
24+
message: "Role already exists!",
25+
});
26+
}
27+
const dataForDiscord = {
28+
rolename,
29+
mentionable: true,
30+
};
31+
const groupRoleData = {
32+
rolename,
33+
createdBy: req.userData.id,
34+
date: admin.firestore.Timestamp.fromDate(new Date()),
35+
};
36+
const authToken = jwt.sign({}, config.get("rdsServerlessBot.rdsServerLessPrivateKey"), {
37+
algorithm: "RS256",
38+
expiresIn: config.get("rdsServerlessBot.ttl"),
39+
});
40+
41+
const responseForCreatedRole = await fetch(`${DISCORD_BASE_URL}/roles/create`, {
42+
method: "PUT",
43+
body: JSON.stringify(dataForDiscord),
44+
headers: { "Content-Type": "application/json", Authorization: `Bearer ${authToken}` },
45+
}).then((response) => response.json());
46+
47+
groupRoleData.roleid = responseForCreatedRole.id;
48+
49+
const { id } = await discordRolesModel.createNewRole(groupRoleData);
50+
return res.status(201).json({
51+
message: "Role created successfully!",
52+
id,
53+
});
54+
} catch (err) {
55+
logger.error(`Error while creating new Role: ${err}`);
56+
return res.boom.badImplementation(INTERNAL_SERVER_ERROR);
57+
}
58+
};
59+
60+
/**
61+
* Gets all group-roles
62+
*
63+
* @param res {Object} - Express response object
64+
*/
65+
66+
const getAllGroupRoles = async (req, res) => {
67+
try {
68+
const { groups } = await discordRolesModel.getAllGroupRoles();
69+
return res.json({
70+
message: "Roles fetched successfully!",
71+
groups,
72+
});
73+
} catch (err) {
74+
logger.error(`Error while getting roles: ${err}`);
75+
return res.boom.badImplementation(INTERNAL_SERVER_ERROR);
76+
}
77+
};
78+
79+
/**
80+
* Gets all group-roles
81+
* @param req {Object} - Express request object
82+
* @param res {Object} - Express response object
83+
*/
84+
85+
const addGroupRoleToMember = async (req, res) => {
86+
try {
87+
const memberGroupRole = {
88+
...req.body,
89+
date: admin.firestore.Timestamp.fromDate(new Date()),
90+
};
91+
92+
const { roleData, wasSuccess } = await discordRolesModel.addGroupRoleToMember(memberGroupRole);
93+
94+
if (!wasSuccess) {
95+
return res.status(400).json({
96+
message: "Role already exists!",
97+
data: {
98+
...roleData,
99+
},
100+
});
101+
}
102+
const dataForDiscord = {
103+
...req.body,
104+
};
105+
const authToken = jwt.sign({}, config.get("rdsServerlessBot.rdsServerLessPrivateKey"), {
106+
algorithm: "RS256",
107+
expiresIn: config.get("rdsServerlessBot.ttl"),
108+
});
109+
110+
await fetch(`${DISCORD_BASE_URL}/roles/add`, {
111+
method: "PUT",
112+
body: JSON.stringify(dataForDiscord),
113+
headers: { "Content-Type": "application/json", Authorization: `Bearer ${authToken}` },
114+
}).then((response) => response.json());
115+
116+
return res.status(201).json({
117+
message: "Role added successfully!",
118+
});
119+
} catch (err) {
120+
logger.error(`Error while adding new Role: ${err}`);
121+
return res.boom.badImplementation(INTERNAL_SERVER_ERROR);
122+
}
123+
};
124+
125+
module.exports = {
126+
createGroupRole,
127+
getAllGroupRoles,
128+
addGroupRoleToMember,
129+
};

controllers/issues.js

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,15 @@ const { SOMETHING_WENT_WRONG } = require("../constants/errorMessages");
1010

1111
const getIssues = async (req, res) => {
1212
try {
13-
const issues = await issuesService.getOrgIssues();
13+
const { q: queryString } = req.query;
14+
let issues = {};
15+
if (queryString) {
16+
const searchedIssues = await issuesService.searchOrgIssues(queryString);
17+
issues.data = searchedIssues?.data?.items ?? [];
18+
} else {
19+
issues = await issuesService.getOrgIssues();
20+
}
21+
1422
let issuesData = issues.data.length > 0 ? issues.data : [];
1523
issuesData = issuesData.filter((issue) => !Object.keys(issue).includes("pull_request"));
1624
issuesData = issuesData.map(async (issue) => {

controllers/users.js

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -73,13 +73,13 @@ const getUsers = async (req, res) => {
7373
if (qualifiers?.filterBy) {
7474
const allPRs = await getFilteredPRsOrIssues(qualifiers);
7575

76-
const filteredUsernames = getUsernamesFromPRs(allPRs);
76+
const usernames = getUsernamesFromPRs(allPRs);
7777

78-
const { filterdUsersWithDetails } = await userQuery.fetchUsers(filteredUsernames);
78+
const { users } = await userQuery.fetchUsers(usernames);
7979

8080
return res.json({
8181
message: "Users returned successfully!",
82-
users: filterdUsersWithDetails,
82+
users,
8383
});
8484
}
8585

@@ -449,12 +449,12 @@ const filterUsers = async (req, res) => {
449449
if (!Object.keys(req.query).length) {
450450
return res.boom.badRequest("filter for item not provided");
451451
}
452-
const allUsers = await userQuery.getUsersBasedOnFilter(req.query);
452+
const users = await userQuery.getUsersBasedOnFilter(req.query);
453453

454454
return res.json({
455-
message: "Users found successfully!",
456-
users: allUsers,
457-
count: allUsers.length,
455+
message: users.length ? "Users found successfully!" : "No users found",
456+
users,
457+
count: users.length,
458458
});
459459
} catch (error) {
460460
logger.error(`Error while fetching all users: ${error}`);
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
const Joi = require("joi");
2+
3+
const validateGroupRoleBody = async (req, res, next) => {
4+
const schema = Joi.object({
5+
rolename: Joi.string().trim().required(),
6+
});
7+
8+
try {
9+
await schema.validateAsync(req.body);
10+
next();
11+
} catch (error) {
12+
logger.error(`Error validating createGroupRole payload : ${error}`);
13+
res.boom.badRequest(error.details[0].message);
14+
}
15+
};
16+
const validateMemberRoleBody = async (req, res, next) => {
17+
const schema = Joi.object({
18+
userid: Joi.string().trim().required(),
19+
roleid: Joi.string().trim().required(),
20+
});
21+
22+
try {
23+
await schema.validateAsync(req.body);
24+
next();
25+
} catch (error) {
26+
logger.error(`Error validating member role payload : ${error}`);
27+
res.boom.badRequest(error.details[0].message);
28+
}
29+
};
30+
31+
module.exports = {
32+
validateGroupRoleBody,
33+
validateMemberRoleBody,
34+
};

middlewares/validators/tasks.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@ const createTask = async (req, res, next) => {
4242
})
4343
.optional(),
4444
isNoteworthy: joi.bool().optional(),
45+
isCollapsed: joi.bool().optional(),
4546
github: joi
4647
.object()
4748
.keys({
@@ -101,6 +102,7 @@ const updateTask = async (req, res, next) => {
101102
})
102103
.optional(),
103104
isNoteworthy: joi.bool().optional(),
105+
isCollapsed: joi.bool().optional(),
104106
});
105107
try {
106108
await schema.validateAsync(req.body);

middlewares/validators/user.js

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -172,14 +172,17 @@ async function validateUserQueryParams(req, res, next) {
172172
joi.array().items(joi.string().valid("IDLE", "OOO", "ACTIVE"))
173173
)
174174
.optional(),
175+
})
176+
.messages({
177+
"object.min": "Please provide at least one filter criteria",
175178
});
176179

177180
try {
178181
await schema.validateAsync(req.query);
179182
next();
180183
} catch (error) {
181184
logger.error(`Error validating query params : ${error}`);
182-
res.boom.badRequest(error.details[0].message);
185+
res.boom.badRequest(error);
183186
}
184187
}
185188

middlewares/verifydiscord.js

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
/**
2+
* Middleware to check if the user has verified themself with the discord bot.
3+
* If user has not verified, then no actions based on discord bot should be allowed.
4+
* Note: This requires that user is authenticated hence must be called after
5+
* the user authentication middleware. We are calling it from within the
6+
* `authenticate` middleware itself to avoid explicitly adding this middleware
7+
* while defining routes.
8+
*
9+
* @param {Object} req - Express request object
10+
* @param {Object} res - Express response object
11+
* @param {Function} next - Express middleware function
12+
* @returns {Object} - Returns unauthorized object if user has been restricted.
13+
*/
14+
const checkIsVerifiedDiscord = async (req, res, next) => {
15+
const { discordId } = req.userData;
16+
if (!discordId) {
17+
return res.boom.forbidden("You are restricted from performing this action");
18+
}
19+
return next();
20+
};
21+
22+
module.exports = checkIsVerifiedDiscord;

0 commit comments

Comments
 (0)