From 9c891182c3335f7288570893085793944c840558 Mon Sep 17 00:00:00 2001 From: LucianoPierdona Date: Thu, 22 Dec 2022 15:00:08 -0300 Subject: [PATCH 01/15] draft: updating checks for block --- .../server/functions/canDeleteMessage.ts | 12 ++++++++---- .../server/functions/upsertPermissions.ts | 1 + apps/meteor/app/lib/server/methods/updateMessage.js | 4 +++- .../packages/rocketchat-i18n/i18n/en.i18n.json | 2 ++ apps/meteor/server/startup/migrations/index.ts | 1 + apps/meteor/server/startup/migrations/v282.ts | 9 +++++++++ 6 files changed, 24 insertions(+), 5 deletions(-) create mode 100644 apps/meteor/server/startup/migrations/v282.ts diff --git a/apps/meteor/app/authorization/server/functions/canDeleteMessage.ts b/apps/meteor/app/authorization/server/functions/canDeleteMessage.ts index 8ffb33958c26..aae0ae295efe 100644 --- a/apps/meteor/app/authorization/server/functions/canDeleteMessage.ts +++ b/apps/meteor/app/authorization/server/functions/canDeleteMessage.ts @@ -31,11 +31,15 @@ export const canDeleteMessageAsync = async (uid: string, { u, rid, ts }: { u: IU if (!allowed) { return false; } - const blockDeleteInMinutes = await getValue('Message_AllowDeleting_BlockDeleteInMinutes'); + const bypassBlockTimeLimit = await hasPermissionAsync(uid, 'bypass-time-limit-edit-and-create'); - if (blockDeleteInMinutes) { - const timeElapsedForMessage = elapsedTime(ts); - return timeElapsedForMessage <= blockDeleteInMinutes; + if (!bypassBlockTimeLimit) { + const blockDeleteInMinutes = await getValue('Message_AllowDeleting_BlockDeleteInMinutes'); + + if (blockDeleteInMinutes) { + const timeElapsedForMessage = elapsedTime(ts); + return timeElapsedForMessage <= blockDeleteInMinutes; + } } const room = await Rooms.findOneById(rid, { fields: { ro: 1, unmuted: 1 } }); diff --git a/apps/meteor/app/authorization/server/functions/upsertPermissions.ts b/apps/meteor/app/authorization/server/functions/upsertPermissions.ts index 3be452c5ca58..4c2c1df1787e 100644 --- a/apps/meteor/app/authorization/server/functions/upsertPermissions.ts +++ b/apps/meteor/app/authorization/server/functions/upsertPermissions.ts @@ -225,6 +225,7 @@ export const upsertPermissions = async (): Promise => { { _id: 'view-import-operations', roles: ['admin'] }, { _id: 'clear-oembed-cache', roles: ['admin'] }, { _id: 'videoconf-ring-users', roles: ['admin', 'owner', 'moderator', 'user'] }, + { _id: 'bypass-time-limit-edit-and-create', roles: ['bot'] }, ]; for await (const permission of permissions) { diff --git a/apps/meteor/app/lib/server/methods/updateMessage.js b/apps/meteor/app/lib/server/methods/updateMessage.js index d3c11f06e53f..d45aabb8a31c 100644 --- a/apps/meteor/app/lib/server/methods/updateMessage.js +++ b/apps/meteor/app/lib/server/methods/updateMessage.js @@ -49,7 +49,9 @@ Meteor.methods({ } const blockEditInMinutes = settings.get('Message_AllowEditing_BlockEditInMinutes'); - if (Match.test(blockEditInMinutes, Number) && blockEditInMinutes !== 0) { + const bypassBlockTimeLimit = hasPermission(Meteor.userId(), 'bypass-time-limit-edit-and-create'); + + if (!bypassBlockTimeLimit && Match.test(blockEditInMinutes, Number) && blockEditInMinutes !== 0) { let currentTsDiff; let msgTs; diff --git a/apps/meteor/packages/rocketchat-i18n/i18n/en.i18n.json b/apps/meteor/packages/rocketchat-i18n/i18n/en.i18n.json index 99e48ccefec0..1e9a93b03d1d 100644 --- a/apps/meteor/packages/rocketchat-i18n/i18n/en.i18n.json +++ b/apps/meteor/packages/rocketchat-i18n/i18n/en.i18n.json @@ -295,6 +295,8 @@ "add-livechat-department-agents_description": "Permission to add omnichannel agents to departments", "add-oauth-service": "Add OAuth Service", "add-oauth-service_description": "Permission to add a new OAuth service", + "bypass-time-limit-edit-and-create": "Bypass time limit", + "bypass-time-limit-edit-and-create_description": "Permission to Bypass time limit for editing and deleting messages", "add-team-channel": "Add Team Channel", "add-team-channel_description": "Permission to add a channel to a team", "add-team-member": "Add Team Member", diff --git a/apps/meteor/server/startup/migrations/index.ts b/apps/meteor/server/startup/migrations/index.ts index 80d9b45cdbe5..958502f81660 100644 --- a/apps/meteor/server/startup/migrations/index.ts +++ b/apps/meteor/server/startup/migrations/index.ts @@ -40,4 +40,5 @@ import './v278'; import './v279'; import './v280'; import './v281'; +import './v282'; import './xrun'; diff --git a/apps/meteor/server/startup/migrations/v282.ts b/apps/meteor/server/startup/migrations/v282.ts new file mode 100644 index 000000000000..824751b90d99 --- /dev/null +++ b/apps/meteor/server/startup/migrations/v282.ts @@ -0,0 +1,9 @@ +import { addMigration } from '../../lib/migrations'; +import { upsertPermissions } from '../../../app/authorization/server/functions/upsertPermissions'; + +addMigration({ + version: 279, + up() { + upsertPermissions(); + }, +}); From cbff75bebf04dc868fd9993b2951b91fb4c17066 Mon Sep 17 00:00:00 2001 From: LucianoPierdona Date: Mon, 26 Dec 2022 12:15:12 -0300 Subject: [PATCH 02/15] re-add migration --- apps/meteor/server/startup/migrations/v283.ts | 9 +++++++++ 1 file changed, 9 insertions(+) create mode 100644 apps/meteor/server/startup/migrations/v283.ts diff --git a/apps/meteor/server/startup/migrations/v283.ts b/apps/meteor/server/startup/migrations/v283.ts new file mode 100644 index 000000000000..811dbfd01c9d --- /dev/null +++ b/apps/meteor/server/startup/migrations/v283.ts @@ -0,0 +1,9 @@ +import { addMigration } from '../../lib/migrations'; +import { upsertPermissions } from '../../../app/authorization/server/functions/upsertPermissions'; + +addMigration({ + version: 283, + up() { + upsertPermissions(); + } +}); \ No newline at end of file From b9392cfe511607ea2701c328790c71b91a26e7e0 Mon Sep 17 00:00:00 2001 From: LucianoPierdona Date: Mon, 26 Dec 2022 12:55:19 -0300 Subject: [PATCH 03/15] added checks for bypass permissions --- .../app/ui-utils/client/lib/messageActionDefault.ts | 8 +++++--- apps/meteor/client/lib/chats/data.ts | 8 +++++--- apps/meteor/client/methods/updateMessage.ts | 10 ++++++---- apps/meteor/server/startup/migrations/v283.ts | 4 ++-- 4 files changed, 18 insertions(+), 12 deletions(-) diff --git a/apps/meteor/app/ui-utils/client/lib/messageActionDefault.ts b/apps/meteor/app/ui-utils/client/lib/messageActionDefault.ts index 4ee0ced859c2..7ae15edfb3cb 100644 --- a/apps/meteor/app/ui-utils/client/lib/messageActionDefault.ts +++ b/apps/meteor/app/ui-utils/client/lib/messageActionDefault.ts @@ -146,14 +146,16 @@ Meteor.startup(async function () { if (isRoomFederated(room)) { return message.u._id === Meteor.userId(); } - const hasPermission = hasAtLeastOnePermission('edit-message', message.rid); + const canEditMessage = hasAtLeastOnePermission('edit-message', message.rid); const isEditAllowed = settings.Message_AllowEditing; const editOwn = message.u && message.u._id === Meteor.userId(); - if (!(hasPermission || (isEditAllowed && editOwn))) { + if (!(canEditMessage || (isEditAllowed && editOwn))) { return false; } const blockEditInMinutes = settings.Message_AllowEditing_BlockEditInMinutes; - if (blockEditInMinutes) { + const bypassBlockTimeLimit = hasPermission('bypass-time-limit-edit-and-create'); + + if (!bypassBlockTimeLimit && blockEditInMinutes) { let msgTs; if (message.ts != null) { msgTs = moment(message.ts); diff --git a/apps/meteor/client/lib/chats/data.ts b/apps/meteor/client/lib/chats/data.ts index d9bea3da0676..55d108678be5 100644 --- a/apps/meteor/client/lib/chats/data.ts +++ b/apps/meteor/client/lib/chats/data.ts @@ -90,17 +90,19 @@ export const createDataAPI = ({ rid, tmid }: { rid: IRoom['_id']; tmid: IMessage return false; } - const hasPermission = hasAtLeastOnePermission('edit-message', message.rid); + const canEditMessage = hasAtLeastOnePermission('edit-message', message.rid); const editAllowed = (settings.get('Message_AllowEditing') as boolean | undefined) ?? false; const editOwn = message?.u && message.u._id === Meteor.userId(); - if (!hasPermission && (!editAllowed || !editOwn)) { + if (!canEditMessage && (!editAllowed || !editOwn)) { return false; } const blockEditInMinutes = settings.get('Message_AllowEditing_BlockEditInMinutes') as number | undefined; + const bypassBlockTimeLimit = hasPermission('bypass-time-limit-edit-and-create'); + const elapsedMinutes = moment().diff(message.ts, 'minutes'); - if (elapsedMinutes && blockEditInMinutes && elapsedMinutes > blockEditInMinutes) { + if (!bypassBlockTimeLimit && elapsedMinutes && blockEditInMinutes && elapsedMinutes > blockEditInMinutes) { return false; } diff --git a/apps/meteor/client/methods/updateMessage.ts b/apps/meteor/client/methods/updateMessage.ts index 0f77b000e3ff..805cecff0ad8 100644 --- a/apps/meteor/client/methods/updateMessage.ts +++ b/apps/meteor/client/methods/updateMessage.ts @@ -4,7 +4,7 @@ import { Tracker } from 'meteor/tracker'; import moment from 'moment'; import _ from 'underscore'; -import { hasAtLeastOnePermission } from '../../app/authorization/client'; +import { hasAtLeastOnePermission, hasPermission } from '../../app/authorization/client'; import { ChatMessage } from '../../app/models/client'; import { settings } from '../../app/settings/client'; import { t } from '../../app/utils/client'; @@ -23,7 +23,7 @@ Meteor.methods({ if (!originalMessage) { return; } - const hasPermission = hasAtLeastOnePermission('edit-message', message.rid); + const canEditMessage = hasAtLeastOnePermission('edit-message', message.rid); const editAllowed = settings.get('Message_AllowEditing'); let editOwn = false; @@ -42,7 +42,7 @@ Meteor.methods({ return false; } - if (!(hasPermission || (editAllowed && editOwn))) { + if (!(canEditMessage || (editAllowed && editOwn))) { dispatchToastMessage({ type: 'error', message: t('error-action-not-allowed', { action: t('Message_editing') }), @@ -51,7 +51,9 @@ Meteor.methods({ } const blockEditInMinutes = settings.get('Message_AllowEditing_BlockEditInMinutes'); - if (_.isNumber(blockEditInMinutes) && blockEditInMinutes !== 0) { + const bypassBlockTimeLimit = hasPermission('bypass-time-limit-edit-and-create'); + + if (!bypassBlockTimeLimit && _.isNumber(blockEditInMinutes) && blockEditInMinutes !== 0) { if (originalMessage.ts) { const msgTs = moment(originalMessage.ts); if (msgTs) { diff --git a/apps/meteor/server/startup/migrations/v283.ts b/apps/meteor/server/startup/migrations/v283.ts index 811dbfd01c9d..96a9397793e9 100644 --- a/apps/meteor/server/startup/migrations/v283.ts +++ b/apps/meteor/server/startup/migrations/v283.ts @@ -5,5 +5,5 @@ addMigration({ version: 283, up() { upsertPermissions(); - } -}); \ No newline at end of file + }, +}); From 2f378dc2b75159fd748b2256d3534f70c37b5f10 Mon Sep 17 00:00:00 2001 From: LucianoPierdona Date: Tue, 27 Dec 2022 09:23:23 -0300 Subject: [PATCH 04/15] update permission name --- .../app/authorization/server/functions/canDeleteMessage.ts | 2 +- .../app/authorization/server/functions/upsertPermissions.ts | 2 +- apps/meteor/app/lib/server/methods/updateMessage.js | 2 +- apps/meteor/app/ui-utils/client/lib/messageActionDefault.ts | 2 +- apps/meteor/client/lib/chats/data.ts | 2 +- apps/meteor/client/methods/updateMessage.ts | 2 +- apps/meteor/packages/rocketchat-i18n/i18n/en.i18n.json | 4 ++-- 7 files changed, 8 insertions(+), 8 deletions(-) diff --git a/apps/meteor/app/authorization/server/functions/canDeleteMessage.ts b/apps/meteor/app/authorization/server/functions/canDeleteMessage.ts index aae0ae295efe..8c1786853dee 100644 --- a/apps/meteor/app/authorization/server/functions/canDeleteMessage.ts +++ b/apps/meteor/app/authorization/server/functions/canDeleteMessage.ts @@ -31,7 +31,7 @@ export const canDeleteMessageAsync = async (uid: string, { u, rid, ts }: { u: IU if (!allowed) { return false; } - const bypassBlockTimeLimit = await hasPermissionAsync(uid, 'bypass-time-limit-edit-and-create'); + const bypassBlockTimeLimit = await hasPermissionAsync(uid, 'bypass-time-limit-edit-and-delete'); if (!bypassBlockTimeLimit) { const blockDeleteInMinutes = await getValue('Message_AllowDeleting_BlockDeleteInMinutes'); diff --git a/apps/meteor/app/authorization/server/functions/upsertPermissions.ts b/apps/meteor/app/authorization/server/functions/upsertPermissions.ts index 4c2c1df1787e..2e2735a5548e 100644 --- a/apps/meteor/app/authorization/server/functions/upsertPermissions.ts +++ b/apps/meteor/app/authorization/server/functions/upsertPermissions.ts @@ -225,7 +225,7 @@ export const upsertPermissions = async (): Promise => { { _id: 'view-import-operations', roles: ['admin'] }, { _id: 'clear-oembed-cache', roles: ['admin'] }, { _id: 'videoconf-ring-users', roles: ['admin', 'owner', 'moderator', 'user'] }, - { _id: 'bypass-time-limit-edit-and-create', roles: ['bot'] }, + { _id: 'bypass-time-limit-edit-and-delete', roles: ['bot'] }, ]; for await (const permission of permissions) { diff --git a/apps/meteor/app/lib/server/methods/updateMessage.js b/apps/meteor/app/lib/server/methods/updateMessage.js index d45aabb8a31c..ce0eb6ebdc97 100644 --- a/apps/meteor/app/lib/server/methods/updateMessage.js +++ b/apps/meteor/app/lib/server/methods/updateMessage.js @@ -49,7 +49,7 @@ Meteor.methods({ } const blockEditInMinutes = settings.get('Message_AllowEditing_BlockEditInMinutes'); - const bypassBlockTimeLimit = hasPermission(Meteor.userId(), 'bypass-time-limit-edit-and-create'); + const bypassBlockTimeLimit = hasPermission(Meteor.userId(), 'bypass-time-limit-edit-and-delete'); if (!bypassBlockTimeLimit && Match.test(blockEditInMinutes, Number) && blockEditInMinutes !== 0) { let currentTsDiff; diff --git a/apps/meteor/app/ui-utils/client/lib/messageActionDefault.ts b/apps/meteor/app/ui-utils/client/lib/messageActionDefault.ts index 7ae15edfb3cb..df9d2452265b 100644 --- a/apps/meteor/app/ui-utils/client/lib/messageActionDefault.ts +++ b/apps/meteor/app/ui-utils/client/lib/messageActionDefault.ts @@ -153,7 +153,7 @@ Meteor.startup(async function () { return false; } const blockEditInMinutes = settings.Message_AllowEditing_BlockEditInMinutes; - const bypassBlockTimeLimit = hasPermission('bypass-time-limit-edit-and-create'); + const bypassBlockTimeLimit = hasPermission('bypass-time-limit-edit-and-delete'); if (!bypassBlockTimeLimit && blockEditInMinutes) { let msgTs; diff --git a/apps/meteor/client/lib/chats/data.ts b/apps/meteor/client/lib/chats/data.ts index 55d108678be5..58f3c6428f1a 100644 --- a/apps/meteor/client/lib/chats/data.ts +++ b/apps/meteor/client/lib/chats/data.ts @@ -99,7 +99,7 @@ export const createDataAPI = ({ rid, tmid }: { rid: IRoom['_id']; tmid: IMessage } const blockEditInMinutes = settings.get('Message_AllowEditing_BlockEditInMinutes') as number | undefined; - const bypassBlockTimeLimit = hasPermission('bypass-time-limit-edit-and-create'); + const bypassBlockTimeLimit = hasPermission('bypass-time-limit-edit-and-delete'); const elapsedMinutes = moment().diff(message.ts, 'minutes'); if (!bypassBlockTimeLimit && elapsedMinutes && blockEditInMinutes && elapsedMinutes > blockEditInMinutes) { diff --git a/apps/meteor/client/methods/updateMessage.ts b/apps/meteor/client/methods/updateMessage.ts index 805cecff0ad8..c03c188c2a25 100644 --- a/apps/meteor/client/methods/updateMessage.ts +++ b/apps/meteor/client/methods/updateMessage.ts @@ -51,7 +51,7 @@ Meteor.methods({ } const blockEditInMinutes = settings.get('Message_AllowEditing_BlockEditInMinutes'); - const bypassBlockTimeLimit = hasPermission('bypass-time-limit-edit-and-create'); + const bypassBlockTimeLimit = hasPermission('bypass-time-limit-edit-and-delete'); if (!bypassBlockTimeLimit && _.isNumber(blockEditInMinutes) && blockEditInMinutes !== 0) { if (originalMessage.ts) { diff --git a/apps/meteor/packages/rocketchat-i18n/i18n/en.i18n.json b/apps/meteor/packages/rocketchat-i18n/i18n/en.i18n.json index 66df9009f2fa..18dc3363af0d 100644 --- a/apps/meteor/packages/rocketchat-i18n/i18n/en.i18n.json +++ b/apps/meteor/packages/rocketchat-i18n/i18n/en.i18n.json @@ -295,8 +295,8 @@ "add-livechat-department-agents_description": "Permission to add omnichannel agents to departments", "add-oauth-service": "Add OAuth Service", "add-oauth-service_description": "Permission to add a new OAuth service", - "bypass-time-limit-edit-and-create": "Bypass time limit", - "bypass-time-limit-edit-and-create_description": "Permission to Bypass time limit for editing and deleting messages", + "bypass-time-limit-edit-and-delete": "Bypass time limit", + "bypass-time-limit-edit-and-delete_description": "Permission to Bypass time limit for editing and deleting messages", "add-team-channel": "Add Team Channel", "add-team-channel_description": "Permission to add a channel to a team", "add-team-member": "Add Team Member", From 2b840670860b893202799a0d894d59951328e70d Mon Sep 17 00:00:00 2001 From: Luciano Marcos Pierdona Junior <64279791+LucianoPierdona@users.noreply.github.com> Date: Tue, 27 Dec 2022 15:56:07 +0000 Subject: [PATCH 05/15] Update apps/meteor/app/authorization/server/functions/upsertPermissions.ts Co-authored-by: Matheus Barbosa Silva <36537004+matheusbsilva137@users.noreply.github.com> --- .../app/authorization/server/functions/upsertPermissions.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/meteor/app/authorization/server/functions/upsertPermissions.ts b/apps/meteor/app/authorization/server/functions/upsertPermissions.ts index 2e2735a5548e..b0cdef52276c 100644 --- a/apps/meteor/app/authorization/server/functions/upsertPermissions.ts +++ b/apps/meteor/app/authorization/server/functions/upsertPermissions.ts @@ -225,7 +225,7 @@ export const upsertPermissions = async (): Promise => { { _id: 'view-import-operations', roles: ['admin'] }, { _id: 'clear-oembed-cache', roles: ['admin'] }, { _id: 'videoconf-ring-users', roles: ['admin', 'owner', 'moderator', 'user'] }, - { _id: 'bypass-time-limit-edit-and-delete', roles: ['bot'] }, + { _id: 'bypass-time-limit-edit-and-delete', roles: ['admin'] }, ]; for await (const permission of permissions) { From 436b852b8f518687c03187be19c7784df766e1a6 Mon Sep 17 00:00:00 2001 From: LucianoPierdona Date: Tue, 27 Dec 2022 13:18:33 -0300 Subject: [PATCH 06/15] updated delete message bypass check --- apps/meteor/client/lib/chats/data.ts | 3 ++- .../RoomFiles/hooks/useMessageDeletionIsAllowed.js | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/apps/meteor/client/lib/chats/data.ts b/apps/meteor/client/lib/chats/data.ts index 58f3c6428f1a..eaea7aff3214 100644 --- a/apps/meteor/client/lib/chats/data.ts +++ b/apps/meteor/client/lib/chats/data.ts @@ -212,10 +212,11 @@ export const createDataAPI = ({ rid, tmid }: { rid: IRoom['_id']; tmid: IMessage } const blockDeleteInMinutes = settings.get('Message_AllowDeleting_BlockDeleteInMinutes') as number | undefined; + const bypassBlockTimeLimit = hasPermission('bypass-time-limit-edit-and-delete'); const elapsedMinutes = moment().diff(message.ts, 'minutes'); const onTimeForDelete = !blockDeleteInMinutes || !elapsedMinutes || elapsedMinutes <= blockDeleteInMinutes; - return deleteAllowed && onTimeForDelete; + return !bypassBlockTimeLimit && deleteAllowed && onTimeForDelete; }; const deleteMessage = async (mid: IMessage['_id']): Promise => { diff --git a/apps/meteor/client/views/room/contextualBar/RoomFiles/hooks/useMessageDeletionIsAllowed.js b/apps/meteor/client/views/room/contextualBar/RoomFiles/hooks/useMessageDeletionIsAllowed.js index 9b426f3bb5fe..187f74d95f4a 100644 --- a/apps/meteor/client/views/room/contextualBar/RoomFiles/hooks/useMessageDeletionIsAllowed.js +++ b/apps/meteor/client/views/room/contextualBar/RoomFiles/hooks/useMessageDeletionIsAllowed.js @@ -8,6 +8,7 @@ export const useMessageDeletionIsAllowed = (rid, uid) => { const deletionIsEnabled = useSetting('Message_AllowDeleting'); const userHasPermissonToDeleteAny = usePermission('delete-message', rid); const userHasPermissonToDeleteOwn = usePermission('delete-own-message'); + const bypassBlockTimeLimit = usePermission('bypass-time-limit-edit-and-delete'); const blockDeleteInMinutes = useSetting('Message_AllowDeleting_BlockDeleteInMinutes'); const isDeletionAllowed = (() => { @@ -24,7 +25,7 @@ export const useMessageDeletionIsAllowed = (rid, uid) => { } const checkTimeframe = - blockDeleteInMinutes !== 0 + !bypassBlockTimeLimit && blockDeleteInMinutes !== 0 ? ({ ts }) => { if (!ts) { return false; From 6a2e0f1d270e3aa96b5c4df95bc6495e0444a931 Mon Sep 17 00:00:00 2001 From: LucianoPierdona Date: Tue, 27 Dec 2022 15:32:26 -0300 Subject: [PATCH 07/15] update default roles for bypass-time-limit-edit-and-delete --- .../app/authorization/server/functions/upsertPermissions.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/meteor/app/authorization/server/functions/upsertPermissions.ts b/apps/meteor/app/authorization/server/functions/upsertPermissions.ts index b0cdef52276c..100ecb6159f5 100644 --- a/apps/meteor/app/authorization/server/functions/upsertPermissions.ts +++ b/apps/meteor/app/authorization/server/functions/upsertPermissions.ts @@ -225,7 +225,7 @@ export const upsertPermissions = async (): Promise => { { _id: 'view-import-operations', roles: ['admin'] }, { _id: 'clear-oembed-cache', roles: ['admin'] }, { _id: 'videoconf-ring-users', roles: ['admin', 'owner', 'moderator', 'user'] }, - { _id: 'bypass-time-limit-edit-and-delete', roles: ['admin'] }, + { _id: 'bypass-time-limit-edit-and-delete', roles: ['bot', 'app'] }, ]; for await (const permission of permissions) { From d586c4b83faeaf650239fd2d0b0a85d2cf91cb01 Mon Sep 17 00:00:00 2001 From: LucianoPierdona Date: Wed, 28 Dec 2022 13:32:58 -0300 Subject: [PATCH 08/15] add migration to index --- apps/meteor/server/startup/migrations/index.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/apps/meteor/server/startup/migrations/index.ts b/apps/meteor/server/startup/migrations/index.ts index 958502f81660..377fcb8e4460 100644 --- a/apps/meteor/server/startup/migrations/index.ts +++ b/apps/meteor/server/startup/migrations/index.ts @@ -41,4 +41,5 @@ import './v279'; import './v280'; import './v281'; import './v282'; +import './v283'; import './xrun'; From a0dfa4b4f6bebff1edba1aeaa5ee0ad65dc7b86e Mon Sep 17 00:00:00 2001 From: LucianoPierdona Date: Thu, 29 Dec 2022 16:30:00 -0300 Subject: [PATCH 09/15] update check for bypass --- apps/meteor/client/lib/chats/data.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/apps/meteor/client/lib/chats/data.ts b/apps/meteor/client/lib/chats/data.ts index eaea7aff3214..6c1ac4c43c7b 100644 --- a/apps/meteor/client/lib/chats/data.ts +++ b/apps/meteor/client/lib/chats/data.ts @@ -214,9 +214,9 @@ export const createDataAPI = ({ rid, tmid }: { rid: IRoom['_id']; tmid: IMessage const blockDeleteInMinutes = settings.get('Message_AllowDeleting_BlockDeleteInMinutes') as number | undefined; const bypassBlockTimeLimit = hasPermission('bypass-time-limit-edit-and-delete'); const elapsedMinutes = moment().diff(message.ts, 'minutes'); - const onTimeForDelete = !blockDeleteInMinutes || !elapsedMinutes || elapsedMinutes <= blockDeleteInMinutes; + const onTimeForDelete = bypassBlockTimeLimit || !blockDeleteInMinutes || !elapsedMinutes || elapsedMinutes <= blockDeleteInMinutes; - return !bypassBlockTimeLimit && deleteAllowed && onTimeForDelete; + return deleteAllowed && onTimeForDelete; }; const deleteMessage = async (mid: IMessage['_id']): Promise => { From 4e71aaae7995f1f1e2d9f72d1a7cf0f7d10e8381 Mon Sep 17 00:00:00 2001 From: LucianoPierdona Date: Tue, 3 Jan 2023 11:35:52 -0300 Subject: [PATCH 10/15] add tests for updateMessage and deleteMessage --- .../meteor/tests/end-to-end/api/24-methods.js | 144 +++++++++++++++++- 1 file changed, 143 insertions(+), 1 deletion(-) diff --git a/apps/meteor/tests/end-to-end/api/24-methods.js b/apps/meteor/tests/end-to-end/api/24-methods.js index 67d8f8253c87..2b5971d52ff6 100644 --- a/apps/meteor/tests/end-to-end/api/24-methods.js +++ b/apps/meteor/tests/end-to-end/api/24-methods.js @@ -1,7 +1,7 @@ import { expect } from 'chai'; import { getCredentials, request, methodCall, api, credentials } from '../../data/api-data.js'; -import { updatePermission } from '../../data/permissions.helper.js'; +import { updatePermission, updateSetting } from '../../data/permissions.helper.js'; describe('Meteor.methods', function () { this.retries(0); @@ -1623,6 +1623,40 @@ describe('Meteor.methods', function () { .end(done); }); + it('should update a message when bypass time limits permission is enabled', (done) => { + updatePermission('bypass-time-limit-edit-and-delete', ['admin']) + .then(() => updateSetting('Message_AllowEditing_BlockEditInMinutes', 0.01)) + .then(() => { + request + .post(methodCall('updateMessage')) + .set(credentials) + .send({ + message: JSON.stringify({ + method: 'updateMessage', + params: [{ _id: messageId, rid, msg: 'https://github.com updated with bypass' }], + id: 'id', + msg: 'method', + }), + }) + .expect('Content-Type', 'application/json') + .expect(200) + .expect((res) => { + expect(res.body).to.have.a.property('success', true); + expect(res.body).to.have.a.property('message').that.is.a('string'); + request + .get(api(`chat.getMessage?msgId=${messageId}`)) + .set(credentials) + .expect('Content-Type', 'application/json') + .expect(200) + .expect((res) => { + expect(res.body).to.have.property('message').that.is.an('object'); + expect(res.body.message.msg).to.equal('https://github.com updated with bypass'); + }); + }) + .end(done); + }); + }); + it('should not parse URLs inside markdown on update', (done) => { request .post(methodCall('updateMessage')) @@ -1667,6 +1701,114 @@ describe('Meteor.methods', function () { }); }); + describe('[@deleteMessage]', () => { + let rid = false; + let messageId; + + before('create room', (done) => { + const channelName = `methods-test-channel-${Date.now()}`; + request + .post(api('groups.create')) + .set(credentials) + .send({ + name: channelName, + }) + .expect('Content-Type', 'application/json') + .expect(200) + .expect((res) => { + expect(res.body).to.have.property('success', true); + expect(res.body).to.have.nested.property('group._id'); + expect(res.body).to.have.nested.property('group.name', channelName); + expect(res.body).to.have.nested.property('group.t', 'p'); + expect(res.body).to.have.nested.property('group.msgs', 0); + rid = res.body.group._id; + }) + .end(done); + }); + + beforeEach('send message with URL', (done) => { + request + .post(methodCall('sendMessage')) + .set(credentials) + .send({ + message: JSON.stringify({ + method: 'sendMessage', + params: [ + { + _id: `${Date.now() + Math.random()}`, + rid, + msg: 'test message with https://github.com', + }, + ], + id: 'id', + msg: 'method', + }), + }) + .expect('Content-Type', 'application/json') + .expect(200) + .expect((res) => { + expect(res.body).to.have.a.property('success', true); + expect(res.body).to.have.a.property('message').that.is.a('string'); + + const data = JSON.parse(res.body.message); + expect(data).to.have.a.property('result').that.is.an('object'); + expect(data.result).to.have.a.property('urls').that.is.an('array'); + expect(data.result.urls[0].url).to.equal('https://github.com'); + messageId = data.result._id; + }) + .end(done); + }); + + it('should delete a message', (done) => { + request + .post(methodCall('deleteMessage')) + .set(credentials) + .send({ + message: JSON.stringify({ + method: 'deleteMessage', + params: [{ _id: messageId, rid }], + id: 'id', + msg: 'method', + }), + }) + .expect('Content-Type', 'application/json') + .expect(200) + .expect((res) => { + expect(res.body).to.have.a.property('success', true); + expect(res.body).to.have.a.property('message').that.is.a('string'); + const data = JSON.parse(res.body.message); + expect(data).to.have.a.property('msg').that.is.an('string'); + }) + .end(done); + }); + + it('should delete a message when bypass time limits permission is enabled', (done) => { + updatePermission('bypass-time-limit-edit-and-delete', ['admin']) + .then(() => updateSetting('Message_AllowEditing_BlockEditInMinutes', 0.01)) + .then(() => { + request + .post(methodCall('deleteMessage')) + .set(credentials) + .send({ + message: JSON.stringify({ + method: 'deleteMessage', + params: [{ _id: messageId, rid }], + id: 'id', + msg: 'method', + }), + }) + .expect('Content-Type', 'application/json') + .expect(200) + .expect((res) => { + console.log('🚀 ~ file: 24-methods.js:1805 ~ .expect ~ res', res.body); + expect(res.body).to.have.a.property('success', true); + expect(res.body).to.have.a.property('message').that.is.a('string'); + }) + .end(done); + }); + }); + }); + describe('[@setUserActiveStatus]', () => { let testUser; let testUser2; From 3c9a1ac7cf9cdb47c1db82944c7361ebd0ef1187 Mon Sep 17 00:00:00 2001 From: Luciano Marcos Pierdona Junior <64279791+LucianoPierdona@users.noreply.github.com> Date: Tue, 7 Feb 2023 10:24:14 -0300 Subject: [PATCH 11/15] Update apps/meteor/tests/end-to-end/api/24-methods.js Co-authored-by: Diego Sampaio --- .../meteor/tests/end-to-end/api/24-methods.js | 63 ++++++++++--------- 1 file changed, 32 insertions(+), 31 deletions(-) diff --git a/apps/meteor/tests/end-to-end/api/24-methods.js b/apps/meteor/tests/end-to-end/api/24-methods.js index 2b5971d52ff6..41040a752483 100644 --- a/apps/meteor/tests/end-to-end/api/24-methods.js +++ b/apps/meteor/tests/end-to-end/api/24-methods.js @@ -1623,37 +1623,38 @@ describe('Meteor.methods', function () { .end(done); }); - it('should update a message when bypass time limits permission is enabled', (done) => { - updatePermission('bypass-time-limit-edit-and-delete', ['admin']) - .then(() => updateSetting('Message_AllowEditing_BlockEditInMinutes', 0.01)) - .then(() => { - request - .post(methodCall('updateMessage')) - .set(credentials) - .send({ - message: JSON.stringify({ - method: 'updateMessage', - params: [{ _id: messageId, rid, msg: 'https://github.com updated with bypass' }], - id: 'id', - msg: 'method', - }), - }) - .expect('Content-Type', 'application/json') - .expect(200) - .expect((res) => { - expect(res.body).to.have.a.property('success', true); - expect(res.body).to.have.a.property('message').that.is.a('string'); - request - .get(api(`chat.getMessage?msgId=${messageId}`)) - .set(credentials) - .expect('Content-Type', 'application/json') - .expect(200) - .expect((res) => { - expect(res.body).to.have.property('message').that.is.an('object'); - expect(res.body.message.msg).to.equal('https://github.com updated with bypass'); - }); - }) - .end(done); + it('should update a message when bypass time limits permission is enabled', async (done) => { + await Promise.all([ + updatePermission('bypass-time-limit-edit-and-delete', ['admin']), + updateSetting('Message_AllowEditing_BlockEditInMinutes', 0.01), + ]); + + await request + .post(methodCall('updateMessage')) + .set(credentials) + .send({ + message: JSON.stringify({ + method: 'updateMessage', + params: [{ _id: messageId, rid, msg: 'https://github.com updated with bypass' }], + id: 'id', + msg: 'method', + }), + }) + .expect('Content-Type', 'application/json') + .expect(200) + .expect((res) => { + expect(res.body).to.have.a.property('success', true); + expect(res.body).to.have.a.property('message').that.is.a('string'); + }); + + await request + .get(api(`chat.getMessage?msgId=${messageId}`)) + .set(credentials) + .expect('Content-Type', 'application/json') + .expect(200) + .expect((res) => { + expect(res.body).to.have.property('message').that.is.an('object'); + expect(res.body.message.msg).to.equal('https://github.com updated with bypass'); }); }); From 499ba0b9db8473ed677052cca7f6ec498685a510 Mon Sep 17 00:00:00 2001 From: LucianoPierdona Date: Tue, 7 Feb 2023 10:32:27 -0300 Subject: [PATCH 12/15] linting --- apps/meteor/tests/end-to-end/api/24-methods.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/apps/meteor/tests/end-to-end/api/24-methods.js b/apps/meteor/tests/end-to-end/api/24-methods.js index 41040a752483..f03bd23de24a 100644 --- a/apps/meteor/tests/end-to-end/api/24-methods.js +++ b/apps/meteor/tests/end-to-end/api/24-methods.js @@ -1655,7 +1655,8 @@ describe('Meteor.methods', function () { .expect((res) => { expect(res.body).to.have.property('message').that.is.an('object'); expect(res.body.message.msg).to.equal('https://github.com updated with bypass'); - }); + }) + .end(done); }); it('should not parse URLs inside markdown on update', (done) => { From 410effa4b593c2a19cbf6bb98572a49072a800c7 Mon Sep 17 00:00:00 2001 From: LucianoPierdona Date: Tue, 7 Feb 2023 13:43:52 -0300 Subject: [PATCH 13/15] fix tests --- apps/meteor/tests/end-to-end/api/24-methods.js | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/apps/meteor/tests/end-to-end/api/24-methods.js b/apps/meteor/tests/end-to-end/api/24-methods.js index f03bd23de24a..760e668664a1 100644 --- a/apps/meteor/tests/end-to-end/api/24-methods.js +++ b/apps/meteor/tests/end-to-end/api/24-methods.js @@ -1623,7 +1623,7 @@ describe('Meteor.methods', function () { .end(done); }); - it('should update a message when bypass time limits permission is enabled', async (done) => { + it('should update a message when bypass time limits permission is enabled', async () => { await Promise.all([ updatePermission('bypass-time-limit-edit-and-delete', ['admin']), updateSetting('Message_AllowEditing_BlockEditInMinutes', 0.01), @@ -1655,8 +1655,7 @@ describe('Meteor.methods', function () { .expect((res) => { expect(res.body).to.have.property('message').that.is.an('object'); expect(res.body.message.msg).to.equal('https://github.com updated with bypass'); - }) - .end(done); + }); }); it('should not parse URLs inside markdown on update', (done) => { From 01e6e8e75779c04c7c6e6ccc839953e334aca87a Mon Sep 17 00:00:00 2001 From: LucianoPierdona Date: Tue, 7 Feb 2023 16:56:33 -0300 Subject: [PATCH 14/15] update tests --- .../meteor/tests/end-to-end/api/24-methods.js | 61 +++++++++++-------- 1 file changed, 37 insertions(+), 24 deletions(-) diff --git a/apps/meteor/tests/end-to-end/api/24-methods.js b/apps/meteor/tests/end-to-end/api/24-methods.js index 760e668664a1..137d60cbc41a 100644 --- a/apps/meteor/tests/end-to-end/api/24-methods.js +++ b/apps/meteor/tests/end-to-end/api/24-methods.js @@ -1656,6 +1656,11 @@ describe('Meteor.methods', function () { expect(res.body).to.have.property('message').that.is.an('object'); expect(res.body.message.msg).to.equal('https://github.com updated with bypass'); }); + + await Promise.all([ + updatePermission('bypass-time-limit-edit-and-delete', ['bot', 'app']), + updateSetting('Message_AllowEditing_BlockEditInMinutes', 0), + ]); }); it('should not parse URLs inside markdown on update', (done) => { @@ -1778,35 +1783,43 @@ describe('Meteor.methods', function () { expect(res.body).to.have.a.property('success', true); expect(res.body).to.have.a.property('message').that.is.a('string'); const data = JSON.parse(res.body.message); - expect(data).to.have.a.property('msg').that.is.an('string'); + expect(data).to.have.a.property('msg', 'result'); + expect(data).to.have.a.property('id', 'id'); }) .end(done); }); - it('should delete a message when bypass time limits permission is enabled', (done) => { - updatePermission('bypass-time-limit-edit-and-delete', ['admin']) - .then(() => updateSetting('Message_AllowEditing_BlockEditInMinutes', 0.01)) - .then(() => { - request - .post(methodCall('deleteMessage')) - .set(credentials) - .send({ - message: JSON.stringify({ - method: 'deleteMessage', - params: [{ _id: messageId, rid }], - id: 'id', - msg: 'method', - }), - }) - .expect('Content-Type', 'application/json') - .expect(200) - .expect((res) => { - console.log('🚀 ~ file: 24-methods.js:1805 ~ .expect ~ res', res.body); - expect(res.body).to.have.a.property('success', true); - expect(res.body).to.have.a.property('message').that.is.a('string'); - }) - .end(done); + it('should delete a message when bypass time limits permission is enabled', async () => { + await Promise.all([ + updatePermission('bypass-time-limit-edit-and-delete', ['admin']), + updateSetting('Message_AllowEditing_BlockEditInMinutes', 0.01), + ]); + + await request + .post(methodCall('deleteMessage')) + .set(credentials) + .send({ + message: JSON.stringify({ + method: 'deleteMessage', + params: [{ _id: messageId, rid }], + id: 'id', + msg: 'method', + }), + }) + .expect('Content-Type', 'application/json') + .expect(200) + .expect((res) => { + expect(res.body).to.have.a.property('success', true); + expect(res.body).to.have.a.property('message').that.is.a('string'); + const data = JSON.parse(res.body.message); + expect(data).to.have.a.property('msg', 'result'); + expect(data).to.have.a.property('id', 'id'); }); + + await Promise.all([ + updatePermission('bypass-time-limit-edit-and-delete', ['bot', 'app']), + updateSetting('Message_AllowEditing_BlockEditInMinutes', 0), + ]); }); }); From f5abd9acb80129468476cbbce6612ead60e3c53c Mon Sep 17 00:00:00 2001 From: Hugo Costa Date: Thu, 9 Feb 2023 14:17:59 -0300 Subject: [PATCH 15/15] renaming migration --- apps/meteor/server/startup/migrations/index.ts | 1 + apps/meteor/server/startup/migrations/v286.ts | 9 +++++++++ 2 files changed, 10 insertions(+) create mode 100644 apps/meteor/server/startup/migrations/v286.ts diff --git a/apps/meteor/server/startup/migrations/index.ts b/apps/meteor/server/startup/migrations/index.ts index c534eae0b295..8fce9cd85682 100644 --- a/apps/meteor/server/startup/migrations/index.ts +++ b/apps/meteor/server/startup/migrations/index.ts @@ -44,4 +44,5 @@ import './v282'; import './v283'; import './v284'; import './v285'; +import './v286'; import './xrun'; diff --git a/apps/meteor/server/startup/migrations/v286.ts b/apps/meteor/server/startup/migrations/v286.ts new file mode 100644 index 000000000000..25e7420b1267 --- /dev/null +++ b/apps/meteor/server/startup/migrations/v286.ts @@ -0,0 +1,9 @@ +import { addMigration } from '../../lib/migrations'; +import { upsertPermissions } from '../../../app/authorization/server/functions/upsertPermissions'; + +addMigration({ + version: 286, + up() { + upsertPermissions(); + }, +});