@wireapp/core 40.5.2-1 → 40.5.3-beta.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +674 -0
- package/lib/Account.d.ts +9 -7
- package/lib/Account.d.ts.map +1 -1
- package/lib/Account.js +32 -35
- package/lib/CoreError.js +1 -1
- package/lib/broadcast/BroadcastService.d.ts +2 -11
- package/lib/broadcast/BroadcastService.d.ts.map +1 -1
- package/lib/broadcast/BroadcastService.js +5 -39
- package/lib/client/ClientDatabaseRepository.d.ts +5 -5
- package/lib/client/ClientDatabaseRepository.d.ts.map +1 -1
- package/lib/client/ClientDatabaseRepository.js +10 -17
- package/lib/client/ClientService.d.ts +5 -1
- package/lib/client/ClientService.d.ts.map +1 -1
- package/lib/client/ClientService.js +11 -9
- package/lib/connection/ConnectionService.d.ts +2 -2
- package/lib/connection/ConnectionService.d.ts.map +1 -1
- package/lib/connection/ConnectionService.js +2 -2
- package/lib/conversation/AssetTransferState.js +1 -1
- package/lib/conversation/ConversationService/ConversationService.d.ts +12 -5
- package/lib/conversation/ConversationService/ConversationService.d.ts.map +1 -1
- package/lib/conversation/ConversationService/ConversationService.js +26 -11
- package/lib/conversation/ConversationService/ConversationService.test.js +1 -1
- package/lib/conversation/ConversationService/ConversationService.types.d.ts +12 -11
- package/lib/conversation/ConversationService/ConversationService.types.d.ts.map +1 -1
- package/lib/conversation/ConversationService/ConversationService.types.js +1 -1
- package/lib/conversation/ConversationService/Utility/getConversationQualifiedMembers.d.ts +1 -1
- package/lib/conversation/ConversationService/Utility/getConversationQualifiedMembers.d.ts.map +1 -1
- package/lib/conversation/GenericMessageType.js +1 -1
- package/lib/conversation/ReactionType.d.ts +1 -4
- package/lib/conversation/ReactionType.d.ts.map +1 -1
- package/lib/conversation/ReactionType.js +0 -6
- package/lib/conversation/message/Message.types.js +1 -1
- package/lib/conversation/message/MessageBuilder.d.ts +1 -1
- package/lib/conversation/message/MessageBuilder.d.ts.map +1 -1
- package/lib/conversation/message/MessageBuilder.js +2 -2
- package/lib/conversation/message/MessageService.d.ts +6 -31
- package/lib/conversation/message/MessageService.d.ts.map +1 -1
- package/lib/conversation/message/MessageService.js +19 -162
- package/lib/conversation/message/MessageService.test.js +151 -141
- package/lib/conversation/message/PayloadBundle.js +1 -1
- package/lib/conversation/message/UserClientsUtil.d.ts +14 -10
- package/lib/conversation/message/UserClientsUtil.d.ts.map +1 -1
- package/lib/conversation/message/UserClientsUtil.js +21 -11
- package/lib/conversation/message/UserClientsUtils.test.js +5 -9
- package/lib/messagingProtocols/mls/EventHandler/EventHandler.d.ts +1 -1
- package/lib/messagingProtocols/mls/EventHandler/EventHandler.d.ts.map +1 -1
- package/lib/messagingProtocols/mls/EventHandler/events/messageAdd/messageAdd.d.ts +1 -1
- package/lib/messagingProtocols/mls/EventHandler/events/messageAdd/messageAdd.d.ts.map +1 -1
- package/lib/messagingProtocols/mls/EventHandler/events/messageAdd/messageAdd.js +7 -2
- package/lib/messagingProtocols/mls/EventHandler/events/welcomeMessage/welcomeMessage.d.ts.map +1 -1
- package/lib/messagingProtocols/mls/EventHandler/events/welcomeMessage/welcomeMessage.js +2 -0
- package/lib/messagingProtocols/mls/EventHandler/events/welcomeMessage/welcomeMessage.test.js +3 -1
- package/lib/messagingProtocols/mls/MLSService/MLSService.d.ts +20 -8
- package/lib/messagingProtocols/mls/MLSService/MLSService.d.ts.map +1 -1
- package/lib/messagingProtocols/mls/MLSService/MLSService.js +81 -40
- package/lib/messagingProtocols/mls/MLSService/MLSService.test.js +9 -0
- package/lib/messagingProtocols/mls/MLSService/commitBundleUtil.d.ts +1 -1
- package/lib/messagingProtocols/mls/MLSService/commitBundleUtil.d.ts.map +1 -1
- package/lib/messagingProtocols/mls/MLSService/commitBundleUtil.js +5 -5
- package/lib/messagingProtocols/mls/MLSService/commitBundleUtil.test.js +3 -3
- package/lib/messagingProtocols/mls/MLSService/stores/subconversationGroupIdStore/subconversationGroupIdStore.d.ts +13 -0
- package/lib/messagingProtocols/mls/MLSService/stores/subconversationGroupIdStore/subconversationGroupIdStore.d.ts.map +1 -0
- package/lib/messagingProtocols/mls/MLSService/stores/subconversationGroupIdStore/subconversationGroupIdStore.js +67 -0
- package/lib/messagingProtocols/mls/MLSService/stores/subconversationGroupIdStore/subconversationGroupIdStore.test.d.ts +2 -0
- package/lib/messagingProtocols/mls/MLSService/stores/subconversationGroupIdStore/subconversationGroupIdStore.test.d.ts.map +1 -0
- package/lib/messagingProtocols/mls/MLSService/stores/subconversationGroupIdStore/subconversationGroupIdStore.test.js +72 -0
- package/lib/messagingProtocols/proteus/ProteusService/CryptoClient/CoreCryptoWrapper/CoreCryptoWrapper.d.ts +10 -5
- package/lib/messagingProtocols/proteus/ProteusService/CryptoClient/CoreCryptoWrapper/CoreCryptoWrapper.d.ts.map +1 -1
- package/lib/messagingProtocols/proteus/ProteusService/CryptoClient/CoreCryptoWrapper/CoreCryptoWrapper.js +33 -11
- package/lib/messagingProtocols/proteus/ProteusService/CryptoClient/CoreCryptoWrapper/PrekeysTracker/PrekeysTracker.d.ts +2 -3
- package/lib/messagingProtocols/proteus/ProteusService/CryptoClient/CoreCryptoWrapper/PrekeysTracker/PrekeysTracker.d.ts.map +1 -1
- package/lib/messagingProtocols/proteus/ProteusService/CryptoClient/CoreCryptoWrapper/PrekeysTracker/PrekeysTracker.js +8 -9
- package/lib/messagingProtocols/proteus/ProteusService/CryptoClient/CoreCryptoWrapper/PrekeysTracker/PrekeysTracker.store.d.ts +4 -9
- package/lib/messagingProtocols/proteus/ProteusService/CryptoClient/CoreCryptoWrapper/PrekeysTracker/PrekeysTracker.store.d.ts.map +1 -1
- package/lib/messagingProtocols/proteus/ProteusService/CryptoClient/CoreCryptoWrapper/PrekeysTracker/PrekeysTracker.store.js +10 -24
- package/lib/messagingProtocols/proteus/ProteusService/CryptoClient/CoreCryptoWrapper/PrekeysTracker/PrekeysTracker.test.js +2 -10
- package/lib/messagingProtocols/proteus/ProteusService/CryptoClient/CryptoClient.d.ts +1 -2
- package/lib/messagingProtocols/proteus/ProteusService/CryptoClient/CryptoClient.d.ts.map +1 -1
- package/lib/messagingProtocols/proteus/ProteusService/CryptoClient/CryptoClient.js +3 -3
- package/lib/messagingProtocols/proteus/ProteusService/CryptoClient/CryptoClient.types.d.ts +2 -2
- package/lib/messagingProtocols/proteus/ProteusService/CryptoClient/CryptoClient.types.d.ts.map +1 -1
- package/lib/messagingProtocols/proteus/ProteusService/CryptoClient/CryptoboxWrapper.d.ts +1 -1
- package/lib/messagingProtocols/proteus/ProteusService/CryptoClient/CryptoboxWrapper.d.ts.map +1 -1
- package/lib/messagingProtocols/proteus/ProteusService/CryptoClient/CryptoboxWrapper.js +2 -2
- package/lib/messagingProtocols/proteus/ProteusService/ProteusService.d.ts +14 -7
- package/lib/messagingProtocols/proteus/ProteusService/ProteusService.d.ts.map +1 -1
- package/lib/messagingProtocols/proteus/ProteusService/ProteusService.js +31 -35
- package/lib/messagingProtocols/proteus/ProteusService/ProteusService.mocks.d.ts +1 -1
- package/lib/messagingProtocols/proteus/ProteusService/ProteusService.mocks.d.ts.map +1 -1
- package/lib/messagingProtocols/proteus/ProteusService/ProteusService.mocks.js +2 -3
- package/lib/messagingProtocols/proteus/ProteusService/ProteusService.test.js +109 -89
- package/lib/messagingProtocols/proteus/ProteusService/ProteusService.types.d.ts +6 -9
- package/lib/messagingProtocols/proteus/ProteusService/ProteusService.types.d.ts.map +1 -1
- package/lib/messagingProtocols/proteus/Utility/Recipients.d.ts +4 -10
- package/lib/messagingProtocols/proteus/Utility/Recipients.d.ts.map +1 -1
- package/lib/messagingProtocols/proteus/Utility/Recipients.js +16 -16
- package/lib/messagingProtocols/proteus/Utility/SessionHandler/SessionHandler.d.ts +15 -10
- package/lib/messagingProtocols/proteus/Utility/SessionHandler/SessionHandler.d.ts.map +1 -1
- package/lib/messagingProtocols/proteus/Utility/SessionHandler/SessionHandler.js +80 -92
- package/lib/messagingProtocols/proteus/Utility/SessionHandler/SessionHandler.test.js +70 -54
- package/lib/messagingProtocols/proteus/Utility/getGenericMessageParams.d.ts +5 -14
- package/lib/messagingProtocols/proteus/Utility/getGenericMessageParams.d.ts.map +1 -1
- package/lib/messagingProtocols/proteus/Utility/getGenericMessageParams.js +3 -35
- package/lib/messagingProtocols/proteus/Utility/isClearFromMismatch.d.ts +2 -2
- package/lib/messagingProtocols/proteus/Utility/isClearFromMismatch.d.ts.map +1 -1
- package/lib/notification/NotificationDatabaseRepository.js +1 -1
- package/lib/notification/Notifications.types.js +1 -1
- package/lib/user/UserService.d.ts +6 -17
- package/lib/user/UserService.d.ts.map +1 -1
- package/lib/user/UserService.js +2 -47
- package/lib/util/TaskScheduler/TaskScheduler.d.ts +4 -1
- package/lib/util/TaskScheduler/TaskScheduler.d.ts.map +1 -1
- package/lib/util/TaskScheduler/TaskScheduler.js +24 -3
- package/lib/util/TaskScheduler/TaskScheduler.store.d.ts +7 -0
- package/lib/util/TaskScheduler/TaskScheduler.store.d.ts.map +1 -0
- package/lib/util/TaskScheduler/TaskScheduler.store.js +34 -0
- package/lib/util/TypePredicateUtil.d.ts +0 -1
- package/lib/util/TypePredicateUtil.d.ts.map +1 -1
- package/lib/util/TypePredicateUtil.js +1 -2
- package/package.json +7 -7
- package/lib/messagingProtocols/mls/MLSService/stores/keyMaterialUpdatesStore/index.d.ts +0 -2
- package/lib/messagingProtocols/mls/MLSService/stores/keyMaterialUpdatesStore/index.d.ts.map +0 -1
- package/lib/messagingProtocols/mls/MLSService/stores/keyMaterialUpdatesStore/index.js +0 -35
- package/lib/messagingProtocols/mls/MLSService/stores/keyMaterialUpdatesStore/keyMaterialUpdatesStore.d.ts +0 -11
- package/lib/messagingProtocols/mls/MLSService/stores/keyMaterialUpdatesStore/keyMaterialUpdatesStore.d.ts.map +0 -1
- package/lib/messagingProtocols/mls/MLSService/stores/keyMaterialUpdatesStore/keyMaterialUpdatesStore.js +0 -50
- package/lib/messagingProtocols/mls/MLSService/stores/keyMaterialUpdatesStore/keyMaterialUpdatesStore.test.d.ts +0 -2
- package/lib/messagingProtocols/mls/MLSService/stores/keyMaterialUpdatesStore/keyMaterialUpdatesStore.test.d.ts.map +0 -1
- package/lib/messagingProtocols/mls/MLSService/stores/keyMaterialUpdatesStore/keyMaterialUpdatesStore.test.js +0 -39
- package/lib/messagingProtocols/mls/MLSService/subconversationGroupIdMapper.d.ts +0 -4
- package/lib/messagingProtocols/mls/MLSService/subconversationGroupIdMapper.d.ts.map +0 -1
- package/lib/messagingProtocols/mls/MLSService/subconversationGroupIdMapper.js +0 -35
- package/lib/messagingProtocols/mls/MLSService/subconversationGroupIdMapper.test.d.ts +0 -2
- package/lib/messagingProtocols/mls/MLSService/subconversationGroupIdMapper.test.d.ts.map +0 -1
- package/lib/messagingProtocols/mls/MLSService/subconversationGroupIdMapper.test.js +0 -35
- package/lib/messagingProtocols/proteus/Utility/PreKeyBundle/PreKeyBundle.d.ts +0 -25
- package/lib/messagingProtocols/proteus/Utility/PreKeyBundle/PreKeyBundle.d.ts.map +0 -1
- package/lib/messagingProtocols/proteus/Utility/PreKeyBundle/PreKeyBundle.js +0 -93
- package/lib/messagingProtocols/proteus/Utility/PreKeyBundle/PreKeyBundle.test.d.ts +0 -2
- package/lib/messagingProtocols/proteus/Utility/PreKeyBundle/PreKeyBundle.test.d.ts.map +0 -1
- package/lib/messagingProtocols/proteus/Utility/PreKeyBundle/PreKeyBundle.test.js +0 -66
- package/lib/messagingProtocols/proteus/Utility/PreKeyBundle/index.d.ts +0 -2
- package/lib/messagingProtocols/proteus/Utility/PreKeyBundle/index.d.ts.map +0 -1
- package/lib/messagingProtocols/proteus/Utility/PreKeyBundle/index.js +0 -35
|
@@ -51,12 +51,14 @@ function generateQualifiedRecipients(users) {
|
|
|
51
51
|
return payload;
|
|
52
52
|
}
|
|
53
53
|
function generateRecipients(users) {
|
|
54
|
-
return users.reduce((acc, { id, clients }) => {
|
|
55
|
-
acc[
|
|
54
|
+
return users.reduce((acc, { id, domain, clients }) => {
|
|
55
|
+
const domainUsers = acc[domain] || {};
|
|
56
|
+
domainUsers[id] = clients;
|
|
57
|
+
acc[domain] = domainUsers;
|
|
56
58
|
return acc;
|
|
57
59
|
}, {});
|
|
58
60
|
}
|
|
59
|
-
function
|
|
61
|
+
function fakeEncrypt(_, recipients) {
|
|
60
62
|
const encryptedPayload = Object.entries(recipients).reduce((acc, [domain, users]) => {
|
|
61
63
|
acc[domain] = Object.entries(users).reduce((userClients, [userId, clients]) => {
|
|
62
64
|
userClients[userId] = clients.reduce((payloads, client) => {
|
|
@@ -67,44 +69,102 @@ function fakeEncryptQualified(_, recipients) {
|
|
|
67
69
|
}, {});
|
|
68
70
|
return acc;
|
|
69
71
|
}, {});
|
|
70
|
-
return Promise.resolve(encryptedPayload);
|
|
71
|
-
}
|
|
72
|
-
function fakeEncrypt(_, recipients) {
|
|
73
|
-
const encryptedPayload = Object.entries(recipients).reduce((userClients, [userId, clients]) => {
|
|
74
|
-
userClients[userId] || (userClients[userId] = clients.reduce((acc, clientId) => {
|
|
75
|
-
acc[clientId] = new Uint8Array();
|
|
76
|
-
return acc;
|
|
77
|
-
}, {}));
|
|
78
|
-
return userClients;
|
|
79
|
-
}, {});
|
|
80
|
-
return Promise.resolve(encryptedPayload);
|
|
72
|
+
return Promise.resolve({ payloads: encryptedPayload });
|
|
81
73
|
}
|
|
82
74
|
const buildMessageService = async () => {
|
|
83
75
|
const apiClient = new api_client_1.APIClient();
|
|
84
|
-
const [proteusService] = await (0, ProteusService_mocks_1.buildProteusService)(
|
|
76
|
+
const [proteusService] = await (0, ProteusService_mocks_1.buildProteusService)();
|
|
85
77
|
const messageService = new MessageService_1.MessageService(apiClient, proteusService);
|
|
86
|
-
jest.spyOn(proteusService, 'encryptQualified').mockImplementation(fakeEncryptQualified);
|
|
87
78
|
jest.spyOn(proteusService, 'encrypt').mockImplementation(fakeEncrypt);
|
|
88
|
-
return [messageService, { apiClient }];
|
|
79
|
+
return [messageService, { apiClient, proteusService }];
|
|
89
80
|
};
|
|
90
81
|
describe('MessageService', () => {
|
|
91
|
-
describe('
|
|
82
|
+
describe('sendMessage', () => {
|
|
83
|
+
const generateUsers = (userCount, clientsPerUser) => {
|
|
84
|
+
return Array.from(Array(userCount)).map((_, i) => ({
|
|
85
|
+
id: `user${i}`,
|
|
86
|
+
domain: `${i}.domain`,
|
|
87
|
+
clients: Array.from(Array(clientsPerUser)).map((_, j) => `client${i}${j}`),
|
|
88
|
+
}));
|
|
89
|
+
};
|
|
90
|
+
const clientId = 'sendingClient';
|
|
91
|
+
const conversationId = { id: 'conv1', domain: '' };
|
|
92
|
+
const createMessage = (content) => {
|
|
93
|
+
const customTextMessage = protocol_messaging_1.GenericMessage.create({
|
|
94
|
+
messageId: (0, PayloadHelper_1.getUUID)(),
|
|
95
|
+
text: protocol_messaging_1.Text.create({ content }),
|
|
96
|
+
});
|
|
97
|
+
return protocol_messaging_1.GenericMessage.encode(customTextMessage).finish();
|
|
98
|
+
};
|
|
92
99
|
it('sends a message and forwards backend response', async () => {
|
|
93
100
|
const [messageService, { apiClient }] = await buildMessageService();
|
|
94
|
-
jest.spyOn(apiClient.api.conversation, '
|
|
101
|
+
jest.spyOn(apiClient.api.conversation, 'postOTRMessage').mockResolvedValue(baseMessageSendingStatus);
|
|
95
102
|
const recipients = generateQualifiedRecipients([user1, user2]);
|
|
96
|
-
const result = await messageService.
|
|
97
|
-
conversationId: { id: 'convid', domain: '' },
|
|
103
|
+
const result = await messageService.sendMessage('senderclientid', recipients, new Uint8Array(), {
|
|
104
|
+
conversationId: { id: 'convid', domain: 'domain' },
|
|
105
|
+
});
|
|
106
|
+
expect(apiClient.api.conversation.postOTRMessage).toHaveBeenCalled();
|
|
107
|
+
expect(result).toEqual(Object.assign(Object.assign({}, baseMessageSendingStatus), { failed: undefined }));
|
|
108
|
+
});
|
|
109
|
+
it('should send regular to conversation', async () => {
|
|
110
|
+
const [messageService, { apiClient }] = await buildMessageService();
|
|
111
|
+
const message = 'Lorem ipsum dolor sit amet';
|
|
112
|
+
jest
|
|
113
|
+
.spyOn(apiClient.api.conversation, 'postOTRMessage')
|
|
114
|
+
.mockReturnValue(Promise.resolve({}));
|
|
115
|
+
await messageService.sendMessage(clientId, generateRecipients(generateUsers(3, 3)), createMessage(message), {
|
|
116
|
+
conversationId,
|
|
98
117
|
});
|
|
99
|
-
expect(apiClient.api.conversation.
|
|
100
|
-
|
|
118
|
+
expect(apiClient.api.conversation.postOTRMessage).toHaveBeenCalledWith(conversationId.id, conversationId.domain, expect.any(Object));
|
|
119
|
+
});
|
|
120
|
+
it('should broadcast regular message if no conversationId is given', async () => {
|
|
121
|
+
const [messageService, { apiClient }] = await buildMessageService();
|
|
122
|
+
const message = 'Lorem ipsum dolor sit amet';
|
|
123
|
+
jest
|
|
124
|
+
.spyOn(apiClient.api.broadcast, 'postBroadcastMessage')
|
|
125
|
+
.mockReturnValue(Promise.resolve({}));
|
|
126
|
+
await messageService.sendMessage(clientId, generateRecipients(generateUsers(3, 3)), createMessage(message));
|
|
127
|
+
expect(apiClient.api.broadcast.postBroadcastMessage).toHaveBeenCalledWith(clientId, expect.any(Object));
|
|
101
128
|
});
|
|
102
129
|
describe('client mismatch', () => {
|
|
130
|
+
const baseClientMismatch = {
|
|
131
|
+
deleted: {},
|
|
132
|
+
missing: {},
|
|
133
|
+
redundant: {},
|
|
134
|
+
failed_to_send: {},
|
|
135
|
+
time: new Date().toISOString(),
|
|
136
|
+
};
|
|
137
|
+
it('handles client mismatch when no other clients from that domain are known', async () => {
|
|
138
|
+
const [messageService, { apiClient }] = await buildMessageService();
|
|
139
|
+
let spyCounter = 0;
|
|
140
|
+
const clientMismatch = Object.assign(Object.assign({}, baseClientMismatch), { missing: { [user1.domain]: { [user1.id]: ['client'] } } });
|
|
141
|
+
jest.spyOn(apiClient.api.conversation, 'postOTRMessage').mockImplementation(() => {
|
|
142
|
+
spyCounter++;
|
|
143
|
+
if (spyCounter === 1) {
|
|
144
|
+
const error = new Error();
|
|
145
|
+
error.response = {
|
|
146
|
+
status: http_status_codes_1.StatusCodes.PRECONDITION_FAILED,
|
|
147
|
+
data: clientMismatch,
|
|
148
|
+
};
|
|
149
|
+
return Promise.reject(error);
|
|
150
|
+
}
|
|
151
|
+
return Promise.resolve(baseClientMismatch);
|
|
152
|
+
});
|
|
153
|
+
jest
|
|
154
|
+
.spyOn(apiClient.api.user, 'postMultiPreKeyBundles')
|
|
155
|
+
.mockReturnValue(Promise.resolve({ qualified_user_client_prekeys: {} }));
|
|
156
|
+
const recipients = generateRecipients([]);
|
|
157
|
+
await messageService.sendMessage('senderclientid', recipients, new Uint8Array(), {
|
|
158
|
+
reportMissing: true,
|
|
159
|
+
conversationId: { id: 'convid', domain: '' },
|
|
160
|
+
});
|
|
161
|
+
expect(apiClient.api.conversation.postOTRMessage).toHaveBeenCalledTimes(2);
|
|
162
|
+
});
|
|
103
163
|
it('handles client mismatch internally if no onClientMismatch is given', async () => {
|
|
104
164
|
const [messageService, { apiClient }] = await buildMessageService();
|
|
105
165
|
let spyCounter = 0;
|
|
106
|
-
const clientMismatch = Object.assign(Object.assign({},
|
|
107
|
-
jest.spyOn(apiClient.api.conversation, '
|
|
166
|
+
const clientMismatch = Object.assign(Object.assign({}, baseClientMismatch), { deleted: { [user1.domain]: { [user1.id]: [user1.clients[0]] } }, missing: { [user2.domain]: { [user2.id]: ['client22'] } } });
|
|
167
|
+
jest.spyOn(apiClient.api.conversation, 'postOTRMessage').mockImplementation(() => {
|
|
108
168
|
spyCounter++;
|
|
109
169
|
if (spyCounter === 1) {
|
|
110
170
|
const error = new Error();
|
|
@@ -114,22 +174,24 @@ describe('MessageService', () => {
|
|
|
114
174
|
};
|
|
115
175
|
return Promise.reject(error);
|
|
116
176
|
}
|
|
117
|
-
return Promise.resolve(
|
|
177
|
+
return Promise.resolve(baseClientMismatch);
|
|
118
178
|
});
|
|
119
|
-
jest
|
|
120
|
-
|
|
121
|
-
|
|
179
|
+
jest
|
|
180
|
+
.spyOn(apiClient.api.user, 'postMultiPreKeyBundles')
|
|
181
|
+
.mockReturnValue(Promise.resolve({ qualified_user_client_prekeys: {} }));
|
|
182
|
+
const recipients = generateRecipients([user1, user2]);
|
|
183
|
+
await messageService.sendMessage('senderclientid', recipients, new Uint8Array(), {
|
|
122
184
|
reportMissing: true,
|
|
123
185
|
conversationId: { id: 'convid', domain: '' },
|
|
124
186
|
});
|
|
125
|
-
expect(apiClient.api.conversation.
|
|
187
|
+
expect(apiClient.api.conversation.postOTRMessage).toHaveBeenCalledTimes(2);
|
|
126
188
|
});
|
|
127
189
|
it('continues message sending if onClientMismatch returns true', async () => {
|
|
128
190
|
const [messageService, { apiClient }] = await buildMessageService();
|
|
129
|
-
const onClientMismatch = jest.fn().mockReturnValue(true);
|
|
130
|
-
const clientMismatch = Object.assign(Object.assign({},
|
|
191
|
+
const onClientMismatch = jest.fn().mockReturnValue(Promise.resolve(true));
|
|
192
|
+
const clientMismatch = Object.assign(Object.assign({}, baseClientMismatch), { missing: { [user2.domain]: { [user2.id]: ['client22'] } } });
|
|
131
193
|
let spyCounter = 0;
|
|
132
|
-
jest.spyOn(apiClient.api.conversation, '
|
|
194
|
+
jest.spyOn(apiClient.api.conversation, 'postOTRMessage').mockImplementation(() => {
|
|
133
195
|
spyCounter++;
|
|
134
196
|
if (spyCounter === 1) {
|
|
135
197
|
const error = new Error();
|
|
@@ -139,23 +201,25 @@ describe('MessageService', () => {
|
|
|
139
201
|
};
|
|
140
202
|
return Promise.reject(error);
|
|
141
203
|
}
|
|
142
|
-
return Promise.resolve(
|
|
204
|
+
return Promise.resolve(baseClientMismatch);
|
|
143
205
|
});
|
|
144
|
-
jest
|
|
145
|
-
|
|
146
|
-
|
|
206
|
+
jest
|
|
207
|
+
.spyOn(apiClient.api.user, 'postMultiPreKeyBundles')
|
|
208
|
+
.mockReturnValue(Promise.resolve({ qualified_user_client_prekeys: {} }));
|
|
209
|
+
const recipients = generateRecipients([user1, user2]);
|
|
210
|
+
await messageService.sendMessage('senderclientid', recipients, new Uint8Array(), {
|
|
147
211
|
reportMissing: true,
|
|
148
212
|
onClientMismatch,
|
|
149
213
|
conversationId: { id: 'convid', domain: '' },
|
|
150
214
|
});
|
|
151
|
-
expect(apiClient.api.conversation.
|
|
215
|
+
expect(apiClient.api.conversation.postOTRMessage).toHaveBeenCalledTimes(2);
|
|
152
216
|
expect(onClientMismatch).toHaveBeenCalledWith(clientMismatch);
|
|
153
217
|
});
|
|
154
218
|
it('stops message sending if onClientMismatch returns false', async () => {
|
|
155
219
|
const [messageService, { apiClient }] = await buildMessageService();
|
|
156
|
-
const onClientMismatch = jest.fn().mockReturnValue(false);
|
|
157
|
-
const clientMismatch = Object.assign(Object.assign({}, baseMessageSendingStatus), { missing: {
|
|
158
|
-
jest.spyOn(apiClient.api.conversation, '
|
|
220
|
+
const onClientMismatch = jest.fn().mockReturnValue(Promise.resolve(false));
|
|
221
|
+
const clientMismatch = Object.assign(Object.assign({}, baseMessageSendingStatus), { missing: { [user2.id]: ['client22'] } });
|
|
222
|
+
jest.spyOn(apiClient.api.conversation, 'postOTRMessage').mockImplementation(() => {
|
|
159
223
|
const error = new Error();
|
|
160
224
|
error.response = {
|
|
161
225
|
status: http_status_codes_1.StatusCodes.PRECONDITION_FAILED,
|
|
@@ -163,105 +227,24 @@ describe('MessageService', () => {
|
|
|
163
227
|
};
|
|
164
228
|
return Promise.reject(error);
|
|
165
229
|
});
|
|
166
|
-
jest
|
|
167
|
-
|
|
168
|
-
|
|
230
|
+
jest
|
|
231
|
+
.spyOn(apiClient.api.user, 'postMultiPreKeyBundles')
|
|
232
|
+
.mockReturnValue(Promise.resolve({ qualified_user_client_prekeys: {} }));
|
|
233
|
+
const recipients = generateRecipients([user1, user2]);
|
|
234
|
+
await messageService.sendMessage('senderclientid', recipients, new Uint8Array(), {
|
|
169
235
|
reportMissing: true,
|
|
170
236
|
onClientMismatch,
|
|
171
237
|
conversationId: { id: 'convid', domain: '' },
|
|
172
238
|
});
|
|
173
|
-
expect(apiClient.api.conversation.
|
|
239
|
+
expect(apiClient.api.conversation.postOTRMessage).toHaveBeenCalledTimes(1);
|
|
174
240
|
expect(onClientMismatch).toHaveBeenCalledWith(clientMismatch);
|
|
175
241
|
});
|
|
176
242
|
});
|
|
177
|
-
});
|
|
178
|
-
describe('sendMessage', () => {
|
|
179
|
-
const generateUsers = (userCount, clientsPerUser) => {
|
|
180
|
-
return Array.from(Array(userCount)).map((_, i) => ({
|
|
181
|
-
id: `user${i}`,
|
|
182
|
-
domain: `${i}.domain`,
|
|
183
|
-
clients: Array.from(Array(clientsPerUser)).map((_, j) => `client${i}${j}`),
|
|
184
|
-
}));
|
|
185
|
-
};
|
|
186
|
-
const clientId = 'sendingClient';
|
|
187
|
-
const conversationId = { id: 'conv1', domain: '' };
|
|
188
|
-
const createMessage = (content) => {
|
|
189
|
-
const customTextMessage = protocol_messaging_1.GenericMessage.create({
|
|
190
|
-
messageId: (0, PayloadHelper_1.getUUID)(),
|
|
191
|
-
text: protocol_messaging_1.Text.create({ content }),
|
|
192
|
-
});
|
|
193
|
-
return protocol_messaging_1.GenericMessage.encode(customTextMessage).finish();
|
|
194
|
-
};
|
|
195
|
-
it('should send regular to conversation', async () => {
|
|
196
|
-
const [messageService, { apiClient }] = await buildMessageService();
|
|
197
|
-
const message = 'Lorem ipsum dolor sit amet';
|
|
198
|
-
jest.spyOn(apiClient.api.conversation, 'postOTRMessage').mockReturnValue(Promise.resolve({}));
|
|
199
|
-
await messageService.sendMessage(clientId, generateRecipients(generateUsers(3, 3)), createMessage(message), {
|
|
200
|
-
conversationId,
|
|
201
|
-
});
|
|
202
|
-
expect(apiClient.api.conversation.postOTRMessage).toHaveBeenCalledWith(clientId, conversationId.id, expect.any(Object), false);
|
|
203
|
-
});
|
|
204
|
-
it('should send protobuf message to conversation', async () => {
|
|
205
|
-
const [messageService, { apiClient }] = await buildMessageService();
|
|
206
|
-
const message = 'Lorem ipsum dolor sit amet';
|
|
207
|
-
jest
|
|
208
|
-
.spyOn(apiClient.api.conversation, 'postOTRProtobufMessage')
|
|
209
|
-
.mockReturnValue(Promise.resolve({}));
|
|
210
|
-
await messageService.sendMessage(clientId, generateRecipients(generateUsers(3, 3)), createMessage(message), {
|
|
211
|
-
conversationId,
|
|
212
|
-
sendAsProtobuf: true,
|
|
213
|
-
});
|
|
214
|
-
expect(apiClient.api.conversation.postOTRProtobufMessage).toHaveBeenCalledWith(clientId, conversationId.id, expect.any(Object), false);
|
|
215
|
-
});
|
|
216
|
-
it('should broadcast regular message if no conversationId is given', async () => {
|
|
217
|
-
const [messageService, { apiClient }] = await buildMessageService();
|
|
218
|
-
const message = 'Lorem ipsum dolor sit amet';
|
|
219
|
-
jest
|
|
220
|
-
.spyOn(apiClient.api.broadcast, 'postBroadcastMessage')
|
|
221
|
-
.mockReturnValue(Promise.resolve({}));
|
|
222
|
-
await messageService.sendMessage(clientId, generateRecipients(generateUsers(3, 3)), createMessage(message));
|
|
223
|
-
expect(apiClient.api.broadcast.postBroadcastMessage).toHaveBeenCalledWith(clientId, expect.any(Object), false);
|
|
224
|
-
});
|
|
225
|
-
it('should broadcast protobuf message if no conversationId is given', async () => {
|
|
226
|
-
const [messageService, { apiClient }] = await buildMessageService();
|
|
227
|
-
const message = 'Lorem ipsum dolor sit amet';
|
|
228
|
-
jest
|
|
229
|
-
.spyOn(apiClient.api.broadcast, 'postBroadcastProtobufMessage')
|
|
230
|
-
.mockReturnValue(Promise.resolve({}));
|
|
231
|
-
await messageService.sendMessage(clientId, generateRecipients(generateUsers(3, 3)), createMessage(message), {
|
|
232
|
-
sendAsProtobuf: true,
|
|
233
|
-
});
|
|
234
|
-
expect(apiClient.api.broadcast.postBroadcastProtobufMessage).toHaveBeenCalledWith(clientId, expect.any(Object), false);
|
|
235
|
-
});
|
|
236
|
-
it('should not send as external if payload small', async () => {
|
|
237
|
-
const [messageService, { apiClient }] = await buildMessageService();
|
|
238
|
-
const message = 'Lorem ipsum dolor sit amet';
|
|
239
|
-
jest.spyOn(apiClient.api.conversation, 'postOTRMessage').mockReturnValue(Promise.resolve({}));
|
|
240
|
-
await messageService.sendMessage(clientId, generateRecipients(generateUsers(3, 3)), createMessage(message), {
|
|
241
|
-
conversationId,
|
|
242
|
-
});
|
|
243
|
-
expect(apiClient.api.conversation.postOTRMessage).toHaveBeenCalledWith(clientId, conversationId.id, expect.objectContaining({ data: undefined }), false);
|
|
244
|
-
});
|
|
245
|
-
it('should send as external if payload is big', async () => {
|
|
246
|
-
const [messageService, { apiClient }] = await buildMessageService();
|
|
247
|
-
const longMessage = 'Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Duis autem Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Duis autem';
|
|
248
|
-
jest.spyOn(apiClient.api.conversation, 'postOTRMessage').mockReturnValue(Promise.resolve({}));
|
|
249
|
-
await messageService.sendMessage(clientId, generateRecipients(generateUsers(30, 10)), createMessage(longMessage), {
|
|
250
|
-
conversationId,
|
|
251
|
-
});
|
|
252
|
-
expect(apiClient.api.conversation.postOTRMessage).toHaveBeenCalledWith(clientId, conversationId.id, expect.objectContaining({ data: expect.any(String) }), false);
|
|
253
|
-
});
|
|
254
243
|
describe('client mismatch', () => {
|
|
255
|
-
const baseClientMismatch = {
|
|
256
|
-
deleted: {},
|
|
257
|
-
missing: {},
|
|
258
|
-
redundant: {},
|
|
259
|
-
time: new Date().toISOString(),
|
|
260
|
-
};
|
|
261
244
|
it('handles client mismatch internally if no onClientMismatch is given', async () => {
|
|
262
245
|
const [messageService, { apiClient }] = await buildMessageService();
|
|
263
246
|
let spyCounter = 0;
|
|
264
|
-
const clientMismatch = Object.assign(Object.assign({},
|
|
247
|
+
const clientMismatch = Object.assign(Object.assign({}, baseMessageSendingStatus), { deleted: { [user1.domain]: { [user1.id]: [user1.clients[0]] } }, missing: { '2.wire.test': { [user2.id]: ['client22'] } } });
|
|
265
248
|
jest.spyOn(apiClient.api.conversation, 'postOTRMessage').mockImplementation(() => {
|
|
266
249
|
spyCounter++;
|
|
267
250
|
if (spyCounter === 1) {
|
|
@@ -272,10 +255,12 @@ describe('MessageService', () => {
|
|
|
272
255
|
};
|
|
273
256
|
return Promise.reject(error);
|
|
274
257
|
}
|
|
275
|
-
return Promise.resolve(
|
|
258
|
+
return Promise.resolve(baseMessageSendingStatus);
|
|
276
259
|
});
|
|
277
|
-
jest
|
|
278
|
-
|
|
260
|
+
jest
|
|
261
|
+
.spyOn(apiClient.api.user, 'postMultiPreKeyBundles')
|
|
262
|
+
.mockReturnValue(Promise.resolve({ qualified_user_client_prekeys: {} }));
|
|
263
|
+
const recipients = generateQualifiedRecipients([user1, user2]);
|
|
279
264
|
await messageService.sendMessage('senderclientid', recipients, new Uint8Array(), {
|
|
280
265
|
reportMissing: true,
|
|
281
266
|
conversationId: { id: 'convid', domain: '' },
|
|
@@ -284,8 +269,8 @@ describe('MessageService', () => {
|
|
|
284
269
|
});
|
|
285
270
|
it('continues message sending if onClientMismatch returns true', async () => {
|
|
286
271
|
const [messageService, { apiClient }] = await buildMessageService();
|
|
287
|
-
const onClientMismatch = jest.fn().mockReturnValue(
|
|
288
|
-
const clientMismatch = Object.assign(Object.assign({},
|
|
272
|
+
const onClientMismatch = jest.fn().mockReturnValue(true);
|
|
273
|
+
const clientMismatch = Object.assign(Object.assign({}, baseMessageSendingStatus), { missing: { '2.wire.test': { [user2.id]: ['client22'] } } });
|
|
289
274
|
let spyCounter = 0;
|
|
290
275
|
jest.spyOn(apiClient.api.conversation, 'postOTRMessage').mockImplementation(() => {
|
|
291
276
|
spyCounter++;
|
|
@@ -297,10 +282,12 @@ describe('MessageService', () => {
|
|
|
297
282
|
};
|
|
298
283
|
return Promise.reject(error);
|
|
299
284
|
}
|
|
300
|
-
return Promise.resolve(
|
|
285
|
+
return Promise.resolve(baseMessageSendingStatus);
|
|
301
286
|
});
|
|
302
|
-
jest
|
|
303
|
-
|
|
287
|
+
jest
|
|
288
|
+
.spyOn(apiClient.api.user, 'postMultiPreKeyBundles')
|
|
289
|
+
.mockReturnValue(Promise.resolve({ qualified_user_client_prekeys: {} }));
|
|
290
|
+
const recipients = generateQualifiedRecipients([user1, user2]);
|
|
304
291
|
await messageService.sendMessage('senderclientid', recipients, new Uint8Array(), {
|
|
305
292
|
reportMissing: true,
|
|
306
293
|
onClientMismatch,
|
|
@@ -309,10 +296,31 @@ describe('MessageService', () => {
|
|
|
309
296
|
expect(apiClient.api.conversation.postOTRMessage).toHaveBeenCalledTimes(2);
|
|
310
297
|
expect(onClientMismatch).toHaveBeenCalledWith(clientMismatch);
|
|
311
298
|
});
|
|
299
|
+
it('warns the consumer if they try to send a message to a deleted client', async () => {
|
|
300
|
+
const [messageService, { apiClient, proteusService }] = await buildMessageService();
|
|
301
|
+
const onClientMismatch = jest.fn().mockReturnValue(true);
|
|
302
|
+
const recipients = generateQualifiedRecipients([user1, user2]);
|
|
303
|
+
const unknowns = {
|
|
304
|
+
[user1.domain]: {
|
|
305
|
+
[user1.id]: [user1.clients[0]],
|
|
306
|
+
},
|
|
307
|
+
};
|
|
308
|
+
jest.spyOn(proteusService, 'encrypt').mockResolvedValue({
|
|
309
|
+
payloads: {},
|
|
310
|
+
unknowns,
|
|
311
|
+
});
|
|
312
|
+
jest.spyOn(apiClient.api.conversation, 'postOTRMessage').mockResolvedValue(baseMessageSendingStatus);
|
|
313
|
+
const result = await messageService.sendMessage('senderclientid', recipients, new Uint8Array(), {
|
|
314
|
+
reportMissing: true,
|
|
315
|
+
onClientMismatch,
|
|
316
|
+
conversationId: { id: 'convid', domain: '' },
|
|
317
|
+
});
|
|
318
|
+
expect(result.deleted).toEqual(unknowns);
|
|
319
|
+
});
|
|
312
320
|
it('stops message sending if onClientMismatch returns false', async () => {
|
|
313
321
|
const [messageService, { apiClient }] = await buildMessageService();
|
|
314
|
-
const onClientMismatch = jest.fn().mockReturnValue(
|
|
315
|
-
const clientMismatch = Object.assign(Object.assign({}, baseMessageSendingStatus), { missing: { [user2.id]: ['client22'] } });
|
|
322
|
+
const onClientMismatch = jest.fn().mockReturnValue(false);
|
|
323
|
+
const clientMismatch = Object.assign(Object.assign({}, baseMessageSendingStatus), { missing: { '2.wire.test': { [user2.id]: ['client22'] } } });
|
|
316
324
|
jest.spyOn(apiClient.api.conversation, 'postOTRMessage').mockImplementation(() => {
|
|
317
325
|
const error = new Error();
|
|
318
326
|
error.response = {
|
|
@@ -321,8 +329,10 @@ describe('MessageService', () => {
|
|
|
321
329
|
};
|
|
322
330
|
return Promise.reject(error);
|
|
323
331
|
});
|
|
324
|
-
jest
|
|
325
|
-
|
|
332
|
+
jest
|
|
333
|
+
.spyOn(apiClient.api.user, 'postMultiPreKeyBundles')
|
|
334
|
+
.mockReturnValue(Promise.resolve({ qualified_user_client_prekeys: {} }));
|
|
335
|
+
const recipients = generateQualifiedRecipients([user1, user2]);
|
|
326
336
|
await messageService.sendMessage('senderclientid', recipients, new Uint8Array(), {
|
|
327
337
|
reportMissing: true,
|
|
328
338
|
onClientMismatch,
|
|
@@ -64,4 +64,4 @@ var PayloadBundleType;
|
|
|
64
64
|
PayloadBundleType["USER_LEGAL_HOLD_REQUEST"] = "PayloadBundleType.USER_LEGAL_HOLD_REQUEST";
|
|
65
65
|
PayloadBundleType["USER_PROPERTIES_SET"] = "PayloadBundleType.USER_PROPERTIES_SET";
|
|
66
66
|
PayloadBundleType["USER_UPDATE"] = "PayloadBundleType.USER_UPDATE";
|
|
67
|
-
})(PayloadBundleType
|
|
67
|
+
})(PayloadBundleType || (exports.PayloadBundleType = PayloadBundleType = {}));
|
|
@@ -1,23 +1,27 @@
|
|
|
1
1
|
import { QualifiedId } from '@wireapp/api-client/lib/user';
|
|
2
|
-
type
|
|
2
|
+
type UserMap<T> = {
|
|
3
3
|
[userId: string]: T;
|
|
4
4
|
};
|
|
5
|
-
type
|
|
6
|
-
[domain: string]:
|
|
5
|
+
type QualifiedUserMap<T> = {
|
|
6
|
+
[domain: string]: UserMap<T>;
|
|
7
7
|
};
|
|
8
|
-
export declare function flattenUserClients<T>(userClients: UserClientsContainer<T>, domain?: string): {
|
|
9
|
-
data: T;
|
|
10
|
-
userId: QualifiedId;
|
|
11
|
-
}[];
|
|
12
8
|
/**
|
|
13
|
-
* Will flatten a container of users=>
|
|
9
|
+
* Will flatten a container of domain=>users=>anything infos to an array
|
|
14
10
|
*
|
|
15
|
-
* @param
|
|
11
|
+
* @param userMap The qualified UserMap to flatten
|
|
16
12
|
* @return An array containing the qualified user Ids and the clients info
|
|
17
13
|
*/
|
|
18
|
-
export declare function
|
|
14
|
+
export declare function flattenUserMap<T = unknown>(userMap: QualifiedUserMap<T>): {
|
|
19
15
|
data: T;
|
|
20
16
|
userId: QualifiedId;
|
|
21
17
|
}[];
|
|
18
|
+
/**
|
|
19
|
+
* Will convert a list of qualified users to a UserMap
|
|
20
|
+
* @param users the list of users to convert
|
|
21
|
+
*/
|
|
22
|
+
export declare function nestUsersList<T = unknown>(users: {
|
|
23
|
+
data: T;
|
|
24
|
+
userId: QualifiedId;
|
|
25
|
+
}[]): QualifiedUserMap<T>;
|
|
22
26
|
export {};
|
|
23
27
|
//# sourceMappingURL=UserClientsUtil.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"UserClientsUtil.d.ts","sourceRoot":"","sources":["../../../src/conversation/message/UserClientsUtil.ts"],"names":[],"mappings":"AAmBA,OAAO,EAAC,WAAW,EAAC,MAAM,8BAA8B,CAAC;AAEzD,KAAK,
|
|
1
|
+
{"version":3,"file":"UserClientsUtil.d.ts","sourceRoot":"","sources":["../../../src/conversation/message/UserClientsUtil.ts"],"names":[],"mappings":"AAmBA,OAAO,EAAC,WAAW,EAAC,MAAM,8BAA8B,CAAC;AAEzD,KAAK,OAAO,CAAC,CAAC,IAAI;IAAC,CAAC,MAAM,EAAE,MAAM,GAAG,CAAC,CAAA;CAAC,CAAC;AACxC,KAAK,gBAAgB,CAAC,CAAC,IAAI;IAAC,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,CAAC,CAAC,CAAA;CAAC,CAAC;AAE1D;;;;;GAKG;AACH,wBAAgB,cAAc,CAAC,CAAC,GAAG,OAAO,EAAE,OAAO,EAAE,gBAAgB,CAAC,CAAC,CAAC,GAAG;IAAC,IAAI,EAAE,CAAC,CAAC;IAAC,MAAM,EAAE,WAAW,CAAA;CAAC,EAAE,CAI1G;AAED;;;GAGG;AACH,wBAAgB,aAAa,CAAC,CAAC,GAAG,OAAO,EAAE,KAAK,EAAE;IAAC,IAAI,EAAE,CAAC,CAAC;IAAC,MAAM,EAAE,WAAW,CAAA;CAAC,EAAE,GAAG,gBAAgB,CAAC,CAAC,CAAC,CAQvG"}
|
|
@@ -18,20 +18,30 @@
|
|
|
18
18
|
*
|
|
19
19
|
*/
|
|
20
20
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
21
|
-
exports.
|
|
22
|
-
function flattenUserClients(userClients, domain = '') {
|
|
23
|
-
return Object.entries(userClients).map(([id, data]) => ({ data, userId: { domain, id } }));
|
|
24
|
-
}
|
|
25
|
-
exports.flattenUserClients = flattenUserClients;
|
|
21
|
+
exports.nestUsersList = exports.flattenUserMap = void 0;
|
|
26
22
|
/**
|
|
27
|
-
* Will flatten a container of users=>
|
|
23
|
+
* Will flatten a container of domain=>users=>anything infos to an array
|
|
28
24
|
*
|
|
29
|
-
* @param
|
|
25
|
+
* @param userMap The qualified UserMap to flatten
|
|
30
26
|
* @return An array containing the qualified user Ids and the clients info
|
|
31
27
|
*/
|
|
32
|
-
function
|
|
33
|
-
return Object.entries(
|
|
34
|
-
return [...ids, ...
|
|
28
|
+
function flattenUserMap(userMap) {
|
|
29
|
+
return Object.entries(userMap).reduce((ids, [domain, userClients]) => {
|
|
30
|
+
return [...ids, ...Object.entries(userClients).map(([id, data]) => ({ data, userId: { domain, id } }))];
|
|
35
31
|
}, []);
|
|
36
32
|
}
|
|
37
|
-
exports.
|
|
33
|
+
exports.flattenUserMap = flattenUserMap;
|
|
34
|
+
/**
|
|
35
|
+
* Will convert a list of qualified users to a UserMap
|
|
36
|
+
* @param users the list of users to convert
|
|
37
|
+
*/
|
|
38
|
+
function nestUsersList(users) {
|
|
39
|
+
return users.reduce((users, { data, userId: { domain, id } }) => {
|
|
40
|
+
if (!users[domain]) {
|
|
41
|
+
users[domain] = {};
|
|
42
|
+
}
|
|
43
|
+
users[domain][id] = data;
|
|
44
|
+
return users;
|
|
45
|
+
}, {});
|
|
46
|
+
}
|
|
47
|
+
exports.nestUsersList = nestUsersList;
|
|
@@ -27,15 +27,11 @@ describe('userClientsUtils', () => {
|
|
|
27
27
|
{ data: ['client11'], userId: { domain: 'domain1', id: 'user2' } },
|
|
28
28
|
{ data: ['client1', 'client2'], userId: { domain: 'domain2', id: 'user3' } },
|
|
29
29
|
];
|
|
30
|
-
expect((0, UserClientsUtil_1.
|
|
30
|
+
expect((0, UserClientsUtil_1.flattenUserMap)(payload)).toEqual(expected);
|
|
31
31
|
});
|
|
32
|
-
it('
|
|
33
|
-
const payload = { user1: ['client1'], user2: ['client11'], user3: ['client1', 'client2'] };
|
|
34
|
-
const
|
|
35
|
-
|
|
36
|
-
{ data: ['client11'], userId: { domain: '', id: 'user2' } },
|
|
37
|
-
{ data: ['client1', 'client2'], userId: { domain: '', id: 'user3' } },
|
|
38
|
-
];
|
|
39
|
-
expect((0, UserClientsUtil_1.flattenUserClients)(payload)).toEqual(expected);
|
|
32
|
+
it('nest and flatten are inverse operations', () => {
|
|
33
|
+
const payload = { domain1: { user1: ['client1'], user2: ['client11'] }, domain2: { user3: ['client1', 'client2'] } };
|
|
34
|
+
const result = (0, UserClientsUtil_1.nestUsersList)((0, UserClientsUtil_1.flattenUserMap)(payload));
|
|
35
|
+
expect(result).toEqual(payload);
|
|
40
36
|
});
|
|
41
37
|
});
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { EventHandlerParams } from './EventHandler.types';
|
|
2
2
|
import { EventHandlerResult } from '../../common.types';
|
|
3
|
-
declare const handleBackendEvent: (params: EventHandlerParams, onEpochChanged: (groupId: string) => void) => EventHandlerResult;
|
|
3
|
+
declare const handleBackendEvent: (params: EventHandlerParams, onEpochChanged: (groupId: string) => Promise<void>) => EventHandlerResult;
|
|
4
4
|
export { handleBackendEvent };
|
|
5
5
|
//# sourceMappingURL=EventHandler.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"EventHandler.d.ts","sourceRoot":"","sources":["../../../../src/messagingProtocols/mls/EventHandler/EventHandler.ts"],"names":[],"mappings":"AAmBA,OAAO,EAAC,kBAAkB,EAAC,MAAM,sBAAsB,CAAC;AAGxD,OAAO,EAAC,kBAAkB,EAAC,MAAM,oBAAoB,CAAC;AAEtD,QAAA,MAAM,kBAAkB,WACd,kBAAkB,4BACA,MAAM,KAAK,IAAI,
|
|
1
|
+
{"version":3,"file":"EventHandler.d.ts","sourceRoot":"","sources":["../../../../src/messagingProtocols/mls/EventHandler/EventHandler.ts"],"names":[],"mappings":"AAmBA,OAAO,EAAC,kBAAkB,EAAC,MAAM,sBAAsB,CAAC;AAGxD,OAAO,EAAC,kBAAkB,EAAC,MAAM,oBAAoB,CAAC;AAEtD,QAAA,MAAM,kBAAkB,WACd,kBAAkB,4BACA,MAAM,KAAK,QAAQ,IAAI,CAAC,uBASnD,CAAC;AAEF,OAAO,EAAC,kBAAkB,EAAC,CAAC"}
|
|
@@ -5,6 +5,6 @@ declare const isMLSMessageAddEvent: (event: BackendEvent) => event is Conversati
|
|
|
5
5
|
interface HandleMLSMessageAddParams extends EventHandlerParams {
|
|
6
6
|
event: ConversationMLSMessageAddEvent;
|
|
7
7
|
}
|
|
8
|
-
declare const handleMLSMessageAdd: ({ mlsService, event }: HandleMLSMessageAddParams, onEpochChanged: (groupId: string) => void) => EventHandlerResult;
|
|
8
|
+
declare const handleMLSMessageAdd: ({ mlsService, event }: HandleMLSMessageAddParams, onEpochChanged: (groupId: string) => Promise<void>) => EventHandlerResult;
|
|
9
9
|
export { isMLSMessageAddEvent, handleMLSMessageAdd };
|
|
10
10
|
//# sourceMappingURL=messageAdd.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"messageAdd.d.ts","sourceRoot":"","sources":["../../../../../../src/messagingProtocols/mls/EventHandler/events/messageAdd/messageAdd.ts"],"names":[],"mappings":"AAmBA,OAAO,EAAC,YAAY,EAAE,8BAA8B,EAAqB,MAAM,+BAA+B,CAAC;AAK/G,OAAO,EAAC,kBAAkB,EAAC,MAAM,0BAA0B,CAAC;AAE5D,OAAO,EAAC,kBAAkB,EAAC,MAAM,0BAA0B,CAAC;AAE5D,QAAA,MAAM,oBAAoB,UAAW,YAAY,4CACE,CAAC;AAEpD,UAAU,yBAA0B,SAAQ,kBAAkB;IAC5D,KAAK,EAAE,8BAA8B,CAAC;CACvC;AACD,QAAA,MAAM,mBAAmB,0BACF,yBAAyB,4BACpB,MAAM,KAAK,IAAI,
|
|
1
|
+
{"version":3,"file":"messageAdd.d.ts","sourceRoot":"","sources":["../../../../../../src/messagingProtocols/mls/EventHandler/events/messageAdd/messageAdd.ts"],"names":[],"mappings":"AAmBA,OAAO,EAAC,YAAY,EAAE,8BAA8B,EAAqB,MAAM,+BAA+B,CAAC;AAK/G,OAAO,EAAC,kBAAkB,EAAC,MAAM,0BAA0B,CAAC;AAE5D,OAAO,EAAC,kBAAkB,EAAC,MAAM,0BAA0B,CAAC;AAE5D,QAAA,MAAM,oBAAoB,UAAW,YAAY,4CACE,CAAC;AAEpD,UAAU,yBAA0B,SAAQ,kBAAkB;IAC5D,KAAK,EAAE,8BAA8B,CAAC;CACvC;AACD,QAAA,MAAM,mBAAmB,0BACF,yBAAyB,4BACpB,MAAM,KAAK,QAAQ,IAAI,CAAC,uBA+CnD,CAAC;AAEF,OAAO,EAAC,oBAAoB,EAAE,mBAAmB,EAAC,CAAC"}
|
|
@@ -28,7 +28,12 @@ exports.isMLSMessageAddEvent = isMLSMessageAddEvent;
|
|
|
28
28
|
const handleMLSMessageAdd = async ({ mlsService, event }, onEpochChanged) => {
|
|
29
29
|
var _a;
|
|
30
30
|
const encryptedData = bazinga64_1.Decoder.fromBase64(event.data).asBytes;
|
|
31
|
-
const
|
|
31
|
+
const qualifiedConversationId = (_a = event.qualified_conversation) !== null && _a !== void 0 ? _a : { id: event.conversation, domain: '' };
|
|
32
|
+
const groupId = await mlsService.getGroupIdFromConversationId(qualifiedConversationId, event.subconv);
|
|
33
|
+
// We should not receive a message for a group the client is not aware of
|
|
34
|
+
if (!groupId) {
|
|
35
|
+
throw new Error(`Could not find a group_id for conversation ${qualifiedConversationId.id}@${qualifiedConversationId.domain}`);
|
|
36
|
+
}
|
|
32
37
|
const groupIdBytes = bazinga64_1.Decoder.fromBase64(groupId).asBytes;
|
|
33
38
|
const { proposals, commitDelay, message, senderClientId: encodedSenderClientId, hasEpochChanged, } = await mlsService.decryptMessage(groupIdBytes, encryptedData);
|
|
34
39
|
if (encodedSenderClientId) {
|
|
@@ -47,7 +52,7 @@ const handleMLSMessageAdd = async ({ mlsService, event }, onEpochChanged) => {
|
|
|
47
52
|
});
|
|
48
53
|
}
|
|
49
54
|
if (hasEpochChanged) {
|
|
50
|
-
onEpochChanged(groupId);
|
|
55
|
+
await onEpochChanged(groupId);
|
|
51
56
|
}
|
|
52
57
|
return message ? { event, decryptedData: protocol_messaging_1.GenericMessage.decode(message) } : undefined;
|
|
53
58
|
};
|
package/lib/messagingProtocols/mls/EventHandler/events/welcomeMessage/welcomeMessage.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"welcomeMessage.d.ts","sourceRoot":"","sources":["../../../../../../src/messagingProtocols/mls/EventHandler/events/welcomeMessage/welcomeMessage.ts"],"names":[],"mappings":"AAmBA,OAAO,EAAC,YAAY,EAAE,2BAA2B,EAAqB,MAAM,+BAA+B,CAAC;AAG5G,OAAO,EAAC,kBAAkB,EAAC,MAAM,0BAA0B,CAAC;AAC5D,OAAO,EAAC,kBAAkB,EAAC,MAAM,0BAA0B,CAAC;AAE5D,QAAA,MAAM,qBAAqB,UAAW,YAAY,yCACK,CAAC;AAExD,UAAU,0BAA2B,SAAQ,kBAAkB;IAC7D,KAAK,EAAE,2BAA2B,CAAC;CACpC;AACD,QAAA,MAAM,oBAAoB,0BAA+B,0BAA0B,
|
|
1
|
+
{"version":3,"file":"welcomeMessage.d.ts","sourceRoot":"","sources":["../../../../../../src/messagingProtocols/mls/EventHandler/events/welcomeMessage/welcomeMessage.ts"],"names":[],"mappings":"AAmBA,OAAO,EAAC,YAAY,EAAE,2BAA2B,EAAqB,MAAM,+BAA+B,CAAC;AAG5G,OAAO,EAAC,kBAAkB,EAAC,MAAM,0BAA0B,CAAC;AAC5D,OAAO,EAAC,kBAAkB,EAAC,MAAM,0BAA0B,CAAC;AAE5D,QAAA,MAAM,qBAAqB,UAAW,YAAY,yCACK,CAAC;AAExD,UAAU,0BAA2B,SAAQ,kBAAkB;IAC7D,KAAK,EAAE,2BAA2B,CAAC;CACpC;AACD,QAAA,MAAM,oBAAoB,0BAA+B,0BAA0B,uBAYlF,CAAC;AAEF,OAAO,EAAC,qBAAqB,EAAE,oBAAoB,EAAC,CAAC"}
|
|
@@ -29,6 +29,8 @@ const handleWelcomeMessage = async ({ mlsService, event }) => {
|
|
|
29
29
|
const newGroupId = await mlsService.processWelcomeMessage(data);
|
|
30
30
|
const groupIdStr = bazinga64_1.Encoder.toBase64(newGroupId).asString;
|
|
31
31
|
// The groupId can then be sent back to the consumer
|
|
32
|
+
// After we were added to the group we need to schedule a periodic key material renewal
|
|
33
|
+
mlsService.scheduleKeyMaterialRenewal(groupIdStr);
|
|
32
34
|
return {
|
|
33
35
|
event: Object.assign(Object.assign({}, event), { data: groupIdStr }),
|
|
34
36
|
};
|
package/lib/messagingProtocols/mls/EventHandler/events/welcomeMessage/welcomeMessage.test.js
CHANGED
|
@@ -36,6 +36,7 @@ const mockParams = {
|
|
|
36
36
|
source: {},
|
|
37
37
|
mlsService: {
|
|
38
38
|
processWelcomeMessage: jest.fn().mockResolvedValue('conversationId'),
|
|
39
|
+
scheduleKeyMaterialRenewal: jest.fn(),
|
|
39
40
|
},
|
|
40
41
|
dryRun: false,
|
|
41
42
|
};
|
|
@@ -55,9 +56,10 @@ describe('MLS welcomeMessage eventHandler', () => {
|
|
|
55
56
|
});
|
|
56
57
|
});
|
|
57
58
|
describe('handleWelcomeMessage', () => {
|
|
58
|
-
it('calls processWelcomeMessage', async () => {
|
|
59
|
+
it('calls processWelcomeMessage and schedules periodic key material updates', async () => {
|
|
59
60
|
await (0, welcomeMessage_1.handleWelcomeMessage)(mockParams);
|
|
60
61
|
expect(mockParams.mlsService.processWelcomeMessage).toHaveBeenCalled();
|
|
62
|
+
expect(mockParams.mlsService.scheduleKeyMaterialRenewal).toHaveBeenCalled();
|
|
61
63
|
});
|
|
62
64
|
it('returns a eventHandlerResult', async () => {
|
|
63
65
|
const eventHandlerResult = await (0, welcomeMessage_1.handleWelcomeMessage)(mockParams);
|