From 6861c00f4ed6f13c9b016463208b2d88a4ed97fe Mon Sep 17 00:00:00 2001 From: Ricardo Garim Date: Thu, 4 Jul 2024 10:43:40 -0300 Subject: [PATCH 1/2] refactor: create middleware to handle dbWatchersDisabled check --- .../app/lib/server/lib/notifyListener.ts | 354 +++++++----------- 1 file changed, 130 insertions(+), 224 deletions(-) diff --git a/apps/meteor/app/lib/server/lib/notifyListener.ts b/apps/meteor/app/lib/server/lib/notifyListener.ts index f4e948390c99..ee841f8652b0 100644 --- a/apps/meteor/app/lib/server/lib/notifyListener.ts +++ b/apps/meteor/app/lib/server/lib/notifyListener.ts @@ -34,87 +34,58 @@ import { type ClientAction = 'inserted' | 'updated' | 'removed'; -export async function notifyOnLivechatPriorityChanged( +function withDbWatcherCheck Promise>(fn: T): T { + return dbWatchersDisabled ? fn : ((() => Promise.resolve()) as T); +} + +const _notifyOnLivechatPriorityChanged = async ( data: Pick, clientAction: ClientAction = 'updated', -): Promise { - if (!dbWatchersDisabled) { - return; - } - +): Promise => { const { _id, ...rest } = data; - void api.broadcast('watch.priorities', { clientAction, id: _id, diff: { ...rest } }); -} - -export async function notifyOnRoomChanged( - data: T | T[], - clientAction: ClientAction = 'updated', -): Promise { - if (!dbWatchersDisabled) { - return; - } +}; +const _notifyOnRoomChanged = async (data: T | T[], clientAction: ClientAction = 'updated'): Promise => { const items = Array.isArray(data) ? data : [data]; - for (const item of items) { void api.broadcast('watch.rooms', { clientAction, room: item }); } -} +}; -export async function notifyOnRoomChangedById( +const _notifyOnRoomChangedById = async ( ids: T['_id'] | T['_id'][], clientAction: ClientAction = 'updated', -): Promise { - if (!dbWatchersDisabled) { - return; - } - +): Promise => { const eligibleIds = Array.isArray(ids) ? ids : [ids]; - const items = Rooms.findByIds(eligibleIds); - for await (const item of items) { void api.broadcast('watch.rooms', { clientAction, room: item }); } -} +}; -export async function notifyOnRoomChangedByUsernamesOrUids( +const _notifyOnRoomChangedByUsernamesOrUids = async ( uids: T['u']['_id'][], usernames: T['u']['username'][], clientAction: ClientAction = 'updated', -): Promise { - if (!dbWatchersDisabled) { - return; - } - +): Promise => { const items = Rooms.findByUsernamesOrUids(uids, usernames); - for await (const item of items) { void api.broadcast('watch.rooms', { clientAction, room: item }); } -} +}; -export async function notifyOnRoomChangedByUserDM( +const _notifyOnRoomChangedByUserDM = async ( userId: T['u']['_id'], clientAction: ClientAction = 'updated', -): Promise { - if (!dbWatchersDisabled) { - return; - } - +): Promise => { const items = Rooms.findDMsByUids([userId]); - for await (const item of items) { void api.broadcast('watch.rooms', { clientAction, room: item }); } -} - -export async function notifyOnPermissionChanged(permission: IPermission, clientAction: ClientAction = 'updated'): Promise { - if (!dbWatchersDisabled) { - return; - } +}; +const _notifyOnPermissionChanged = async (permission: IPermission, clientAction: ClientAction = 'updated'): Promise => { void api.broadcast('permission.changed', { clientAction, data: permission }); if (permission.level === 'settings' && permission.settingId) { @@ -122,86 +93,56 @@ export async function notifyOnPermissionChanged(permission: IPermission, clientA if (!setting) { return; } - void notifyOnSettingChanged(setting, 'updated'); - } -} - -export async function notifyOnPermissionChangedById(pid: IPermission['_id'], clientAction: ClientAction = 'updated'): Promise { - if (!dbWatchersDisabled) { - return; + void _notifyOnSettingChanged(setting, 'updated'); } +}; +const _notifyOnPermissionChangedById = async (pid: IPermission['_id'], clientAction: ClientAction = 'updated'): Promise => { const permission = await Permissions.findOneById(pid); if (!permission) { return; } - return notifyOnPermissionChanged(permission, clientAction); -} - -export async function notifyOnPbxEventChangedById( - id: T['_id'], - clientAction: ClientAction = 'updated', -): Promise { - if (!dbWatchersDisabled) { - return; - } + return _notifyOnPermissionChanged(permission, clientAction); +}; +const _notifyOnPbxEventChangedById = async (id: T['_id'], clientAction: ClientAction = 'updated'): Promise => { const item = await PbxEvents.findOneById(id); if (!item) { return; } void api.broadcast('watch.pbxevents', { clientAction, id, data: item }); -} - -export async function notifyOnRoleChanged(role: T, clientAction: 'removed' | 'changed' = 'changed'): Promise { - if (!dbWatchersDisabled) { - return; - } +}; +const _notifyOnRoleChanged = async (role: T, clientAction: 'removed' | 'changed' = 'changed'): Promise => { void api.broadcast('watch.roles', { clientAction, role }); -} - -export async function notifyOnRoleChangedById( - id: T['_id'], - clientAction: 'removed' | 'changed' = 'changed', -): Promise { - if (!dbWatchersDisabled) { - return; - } +}; +const _notifyOnRoleChangedById = async (id: T['_id'], clientAction: 'removed' | 'changed' = 'changed'): Promise => { const role = await Roles.findOneById(id); if (!role) { return; } - void notifyOnRoleChanged(role, clientAction); -} + void _notifyOnRoleChanged(role, clientAction); +}; -export async function notifyOnLoginServiceConfigurationChanged( +const _notifyOnLoginServiceConfigurationChanged = async ( service: Partial & Pick, clientAction: ClientAction = 'updated', -): Promise { - if (!dbWatchersDisabled) { - return; - } - +): Promise => { void api.broadcast('watch.loginServiceConfiguration', { clientAction, id: service._id, data: service, }); -} +}; -export async function notifyOnLoginServiceConfigurationChangedByService( +const _notifyOnLoginServiceConfigurationChangedByService = async ( service: T['service'], clientAction: ClientAction = 'updated', -): Promise { - if (!dbWatchersDisabled) { - return; - } - +): Promise => { const item = await LoginServiceConfiguration.findOneByService>(service, { projection: { secret: 0 }, }); @@ -209,99 +150,71 @@ export async function notifyOnLoginServiceConfigurationChangedByService(data: T, clientAction: ClientAction = 'updated'): Promise { - if (!dbWatchersDisabled) { - return; - } + void _notifyOnLoginServiceConfigurationChanged(item, clientAction); +}; +const _notifyOnIntegrationChanged = async (data: T, clientAction: ClientAction = 'updated'): Promise => { void api.broadcast('watch.integrations', { clientAction, id: data._id, data }); -} +}; -export async function notifyOnIntegrationChangedById( +const _notifyOnIntegrationChangedById = async ( id: T['_id'], clientAction: ClientAction = 'updated', -): Promise { - if (!dbWatchersDisabled) { - return; - } - +): Promise => { const item = await Integrations.findOneById(id); if (!item) { return; } void api.broadcast('watch.integrations', { clientAction, id: item._id, data: item }); -} +}; -export async function notifyOnIntegrationChangedByUserId( +const _notifyOnIntegrationChangedByUserId = async ( id: T['userId'], clientAction: ClientAction = 'updated', -): Promise { - if (!dbWatchersDisabled) { - return; - } - +): Promise => { const items = Integrations.findByUserId(id); for await (const item of items) { void api.broadcast('watch.integrations', { clientAction, id: item._id, data: item }); } -} +}; -export async function notifyOnIntegrationChangedByChannels( +const _notifyOnIntegrationChangedByChannels = async ( channels: T['channel'], clientAction: ClientAction = 'updated', -): Promise { - if (!dbWatchersDisabled) { - return; - } - +): Promise => { const items = Integrations.findByChannels(channels); for await (const item of items) { void api.broadcast('watch.integrations', { clientAction, id: item._id, data: item }); } -} +}; -export async function notifyOnEmailInboxChanged( +const _notifyOnEmailInboxChanged = async ( data: Pick | T, // TODO: improve typing clientAction: ClientAction = 'updated', -): Promise { - if (!dbWatchersDisabled) { - return; - } - +): Promise => { void api.broadcast('watch.emailInbox', { clientAction, id: data._id, data }); -} +}; -export async function notifyOnLivechatInquiryChanged( +const _notifyOnLivechatInquiryChanged = async ( data: ILivechatInquiryRecord | ILivechatInquiryRecord[], clientAction: ClientAction = 'updated', diff?: Partial & { queuedAt: unknown; takenAt: unknown }>, -): Promise { - if (!dbWatchersDisabled) { - return; - } - +): Promise => { const items = Array.isArray(data) ? data : [data]; for (const item of items) { void api.broadcast('watch.inquiries', { clientAction, inquiry: item, diff }); } -} +}; -export async function notifyOnLivechatInquiryChangedById( +const _notifyOnLivechatInquiryChangedById = async ( id: ILivechatInquiryRecord['_id'], clientAction: ClientAction = 'updated', diff?: Partial & { queuedAt: unknown; takenAt: unknown }>, -): Promise { - if (!dbWatchersDisabled) { - return; - } - +): Promise => { const inquiry = clientAction === 'removed' ? await LivechatInquiry.trashFindOneById(id) : await LivechatInquiry.findOneById(id); if (!inquiry) { @@ -309,17 +222,13 @@ export async function notifyOnLivechatInquiryChangedById( } void api.broadcast('watch.inquiries', { clientAction, inquiry, diff }); -} +}; -export async function notifyOnLivechatInquiryChangedByRoom( +const _notifyOnLivechatInquiryChangedByRoom = async ( rid: ILivechatInquiryRecord['rid'], clientAction: ClientAction = 'updated', diff?: Partial & { queuedAt: unknown; takenAt: unknown }>, -): Promise { - if (!dbWatchersDisabled) { - return; - } - +): Promise => { const inquiry = await LivechatInquiry.findOneByRoomId(rid, {}); if (!inquiry) { @@ -327,17 +236,13 @@ export async function notifyOnLivechatInquiryChangedByRoom( } void api.broadcast('watch.inquiries', { clientAction, inquiry, diff }); -} +}; -export async function notifyOnLivechatInquiryChangedByToken( +const _notifyOnLivechatInquiryChangedByToken = async ( token: ILivechatInquiryRecord['v']['token'], clientAction: ClientAction = 'updated', diff?: Partial & { queuedAt: unknown; takenAt: unknown }>, -): Promise { - if (!dbWatchersDisabled) { - return; - } - +): Promise => { const inquiry = await LivechatInquiry.findOneByToken(token); if (!inquiry) { @@ -345,29 +250,21 @@ export async function notifyOnLivechatInquiryChangedByToken( } void api.broadcast('watch.inquiries', { clientAction, inquiry, diff }); -} +}; -export async function notifyOnIntegrationHistoryChanged( +const _notifyOnIntegrationHistoryChanged = async ( data: AtLeast, clientAction: ClientAction = 'updated', diff: Partial = {}, -): Promise { - if (!dbWatchersDisabled) { - return; - } - +): Promise => { void api.broadcast('watch.integrationHistory', { clientAction, id: data._id, data, diff }); -} +}; -export async function notifyOnIntegrationHistoryChangedById( +const _notifyOnIntegrationHistoryChangedById = async ( id: T['_id'], clientAction: ClientAction = 'updated', diff: Partial = {}, -): Promise { - if (!dbWatchersDisabled) { - return; - } - +): Promise => { const item = await IntegrationHistory.findOneById(id); if (!item) { @@ -375,43 +272,31 @@ export async function notifyOnIntegrationHistoryChangedById( +const _notifyOnLivechatDepartmentAgentChanged = async ( data: Partial & Pick, clientAction: ClientAction = 'updated', -): Promise { - if (!dbWatchersDisabled) { - return; - } - +): Promise => { void api.broadcast('watch.livechatDepartmentAgents', { clientAction, id: data._id, data }); -} +}; -export async function notifyOnLivechatDepartmentAgentChangedByDepartmentId( +const _notifyOnLivechatDepartmentAgentChangedByDepartmentId = async ( departmentId: T['departmentId'], clientAction: 'inserted' | 'updated' = 'updated', -): Promise { - if (!dbWatchersDisabled) { - return; - } - +): Promise => { const items = LivechatDepartmentAgents.findByDepartmentId(departmentId, { projection: { _id: 1, agentId: 1, departmentId: 1 } }); for await (const item of items) { void api.broadcast('watch.livechatDepartmentAgents', { clientAction, id: item._id, data: item }); } -} +}; -export async function notifyOnLivechatDepartmentAgentChangedByAgentsAndDepartmentId( +const _notifyOnLivechatDepartmentAgentChangedByAgentsAndDepartmentId = async ( agentsIds: T['agentId'][], departmentId: T['departmentId'], clientAction: 'inserted' | 'updated' = 'updated', -): Promise { - if (!dbWatchersDisabled) { - return; - } - +): Promise => { const items = LivechatDepartmentAgents.findByAgentsAndDepartmentId(agentsIds, departmentId, { projection: { _id: 1, agentId: 1, departmentId: 1 }, }); @@ -419,22 +304,16 @@ export async function notifyOnLivechatDepartmentAgentChangedByAgentsAndDepartmen for await (const item of items) { void api.broadcast('watch.livechatDepartmentAgents', { clientAction, id: item._id, data: item }); } -} +}; -export async function notifyOnSettingChanged( +const _notifyOnSettingChanged = async ( setting: ISetting & { editor?: ISettingColor['editor'] }, clientAction: ClientAction = 'updated', -): Promise { - if (!dbWatchersDisabled) { - return; - } +): Promise => { void api.broadcast('watch.settings', { clientAction, setting }); -} +}; -export async function notifyOnSettingChangedById(id: ISetting['_id'], clientAction: ClientAction = 'updated'): Promise { - if (!dbWatchersDisabled) { - return; - } +const _notifyOnSettingChangedById = async (id: ISetting['_id'], clientAction: ClientAction = 'updated'): Promise => { const item = clientAction === 'removed' ? await Settings.trashFindOneById(id) : await Settings.findOneById(id); if (!item) { @@ -442,7 +321,7 @@ export async function notifyOnSettingChangedById(id: ISetting['_id'], clientActi } void api.broadcast('watch.settings', { clientAction, setting: item }); -} +}; type NotifyUserChange = { id: IUser['_id']; @@ -452,52 +331,79 @@ type NotifyUserChange = { unset?: Record; }; -export async function notifyOnUserChange({ clientAction, id, data, diff, unset }: NotifyUserChange) { - if (!dbWatchersDisabled) { - return; - } +const _notifyOnUserChange = async ({ clientAction, id, data, diff, unset }: NotifyUserChange) => { if (clientAction === 'removed') { void api.broadcast('watch.users', { clientAction, id }); return; } + if (clientAction === 'inserted') { void api.broadcast('watch.users', { clientAction, id, data: data! }); return; } void api.broadcast('watch.users', { clientAction, diff: diff!, unset: unset || {}, id }); -} +}; /** * Calls the callback only if DB Watchers are disabled */ -export async function notifyOnUserChangeAsync(cb: () => Promise) { - if (!dbWatchersDisabled) { - return; - } - +const _notifyOnUserChangeAsync = async (cb: () => Promise) => { const result = await cb(); if (!result) { return; } if (Array.isArray(result)) { - result.forEach((n) => notifyOnUserChange(n)); + result.forEach((n) => _notifyOnUserChange(n)); return; } - return notifyOnUserChange(result); -} + return _notifyOnUserChange(result); +}; // TODO this may be only useful on 'inserted' -export async function notifyOnUserChangeById({ clientAction, id }: { id: IUser['_id']; clientAction: 'inserted' | 'removed' | 'updated' }) { - if (!dbWatchersDisabled) { - return; - } +const _notifyOnUserChangeById = async ({ clientAction, id }: { id: IUser['_id']; clientAction: 'inserted' | 'removed' | 'updated' }) => { const user = await Users.findOneById(id); if (!user) { return; } - void notifyOnUserChange({ id, clientAction, data: user }); -} + void _notifyOnUserChange({ id, clientAction, data: user }); +}; + +export const notifyOnLivechatPriorityChanged = withDbWatcherCheck(_notifyOnLivechatPriorityChanged); +export const notifyOnRoomChanged = withDbWatcherCheck(_notifyOnRoomChanged); +export const notifyOnRoomChangedById = withDbWatcherCheck(_notifyOnRoomChangedById); +export const notifyOnRoomChangedByUsernamesOrUids = withDbWatcherCheck(_notifyOnRoomChangedByUsernamesOrUids); +export const notifyOnRoomChangedByUserDM = withDbWatcherCheck(_notifyOnRoomChangedByUserDM); +export const notifyOnPermissionChanged = withDbWatcherCheck(_notifyOnPermissionChanged); +export const notifyOnPermissionChangedById = withDbWatcherCheck(_notifyOnPermissionChangedById); +export const notifyOnPbxEventChangedById = withDbWatcherCheck(_notifyOnPbxEventChangedById); +export const notifyOnRoleChanged = withDbWatcherCheck(_notifyOnRoleChanged); +export const notifyOnRoleChangedById = withDbWatcherCheck(_notifyOnRoleChangedById); +export const notifyOnLoginServiceConfigurationChanged = withDbWatcherCheck(_notifyOnLoginServiceConfigurationChanged); +export const notifyOnLoginServiceConfigurationChangedByService = withDbWatcherCheck(_notifyOnLoginServiceConfigurationChangedByService); +export const notifyOnIntegrationChanged = withDbWatcherCheck(_notifyOnIntegrationChanged); +export const notifyOnIntegrationChangedById = withDbWatcherCheck(_notifyOnIntegrationChangedById); +export const notifyOnIntegrationChangedByUserId = withDbWatcherCheck(_notifyOnIntegrationChangedByUserId); +export const notifyOnIntegrationChangedByChannels = withDbWatcherCheck(_notifyOnIntegrationChangedByChannels); +export const notifyOnEmailInboxChanged = withDbWatcherCheck(_notifyOnEmailInboxChanged); +export const notifyOnLivechatInquiryChanged = withDbWatcherCheck(_notifyOnLivechatInquiryChanged); +export const notifyOnLivechatInquiryChangedById = withDbWatcherCheck(_notifyOnLivechatInquiryChangedById); +export const notifyOnLivechatInquiryChangedByRoom = withDbWatcherCheck(_notifyOnLivechatInquiryChangedByRoom); +export const notifyOnLivechatInquiryChangedByToken = withDbWatcherCheck(_notifyOnLivechatInquiryChangedByToken); +export const notifyOnIntegrationHistoryChanged = withDbWatcherCheck(_notifyOnIntegrationHistoryChanged); +export const notifyOnIntegrationHistoryChangedById = withDbWatcherCheck(_notifyOnIntegrationHistoryChangedById); +export const notifyOnLivechatDepartmentAgentChanged = withDbWatcherCheck(_notifyOnLivechatDepartmentAgentChanged); +export const notifyOnLivechatDepartmentAgentChangedByDepartmentId = withDbWatcherCheck( + _notifyOnLivechatDepartmentAgentChangedByDepartmentId, +); +export const notifyOnLivechatDepartmentAgentChangedByAgentsAndDepartmentId = withDbWatcherCheck( + _notifyOnLivechatDepartmentAgentChangedByAgentsAndDepartmentId, +); +export const notifyOnSettingChanged = withDbWatcherCheck(_notifyOnSettingChanged); +export const notifyOnSettingChangedById = withDbWatcherCheck(_notifyOnSettingChangedById); +export const notifyOnUserChange = withDbWatcherCheck(_notifyOnUserChange); +export const notifyOnUserChangeAsync = withDbWatcherCheck(_notifyOnUserChangeAsync); +export const notifyOnUserChangeById = withDbWatcherCheck(_notifyOnUserChangeById); From 250dc85ba015ca38686b4921b9e98a95875e93d1 Mon Sep 17 00:00:00 2001 From: Ricardo Garim Date: Mon, 8 Jul 2024 11:06:59 -0300 Subject: [PATCH 2/2] refactor: wrap middleware with exported const --- .../app/lib/server/lib/notifyListener.ts | 564 +++++++++--------- 1 file changed, 279 insertions(+), 285 deletions(-) diff --git a/apps/meteor/app/lib/server/lib/notifyListener.ts b/apps/meteor/app/lib/server/lib/notifyListener.ts index ee841f8652b0..635c236fda27 100644 --- a/apps/meteor/app/lib/server/lib/notifyListener.ts +++ b/apps/meteor/app/lib/server/lib/notifyListener.ts @@ -38,290 +38,318 @@ function withDbWatcherCheck Promise>(fn: T): return dbWatchersDisabled ? fn : ((() => Promise.resolve()) as T); } -const _notifyOnLivechatPriorityChanged = async ( - data: Pick, - clientAction: ClientAction = 'updated', -): Promise => { - const { _id, ...rest } = data; - void api.broadcast('watch.priorities', { clientAction, id: _id, diff: { ...rest } }); -}; - -const _notifyOnRoomChanged = async (data: T | T[], clientAction: ClientAction = 'updated'): Promise => { - const items = Array.isArray(data) ? data : [data]; - for (const item of items) { - void api.broadcast('watch.rooms', { clientAction, room: item }); - } -}; - -const _notifyOnRoomChangedById = async ( - ids: T['_id'] | T['_id'][], - clientAction: ClientAction = 'updated', -): Promise => { - const eligibleIds = Array.isArray(ids) ? ids : [ids]; - const items = Rooms.findByIds(eligibleIds); - for await (const item of items) { - void api.broadcast('watch.rooms', { clientAction, room: item }); - } -}; +export const notifyOnLivechatPriorityChanged = withDbWatcherCheck( + async (data: Pick, clientAction: ClientAction = 'updated'): Promise => { + const { _id, ...rest } = data; + void api.broadcast('watch.priorities', { clientAction, id: _id, diff: { ...rest } }); + }, +); -const _notifyOnRoomChangedByUsernamesOrUids = async ( - uids: T['u']['_id'][], - usernames: T['u']['username'][], - clientAction: ClientAction = 'updated', -): Promise => { - const items = Rooms.findByUsernamesOrUids(uids, usernames); - for await (const item of items) { - void api.broadcast('watch.rooms', { clientAction, room: item }); - } -}; +export const notifyOnRoomChanged = withDbWatcherCheck( + async (data: T | T[], clientAction: ClientAction = 'updated'): Promise => { + const items = Array.isArray(data) ? data : [data]; + for (const item of items) { + void api.broadcast('watch.rooms', { clientAction, room: item }); + } + }, +); -const _notifyOnRoomChangedByUserDM = async ( - userId: T['u']['_id'], - clientAction: ClientAction = 'updated', -): Promise => { - const items = Rooms.findDMsByUids([userId]); - for await (const item of items) { - void api.broadcast('watch.rooms', { clientAction, room: item }); - } -}; +export const notifyOnRoomChangedById = withDbWatcherCheck( + async (ids: T['_id'] | T['_id'][], clientAction: ClientAction = 'updated'): Promise => { + const eligibleIds = Array.isArray(ids) ? ids : [ids]; + const items = Rooms.findByIds(eligibleIds); + for await (const item of items) { + void api.broadcast('watch.rooms', { clientAction, room: item }); + } + }, +); -const _notifyOnPermissionChanged = async (permission: IPermission, clientAction: ClientAction = 'updated'): Promise => { - void api.broadcast('permission.changed', { clientAction, data: permission }); +export const notifyOnRoomChangedByUsernamesOrUids = withDbWatcherCheck( + async ( + uids: T['u']['_id'][], + usernames: T['u']['username'][], + clientAction: ClientAction = 'updated', + ): Promise => { + const items = Rooms.findByUsernamesOrUids(uids, usernames); + for await (const item of items) { + void api.broadcast('watch.rooms', { clientAction, room: item }); + } + }, +); - if (permission.level === 'settings' && permission.settingId) { - const setting = await Settings.findOneNotHiddenById(permission.settingId); - if (!setting) { - return; +export const notifyOnRoomChangedByUserDM = withDbWatcherCheck( + async (userId: T['u']['_id'], clientAction: ClientAction = 'updated'): Promise => { + const items = Rooms.findDMsByUids([userId]); + for await (const item of items) { + void api.broadcast('watch.rooms', { clientAction, room: item }); } - void _notifyOnSettingChanged(setting, 'updated'); - } -}; + }, +); -const _notifyOnPermissionChangedById = async (pid: IPermission['_id'], clientAction: ClientAction = 'updated'): Promise => { - const permission = await Permissions.findOneById(pid); - if (!permission) { - return; - } +export const notifyOnPermissionChanged = withDbWatcherCheck( + async (permission: IPermission, clientAction: ClientAction = 'updated'): Promise => { + void api.broadcast('permission.changed', { clientAction, data: permission }); - return _notifyOnPermissionChanged(permission, clientAction); -}; + if (permission.level === 'settings' && permission.settingId) { + const setting = await Settings.findOneNotHiddenById(permission.settingId); + if (!setting) { + return; + } + void notifyOnSettingChanged(setting, 'updated'); + } + }, +); -const _notifyOnPbxEventChangedById = async (id: T['_id'], clientAction: ClientAction = 'updated'): Promise => { - const item = await PbxEvents.findOneById(id); - if (!item) { - return; - } +export const notifyOnPermissionChangedById = withDbWatcherCheck( + async (pid: IPermission['_id'], clientAction: ClientAction = 'updated'): Promise => { + const permission = await Permissions.findOneById(pid); + if (!permission) { + return; + } - void api.broadcast('watch.pbxevents', { clientAction, id, data: item }); -}; + return notifyOnPermissionChanged(permission, clientAction); + }, +); -const _notifyOnRoleChanged = async (role: T, clientAction: 'removed' | 'changed' = 'changed'): Promise => { - void api.broadcast('watch.roles', { clientAction, role }); -}; +export const notifyOnPbxEventChangedById = withDbWatcherCheck( + async (id: T['_id'], clientAction: ClientAction = 'updated'): Promise => { + const item = await PbxEvents.findOneById(id); + if (!item) { + return; + } -const _notifyOnRoleChangedById = async (id: T['_id'], clientAction: 'removed' | 'changed' = 'changed'): Promise => { - const role = await Roles.findOneById(id); - if (!role) { - return; - } + void api.broadcast('watch.pbxevents', { clientAction, id, data: item }); + }, +); - void _notifyOnRoleChanged(role, clientAction); -}; +export const notifyOnRoleChanged = withDbWatcherCheck( + async (role: T, clientAction: 'removed' | 'changed' = 'changed'): Promise => { + void api.broadcast('watch.roles', { clientAction, role }); + }, +); -const _notifyOnLoginServiceConfigurationChanged = async ( - service: Partial & Pick, - clientAction: ClientAction = 'updated', -): Promise => { - void api.broadcast('watch.loginServiceConfiguration', { - clientAction, - id: service._id, - data: service, - }); -}; +export const notifyOnRoleChangedById = withDbWatcherCheck( + async (id: T['_id'], clientAction: 'removed' | 'changed' = 'changed'): Promise => { + const role = await Roles.findOneById(id); + if (!role) { + return; + } -const _notifyOnLoginServiceConfigurationChangedByService = async ( - service: T['service'], - clientAction: ClientAction = 'updated', -): Promise => { - const item = await LoginServiceConfiguration.findOneByService>(service, { - projection: { secret: 0 }, - }); - if (!item) { - return; - } + void notifyOnRoleChanged(role, clientAction); + }, +); - void _notifyOnLoginServiceConfigurationChanged(item, clientAction); -}; +export const notifyOnLoginServiceConfigurationChanged = withDbWatcherCheck( + async ( + service: Partial & Pick, + clientAction: ClientAction = 'updated', + ): Promise => { + void api.broadcast('watch.loginServiceConfiguration', { + clientAction, + id: service._id, + data: service, + }); + }, +); -const _notifyOnIntegrationChanged = async (data: T, clientAction: ClientAction = 'updated'): Promise => { - void api.broadcast('watch.integrations', { clientAction, id: data._id, data }); -}; +export const notifyOnLoginServiceConfigurationChangedByService = withDbWatcherCheck( + async (service: T['service'], clientAction: ClientAction = 'updated'): Promise => { + const item = await LoginServiceConfiguration.findOneByService>(service, { + projection: { secret: 0 }, + }); + if (!item) { + return; + } -const _notifyOnIntegrationChangedById = async ( - id: T['_id'], - clientAction: ClientAction = 'updated', -): Promise => { - const item = await Integrations.findOneById(id); - if (!item) { - return; - } + void notifyOnLoginServiceConfigurationChanged(item, clientAction); + }, +); - void api.broadcast('watch.integrations', { clientAction, id: item._id, data: item }); -}; +export const notifyOnIntegrationChanged = withDbWatcherCheck( + async (data: T, clientAction: ClientAction = 'updated'): Promise => { + void api.broadcast('watch.integrations', { clientAction, id: data._id, data }); + }, +); -const _notifyOnIntegrationChangedByUserId = async ( - id: T['userId'], - clientAction: ClientAction = 'updated', -): Promise => { - const items = Integrations.findByUserId(id); +export const notifyOnIntegrationChangedById = withDbWatcherCheck( + async (id: T['_id'], clientAction: ClientAction = 'updated'): Promise => { + const item = await Integrations.findOneById(id); + if (!item) { + return; + } - for await (const item of items) { void api.broadcast('watch.integrations', { clientAction, id: item._id, data: item }); - } -}; + }, +); -const _notifyOnIntegrationChangedByChannels = async ( - channels: T['channel'], - clientAction: ClientAction = 'updated', -): Promise => { - const items = Integrations.findByChannels(channels); +export const notifyOnIntegrationChangedByUserId = withDbWatcherCheck( + async (id: T['userId'], clientAction: ClientAction = 'updated'): Promise => { + const items = Integrations.findByUserId(id); - for await (const item of items) { - void api.broadcast('watch.integrations', { clientAction, id: item._id, data: item }); - } -}; + for await (const item of items) { + void api.broadcast('watch.integrations', { clientAction, id: item._id, data: item }); + } + }, +); -const _notifyOnEmailInboxChanged = async ( - data: Pick | T, // TODO: improve typing - clientAction: ClientAction = 'updated', -): Promise => { - void api.broadcast('watch.emailInbox', { clientAction, id: data._id, data }); -}; +export const notifyOnIntegrationChangedByChannels = withDbWatcherCheck( + async (channels: T['channel'], clientAction: ClientAction = 'updated'): Promise => { + const items = Integrations.findByChannels(channels); -const _notifyOnLivechatInquiryChanged = async ( - data: ILivechatInquiryRecord | ILivechatInquiryRecord[], - clientAction: ClientAction = 'updated', - diff?: Partial & { queuedAt: unknown; takenAt: unknown }>, -): Promise => { - const items = Array.isArray(data) ? data : [data]; + for await (const item of items) { + void api.broadcast('watch.integrations', { clientAction, id: item._id, data: item }); + } + }, +); - for (const item of items) { - void api.broadcast('watch.inquiries', { clientAction, inquiry: item, diff }); - } -}; +export const notifyOnEmailInboxChanged = withDbWatcherCheck( + async ( + data: Pick | T, // TODO: improve typing + clientAction: ClientAction = 'updated', + ): Promise => { + void api.broadcast('watch.emailInbox', { clientAction, id: data._id, data }); + }, +); -const _notifyOnLivechatInquiryChangedById = async ( - id: ILivechatInquiryRecord['_id'], - clientAction: ClientAction = 'updated', - diff?: Partial & { queuedAt: unknown; takenAt: unknown }>, -): Promise => { - const inquiry = clientAction === 'removed' ? await LivechatInquiry.trashFindOneById(id) : await LivechatInquiry.findOneById(id); +export const notifyOnLivechatInquiryChanged = withDbWatcherCheck( + async ( + data: ILivechatInquiryRecord | ILivechatInquiryRecord[], + clientAction: ClientAction = 'updated', + diff?: Partial & { queuedAt: unknown; takenAt: unknown }>, + ): Promise => { + const items = Array.isArray(data) ? data : [data]; - if (!inquiry) { - return; - } + for (const item of items) { + void api.broadcast('watch.inquiries', { clientAction, inquiry: item, diff }); + } + }, +); - void api.broadcast('watch.inquiries', { clientAction, inquiry, diff }); -}; +export const notifyOnLivechatInquiryChangedById = withDbWatcherCheck( + async ( + id: ILivechatInquiryRecord['_id'], + clientAction: ClientAction = 'updated', + diff?: Partial & { queuedAt: unknown; takenAt: unknown }>, + ): Promise => { + const inquiry = clientAction === 'removed' ? await LivechatInquiry.trashFindOneById(id) : await LivechatInquiry.findOneById(id); -const _notifyOnLivechatInquiryChangedByRoom = async ( - rid: ILivechatInquiryRecord['rid'], - clientAction: ClientAction = 'updated', - diff?: Partial & { queuedAt: unknown; takenAt: unknown }>, -): Promise => { - const inquiry = await LivechatInquiry.findOneByRoomId(rid, {}); + if (!inquiry) { + return; + } - if (!inquiry) { - return; - } + void api.broadcast('watch.inquiries', { clientAction, inquiry, diff }); + }, +); - void api.broadcast('watch.inquiries', { clientAction, inquiry, diff }); -}; +export const notifyOnLivechatInquiryChangedByRoom = withDbWatcherCheck( + async ( + rid: ILivechatInquiryRecord['rid'], + clientAction: ClientAction = 'updated', + diff?: Partial & { queuedAt: unknown; takenAt: unknown }>, + ): Promise => { + const inquiry = await LivechatInquiry.findOneByRoomId(rid, {}); -const _notifyOnLivechatInquiryChangedByToken = async ( - token: ILivechatInquiryRecord['v']['token'], - clientAction: ClientAction = 'updated', - diff?: Partial & { queuedAt: unknown; takenAt: unknown }>, -): Promise => { - const inquiry = await LivechatInquiry.findOneByToken(token); + if (!inquiry) { + return; + } - if (!inquiry) { - return; - } + void api.broadcast('watch.inquiries', { clientAction, inquiry, diff }); + }, +); - void api.broadcast('watch.inquiries', { clientAction, inquiry, diff }); -}; +export const notifyOnLivechatInquiryChangedByToken = withDbWatcherCheck( + async ( + token: ILivechatInquiryRecord['v']['token'], + clientAction: ClientAction = 'updated', + diff?: Partial & { queuedAt: unknown; takenAt: unknown }>, + ): Promise => { + const inquiry = await LivechatInquiry.findOneByToken(token); -const _notifyOnIntegrationHistoryChanged = async ( - data: AtLeast, - clientAction: ClientAction = 'updated', - diff: Partial = {}, -): Promise => { - void api.broadcast('watch.integrationHistory', { clientAction, id: data._id, data, diff }); -}; + if (!inquiry) { + return; + } -const _notifyOnIntegrationHistoryChangedById = async ( - id: T['_id'], - clientAction: ClientAction = 'updated', - diff: Partial = {}, -): Promise => { - const item = await IntegrationHistory.findOneById(id); + void api.broadcast('watch.inquiries', { clientAction, inquiry, diff }); + }, +); - if (!item) { - return; - } +export const notifyOnIntegrationHistoryChanged = withDbWatcherCheck( + async ( + data: AtLeast, + clientAction: ClientAction = 'updated', + diff: Partial = {}, + ): Promise => { + void api.broadcast('watch.integrationHistory', { clientAction, id: data._id, data, diff }); + }, +); - void api.broadcast('watch.integrationHistory', { clientAction, id: item._id, data: item, diff }); -}; +export const notifyOnIntegrationHistoryChangedById = withDbWatcherCheck( + async (id: T['_id'], clientAction: ClientAction = 'updated', diff: Partial = {}): Promise => { + const item = await IntegrationHistory.findOneById(id); -const _notifyOnLivechatDepartmentAgentChanged = async ( - data: Partial & Pick, - clientAction: ClientAction = 'updated', -): Promise => { - void api.broadcast('watch.livechatDepartmentAgents', { clientAction, id: data._id, data }); -}; + if (!item) { + return; + } -const _notifyOnLivechatDepartmentAgentChangedByDepartmentId = async ( - departmentId: T['departmentId'], - clientAction: 'inserted' | 'updated' = 'updated', -): Promise => { - const items = LivechatDepartmentAgents.findByDepartmentId(departmentId, { projection: { _id: 1, agentId: 1, departmentId: 1 } }); + void api.broadcast('watch.integrationHistory', { clientAction, id: item._id, data: item, diff }); + }, +); - for await (const item of items) { - void api.broadcast('watch.livechatDepartmentAgents', { clientAction, id: item._id, data: item }); - } -}; +export const notifyOnLivechatDepartmentAgentChanged = withDbWatcherCheck( + async ( + data: Partial & Pick, + clientAction: ClientAction = 'updated', + ): Promise => { + void api.broadcast('watch.livechatDepartmentAgents', { clientAction, id: data._id, data }); + }, +); -const _notifyOnLivechatDepartmentAgentChangedByAgentsAndDepartmentId = async ( - agentsIds: T['agentId'][], - departmentId: T['departmentId'], - clientAction: 'inserted' | 'updated' = 'updated', -): Promise => { - const items = LivechatDepartmentAgents.findByAgentsAndDepartmentId(agentsIds, departmentId, { - projection: { _id: 1, agentId: 1, departmentId: 1 }, - }); - - for await (const item of items) { - void api.broadcast('watch.livechatDepartmentAgents', { clientAction, id: item._id, data: item }); - } -}; +export const notifyOnLivechatDepartmentAgentChangedByDepartmentId = withDbWatcherCheck( + async ( + departmentId: T['departmentId'], + clientAction: 'inserted' | 'updated' = 'updated', + ): Promise => { + const items = LivechatDepartmentAgents.findByDepartmentId(departmentId, { projection: { _id: 1, agentId: 1, departmentId: 1 } }); + + for await (const item of items) { + void api.broadcast('watch.livechatDepartmentAgents', { clientAction, id: item._id, data: item }); + } + }, +); -const _notifyOnSettingChanged = async ( - setting: ISetting & { editor?: ISettingColor['editor'] }, - clientAction: ClientAction = 'updated', -): Promise => { - void api.broadcast('watch.settings', { clientAction, setting }); -}; +export const notifyOnLivechatDepartmentAgentChangedByAgentsAndDepartmentId = withDbWatcherCheck( + async ( + agentsIds: T['agentId'][], + departmentId: T['departmentId'], + clientAction: 'inserted' | 'updated' = 'updated', + ): Promise => { + const items = LivechatDepartmentAgents.findByAgentsAndDepartmentId(agentsIds, departmentId, { + projection: { _id: 1, agentId: 1, departmentId: 1 }, + }); + + for await (const item of items) { + void api.broadcast('watch.livechatDepartmentAgents', { clientAction, id: item._id, data: item }); + } + }, +); -const _notifyOnSettingChangedById = async (id: ISetting['_id'], clientAction: ClientAction = 'updated'): Promise => { - const item = clientAction === 'removed' ? await Settings.trashFindOneById(id) : await Settings.findOneById(id); +export const notifyOnSettingChanged = withDbWatcherCheck( + async (setting: ISetting & { editor?: ISettingColor['editor'] }, clientAction: ClientAction = 'updated'): Promise => { + void api.broadcast('watch.settings', { clientAction, setting }); + }, +); - if (!item) { - return; - } +export const notifyOnSettingChangedById = withDbWatcherCheck( + async (id: ISetting['_id'], clientAction: ClientAction = 'updated'): Promise => { + const item = clientAction === 'removed' ? await Settings.trashFindOneById(id) : await Settings.findOneById(id); - void api.broadcast('watch.settings', { clientAction, setting: item }); -}; + if (!item) { + return; + } + + void api.broadcast('watch.settings', { clientAction, setting: item }); + }, +); type NotifyUserChange = { id: IUser['_id']; @@ -331,7 +359,7 @@ type NotifyUserChange = { unset?: Record; }; -const _notifyOnUserChange = async ({ clientAction, id, data, diff, unset }: NotifyUserChange) => { +export const notifyOnUserChange = withDbWatcherCheck(async ({ clientAction, id, data, diff, unset }: NotifyUserChange) => { if (clientAction === 'removed') { void api.broadcast('watch.users', { clientAction, id }); return; @@ -343,67 +371,33 @@ const _notifyOnUserChange = async ({ clientAction, id, data, diff, unset }: Noti } void api.broadcast('watch.users', { clientAction, diff: diff!, unset: unset || {}, id }); -}; +}); /** * Calls the callback only if DB Watchers are disabled */ -const _notifyOnUserChangeAsync = async (cb: () => Promise) => { +export const notifyOnUserChangeAsync = withDbWatcherCheck(async (cb: () => Promise) => { const result = await cb(); if (!result) { return; } if (Array.isArray(result)) { - result.forEach((n) => _notifyOnUserChange(n)); + result.forEach((n) => notifyOnUserChange(n)); return; } - return _notifyOnUserChange(result); -}; + return notifyOnUserChange(result); +}); // TODO this may be only useful on 'inserted' -const _notifyOnUserChangeById = async ({ clientAction, id }: { id: IUser['_id']; clientAction: 'inserted' | 'removed' | 'updated' }) => { - const user = await Users.findOneById(id); - if (!user) { - return; - } - - void _notifyOnUserChange({ id, clientAction, data: user }); -}; +export const notifyOnUserChangeById = withDbWatcherCheck( + async ({ clientAction, id }: { id: IUser['_id']; clientAction: 'inserted' | 'removed' | 'updated' }) => { + const user = await Users.findOneById(id); + if (!user) { + return; + } -export const notifyOnLivechatPriorityChanged = withDbWatcherCheck(_notifyOnLivechatPriorityChanged); -export const notifyOnRoomChanged = withDbWatcherCheck(_notifyOnRoomChanged); -export const notifyOnRoomChangedById = withDbWatcherCheck(_notifyOnRoomChangedById); -export const notifyOnRoomChangedByUsernamesOrUids = withDbWatcherCheck(_notifyOnRoomChangedByUsernamesOrUids); -export const notifyOnRoomChangedByUserDM = withDbWatcherCheck(_notifyOnRoomChangedByUserDM); -export const notifyOnPermissionChanged = withDbWatcherCheck(_notifyOnPermissionChanged); -export const notifyOnPermissionChangedById = withDbWatcherCheck(_notifyOnPermissionChangedById); -export const notifyOnPbxEventChangedById = withDbWatcherCheck(_notifyOnPbxEventChangedById); -export const notifyOnRoleChanged = withDbWatcherCheck(_notifyOnRoleChanged); -export const notifyOnRoleChangedById = withDbWatcherCheck(_notifyOnRoleChangedById); -export const notifyOnLoginServiceConfigurationChanged = withDbWatcherCheck(_notifyOnLoginServiceConfigurationChanged); -export const notifyOnLoginServiceConfigurationChangedByService = withDbWatcherCheck(_notifyOnLoginServiceConfigurationChangedByService); -export const notifyOnIntegrationChanged = withDbWatcherCheck(_notifyOnIntegrationChanged); -export const notifyOnIntegrationChangedById = withDbWatcherCheck(_notifyOnIntegrationChangedById); -export const notifyOnIntegrationChangedByUserId = withDbWatcherCheck(_notifyOnIntegrationChangedByUserId); -export const notifyOnIntegrationChangedByChannels = withDbWatcherCheck(_notifyOnIntegrationChangedByChannels); -export const notifyOnEmailInboxChanged = withDbWatcherCheck(_notifyOnEmailInboxChanged); -export const notifyOnLivechatInquiryChanged = withDbWatcherCheck(_notifyOnLivechatInquiryChanged); -export const notifyOnLivechatInquiryChangedById = withDbWatcherCheck(_notifyOnLivechatInquiryChangedById); -export const notifyOnLivechatInquiryChangedByRoom = withDbWatcherCheck(_notifyOnLivechatInquiryChangedByRoom); -export const notifyOnLivechatInquiryChangedByToken = withDbWatcherCheck(_notifyOnLivechatInquiryChangedByToken); -export const notifyOnIntegrationHistoryChanged = withDbWatcherCheck(_notifyOnIntegrationHistoryChanged); -export const notifyOnIntegrationHistoryChangedById = withDbWatcherCheck(_notifyOnIntegrationHistoryChangedById); -export const notifyOnLivechatDepartmentAgentChanged = withDbWatcherCheck(_notifyOnLivechatDepartmentAgentChanged); -export const notifyOnLivechatDepartmentAgentChangedByDepartmentId = withDbWatcherCheck( - _notifyOnLivechatDepartmentAgentChangedByDepartmentId, -); -export const notifyOnLivechatDepartmentAgentChangedByAgentsAndDepartmentId = withDbWatcherCheck( - _notifyOnLivechatDepartmentAgentChangedByAgentsAndDepartmentId, + void notifyOnUserChange({ id, clientAction, data: user }); + }, ); -export const notifyOnSettingChanged = withDbWatcherCheck(_notifyOnSettingChanged); -export const notifyOnSettingChangedById = withDbWatcherCheck(_notifyOnSettingChangedById); -export const notifyOnUserChange = withDbWatcherCheck(_notifyOnUserChange); -export const notifyOnUserChangeAsync = withDbWatcherCheck(_notifyOnUserChangeAsync); -export const notifyOnUserChangeById = withDbWatcherCheck(_notifyOnUserChangeById);