From 7955a6c1de3107a3458cd76458c5049a1bdc8239 Mon Sep 17 00:00:00 2001 From: Ricardo Garim Date: Fri, 18 Oct 2024 10:56:25 -0300 Subject: [PATCH 1/6] chore: remove query field on custom emojis listing --- .../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 | 15 ++++--- 5 files changed, 47 insertions(+), 17 deletions(-) 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..c3c9f495d5fd 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,16 @@ const emojiCustomListSchema = { type: 'string', nullable: true, }, + _updatedAt: { + type: 'string', + nullable: true, + }, + _id: { + type: 'string', + nullable: true, + }, }, - required: ['query'], + required: [], additionalProperties: false, }; From 863e2936517aa826c066a7482c57906f2ce79932 Mon Sep 17 00:00:00 2001 From: Ricardo Garim Date: Fri, 18 Oct 2024 12:41:19 -0300 Subject: [PATCH 2/6] chore: make query as optional --- packages/rest-typings/src/v1/emojiCustom.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/rest-typings/src/v1/emojiCustom.ts b/packages/rest-typings/src/v1/emojiCustom.ts index c3c9f495d5fd..cdcbbcd142ec 100644 --- a/packages/rest-typings/src/v1/emojiCustom.ts +++ b/packages/rest-typings/src/v1/emojiCustom.ts @@ -25,7 +25,7 @@ const emojiCustomDeletePropsSchema = { export const isEmojiCustomDelete = ajv.compile(emojiCustomDeletePropsSchema); -type emojiCustomList = { query: string; updatedSince?: string; _updatedAt?: string; _id?: string }; +type emojiCustomList = { query?: string; updatedSince?: string; _updatedAt?: string; _id?: string }; const emojiCustomListSchema = { type: 'object', From 9d03ace6b5e47958d5838411d9e4832cd850da1f Mon Sep 17 00:00:00 2001 From: Ricardo Garim Date: Fri, 18 Oct 2024 17:28:47 -0300 Subject: [PATCH 3/6] changeset added --- .changeset/perfect-wolves-impress.md | 6 ++++++ 1 file changed, 6 insertions(+) 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..cd83580e155d --- /dev/null +++ b/.changeset/perfect-wolves-impress.md @@ -0,0 +1,6 @@ +--- +'@rocket.chat/rest-typings': patch +'@rocket.chat/meteor': patch +--- + +Changed custom emoji listing endpoint by moving query params from the 'query' attribute to standard query parameters. From f41965988fd097fda574c1296a82733c1cc759e4 Mon Sep 17 00:00:00 2001 From: Marcos Spessatto Defendi Date: Fri, 18 Oct 2024 17:33:28 -0300 Subject: [PATCH 4/6] Update .changeset/perfect-wolves-impress.md --- .changeset/perfect-wolves-impress.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.changeset/perfect-wolves-impress.md b/.changeset/perfect-wolves-impress.md index cd83580e155d..f8921190de10 100644 --- a/.changeset/perfect-wolves-impress.md +++ b/.changeset/perfect-wolves-impress.md @@ -1,6 +1,6 @@ --- -'@rocket.chat/rest-typings': patch -'@rocket.chat/meteor': patch +'@rocket.chat/rest-typings': major +'@rocket.chat/meteor': major --- Changed custom emoji listing endpoint by moving query params from the 'query' attribute to standard query parameters. From 522df562fa196207bac9264eb2981d7da48dabe2 Mon Sep 17 00:00:00 2001 From: Ricardo Garim Date: Fri, 18 Oct 2024 19:16:36 -0300 Subject: [PATCH 5/6] Update .changeset/perfect-wolves-impress.md Co-authored-by: gabriellsh <40830821+gabriellsh@users.noreply.github.com> --- .changeset/perfect-wolves-impress.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.changeset/perfect-wolves-impress.md b/.changeset/perfect-wolves-impress.md index f8921190de10..becaf1d706d2 100644 --- a/.changeset/perfect-wolves-impress.md +++ b/.changeset/perfect-wolves-impress.md @@ -3,4 +3,4 @@ '@rocket.chat/meteor': major --- -Changed custom emoji listing endpoint by moving query params from the 'query' attribute to standard query parameters. +Changes custom emoji listing endpoint by moving query params from the 'query' attribute to standard query parameters. From e74c1a5614ae2de6b3fc31c85b1b346940cdc4c2 Mon Sep 17 00:00:00 2001 From: Ricardo Garim Date: Fri, 18 Oct 2024 20:01:01 -0300 Subject: [PATCH 6/6] chore: remove nullable option on _updatedAt and _id --- packages/rest-typings/src/v1/emojiCustom.ts | 2 -- 1 file changed, 2 deletions(-) diff --git a/packages/rest-typings/src/v1/emojiCustom.ts b/packages/rest-typings/src/v1/emojiCustom.ts index cdcbbcd142ec..1ffb41f671a8 100644 --- a/packages/rest-typings/src/v1/emojiCustom.ts +++ b/packages/rest-typings/src/v1/emojiCustom.ts @@ -39,11 +39,9 @@ const emojiCustomListSchema = { }, _updatedAt: { type: 'string', - nullable: true, }, _id: { type: 'string', - nullable: true, }, }, required: [],