-
Notifications
You must be signed in to change notification settings - Fork 10k
/
e2e.ts
140 lines (115 loc) · 3.84 KB
/
e2e.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
import type { AtLeast, IMessage, IRoom, ISubscription } from '@rocket.chat/core-typings';
import { FlowRouter } from 'meteor/kadira:flow-router';
import { Meteor } from 'meteor/meteor';
import { Tracker } from 'meteor/tracker';
import { e2e } from '../../app/e2e/client/rocketchat.e2e';
import { Subscriptions, Rooms } from '../../app/models/client';
import { Notifications } from '../../app/notifications/client';
import { settings } from '../../app/settings/client';
import { onClientBeforeSendMessage } from '../lib/onClientBeforeSendMessage';
import { onClientMessageReceived } from '../lib/onClientMessageReceived';
import { isLayoutEmbedded } from '../lib/utils/isLayoutEmbedded';
import { waitUntilFind } from '../lib/utils/waitUntilFind';
const handle = async (roomId: IRoom['_id'], keyId: string): Promise<void> => {
const e2eRoom = await e2e.getInstanceByRoomId(roomId);
if (!e2eRoom) {
return;
}
e2eRoom.provideKeyToUser(keyId);
};
Meteor.startup(() => {
Tracker.autorun(() => {
if (!Meteor.userId()) {
return;
}
const adminEmbedded = isLayoutEmbedded() && FlowRouter.current().path.startsWith('/admin');
if (!adminEmbedded && settings.get('E2E_Enable') && window.crypto) {
e2e.startClient();
e2e.enabled.set(true);
} else {
e2e.enabled.set(false);
e2e.closeAlert();
}
});
let observable: Meteor.LiveQueryHandle | null = null;
let offClientMessageReceived: undefined | (() => void);
let offClientBeforeSendMessage: undefined | (() => void);
Tracker.autorun(() => {
if (!e2e.isReady()) {
offClientMessageReceived?.();
Notifications.unUser('e2ekeyRequest', handle);
observable?.stop();
offClientBeforeSendMessage?.();
return;
}
Notifications.onUser('e2ekeyRequest', handle);
observable = Subscriptions.find().observe({
changed: async (sub: ISubscription) => {
if (!sub.encrypted && !sub.E2EKey) {
e2e.removeInstanceByRoomId(sub.rid);
return;
}
const e2eRoom = await e2e.getInstanceByRoomId(sub.rid);
if (!e2eRoom) {
return;
}
if (sub.E2ESuggestedKey) {
if (await e2eRoom.importGroupKey(sub.E2ESuggestedKey)) {
e2e.acceptSuggestedKey(sub.rid);
} else {
console.log('Invalid E2ESuggestedKey', sub.E2ESuggestedKey);
}
}
sub.encrypted ? e2eRoom.resume() : e2eRoom.pause();
// Cover private groups and direct messages
if (!e2eRoom.isSupportedRoomType(sub.t)) {
e2eRoom.disable();
return;
}
if (sub.E2EKey && e2eRoom.isWaitingKeys()) {
e2eRoom.keyReceived();
return;
}
if (!e2eRoom.isReady()) {
return;
}
e2eRoom.decryptSubscription();
},
added: async (sub: ISubscription) => {
if (!sub.encrypted && !sub.E2EKey) {
return;
}
return e2e.getInstanceByRoomId(sub.rid);
},
removed: (sub: ISubscription) => {
e2e.removeInstanceByRoomId(sub.rid);
},
});
offClientMessageReceived = onClientMessageReceived.use(async (msg: IMessage) => {
const e2eRoom = await e2e.getInstanceByRoomId(msg.rid);
if (!e2eRoom || !e2eRoom.shouldConvertReceivedMessages()) {
return msg;
}
return e2e.decryptMessage(msg);
});
// Encrypt messages before sending
offClientBeforeSendMessage = onClientBeforeSendMessage.use(async (message: AtLeast<IMessage, '_id' | 'rid' | 'msg'>) => {
const e2eRoom = await e2e.getInstanceByRoomId(message.rid);
if (!e2eRoom) {
return message;
}
const subscription = await waitUntilFind(() => Rooms.findOne({ _id: message.rid }));
subscription.encrypted ? e2eRoom.resume() : e2eRoom.pause();
const shouldConvertSentMessages = await e2eRoom.shouldConvertSentMessages(message);
if (!shouldConvertSentMessages) {
return message;
}
// Should encrypt this message.
const msg = await e2eRoom.encrypt(message);
message.msg = msg;
message.t = 'e2e';
message.e2e = 'pending';
return message;
});
});
});