diff --git a/apps/meteor/app/api/server/index.ts b/apps/meteor/app/api/server/index.ts index e4f6370bfb069..9efdb889fd0d7 100644 --- a/apps/meteor/app/api/server/index.ts +++ b/apps/meteor/app/api/server/index.ts @@ -48,7 +48,6 @@ import './v1/voip/omnichannel'; import './v1/voip'; import './v1/federation'; import './v1/moderation'; -import './v1/server-events'; // This has to come last so all endpoints are registered before generating the OpenAPI documentation import './default/openApi'; diff --git a/apps/meteor/app/api/server/v1/server-events.ts b/apps/meteor/app/api/server/v1/server-events.ts deleted file mode 100644 index 59fe33d41e530..0000000000000 --- a/apps/meteor/app/api/server/v1/server-events.ts +++ /dev/null @@ -1,104 +0,0 @@ -import { ServerEvents } from '@rocket.chat/models'; -import { isServerEventsAuditSettingsProps } from '@rocket.chat/rest-typings'; -import { ajv } from '@rocket.chat/rest-typings/src/v1/Ajv'; - -import { API } from '../api'; -import { getPaginationItems } from '../helpers/getPaginationItems'; - -API.v1.get( - 'audit.settings', - { - response: { - 200: ajv.compile({ - additionalProperties: false, - type: 'object', - properties: { - events: { - type: 'array', - items: { - type: 'object', - }, - }, - count: { - type: 'number', - description: 'The number of events returned in this response.', - }, - offset: { - type: 'number', - description: 'The number of events that were skipped in this response.', - }, - total: { - type: 'number', - description: 'The total number of events that match the query.', - }, - success: { - type: 'boolean', - description: 'Indicates if the request was successful.', - }, - }, - required: ['events', 'count', 'offset', 'total', 'success'], - }), - 400: ajv.compile({ - type: 'object', - properties: { - success: { - type: 'boolean', - enum: [false], - }, - error: { - type: 'string', - }, - errorType: { - type: 'string', - }, - }, - required: ['success', 'error'], - }), - }, - query: isServerEventsAuditSettingsProps, - authRequired: true, - permissionsRequired: ['can-audit'], - }, - async function action() { - const { start, end, settingId, actor } = this.queryParams; - - if (start && isNaN(Date.parse(start as string))) { - return API.v1.failure('The "start" query parameter must be a valid date.'); - } - - if (end && isNaN(Date.parse(end as string))) { - return API.v1.failure('The "end" query parameter must be a valid date.'); - } - - const { offset, count } = await getPaginationItems(this.queryParams as Record); - const { sort } = await this.parseJsonQuery(); - const _sort = { ts: sort?.ts ? sort?.ts : -1 }; - - const { cursor, totalCount } = ServerEvents.findPaginated( - { - ...(settingId && { 'data.key': 'id', 'data.value': settingId }), - ...(actor && { actor }), - ts: { - $gte: start ? new Date(start as string) : new Date(0), - $lte: end ? new Date(end as string) : new Date(), - }, - t: 'settings.changed', - }, - { - sort: _sort, - skip: offset, - limit: count, - allowDiskUse: true, - }, - ); - - const [events, total] = await Promise.all([cursor.toArray(), totalCount]); - - return API.v1.success({ - events, - count: events.length, - offset, - total, - }); - }, -); diff --git a/apps/meteor/ee/server/api/audit.ts b/apps/meteor/ee/server/api/audit.ts index 61a0c618b410d..f86db47db4df2 100644 --- a/apps/meteor/ee/server/api/audit.ts +++ b/apps/meteor/ee/server/api/audit.ts @@ -1,5 +1,6 @@ import type { IUser, IRoom } from '@rocket.chat/core-typings'; -import { Rooms, AuditLog } from '@rocket.chat/models'; +import { Rooms, AuditLog, ServerEvents } from '@rocket.chat/models'; +import { isServerEventsAuditSettingsProps } from '@rocket.chat/rest-typings'; import type { PaginatedRequest, PaginatedResult } from '@rocket.chat/rest-typings'; import Ajv from 'ajv'; @@ -98,3 +99,102 @@ API.v1.addRoute( }, }, ); + +API.v1.get( + 'audit.settings', + { + response: { + 200: ajv.compile({ + additionalProperties: false, + type: 'object', + properties: { + events: { + type: 'array', + items: { + type: 'object', + }, + }, + count: { + type: 'number', + description: 'The number of events returned in this response.', + }, + offset: { + type: 'number', + description: 'The number of events that were skipped in this response.', + }, + total: { + type: 'number', + description: 'The total number of events that match the query.', + }, + success: { + type: 'boolean', + description: 'Indicates if the request was successful.', + }, + }, + required: ['events', 'count', 'offset', 'total', 'success'], + }), + 400: ajv.compile({ + type: 'object', + properties: { + success: { + type: 'boolean', + enum: [false], + }, + error: { + type: 'string', + }, + errorType: { + type: 'string', + }, + }, + required: ['success', 'error'], + }), + }, + query: isServerEventsAuditSettingsProps, + authRequired: true, + permissionsRequired: ['can-audit'], + license: ['auditing'], + }, + async function action() { + const { start, end, settingId, actor } = this.queryParams; + + if (start && isNaN(Date.parse(start as string))) { + return API.v1.failure('The "start" query parameter must be a valid date.'); + } + + if (end && isNaN(Date.parse(end as string))) { + return API.v1.failure('The "end" query parameter must be a valid date.'); + } + + const { offset, count } = await getPaginationItems(this.queryParams as Record); + const { sort } = await this.parseJsonQuery(); + const _sort = { ts: sort?.ts ? sort?.ts : -1 }; + + const { cursor, totalCount } = ServerEvents.findPaginated( + { + ...(settingId && { 'data.key': 'id', 'data.value': settingId }), + ...(actor && { actor }), + ts: { + $gte: start ? new Date(start as string) : new Date(0), + $lte: end ? new Date(end as string) : new Date(), + }, + t: 'settings.changed', + }, + { + sort: _sort, + skip: offset, + limit: count, + allowDiskUse: true, + }, + ); + + const [events, total] = await Promise.all([cursor.toArray(), totalCount]); + + return API.v1.success({ + events, + count: events.length, + offset, + total, + }); + }, +); diff --git a/apps/meteor/tests/end-to-end/api/settings.ts b/apps/meteor/tests/end-to-end/api/settings.ts index 6cd635e41e8f8..be301ed4a088a 100644 --- a/apps/meteor/tests/end-to-end/api/settings.ts +++ b/apps/meteor/tests/end-to-end/api/settings.ts @@ -4,6 +4,7 @@ import { before, describe, it, after } from 'mocha'; import { getCredentials, api, request, credentials } from '../../data/api-data'; import { updatePermission, updateSetting } from '../../data/permissions.helper'; +import { IS_EE } from '../../e2e/config/constants'; describe('[Settings]', () => { before((done) => getCredentials(done)); @@ -274,7 +275,7 @@ describe('[Settings]', () => { }); }); - describe('/audit.settings', () => { + (IS_EE ? describe : describe.skip)('/audit.settings', () => { const formatDate = (date: Date) => date.toISOString().slice(0, 10).replace(/-/g, '/'); it('should return list of settings changed (no filters)', async () => {