Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 5 additions & 1 deletion apps/meteor/server/services/video-conference/service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1115,7 +1115,11 @@ export class VideoConfService extends ServiceClassInternal implements IVideoConf
}

private isPersistentChatEnabled(): boolean {
return settings.get<boolean>('VideoConf_Enable_Persistent_Chat') && settings.get<boolean>('Discussion_enabled');
// Persistent chat discussions are always created unencrypted, so persistent chat is treated as disabled
// while the workspace enforces encryption on private rooms.
const encryptionEnforced = settings.get<boolean>('E2E_Enable') && settings.get<boolean>('E2E_Force_Encryption_For_Private_Rooms');

return settings.get<boolean>('VideoConf_Enable_Persistent_Chat') && settings.get<boolean>('Discussion_enabled') && !encryptionEnforced;
Comment thread
milton-rucks marked this conversation as resolved.
}

private async maybeCreateDiscussion(callId: VideoConference['_id'], createdBy?: IUser): Promise<void> {
Expand Down
1 change: 1 addition & 0 deletions apps/meteor/server/settings/e2e.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ export const createE2ESettings = () =>
type: 'boolean',
i18nLabel: 'Force_Encryption_For_Private_Rooms',
i18nDescription: 'Force_Encryption_For_Private_Rooms_Description',
alert: 'Force_Encryption_For_Private_Rooms_Alert',
public: true,
enableQuery: { _id: 'E2E_Enable', value: true },
});
Expand Down
113 changes: 113 additions & 0 deletions apps/meteor/tests/end-to-end/apps/video-conferences.ts
Original file line number Diff line number Diff line change
Expand Up @@ -602,6 +602,119 @@ describe('Apps - Video Conferences', () => {
});
});

describe('[Persistent Chat provider with the persistent chat feature enabled and encryption forced on private rooms]', () => {
let callId: string | undefined;

before(async () => {
if (!process.env.IS_EE) {
return;
}

await updateSetting('VideoConf_Default_Provider', 'persistentchat');
await updateSetting('Discussion_enabled', true);
await updateSetting('VideoConf_Enable_Persistent_Chat', true);
await Promise.all([updateSetting('E2E_Enable', true), updateSetting('E2E_Force_Encryption_For_Private_Rooms', true)]);

const res = await request.post(api('video-conference.start')).set(credentials).send({
roomId,
});

callId = res.body.data?.callId;
});

after(async () => {
if (!process.env.IS_EE) {
return;
}

await Promise.all([updateSetting('E2E_Enable', false), updateSetting('E2E_Force_Encryption_For_Private_Rooms', false)]);
Comment thread
milton-rucks marked this conversation as resolved.
});

it('should start the call and treat persistent chat as disabled', async function () {
if (!process.env.IS_EE) {
this.skip();
}

expect(callId).to.be.a('string');

await request
.get(api('video-conference.info'))
.set(credentials)
.query({
callId,
})
.expect(200)
.expect((res: Response) => {
expect(res.body.success).to.be.equal(true);
expect(res.body).to.have.a.property('_id').equal(callId);
expect(res.body).to.have.a.property('rid').equal(roomId);
// the call must be fully started, since persistent chat is skipped instead of attempted
expect(res.body).to.have.a.property('url').that.is.a('string');
expect(res.body).to.have.a.property('status').equal(1);
expect(res.body).to.have.a.property('messages').that.is.an('object');
expect(res.body.messages).to.have.a.property('started').that.is.a('string');
// even with VideoConf_Enable_Persistent_Chat on, enforcing encryption disables persistent chat
expect(res.body).to.not.have.a.property('discussionRid');
});
});
});

describe('[Persistent Chat provider with the persistent chat feature enabled and encryption forced but E2EE off]', () => {
let callId: string | undefined;
let discussionRid: string | undefined;

before(async () => {
if (!process.env.IS_EE) {
return;
}

await updateSetting('VideoConf_Default_Provider', 'persistentchat');
await updateSetting('Discussion_enabled', true);
await updateSetting('VideoConf_Enable_Persistent_Chat', true);
// the encryption policy only takes effect while E2EE is enabled, so persistent chat must keep working
await Promise.all([updateSetting('E2E_Enable', false), updateSetting('E2E_Force_Encryption_For_Private_Rooms', true)]);

const res = await request.post(api('video-conference.start')).set(credentials).send({
roomId,
});

callId = res.body.data?.callId;
});

after(async () => {
if (!process.env.IS_EE) {
return;
}

await Promise.all([
updateSetting('E2E_Force_Encryption_For_Private_Rooms', false),
...(discussionRid ? [deleteRoom({ type: 'p', roomId: discussionRid })] : []),
]);
});

it('should still create the persistent chat discussion', async function () {
if (!process.env.IS_EE) {
this.skip();
}

expect(callId).to.be.a('string');

await request
.get(api('video-conference.info'))
.set(credentials)
.query({
callId,
})
.expect(200)
.expect((res: Response) => {
discussionRid = res.body.discussionRid;
expect(res.body.success).to.be.equal(true);
expect(res.body).to.have.a.property('_id').equal(callId);
expect(res.body).to.have.a.property('discussionRid').that.is.a('string');
});
});
});

describe('[Persistent Chat provider with the persistent chat feature enabled and custom discussion names]', () => {
let callId: string | undefined;
let discussionRid: string | undefined;
Expand Down
3 changes: 2 additions & 1 deletion packages/i18n/src/locales/en.i18n.json
Original file line number Diff line number Diff line change
Expand Up @@ -2559,6 +2559,7 @@
"Force_Disable_OpLog_For_Cache": "Force Disable OpLog for Cache",
"Force_Disable_OpLog_For_Cache_Description": "Will not use OpLog to sync cache even when it's available",
"Force_Encryption_For_Private_Rooms": "Force end-to-end encryption on private rooms",
"Force_Encryption_For_Private_Rooms_Alert": "<b>Not compatible with video conference persistent chat</b><br/>Persistent chat discussions are unencrypted, so while this setting is enabled persistent chat is treated as disabled and video calls will not create a chat history discussion.",
"Force_Encryption_For_Private_Rooms_Description": "When enabled, all newly created private rooms will be encrypted by default, and users will not be able to disable encryption for them.",
"Force_SSL": "Force SSL",
"Force_SSL_Description": "*Caution!* _Force SSL_ should never be used with reverse proxy. If you have a reverse proxy, you should do the redirect THERE. This option exists for deployments like Heroku, that does not allow the redirect configuration at the reverse proxy.",
Expand Down Expand Up @@ -6018,7 +6019,7 @@
"VideoConf_Enable_DMs": "Enable in direct messages",
"VideoConf_Enable_Groups": "Enable in private channels",
"VideoConf_Enable_Persistent_Chat": "Enable Persistent Chat",
"VideoConf_Enable_Persistent_Chat_Alert": "Persistent Chat will not work if discussions are disabled on the workspace. It will also not work if the provider app being used do not explicitly support this feature.",
"VideoConf_Enable_Persistent_Chat_Alert": "Persistent Chat will not work if discussions are disabled on the workspace, or if E2E encryption is mandatory. It will also not work if the provider app being used do not explicitly support this feature.",
"VideoConf_Enable_Persistent_Chat_description": "When persistent chat is enabled, Rocket.Chat will create a discussion every time a conference call is initiated. The provider app is responsible for sending the chat messages to this discussion.",
"VideoConf_Enable_Teams": "Enable in teams",
"VideoConf_Mobile_Ringing": "Enable mobile ringing",
Expand Down
Loading