diff --git a/services/web/app/src/Features/Collaborators/CollaboratorsController.mjs b/services/web/app/src/Features/Collaborators/CollaboratorsController.mjs index 849c10d5c5..f7ce8ece8a 100644 --- a/services/web/app/src/Features/Collaborators/CollaboratorsController.mjs +++ b/services/web/app/src/Features/Collaborators/CollaboratorsController.mjs @@ -17,6 +17,7 @@ import LimitationsManager from '../Subscription/LimitationsManager.mjs' import PrivilegeLevels from '../Authorization/PrivilegeLevels.mjs' import { z, zz, parseReq } from '../../infrastructure/Validation.mjs' import Features from '../../infrastructure/Features.mjs' +import UserGetter from '../User/UserGetter.mjs' const { hasAdminAccess } = AdminAuthorizationHelper const ObjectId = mongodb.ObjectId @@ -39,12 +40,20 @@ async function removeUserFromProject(req, res, next) { members: true, }) + const removedUser = await UserGetter.promises.getUser( + { _id: userId }, + { email: 1 } + ) + ProjectAuditLogHandler.addEntryInBackground( projectId, 'remove-collaborator', sessionUserId, req.ip, - { userId } + { + userId, + collaboratorEmail: removedUser?.email, + } ) res.sendStatus(204) diff --git a/services/web/app/src/Features/Collaborators/CollaboratorsInviteController.mjs b/services/web/app/src/Features/Collaborators/CollaboratorsInviteController.mjs index 7cbcb38f8e..099e6a5887 100644 --- a/services/web/app/src/Features/Collaborators/CollaboratorsInviteController.mjs +++ b/services/web/app/src/Features/Collaborators/CollaboratorsInviteController.mjs @@ -204,6 +204,7 @@ async function revokeInvite(req, res) { req.ip, { inviteId: invite._id, + collaboratorEmail: invite.email, role: CollaboratorsInviteHelper.privilegeLevelToRole(invite.privileges), } ) @@ -380,6 +381,7 @@ async function acceptInvite(req, res) { req.ip, { inviteId: invite._id, + collaboratorEmail: invite.email, privileges: invite.privileges, } ) diff --git a/services/web/test/unit/src/Collaborators/CollaboratorsController.test.mjs b/services/web/test/unit/src/Collaborators/CollaboratorsController.test.mjs index eb61d8073f..cafc5cddd3 100644 --- a/services/web/test/unit/src/Collaborators/CollaboratorsController.test.mjs +++ b/services/web/test/unit/src/Collaborators/CollaboratorsController.test.mjs @@ -19,7 +19,7 @@ describe('CollaboratorsController', function () { ctx.res = new MockResponse(vi) ctx.req = new MockRequest(vi) - ctx.user = { _id: new ObjectId() } + ctx.user = { _id: new ObjectId(), email: 'user@example.com' } ctx.projectId = new ObjectId() ctx.callback = sinon.stub() @@ -51,6 +51,13 @@ describe('CollaboratorsController', function () { getSessionUser: sinon.stub().returns(ctx.user), getLoggedInUserId: sinon.stub().returns(ctx.user._id), } + + ctx.UserGetter = { + promises: { + getAllInvitedMembers: sinon.stub(), + getUser: sinon.stub().resolves(ctx.user), + }, + } ctx.OwnershipTransferHandler = { promises: { transferOwnership: sinon.stub().resolves(), @@ -133,6 +140,10 @@ describe('CollaboratorsController', function () { }) ) + vi.doMock('../../../../app/src/Features/User/UserGetter.mjs', () => ({ + default: ctx.UserGetter, + })) + vi.doMock( '../../../../app/src/Features/TokenAccess/TokenAccessHandler.mjs', () => ({ @@ -207,13 +218,23 @@ describe('CollaboratorsController', function () { ) }) + it('should look up the collaborator email', function (ctx) { + expect(ctx.UserGetter.promises.getUser).to.have.been.calledWith( + { _id: ctx.user._id }, + { email: 1 } + ) + }) + it('should write a project audit log', function (ctx) { ctx.ProjectAuditLogHandler.addEntryInBackground.should.have.been.calledWith( ctx.projectId, 'remove-collaborator', ctx.user._id, ctx.req.ip, - { userId: ctx.user._id } + { + userId: ctx.user._id, + collaboratorEmail: 'user@example.com', + } ) }) }) diff --git a/services/web/test/unit/src/Collaborators/CollaboratorsInviteController.test.mjs b/services/web/test/unit/src/Collaborators/CollaboratorsInviteController.test.mjs index 8c61e5e479..442067db1b 100644 --- a/services/web/test/unit/src/Collaborators/CollaboratorsInviteController.test.mjs +++ b/services/web/test/unit/src/Collaborators/CollaboratorsInviteController.test.mjs @@ -70,7 +70,7 @@ describe('CollaboratorsInviteController', function () { ctx.UserGetter = { promises: { getUserByAnyEmail: sinon.stub(), - getUser: sinon.stub(), + getUser: sinon.stub().resolves(ctx.currentUser), }, } @@ -1600,6 +1600,7 @@ describe('CollaboratorsInviteController', function () { ctx.req.ip, { inviteId: ctx.invite._id, + collaboratorEmail: ctx.invite.email, role: ctx.role, } ) @@ -1689,6 +1690,7 @@ describe('CollaboratorsInviteController', function () { ctx.req.ip, { inviteId: ctx.invite._id, + collaboratorEmail: ctx.invite.email, privileges: ctx.privileges, } )