@wireapp/core 46.43.0 → 46.44.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.
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ConversationService.d.ts","sourceRoot":"","sources":["../../../src/conversation/ConversationService/ConversationService.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"ConversationService.d.ts","sourceRoot":"","sources":["../../../src/conversation/ConversationService/ConversationService.ts"],"names":[],"mappings":"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"}
|
|
@@ -363,6 +363,19 @@ class ConversationService extends commons_1.TypedEventEmitter {
|
|
|
363
363
|
this.logger.warn("Tried to add users to MLS conversation but it's broken, resetting the conversation", error);
|
|
364
364
|
return this.handleBrokenMLSConversation(conversationId, newGroupId => this.addUsersToMLSConversation({ qualifiedUsers, groupId: newGroupId, conversationId, shouldRetry: false }));
|
|
365
365
|
}
|
|
366
|
+
if ((0, CoreCryptoMLSError_1.isMLSStaleMessageError)(error)) {
|
|
367
|
+
this.logger.info('Failed to add users to MLS conversation because of stale message, recovering by joining with external commit', {
|
|
368
|
+
error,
|
|
369
|
+
groupId,
|
|
370
|
+
});
|
|
371
|
+
await this.recoverMLSGroupFromEpochMismatch(conversationId);
|
|
372
|
+
return this.addUsersToMLSConversation({
|
|
373
|
+
groupId,
|
|
374
|
+
conversationId,
|
|
375
|
+
qualifiedUsers,
|
|
376
|
+
shouldRetry: false,
|
|
377
|
+
});
|
|
378
|
+
}
|
|
366
379
|
if ((0, CoreCryptoMLSError_1.isMLSGroupOutOfSyncError)(error)) {
|
|
367
380
|
this.logger.info('Failed to send MLS message because of group out of sync, recovering by adding missing users', {
|
|
368
381
|
error,
|
|
@@ -402,6 +415,13 @@ class ConversationService extends commons_1.TypedEventEmitter {
|
|
|
402
415
|
shouldRetry: false,
|
|
403
416
|
}));
|
|
404
417
|
}
|
|
418
|
+
if ((0, CoreCryptoMLSError_1.isMLSStaleMessageError)(error)) {
|
|
419
|
+
this.logger.info('Failed to remove users from MLS conversation because of stale message, recovering by joining with external commit', {
|
|
420
|
+
error,
|
|
421
|
+
groupId,
|
|
422
|
+
});
|
|
423
|
+
await this.recoverMLSGroupFromEpochMismatch(conversationId);
|
|
424
|
+
}
|
|
405
425
|
if ((0, CoreCryptoMLSError_1.isMLSGroupOutOfSyncError)(error)) {
|
|
406
426
|
this.logger.info('Failed to send MLS message because of group out of sync, recovering by adding missing users', {
|
|
407
427
|
error,
|
|
@@ -413,14 +433,13 @@ class ConversationService extends commons_1.TypedEventEmitter {
|
|
|
413
433
|
conversationId,
|
|
414
434
|
qualifiedUsers: missingUsers,
|
|
415
435
|
});
|
|
416
|
-
return this.removeUsersFromMLSConversation({
|
|
417
|
-
groupId,
|
|
418
|
-
conversationId,
|
|
419
|
-
qualifiedUserIds,
|
|
420
|
-
shouldRetry: false,
|
|
421
|
-
});
|
|
422
436
|
}
|
|
423
|
-
|
|
437
|
+
return this.removeUsersFromMLSConversation({
|
|
438
|
+
groupId,
|
|
439
|
+
conversationId,
|
|
440
|
+
qualifiedUserIds,
|
|
441
|
+
shouldRetry: false,
|
|
442
|
+
});
|
|
424
443
|
}
|
|
425
444
|
}
|
|
426
445
|
async joinByExternalCommit(conversationId, shouldRetry = true) {
|
|
@@ -437,6 +456,11 @@ class ConversationService extends commons_1.TypedEventEmitter {
|
|
|
437
456
|
this.logger.info('Resetting MLS conversation due to broken mls conversation error', error);
|
|
438
457
|
return this.handleBrokenMLSConversation(conversationId);
|
|
439
458
|
}
|
|
459
|
+
if ((0, CoreCryptoMLSError_1.isMLSStaleMessageError)(error)) {
|
|
460
|
+
this.logger.info('Failed to join MLS conversation with external commit because of stale message, recovering by joining with external commit', { error, conversationId });
|
|
461
|
+
await this.recoverMLSGroupFromEpochMismatch(conversationId);
|
|
462
|
+
return;
|
|
463
|
+
}
|
|
440
464
|
throw error;
|
|
441
465
|
}
|
|
442
466
|
}
|
|
@@ -473,6 +497,13 @@ class ConversationService extends commons_1.TypedEventEmitter {
|
|
|
473
497
|
this.logger.info('Tried to update key material for a broken MLS conversation, initiating reset', error);
|
|
474
498
|
return this.handleBrokenMLSConversation(conversation.qualified_id);
|
|
475
499
|
}
|
|
500
|
+
if ((0, CoreCryptoMLSError_1.isMLSStaleMessageError)(error)) {
|
|
501
|
+
this.logger.info('Tried to update key material for a stale MLS conversation, recovering by joining with external commit', {
|
|
502
|
+
error,
|
|
503
|
+
groupId,
|
|
504
|
+
});
|
|
505
|
+
await this.recoverMLSGroupFromEpochMismatch(conversation.qualified_id);
|
|
506
|
+
}
|
|
476
507
|
if ((0, CoreCryptoMLSError_1.isMLSGroupOutOfSyncError)(error)) {
|
|
477
508
|
this.logger.info('Tried to update key material for an out of sync conversation, recovering by adding missing users', {
|
|
478
509
|
error,
|
|
@@ -130,6 +130,7 @@ describe('ConversationService', () => {
|
|
|
130
130
|
getClientIdsInGroup: jest.fn(),
|
|
131
131
|
getKeyPackagesPayload: jest.fn(),
|
|
132
132
|
addUsersToExistingConversation: jest.fn(),
|
|
133
|
+
removeClientsFromConversation: jest.fn(),
|
|
133
134
|
resetKeyMaterialRenewal: jest.fn(),
|
|
134
135
|
handleMLSWelcomeMessageEvent: jest.fn(),
|
|
135
136
|
};
|
|
@@ -170,6 +171,80 @@ describe('ConversationService', () => {
|
|
|
170
171
|
});
|
|
171
172
|
});
|
|
172
173
|
});
|
|
174
|
+
describe('removeUsersFromMLSConversation', () => {
|
|
175
|
+
it('recovers and retries when stale-message occurs during remove users commit upload', async () => {
|
|
176
|
+
const [conversationService, { apiClient, mlsService }] = await buildConversationService();
|
|
177
|
+
const mockGroupId = 'groupId-stale-remove';
|
|
178
|
+
const mockConversationId = { id: PayloadHelper.getUUID(), domain: 'staging.zinfra.io' };
|
|
179
|
+
const qualifiedUserIds = [
|
|
180
|
+
{ id: 'test-id-1', domain: 'test-domain' },
|
|
181
|
+
{ id: 'test-id-2', domain: 'test-domain' },
|
|
182
|
+
];
|
|
183
|
+
const staleMessageError = {
|
|
184
|
+
type: core_crypto_1.ErrorType.Mls,
|
|
185
|
+
context: {
|
|
186
|
+
type: core_crypto_1.MlsErrorType.MessageRejected,
|
|
187
|
+
context: {
|
|
188
|
+
reason: (0, CoreCryptoMLSError_1.serializeAbortReason)({ message: CoreCryptoMLSError_1.UPLOAD_COMMIT_BUNDLE_ABORT_REASONS.MLS_STALE_MESSAGE }),
|
|
189
|
+
},
|
|
190
|
+
},
|
|
191
|
+
};
|
|
192
|
+
// First removal attempt fails with stale, second succeeds
|
|
193
|
+
jest
|
|
194
|
+
.spyOn(mlsService, 'removeClientsFromConversation')
|
|
195
|
+
.mockRejectedValueOnce(staleMessageError)
|
|
196
|
+
.mockResolvedValueOnce(undefined);
|
|
197
|
+
const remoteEpoch = 6;
|
|
198
|
+
const localEpoch = 5;
|
|
199
|
+
jest.spyOn(mlsService, 'conversationExists').mockResolvedValueOnce(true);
|
|
200
|
+
jest.spyOn(mlsService, 'getEpoch').mockResolvedValueOnce(localEpoch);
|
|
201
|
+
jest.spyOn(apiClient.api.conversation, 'getConversation').mockResolvedValue({
|
|
202
|
+
qualified_id: mockConversationId,
|
|
203
|
+
protocol: conversation_1.ConversationProtocol.MLS,
|
|
204
|
+
epoch: remoteEpoch,
|
|
205
|
+
group_id: mockGroupId,
|
|
206
|
+
});
|
|
207
|
+
await conversationService.removeUsersFromMLSConversation({
|
|
208
|
+
groupId: mockGroupId,
|
|
209
|
+
conversationId: mockConversationId,
|
|
210
|
+
qualifiedUserIds,
|
|
211
|
+
});
|
|
212
|
+
expect(conversationService.joinByExternalCommit).toHaveBeenCalledWith(mockConversationId);
|
|
213
|
+
expect(mlsService.removeClientsFromConversation).toHaveBeenCalledTimes(2);
|
|
214
|
+
expect(mlsService.resetKeyMaterialRenewal).toHaveBeenCalledWith(mockGroupId);
|
|
215
|
+
});
|
|
216
|
+
});
|
|
217
|
+
describe('joinByExternalCommit', () => {
|
|
218
|
+
it('retries join when stale-message occurs during external commit join', async () => {
|
|
219
|
+
const [conversationService, { apiClient, mlsService }] = await buildConversationService();
|
|
220
|
+
const conversationId = { id: 'conv-join-stale', domain: 'staging.zinfra.io' };
|
|
221
|
+
const staleMessageError = {
|
|
222
|
+
type: core_crypto_1.ErrorType.Mls,
|
|
223
|
+
context: {
|
|
224
|
+
type: core_crypto_1.MlsErrorType.MessageRejected,
|
|
225
|
+
context: {
|
|
226
|
+
reason: (0, CoreCryptoMLSError_1.serializeAbortReason)({ message: CoreCryptoMLSError_1.UPLOAD_COMMIT_BUNDLE_ABORT_REASONS.MLS_STALE_MESSAGE }),
|
|
227
|
+
},
|
|
228
|
+
},
|
|
229
|
+
};
|
|
230
|
+
jest
|
|
231
|
+
.spyOn(mlsService, 'joinByExternalCommit')
|
|
232
|
+
.mockRejectedValueOnce(staleMessageError)
|
|
233
|
+
.mockResolvedValueOnce(undefined);
|
|
234
|
+
const remoteEpoch = 10;
|
|
235
|
+
const localEpoch = 9;
|
|
236
|
+
jest.spyOn(mlsService, 'conversationExists').mockResolvedValueOnce(true);
|
|
237
|
+
jest.spyOn(mlsService, 'getEpoch').mockResolvedValueOnce(localEpoch);
|
|
238
|
+
jest.spyOn(apiClient.api.conversation, 'getConversation').mockResolvedValueOnce({
|
|
239
|
+
qualified_id: conversationId,
|
|
240
|
+
protocol: conversation_1.ConversationProtocol.MLS,
|
|
241
|
+
epoch: remoteEpoch,
|
|
242
|
+
group_id: 'gid-join-stale',
|
|
243
|
+
});
|
|
244
|
+
await conversationService.joinByExternalCommit(conversationId);
|
|
245
|
+
expect(mlsService.joinByExternalCommit).toHaveBeenCalledTimes(2);
|
|
246
|
+
});
|
|
247
|
+
});
|
|
173
248
|
describe('"send MLS"', () => {
|
|
174
249
|
const groupId = PayloadHelper.getUUID();
|
|
175
250
|
const messages = [
|
|
@@ -194,6 +269,43 @@ describe('ConversationService', () => {
|
|
|
194
269
|
expect(result.state).toBe(__1.MessageSendingState.OUTGOING_SENT);
|
|
195
270
|
});
|
|
196
271
|
});
|
|
272
|
+
it('rejoins a MLS group when stale-message error occurs during commit bundle upload', async () => {
|
|
273
|
+
const [conversationService, { apiClient, mlsService }] = await buildConversationService();
|
|
274
|
+
const mockGroupId = 'AAEAAH87aajaQ011i+rNLmwpy0sAZGl5YS53aXJlamxpbms=';
|
|
275
|
+
const mockConversationId = { id: 'mockConversationId', domain: 'staging.zinfra.io' };
|
|
276
|
+
const mockedMessage = MessageBuilder.buildTextMessage({ text: 'test' });
|
|
277
|
+
const staleMessageError = new conversation_1.MLSStaleMessageError('', http_1.BackendErrorLabel.MLS_STALE_MESSAGE, http_status_codes_1.StatusCodes.CONFLICT);
|
|
278
|
+
// First attempt to upload commit bundle fails with stale-message, second attempt succeeds
|
|
279
|
+
jest
|
|
280
|
+
.spyOn(mlsService, 'commitPendingProposals')
|
|
281
|
+
.mockRejectedValueOnce(staleMessageError)
|
|
282
|
+
.mockResolvedValueOnce(undefined);
|
|
283
|
+
const remoteEpoch = 5;
|
|
284
|
+
const localEpoch = 4;
|
|
285
|
+
jest.spyOn(mlsService, 'conversationExists').mockResolvedValueOnce(true);
|
|
286
|
+
jest.spyOn(mlsService, 'getEpoch').mockResolvedValueOnce(localEpoch);
|
|
287
|
+
jest.spyOn(apiClient.api.conversation, 'getConversation').mockResolvedValueOnce({
|
|
288
|
+
qualified_id: mockConversationId,
|
|
289
|
+
protocol: conversation_1.ConversationProtocol.MLS,
|
|
290
|
+
epoch: remoteEpoch,
|
|
291
|
+
group_id: mockGroupId,
|
|
292
|
+
});
|
|
293
|
+
await conversationService.send({
|
|
294
|
+
protocol: conversation_1.ConversationProtocol.MLS,
|
|
295
|
+
groupId: mockGroupId,
|
|
296
|
+
payload: mockedMessage,
|
|
297
|
+
conversationId: mockConversationId,
|
|
298
|
+
});
|
|
299
|
+
// Recovery via external commit should have been triggered
|
|
300
|
+
expect(conversationService.joinByExternalCommit).toHaveBeenCalledWith(mockConversationId);
|
|
301
|
+
expect(conversationService.emit).toHaveBeenCalledWith('MLSConversationRecovered', {
|
|
302
|
+
conversationId: mockConversationId,
|
|
303
|
+
});
|
|
304
|
+
// Because the failure happened before posting the message, postMlsMessage should be called only once (after recovery)
|
|
305
|
+
expect(apiClient.api.conversation.postMlsMessage).toHaveBeenCalledTimes(1);
|
|
306
|
+
// commitPendingProposals is called twice: first fails, second succeeds
|
|
307
|
+
expect(mlsService.commitPendingProposals).toHaveBeenCalledTimes(2);
|
|
308
|
+
});
|
|
197
309
|
it('rejoins a MLS group when failed encrypting MLS message', async () => {
|
|
198
310
|
const [conversationService, { apiClient, mlsService }] = await buildConversationService();
|
|
199
311
|
const mockGroupId = 'AAEAAH87aajaQ011i+rNLmwpy0sAZGl5YS53aXJlamxpbms=';
|
|
@@ -599,6 +711,52 @@ describe('ConversationService', () => {
|
|
|
599
711
|
});
|
|
600
712
|
expect(failedToAdd).toEqual([keysClaimingFailure]);
|
|
601
713
|
});
|
|
714
|
+
it('recovers and retries when stale-message occurs during add users commit upload', async () => {
|
|
715
|
+
const [conversationService, { apiClient, mlsService }] = await buildConversationService();
|
|
716
|
+
const mockGroupId = 'groupId-stale-add';
|
|
717
|
+
const mockConversationId = { id: PayloadHelper.getUUID(), domain: 'local.wire.com' };
|
|
718
|
+
const otherUsersToAdd = Array(2)
|
|
719
|
+
.fill(0)
|
|
720
|
+
.map(() => ({ id: PayloadHelper.getUUID(), domain: 'local.wire.com' }));
|
|
721
|
+
const qualifiedUsers = [...otherUsersToAdd];
|
|
722
|
+
const staleMessageError = {
|
|
723
|
+
type: core_crypto_1.ErrorType.Mls,
|
|
724
|
+
context: {
|
|
725
|
+
type: core_crypto_1.MlsErrorType.MessageRejected,
|
|
726
|
+
context: {
|
|
727
|
+
reason: (0, CoreCryptoMLSError_1.serializeAbortReason)({ message: CoreCryptoMLSError_1.UPLOAD_COMMIT_BUNDLE_ABORT_REASONS.MLS_STALE_MESSAGE }),
|
|
728
|
+
},
|
|
729
|
+
},
|
|
730
|
+
};
|
|
731
|
+
const getKPSpy = jest.spyOn(mlsService, 'getKeyPackagesPayload');
|
|
732
|
+
getKPSpy.mockResolvedValue({
|
|
733
|
+
keyPackages: [new Uint8Array(0)],
|
|
734
|
+
failures: [],
|
|
735
|
+
});
|
|
736
|
+
// Simulate commit upload failing once with stale, then succeeding
|
|
737
|
+
jest
|
|
738
|
+
.spyOn(mlsService, 'addUsersToExistingConversation')
|
|
739
|
+
.mockRejectedValueOnce(staleMessageError)
|
|
740
|
+
.mockResolvedValueOnce(undefined);
|
|
741
|
+
const remoteEpoch = 5;
|
|
742
|
+
const localEpoch = 4;
|
|
743
|
+
jest.spyOn(mlsService, 'conversationExists').mockResolvedValueOnce(true);
|
|
744
|
+
jest.spyOn(mlsService, 'getEpoch').mockResolvedValueOnce(localEpoch);
|
|
745
|
+
const getConvSpy = jest.spyOn(apiClient.api.conversation, 'getConversation');
|
|
746
|
+
getConvSpy.mockResolvedValue({
|
|
747
|
+
qualified_id: mockConversationId,
|
|
748
|
+
protocol: conversation_1.ConversationProtocol.MLS,
|
|
749
|
+
epoch: remoteEpoch,
|
|
750
|
+
group_id: mockGroupId,
|
|
751
|
+
});
|
|
752
|
+
await conversationService.addUsersToMLSConversation({
|
|
753
|
+
qualifiedUsers,
|
|
754
|
+
groupId: mockGroupId,
|
|
755
|
+
conversationId: mockConversationId,
|
|
756
|
+
});
|
|
757
|
+
expect(conversationService.joinByExternalCommit).toHaveBeenCalledWith(mockConversationId);
|
|
758
|
+
expect(mlsService.addUsersToExistingConversation).toHaveBeenCalledTimes(2);
|
|
759
|
+
});
|
|
602
760
|
});
|
|
603
761
|
describe('tryEstablishingMLSGroup', () => {
|
|
604
762
|
it('should add all the users to a MLS group after group was established by the self client', async () => {
|
|
@@ -746,6 +904,38 @@ describe('ConversationService', () => {
|
|
|
746
904
|
await Promise.allSettled([p1, p2]);
|
|
747
905
|
expect(resetSpy).toHaveBeenCalledTimes(1);
|
|
748
906
|
});
|
|
907
|
+
it('handles stale-message by rejoining via external commit and emits recovery event', async () => {
|
|
908
|
+
const [conversationService, { apiClient, mlsService }] = await buildConversationService();
|
|
909
|
+
const groupId = 'group-stale';
|
|
910
|
+
const qualified_id = { id: 'conv-stale', domain: 'staging.zinfra.io' };
|
|
911
|
+
jest.spyOn(apiClient.api.conversation, 'getConversationList').mockResolvedValueOnce({
|
|
912
|
+
found: [{ group_id: groupId, qualified_id, protocol: conversation_1.ConversationProtocol.MLS, epoch: 2 }],
|
|
913
|
+
});
|
|
914
|
+
const handler = getKeyMaterialFailureHandler(mlsService);
|
|
915
|
+
const staleMessageError = {
|
|
916
|
+
type: core_crypto_1.ErrorType.Mls,
|
|
917
|
+
context: {
|
|
918
|
+
type: core_crypto_1.MlsErrorType.MessageRejected,
|
|
919
|
+
context: {
|
|
920
|
+
reason: (0, CoreCryptoMLSError_1.serializeAbortReason)({ message: CoreCryptoMLSError_1.UPLOAD_COMMIT_BUNDLE_ABORT_REASONS.MLS_STALE_MESSAGE }),
|
|
921
|
+
},
|
|
922
|
+
},
|
|
923
|
+
};
|
|
924
|
+
const remoteEpoch = 3;
|
|
925
|
+
const localEpoch = 2;
|
|
926
|
+
jest.spyOn(mlsService, 'conversationExists').mockResolvedValueOnce(true);
|
|
927
|
+
jest.spyOn(mlsService, 'getEpoch').mockResolvedValueOnce(localEpoch);
|
|
928
|
+
jest.spyOn(apiClient.api.conversation, 'getConversation').mockResolvedValueOnce({
|
|
929
|
+
qualified_id,
|
|
930
|
+
protocol: conversation_1.ConversationProtocol.MLS,
|
|
931
|
+
epoch: remoteEpoch,
|
|
932
|
+
group_id: groupId,
|
|
933
|
+
});
|
|
934
|
+
await handler({ error: staleMessageError, groupId });
|
|
935
|
+
// Expect a rejoin on stale and a recovery event
|
|
936
|
+
expect(conversationService.joinByExternalCommit).toHaveBeenCalledWith(qualified_id);
|
|
937
|
+
expect(conversationService.emit).toHaveBeenCalledWith('MLSConversationRecovered', { conversationId: qualified_id });
|
|
938
|
+
});
|
|
749
939
|
});
|
|
750
940
|
describe('groupIdConversationMap cache', () => {
|
|
751
941
|
function makeConversation(group_id, id) {
|
package/package.json
CHANGED