Skip to content

Commit

Permalink
Merge branch 'develop' into fix-flaky-omni
Browse files Browse the repository at this point in the history
  • Loading branch information
kodiakhq[bot] authored Oct 24, 2024
2 parents 9051adb + ad5d85b commit fb3f674
Show file tree
Hide file tree
Showing 118 changed files with 831 additions and 220 deletions.
5 changes: 5 additions & 0 deletions .changeset/bump-patch-1729717124346.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@rocket.chat/meteor': patch
---

Bump @rocket.chat/meteor version.
1 change: 1 addition & 0 deletions .changeset/pre.json
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,7 @@
"brown-pants-press",
"bump-patch-1729526930133",
"bump-patch-1729648473274",
"bump-patch-1729717124346",
"chilled-boats-sip",
"chilled-files-relate",
"chilly-flowers-brake",
Expand Down
5 changes: 4 additions & 1 deletion _templates/service/new/service.ejs.t
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,17 @@ to: ee/apps/<%= name %>/src/service.ts
---
import { api, getConnection, getTrashCollection } from '@rocket.chat/core-services';
import { broker } from '@rocket.chat/network-broker';
import { startTracing } from '@rocket.chat/tracing';
import polka from 'polka';

import { registerServiceModels } from '../../../../apps/meteor/ee/server/lib/registerServiceModels';

const PORT = process.env.PORT || <%= h.random() %>;

(async () => {
const db = await getConnection();
const { db } = await getConnection();

startTracing({ service: '<%= name %>', db: client });

registerServiceModels(db, await getTrashCollection());

Expand Down
35 changes: 35 additions & 0 deletions apps/meteor/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,40 @@
# @rocket.chat/meteor

## 7.0.0-rc.3

### Patch Changes

- Bump @rocket.chat/meteor version.

- <details><summary>Updated dependencies []:</summary>

- @rocket.chat/[email protected]
- @rocket.chat/[email protected]
- @rocket.chat/[email protected]
- @rocket.chat/[email protected]
- @rocket.chat/[email protected]
- @rocket.chat/[email protected]
- @rocket.chat/[email protected]
- @rocket.chat/[email protected]
- @rocket.chat/[email protected]
- @rocket.chat/[email protected]
- @rocket.chat/[email protected]
- @rocket.chat/[email protected]
- @rocket.chat/[email protected]
- @rocket.chat/[email protected]
- @rocket.chat/[email protected]
- @rocket.chat/[email protected]
- @rocket.chat/[email protected]
- @rocket.chat/[email protected]
- @rocket.chat/[email protected]
- @rocket.chat/[email protected]
- @rocket.chat/[email protected]
- @rocket.chat/[email protected]
- @rocket.chat/[email protected]
- @rocket.chat/[email protected]
- @rocket.chat/[email protected]
</details>

## 7.0.0-rc.2

### Patch Changes
Expand Down
3 changes: 2 additions & 1 deletion apps/meteor/app/api/server/v1/misc.ts
Original file line number Diff line number Diff line change
Expand Up @@ -664,7 +664,8 @@ API.v1.addRoute(
const settingsIds: string[] = [];

if (this.bodyParams.setDeploymentAs === 'new-workspace') {
await WorkspaceCredentials.unsetCredentialByScope();
await WorkspaceCredentials.removeAllCredentials();

settingsIds.push(
'Cloud_Service_Agree_PrivacyTerms',
'Cloud_Workspace_Id',
Expand Down
2 changes: 1 addition & 1 deletion apps/meteor/app/apps/server/bridges/cloud.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ export class AppCloudBridge extends CloudWorkspaceBridge {
public async getWorkspaceToken(scope: string, appId: string): Promise<IWorkspaceToken> {
this.orch.debugLog(`App ${appId} is getting the workspace's token`);

const token = await getWorkspaceAccessTokenWithScope(scope);
const token = await getWorkspaceAccessTokenWithScope({ scope });

return token;
}
Expand Down
21 changes: 15 additions & 6 deletions apps/meteor/app/cloud/server/functions/getWorkspaceAccessToken.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
import type { IWorkspaceCredentials } from '@rocket.chat/core-typings';
import { WorkspaceCredentials } from '@rocket.chat/models';

import { SystemLogger } from '../../../../server/lib/logger/system';
import { workspaceScopes } from '../oauthScopes';
import { getWorkspaceAccessTokenWithScope } from './getWorkspaceAccessTokenWithScope';
import { retrieveRegistrationStatus } from './retrieveRegistrationStatus';

Expand All @@ -24,20 +26,27 @@ export async function getWorkspaceAccessToken(forceNew = false, scope = '', save
return '';
}

const workspaceCredentials = await WorkspaceCredentials.getCredentialByScope(scope);
if (!workspaceCredentials) {
throw new CloudWorkspaceAccessTokenError();
// Note: If no scope is given, it means we should assume the default scope, we store the default scopes
// in the global variable workspaceScopes.
if (scope === '') {
scope = workspaceScopes.join(' ');
}

if (!hasWorkspaceAccessTokenExpired(workspaceCredentials) && !forceNew) {
const workspaceCredentials = await WorkspaceCredentials.getCredentialByScope(scope);
if (workspaceCredentials && !hasWorkspaceAccessTokenExpired(workspaceCredentials) && !forceNew) {
SystemLogger.debug(
`Workspace credentials cache hit using scope: ${scope}. Avoiding generating a new access token from cloud services.`,
);
return workspaceCredentials.accessToken;
}

const accessToken = await getWorkspaceAccessTokenWithScope(scope, throwOnError);
SystemLogger.debug(`Workspace credentials cache miss using scope: ${scope}, fetching new access token from cloud services.`);

const accessToken = await getWorkspaceAccessTokenWithScope({ scope, throwOnError });

if (save) {
await WorkspaceCredentials.updateCredentialByScope({
scope,
scope: accessToken.scope,
accessToken: accessToken.token,
expirationDate: accessToken.expiresAt,
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,24 @@ import { CloudWorkspaceAccessTokenError } from './getWorkspaceAccessToken';
import { removeWorkspaceRegistrationInfo } from './removeWorkspaceRegistrationInfo';
import { retrieveRegistrationStatus } from './retrieveRegistrationStatus';

export async function getWorkspaceAccessTokenWithScope(scope = '', throwOnError = false) {
type WorkspaceAccessTokenWithScope = {
token: string;
expiresAt: Date;
scope: string;
};

type GetWorkspaceAccessTokenWithScopeParams = {
scope?: string;
throwOnError?: boolean;
};

export async function getWorkspaceAccessTokenWithScope({
scope = '',
throwOnError = false,
}: GetWorkspaceAccessTokenWithScopeParams): Promise<WorkspaceAccessTokenWithScope> {
const { workspaceRegistered } = await retrieveRegistrationStatus();

const tokenResponse = { token: '', expiresAt: new Date() };
const tokenResponse = { token: '', expiresAt: new Date(), scope: '' };

if (!workspaceRegistered) {
return tokenResponse;
Expand Down Expand Up @@ -62,6 +76,7 @@ export async function getWorkspaceAccessTokenWithScope(scope = '', throwOnError
return {
token: payload.access_token,
expiresAt,
scope: payload.scope,
};
} catch (err: any) {
if (err instanceof CloudWorkspaceAccessTokenError) {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { applyLicense } from '@rocket.chat/license';
import { Settings, WorkspaceCredentials } from '@rocket.chat/models';
import { Settings } from '@rocket.chat/models';

import { notifyOnSettingChangedById } from '../../../lib/server/lib/notifyListener';
import { settings } from '../../../settings/server';
Expand Down Expand Up @@ -59,12 +59,6 @@ async function saveRegistrationDataBase({
{ _id: 'Cloud_Workspace_Registration_Client_Uri', value: registration_client_uri },
];

await WorkspaceCredentials.updateCredentialByScope({
scope: '',
accessToken: '',
expirationDate: new Date(0),
});

const promises = [...settingsData.map(({ _id, value }) => Settings.updateValueById(_id, value))];

(await Promise.all(promises)).forEach((value, index) => {
Expand Down
61 changes: 39 additions & 22 deletions apps/meteor/app/e2e/server/methods/updateGroupKey.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,13 @@
import type { ServerMethods } from '@rocket.chat/ddp-client';
import { Subscriptions } from '@rocket.chat/models';
import { Subscriptions, Rooms } from '@rocket.chat/models';
import { Meteor } from 'meteor/meteor';

import { methodDeprecationLogger } from '../../../lib/server/lib/deprecationWarningLogger';
import { notifyOnSubscriptionChangedById, notifyOnSubscriptionChanged } from '../../../lib/server/lib/notifyListener';
import {
notifyOnSubscriptionChangedById,
notifyOnSubscriptionChanged,
notifyOnRoomChangedById,
} from '../../../lib/server/lib/notifyListener';

declare module '@rocket.chat/ddp-client' {
// eslint-disable-next-line @typescript-eslint/naming-convention
Expand All @@ -12,32 +16,45 @@ declare module '@rocket.chat/ddp-client' {
}
}

export async function updateGroupKey(rid: string, uid: string, key: string, callerUserId: string) {
// I have a subscription to this room
const mySub = await Subscriptions.findOneByRoomIdAndUserId(rid, callerUserId);

if (mySub) {
// Setting the key to myself, can set directly to the final field
if (callerUserId === uid) {
const setGroupE2EKeyResponse = await Subscriptions.setGroupE2EKey(mySub._id, key);
// Case: I create an encrypted room before setting up my keys, and I reset the e2e keys
// Next login, I'll create the keys for the room, and set them here.
// However as I reset my keys, I'm on the `usersWaitingForKeys` queue
// So I need to remove myself from the queue and notify the time i reach here
// This way, I can provide the keys to other users
const { modifiedCount } = await Rooms.removeUsersFromE2EEQueueByRoomId(mySub.rid, [callerUserId]);
if (setGroupE2EKeyResponse.modifiedCount) {
void notifyOnSubscriptionChangedById(mySub._id);
}
if (modifiedCount) {
void notifyOnRoomChangedById(mySub.rid);
}
return;
}

// uid also has subscription to this room
const { value } = await Subscriptions.setGroupE2ESuggestedKey(uid, rid, key);
if (value) {
void notifyOnSubscriptionChanged(value);
}
}
}

Meteor.methods<ServerMethods>({
async 'e2e.updateGroupKey'(rid, uid, key) {
methodDeprecationLogger.method('e2e.updateGroupKey', '8.0.0');
const userId = Meteor.userId();
if (!userId) {
throw new Meteor.Error('error-invalid-user', 'Invalid user', { method: 'e2e.acceptSuggestedGroupKey' });
}

// I have a subscription to this room
const mySub = await Subscriptions.findOneByRoomIdAndUserId(rid, userId);

if (mySub) {
// Setting the key to myself, can set directly to the final field
if (userId === uid) {
const setGroupE2EKeyResponse = await Subscriptions.setGroupE2EKey(mySub._id, key);
if (setGroupE2EKeyResponse.modifiedCount) {
void notifyOnSubscriptionChangedById(mySub._id);
}
return;
}

// uid also has subscription to this room
const { value } = await Subscriptions.setGroupE2ESuggestedKey(uid, rid, key);
if (value) {
void notifyOnSubscriptionChanged(value);
}
}
methodDeprecationLogger.method('e2e.updateGroupKey', '8.0.0');
return updateGroupKey(rid, uid, key, userId);
},
});
1 change: 0 additions & 1 deletion apps/meteor/app/livechat/server/lib/Helper.ts
Original file line number Diff line number Diff line change
Expand Up @@ -407,7 +407,6 @@ export const dispatchInquiryQueued = async (inquiry: ILivechatInquiryRecord, age
return;
}

logger.debug(`Notifying ${await onlineAgents.count()} agents of new inquiry`);
const notificationUserName = v && (v.name || v.username);

for await (const agent of onlineAgents) {
Expand Down
10 changes: 9 additions & 1 deletion apps/meteor/app/livechat/server/lib/LivechatTyped.ts
Original file line number Diff line number Diff line change
Expand Up @@ -132,7 +132,7 @@ class LivechatClass {
Livechat.logger.debug(`Fetching online bot agents for department ${department}`);
const botAgents = await Livechat.getBotAgents(department);
if (botAgents) {
const onlineBots = await botAgents.count();
const onlineBots = await Livechat.countBotAgents(department);
this.logger.debug(`Found ${onlineBots} online`);
if (onlineBots > 0) {
return true;
Expand Down Expand Up @@ -632,6 +632,14 @@ class LivechatClass {
return Users.findBotAgents();
}

private async countBotAgents(department?: string) {
if (department) {
return LivechatDepartmentAgents.countBotsForDepartment(department);
}

return Users.countBotAgents();
}

private async resolveChatTags(
room: IOmnichannelRoom,
options: CloseRoomParams['options'] = {},
Expand Down
1 change: 0 additions & 1 deletion apps/meteor/app/livechat/server/lib/QueueManager.ts
Original file line number Diff line number Diff line change
Expand Up @@ -331,7 +331,6 @@ export class QueueManager {
return;
}

logger.debug(`Notifying ${await onlineAgents.count()} agents of new inquiry`);
const notificationUserName = v && (v.name || v.username);

for await (const agent of onlineAgents) {
Expand Down
4 changes: 2 additions & 2 deletions apps/meteor/app/livechat/server/lib/analytics/dashboards.ts
Original file line number Diff line number Diff line change
Expand Up @@ -247,11 +247,11 @@ const getConversationsMetricsAsync = async ({
language: user.language || settings.get('Language') || 'en',
})) || [];
const metrics = ['Total_conversations', 'Open_conversations', 'On_Hold_conversations', 'Total_messages'];
const visitorsCount = await LivechatVisitors.getVisitorsBetweenDate({
const visitorsCount = await LivechatVisitors.countVisitorsBetweenDate({
start: new Date(start),
end: new Date(end),
department: departmentId,
}).count();
});
return {
totalizers: [
...totalizers.filter((metric: { title: string }) => metrics.includes(metric.title)),
Expand Down
4 changes: 2 additions & 2 deletions apps/meteor/app/livechat/server/lib/departmentsLib.ts
Original file line number Diff line number Diff line change
Expand Up @@ -296,8 +296,8 @@ export async function getRequiredDepartment(onlineRequired = true) {
return dept;
}

const onlineAgents = await LivechatDepartmentAgents.getOnlineForDepartment(dept._id);
if (onlineAgents && (await onlineAgents.count())) {
const onlineAgents = await LivechatDepartmentAgents.countOnlineForDepartment(dept._id);
if (onlineAgents) {
return dept;
}
}
Expand Down
Loading

0 comments on commit fb3f674

Please sign in to comment.