From b3d05604a9fd964901459e231532f3d9f7f62186 Mon Sep 17 00:00:00 2001 From: Bhavika Tibrewal Date: Fri, 28 Apr 2023 22:15:48 +0530 Subject: [PATCH 01/10] initial commit --- constants/roles.js | 1 + controllers/users.js | 26 ++++++++++++++++++++++++++ models/users.js | 25 +++++++++++++++++++++++++ routes/users.js | 3 +++ 4 files changed, 55 insertions(+) diff --git a/constants/roles.js b/constants/roles.js index 9f80a4968..a4e5f13b5 100644 --- a/constants/roles.js +++ b/constants/roles.js @@ -4,6 +4,7 @@ const ROLES = { APPOWNER: "app_owner", MEMBER: "member", ARCHIVED: "archived", + IN_DISCORD: "inDiscord", }; module.exports = ROLES; diff --git a/controllers/users.js b/controllers/users.js index 88f31ac60..0221977ff 100644 --- a/controllers/users.js +++ b/controllers/users.js @@ -12,6 +12,7 @@ const { getPaginationLink, getUsernamesFromPRs } = require("../utils/users"); const { getQualifiers } = require("../utils/helper"); const { SOMETHING_WENT_WRONG, INTERNAL_SERVER_ERROR } = require("../constants/errorMessages"); const { getFilteredPRsOrIssues } = require("../utils/pullRequests"); +const { IN_DISCORD } = require("../constants/roles"); const verifyUser = async (req, res) => { const userId = req.userData.id; @@ -107,6 +108,7 @@ const getUsers = async (req, res) => { */ const getUser = async (req, res) => { + console.log(req.params.username); try { const result = await userQuery.fetchUser({ username: req.params.username }); const { phone, email, ...user } = result.user; @@ -462,6 +464,29 @@ const filterUsers = async (req, res) => { } }; +// const syncInDiscordRole = async (req, res) => { +// try { +// } catch (error) { +// logger.error(`Error while fetching all users: ${error}`); +// return res.boom.serverUnavailable("Something went wrong please contact admin"); +// } +// }; + +const fetchInDiscordUsers = async (req, res) => { + try { + const allUsers = await userQuery.fetchUsersWithRole(IN_DISCORD); + + return res.json({ + message: "Users found successfully!", + users: allUsers, + count: allUsers.length, + }); + } catch (error) { + logger.error(`Error while fetching all users: ${error}`); + return res.boom.serverUnavailable("Something went wrong please contact admin"); + } +}; + module.exports = { verifyUser, generateChaincode, @@ -481,4 +506,5 @@ module.exports = { addDefaultArchivedRole, getUserSkills, filterUsers, + fetchInDiscordUsers, }; diff --git a/models/users.js b/models/users.js index 6b60a9545..660dd12d8 100644 --- a/models/users.js +++ b/models/users.js @@ -409,6 +409,30 @@ const getUsersBasedOnFilter = async (query) => { return userDocs; }; +const fetchUsersWithRole = async (role) => { + try { + // console.log(role); + const snapshot = await userModel.where(`roles.${role}`, "==", true).get(); + const onlyMembers = []; + + if (!snapshot.empty) { + snapshot.forEach((doc) => { + onlyMembers.push({ + id: doc.id, + ...doc.data(), + phone: undefined, + email: undefined, + tokens: undefined, + }); + }); + } + return onlyMembers; + } catch (err) { + logger.error("Error retrieving users data with roles of inDiscord", err); + throw err; + } +}; + module.exports = { addOrUpdate, fetchPaginatedUsers, @@ -424,4 +448,5 @@ module.exports = { getRdsUserInfoByGitHubUsername, fetchUsers, getUsersBasedOnFilter, + fetchUsersWithRole, }; diff --git a/routes/users.js b/routes/users.js index 02b11c475..73ebf8262 100644 --- a/routes/users.js +++ b/routes/users.js @@ -16,6 +16,7 @@ router.get("/self", authenticate, users.getSelfDetails); router.get("/isUsernameAvailable/:username", authenticate, users.getUsernameAvailabilty); router.get("/chaincode", authenticate, users.generateChaincode); router.get("/search", userValidator.validateUserQueryParams, users.filterUsers); +router.get("/InDiscord", authenticate, users.fetchInDiscordUsers); router.get("/:username", users.getUser); router.get("/:userId/intro", authenticate, authorizeRoles([SUPERUSER]), users.getUserIntro); router.put("/self/intro", authenticate, userValidator.validateJoinData, users.addUserIntro); @@ -29,4 +30,6 @@ router.patch("/rejectDiff", authenticate, authorizeRoles([SUPERUSER]), users.rej router.patch("/:userId", authenticate, authorizeRoles([SUPERUSER]), users.updateUser); router.get("/suggestedUsers/:skillId", authenticate, authorizeRoles([SUPERUSER]), users.getSuggestedUsers); +router.post("/syncInDiscord", authenticate, users.getSelfDetails); + module.exports = router; From 088b2e9c6203f8a13efbde016188baab94245ad4 Mon Sep 17 00:00:00 2001 From: Bhavika Tibrewal Date: Tue, 2 May 2023 13:18:34 +0530 Subject: [PATCH 02/10] sync API --- controllers/users.js | 60 +++++++++++++++++++++++++++++++++----------- models/users.js | 36 +++++++++++++++++++++++++- routes/users.js | 6 ++--- utils/users.js | 24 ++++++++++++++++++ 4 files changed, 108 insertions(+), 18 deletions(-) diff --git a/controllers/users.js b/controllers/users.js index 0221977ff..1480182bf 100644 --- a/controllers/users.js +++ b/controllers/users.js @@ -5,14 +5,15 @@ const logsQuery = require("../models/logs"); const imageService = require("../services/imageService"); const { profileDiffStatus } = require("../constants/profileDiff"); const { logType } = require("../constants/logs"); -const { fetch } = require("../utils/fetch"); + const logger = require("../utils/logger"); const obfuscate = require("../utils/obfuscate"); -const { getPaginationLink, getUsernamesFromPRs } = require("../utils/users"); +const { getPaginationLink, getUsernamesFromPRs, mapDiscordMembersDataAndSyncRole } = require("../utils/users"); const { getQualifiers } = require("../utils/helper"); const { SOMETHING_WENT_WRONG, INTERNAL_SERVER_ERROR } = require("../constants/errorMessages"); const { getFilteredPRsOrIssues } = require("../utils/pullRequests"); const { IN_DISCORD } = require("../constants/roles"); +const jwt = require("jsonwebtoken"); const verifyUser = async (req, res) => { const userId = req.userData.id; @@ -25,7 +26,11 @@ const verifyUser = async (req, res) => { logger.error(`Error while verifying user: ${error}`); return res.boom.serverUnavailable(SOMETHING_WENT_WRONG); } - fetch(process.env.IDENTITY_SERVICE_URL, "POST", null, { userId }, { "Content-Type": "application/json" }); + fetch(process.env.IDENTITY_SERVICE_URL, { + method: "POST", + body: { userId }, + headers: { "Content-Type": "application/json" }, + }); return res.json({ message: "Your request has been queued successfully", }); @@ -108,7 +113,6 @@ const getUsers = async (req, res) => { */ const getUser = async (req, res) => { - console.log(req.params.username); try { const result = await userQuery.fetchUser({ username: req.params.username }); const { phone, email, ...user } = result.user; @@ -463,23 +467,49 @@ const filterUsers = async (req, res) => { return res.boom.serverUnavailable("Something went wrong please contact admin"); } }; +const DISCORD_BASE_URL = "https://89d4-49-36-233-201.ngrok.io"; +const syncInDiscordRole = async (req, res) => { + try { + const authToken = jwt.sign({}, config.get("botToken.botPrivateKey"), { + algorithm: "RS256", + }); + // console.log(authToken); + const response = await fetch(`${DISCORD_BASE_URL}/discord-members`, { + headers: { + "Content-Type": "application/json", + Authorization: `Bearer ${authToken}`, + }, + }); + const discordMembers = await response.json(); -// const syncInDiscordRole = async (req, res) => { -// try { -// } catch (error) { -// logger.error(`Error while fetching all users: ${error}`); -// return res.boom.serverUnavailable("Something went wrong please contact admin"); -// } -// }; + const allUsers = await userQuery.getAllUsers(); + mapDiscordMembersDataAndSyncRole(allUsers, discordMembers); + + return res.json({ message: "Synced with discord members " }); + } catch (error) { + logger.error(`Error while fetching all users: ${error}`); + return res.boom.serverUnavailable("Something went wrong please contact admin"); + } +}; + +const fetchVerifiedUsers = async (req, res) => { + try { + const verifiedUsers = await userQuery.fetchUsersWhereFieldNotNull("discordId"); + return res.json(verifiedUsers); + } catch (error) { + logger.error(`Error while fetching all users: ${error}`); + return res.boom.serverUnavailable("Something went wrong please contact admin"); + } +}; const fetchInDiscordUsers = async (req, res) => { try { - const allUsers = await userQuery.fetchUsersWithRole(IN_DISCORD); + const usersInDiscord = await userQuery.fetchUsersWithRole(IN_DISCORD); return res.json({ message: "Users found successfully!", - users: allUsers, - count: allUsers.length, + users: usersInDiscord, + count: usersInDiscord.length, }); } catch (error) { logger.error(`Error while fetching all users: ${error}`); @@ -507,4 +537,6 @@ module.exports = { getUserSkills, filterUsers, fetchInDiscordUsers, + syncInDiscordRole, + fetchVerifiedUsers, }; diff --git a/models/users.js b/models/users.js index 660dd12d8..3d3707d6d 100644 --- a/models/users.js +++ b/models/users.js @@ -408,7 +408,15 @@ const getUsersBasedOnFilter = async (query) => { const userDocs = (await firestore.getAll(...userRefs)).map((doc) => ({ id: doc.id, ...doc.data() })); return userDocs; }; - +const getAllUsers = async () => { + try { + const usersRef = await userModel.get(); + return usersRef; + } catch (err) { + logger.error("Error retrieving users data with roles of inDiscord", err); + throw err; + } +}; const fetchUsersWithRole = async (role) => { try { // console.log(role); @@ -426,12 +434,36 @@ const fetchUsersWithRole = async (role) => { }); }); } + return onlyMembers; } catch (err) { logger.error("Error retrieving users data with roles of inDiscord", err); throw err; } }; +const fetchUsersWhereFieldNotNull = async (field) => { + try { + const snapshot = await userModel.where(field, "!=", null).get(); + const users = []; + + if (!snapshot.empty) { + snapshot.forEach((doc) => { + users.push({ + id: doc.id, + ...doc.data(), + phone: undefined, + email: undefined, + tokens: undefined, + }); + }); + } + + return users; + } catch (err) { + logger.error("Error retrieving users data with roles of inDiscord", err); + throw err; + } +}; module.exports = { addOrUpdate, @@ -449,4 +481,6 @@ module.exports = { fetchUsers, getUsersBasedOnFilter, fetchUsersWithRole, + fetchUsersWhereFieldNotNull, + getAllUsers, }; diff --git a/routes/users.js b/routes/users.js index 73ebf8262..1900bd720 100644 --- a/routes/users.js +++ b/routes/users.js @@ -16,7 +16,9 @@ router.get("/self", authenticate, users.getSelfDetails); router.get("/isUsernameAvailable/:username", authenticate, users.getUsernameAvailabilty); router.get("/chaincode", authenticate, users.generateChaincode); router.get("/search", userValidator.validateUserQueryParams, users.filterUsers); -router.get("/InDiscord", authenticate, users.fetchInDiscordUsers); +router.get("/inDiscord", authenticate, users.fetchInDiscordUsers); +router.post("/syncInDiscord", authenticate, users.syncInDiscordRole); +router.get("/verified", authenticate, users.fetchVerifiedUsers); router.get("/:username", users.getUser); router.get("/:userId/intro", authenticate, authorizeRoles([SUPERUSER]), users.getUserIntro); router.put("/self/intro", authenticate, userValidator.validateJoinData, users.addUserIntro); @@ -30,6 +32,4 @@ router.patch("/rejectDiff", authenticate, authorizeRoles([SUPERUSER]), users.rej router.patch("/:userId", authenticate, authorizeRoles([SUPERUSER]), users.updateUser); router.get("/suggestedUsers/:skillId", authenticate, authorizeRoles([SUPERUSER]), users.getSuggestedUsers); -router.post("/syncInDiscord", authenticate, users.getSelfDetails); - module.exports = router; diff --git a/utils/users.js b/utils/users.js index f3754d74e..f89a0dec3 100644 --- a/utils/users.js +++ b/utils/users.js @@ -142,6 +142,29 @@ function getUsernamesFromPRs(allPRs) { return usernames; } +function mapDiscordMembersDataAndSyncRole(allUsers, discordMembers) { + try { + allUsers.forEach((doc) => { + const user = doc.data(); + + if (user.roles.archived) { + const roles = user.roles ? { ...user.roles, inDiscord: false } : { inDiscord: false }; + doc.ref.update({ roles }); + } else if (user.discordId) { + const discordUserData = discordMembers.find((item) => item.user.id === user.discordId); + if (discordUserData) { + const roles = user.roles ? { ...user.roles, inDiscord: true } : { inDiscord: true }; + doc.ref.update({ roles, joined_RDS: discordUserData.joined_at }); + } else { + const roles = user.roles ? { ...user.roles, inDiscord: false } : { inDiscord: false }; + doc.ref.update({ roles }); + } + } + }); + } catch (err) { + logger.error(err); + } +} module.exports = { addUserToDBForTest, @@ -152,4 +175,5 @@ module.exports = { getLowestLevelSkill, getPaginationLink, getUsernamesFromPRs, + mapDiscordMembersDataAndSyncRole, }; From 23e594cdf6f6e53683f4ac23f487946314a9cdb1 Mon Sep 17 00:00:00 2001 From: Bhavika Tibrewal Date: Sat, 13 May 2023 18:26:45 +0530 Subject: [PATCH 03/10] func: search roles and verified users --- constants/users.js | 1 + controllers/users.js | 2 +- middlewares/validators/user.js | 5 +++ test/unit/utils/users.test.js | 58 ++++++++++++++++++++++++++++++++++ utils/users.js | 2 +- 5 files changed, 66 insertions(+), 2 deletions(-) diff --git a/constants/users.js b/constants/users.js index fea46dd70..bdb5939f9 100644 --- a/constants/users.js +++ b/constants/users.js @@ -13,6 +13,7 @@ const USER_STATUS = { const ALLOWED_FILTER_PARAMS = { ITEM_TAG: ["levelId", "levelName", "levelValue", "tagId"], USER_STATE: ["state"], + ROLE: ["role"], }; module.exports = { profileStatus, USER_STATUS, ALLOWED_FILTER_PARAMS }; diff --git a/controllers/users.js b/controllers/users.js index 30415558a..755eaf9ba 100644 --- a/controllers/users.js +++ b/controllers/users.js @@ -473,7 +473,7 @@ const syncInDiscordRole = async (req, res) => { const authToken = jwt.sign({}, config.get("botToken.botPrivateKey"), { algorithm: "RS256", }); - // console.log(authToken); + const response = await fetch(`${DISCORD_BASE_URL}/discord-members`, { headers: { "Content-Type": "application/json", diff --git a/middlewares/validators/user.js b/middlewares/validators/user.js index 8ead61e64..3033f0f30 100644 --- a/middlewares/validators/user.js +++ b/middlewares/validators/user.js @@ -172,6 +172,11 @@ async function validateUserQueryParams(req, res, next) { joi.array().items(joi.string().valid("IDLE", "OOO", "ACTIVE")) ) .optional(), + role: joi + .alternatives() + .try(joi.string().valid("in_discord", "member"), joi.array().items(joi.string().valid("in_discord", "member"))) + .optional(), + verified: joi.string().optional(), }) .messages({ "object.min": "Please provide at least one filter criteria", diff --git a/test/unit/utils/users.test.js b/test/unit/utils/users.test.js index 04298d6c2..5a8fbdaf6 100644 --- a/test/unit/utils/users.test.js +++ b/test/unit/utils/users.test.js @@ -1,6 +1,8 @@ const chai = require("chai"); const { expect } = chai; +const sinon = require("sinon"); + const usersUtils = require("../../../utils/users"); const cleanDb = require("../../utils/cleanDb"); const addUser = require("../../utils/addUser"); @@ -65,4 +67,60 @@ describe("users", function () { expect(participantUserId).to.include(userId); }); }); + + describe("mapDiscordMembersDataAndSyncRole", function () { + it("should update roles and joined_discord fields for users with matching Discord IDs", function () { + const allUsers = [ + { + data: () => ({ roles: { archived: false }, discordId: "123" }), + ref: { update: sinon.spy() }, + }, + ]; + const discordMembers = [ + { + user: { id: "123" }, + joined_at: "2022-05-01T00:00:00.000Z", + }, + ]; + + usersUtils.mapDiscordMembersDataAndSyncRole(allUsers, discordMembers); + + sinon.assert.calledWithExactly(allUsers[0].ref.update, { + roles: { archived: false, inDiscord: true }, + joined_discord: discordMembers[0].joined_at, + }); + }); + + it("should update roles field to inDiscord: false for users with no matching Discord ID", function () { + const allUsers = [ + { + data: () => ({ roles: { archived: false }, discordId: "123" }), + ref: { update: sinon.spy() }, + }, + ]; + const discordMembers = []; + + usersUtils.mapDiscordMembersDataAndSyncRole(allUsers, discordMembers); + + sinon.assert.calledWithExactly(allUsers[0].ref.update, { + roles: { archived: false, inDiscord: false }, + }); + }); + + it("should update roles field to inDiscord: false for users with archived roles", function () { + const allUsers = [ + { + data: () => ({ roles: { archived: true }, discordId: "123" }), + ref: { update: () => sinon.spy() }, + }, + ]; + const discordMembers = []; + + usersUtils.mapDiscordMembersDataAndSyncRole(allUsers, discordMembers); + + expect(allUsers[0].ref.update).to.have.been.calledWith({ + roles: { archived: true, inDiscord: false }, + }); + }); + }); }); diff --git a/utils/users.js b/utils/users.js index f89a0dec3..b24e0336d 100644 --- a/utils/users.js +++ b/utils/users.js @@ -154,7 +154,7 @@ function mapDiscordMembersDataAndSyncRole(allUsers, discordMembers) { const discordUserData = discordMembers.find((item) => item.user.id === user.discordId); if (discordUserData) { const roles = user.roles ? { ...user.roles, inDiscord: true } : { inDiscord: true }; - doc.ref.update({ roles, joined_RDS: discordUserData.joined_at }); + doc.ref.update({ roles, joined_discord: discordUserData.joined_at }); } else { const roles = user.roles ? { ...user.roles, inDiscord: false } : { inDiscord: false }; doc.ref.update({ roles }); From 07c0bb0a27855516c2858fec30574c512ea6285f Mon Sep 17 00:00:00 2001 From: Bhavika Tibrewal Date: Sun, 14 May 2023 20:30:38 +0530 Subject: [PATCH 04/10] feat: search in_discord and verified --- middlewares/validators/user.js | 5 +-- models/users.js | 59 ++++++++++++++-------------------- 2 files changed, 26 insertions(+), 38 deletions(-) diff --git a/middlewares/validators/user.js b/middlewares/validators/user.js index 3033f0f30..d1172f42c 100644 --- a/middlewares/validators/user.js +++ b/middlewares/validators/user.js @@ -172,10 +172,7 @@ async function validateUserQueryParams(req, res, next) { joi.array().items(joi.string().valid("IDLE", "OOO", "ACTIVE")) ) .optional(), - role: joi - .alternatives() - .try(joi.string().valid("in_discord", "member"), joi.array().items(joi.string().valid("in_discord", "member"))) - .optional(), + role: joi.string().valid("in_discord", "member").optional(), verified: joi.string().optional(), }) .messages({ diff --git a/models/users.js b/models/users.js index 78817b2a8..bf28924f7 100644 --- a/models/users.js +++ b/models/users.js @@ -360,6 +360,8 @@ const getRdsUserInfoByGitHubUsername = async (githubUsername) => { * @param {Array} query.levelNumber - Array of levelNumbers to filter the users on * @param {Array} query.tagId - Array of tagIds to filter the users on * @param {Array} query.state - Array of states to filter the users on + * @param {String} query.role - filter the users on + * @param {String} query.verified - filter the users on * @return {Promise} - Array of user documents that match the filter criteria */ @@ -429,46 +431,35 @@ const fetchUsersWithRole = async (role) => { const snapshot = await userModel.where(`roles.${role}`, "==", true).get(); const onlyMembers = []; - if (!snapshot.empty) { - snapshot.forEach((doc) => { - onlyMembers.push({ - id: doc.id, - ...doc.data(), - phone: undefined, - email: undefined, - tokens: undefined, - }); + const roleQuery = query.role; + const verifiedQuery = query.verified; + + if (roleQuery) { + const filteredUsers = []; + const snapshot = await userModel.where(`roles.${roleQuery}`, "==", true).get(); + snapshot.forEach((doc) => { + filteredUsers.push({ + id: doc.id, + ...doc.data(), }); - } + }); - return onlyMembers; - } catch (err) { - logger.error("Error retrieving users data with roles of inDiscord", err); - throw err; + return filteredUsers; } -}; -const fetchUsersWhereFieldNotNull = async (field) => { - try { - const snapshot = await userModel.where(field, "!=", null).get(); - const users = []; - - if (!snapshot.empty) { - snapshot.forEach((doc) => { - users.push({ - id: doc.id, - ...doc.data(), - phone: undefined, - email: undefined, - tokens: undefined, - }); + if (verifiedQuery) { + console.log(typeof verifiedQuery); + const filteredUsers = []; + const snapshot = await userModel.orderBy("discordId").get(); + snapshot.forEach((doc) => { + filteredUsers.push({ + id: doc.id, + ...doc.data(), }); - } + }); - return users; - } catch (err) { - logger.error("Error retrieving users data with roles of inDiscord", err); - throw err; + return filteredUsers; } + return []; }; module.exports = { From 19fe12a5e1cd8940f587a27188d2f3e27028db78 Mon Sep 17 00:00:00 2001 From: Bhavika Tibrewal Date: Sun, 14 May 2023 20:31:04 +0530 Subject: [PATCH 05/10] chore: remove unused code --- constants/roles.js | 2 +- controllers/users.js | 56 +-------------------------------- models/users.js | 20 ------------ routes/users.js | 3 -- test/unit/utils/users.test.js | 58 ----------------------------------- 5 files changed, 2 insertions(+), 137 deletions(-) diff --git a/constants/roles.js b/constants/roles.js index a4e5f13b5..d28e484a0 100644 --- a/constants/roles.js +++ b/constants/roles.js @@ -4,7 +4,7 @@ const ROLES = { APPOWNER: "app_owner", MEMBER: "member", ARCHIVED: "archived", - IN_DISCORD: "inDiscord", + INDISCORD: "in_discord", }; module.exports = ROLES; diff --git a/controllers/users.js b/controllers/users.js index 755eaf9ba..4db6a2ae3 100644 --- a/controllers/users.js +++ b/controllers/users.js @@ -8,12 +8,10 @@ const { logType } = require("../constants/logs"); const logger = require("../utils/logger"); const obfuscate = require("../utils/obfuscate"); -const { getPaginationLink, getUsernamesFromPRs, mapDiscordMembersDataAndSyncRole } = require("../utils/users"); +const { getPaginationLink, getUsernamesFromPRs } = require("../utils/users"); const { getQualifiers } = require("../utils/helper"); const { SOMETHING_WENT_WRONG, INTERNAL_SERVER_ERROR } = require("../constants/errorMessages"); const { getFilteredPRsOrIssues } = require("../utils/pullRequests"); -const { IN_DISCORD } = require("../constants/roles"); -const jwt = require("jsonwebtoken"); const verifyUser = async (req, res) => { const userId = req.userData.id; @@ -467,55 +465,6 @@ const filterUsers = async (req, res) => { return res.boom.serverUnavailable("Something went wrong please contact admin"); } }; -const DISCORD_BASE_URL = "https://89d4-49-36-233-201.ngrok.io"; -const syncInDiscordRole = async (req, res) => { - try { - const authToken = jwt.sign({}, config.get("botToken.botPrivateKey"), { - algorithm: "RS256", - }); - - const response = await fetch(`${DISCORD_BASE_URL}/discord-members`, { - headers: { - "Content-Type": "application/json", - Authorization: `Bearer ${authToken}`, - }, - }); - const discordMembers = await response.json(); - - const allUsers = await userQuery.getAllUsers(); - mapDiscordMembersDataAndSyncRole(allUsers, discordMembers); - - return res.json({ message: "Synced with discord members " }); - } catch (error) { - logger.error(`Error while fetching all users: ${error}`); - return res.boom.serverUnavailable("Something went wrong please contact admin"); - } -}; - -const fetchVerifiedUsers = async (req, res) => { - try { - const verifiedUsers = await userQuery.fetchUsersWhereFieldNotNull("discordId"); - return res.json(verifiedUsers); - } catch (error) { - logger.error(`Error while fetching all users: ${error}`); - return res.boom.serverUnavailable("Something went wrong please contact admin"); - } -}; - -const fetchInDiscordUsers = async (req, res) => { - try { - const usersInDiscord = await userQuery.fetchUsersWithRole(IN_DISCORD); - - return res.json({ - message: "Users found successfully!", - users: usersInDiscord, - count: usersInDiscord.length, - }); - } catch (error) { - logger.error(`Error while fetching all users: ${error}`); - return res.boom.serverUnavailable("Something went wrong please contact admin"); - } -}; module.exports = { verifyUser, @@ -536,7 +485,4 @@ module.exports = { addDefaultArchivedRole, getUserSkills, filterUsers, - fetchInDiscordUsers, - syncInDiscordRole, - fetchVerifiedUsers, }; diff --git a/models/users.js b/models/users.js index bf28924f7..c52879b2b 100644 --- a/models/users.js +++ b/models/users.js @@ -414,22 +414,6 @@ const getUsersBasedOnFilter = async (query) => { const filteredUserDocs = userDocs.filter((doc) => !doc.roles?.archived); return filteredUserDocs; } - return []; -}; -const getAllUsers = async () => { - try { - const usersRef = await userModel.get(); - return usersRef; - } catch (err) { - logger.error("Error retrieving users data with roles of inDiscord", err); - throw err; - } -}; -const fetchUsersWithRole = async (role) => { - try { - // console.log(role); - const snapshot = await userModel.where(`roles.${role}`, "==", true).get(); - const onlyMembers = []; const roleQuery = query.role; const verifiedQuery = query.verified; @@ -447,7 +431,6 @@ const fetchUsersWithRole = async (role) => { return filteredUsers; } if (verifiedQuery) { - console.log(typeof verifiedQuery); const filteredUsers = []; const snapshot = await userModel.orderBy("discordId").get(); snapshot.forEach((doc) => { @@ -477,7 +460,4 @@ module.exports = { getRdsUserInfoByGitHubUsername, fetchUsers, getUsersBasedOnFilter, - fetchUsersWithRole, - fetchUsersWhereFieldNotNull, - getAllUsers, }; diff --git a/routes/users.js b/routes/users.js index 1900bd720..02b11c475 100644 --- a/routes/users.js +++ b/routes/users.js @@ -16,9 +16,6 @@ router.get("/self", authenticate, users.getSelfDetails); router.get("/isUsernameAvailable/:username", authenticate, users.getUsernameAvailabilty); router.get("/chaincode", authenticate, users.generateChaincode); router.get("/search", userValidator.validateUserQueryParams, users.filterUsers); -router.get("/inDiscord", authenticate, users.fetchInDiscordUsers); -router.post("/syncInDiscord", authenticate, users.syncInDiscordRole); -router.get("/verified", authenticate, users.fetchVerifiedUsers); router.get("/:username", users.getUser); router.get("/:userId/intro", authenticate, authorizeRoles([SUPERUSER]), users.getUserIntro); router.put("/self/intro", authenticate, userValidator.validateJoinData, users.addUserIntro); diff --git a/test/unit/utils/users.test.js b/test/unit/utils/users.test.js index 5a8fbdaf6..04298d6c2 100644 --- a/test/unit/utils/users.test.js +++ b/test/unit/utils/users.test.js @@ -1,8 +1,6 @@ const chai = require("chai"); const { expect } = chai; -const sinon = require("sinon"); - const usersUtils = require("../../../utils/users"); const cleanDb = require("../../utils/cleanDb"); const addUser = require("../../utils/addUser"); @@ -67,60 +65,4 @@ describe("users", function () { expect(participantUserId).to.include(userId); }); }); - - describe("mapDiscordMembersDataAndSyncRole", function () { - it("should update roles and joined_discord fields for users with matching Discord IDs", function () { - const allUsers = [ - { - data: () => ({ roles: { archived: false }, discordId: "123" }), - ref: { update: sinon.spy() }, - }, - ]; - const discordMembers = [ - { - user: { id: "123" }, - joined_at: "2022-05-01T00:00:00.000Z", - }, - ]; - - usersUtils.mapDiscordMembersDataAndSyncRole(allUsers, discordMembers); - - sinon.assert.calledWithExactly(allUsers[0].ref.update, { - roles: { archived: false, inDiscord: true }, - joined_discord: discordMembers[0].joined_at, - }); - }); - - it("should update roles field to inDiscord: false for users with no matching Discord ID", function () { - const allUsers = [ - { - data: () => ({ roles: { archived: false }, discordId: "123" }), - ref: { update: sinon.spy() }, - }, - ]; - const discordMembers = []; - - usersUtils.mapDiscordMembersDataAndSyncRole(allUsers, discordMembers); - - sinon.assert.calledWithExactly(allUsers[0].ref.update, { - roles: { archived: false, inDiscord: false }, - }); - }); - - it("should update roles field to inDiscord: false for users with archived roles", function () { - const allUsers = [ - { - data: () => ({ roles: { archived: true }, discordId: "123" }), - ref: { update: () => sinon.spy() }, - }, - ]; - const discordMembers = []; - - usersUtils.mapDiscordMembersDataAndSyncRole(allUsers, discordMembers); - - expect(allUsers[0].ref.update).to.have.been.calledWith({ - roles: { archived: true, inDiscord: false }, - }); - }); - }); }); From 6b013d7e8c574f7c766a8c722fef868fa3c75834 Mon Sep 17 00:00:00 2001 From: Bhavika Tibrewal Date: Sun, 14 May 2023 21:57:03 +0530 Subject: [PATCH 06/10] chore: remove mapDiscordMembersDataAndSyncRole function --- utils/users.js | 24 ------------------------ 1 file changed, 24 deletions(-) diff --git a/utils/users.js b/utils/users.js index b24e0336d..f3754d74e 100644 --- a/utils/users.js +++ b/utils/users.js @@ -142,29 +142,6 @@ function getUsernamesFromPRs(allPRs) { return usernames; } -function mapDiscordMembersDataAndSyncRole(allUsers, discordMembers) { - try { - allUsers.forEach((doc) => { - const user = doc.data(); - - if (user.roles.archived) { - const roles = user.roles ? { ...user.roles, inDiscord: false } : { inDiscord: false }; - doc.ref.update({ roles }); - } else if (user.discordId) { - const discordUserData = discordMembers.find((item) => item.user.id === user.discordId); - if (discordUserData) { - const roles = user.roles ? { ...user.roles, inDiscord: true } : { inDiscord: true }; - doc.ref.update({ roles, joined_discord: discordUserData.joined_at }); - } else { - const roles = user.roles ? { ...user.roles, inDiscord: false } : { inDiscord: false }; - doc.ref.update({ roles }); - } - } - }); - } catch (err) { - logger.error(err); - } -} module.exports = { addUserToDBForTest, @@ -175,5 +152,4 @@ module.exports = { getLowestLevelSkill, getPaginationLink, getUsernamesFromPRs, - mapDiscordMembersDataAndSyncRole, }; From cf520e19972242eb920d6f5764bb2c879aa1825c Mon Sep 17 00:00:00 2001 From: Bhavika Tibrewal Date: Wed, 17 May 2023 18:52:31 +0530 Subject: [PATCH 07/10] write test for brew install redis --- models/users.js | 8 ++++---- test/fixtures/user/user.js | 4 ++++ test/unit/models/users.test.js | 12 ++++++++++++ 3 files changed, 20 insertions(+), 4 deletions(-) diff --git a/models/users.js b/models/users.js index c52879b2b..f4b158620 100644 --- a/models/users.js +++ b/models/users.js @@ -428,11 +428,11 @@ const getUsersBasedOnFilter = async (query) => { }); }); - return filteredUsers; + return filteredUsers.filter((user) => !user.roles?.archived); } - if (verifiedQuery) { + if (verifiedQuery === "true") { const filteredUsers = []; - const snapshot = await userModel.orderBy("discordId").get(); + const snapshot = await userModel.where("discordId", "!=", null).get(); snapshot.forEach((doc) => { filteredUsers.push({ id: doc.id, @@ -440,7 +440,7 @@ const getUsersBasedOnFilter = async (query) => { }); }); - return filteredUsers; + return filteredUsers.filter((user) => !user.roles?.archived); } return []; }; diff --git a/test/fixtures/user/user.js b/test/fixtures/user/user.js index 94d9d7f9d..e46c6eafe 100644 --- a/test/fixtures/user/user.js +++ b/test/fixtures/user/user.js @@ -21,8 +21,10 @@ module.exports = () => { isMember: true, phone: "1234567890", email: "abc@gmail.com", + joined_discord: "2023-01-13T18:21:09.278000+00:00", roles: { member: true, + in_discord: true, }, tokens: { githubAccessToken: "githubAccessToken", @@ -105,6 +107,7 @@ module.exports = () => { github_display_name: "Ankush Dharkar", phone: "1234567890", email: "ad@amazon.com", + joined_discord: "2023-01-13T18:21:09.278000+00:00", status: "idle", tokens: { githubAccessToken: "githubAccessToken", @@ -112,6 +115,7 @@ module.exports = () => { roles: { super_user: true, archived: false, + in_discord: true, }, picture: { publicId: "profile/mtS4DhUvNYsKqI7oCWVB/aenklfhtjldc5ytei3ar", diff --git a/test/unit/models/users.test.js b/test/unit/models/users.test.js index 728f267c9..04d081d63 100644 --- a/test/unit/models/users.test.js +++ b/test/unit/models/users.test.js @@ -88,4 +88,16 @@ describe("users", function () { expect(userExists).to.equal(true); }); }); + + describe("brew install redis", function () { + it("should return an empty array if no query is provided", async function () { + const result = await users.getUsersBasedOnFilter({}); + expect(result).to.deep.equal([]); + }); + + it("should return an array of verified users", async function () { + const result = await users.getUsersBasedOnFilter({ verified: "true" }); + expect(result).to.deep.equal(userDataArray.filter((user) => user.discordId)); + }); + }); }); From e1ef0de07b7b7e5814216f1d0e4ba46b9c5f0895 Mon Sep 17 00:00:00 2001 From: Bhavika Tibrewal Date: Thu, 18 May 2023 20:24:02 +0530 Subject: [PATCH 08/10] chore: change test description --- test/unit/models/users.test.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/unit/models/users.test.js b/test/unit/models/users.test.js index 04d081d63..747015fed 100644 --- a/test/unit/models/users.test.js +++ b/test/unit/models/users.test.js @@ -89,7 +89,7 @@ describe("users", function () { }); }); - describe("brew install redis", function () { + describe(" search users API: getUsersBasedOnFilter", function () { it("should return an empty array if no query is provided", async function () { const result = await users.getUsersBasedOnFilter({}); expect(result).to.deep.equal([]); From 70a0d199fa13d884451b78b42ca4d5588985c910 Mon Sep 17 00:00:00 2001 From: Bhavika Tibrewal Date: Thu, 18 May 2023 20:57:48 +0530 Subject: [PATCH 09/10] chore: address comments --- models/users.js | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/models/users.js b/models/users.js index f4b158620..0d4ba5b15 100644 --- a/models/users.js +++ b/models/users.js @@ -360,8 +360,8 @@ const getRdsUserInfoByGitHubUsername = async (githubUsername) => { * @param {Array} query.levelNumber - Array of levelNumbers to filter the users on * @param {Array} query.tagId - Array of tagIds to filter the users on * @param {Array} query.state - Array of states to filter the users on - * @param {String} query.role - filter the users on - * @param {String} query.verified - filter the users on + * @param {String} query.role - filter the users on role + * @param {String} query.verified - filter the users on verified i.e, discordId data * @return {Promise} - Array of user documents that match the filter criteria */ @@ -415,8 +415,7 @@ const getUsersBasedOnFilter = async (query) => { return filteredUserDocs; } - const roleQuery = query.role; - const verifiedQuery = query.verified; + const { role: roleQuery, verified: verifiedQuery } = query; if (roleQuery) { const filteredUsers = []; From 9aa1166a57abf26df8d1e7e7b355d15440229700 Mon Sep 17 00:00:00 2001 From: Bhavika Tibrewal Date: Thu, 18 May 2023 22:05:41 +0530 Subject: [PATCH 10/10] chore: use roles constant in validation --- middlewares/validators/user.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/middlewares/validators/user.js b/middlewares/validators/user.js index d1172f42c..ac91998d0 100644 --- a/middlewares/validators/user.js +++ b/middlewares/validators/user.js @@ -1,5 +1,6 @@ const joi = require("joi"); const { USER_STATUS } = require("../../constants/users"); +const ROLES = require("../../constants/roles"); const updateUser = async (req, res, next) => { const schema = joi @@ -172,7 +173,7 @@ async function validateUserQueryParams(req, res, next) { joi.array().items(joi.string().valid("IDLE", "OOO", "ACTIVE")) ) .optional(), - role: joi.string().valid("in_discord", "member").optional(), + role: joi.string().valid(ROLES.MEMBER, ROLES.INDISCORD).optional(), verified: joi.string().optional(), }) .messages({