@wireapp/core 46.39.12 → 46.40.1

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":"AAmBA,OAAO,EACL,YAAY,EACZ,2BAA2B,EAC3B,WAAW,EACX,eAAe,EACf,oBAAoB,EAEpB,mBAAmB,EACnB,eAAe,EACf,kBAAkB,EAInB,MAAM,sCAAsC,CAAC;AAE9C,OAAO,EACL,YAAY,EAIZ,4BAA4B,EAE7B,MAAM,+BAA+B,CAAC;AACvC,OAAO,EAAC,WAAW,EAAC,MAAM,8BAA8B,CAAC;AACzD,OAAO,EAAC,GAAG,EAAC,MAAM,oCAAoC,CAAC;AAGvD,OAAO,EAAC,SAAS,EAAC,MAAM,qBAAqB,CAAC;AAC9C,OAAO,EAAa,iBAAiB,EAAC,MAAM,kBAAkB,CAAC;AAY/D,OAAO,EACL,cAAc,EACd,8BAA8B,EAE9B,oBAAoB,EACpB,UAAU,EACX,MAAM,6BAA6B,CAAC;AAErC,OAAO,EAAC,YAAY,EAAuB,iBAAiB,EAAC,MAAM,qBAAqB,CAAC;AACzF,OAAO,EAAC,UAAU,EAAE,gBAAgB,EAAC,MAAM,8BAA8B,CAAC;AAG1E,OAAO,EAAkC,cAAc,EAAC,MAAM,kCAAkC,CAAC;AACjG,OAAO,EACL,mCAAmC,EACnC,wBAAwB,EACzB,MAAM,sEAAsE,CAAC;AAC9E,OAAO,EAAsB,kBAAkB,EAAC,MAAM,oBAAoB,CAAC;AAC3E,OAAO,EAAC,YAAY,EAAC,MAAM,sBAAsB,CAAC;AAIlD,OAAO,EAAC,sBAAsB,EAAC,MAAM,kDAAkD,CAAC;AAExF,KAAK,MAAM,GAAG;IACZ,wBAAwB,EAAE;QAAC,cAAc,EAAE,WAAW,CAAA;KAAC,CAAC;IACxD,CAAC,gBAAgB,CAAC,qBAAqB,CAAC,EAAE;QAAC,MAAM,EAAE,GAAG,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAC,CAAC;CACvE,CAAC;AAEF,qBAAa,mBAAoB,SAAQ,iBAAiB,CAAC,MAAM,CAAC;IAK9D,OAAO,CAAC,QAAQ,CAAC,SAAS;IAC1B,OAAO,CAAC,QAAQ,CAAC,cAAc;IAC/B,OAAO,CAAC,QAAQ,CAAC,YAAY;IAC7B,OAAO,CAAC,QAAQ,CAAC,yBAAyB;IAI1C,OAAO,CAAC,QAAQ,CAAC,sBAAsB;IACvC,OAAO,CAAC,QAAQ,CAAC,gCAAgC;IACjD,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAC;IAb/B,SAAgB,YAAY,EAAE,YAAY,CAAC;IAC3C,OAAO,CAAC,QAAQ,CAAC,MAAM,CAA6D;gBAGjE,SAAS,EAAE,SAAS,EACpB,cAAc,EAAE,cAAc,EAC9B,YAAY,EAAE,YAAY,EAC1B,yBAAyB,EAAE,CAC1C,cAAc,EAAE,WAAW,EAC3B,iBAAiB,CAAC,EAAE,kBAAkB,KACnC,OAAO,CAAC,MAAM,GAAG,SAAS,CAAC,EACf,sBAAsB,EAAE,sBAAsB,EAC9C,gCAAgC,EAAE,MAAM,OAAO,CAAC,OAAO,CAAC,EACxD,WAAW,CAAC,EAAE,UAAU,YAAA;IAY3C,IAAI,UAAU,IAAI,UAAU,CAK3B;IAED;;;;;OAKG;IACU,2BAA2B,CAAC,cAAc,EAAE,WAAW,GAAG,OAAO,CAAC,oBAAoB,CAAC;IAkBpG;;;;;;;;;;OAUG;IACU,yBAAyB,CAAC,gBAAgB,EAAE,eAAe;IAI3D,eAAe,CAAC,cAAc,EAAE,WAAW,GAAG,OAAO,CAAC,YAAY,CAAC;IAInE,sBAAsB,IAAI,OAAO,CAAC,eAAe,CAAC;IAIlD,gBAAgB,CAAC,eAAe,CAAC,EAAE,WAAW,EAAE,GAAG,OAAO,CAAC,mBAAmB,CAAC;IAQ/E,6BAA6B,CAAC,MAAM,EAAE,mCAAmC;IAIzE,0BAA0B,CACrC,cAAc,EAAE,WAAW,EAC3B,MAAM,EAAE,WAAW,GAClB,OAAO,CAAC,4BAA4B,CAAC;IAIxC;;;OAGG;IACU,IAAI,CAAC,MAAM,EAAE,GAAG,CAAC,oBAAoB,EAAE,wBAAwB,CAAC,GAAG,OAAO,CAAC,UAAU,CAAC;IAO5F,eAAe,CAAC,cAAc,EAAE,WAAW,GAAG,OAAO,CAAC,IAAI,CAAC;IAI3D,cAAc,CAAC,cAAc,EAAE,WAAW,GAAG,OAAO,CAAC,IAAI,CAAC;IAIjE;;;;OAIG;IACH,SAAgB,qBAAqB,mBAA0B,WAAW,KAAG,OAAO,CAAC,IAAI,CAAC,CAExF;IAEF;;;OAGG;IACH,SAAgB,+BAA+B,mBAA0B,WAAW,KAAG,OAAO,CAAC,IAAI,CAAC,CAElG;IAEF;;OAEG;IACH,gBAAgB,IAAI,OAAO;IAIpB,0BAA0B,CAC/B,cAAc,EAAE,WAAW,EAC3B,MAAM,EAAE,WAAW,EACnB,aAAa,EAAE,MAAM,GAAG,IAAI,GAC3B,OAAO,CAAC,IAAI,CAAC;IAaT,yBAAyB,CAC9B,cAAc,EAAE,WAAW,EAC3B,QAAQ,EAAE,OAAO,EACjB,gBAAgB,GAAE,MAAM,GAAG,IAAiB,GAC3C,OAAO,CAAC,IAAI,CAAC;IAaT,yBAAyB,CAC9B,cAAc,EAAE,WAAW,EAC3B,MAAM,EAAE,WAAW,EACnB,gBAAgB,EAAE,2BAA2B,GAAG,MAAM,GACrD,OAAO,CAAC,IAAI,CAAC;IAMhB;;;;OAIG;IAEH;;;OAGG;IACU,qBAAqB,CAChC,gBAAgB,EAAE,eAAe,EACjC,UAAU,EAAE,WAAW,EACvB,YAAY,EAAE,MAAM,GACnB,OAAO,CAAC,8BAA8B,CAAC;IAuB1C;;;;;;;;;OASG;YACW,2BAA2B;IA2BzC;;;OAGG;IACU,6BAA6B,CACxC,OAAO,EAAE,MAAM,EACf,YAAY,EAAE,WAAW,EAAE,EAC3B,UAAU,EAAE,WAAW,EACvB,YAAY,EAAE,MAAM,EACpB,uBAAuB,EAAE,WAAW,GACnC,OAAO,CAAC,8BAA8B,CAAC;YAiB5B,cAAc;IAgF5B;;;;;;OAMG;IACU,yBAAyB,CAAC,EACrC,cAAc,EACd,OAAO,EACP,cAAc,EACd,WAAkB,GACnB,EAAE,QAAQ,CAAC,cAAc,CAAC,GAAG;QAAC,WAAW,CAAC,EAAE,OAAO,CAAA;KAAC,GAAG,OAAO,CAAC,8BAA8B,CAAC;IAqClF,8BAA8B,CAAC,EAC1C,OAAO,EACP,cAAc,EACd,gBAAgB,EAChB,WAAkB,GACnB,EAAE,iBAAiB,GAAG;QAAC,WAAW,CAAC,EAAE,OAAO,CAAA;KAAC,GAAG,OAAO,CAAC,YAAY,CAAC;IAsCzD,oBAAoB,CAAC,cAAc,EAAE,WAAW,EAAE,WAAW,UAAO,GAAG,OAAO,CAAC,IAAI,CAAC;YAiBnF,oBAAoB;IAiElC;;;OAGG;IACU,qBAAqB,CAAC,OAAO,EAAE,MAAM;IAIlD;;;;OAIG;IACU,4BAA4B,CAAC,OAAO,EAAE,MAAM;IAI5C,mBAAmB,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;YAIlD,YAAY;IAYb,gCAAgC;IAe7C;;;OAGG;YACW,kCAAkC;IA2BhD;;;OAGG;YACW,+BAA+B;IAqB7C;;;;;;;OAOG;YACW,gBAAgB;IAQ9B;;;OAGG;IACG,sBAAsB,CAAC,MAAM,EAAE,WAAW;IAShD;;;;;;;OAOG;IACH,SAAgB,4BAA4B,YACjC,MAAM,YACL;QAAC,IAAI,EAAE,WAAW,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAC,eAChC,WAAW,4BAEvB,OAAO,CAAC,eAAe,CAAC,CAwDzB;IAEF;;;;;;;;OAQG;IACU,uBAAuB,CAAC,EACnC,OAAO,EACP,cAAc,EACd,UAAU,EACV,cAAc,GACf,EAAE;QACD,OAAO,EAAE,MAAM,CAAC;QAChB,cAAc,EAAE,WAAW,CAAC;QAC5B,UAAU,EAAE,WAAW,CAAC;QACxB,cAAc,EAAE,WAAW,EAAE,CAAC;KAC/B,GAAG,OAAO,CAAC,IAAI,CAAC;YAkCH,wBAAwB;YAsBxB,gCAAgC;YAyBhC,4BAA4B;IA2B1C,OAAO,CAAC,2BAA2B;IAmBnC;;;OAGG;YACW,uCAAuC;YA4BvC,wBAAwB;YAIxB,yBAAyB;IAKvC;;;;OAIG;IACU,WAAW,CAAC,KAAK,EAAE,YAAY,GAAG,OAAO,CAAC,kBAAkB,CAAC;CAoB3E"}
1
+ {"version":3,"file":"ConversationService.d.ts","sourceRoot":"","sources":["../../../src/conversation/ConversationService/ConversationService.ts"],"names":[],"mappings":"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"}
@@ -263,9 +263,9 @@ class ConversationService extends commons_1.TypedEventEmitter {
263
263
  };
264
264
  }
265
265
  catch (error) {
266
- this.logger.error('Failed to send MLS message', { error, groupId });
266
+ this.logger.warn('Failed to send MLS message', { error, groupId });
267
267
  if (!shouldRetry) {
268
- this.logger.warn("Tried to send MLS message but it's still failing after recovery", {
268
+ this.logger.error("Tried to send MLS message but it's still failing after recovery", {
269
269
  error,
270
270
  groupId,
271
271
  });
@@ -280,7 +280,6 @@ class ConversationService extends commons_1.TypedEventEmitter {
280
280
  groupId,
281
281
  });
282
282
  await this.handleBrokenMLSConversation(conversationId);
283
- return this.sendMLSMessage(params, false);
284
283
  }
285
284
  /**
286
285
  * We may have the same error from core-crypto or from the backend error mapper
@@ -293,13 +292,19 @@ class ConversationService extends commons_1.TypedEventEmitter {
293
292
  groupId,
294
293
  });
295
294
  await this.recoverMLSGroupFromEpochMismatch(conversationId);
296
- return this.sendMLSMessage(params, false);
297
295
  }
298
- this.logger.error('Failed to send MLS message, error did not match any known patterns, rethrowing the error', {
299
- error,
300
- groupId,
301
- });
302
- throw error;
296
+ if (error instanceof conversation_1.MLSGroupOutOfSyncError) {
297
+ this.logger.info('Failed to send MLS message because of group out of sync, recovering by adding missing users', {
298
+ error,
299
+ groupId,
300
+ });
301
+ await this.addUsersToMLSConversation({
302
+ groupId,
303
+ conversationId,
304
+ qualifiedUsers: error.missing_users,
305
+ });
306
+ }
307
+ return this.sendMLSMessage(params, false);
303
308
  }
304
309
  }
305
310
  /**
@@ -311,6 +316,7 @@ class ConversationService extends commons_1.TypedEventEmitter {
311
316
  */
312
317
  async addUsersToMLSConversation({ qualifiedUsers, groupId, conversationId, shouldRetry = true, }) {
313
318
  try {
319
+ this.logger.info(`Adding users to MLS conversation`, { groupId, conversationId, qualifiedUsers });
314
320
  const exisitingClientIdsInGroup = await this.mlsService.getClientIdsInGroup(groupId);
315
321
  const conversation = await this.getConversation(conversationId);
316
322
  const { keyPackages, failures: keysClaimingFailures } = await this.mlsService.getKeyPackagesPayload(qualifiedUsers, exisitingClientIdsInGroup);
@@ -326,6 +332,7 @@ class ConversationService extends commons_1.TypedEventEmitter {
326
332
  };
327
333
  }
328
334
  catch (error) {
335
+ this.logger.warn('Failed to add users to MLS conversation', { error, groupId, conversationId });
329
336
  if (mls_1.MLSService.isBrokenMLSConversationError(error)) {
330
337
  if (!shouldRetry) {
331
338
  this.logger.warn("Tried to add users to MLS conversation but it's still broken after reset", error);
@@ -510,8 +517,14 @@ class ConversationService extends commons_1.TypedEventEmitter {
510
517
  async hasEpochMismatch(groupId, epoch) {
511
518
  const isEstablished = await this.mlsGroupExistsLocally(groupId);
512
519
  const doesEpochMatch = isEstablished && (await this.matchesEpoch(groupId, epoch));
513
- //if conversation is not established or epoch does not match -> try to rejoin
514
- return !isEstablished || !doesEpochMatch;
520
+ // if conversation is not established or epoch does not match -> try to rejoin
521
+ const hasEpochMismatch = !isEstablished || !doesEpochMatch;
522
+ this.logger.info(`Conversation (group_id: ${groupId}) epoch mismatch check result: ${hasEpochMismatch}`, {
523
+ isEstablished,
524
+ doesEpochMatch,
525
+ epoch,
526
+ });
527
+ return hasEpochMismatch;
515
528
  }
516
529
  /**
517
530
  * Get a MLS 1:1-conversation with a given user.
@@ -628,6 +641,7 @@ class ConversationService extends commons_1.TypedEventEmitter {
628
641
  }
629
642
  }
630
643
  async recoverMLSGroupFromEpochMismatch(conversationId, subconversationId) {
644
+ this.logger.info(`Recovering MLS group from epoch mismatch`, { conversationId, subconversationId });
631
645
  if (subconversationId) {
632
646
  const parentGroupId = await this.groupIdFromConversationId(conversationId);
633
647
  const subconversation = await this.apiClient.api.conversation.getSubconversation(conversationId, subconversationId);
@@ -222,6 +222,34 @@ describe('ConversationService', () => {
222
222
  });
223
223
  expect(apiClient.api.conversation.postMlsMessage).toHaveBeenCalledTimes(2);
224
224
  });
225
+ it('adds missing users to MLS group and retries when group is out of sync during send', async () => {
226
+ const [conversationService, { apiClient }] = await buildConversationService();
227
+ const mockGroupId = 'AAEAAH87aajaQ011i+rNLmwpy0sAZGl5YS53aXJlamxpbms=';
228
+ const mockConversationId = { id: 'mockConversationId', domain: 'staging.zinfra.io' };
229
+ const mockedMessage = MessageBuilder.buildTextMessage({ text: 'test' });
230
+ const missingUsers = [
231
+ { id: 'user-1', domain: 'staging.zinfra.io' },
232
+ { id: 'user-2', domain: 'staging.zinfra.io' },
233
+ ];
234
+ const outOfSyncError = new conversation_1.MLSGroupOutOfSyncError(http_status_codes_1.StatusCodes.CONFLICT, missingUsers, http_1.BackendErrorLabel.MLS_GROUP_OUT_OF_SYNC);
235
+ // First send fails with out-of-sync, second succeeds via default mock
236
+ jest.spyOn(apiClient.api.conversation, 'postMlsMessage').mockRejectedValueOnce(outOfSyncError);
237
+ const addUsersSpy = jest
238
+ .spyOn(conversationService, 'addUsersToMLSConversation')
239
+ .mockResolvedValueOnce({ conversation: { members: { others: [] } } });
240
+ await conversationService.send({
241
+ protocol: conversation_1.ConversationProtocol.MLS,
242
+ groupId: mockGroupId,
243
+ payload: mockedMessage,
244
+ conversationId: mockConversationId,
245
+ });
246
+ expect(addUsersSpy).toHaveBeenCalledWith({
247
+ groupId: mockGroupId,
248
+ conversationId: mockConversationId,
249
+ qualifiedUsers: missingUsers,
250
+ });
251
+ expect(apiClient.api.conversation.postMlsMessage).toHaveBeenCalledTimes(2);
252
+ });
225
253
  });
226
254
  describe('handleConversationsEpochMismatch', () => {
227
255
  beforeEach(() => {
@@ -1 +1 @@
1
- {"version":3,"file":"SubconversationService.d.ts","sourceRoot":"","sources":["../../../src/conversation/SubconversationService/SubconversationService.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"SubconversationService.d.ts","sourceRoot":"","sources":["../../../src/conversation/SubconversationService/SubconversationService.ts"],"names":[],"mappings":"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"}
@@ -52,6 +52,7 @@ class SubconversationService extends commons_1.TypedEventEmitter {
52
52
  */
53
53
  async joinConferenceSubconversation(conversationId, groupId, shouldRetry = true) {
54
54
  try {
55
+ this.logger.info('Joining conference subconversation', { conversationId, groupId });
55
56
  const { group_id: subconversationGroupId, epoch: subconversationEpoch, epoch_timestamp: subconversationEpochTimestamp, subconv_id: subconversationId, } = await this.getConferenceSubconversation(conversationId);
56
57
  // We store the mapping between the subconversation and the parent conversation
57
58
  await this.saveSubconversationGroupId(conversationId, subconversationId, subconversationGroupId);
@@ -81,6 +82,7 @@ class SubconversationService extends commons_1.TypedEventEmitter {
81
82
  return { groupId: subconversationGroupId, epoch };
82
83
  }
83
84
  catch (error) {
85
+ this.logger.error('Failed to join conference subconversation', { conversationId, groupId, error, shouldRetry });
84
86
  if (shouldRetry) {
85
87
  return this.joinConferenceSubconversation(conversationId, groupId, false);
86
88
  }
@@ -93,71 +95,132 @@ class SubconversationService extends commons_1.TypedEventEmitter {
93
95
  * @param conversationId Id of the parent conversation which subconversation we want to leave
94
96
  */
95
97
  async leaveConferenceSubconversation(conversationId) {
98
+ this.logger.info('Leaving conference subconversation', { conversationId });
96
99
  const subconversationGroupId = await this.getSubconversationGroupId(conversationId, conversation_1.SUBCONVERSATION_ID.CONFERENCE);
97
100
  if (!subconversationGroupId) {
101
+ this.logger.warn('No subconversation groupId found when leaving conference subconversation', { conversationId });
98
102
  return;
99
103
  }
100
104
  const doesGroupExistLocally = await this.mlsService.conversationExists(subconversationGroupId);
101
105
  if (!doesGroupExistLocally) {
102
106
  // If the subconversation was known by a client but is does not exist locally, we can remove it from the store.
107
+ this.logger.info('Subconversation not found locally; clearing stored mapping', {
108
+ conversationId,
109
+ subconversationId: conversation_1.SUBCONVERSATION_ID.CONFERENCE,
110
+ subconversationGroupId,
111
+ });
103
112
  return this.clearSubconversationGroupId(conversationId, conversation_1.SUBCONVERSATION_ID.CONFERENCE);
104
113
  }
105
114
  try {
106
115
  await this.apiClient.api.conversation.deleteSubconversationSelf(conversationId, conversation_1.SUBCONVERSATION_ID.CONFERENCE);
107
116
  }
108
117
  catch (error) {
109
- this.logger.error(`Failed to leave conference subconversation:`, error);
118
+ this.logger.error('Failed to leave conference subconversation', {
119
+ conversationId,
120
+ subconversationId: conversation_1.SUBCONVERSATION_ID.CONFERENCE,
121
+ subconversationGroupId,
122
+ error,
123
+ });
110
124
  }
111
125
  await this.mlsService.wipeConversation(subconversationGroupId);
112
126
  // once we've left the subconversation, we can remove it from the store
127
+ this.logger.info('Clearing stored mapping after leaving conference subconversation', {
128
+ conversationId,
129
+ subconversationId: conversation_1.SUBCONVERSATION_ID.CONFERENCE,
130
+ subconversationGroupId,
131
+ });
113
132
  await this.clearSubconversationGroupId(conversationId, conversation_1.SUBCONVERSATION_ID.CONFERENCE);
114
133
  }
115
134
  async leaveStaleConferenceSubconversations() {
135
+ this.logger.info('Leaving all stale conference subconversations');
116
136
  const conversationIds = await this.getAllGroupIdsBySubconversationId(conversation_1.SUBCONVERSATION_ID.CONFERENCE);
117
137
  for (const { parentConversationId } of conversationIds) {
138
+ this.logger.debug('Leaving stale conference subconversation for parent conversation', {
139
+ parentConversationId,
140
+ });
118
141
  await this.leaveConferenceSubconversation(parentConversationId);
119
142
  }
120
143
  }
121
144
  async getSubconversationEpochInfo(parentConversationId, parentConversationGroupId, shouldAdvanceEpoch = false) {
145
+ this.logger.info('Getting subconversation epoch info', {
146
+ parentConversationId,
147
+ parentConversationGroupId,
148
+ shouldAdvanceEpoch,
149
+ });
122
150
  const subconversationGroupId = await this.getSubconversationGroupId(parentConversationId, conversation_1.SUBCONVERSATION_ID.CONFERENCE);
123
151
  // this method should not be called if the subconversation (and its parent conversation) is not established
124
152
  if (!subconversationGroupId) {
125
- this.logger.error(`Could not obtain epoch info for conference subconversation of conversation ${JSON.stringify(parentConversationId)}: parent or subconversation group ID is missing`);
153
+ this.logger.error('Could not obtain epoch info for conference subconversation: missing groupId', {
154
+ parentConversationId,
155
+ });
126
156
  return null;
127
157
  }
128
158
  //we don't want to react to avs callbacks when conversation was not yet established
129
159
  const doesMLSGroupExist = await this.mlsService.conversationExists(subconversationGroupId);
130
160
  if (!doesMLSGroupExist) {
161
+ this.logger.debug('Subconversation MLS group does not exist locally; skipping epoch info', {
162
+ parentConversationId,
163
+ parentConversationGroupId,
164
+ subconversationGroupId,
165
+ });
131
166
  return null;
132
167
  }
133
168
  const members = await this.generateSubconversationMembers(subconversationGroupId, parentConversationGroupId);
134
169
  if (shouldAdvanceEpoch) {
170
+ this.logger.info('Advancing epoch and renewing key material for subconversation', { subconversationGroupId });
135
171
  await this.mlsService.renewKeyMaterial(subconversationGroupId);
136
172
  }
137
173
  const epoch = Number(await this.mlsService.getEpoch(subconversationGroupId));
138
174
  const secretKey = await this.mlsService.exportSecretKey(subconversationGroupId, MLS_CONVERSATION_KEY_LENGTH);
175
+ this.logger.debug('Obtained subconversation epoch info', {
176
+ parentConversationId,
177
+ parentConversationGroupId,
178
+ subconversationGroupId,
179
+ epoch,
180
+ membersCount: members.length,
181
+ keyLength: MLS_CONVERSATION_KEY_LENGTH,
182
+ });
139
183
  return { members, epoch, keyLength: MLS_CONVERSATION_KEY_LENGTH, secretKey };
140
184
  }
141
185
  async subscribeToEpochUpdates(parentConversationId, parentConversationGroupId, findConversationByGroupId, onEpochUpdate) {
186
+ this.logger.info('Subscribing to subconversation epoch updates', {
187
+ parentConversationId,
188
+ parentConversationGroupId,
189
+ });
142
190
  const { epoch: initialEpoch, groupId: subconversationGroupId } = await this.joinConferenceSubconversation(parentConversationId, parentConversationGroupId);
143
191
  const forwardNewEpoch = async ({ groupId }) => {
192
+ this.logger.debug('Received MLS NEW_EPOCH event', { eventGroupId: groupId, subconversationGroupId });
144
193
  if (groupId !== subconversationGroupId) {
145
194
  // if the epoch update did not happen in the subconversation directly, check if it happened in the parent conversation
146
195
  const parentConversationId = findConversationByGroupId(groupId);
147
196
  if (!parentConversationId) {
197
+ this.logger.debug('Ignoring NEW_EPOCH event: could not map to parent conversation');
148
198
  return;
149
199
  }
150
200
  const foundSubconversationGroupId = await this.getSubconversationGroupId(parentConversationId, conversation_1.SUBCONVERSATION_ID.CONFERENCE);
151
201
  // if the conference subconversation of parent conversation is not known, ignore the epoch update
152
202
  if (foundSubconversationGroupId !== subconversationGroupId) {
203
+ this.logger.debug('Ignoring NEW_EPOCH event: not related to subscribed subconversation', {
204
+ eventGroupId: groupId,
205
+ foundSubconversationGroupId,
206
+ expectedSubconversationGroupId: subconversationGroupId,
207
+ });
153
208
  return;
154
209
  }
155
210
  }
156
211
  const subconversationEpochInfo = await this.getSubconversationEpochInfo(parentConversationId, parentConversationGroupId);
157
212
  if (!subconversationEpochInfo) {
213
+ this.logger.debug('No subconversation epoch info available; skipping callback', {
214
+ parentConversationId,
215
+ parentConversationGroupId,
216
+ });
158
217
  return;
159
218
  }
160
219
  const newSubconversationEpoch = Number(await this.mlsService.getEpoch(subconversationGroupId));
220
+ this.logger.info('Forwarding epoch update to subscriber', {
221
+ subconversationGroupId,
222
+ epoch: newSubconversationEpoch,
223
+ });
161
224
  return onEpochUpdate({
162
225
  ...subconversationEpochInfo,
163
226
  epoch: newSubconversationEpoch,
@@ -165,15 +228,26 @@ class SubconversationService extends commons_1.TypedEventEmitter {
165
228
  };
166
229
  this.mlsService.on(mls_1.MLSServiceEvents.NEW_EPOCH, forwardNewEpoch);
167
230
  await forwardNewEpoch({ groupId: subconversationGroupId, epoch: initialEpoch });
231
+ this.logger.info('Subscribed to MLS NEW_EPOCH events for subconversation', { subconversationGroupId });
168
232
  return () => this.mlsService.off(mls_1.MLSServiceEvents.NEW_EPOCH, forwardNewEpoch);
169
233
  }
170
234
  async removeClientFromConferenceSubconversation(conversationId, clientToRemove) {
235
+ this.logger.info('Removing client from conference subconversation', {
236
+ conversationId,
237
+ user: clientToRemove.user,
238
+ clientId: clientToRemove.clientId,
239
+ });
171
240
  const subconversationGroupId = await this.getSubconversationGroupId(conversationId, conversation_1.SUBCONVERSATION_ID.CONFERENCE);
172
241
  if (!subconversationGroupId) {
242
+ this.logger.warn('Cannot remove client: subconversation groupId missing', { conversationId });
173
243
  return;
174
244
  }
175
245
  const doesMLSGroupExist = await this.mlsService.conversationExists(subconversationGroupId);
176
246
  if (!doesMLSGroupExist) {
247
+ this.logger.debug('Cannot remove client: subconversation MLS group does not exist locally', {
248
+ conversationId,
249
+ subconversationGroupId,
250
+ });
177
251
  return;
178
252
  }
179
253
  const { user: { id: userId, domain }, clientId, } = clientToRemove;
@@ -181,23 +255,70 @@ class SubconversationService extends commons_1.TypedEventEmitter {
181
255
  const subconversationMembers = await this.mlsService.getClientIds(subconversationGroupId);
182
256
  const isSubconversationMember = subconversationMembers.some(({ userId, clientId, domain }) => (0, fullyQualifiedClientIdUtils_1.constructFullyQualifiedClientId)(userId, clientId, domain) === clientToRemoveQualifiedId);
183
257
  if (!isSubconversationMember) {
258
+ this.logger.info('Client is not a member of the subconversation; nothing to remove', {
259
+ conversationId,
260
+ subconversationGroupId,
261
+ clientToRemoveQualifiedId,
262
+ });
184
263
  return;
185
264
  }
186
- return void this.mlsService.removeClientsFromConversation(subconversationGroupId, [clientToRemoveQualifiedId]);
265
+ this.logger.info('Removing client from subconversation', {
266
+ subconversationGroupId,
267
+ clientToRemoveQualifiedId,
268
+ });
269
+ try {
270
+ await this.mlsService.removeClientsFromConversation(subconversationGroupId, [clientToRemoveQualifiedId]);
271
+ }
272
+ catch (error) {
273
+ this.logger.error('Failed to remove client from subconversation', {
274
+ subconversationGroupId,
275
+ clientToRemoveQualifiedId,
276
+ error,
277
+ });
278
+ }
187
279
  }
188
280
  async joinSubconversationByExternalCommit(conversationId, subconversation) {
189
- await this.mlsService.joinByExternalCommit(() => this.apiClient.api.conversation.getSubconversationGroupInfo(conversationId, subconversation));
281
+ try {
282
+ this.logger.info('Joining subconversation by external commit', { conversationId, subconversation });
283
+ await this.mlsService.joinByExternalCommit(() => this.apiClient.api.conversation.getSubconversationGroupInfo(conversationId, subconversation));
284
+ }
285
+ catch (error) {
286
+ this.logger.error('Failed to join subconversation by external commit', {
287
+ conversationId,
288
+ subconversation,
289
+ error,
290
+ });
291
+ throw error;
292
+ }
190
293
  }
191
294
  async getConferenceSubconversation(conversationId) {
192
- return this.apiClient.api.conversation.getSubconversation(conversationId, conversation_1.SUBCONVERSATION_ID.CONFERENCE);
295
+ this.logger.debug('Fetching conference subconversation metadata', { conversationId });
296
+ try {
297
+ return await this.apiClient.api.conversation.getSubconversation(conversationId, conversation_1.SUBCONVERSATION_ID.CONFERENCE);
298
+ }
299
+ catch (error) {
300
+ this.logger.error('Failed to fetch conference subconversation metadata', { conversationId, error });
301
+ throw error;
302
+ }
193
303
  }
194
304
  async deleteConferenceSubconversation(conversationId, data) {
195
- return this.apiClient.api.conversation.deleteSubconversation(conversationId, conversation_1.SUBCONVERSATION_ID.CONFERENCE, data);
305
+ this.logger.info('Deleting conference subconversation', { conversationId, data });
306
+ try {
307
+ return await this.apiClient.api.conversation.deleteSubconversation(conversationId, conversation_1.SUBCONVERSATION_ID.CONFERENCE, data);
308
+ }
309
+ catch (error) {
310
+ this.logger.error('Failed to delete conference subconversation', { conversationId, data, error });
311
+ throw error;
312
+ }
196
313
  }
197
314
  async generateSubconversationMembers(subconversationGroupId, parentGroupId) {
315
+ this.logger.debug('Generating subconversation members info', {
316
+ subconversationGroupId,
317
+ parentGroupId,
318
+ });
198
319
  const subconversationMemberIds = await this.mlsService.getClientIds(subconversationGroupId);
199
320
  const parentMemberIds = await this.mlsService.getClientIds(parentGroupId);
200
- return parentMemberIds.map(parentMember => {
321
+ const members = parentMemberIds.map(parentMember => {
201
322
  const isSubconversationMember = subconversationMemberIds.some(({ userId, clientId, domain }) => (0, fullyQualifiedClientIdUtils_1.constructFullyQualifiedClientId)(userId, clientId, domain) ===
202
323
  (0, fullyQualifiedClientIdUtils_1.constructFullyQualifiedClientId)(parentMember.userId, parentMember.clientId, parentMember.domain));
203
324
  return {
@@ -208,20 +329,45 @@ class SubconversationService extends commons_1.TypedEventEmitter {
208
329
  in_subconv: isSubconversationMember,
209
330
  };
210
331
  });
332
+ this.logger.debug('Generated subconversation members info', {
333
+ subconversationGroupId,
334
+ parentGroupId,
335
+ membersCount: members.length,
336
+ });
337
+ return members;
211
338
  }
212
339
  getSubconversationGroupId = async (parentConversationId, subconversationId) => {
213
340
  const foundSubconversation = await this.coreDatabase.get('subconversations', (0, subconversationUtil_1.generateSubconversationStoreKey)(parentConversationId, subconversationId));
341
+ this.logger.debug('Loaded subconversation groupId from store', {
342
+ parentConversationId,
343
+ subconversationId,
344
+ found: Boolean(foundSubconversation?.groupId),
345
+ });
214
346
  return foundSubconversation?.groupId;
215
347
  };
216
348
  getAllGroupIdsBySubconversationId = async (subconversationId) => {
349
+ this.logger.debug('Retrieving all subconversations by subconversationId', { subconversationId });
217
350
  const allSubconversations = await this.coreDatabase.getAll('subconversations');
218
351
  const foundSubconversations = allSubconversations.filter(subconversation => subconversation.subconversationId === subconversationId);
352
+ this.logger.debug('Found subconversations by id', {
353
+ subconversationId,
354
+ count: foundSubconversations.length,
355
+ });
219
356
  return foundSubconversations;
220
357
  };
221
358
  saveSubconversationGroupId = async (parentConversationId, subconversationId, groupId) => {
359
+ this.logger.debug('Saving subconversation groupId mapping', {
360
+ parentConversationId,
361
+ subconversationId,
362
+ groupId,
363
+ });
222
364
  return this.coreDatabase.put('subconversations', { parentConversationId, subconversationId, groupId }, (0, subconversationUtil_1.generateSubconversationStoreKey)(parentConversationId, subconversationId));
223
365
  };
224
366
  clearSubconversationGroupId = async (parentConversationId, subconversationId) => {
367
+ this.logger.debug('Clearing subconversation groupId mapping', {
368
+ parentConversationId,
369
+ subconversationId,
370
+ });
225
371
  return this.coreDatabase.delete('subconversations', (0, subconversationUtil_1.generateSubconversationStoreKey)(parentConversationId, subconversationId));
226
372
  };
227
373
  }
package/package.json CHANGED
@@ -11,7 +11,7 @@
11
11
  "./lib/cryptography/AssetCryptography/crypto.node": "./lib/cryptography/AssetCryptography/crypto.browser.js"
12
12
  },
13
13
  "dependencies": {
14
- "@wireapp/api-client": "^27.81.0",
14
+ "@wireapp/api-client": "^27.82.0",
15
15
  "@wireapp/commons": "^5.4.5",
16
16
  "@wireapp/core-crypto": "9.1.0",
17
17
  "@wireapp/cryptobox": "12.8.0",
@@ -61,6 +61,6 @@
61
61
  "test:coverage": "jest --coverage",
62
62
  "watch": "tsc --watch"
63
63
  },
64
- "version": "46.39.12",
65
- "gitHead": "5c163bf9fccc9529595855f48bf68f9bbf405604"
64
+ "version": "46.40.1",
65
+ "gitHead": "b1f2c021022374610797c31b73dfeb8a934b8f2d"
66
66
  }