From 4495f0a28c17c14d5b87d67c2c3821f4497f63ae Mon Sep 17 00:00:00 2001 From: Jerry Ren Date: Wed, 6 Sep 2023 14:27:56 -0400 Subject: [PATCH 1/5] Permission change log saved to database Log containing account, role, and permission information gets saved to hgnData_dev.permissionChangeLogs collection. --- src/models/permissionChangeLog.js | 24 +++++++++++ src/routes/roleRouter.js | 3 +- src/utilities/logPermissionChangeByAccount.js | 43 +++++++++++++++++++ 3 files changed, 69 insertions(+), 1 deletion(-) create mode 100644 src/models/permissionChangeLog.js create mode 100644 src/utilities/logPermissionChangeByAccount.js diff --git a/src/models/permissionChangeLog.js b/src/models/permissionChangeLog.js new file mode 100644 index 000000000..cd9eb6899 --- /dev/null +++ b/src/models/permissionChangeLog.js @@ -0,0 +1,24 @@ +const mongoose = require('mongoose'); +const { Schema } = mongoose; + +const User = require('./userProfile'); +const rolesMergedPermissions = require('./role') + +const PermissionChangeLog = new Schema({ + logDateTime: { type: String, required: true }, + roleId: { + type: mongoose.Types.ObjectId, + ref: rolesMergedPermissions, + required: true + }, + roleName: { type: String }, + permissions: { type: [String], required: true }, + requestorId: { + type: mongoose.Types.ObjectId, + ref: User + }, + requestorRole: { type: String }, + requestorEmail: { type: String, required: true}, +}); + +module.exports = mongoose.model('permissionChangeLog', PermissionChangeLog, 'permissionChangeLogs'); \ No newline at end of file diff --git a/src/routes/roleRouter.js b/src/routes/roleRouter.js index 8c5164f12..c9d4f963f 100644 --- a/src/routes/roleRouter.js +++ b/src/routes/roleRouter.js @@ -1,4 +1,5 @@ const express = require('express'); +const changedPermissionsLogger = require('../utilities/logPermissionChangeByAccount') const routes = function (role) { const controller = require('../controllers/rolesController')(role); @@ -10,7 +11,7 @@ const routes = function (role) { RolesRouter.route('/roles/:roleId') .get(controller.getRoleById) - .patch(controller.updateRoleById) + .patch(changedPermissionsLogger,controller.updateRoleById) .delete(controller.deleteRoleById); return RolesRouter; }; diff --git a/src/utilities/logPermissionChangeByAccount.js b/src/utilities/logPermissionChangeByAccount.js new file mode 100644 index 000000000..56979c6c9 --- /dev/null +++ b/src/utilities/logPermissionChangeByAccount.js @@ -0,0 +1,43 @@ +const moment = require("moment-timezone"); +const PermissionChangeLog = require("../models/permissionChangeLog") + +// Middleware function +const changedPermissionsLogger = async (req, res, next) => { + await logPermissionChangeByAccount(req.body) + next(); +}; + +// Function saves logs to hgnData_dev.permissionChangeLogs collection +const logPermissionChangeByAccount = async (requestBody) => { + const { updatedRole, userProfile, requestor } = requestBody + const dateTime = moment().tz("America/Los_Angeles").format(); + + try { + // Extract relevant data from the request + const { roleId, roleName, permissions } = updatedRole; // Adjust this as per your request body structure + const { role, email } = userProfile; + const { requestorId } = requestor; + + // Create a new PermissionChangeLog object + const logEntry = new PermissionChangeLog({ + logDateTime: dateTime, + roleId: roleId, + roleName: roleName, + permissions: permissions, + requestorId: requestorId, + requestorRole: role, + requestorEmail: email, + }); + + // Save the log entry to the database + await logEntry.save(); + + } catch (error) { + // Handle any errors that occur during logging + console.error('Error logging permission change:', error); + // You can choose to send an error response to the client or handle it differently + res.status(500).json({ error: 'Failed to log permission change' }); + } +} + +module.exports = changedPermissionsLogger; From 004f5ca52b49fdd9f3f429135e92ac5c70acdbc0 Mon Sep 17 00:00:00 2001 From: Jerry Ren Date: Thu, 7 Sep 2023 11:00:06 -0400 Subject: [PATCH 2/5] Edit logging function to accomodate new req.body --- src/utilities/logPermissionChangeByAccount.js | 13 ++----------- 1 file changed, 2 insertions(+), 11 deletions(-) diff --git a/src/utilities/logPermissionChangeByAccount.js b/src/utilities/logPermissionChangeByAccount.js index 56979c6c9..845eb2581 100644 --- a/src/utilities/logPermissionChangeByAccount.js +++ b/src/utilities/logPermissionChangeByAccount.js @@ -9,33 +9,24 @@ const changedPermissionsLogger = async (req, res, next) => { // Function saves logs to hgnData_dev.permissionChangeLogs collection const logPermissionChangeByAccount = async (requestBody) => { - const { updatedRole, userProfile, requestor } = requestBody + const { roleId, roleName, permissions, requestor, role, email } = requestBody const dateTime = moment().tz("America/Los_Angeles").format(); try { - // Extract relevant data from the request - const { roleId, roleName, permissions } = updatedRole; // Adjust this as per your request body structure - const { role, email } = userProfile; - const { requestorId } = requestor; - - // Create a new PermissionChangeLog object const logEntry = new PermissionChangeLog({ logDateTime: dateTime, roleId: roleId, roleName: roleName, permissions: permissions, - requestorId: requestorId, + requestorId: requestor.requestorId, requestorRole: role, requestorEmail: email, }); - // Save the log entry to the database await logEntry.save(); } catch (error) { - // Handle any errors that occur during logging console.error('Error logging permission change:', error); - // You can choose to send an error response to the client or handle it differently res.status(500).json({ error: 'Failed to log permission change' }); } } From 7a8cf99f520fc106feebe5d4fa37994fbb0db001 Mon Sep 17 00:00:00 2001 From: Jerry Ren Date: Fri, 15 Sep 2023 18:45:29 -0400 Subject: [PATCH 3/5] Added router + controller for permissionChangeLog --- src/controllers/permissionChangeLogsController.js | 15 +++++++++++++++ src/routes/permissionChangeLogsRouter.js | 14 ++++++++++++++ src/startup/routes.js | 3 +++ 3 files changed, 32 insertions(+) create mode 100644 src/controllers/permissionChangeLogsController.js create mode 100644 src/routes/permissionChangeLogsRouter.js diff --git a/src/controllers/permissionChangeLogsController.js b/src/controllers/permissionChangeLogsController.js new file mode 100644 index 000000000..c81708e13 --- /dev/null +++ b/src/controllers/permissionChangeLogsController.js @@ -0,0 +1,15 @@ +const permissionChangeLogController = function (PermissionChangeLog) { + const getPermissionChangeLogs = async function (req, res) { + // Check if user is Owner here. Skipped for now. + + const changeLogs = await PermissionChangeLog.find({}) + console.log("🚀 ~ file: permissionChangeLogsController.js:8 ~ getPermissionChangeLogs ~ changeLogs:", changeLogs) + res.status(200).send(changeLogs) + } + + return { + getPermissionChangeLogs + } +} + +module.exports = permissionChangeLogController \ No newline at end of file diff --git a/src/routes/permissionChangeLogsRouter.js b/src/routes/permissionChangeLogsRouter.js new file mode 100644 index 000000000..8a454c611 --- /dev/null +++ b/src/routes/permissionChangeLogsRouter.js @@ -0,0 +1,14 @@ +const express = require('express'); + +const routes = function (permissionChangeLog) { + const controller = require('../controllers/permissionChangeLogsController')(permissionChangeLog) + + const permissionChangeLogRouter = express.Router() + + permissionChangeLogRouter.route("/permissionChangeLogs") + .get(controller.getPermissionChangeLogs) + + return permissionChangeLogRouter +} + +module.exports = routes \ No newline at end of file diff --git a/src/startup/routes.js b/src/startup/routes.js index 6e000002e..7989e5235 100644 --- a/src/startup/routes.js +++ b/src/startup/routes.js @@ -20,6 +20,7 @@ const ownerStandardMessage = require('../models/ownerStandardMessage'); const profileInitialSetuptoken = require('../models/profileInitialSetupToken'); const reason = require('../models/reason'); const mouseoverText = require('../models/mouseoverText'); +const permissionChangeLog = require('../models/permissionChangeLog') const userProfileRouter = require('../routes/userProfileRouter')(userProfile); const badgeRouter = require('../routes/badgeRouter')(badge); @@ -43,6 +44,7 @@ const taskNotificationRouter = require('../routes/taskNotificationRouter')(taskN const inventoryRouter = require('../routes/inventoryRouter')(inventoryItem, inventoryItemType); const timeZoneAPIRouter = require('../routes/timeZoneAPIRoutes')(); const profileInitialSetupRouter = require('../routes/profileInitialSetupRouter')(profileInitialSetuptoken, userProfile, project); +const permissionChangeLogRouter = require('../routes/permissionChangeLogsRouter')(permissionChangeLog) const taskEditSuggestion = require('../models/taskEditSuggestion'); const taskEditSuggestionRouter = require('../routes/taskEditSuggestionRouter')(taskEditSuggestion); @@ -83,4 +85,5 @@ module.exports = function (app) { app.use('/api', reasonRouter); app.use('/api', informationRouter); app.use('/api', mouseoverTextRouter); + app.use('/api', permissionChangeLogRouter); }; From c2cd1e5692ed84682ee4456d8091097903f18582 Mon Sep 17 00:00:00 2001 From: Jerry Ren Date: Wed, 20 Sep 2023 20:31:03 -0400 Subject: [PATCH 4/5] Added Permissions Added/Removed columns to table --- src/models/permissionChangeLog.js | 2 + src/utilities/logPermissionChangeByAccount.js | 48 +++++++++++++++++-- 2 files changed, 47 insertions(+), 3 deletions(-) diff --git a/src/models/permissionChangeLog.js b/src/models/permissionChangeLog.js index cd9eb6899..3ca37e416 100644 --- a/src/models/permissionChangeLog.js +++ b/src/models/permissionChangeLog.js @@ -13,6 +13,8 @@ const PermissionChangeLog = new Schema({ }, roleName: { type: String }, permissions: { type: [String], required: true }, + permissionsAdded: { type: [String], required: true }, + permissionsRemoved: { type: [String], required: true }, requestorId: { type: mongoose.Types.ObjectId, ref: User diff --git a/src/utilities/logPermissionChangeByAccount.js b/src/utilities/logPermissionChangeByAccount.js index 845eb2581..3f5a2ffe3 100644 --- a/src/utilities/logPermissionChangeByAccount.js +++ b/src/utilities/logPermissionChangeByAccount.js @@ -7,25 +7,67 @@ const changedPermissionsLogger = async (req, res, next) => { next(); }; +// Helper function finds the latest log related to the permission +const findLatestRelatedLog = (roleId) => { + + return new Promise((resolve, reject) => { + PermissionChangeLog.findOne({ roleId: roleId }) + .sort({ logDateTime: -1 }) + .exec((err, document) => { + if (err) { + console.error(err); + reject(err); + return; + } + console.log("🚀 ~ file: logPermissionChangeByAccount.js:20 ~ .exec ~ document:", document); + resolve(document); + }); + }) +} + // Function saves logs to hgnData_dev.permissionChangeLogs collection const logPermissionChangeByAccount = async (requestBody) => { const { roleId, roleName, permissions, requestor, role, email } = requestBody const dateTime = moment().tz("America/Los_Angeles").format(); try { + let permissionsAdded = [] + let permissionsRemoved = [] + + // Find the latest log related to permission + const document = await findLatestRelatedLog(roleId) + console.log("🚀 ~ file: logPermissionChangeByAccount.js:36 ~ logPermissionChangeByAccount ~ document:", document) + + if (document) { + // console.log(document); + console.log("🚀 ~ file: logPermissionChangeByAccount.js:29 ~ .exec ~ document:", document) + permissionsRemoved = document.permissions.filter(item => !(permissions.includes(item))) + console.log("🚀 ~ file: logPermissionChangeByAccount.js:31 ~ .exec ~ permissionsRemoved:", permissionsRemoved) + permissionsAdded = permissions.filter(item => !(document.permissions.includes(item))) + console.log("🚀 ~ file: logPermissionChangeByAccount.js:33 ~ .exec ~ permissionsAdded:", permissionsAdded) + } else { + // else this is the first permissions change log for this particular role + permissionsAdded = permissions + } + + const logEntry = new PermissionChangeLog({ logDateTime: dateTime, roleId: roleId, roleName: roleName, permissions: permissions, + permissionsAdded: permissionsAdded, + permissionsRemoved: permissionsRemoved, requestorId: requestor.requestorId, requestorRole: role, requestorEmail: email, - }); + }) + + console.log("🚀 ~ file: logPermissionChangeByAccount.js:46 ~ .exec ~ logEntry:", logEntry) - await logEntry.save(); + await logEntry.save() - } catch (error) { + } catch (error) { console.error('Error logging permission change:', error); res.status(500).json({ error: 'Failed to log permission change' }); } From d516ccc81d7d69575b132054eff4ee532b157b1e Mon Sep 17 00:00:00 2001 From: Jerry Ren Date: Thu, 21 Sep 2023 12:51:56 -0400 Subject: [PATCH 5/5] Edited Permission Change Logs controller + router Edited controller and router related to PermissionChangeLog to handle getting permissionChangeLogs from the database. --- .../permissionChangeLogsController.js | 23 +++++++++++++++---- src/routes/permissionChangeLogsRouter.js | 2 +- src/utilities/logPermissionChangeByAccount.js | 8 ------- 3 files changed, 20 insertions(+), 13 deletions(-) diff --git a/src/controllers/permissionChangeLogsController.js b/src/controllers/permissionChangeLogsController.js index c81708e13..317b9f144 100644 --- a/src/controllers/permissionChangeLogsController.js +++ b/src/controllers/permissionChangeLogsController.js @@ -1,10 +1,25 @@ +const UserProfile = require('../models/userProfile'); + const permissionChangeLogController = function (PermissionChangeLog) { + const getPermissionChangeLogs = async function (req, res) { - // Check if user is Owner here. Skipped for now. - const changeLogs = await PermissionChangeLog.find({}) - console.log("🚀 ~ file: permissionChangeLogsController.js:8 ~ getPermissionChangeLogs ~ changeLogs:", changeLogs) - res.status(200).send(changeLogs) + try { + const userProfile = await UserProfile.findOne({ _id: req.params.userId }).exec() + + if (userProfile) { + if (userProfile.role !== 'Owner') { + res.status(204).send([]) + } else { + const changeLogs = await PermissionChangeLog.find({}) + res.status(200).send(changeLogs) + } + } else { + res.status(403).send(`User (${req.params.userId}) not found.`) + } + } catch (err) { + console.error(err) + } } return { diff --git a/src/routes/permissionChangeLogsRouter.js b/src/routes/permissionChangeLogsRouter.js index 8a454c611..8c1f46219 100644 --- a/src/routes/permissionChangeLogsRouter.js +++ b/src/routes/permissionChangeLogsRouter.js @@ -5,7 +5,7 @@ const routes = function (permissionChangeLog) { const permissionChangeLogRouter = express.Router() - permissionChangeLogRouter.route("/permissionChangeLogs") + permissionChangeLogRouter.route("/permissionChangeLogs/:userId") .get(controller.getPermissionChangeLogs) return permissionChangeLogRouter diff --git a/src/utilities/logPermissionChangeByAccount.js b/src/utilities/logPermissionChangeByAccount.js index 3f5a2ffe3..dac2a4016 100644 --- a/src/utilities/logPermissionChangeByAccount.js +++ b/src/utilities/logPermissionChangeByAccount.js @@ -19,7 +19,6 @@ const findLatestRelatedLog = (roleId) => { reject(err); return; } - console.log("🚀 ~ file: logPermissionChangeByAccount.js:20 ~ .exec ~ document:", document); resolve(document); }); }) @@ -36,15 +35,10 @@ const logPermissionChangeByAccount = async (requestBody) => { // Find the latest log related to permission const document = await findLatestRelatedLog(roleId) - console.log("🚀 ~ file: logPermissionChangeByAccount.js:36 ~ logPermissionChangeByAccount ~ document:", document) if (document) { - // console.log(document); - console.log("🚀 ~ file: logPermissionChangeByAccount.js:29 ~ .exec ~ document:", document) permissionsRemoved = document.permissions.filter(item => !(permissions.includes(item))) - console.log("🚀 ~ file: logPermissionChangeByAccount.js:31 ~ .exec ~ permissionsRemoved:", permissionsRemoved) permissionsAdded = permissions.filter(item => !(document.permissions.includes(item))) - console.log("🚀 ~ file: logPermissionChangeByAccount.js:33 ~ .exec ~ permissionsAdded:", permissionsAdded) } else { // else this is the first permissions change log for this particular role permissionsAdded = permissions @@ -62,8 +56,6 @@ const logPermissionChangeByAccount = async (requestBody) => { requestorRole: role, requestorEmail: email, }) - - console.log("🚀 ~ file: logPermissionChangeByAccount.js:46 ~ .exec ~ logEntry:", logEntry) await logEntry.save()