diff --git a/README.md b/README.md
index 16d5232c9..eae2d9e8c 100644
--- a/README.md
+++ b/README.md
@@ -42,6 +42,7 @@ You can see the designs [here](https://www.figma.com/design/RPSfaw66HjzSwzntKcgD
- POST [/api/v1/auth/register](#post-register)
- POST [/api/v1/auth/login](#post-login)
- POST [/api/v1/auth/user/{userId}](#post-auth-user-edit-id)
+ - GET [/api/v1/auth/users](#get-all-users-id)
- POST [/api/v1/auth/recovery/request](#post-auth-recovery-request-id)
- POST [/api/v1/auth/recovery/validate](#post-auth-recovery-validate-id)
- POST [/api/v1/auth/recovery/reset](#post-auth-recovery-reset-id)
@@ -453,6 +454,55 @@ curl --request POST \
+
+GET/api/v1/auth/users
+
+###### Method/Headers
+
+> | Method/Headers | Value |
+> | -------------- | ----- |
+> | Method | GET |
+
+###### Response Payload
+
+> | Type | Notes |
+> | ------------- | ------------------------------------- |
+> | `Array` | Returns an array containing all users |
+
+##### Sample CURL request
+
+```
+curl --request GET \
+ --url http://localhost:5000/api/v1/auth/users \
+ --header 'Authorization: \
+ --header 'User-Agent: insomnia/2023.5.8'
+```
+
+##### Sample Resonse
+
+```json
+{
+ "success": true,
+ "msg": "Got all users",
+ "data": [
+ {
+ "_id": "669e90072d5663d25808bc7b",
+ "firstName": "Alex",
+ "lastName": "Holliday",
+ "email": "test@test.com",
+ "isActive": true,
+ "isVerified": false,
+ "role": ["admin"],
+ "createdAt": "2024-07-22T16:59:51.695Z",
+ "updatedAt": "2024-07-22T16:59:51.695Z",
+ "__v": 0
+ }
+ ]
+}
+```
+
+
+
POST/api/v1/auth/recovery/request
diff --git a/Server/controllers/authController.js b/Server/controllers/authController.js
index 53fc9c384..28126c0a2 100644
--- a/Server/controllers/authController.js
+++ b/Server/controllers/authController.js
@@ -428,6 +428,18 @@ const deleteUserController = async (req, res, next) => {
}
};
+const getAllUsersController = async (req, res) => {
+ try {
+ const allUsers = await req.db.getAllUsers(req, res);
+ res
+ .status(200)
+ .json({ success: true, msg: "Got all users", data: allUsers });
+ } catch (error) {
+ error.service = SERVICE_NAME;
+ next(error);
+ }
+};
+
module.exports = {
registerController,
loginController,
@@ -438,4 +450,5 @@ module.exports = {
validateRecoveryTokenController,
resetPasswordController,
deleteUserController,
+ getAllUsersController,
};
diff --git a/Server/db/MongoDB.js b/Server/db/MongoDB.js
index a59822f98..52dc59084 100644
--- a/Server/db/MongoDB.js
+++ b/Server/db/MongoDB.js
@@ -159,6 +159,17 @@ const deleteUser = async (req, res) => {
}
};
+const getAllUsers = async (req, res) => {
+ try {
+ const users = await UserModel.find()
+ .select("-password")
+ .select("-profileImage");
+ return users;
+ } catch (error) {
+ throw error;
+ }
+};
+
const requestInviteToken = async (req, res) => {
try {
await InviteToken.deleteMany({ email: req.body.email });
@@ -629,6 +640,7 @@ module.exports = {
getUserByEmail,
updateUser,
deleteUser,
+ getAllUsers,
requestInviteToken,
requestRecoveryToken,
validateRecoveryToken,
diff --git a/Server/middleware/verifyAdmin.js b/Server/middleware/verifyAdmin.js
new file mode 100644
index 000000000..7ef123451
--- /dev/null
+++ b/Server/middleware/verifyAdmin.js
@@ -0,0 +1,57 @@
+const jwt = require("jsonwebtoken");
+const logger = require("../utils/logger");
+const SERVICE_NAME = "verifyAdmin";
+const TOKEN_PREFIX = "Bearer ";
+const { errorMessages } = require("../utils/messages");
+/**
+ * Verifies the JWT token
+ * @function
+ * @param {express.Request} req
+ * @param {express.Response} res
+ * @param {express.NextFunction} next
+ * @returns {express.Response}
+ */
+const verifyAdmin = (req, res, next) => {
+ const token = req.headers["authorization"];
+ // Make sure a token is provided
+ if (!token) {
+ const error = new Error(errorMessages.NO_AUTH_TOKEN);
+ error.status = 401;
+ error.service = SERVICE_NAME;
+ next(error);
+ return;
+ }
+ // Make sure it is properly formatted
+ if (!token.startsWith(TOKEN_PREFIX)) {
+ const error = new Error(errorMessages.INVALID_AUTH_TOKEN); // Instantiate a new Error object for improperly formatted token
+ error.status = 400;
+ error.service = SERVICE_NAME;
+ next(error);
+ return;
+ }
+
+ const parsedToken = token.slice(TOKEN_PREFIX.length, token.length);
+ // verify admin role is present
+ jwt.verify(parsedToken, process.env.JWT_SECRET, (err, decoded) => {
+ if (err) {
+ logger.error(errorMessages.INVALID_AUTH_TOKEN, {
+ service: SERVICE_NAME,
+ });
+ return res
+ .status(401)
+ .json({ success: false, msg: errorMessages.INVALID_AUTH_TOKEN });
+ }
+
+ if (decoded.role.includes("admin") === false) {
+ logger.error(errorMessages.INVALID_AUTH_TOKEN, {
+ service: SERVICE_NAME,
+ });
+ return res
+ .status(401)
+ .json({ success: false, msg: errorMessages.UNAUTHORIZED });
+ }
+ next();
+ });
+};
+
+module.exports = { verifyAdmin };
diff --git a/Server/routes/authRoute.js b/Server/routes/authRoute.js
index 219032e26..02a1a67dd 100644
--- a/Server/routes/authRoute.js
+++ b/Server/routes/authRoute.js
@@ -1,5 +1,6 @@
const router = require("express").Router();
const { verifyJWT } = require("../middleware/verifyJWT");
+const { verifyAdmin } = require("../middleware/verifyAdmin");
const { verifyOwnership } = require("../middleware/verifyOwnership");
const multer = require("multer");
const upload = multer();
@@ -13,6 +14,7 @@ const {
validateRecoveryTokenController,
resetPasswordController,
checkAdminController,
+ getAllUsersController,
deleteUserController,
inviteController,
} = require("../controllers/authController");
@@ -27,6 +29,7 @@ router.post(
userEditController
);
router.get("/users/admin", checkAdminController);
+router.get("/users", verifyJWT, verifyAdmin, getAllUsersController);
router.delete(
"/user/:userId",
verifyJWT,
diff --git a/Server/utils/messages.js b/Server/utils/messages.js
index 787adc8f6..9ef5c6938 100644
--- a/Server/utils/messages.js
+++ b/Server/utils/messages.js
@@ -2,6 +2,7 @@ const errorMessages = {
// General Errors:
FRIENDLY_ERROR: "Something went wrong...",
UNKNOWN_ERROR: "An unknown error occurred",
+
// Auth Controller
UNAUTHORIZED: "Unauthorized access",
AUTH_ADMIN_EXISTS: "Admin already exists",