From f4365b7dd45ab3f3e42de703ff76584b069f5a66 Mon Sep 17 00:00:00 2001 From: Ricardo Garim Date: Fri, 18 Oct 2024 21:54:33 -0300 Subject: [PATCH] chore!: remove query field on custom emojis listing (#33650) --- .changeset/perfect-wolves-impress.md | 6 +++ .../app/api/server/helpers/parseJsonQuery.ts | 1 + apps/meteor/app/api/server/v1/emoji-custom.ts | 42 +++++++++++++++---- .../customEmoji/EditCustomEmojiWithData.tsx | 2 +- .../tests/end-to-end/api/emoji-custom.ts | 4 +- packages/rest-typings/src/v1/emojiCustom.ts | 13 +++--- 6 files changed, 51 insertions(+), 17 deletions(-) create mode 100644 .changeset/perfect-wolves-impress.md diff --git a/.changeset/perfect-wolves-impress.md b/.changeset/perfect-wolves-impress.md new file mode 100644 index 000000000000..becaf1d706d2 --- /dev/null +++ b/.changeset/perfect-wolves-impress.md @@ -0,0 +1,6 @@ +--- +'@rocket.chat/rest-typings': major +'@rocket.chat/meteor': major +--- + +Changes custom emoji listing endpoint by moving query params from the 'query' attribute to standard query parameters. diff --git a/apps/meteor/app/api/server/helpers/parseJsonQuery.ts b/apps/meteor/app/api/server/helpers/parseJsonQuery.ts index bbd58e118556..35fe6155a396 100644 --- a/apps/meteor/app/api/server/helpers/parseJsonQuery.ts +++ b/apps/meteor/app/api/server/helpers/parseJsonQuery.ts @@ -62,6 +62,7 @@ export async function parseJsonQuery(api: PartialThis): Promise<{ '/api/v1/custom-sounds.list', '/api/v1/channels.list', '/api/v1/channels.online', + '/api/v1/emoji-custom.list', ].includes(route); const isUnsafeQueryParamsAllowed = process.env.ALLOW_UNSAFE_QUERY_AND_FIELDS_API_PARAMS?.toUpperCase() === 'TRUE'; diff --git a/apps/meteor/app/api/server/v1/emoji-custom.ts b/apps/meteor/app/api/server/v1/emoji-custom.ts index 9cbf202896e1..261743e6c0a9 100644 --- a/apps/meteor/app/api/server/v1/emoji-custom.ts +++ b/apps/meteor/app/api/server/v1/emoji-custom.ts @@ -1,5 +1,6 @@ import { Media } from '@rocket.chat/core-services'; import { EmojiCustom } from '@rocket.chat/models'; +import { isEmojiCustomList } from '@rocket.chat/rest-typings'; import { Meteor } from 'meteor/meteor'; import { SystemLogger } from '../../../../server/lib/logger/system'; @@ -11,22 +12,41 @@ import { getPaginationItems } from '../helpers/getPaginationItems'; import { findEmojisCustom } from '../lib/emoji-custom'; import { getUploadFormData } from '../lib/getUploadFormData'; +function validateDateParam(paramName: string, paramValue: string | undefined): Date | undefined { + if (!paramValue) { + return undefined; + } + + const date = new Date(paramValue); + if (isNaN(date.getTime())) { + throw new Meteor.Error('error-roomId-param-invalid', `The "${paramName}" query parameter must be a valid date.`); + } + + return date; +} + API.v1.addRoute( 'emoji-custom.list', - { authRequired: true }, + { authRequired: true, validateParams: isEmojiCustomList }, { async get() { const { query } = await this.parseJsonQuery(); - const { updatedSince } = this.queryParams; - if (updatedSince) { - const updatedSinceDate = new Date(updatedSince); - if (isNaN(Date.parse(updatedSince))) { - throw new Meteor.Error('error-roomId-param-invalid', 'The "updatedSince" query parameter must be a valid date.'); - } + const { updatedSince, _updatedAt, _id } = this.queryParams; + + const updatedSinceDate = validateDateParam('updatedSince', updatedSince); + const _updatedAtDate = validateDateParam('_updatedAt', _updatedAt); + + if (updatedSinceDate) { const [update, remove] = await Promise.all([ - EmojiCustom.find({ ...query, _updatedAt: { $gt: updatedSinceDate } }).toArray(), + EmojiCustom.find({ + ...query, + ...(_id ? { _id } : {}), + ...(_updatedAtDate ? { _updatedAt: { $gt: _updatedAtDate } } : {}), + _updatedAt: { $gt: updatedSinceDate }, + }).toArray(), EmojiCustom.trashFindDeletedAfter(updatedSinceDate).toArray(), ]); + return API.v1.success({ emojis: { update, @@ -37,7 +57,11 @@ API.v1.addRoute( return API.v1.success({ emojis: { - update: await EmojiCustom.find(query).toArray(), + update: await EmojiCustom.find({ + ...query, + ...(_id ? { _id } : {}), + ...(_updatedAtDate ? { _updatedAt: { $gt: _updatedAtDate } } : {}), + }).toArray(), remove: [], }, }); diff --git a/apps/meteor/client/views/admin/customEmoji/EditCustomEmojiWithData.tsx b/apps/meteor/client/views/admin/customEmoji/EditCustomEmojiWithData.tsx index 2ee8a79f5568..fff37214b530 100644 --- a/apps/meteor/client/views/admin/customEmoji/EditCustomEmojiWithData.tsx +++ b/apps/meteor/client/views/admin/customEmoji/EditCustomEmojiWithData.tsx @@ -14,7 +14,7 @@ type EditCustomEmojiWithDataProps = { const EditCustomEmojiWithData = ({ _id, onChange, close, ...props }: EditCustomEmojiWithDataProps) => { const t = useTranslation(); - const query = useMemo(() => ({ query: JSON.stringify({ _id }) }), [_id]); + const query = useMemo(() => ({ _id }), [_id]); const getEmojis = useEndpoint('GET', '/v1/emoji-custom.list'); diff --git a/apps/meteor/tests/end-to-end/api/emoji-custom.ts b/apps/meteor/tests/end-to-end/api/emoji-custom.ts index 31042363836e..c87a83783e0e 100644 --- a/apps/meteor/tests/end-to-end/api/emoji-custom.ts +++ b/apps/meteor/tests/end-to-end/api/emoji-custom.ts @@ -214,7 +214,7 @@ describe('[EmojiCustom]', () => { it('should return emojis when use "query" query parameter', (done) => { void request .get(api('emoji-custom.list')) - .query({ query: `{ "_updatedAt": { "$gt": { "$date": "${new Date().toISOString()}" } } }` }) + .query({ _updatedAt: new Date().toISOString() }) .set(credentials) .expect(200) .expect((res) => { @@ -242,7 +242,7 @@ describe('[EmojiCustom]', () => { it('should return emojis when use both, "updateSince" and "query" query parameter', (done) => { void request .get(api('emoji-custom.list')) - .query({ query: `{"_updatedAt": {"$gt": { "$date": "${new Date().toISOString()}" } }}`, updatedSince: new Date().toISOString() }) + .query({ _updatedAt: new Date().toISOString(), updatedSince: new Date().toISOString() }) .set(credentials) .expect(200) .expect((res) => { diff --git a/packages/rest-typings/src/v1/emojiCustom.ts b/packages/rest-typings/src/v1/emojiCustom.ts index e0cd87906c36..1ffb41f671a8 100644 --- a/packages/rest-typings/src/v1/emojiCustom.ts +++ b/packages/rest-typings/src/v1/emojiCustom.ts @@ -25,10 +25,7 @@ const emojiCustomDeletePropsSchema = { export const isEmojiCustomDelete = ajv.compile(emojiCustomDeletePropsSchema); -type emojiCustomList = { - query: string; - updatedSince?: string; -}; +type emojiCustomList = { query?: string; updatedSince?: string; _updatedAt?: string; _id?: string }; const emojiCustomListSchema = { type: 'object', @@ -40,8 +37,14 @@ const emojiCustomListSchema = { type: 'string', nullable: true, }, + _updatedAt: { + type: 'string', + }, + _id: { + type: 'string', + }, }, - required: ['query'], + required: [], additionalProperties: false, };