{"record":{"id":"ae834433fc30ed06","repo":"RocketChat/Rocket.Chat","slug":"not-authorized-ae8344","errorCode":"not_authorized","errorMessage":"Unauthorized","messagePattern":"Unauthorized","errorType":"exception","errorClass":"Meteor.Error","httpStatus":null,"severity":"error","filePath":"apps/meteor/server/lib/integrations/functions/clearIntegrationHistory.ts","lineNumber":20,"sourceCode":"import { Integrations, IntegrationHistory } from '@rocket.chat/models';\nimport { Meteor } from 'meteor/meteor';\n\nimport { hasPermissionAsync } from '../../authorization/hasPermission';\nimport notifications from '../../notifications/core/lib/Notifications';\nimport { triggerHandler } from '../lib/triggerHandler';\n\nexport const clearIntegrationHistoryMethod = async (userId: string, integrationId: string): Promise<void> => {\n\tlet integration: IIntegration | null = null;\n\n\tif (await hasPermissionAsync(userId, 'manage-outgoing-integrations')) {\n\t\tintegration = await Integrations.findOneById<IIntegration>(integrationId);\n\t} else if (await hasPermissionAsync(userId, 'manage-own-outgoing-integrations')) {\n\t\tintegration = await Integrations.findOne<IIntegration>({\n\t\t\t'_id': integrationId,\n\t\t\t'_createdBy._id': userId,\n\t\t});\n\t} else {\n\t\tthrow new Meteor.Error('not_authorized', 'Unauthorized', { method: 'clearIntegrationHistory' });\n\t}\n\n\tif (!integration) {\n\t\tthrow new Meteor.Error('error-invalid-integration', 'Invalid integration', { method: 'clearIntegrationHistory' });\n\t}\n\n\tawait IntegrationHistory.removeByIntegrationId(integrationId);\n\n\tnotifications.streamIntegrationHistory.emit(integrationId, { type: 'removed', id: integrationId });\n};\n\nexport const replayOutgoingIntegrationMethod = async (\n\tuserId: string,\n\t{ integrationId, historyId }: { integrationId: string; historyId: string },\n): Promise<void> => {\n\tlet integration: IOutgoingIntegration | null = null;\n\n\tif (await hasPermissionAsync(userId, 'manage-outgoing-integrations')) {","sourceCodeStart":2,"sourceCodeEnd":38,"githubUrl":"https://github.com/RocketChat/Rocket.Chat/blob/b2c16d5842cbe6b69b59bdf6fc5e5f1afcd1f0b0/apps/meteor/server/lib/integrations/functions/clearIntegrationHistory.ts#L2-L38","documentation":"clearIntegrationHistory authorizes via one of two permissions: manage-outgoing-integrations (any integration) or manage-own-outgoing-integrations (integrations the caller created). When the user holds neither, this Meteor.Error (not_authorized) is thrown before any lookup happens.","triggerScenarios":"Invoking the clearIntegrationHistory method with a user whose roles lack both outgoing-integration permissions.","commonSituations":"Custom roles built without integration permissions; permission sets tightened during a security audit; new admins not granted the integration role.","solutions":["Grant manage-outgoing-integrations (full) or manage-own-outgoing-integrations (own only) to the user's role in Administration > Permissions","Or have a user already holding the permission perform the action"],"exampleFix":null,"handlingStrategy":"validation","validationCode":"const canManageAll = await hasPermissionAsync(userId, 'manage-outgoing-integrations');\nconst canManageOwn = await hasPermissionAsync(userId, 'manage-own-outgoing-integrations');\nif (!canManageAll && !canManageOwn) {\n  // hide the clear-history action entirely\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Gate integration management UI on the same permission checks the server performs","Review custom roles after upgrades for missing integration permissions"],"tags":["integrations","permissions","authorization"],"backgroundTag":"permission-denied","analyzedSha":"b2c16d5842cbe6b69b59bdf6fc5e5f1afcd1f0b0","analyzedAt":"2026-08-18T15:26:39.429Z","schemaVersion":2},"datasetVersion":"2026-08-21T13:17:26.733Z"}