Skip to content

Commit

Permalink
Merge pull request RocketChat#890 from Shailesh351/upstream_catchup_3…
Browse files Browse the repository at this point in the history
….17.1

[Upstream Catchup] Merge RC:master to develop_pwa (3.17.1)
  • Loading branch information
chadgoss authored Aug 18, 2021
2 parents c6ba9cf + 69887e5 commit ac4252d
Show file tree
Hide file tree
Showing 22 changed files with 208 additions and 37 deletions.
2 changes: 1 addition & 1 deletion .docker/Dockerfile.rhel
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
FROM registry.access.redhat.com/ubi8/nodejs-12

ENV RC_VERSION 3.17.0
ENV RC_VERSION 3.17.1

MAINTAINER [email protected]

Expand Down
71 changes: 71 additions & 0 deletions .github/history.json
Original file line number Diff line number Diff line change
Expand Up @@ -63650,6 +63650,77 @@
"4.2"
],
"pull_requests": []
},
"3.17.1": {
"node_version": "12.22.1",
"npm_version": "6.14.1",
"apps_engine_version": "1.27.1",
"mongo_versions": [
"3.4",
"3.6",
"4.0",
"4.2"
],
"pull_requests": [
{
"pr": "22871",
"title": "[FIX] \"Click to Join\" button is not working if there are no muted users in the room",
"userLogin": "matheusbsilva137",
"description": "- Add check to `room.muted` array so as to cover the case in which it is `undefined`;",
"milestone": "3.17.1",
"contributors": [
"matheusbsilva137",
"web-flow",
"tassoevan"
]
},
{
"pr": "22856",
"title": "[FIX] Message update not working in some cases",
"userLogin": "murtaza98",
"milestone": "3.17.1",
"contributors": [
"murtaza98",
"KevLehman",
"web-flow"
]
},
{
"pr": "22835",
"title": "[FIX] Use correct param on saveBusinessHour method",
"userLogin": "KevLehman",
"milestone": "3.17.1",
"contributors": [
"KevLehman",
"web-flow",
"renatobecker",
"murtaza98"
]
},
{
"pr": "22882",
"title": "[FIX] Apps-Engine's scheduler failing to update run tasks",
"userLogin": "thassiov",
"description": "[Agenda](https://github.com/agenda/agenda), the library that manages scheduling, depended on setting a job property named `nextRunAt` as `undefined` to signal whether it should be run on schedule or not. [Rocket.Chat's current Mongo driver](https://github.com/RocketChat/Rocket.Chat/pull/22399) ignores `undefined` values when updating documents and this was causing jobs to never stop running as Agenda couldn't clear that property (set them as `undefined`). \r\nThis updates Rocket.Chat's dependency on Agenda.js to point to [a fork that fixes the problem](https://github.com/RocketChat/agenda/releases/tag/3.1.2).",
"milestone": "3.17.1",
"contributors": [
"thassiov",
"web-flow",
"d-gubert"
]
},
{
"pr": "22917",
"title": "[FIX] Close omnichannel conversations when agent is deactivated",
"userLogin": "KevLehman",
"milestone": "3.17.1",
"contributors": [
"KevLehman",
"renatobecker",
"web-flow"
]
}
]
}
}
}
2 changes: 1 addition & 1 deletion .snapcraft/resources/prepareRocketChat
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
#!/bin/bash

curl -SLf "https://releases.rocket.chat/3.17.0/download/" -o rocket.chat.tgz
curl -SLf "https://releases.rocket.chat/3.17.1/download/" -o rocket.chat.tgz

tar xf rocket.chat.tgz --strip 1

Expand Down
2 changes: 1 addition & 1 deletion .snapcraft/snap/snapcraft.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
# 5. `snapcraft snap`

name: rocketchat-server
version: 3.17.0
version: 3.17.1
summary: Rocket.Chat server
description: Have your own Slack like online chat, built with Meteor. https://rocket.chat/
confinement: strict
Expand Down
39 changes: 38 additions & 1 deletion HISTORY.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,41 @@

# 3.17.1
`2021-08-16 · 5 🐛 · 7 👩‍💻👨‍💻`

### Engine versions
- Node: `12.22.1`
- NPM: `6.14.1`
- MongoDB: `3.4, 3.6, 4.0, 4.2`
- Apps-Engine: `1.27.1`

### 🐛 Bug fixes


- "Click to Join" button is not working if there are no muted users in the room ([#22871](https://github.com/RocketChat/Rocket.Chat/pull/22871))

- Add check to `room.muted` array so as to cover the case in which it is `undefined`;

- Apps-Engine's scheduler failing to update run tasks ([#22882](https://github.com/RocketChat/Rocket.Chat/pull/22882))

[Agenda](https://github.com/agenda/agenda), the library that manages scheduling, depended on setting a job property named `nextRunAt` as `undefined` to signal whether it should be run on schedule or not. [Rocket.Chat's current Mongo driver](https://github.com/RocketChat/Rocket.Chat/pull/22399) ignores `undefined` values when updating documents and this was causing jobs to never stop running as Agenda couldn't clear that property (set them as `undefined`).
This updates Rocket.Chat's dependency on Agenda.js to point to [a fork that fixes the problem](https://github.com/RocketChat/agenda/releases/tag/3.1.2).

- Close omnichannel conversations when agent is deactivated ([#22917](https://github.com/RocketChat/Rocket.Chat/pull/22917))

- Message update not working in some cases ([#22856](https://github.com/RocketChat/Rocket.Chat/pull/22856))

- Use correct param on saveBusinessHour method ([#22835](https://github.com/RocketChat/Rocket.Chat/pull/22835))

### 👩‍💻👨‍💻 Core Team 🤓

- [@KevLehman](https://github.com/KevLehman)
- [@d-gubert](https://github.com/d-gubert)
- [@matheusbsilva137](https://github.com/matheusbsilva137)
- [@murtaza98](https://github.com/murtaza98)
- [@renatobecker](https://github.com/renatobecker)
- [@tassoevan](https://github.com/tassoevan)
- [@thassiov](https://github.com/thassiov)

# 3.17.0
`2021-07-30 · 7 🎉 · 19 🚀 · 39 🐛 · 56 🔍 · 28 👩‍💻👨‍💻`

Expand Down Expand Up @@ -5051,7 +5088,7 @@
- [@sampaiodiego](https://github.com/sampaiodiego)

# 3.8.0
`2020-11-13 · 14 🎉 · 4 🚀 · 40 🐛 · 54 🔍 · 30 👩‍💻👨‍💻`
`2020-11-14 · 14 🎉 · 4 🚀 · 40 🐛 · 54 🔍 · 30 👩‍💻👨‍💻`

### Engine versions
- Node: `12.18.4`
Expand Down
2 changes: 1 addition & 1 deletion app/api/server/lib/users.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ export async function findUsersToAutocomplete({ uid, selector }) {
const exceptions = selector.exceptions || [];
const conditions = selector.conditions || {};
const options = {
fields: {
projection: {
name: 1,
username: 1,
nickname: 1,
Expand Down
8 changes: 4 additions & 4 deletions app/apps/server/bridges/scheduler.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,12 +17,12 @@ function _callProcessor(processor: Function): (job: { attrs?: { data: object } }
// This field is for internal use, no need to leak to app processor
delete (data as any).appId;

processor(data);
return processor(data);
};
}

/**
* Provides the Apps Engine with task scheduling capabilities
* Provides the Apps Engine with task scheduling capabilities.
* It uses {@link agenda:github.com/agenda/agenda} as backend
*/
export class AppSchedulerBridge extends SchedulerBridge {
Expand All @@ -43,7 +43,7 @@ export class AppSchedulerBridge extends SchedulerBridge {
}

/**
* Entity that will be run in a job
* Entity that will be run in a job.
* @typedef {Object} Processor
* @property {string} id The processor's identifier
* @property {function} processor The function that will be run on a given schedule
Expand Down Expand Up @@ -127,7 +127,7 @@ export class AppSchedulerBridge extends SchedulerBridge {
}

/**
* Schedules a registered processor to run recurrently according to a given interval
* Schedules a registered processor to run recurrently according to a given interval.
*
* @param {Object} job
* @param {string} job.id The processor's id
Expand Down
2 changes: 1 addition & 1 deletion app/authorization/server/functions/canSendMessage.js
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ export const validateRoomMessagePermissionsAsync = async (room, { uid, username,
}
}

if ((room.muted || []).includes(username)) {
if (room?.muted?.includes(username)) {
throw new Error('You_have_been_muted');
}
};
Expand Down
19 changes: 19 additions & 0 deletions app/lib/server/functions/closeOmnichannelConversations.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import { TAPi18n } from 'meteor/rocketchat:tap-i18n';

import { LivechatRooms } from '../../../models/server';
import { IUser } from '../../../../definition/IUser';
import { settings } from '../../../settings/server';
import { Livechat } from '../../../livechat/server/lib/Livechat';

type SubscribedRooms = {
rid: string;
t: string;
}

export const closeOmnichannelConversations = (user: IUser, subscribedRooms: SubscribedRooms[]): void => {
const roomsInfo = LivechatRooms.findByIds(subscribedRooms.map(({ rid }) => rid));
const language = settings.get('Language') || 'en';
roomsInfo.map((room: any) =>
Livechat.closeRoom({ user, visitor: {}, room, comment: TAPi18n.__('Agent_deactivated', { lng: language }) }),
);
};
11 changes: 8 additions & 3 deletions app/lib/server/functions/setUserActiveStatus.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import * as Mailer from '../../../mailer';
import { Users, Subscriptions, Rooms } from '../../../models';
import { settings } from '../../../settings';
import { relinquishRoomOwnerships } from './relinquishRoomOwnerships';
import { closeOmnichannelConversations } from './closeOmnichannelConversations';
import { shouldRemoveOrChangeOwner, getSubscribedRoomsForUserWithDetails } from './getRoomsWithSingleOwner';
import { getUserSingleOwnedRooms } from './getUserSingleOwnedRooms';

Expand Down Expand Up @@ -41,13 +42,17 @@ export function setUserActiveStatus(userId, active, confirmRelinquish = false) {
// Users without username can't do anything, so there is no need to check for owned rooms
if (user.username != null && !active) {
const subscribedRooms = getSubscribedRoomsForUserWithDetails(userId);
// give omnichannel rooms a special treatment :)
const chatSubscribedRooms = subscribedRooms.filter(({ t }) => t !== 'l');
const livechatSubscribedRooms = subscribedRooms.filter(({ t }) => t === 'l');

if (shouldRemoveOrChangeOwner(subscribedRooms) && !confirmRelinquish) {
const rooms = getUserSingleOwnedRooms(subscribedRooms);
if (shouldRemoveOrChangeOwner(chatSubscribedRooms) && !confirmRelinquish) {
const rooms = getUserSingleOwnedRooms(chatSubscribedRooms);
throw new Meteor.Error('user-last-owner', '', rooms);
}

relinquishRoomOwnerships(user._id, subscribedRooms, false);
closeOmnichannelConversations(user, livechatSubscribedRooms);
relinquishRoomOwnerships(user, chatSubscribedRooms, false);
}

Users.setUserActive(userId, active);
Expand Down
2 changes: 1 addition & 1 deletion app/lib/server/lib/processDirectEmail.js
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,7 @@ export const processDirectEmail = function(email) {
return false;
}

if ((room.muted || []).includes(user.username)) {
if (room?.muted?.includes(user.username)) {
// user is muted
return false;
}
Expand Down
6 changes: 5 additions & 1 deletion app/livechat/server/methods/saveBusinessHour.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,10 @@ import { businessHourManager } from '../business-hour';

Meteor.methods({
'livechat:saveBusinessHour'(businessHourData: ILivechatBusinessHour) {
businessHourManager.saveBusinessHour(businessHourData);
try {
Promise.await(businessHourManager.saveBusinessHour(businessHourData));
} catch (e) {
throw new Meteor.Error(e.message);
}
},
});
15 changes: 15 additions & 0 deletions app/models/server/models/LivechatRooms.js
Original file line number Diff line number Diff line change
Expand Up @@ -138,6 +138,21 @@ export class LivechatRooms extends Base {
return this.find(query, options);
}

findByIds(ids, fields) {
const options = {};

if (fields) {
options.fields = fields;
}

const query = {
t: 'l',
_id: { $in: ids },
};

return this.find(query, options);
}

findOneById(_id, fields = {}) {
const options = {};

Expand Down
2 changes: 1 addition & 1 deletion app/utils/rocketchat.info
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
{
"version": "3.17.0"
"version": "3.17.1"
}
2 changes: 1 addition & 1 deletion app/videobridge/client/actionLink.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ actionLinks.register('joinJitsiCall', function(message, params, instance) {
const currentTime = new Date().getTime();
const jitsiTimeout = new Date((room && room.jitsiTimeout) || currentTime).getTime();

if (room && room.muted.includes(username)) {
if (room && room?.muted?.includes(username)) {
toastr.error(TAPi18n.__('You_have_been_muted', ''));
} else if (jitsiTimeout > currentTime) {
instance.tabBar.open('video');
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
import get from 'lodash.get';

import { settings } from '../../../../../app/settings/server';
import { callbacks } from '../../../../../app/callbacks/server';
import { Users, LivechatVisitors } from '../../../../../app/models/server';
import { Users, LivechatVisitors, Rooms } from '../../../../../app/models/server';
import { IMessage } from '../../../../../definition/IMessage';
import { IOmnichannelRoom, isOmnichannelRoom } from '../../../../../definition/IRoom';

Expand All @@ -28,7 +29,12 @@ const placeholderFields = {
},
};

callbacks.add('beforeSaveMessage', (message: IMessage, room: IOmnichannelRoom): any => {
const handleBeforeSaveMessage = (message: IMessage, room: IOmnichannelRoom): any => {
if (!message.msg || message.msg === '') {
return message;
}

room = room?._id ? room : Rooms.findOneById(message.rid);
if (!isOmnichannelRoom(room)) {
return message;
}
Expand All @@ -51,4 +57,13 @@ callbacks.add('beforeSaveMessage', (message: IMessage, room: IOmnichannelRoom):

message.msg = messageText;
return message;
}, callbacks.priority.LOW, 'canned-responses-replace-placeholders');
};

settings.get('Canned_Responses_Enable', function(_, value) {
if (!value) {
callbacks.remove('beforeSaveMessage', 'canned-responses-replace-placeholders');
return;
}

callbacks.add('beforeSaveMessage', handleBeforeSaveMessage, callbacks.priority.MEDIUM, 'canned-responses-replace-placeholders');
});
8 changes: 6 additions & 2 deletions ee/app/livechat-enterprise/server/business-hour/Custom.ts
Original file line number Diff line number Diff line change
Expand Up @@ -35,15 +35,19 @@ class CustomBusinessHour extends AbstractBusinessHourType implements IBusinessHo
}

async saveBusinessHour(businessHour: ILivechatBusinessHour & IBusinessHoursExtraProperties): Promise<ILivechatBusinessHour> {
const existingBusinessHour = await this.BusinessHourRepository.findOne({ name: businessHour.name }, { projection: { _id: 1 } }) as ILivechatBusinessHour;
if (existingBusinessHour && existingBusinessHour._id !== businessHour._id) {
throw new Error('error-business-hour-name-already-in-use');
}
const { timezoneName, departmentsToApplyBusinessHour, ...businessHourData } = businessHour;
businessHourData.timezone = {
name: timezoneName,
utc: this.getUTCFromTimezone(timezoneName),
};
const departments = departmentsToApplyBusinessHour?.split(',').filter(Boolean) || [];
const businessHourToReturn = { ...businessHourData };
const businessHourToReturn = { ...businessHourData, departmentsToApplyBusinessHour };
delete businessHourData.departments;
const businessHourId = await this.baseSaveBusinessHour(businessHour);
const businessHourId = await this.baseSaveBusinessHour(businessHourData);
const currentDepartments = (await this.DepartmentsRepository.findByBusinessHourId(businessHourId, { fields: { _id: 1 } }).toArray()).map((dept: any) => dept._id);
const toRemove = [...currentDepartments.filter((dept: string) => !departments.includes(dept))];
const toAdd = [...departments.filter((dept: string) => !currentDepartments.includes(dept))];
Expand Down
6 changes: 3 additions & 3 deletions ee/app/livechat-enterprise/server/business-hour/Helper.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,16 +13,16 @@ const getAllAgentIdsWithoutDepartment = async (): Promise<string[]> => {
const agentIdsWithDepartment = (await LivechatDepartmentAgents.find({}, { fields: { agentId: 1 } }).toArray()).map((dept: any) => dept.agentId);
const agentIdsWithoutDepartment = (await Users.findUsersInRolesWithQuery('livechat-agent', {
_id: { $nin: agentIdsWithDepartment },
}, { fields: { _id: 1 } }).toArray()).map((user: any) => user._id);
}, { projection: { _id: 1 } }).toArray()).map((user: any) => user._id);
return agentIdsWithoutDepartment;
};

const getAgentIdsToHandle = async (businessHour: Record<string, any>): Promise<string[]> => {
if (businessHour.type === LivechatBusinessHourTypes.DEFAULT) {
return getAllAgentIdsWithoutDepartment();
}
const departmentIds = (await LivechatDepartment.findEnabledByBusinessHourId(businessHour._id, { fields: { _id: 1 } }).toArray()).map((dept: any) => dept._id);
return (await LivechatDepartmentAgents.findByDepartmentIds(departmentIds, { fields: { agentId: 1 } }).toArray()).map((dept: any) => dept.agentId);
const departmentIds = (await LivechatDepartment.findEnabledByBusinessHourId(businessHour._id, { projection: { _id: 1 } }).toArray()).map((dept: any) => dept._id);
return (await LivechatDepartmentAgents.findByDepartmentIds(departmentIds, { projection: { agentId: 1 } }).toArray()).map((dept: any) => dept.agentId);
};

export const openBusinessHour = async (businessHour: Record<string, any>): Promise<void> => {
Expand Down
Loading

0 comments on commit ac4252d

Please sign in to comment.