From 4b5f31ac9567c8d12fad409c10aa99e16e62f145 Mon Sep 17 00:00:00 2001 From: Jessica Lawshe <5312836+lawshe@users.noreply.github.com> Date: Wed, 7 May 2025 10:15:36 -0500 Subject: [PATCH] Merge pull request #25353 from overleaf/revert-25351-revert-24919-jel-create-group-audit-log Revert "Revert "[web] Add group audit log"" GitOrigin-RevId: 4d61cfd9e8a7dac1f5837a4028aff95fa19c308a --- .../web/app/src/infrastructure/mongodb.js | 1 + .../web/app/src/models/GroupAuditLogEntry.js | 23 ++++++++++++ services/web/frontend/js/utils/meta.ts | 1 + .../20250409155536_group_audit_log_index.mjs | 35 +++++++++++++++++++ .../test/acceptance/src/helpers/groupSSO.mjs | 18 +++++----- 5 files changed, 70 insertions(+), 8 deletions(-) create mode 100644 services/web/app/src/models/GroupAuditLogEntry.js create mode 100644 services/web/migrations/20250409155536_group_audit_log_index.mjs diff --git a/services/web/app/src/infrastructure/mongodb.js b/services/web/app/src/infrastructure/mongodb.js index aa7aa4ac44..7fc1039140 100644 --- a/services/web/app/src/infrastructure/mongodb.js +++ b/services/web/app/src/infrastructure/mongodb.js @@ -49,6 +49,7 @@ const db = { githubSyncUserCredentials: internalDb.collection('githubSyncUserCredentials'), globalMetrics: internalDb.collection('globalMetrics'), grouppolicies: internalDb.collection('grouppolicies'), + groupAuditLogEntries: internalDb.collection('groupAuditLogEntries'), institutions: internalDb.collection('institutions'), messages: internalDb.collection('messages'), migrations: internalDb.collection('migrations'), diff --git a/services/web/app/src/models/GroupAuditLogEntry.js b/services/web/app/src/models/GroupAuditLogEntry.js new file mode 100644 index 0000000000..3bda4ebf95 --- /dev/null +++ b/services/web/app/src/models/GroupAuditLogEntry.js @@ -0,0 +1,23 @@ +const mongoose = require('../infrastructure/Mongoose') +const { Schema } = mongoose + +const GroupAuditLogEntrySchema = new Schema( + { + groupId: { type: Schema.Types.ObjectId, index: true }, + info: { type: Object }, + initiatorId: { type: Schema.Types.ObjectId }, + ipAddress: { type: String }, + operation: { type: String }, + timestamp: { type: Date, default: Date.now }, + }, + { + collection: 'groupAuditLogEntries', + minimize: false, + } +) + +exports.GroupAuditLogEntry = mongoose.model( + 'GroupAuditLogEntry', + GroupAuditLogEntrySchema +) +exports.GroupAuditLogEntrySchema = GroupAuditLogEntrySchema diff --git a/services/web/frontend/js/utils/meta.ts b/services/web/frontend/js/utils/meta.ts index 7aab88b050..6c7209a5bb 100644 --- a/services/web/frontend/js/utils/meta.ts +++ b/services/web/frontend/js/utils/meta.ts @@ -103,6 +103,7 @@ export interface Meta { 'ol-gitBridgeEnabled': boolean 'ol-gitBridgePublicBaseUrl': string 'ol-github': { enabled: boolean; error: boolean } + 'ol-groupAuditLogs': [] 'ol-groupId': string 'ol-groupName': string 'ol-groupPlans': GroupPlans diff --git a/services/web/migrations/20250409155536_group_audit_log_index.mjs b/services/web/migrations/20250409155536_group_audit_log_index.mjs new file mode 100644 index 0000000000..282b3c6d2d --- /dev/null +++ b/services/web/migrations/20250409155536_group_audit_log_index.mjs @@ -0,0 +1,35 @@ +/* eslint-disable no-unused-vars */ + +import Helpers from './lib/helpers.mjs' + +const tags = ['saas'] + +const indexes = [ + { + key: { + groupId: 1, + timestamp: 1, + }, + name: 'groupId_1_timestamp_1', + }, +] + +const migrate = async client => { + const { db } = client + await Helpers.addIndexesToCollection(db.groupAuditLogEntries, indexes) +} + +const rollback = async client => { + const { db } = client + try { + await Helpers.dropIndexesFromCollection(db.groupAuditLogEntries, indexes) + } catch (err) { + console.error('Something went wrong rolling back the migrations', err) + } +} + +export default { + tags, + migrate, + rollback, +} diff --git a/services/web/test/acceptance/src/helpers/groupSSO.mjs b/services/web/test/acceptance/src/helpers/groupSSO.mjs index f7efeb9e63..c5bde77236 100644 --- a/services/web/test/acceptance/src/helpers/groupSSO.mjs +++ b/services/web/test/acceptance/src/helpers/groupSSO.mjs @@ -34,7 +34,7 @@ export const baseSsoConfig = { userIdAttribute, } // the database also sets enabled and validated, but we cannot set that in the POST request for /manage/groups/:ID/settings/sso -export async function createGroupSSO() { +export async function createGroupSSO(SSOConfigValidated = true) { const nonSSOMemberHelper = await UserHelper.createUser() const nonSSOMember = nonSSOMemberHelper.user @@ -47,7 +47,7 @@ export async function createGroupSSO() { const ssoConfig = new SSOConfig({ ...baseSsoConfig, enabled: true, - validated: true, + validated: SSOConfigValidated, }) await ssoConfig.save() @@ -68,12 +68,14 @@ export async function createGroupSSO() { const enrollmentUrl = getEnrollmentUrl(subscriptionId) const internalProviderId = getProviderId(subscriptionId) - await linkGroupMember( - memberUser.email, - memberUser.password, - subscriptionId, - 'mock@email.com' - ) + if (SSOConfigValidated) { + await linkGroupMember( + memberUser.email, + memberUser.password, + subscriptionId, + 'mock@email.com' + ) + } const userHelper = new UserHelper()