Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[IMPROVE] OTR Message #24297

Merged
merged 62 commits into from
Sep 6, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
62 commits
Select commit Hold shift + click to select a range
59aa4af
WIP
yash-rajpal Jan 25, 2022
608b5cc
remove unneccessary changes
yash-rajpal Jan 25, 2022
6069afb
Validate OTR Message before sending
albuquerquefabio Jan 25, 2022
e3dbf69
some old methods have been deleted
albuquerquefabio Jan 25, 2022
4102b3d
handle error if room name does not exist
albuquerquefabio Jan 25, 2022
f938010
remove console.log and scratch code
albuquerquefabio Jan 25, 2022
226242b
Merge branch 'improve/otr-message' of https://github.com/RocketChat/R…
albuquerquefabio Jan 25, 2022
4978086
Remove unused vars and empty row
albuquerquefabio Jan 25, 2022
157835e
Merge branch 'develop' into improve/otr-message
albuquerquefabio Jan 26, 2022
6d439e8
Merge branch 'develop' into improve/otr-message
albuquerquefabio Jan 27, 2022
6aed46e
POC: Send OTR message over the stream
albuquerquefabio Jan 31, 2022
ee421b6
Merge branch 'develop' into improve/otr-message
albuquerquefabio Feb 2, 2022
028a9a2
Remove unnecessary code
albuquerquefabio Feb 2, 2022
8e84ff0
declaring variable after validation.
albuquerquefabio Feb 2, 2022
5b3b066
Fix: OTR message sent by both like same user
albuquerquefabio Feb 2, 2022
220a653
Improve: OTR Message Received
albuquerquefabio Feb 10, 2022
12e599e
Improve: OTR Before Send Message
albuquerquefabio Feb 10, 2022
cc776e6
Remove console.error and return Error
albuquerquefabio Feb 10, 2022
c30e5d6
Remove unnecessary if statement
albuquerquefabio Feb 10, 2022
6bd6650
Merge branch 'develop' into improve/otr-message
yash-rajpal Feb 15, 2022
87c2355
Moving otr startups to client/startup
yash-rajpal Feb 16, 2022
d5948f3
fix conflicts
yash-rajpal Mar 2, 2022
33d426e
otr message types
yash-rajpal Mar 2, 2022
0c82f41
Prevent OTR connection if OTR is not enable
albuquerquefabio Mar 3, 2022
282fb8e
Merge branch 'develop' into improve/otr-message
albuquerquefabio Mar 28, 2022
e46bd71
Fix: OTR user stream logic
albuquerquefabio Mar 28, 2022
a0c08fe
Fix: streamUser return
albuquerquefabio Mar 28, 2022
662116c
Merge branch 'develop' into improve/otr-message
albuquerquefabio May 2, 2022
bef006d
Merge branch 'develop' into improve/otr-message
albuquerquefabio May 12, 2022
880bd36
Merge branch 'develop' into improve/otr-message
albuquerquefabio May 12, 2022
240688b
Interface IOTRMessage
albuquerquefabio May 12, 2022
11a6449
fix conflicts and merge
yash-rajpal Jun 16, 2022
0535d60
fix conflicts and merge
yash-rajpal Jun 29, 2022
345f5ee
fix timeout scope
yash-rajpal Jun 30, 2022
66868c9
Merge branch 'develop' into improve/otr-message
albuquerquefabio Aug 16, 2022
21b2de0
Remove IOTRMessage
albuquerquefabio Aug 16, 2022
e4a43b7
Check OTR instance by room id
albuquerquefabio Aug 16, 2022
893bf06
Get state with method
albuquerquefabio Aug 16, 2022
40e183e
lint issue
albuquerquefabio Aug 16, 2022
282a05a
Merge branch 'develop' into improve/otr-message
albuquerquefabio Aug 16, 2022
fd81adc
Update otr.ts
albuquerquefabio Aug 16, 2022
715e4b4
Import order
albuquerquefabio Aug 16, 2022
47abe04
Check values
albuquerquefabio Aug 17, 2022
3bc8581
Update OTRRoom.ts
albuquerquefabio Aug 17, 2022
07dab3e
Update otr.ts
albuquerquefabio Aug 17, 2022
c5c5ffd
restore declaration name
albuquerquefabio Aug 17, 2022
46ea822
Merge branch 'develop' into improve/otr-message
albuquerquefabio Aug 17, 2022
00de162
whitespace difference
albuquerquefabio Aug 17, 2022
81a20ea
Merge branch 'develop' into improve/otr-message
albuquerquefabio Aug 19, 2022
423c8c6
Merge branch 'develop' into improve/otr-message
albuquerquefabio Aug 19, 2022
c14f855
Fix refresh keys timeout
albuquerquefabio Aug 22, 2022
97da54c
Merge branch 'develop' into improve/otr-message
yash-rajpal Aug 22, 2022
5c923af
Merge branch 'develop' of github.com:RocketChat/Rocket.Chat into impr…
gabriellsh Aug 24, 2022
05d87d3
Merge branch 'develop' into improve/otr-message
yash-rajpal Aug 25, 2022
71ce159
Merge branch 'develop' into improve/otr-message
yash-rajpal Aug 30, 2022
6985f41
fix lint
yash-rajpal Aug 30, 2022
b4f618f
Merge branch 'develop' into improve/otr-message
yash-rajpal Aug 31, 2022
184e745
Merge branch 'develop' into improve/otr-message
gabriellsh Sep 1, 2022
ff7d20f
Merge branch 'develop' into improve/otr-message
yash-rajpal Sep 1, 2022
de72e2f
Merge branch 'develop' into improve/otr-message
gabriellsh Sep 6, 2022
1e54954
Merge branch 'develop' into improve/otr-message
kodiakhq[bot] Sep 6, 2022
55addb8
Merge branch 'develop' into improve/otr-message
kodiakhq[bot] Sep 6, 2022
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/app/lib/server/functions/sendMessage.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import { hasPermission } from '../../../authorization/server';
import { SystemLogger } from '../../../../server/lib/logger/system';
import { parseUrlsInMessage } from './parseUrlsInMessage';
import { isRelativeURL } from '../../../../lib/utils/isRelativeURL';
import notifications from '../../../notifications/server/lib/Notifications';

/**
* IMPORTANT
Expand Down Expand Up @@ -244,7 +245,10 @@ export const sendMessage = function (user, message, room, upsert = false) {

message = callbacks.run('beforeSaveMessage', message, room);
if (message) {
if (message._id && upsert) {
if (message.t === 'otr') {
const otrStreamer = notifications.streamRoomMessage;
otrStreamer.emit(message.rid, message, user, room);
} else if (message._id && upsert) {
const { _id } = message;
delete message._id;
Messages.upsert(
Expand Down
24 changes: 12 additions & 12 deletions apps/meteor/app/otr/client/OTRRoom.ts
Original file line number Diff line number Diff line change
Expand Up @@ -66,8 +66,7 @@ export class OTRRoom implements IOTRRoom {
}

setState(nextState: OtrRoomState): void {
const currentState = this.state.get();
if (currentState === nextState) {
if (this.getState() === nextState) {
return;
}

Expand Down Expand Up @@ -141,7 +140,7 @@ export class OTRRoom implements IOTRRoom {
this._userOnlineComputation = Tracker.autorun(() => {
const $room = $(`#chat-window-${this._roomId}`);
const $title = $('.rc-header__title', $room);
if (this.state.get() === OtrRoomState.ESTABLISHED) {
if (this.getState() === OtrRoomState.ESTABLISHED) {
if ($room.length && $title.length && !$('.otr-icon', $title).length) {
$title.prepend("<i class='otr-icon icon-key'></i>");
}
Expand Down Expand Up @@ -252,8 +251,8 @@ export class OTRRoom implements IOTRRoom {
const establishConnection = async (): Promise<void> => {
this.setState(OtrRoomState.ESTABLISHING);
Meteor.clearTimeout(timeout);

try {
if (!data.publicKey) throw new Error('Public key is not generated');
await this.generateKeyPair();
await this.importPublicKey(data.publicKey);
await goToRoomById(data.roomId);
Expand Down Expand Up @@ -283,11 +282,11 @@ export class OTRRoom implements IOTRRoom {
throw new Meteor.Error('user-not-defined', 'User not defined.');
}

if (data.refresh && this.state.get() === OtrRoomState.ESTABLISHED) {
if (data.refresh && this.getState() === OtrRoomState.ESTABLISHED) {
this.reset();
await establishConnection();
} else {
if (this.state.get() === OtrRoomState.ESTABLISHED) {
if (this.getState() === OtrRoomState.ESTABLISHED) {
this.reset();
}
imperativeModal.open({
Expand All @@ -308,18 +307,19 @@ export class OTRRoom implements IOTRRoom {
},
},
});
timeout = Meteor.setTimeout(() => {
this.setState(OtrRoomState.TIMEOUT);
imperativeModal.close();
}, 10000);
}
timeout = Meteor.setTimeout(() => {
this.setState(OtrRoomState.TIMEOUT);
imperativeModal.close();
}, 10000);
} catch (e) {
dispatchToastMessage({ type: 'error', message: e });
}
break;

case 'acknowledge':
try {
if (!data.publicKey) throw new Error('Public key is not generated');
await this.importPublicKey(data.publicKey);

this.setState(OtrRoomState.ESTABLISHED);
Expand All @@ -334,7 +334,7 @@ export class OTRRoom implements IOTRRoom {
break;

case 'deny':
if (this.state.get() === OtrRoomState.ESTABLISHING) {
if (this.getState() === OtrRoomState.ESTABLISHING) {
this.reset();
this.setState(OtrRoomState.DECLINED);
}
Expand All @@ -347,7 +347,7 @@ export class OTRRoom implements IOTRRoom {
throw new Meteor.Error('user-not-defined', 'User not defined.');
}

if (this.state.get() === OtrRoomState.ESTABLISHED) {
if (this.getState() === OtrRoomState.ESTABLISHED) {
this.reset();
this.setState(OtrRoomState.NOT_STARTED);
imperativeModal.open({
Expand Down
2 changes: 1 addition & 1 deletion apps/meteor/app/otr/lib/IOTR.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@ import type { OTRRoom } from '../client/OTRRoom';

export interface IOnUserStreamData {
roomId: IRoom['_id'];
publicKey: string;
userId: IUser['_id'];
publicKey?: string;
refresh?: boolean;
}

Expand Down
2 changes: 1 addition & 1 deletion apps/meteor/app/otr/server/index.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import './settings';
import './methods/deleteOldOTRMessages';
import './methods/updateOTRAck';
import './methods/sendSystemMessages';
import './methods/deleteOldOTRMessages';
8 changes: 4 additions & 4 deletions apps/meteor/app/otr/server/methods/updateOTRAck.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
import type { IMessage } from '@rocket.chat/core-typings';
import { Meteor } from 'meteor/meteor';

import { Messages } from '../../../models/server';
import notifications from '../../../notifications/server/lib/Notifications';

Meteor.methods({
updateOTRAck(_id: IMessage['_id'], ack: IMessage['otrAck']): void {
updateOTRAck({ message, ack }) {
if (!Meteor.userId()) {
throw new Meteor.Error('error-invalid-user', 'Invalid user', { method: 'updateOTRAck' });
}
Messages.updateOTRAck(_id, ack);
const otrStreamer = notifications.streamRoomMessage;
otrStreamer.emit(message.rid, { ...message, otr: { ack } });
},
});
2 changes: 1 addition & 1 deletion apps/meteor/app/ui-utils/client/lib/RoomManager.ts
Original file line number Diff line number Diff line change
Expand Up @@ -193,7 +193,7 @@ const computation = Tracker.autorun(() => {
}
}

msg.name = room.name;
msg.name = room.name || '';

handleTrackSettingsChange(msg);

Expand Down
34 changes: 21 additions & 13 deletions apps/meteor/client/startup/otr.ts
Original file line number Diff line number Diff line change
@@ -1,23 +1,32 @@
import { AtLeast, IMessage } from '@rocket.chat/core-typings';
import { IMessage, IRoom, IUser, AtLeast } from '@rocket.chat/core-typings';
import { Meteor } from 'meteor/meteor';
import { Tracker } from 'meteor/tracker';

import { Notifications } from '../../app/notifications/client';
import OTR from '../../app/otr/client/OTR';
import { IOnUserStreamData, IOTRDecrypt } from '../../app/otr/lib/IOTR';
import { OtrRoomState } from '../../app/otr/lib/OtrRoomState';
import { t } from '../../app/utils/client';
import { onClientBeforeSendMessage } from '../lib/onClientBeforeSendMessage';
import { onClientMessageReceived } from '../lib/onClientMessageReceived';

type NotifyUserData = {
roomId: IRoom['_id'];
userId: IUser['_id'];
};

Meteor.startup(() => {
Tracker.autorun(() => {
if (Meteor.userId()) {
Notifications.onUser('otr', (type: string, data: IOnUserStreamData) => {
Notifications.onUser('otr', (type: string, data: NotifyUserData) => {
if (!data.roomId || !data.userId || data.userId === Meteor.userId()) {
return;
}
const instanceByRoomId = OTR.getInstanceByRoomId(data.roomId);
if (!data.roomId || !data.userId || data.userId === Meteor.userId() || !instanceByRoomId) {

if (!instanceByRoomId) {
return;
}

instanceByRoomId.onUserStream(type, data);
});
}
Expand All @@ -37,33 +46,32 @@ Meteor.startup(() => {
const instanceByRoomId = OTR.getInstanceByRoomId(message.rid);

if (message.rid && instanceByRoomId && instanceByRoomId.getState() === OtrRoomState.ESTABLISHED) {
if (message.notification) {
if (message?.notification) {
message.msg = t('Encrypted_message');
return message;
}
if (message?.t !== 'otr') {
if (message.t !== 'otr') {
return message;
}
const otrRoom = instanceByRoomId;
const decrypted = await otrRoom.decrypt(message.msg);

const decrypted = await instanceByRoomId.decrypt(message.msg);
if (typeof decrypted === 'string') {
return { ...message, msg: decrypted };
}
const { _id, text: msg, ack, ts, userId }: IOTRDecrypt = decrypted;
const { _id, text: msg, ack, ts, userId } = decrypted;

if (ts) message.ts = ts;

if (message.otrAck) {
const otrAck = await otrRoom.decrypt(message.otrAck);
const otrAck = await instanceByRoomId.decrypt(message.otrAck);
if (typeof otrAck === 'string') {
return { ...message, msg: otrAck };
}

if (ack === otrAck.text) message.t = 'otr-ack';
} else if (userId !== Meteor.userId()) {
const encryptedAck = await otrRoom.encryptText(ack);
const encryptedAck = await instanceByRoomId.encryptText(ack);

Meteor.call('updateOTRAck', _id, encryptedAck);
Meteor.call('updateOTRAck', { message, ack: encryptedAck });
}

return { ...message, _id, msg };
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -282,6 +282,10 @@ export class NotificationsModule {

this.streamUser.allowWrite(async function (eventName: string, data: unknown) {
const [, e] = eventName.split('/');
if (e === 'otr' && (data === 'handshake' || data === 'acknowledge')) {
const isEnable = await Settings.getValueById('OTR_Enable');
return Boolean(this.userId) && (isEnable === 'true' || isEnable === true);
}
if (e === 'webrtc') {
return true;
}
Expand All @@ -308,11 +312,15 @@ export class NotificationsModule {
this.streamUser.allowRead(async function (eventName) {
const [userId, e] = eventName.split('/');

if (e === 'otr') {
const isEnable = await Settings.getValueById('OTR_Enable');
return Boolean(this.userId) && this.userId === userId && (isEnable === 'true' || isEnable === true);
}
if (e === 'webrtc') {
return true;
}

return this.userId != null && this.userId === userId;
return Boolean(this.userId) && this.userId === userId;
});

this.streamImporters.allowRead('all');
Expand Down
3 changes: 1 addition & 2 deletions packages/core-typings/src/IMessage/IMessage.ts
Original file line number Diff line number Diff line change
Expand Up @@ -57,12 +57,11 @@ type OmnichannelTypesValues =
| 'omnichannel_on_hold_chat_resumed';

type OtrMessageTypeValues = 'otr' | 'otr-ack';

type OtrSystemMessages = 'user_joined_otr' | 'user_requested_otr_key_refresh' | 'user_key_refreshed_successfully';

export type MessageTypesValues =
| 'e2e'
| 'otr'
| 'otr-ack'
| 'uj'
| 'ul'
| 'ru'
Expand Down