From e80846bace7f7c678ecc0e289f565daa0ca84756 Mon Sep 17 00:00:00 2001 From: Domagoj Kriskovic Date: Tue, 18 Mar 2025 16:06:26 +0100 Subject: [PATCH] Update project-joined event to include role, mode, ownerId, and source (#23677) * Update project-joined event to include role, mode, ownerId, and source * fix test GitOrigin-RevId: 67c428a80f5791b69a57b6719ec795399e2a98ef --- .../CollaboratorsInviteController.mjs | 13 ++++++++++++- .../TokenAccess/TokenAccessController.mjs | 10 ++++++++-- .../Features/TokenAccess/TokenAccessHandler.js | 7 +++++-- .../TokenAccess/TokenAccessControllerTests.mjs | 17 ++++++++++++++--- .../src/TokenAccess/TokenAccessHandlerTests.js | 12 ++++++++++-- 5 files changed, 49 insertions(+), 10 deletions(-) diff --git a/services/web/app/src/Features/Collaborators/CollaboratorsInviteController.mjs b/services/web/app/src/Features/Collaborators/CollaboratorsInviteController.mjs index 722b1bdd4e..c6ffba1ea5 100644 --- a/services/web/app/src/Features/Collaborators/CollaboratorsInviteController.mjs +++ b/services/web/app/src/Features/Collaborators/CollaboratorsInviteController.mjs @@ -359,11 +359,22 @@ async function acceptInvite(req, res) { 'project:membership:changed', { invites: true, members: true } ) + + let editMode = 'edit' + if (invite.privileges === PrivilegeLevels.REVIEW) { + editMode = 'review' + } else if (invite.privileges === PrivilegeLevels.READ_ONLY) { + editMode = 'view' + } AnalyticsManager.recordEventForUserInBackground( currentUser._id, - 'project-invite-accept', + 'project-joined', { projectId, + ownerId: invite.sendingUserId, // only owner can invite others + mode: editMode, + role: invite.privileges, + source: 'email-invite', } ) diff --git a/services/web/app/src/Features/TokenAccess/TokenAccessController.mjs b/services/web/app/src/Features/TokenAccess/TokenAccessController.mjs index f573d3c726..63c29466f8 100644 --- a/services/web/app/src/Features/TokenAccess/TokenAccessController.mjs +++ b/services/web/app/src/Features/TokenAccess/TokenAccessController.mjs @@ -347,7 +347,12 @@ async function grantTokenAccessReadAndWrite(req, res, next) { } ) AnalyticsManager.recordEventForUserInBackground(userId, 'project-joined', { - mode: pendingEditor ? 'read-only' : 'read-write', + role: pendingEditor + ? PrivilegeLevels.READ_ONLY + : PrivilegeLevels.READ_AND_WRITE, + ownerId: project.owner_ref.toString(), + source: 'link-sharing', + mode: pendingEditor ? 'view' : 'edit', projectId: project._id.toString(), ...(pendingEditor && { pendingEditor: true }), }) @@ -450,7 +455,8 @@ async function grantTokenAccessReadOnly(req, res, next) { await TokenAccessHandler.promises.addReadOnlyUserToProject( userId, - project._id + project._id, + project.owner_ref ) return res.json({ diff --git a/services/web/app/src/Features/TokenAccess/TokenAccessHandler.js b/services/web/app/src/Features/TokenAccess/TokenAccessHandler.js index 06a5735e86..0d08903ec3 100644 --- a/services/web/app/src/Features/TokenAccess/TokenAccessHandler.js +++ b/services/web/app/src/Features/TokenAccess/TokenAccessHandler.js @@ -151,12 +151,15 @@ const TokenAccessHandler = { throw new Error('invalid token type') }, - async addReadOnlyUserToProject(userId, projectId) { + async addReadOnlyUserToProject(userId, projectId, ownerId) { userId = new ObjectId(userId.toString()) projectId = new ObjectId(projectId.toString()) Analytics.recordEventForUserInBackground(userId, 'project-joined', { - mode: 'read-only', + role: PrivilegeLevels.READ_ONLY, projectId: projectId.toString(), + source: 'link-sharing', + ownerId: ownerId.toString(), + mode: 'view', }) return await Project.updateOne( diff --git a/services/web/test/unit/src/TokenAccess/TokenAccessControllerTests.mjs b/services/web/test/unit/src/TokenAccess/TokenAccessControllerTests.mjs index 277330fdeb..8097218076 100644 --- a/services/web/test/unit/src/TokenAccess/TokenAccessControllerTests.mjs +++ b/services/web/test/unit/src/TokenAccess/TokenAccessControllerTests.mjs @@ -18,6 +18,7 @@ describe('TokenAccessController', function () { this.user = { _id: new ObjectId() } this.project = { _id: new ObjectId(), + owner_ref: this.user._id, name: 'test', tokenAccessReadAndWrite_refs: [], tokenAccessReadOnly_refs: [], @@ -242,8 +243,11 @@ describe('TokenAccessController', function () { expect( this.AnalyticsManager.recordEventForUserInBackground ).to.have.been.calledWith(this.user._id, 'project-joined', { - mode: 'read-write', + mode: 'edit', projectId: this.project._id.toString(), + ownerId: this.project.owner_ref.toString(), + role: PrivilegeLevels.READ_AND_WRITE, + source: 'link-sharing', }) }) @@ -316,9 +320,12 @@ describe('TokenAccessController', function () { expect( this.AnalyticsManager.recordEventForUserInBackground ).to.have.been.calledWith(this.user._id, 'project-joined', { - mode: 'read-only', + mode: 'view', projectId: this.project._id.toString(), pendingEditor: true, + ownerId: this.project.owner_ref.toString(), + role: PrivilegeLevels.READ_ONLY, + source: 'link-sharing', }) }) @@ -754,7 +761,11 @@ describe('TokenAccessController', function () { it('grants read-only access', function () { expect( this.TokenAccessHandler.promises.addReadOnlyUserToProject - ).to.have.been.calledWith(this.user._id, this.project._id) + ).to.have.been.calledWith( + this.user._id, + this.project._id, + this.project.owner_ref + ) }) it('writes a project audit log', function () { diff --git a/services/web/test/unit/src/TokenAccess/TokenAccessHandlerTests.js b/services/web/test/unit/src/TokenAccess/TokenAccessHandlerTests.js index 8a587437f0..52ed31d0a1 100644 --- a/services/web/test/unit/src/TokenAccess/TokenAccessHandlerTests.js +++ b/services/web/test/unit/src/TokenAccess/TokenAccessHandlerTests.js @@ -7,6 +7,7 @@ const modulePath = path.join( ) const { expect } = require('chai') const { ObjectId } = require('mongodb-legacy') +const PrivilegeLevels = require('../../../../app/src/Features/Authorization/PrivilegeLevels') describe('TokenAccessHandler', function () { beforeEach(function () { @@ -115,7 +116,8 @@ describe('TokenAccessHandler', function () { it('should call Project.updateOne', async function () { await this.TokenAccessHandler.promises.addReadOnlyUserToProject( this.userId, - this.projectId + this.projectId, + this.project.owner_ref ) expect(this.Project.updateOne.callCount).to.equal(1) expect( @@ -130,7 +132,13 @@ describe('TokenAccessHandler', function () { this.Analytics.recordEventForUserInBackground, this.userId, 'project-joined', - { mode: 'read-only', projectId: this.projectId.toString() } + { + mode: 'view', + role: PrivilegeLevels.READ_ONLY, + projectId: this.projectId.toString(), + ownerId: this.project.owner_ref.toString(), + source: 'link-sharing', + } ) })