From dd4c2f77b326f248bd9328119e109323463698e6 Mon Sep 17 00:00:00 2001
From: Kevin Aleman <kaleman960@gmail.com>
Date: Mon, 29 Aug 2022 13:06:04 -0600
Subject: [PATCH] [FIX] Business Units endpoints not filtering by Unit type
 (#26713)

Co-authored-by: murtaza98 <murtaza.patrawala@rocket.chat>
---
 .../server/roomAccessValidator.compatibility.js    |  3 +++
 apps/meteor/ee/app/license/server/getStatistics.ts | 10 ++++++----
 .../livechat-enterprise/server/api/lib/units.ts    |  3 +--
 .../ee/app/models/server/raw/LivechatRooms.js      |  1 +
 apps/meteor/ee/server/models/raw/LivechatUnit.ts   | 14 ++++++++++++--
 .../model-typings/src/models/ILivechatUnitModel.ts |  8 ++++++++
 6 files changed, 31 insertions(+), 8 deletions(-)

diff --git a/apps/meteor/app/livechat/server/roomAccessValidator.compatibility.js b/apps/meteor/app/livechat/server/roomAccessValidator.compatibility.js
index fa2e7dcecdb..fe6e1d4a636 100644
--- a/apps/meteor/app/livechat/server/roomAccessValidator.compatibility.js
+++ b/apps/meteor/app/livechat/server/roomAccessValidator.compatibility.js
@@ -51,6 +51,9 @@ export const validators = [
 				{
 					...(departmentIds && departmentIds.length > 0 && { department: { $in: departmentIds } }),
 				},
+				{
+					department: { $exists: false }, // No department == public queue
+				},
 			],
 		};
 
diff --git a/apps/meteor/ee/app/license/server/getStatistics.ts b/apps/meteor/ee/app/license/server/getStatistics.ts
index 9c6146d1350..ece779f63c8 100644
--- a/apps/meteor/ee/app/license/server/getStatistics.ts
+++ b/apps/meteor/ee/app/license/server/getStatistics.ts
@@ -57,10 +57,12 @@ export async function getStatistics(): Promise<ENTERPRISE_STATISTICS> {
 
 	// Number of business units
 	statsPms.push(
-		LivechatUnit.col.count().then((count) => {
-			statistics.businessUnits = count;
-			return true;
-		}),
+		LivechatUnit.find({ type: 'u' })
+			.count()
+			.then((count) => {
+				statistics.businessUnits = count;
+				return true;
+			}),
 	);
 
 	await Promise.all(statsPms).catch(log);
diff --git a/apps/meteor/ee/app/livechat-enterprise/server/api/lib/units.ts b/apps/meteor/ee/app/livechat-enterprise/server/api/lib/units.ts
index 007ed787234..1f476443eeb 100644
--- a/apps/meteor/ee/app/livechat-enterprise/server/api/lib/units.ts
+++ b/apps/meteor/ee/app/livechat-enterprise/server/api/lib/units.ts
@@ -30,8 +30,7 @@ export async function findUnits({
 
 	const query = { ...(text && { $or: [{ name: filter }] }) };
 
-	// TODO need to enfore type IOmnichannelBusinessUnit on LivechatUnit model, so don't need to use generic everywhere
-	const { cursor, totalCount } = LivechatUnit.findPaginated<IOmnichannelBusinessUnit>(query, {
+	const { cursor, totalCount } = LivechatUnit.findPaginatedUnits(query, {
 		sort: sort || { name: 1 },
 		skip: offset,
 		limit: count,
diff --git a/apps/meteor/ee/app/models/server/raw/LivechatRooms.js b/apps/meteor/ee/app/models/server/raw/LivechatRooms.js
index 6f72f076e38..bc7ee28ac5e 100644
--- a/apps/meteor/ee/app/models/server/raw/LivechatRooms.js
+++ b/apps/meteor/ee/app/models/server/raw/LivechatRooms.js
@@ -13,6 +13,7 @@ const applyRestrictions = (method) =>
 overwriteClassOnLicense('livechat-enterprise', LivechatRoomsRaw, {
 	find: applyRestrictions('find'),
 	update: applyRestrictions('update'),
+	findPaginated: applyRestrictions('findPaginated'),
 	remove: applyRestrictions('remove'),
 	updateDepartmentAncestorsById(originalFn, _id, departmentAncestors) {
 		const query = {
diff --git a/apps/meteor/ee/server/models/raw/LivechatUnit.ts b/apps/meteor/ee/server/models/raw/LivechatUnit.ts
index 7429f83d485..c3fd0b418c0 100644
--- a/apps/meteor/ee/server/models/raw/LivechatUnit.ts
+++ b/apps/meteor/ee/server/models/raw/LivechatUnit.ts
@@ -1,5 +1,15 @@
-import type { ILivechatUnitModel } from '@rocket.chat/model-typings';
+import type { IOmnichannelBusinessUnit } from '@rocket.chat/core-typings';
+import type { FindPaginated, ILivechatUnitModel } from '@rocket.chat/model-typings';
+import type { FindOptions, Filter, FindCursor } from 'mongodb';
 
 import { LivechatDepartmentRaw } from '../../../../server/models/raw/LivechatDepartment';
 
-export class LivechatUnitRaw extends LivechatDepartmentRaw implements ILivechatUnitModel {}
+export class LivechatUnitRaw extends LivechatDepartmentRaw implements ILivechatUnitModel {
+	findPaginatedUnits(
+		query: Filter<IOmnichannelBusinessUnit>,
+		options?: FindOptions<IOmnichannelBusinessUnit>,
+	): FindPaginated<FindCursor<IOmnichannelBusinessUnit>> {
+		// @ts-expect-error - This extend from LivechatDepartment messes up with the types
+		return super.findPaginated({ ...query, type: 'u' }, options);
+	}
+}
diff --git a/packages/model-typings/src/models/ILivechatUnitModel.ts b/packages/model-typings/src/models/ILivechatUnitModel.ts
index 923c180052a..5906fc92c25 100644
--- a/packages/model-typings/src/models/ILivechatUnitModel.ts
+++ b/packages/model-typings/src/models/ILivechatUnitModel.ts
@@ -1,6 +1,14 @@
+import type { IOmnichannelBusinessUnit } from '@rocket.chat/core-typings';
+import type { FindOptions, Filter, FindCursor } from 'mongodb';
+
+import type { FindPaginated } from './IBaseModel';
 import type { ILivechatDepartmentModel } from './ILivechatDepartmentModel';
 
 // eslint-disable-next-line @typescript-eslint/no-empty-interface
 export interface ILivechatUnitModel extends ILivechatDepartmentModel {
 	//
+	findPaginatedUnits(
+		query: Filter<IOmnichannelBusinessUnit>,
+		options?: FindOptions<IOmnichannelBusinessUnit>,
+	): FindPaginated<FindCursor<IOmnichannelBusinessUnit>>;
 }
-- 
GitLab