Skip to content

Commit

Permalink
Merge pull request #530 from OneCommunityGlobal/jerry_track_who_chang…
Browse files Browse the repository at this point in the history
…es_permissions

Jerry - Track Who Changes Permissions On Permissions Management Page
  • Loading branch information
one-community authored Jan 18, 2024
2 parents e6c6620 + cea5f4a commit 556f90a
Show file tree
Hide file tree
Showing 6 changed files with 143 additions and 2 deletions.
30 changes: 30 additions & 0 deletions src/controllers/permissionChangeLogsController.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
const UserProfile = require('../models/userProfile');

const permissionChangeLogController = function (PermissionChangeLog) {

const getPermissionChangeLogs = async function (req, res) {

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 {
getPermissionChangeLogs
}
}

module.exports = permissionChangeLogController
26 changes: 26 additions & 0 deletions src/models/permissionChangeLog.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
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 },
permissionsAdded: { type: [String], required: true },
permissionsRemoved: { 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');
14 changes: 14 additions & 0 deletions src/routes/permissionChangeLogsRouter.js
Original file line number Diff line number Diff line change
@@ -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/:userId")
.get(controller.getPermissionChangeLogs)

return permissionChangeLogRouter
}

module.exports = routes
3 changes: 2 additions & 1 deletion src/routes/roleRouter.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
const express = require('express');
const changedPermissionsLogger = require('../utilities/logPermissionChangeByAccount')

const routes = function (role) {
const controller = require('../controllers/rolesController')(role);
Expand All @@ -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;
};
Expand Down
4 changes: 3 additions & 1 deletion src/startup/routes.js
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ const weeklySummaryAIPrompt = require('../models/weeklySummaryAIPrompt');
const profileInitialSetuptoken = require('../models/profileInitialSetupToken');
const reason = require('../models/reason');
const mouseoverText = require('../models/mouseoverText');
const permissionChangeLog = require('../models/permissionChangeLog')
// const inventoryItemMaterial = require('../models/inventoryItemMaterial');
const mapLocations = require('../models/mapLocation');
const buildingProject = require('../models/bmdashboard/buildingProject');
Expand Down Expand Up @@ -61,9 +62,9 @@ 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, mapLocations);
const permissionChangeLogRouter = require('../routes/permissionChangeLogsRouter')(permissionChangeLog)
const isEmailExistsRouter = require('../routes/isEmailExistsRouter')();


const taskEditSuggestion = require('../models/taskEditSuggestion');
const taskEditSuggestionRouter = require('../routes/taskEditSuggestionRouter')(taskEditSuggestion);
const roleRouter = require('../routes/roleRouter')(role);
Expand Down Expand Up @@ -112,6 +113,7 @@ module.exports = function (app) {
app.use('/api', reasonRouter);
app.use('/api', informationRouter);
app.use('/api', mouseoverTextRouter);
app.use('/api', permissionChangeLogRouter);
app.use('/api', isEmailExistsRouter);
app.use('/api', mapLocationRouter);
// bm dashboard
Expand Down
68 changes: 68 additions & 0 deletions src/utilities/logPermissionChangeByAccount.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
const moment = require("moment-timezone");
const PermissionChangeLog = require("../models/permissionChangeLog")

// Middleware function
const changedPermissionsLogger = async (req, res, next) => {
await logPermissionChangeByAccount(req.body)
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;
}
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)

if (document) {
permissionsRemoved = document.permissions.filter(item => !(permissions.includes(item)))
permissionsAdded = permissions.filter(item => !(document.permissions.includes(item)))
} 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,
})

await logEntry.save()

} catch (error) {
console.error('Error logging permission change:', error);
res.status(500).json({ error: 'Failed to log permission change' });
}
}

module.exports = changedPermissionsLogger;

0 comments on commit 556f90a

Please sign in to comment.