@wireapp/core 46.0.19 → 46.1.0-hotfix-1.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.
Files changed (120) hide show
  1. package/lib/Account.js +56 -43
  2. package/lib/account/AccountService.js +0 -1
  3. package/lib/broadcast/BroadcastService.js +0 -3
  4. package/lib/client/ClientBackendRepository.js +0 -1
  5. package/lib/client/ClientDatabaseRepository.js +7 -16
  6. package/lib/client/ClientService.d.ts.map +1 -1
  7. package/lib/client/ClientService.js +13 -14
  8. package/lib/connection/ConnectionService.js +0 -1
  9. package/lib/conversation/AssetService/AssetService.d.ts +1 -0
  10. package/lib/conversation/AssetService/AssetService.d.ts.map +1 -1
  11. package/lib/conversation/AssetService/AssetService.js +6 -13
  12. package/lib/conversation/AssetService/AssetService.test.js +1 -1
  13. package/lib/conversation/ConversationService/ConversationService.d.ts.map +1 -1
  14. package/lib/conversation/ConversationService/ConversationService.js +80 -90
  15. package/lib/conversation/ConversationService/ConversationService.test.js +5 -12
  16. package/lib/conversation/ConversationService/Utility/getConversationQualifiedMembers.d.ts.map +1 -1
  17. package/lib/conversation/MessageTimer/MessageTimer.js +0 -2
  18. package/lib/conversation/SubconversationService/SubconversationService.d.ts +8 -0
  19. package/lib/conversation/SubconversationService/SubconversationService.d.ts.map +1 -1
  20. package/lib/conversation/SubconversationService/SubconversationService.js +51 -23
  21. package/lib/conversation/content/AssetContent.d.ts +1 -0
  22. package/lib/conversation/content/AssetContent.d.ts.map +1 -1
  23. package/lib/conversation/content/ContentType.js +19 -18
  24. package/lib/conversation/content/FileContent.d.ts +1 -0
  25. package/lib/conversation/content/FileContent.d.ts.map +1 -1
  26. package/lib/conversation/content/ImageContent.d.ts +1 -0
  27. package/lib/conversation/content/ImageContent.d.ts.map +1 -1
  28. package/lib/conversation/message/MessageBuilder.js +23 -22
  29. package/lib/conversation/message/MessageService.js +4 -5
  30. package/lib/conversation/message/MessageService.test.js +9 -20
  31. package/lib/conversation/message/MessageToProtoMapper.js +2 -2
  32. package/lib/conversation/message/RecipientsHelper.js +2 -1
  33. package/lib/conversation/message/TextContentBuilder.js +2 -3
  34. package/lib/conversation/message/UserClientsUtil.js +3 -2
  35. package/lib/conversation/message/messageSender.js +6 -5
  36. package/lib/cryptography/AssetCryptography/AssetCryptography.d.ts.map +1 -1
  37. package/lib/cryptography/GenericMessageMapper.js +22 -74
  38. package/lib/cryptography/MessageHashService.d.ts +1 -0
  39. package/lib/cryptography/MessageHashService.d.ts.map +1 -1
  40. package/lib/cryptography/MessageHashService.js +0 -2
  41. package/lib/errors/DecryptionError.js +0 -2
  42. package/lib/errors/FederatedBackendsError.js +2 -3
  43. package/lib/giphy/GiphyService.js +0 -1
  44. package/lib/linkPreview/LinkPreviewService.js +12 -2
  45. package/lib/messagingProtocols/mls/E2EIdentityService/Connection/AcmeServer/AcmeService.d.ts +4 -4
  46. package/lib/messagingProtocols/mls/E2EIdentityService/Connection/AcmeServer/AcmeService.js +8 -9
  47. package/lib/messagingProtocols/mls/E2EIdentityService/Connection/AcmeServer/schema.d.ts +8 -8
  48. package/lib/messagingProtocols/mls/E2EIdentityService/E2EIServiceExternal.js +3 -33
  49. package/lib/messagingProtocols/mls/E2EIdentityService/E2EIServiceExternal.test.js +11 -11
  50. package/lib/messagingProtocols/mls/E2EIdentityService/E2EIServiceInternal.js +5 -15
  51. package/lib/messagingProtocols/mls/E2EIdentityService/Helper/index.d.ts.map +1 -1
  52. package/lib/messagingProtocols/mls/E2EIdentityService/Helper/index.js +0 -1
  53. package/lib/messagingProtocols/mls/E2EIdentityService/Steps/Account.d.ts.map +1 -1
  54. package/lib/messagingProtocols/mls/E2EIdentityService/Steps/Account.js +1 -1
  55. package/lib/messagingProtocols/mls/E2EIdentityService/Steps/Authorization.d.ts +1 -1
  56. package/lib/messagingProtocols/mls/E2EIdentityService/Steps/Authorization.d.ts.map +1 -1
  57. package/lib/messagingProtocols/mls/E2EIdentityService/Steps/Authorization.js +3 -2
  58. package/lib/messagingProtocols/mls/E2EIdentityService/Steps/Certificate.js +1 -1
  59. package/lib/messagingProtocols/mls/E2EIdentityService/Steps/Order.d.ts.map +1 -1
  60. package/lib/messagingProtocols/mls/E2EIdentityService/Steps/Order.js +2 -2
  61. package/lib/messagingProtocols/mls/E2EIdentityService/Storage/E2EIStorage.d.ts.map +1 -1
  62. package/lib/messagingProtocols/mls/E2EIdentityService/Storage/E2EIStorage.js +2 -1
  63. package/lib/messagingProtocols/mls/E2EIdentityService/Storage/E2EIStorage.schema.d.ts +4 -4
  64. package/lib/messagingProtocols/mls/EventHandler/events/messageAdd/IncomingMessagesQueue/IncomingMesssagesQueue.d.ts.map +1 -1
  65. package/lib/messagingProtocols/mls/EventHandler/events/messageAdd/messageAdd.d.ts.map +1 -1
  66. package/lib/messagingProtocols/mls/EventHandler/events/messageAdd/messageAdd.js +1 -1
  67. package/lib/messagingProtocols/mls/EventHandler/events/welcomeMessage/welcomeMessage.d.ts.map +1 -1
  68. package/lib/messagingProtocols/mls/EventHandler/events/welcomeMessage/welcomeMessage.js +1 -1
  69. package/lib/messagingProtocols/mls/EventHandler/events/welcomeMessage/welcomeMessage.test.js +3 -7
  70. package/lib/messagingProtocols/mls/MLSService/ClientMLSError.js +0 -1
  71. package/lib/messagingProtocols/mls/MLSService/CoreCryptoMLSError.d.ts.map +1 -1
  72. package/lib/messagingProtocols/mls/MLSService/MLSService.d.ts.map +1 -1
  73. package/lib/messagingProtocols/mls/MLSService/MLSService.js +115 -110
  74. package/lib/messagingProtocols/mls/MLSService/MLSService.test.js +9 -31
  75. package/lib/messagingProtocols/mls/MLSService/commitBundleUtil.js +2 -1
  76. package/lib/messagingProtocols/mls/conversationRejoinQueue.js +4 -3
  77. package/lib/messagingProtocols/mls/utils/MLSId.js +3 -2
  78. package/lib/messagingProtocols/proteus/EventHandler/events/otrMessageAdd/otrMessageAdd.d.ts.map +1 -1
  79. package/lib/messagingProtocols/proteus/ProteusService/CryptoClient/CoreCryptoWrapper/CoreCryptoWrapper.js +2 -6
  80. package/lib/messagingProtocols/proteus/ProteusService/CryptoClient/CoreCryptoWrapper/PrekeysTracker/PrekeysTracker.js +0 -3
  81. package/lib/messagingProtocols/proteus/ProteusService/CryptoClient/CoreCryptoWrapper/PrekeysTracker/PrekeysTracker.store.js +1 -1
  82. package/lib/messagingProtocols/proteus/ProteusService/CryptoClient/CryptoboxWrapper.js +4 -5
  83. package/lib/messagingProtocols/proteus/ProteusService/DecryptionErrorGenerator/DecryptionErrorGenerator.js +2 -1
  84. package/lib/messagingProtocols/proteus/ProteusService/ProteusService.d.ts.map +1 -1
  85. package/lib/messagingProtocols/proteus/ProteusService/ProteusService.js +16 -20
  86. package/lib/messagingProtocols/proteus/ProteusService/ProteusService.mocks.d.ts +7 -4
  87. package/lib/messagingProtocols/proteus/ProteusService/ProteusService.mocks.d.ts.map +1 -1
  88. package/lib/messagingProtocols/proteus/ProteusService/ProteusService.test.js +15 -15
  89. package/lib/messagingProtocols/proteus/ProteusService/cryptoMigrationStateStore.js +1 -1
  90. package/lib/messagingProtocols/proteus/ProteusService/identityClearer.js +2 -1
  91. package/lib/messagingProtocols/proteus/ProteusService/sessionIdMigrator.js +3 -2
  92. package/lib/messagingProtocols/proteus/ProteusService/userDomainFilters.js +2 -1
  93. package/lib/messagingProtocols/proteus/Utility/Recipients.d.ts.map +1 -1
  94. package/lib/messagingProtocols/proteus/Utility/SessionHandler/SessionHandler.d.ts.map +1 -1
  95. package/lib/messagingProtocols/proteus/Utility/SessionHandler/SessionHandler.js +14 -14
  96. package/lib/messagingProtocols/proteus/Utility/SessionHandler/SessionHandler.test.js +2 -5
  97. package/lib/messagingProtocols/proteus/Utility/getGenericMessageParams.d.ts.map +1 -1
  98. package/lib/notification/NotificationBackendRepository.d.ts +1 -1
  99. package/lib/notification/NotificationBackendRepository.js +0 -1
  100. package/lib/notification/NotificationDatabaseRepository.js +0 -1
  101. package/lib/notification/NotificationService.js +49 -38
  102. package/lib/secretStore/encryptedStore.js +22 -10
  103. package/lib/secretStore/secretKeyGenerator.js +2 -2
  104. package/lib/secretStore/secretKeyGenerator.test.js +1 -1
  105. package/lib/self/SelfService.js +1 -2
  106. package/lib/storage/CoreDB.js +3 -2
  107. package/lib/team/TeamService.js +0 -1
  108. package/lib/test/PayloadHelper.js +4 -3
  109. package/lib/testUtils/index.js +3 -2
  110. package/lib/user/UserService.d.ts +2 -2
  111. package/lib/user/UserService.js +0 -1
  112. package/lib/util/LocalStorageStore/index.d.ts.map +1 -1
  113. package/lib/util/LowPrecisionTaskScheduler/LowPrecisionTaskScheduler.js +6 -4
  114. package/lib/util/RecurringTaskScheduler/RecurringTaskScheduler.d.ts.map +1 -1
  115. package/lib/util/RecurringTaskScheduler/RecurringTaskScheduler.js +33 -34
  116. package/lib/util/TaskScheduler/TaskScheduler.d.ts +1 -1
  117. package/lib/util/TaskScheduler/TaskScheduler.d.ts.map +1 -1
  118. package/lib/util/TypePredicateUtil.js +10 -7
  119. package/lib/util/fullyQualifiedClientIdUtils.js +2 -1
  120. package/package.json +6 -6
@@ -38,14 +38,6 @@ const util_1 = require("../../util");
38
38
  const fullyQualifiedClientIdUtils_1 = require("../../util/fullyQualifiedClientIdUtils");
39
39
  const messageSender_1 = require("../message/messageSender");
40
40
  class ConversationService extends commons_1.TypedEventEmitter {
41
- apiClient;
42
- proteusService;
43
- coreDatabase;
44
- groupIdFromConversationId;
45
- subconversationService;
46
- _mlsService;
47
- messageTimer;
48
- logger = (0, logdown_1.default)('@wireapp/core/ConversationService');
49
41
  constructor(apiClient, proteusService, coreDatabase, groupIdFromConversationId, subconversationService, _mlsService) {
50
42
  super();
51
43
  this.apiClient = apiClient;
@@ -54,6 +46,67 @@ class ConversationService extends commons_1.TypedEventEmitter {
54
46
  this.groupIdFromConversationId = groupIdFromConversationId;
55
47
  this.subconversationService = subconversationService;
56
48
  this._mlsService = _mlsService;
49
+ this.logger = (0, logdown_1.default)('@wireapp/core/ConversationService');
50
+ /**
51
+ * Blacklists a conversation.
52
+ * When conversations is blacklisted, it means that it will be completely ignored by a client, even though it does exist on backend and we're the conversation member.
53
+ * @param conversationId id of the conversation to blacklist
54
+ */
55
+ this.blacklistConversation = async (conversationId) => {
56
+ await this.coreDatabase.put('conversationBlacklist', conversationId, conversationId.id);
57
+ };
58
+ /**
59
+ * Removes a conversation from the blacklists.
60
+ * @param conversationId id of the conversation to remove from the blacklist
61
+ */
62
+ this.removeConversationFromBlacklist = async (conversationId) => {
63
+ await this.coreDatabase.delete('conversationBlacklist', conversationId.id);
64
+ };
65
+ /**
66
+ * Will try registering mls 1:1 conversation adding the other user.
67
+ * If it fails and the conversation is already established, it will try joining via external commit instead.
68
+ *
69
+ * @param mlsConversation - mls 1:1 conversation
70
+ * @param selfUser - user and client ids of the self user
71
+ * @param otherUserId - id of the other user
72
+ */
73
+ this.establishMLS1to1Conversation = async (groupId, selfUser, otherUserId, shouldRetry = true) => {
74
+ this.logger.info(`Trying to establish a MLS 1:1 conversation with user ${otherUserId.id}...`);
75
+ // Before trying to register a group, check if the group is already established o backend.
76
+ // If remote epoch is higher than 0, it means that the group was already established.
77
+ // It's possible that we've already received a welcome message.
78
+ const mlsConversation = await this.getMLS1to1Conversation(otherUserId);
79
+ if (mlsConversation.epoch > 0) {
80
+ this.logger.info(`Conversation (id ${mlsConversation.qualified_id.id}) is already established on backend, checking the local epoch...`);
81
+ const isMLSGroupEstablishedLocally = await this.isMLSGroupEstablishedLocally(groupId);
82
+ // If group is already established locally, there's nothing more to do
83
+ if (isMLSGroupEstablishedLocally) {
84
+ this.logger.info(`Conversation (id ${mlsConversation.qualified_id.id}) is already established locally.`);
85
+ return mlsConversation;
86
+ }
87
+ // If local epoch is 0 it means that we've not received a welcome message
88
+ // We try joining via external commit.
89
+ this.logger.info(`Conversation (id ${mlsConversation.qualified_id.id}) is not yet established locally, joining via external commit...`);
90
+ await this.joinByExternalCommit(mlsConversation.qualified_id);
91
+ return this.getMLS1to1Conversation(otherUserId);
92
+ }
93
+ // If group is not established on backend,
94
+ // we wipe the it locally (in case it exsits in the local store) and try to register it.
95
+ await this.mlsService.wipeConversation(groupId);
96
+ try {
97
+ await this.mlsService.register1to1Conversation(groupId, otherUserId, selfUser);
98
+ this.logger.info(`Conversation (id ${mlsConversation.qualified_id.id}) established successfully.`);
99
+ return this.getMLS1to1Conversation(otherUserId);
100
+ }
101
+ catch (error) {
102
+ this.logger.info(`Could not register MLS group with id ${groupId}: `, error);
103
+ if (!shouldRetry) {
104
+ throw error;
105
+ }
106
+ this.logger.info(`Conversation (id ${mlsConversation.qualified_id.id}) is not established, retrying to establish it`);
107
+ return this.establishMLS1to1Conversation(groupId, selfUser, otherUserId, false);
108
+ }
109
+ };
57
110
  this.messageTimer = new conversation_2.MessageTimer();
58
111
  }
59
112
  get mlsService() {
@@ -76,7 +129,7 @@ class ConversationService extends commons_1.TypedEventEmitter {
76
129
  const allClients = await this.apiClient.api.user.postListClients({ qualified_users: qualifiedMembers });
77
130
  const qualifiedUserClients = {};
78
131
  Object.entries(allClients.qualified_user_map).map(([domain, userClientMap]) => Object.entries(userClientMap).map(async ([userId, clients]) => {
79
- qualifiedUserClients[domain] ||= {};
132
+ qualifiedUserClients[domain] || (qualifiedUserClients[domain] = {});
80
133
  qualifiedUserClients[domain][userId] = clients.map(client => client.id);
81
134
  }));
82
135
  return qualifiedUserClients;
@@ -130,21 +183,6 @@ class ConversationService extends commons_1.TypedEventEmitter {
130
183
  sendTypingStop(conversationId) {
131
184
  return this.apiClient.api.conversation.postTyping(conversationId, { status: data_1.CONVERSATION_TYPING.STOPPED });
132
185
  }
133
- /**
134
- * Blacklists a conversation.
135
- * When conversations is blacklisted, it means that it will be completely ignored by a client, even though it does exist on backend and we're the conversation member.
136
- * @param conversationId id of the conversation to blacklist
137
- */
138
- blacklistConversation = async (conversationId) => {
139
- await this.coreDatabase.put('conversationBlacklist', conversationId, conversationId.id);
140
- };
141
- /**
142
- * Removes a conversation from the blacklists.
143
- * @param conversationId id of the conversation to remove from the blacklist
144
- */
145
- removeConversationFromBlacklist = async (conversationId) => {
146
- await this.coreDatabase.delete('conversationBlacklist', conversationId.id);
147
- };
148
186
  /**
149
187
  * returns the number of messages that are in the queue expecting to be sent
150
188
  */
@@ -192,11 +230,7 @@ class ConversationService extends commons_1.TypedEventEmitter {
192
230
  * field must be empty as backend is not aware which users
193
231
  * are in a MLS conversation because of the MLS architecture.
194
232
  */
195
- const newConversation = await this.apiClient.api.conversation.postConversation({
196
- ...conversationData,
197
- users: undefined,
198
- qualified_users: undefined,
199
- });
233
+ const newConversation = await this.apiClient.api.conversation.postConversation(Object.assign(Object.assign({}, conversationData), { users: undefined, qualified_users: undefined }));
200
234
  const { group_id: groupId, qualified_id: qualifiedId } = newConversation;
201
235
  if (!groupId) {
202
236
  throw new Error('No group_id found in response which is required for creating MLS conversations.');
@@ -216,6 +250,7 @@ class ConversationService extends commons_1.TypedEventEmitter {
216
250
  };
217
251
  }
218
252
  async sendMLSMessage(params, shouldRetry = true) {
253
+ var _a, _b;
219
254
  const { payload, groupId, conversationId } = params;
220
255
  const groupIdBytes = bazinga64_1.Decoder.fromBase64(groupId).asBytes;
221
256
  // immediately execute pending commits before sending the message
@@ -225,7 +260,7 @@ class ConversationService extends commons_1.TypedEventEmitter {
225
260
  let sentAt = '';
226
261
  try {
227
262
  response = await this.apiClient.api.conversation.postMlsMessage(encrypted);
228
- sentAt = response.time?.length > 0 ? response.time : new Date().toISOString();
263
+ sentAt = ((_a = response.time) === null || _a === void 0 ? void 0 : _a.length) > 0 ? response.time : new Date().toISOString();
229
264
  }
230
265
  catch (error) {
231
266
  const isMLSStaleMessageError = error instanceof http_1.BackendError && error.label === http_1.BackendErrorLabel.MLS_STALE_MESSAGE;
@@ -237,10 +272,10 @@ class ConversationService extends commons_1.TypedEventEmitter {
237
272
  }
238
273
  throw error;
239
274
  }
240
- const failedToSend = response?.failed || (response?.failed_to_send ?? []).length > 0
275
+ const failedToSend = (response === null || response === void 0 ? void 0 : response.failed) || ((_b = response === null || response === void 0 ? void 0 : response.failed_to_send) !== null && _b !== void 0 ? _b : []).length > 0
241
276
  ? {
242
- queued: response?.failed_to_send,
243
- failed: response?.failed,
277
+ queued: response === null || response === void 0 ? void 0 : response.failed_to_send,
278
+ failed: response === null || response === void 0 ? void 0 : response.failed,
244
279
  }
245
280
  : undefined;
246
281
  return {
@@ -306,12 +341,12 @@ class ConversationService extends commons_1.TypedEventEmitter {
306
341
  }
307
342
  async matchesEpoch(groupId, backendEpoch) {
308
343
  const localEpoch = await this.mlsService.getEpoch(groupId);
309
- this.logger.debug(`Comparing conversation's (group_id: ${groupId}) local and backend epoch number: {local: ${String(localEpoch)}, backend: ${backendEpoch}}`);
344
+ this.logger.log(`Comparing conversation's (group_id: ${groupId}) local and backend epoch number: {local: ${String(localEpoch)}, backend: ${backendEpoch}}`);
310
345
  //corecrypto stores epoch number as BigInt, we're mapping both values to be sure comparison is valid
311
346
  return BigInt(localEpoch) === BigInt(backendEpoch);
312
347
  }
313
348
  async handleConversationsEpochMismatch() {
314
- this.logger.warn(`There were some missed messages, handling possible epoch mismatch in MLS conversations.`);
349
+ this.logger.info(`There were some missed messages, handling possible epoch mismatch in MLS conversations.`);
315
350
  //fetch all the mls conversations from backend
316
351
  const conversations = await this.apiClient.api.conversation.getConversationList();
317
352
  const foundConversations = conversations.found || [];
@@ -328,7 +363,7 @@ class ConversationService extends commons_1.TypedEventEmitter {
328
363
  async handleSubconversationEpochMismatch(subconversation, parentGroupId) {
329
364
  const { parent_qualified_id: parentConversationId, group_id: groupId, epoch, subconv_id: subconversationId, } = subconversation;
330
365
  if (await this.hasEpochMismatch(groupId, epoch)) {
331
- this.logger.warn(`Subconversation "${subconversationId}" (parent id: ${parentConversationId.id}) was not established or its epoch number was out of date, joining via external commit`);
366
+ this.logger.log(`Subconversation "${subconversationId}" (parent id: ${parentConversationId.id}) was not established or its epoch number was out of date, joining via external commit`);
332
367
  // We only support conference subconversations for now
333
368
  if (subconversationId !== conversation_1.SUBCONVERSATION_ID.CONFERENCE) {
334
369
  throw new Error('Unexpected subconversation id');
@@ -349,10 +384,10 @@ class ConversationService extends commons_1.TypedEventEmitter {
349
384
  async handleConversationEpochMismatch(remoteMlsConversation, onSuccessfulRejoin) {
350
385
  const { qualified_id: qualifiedId, group_id: groupId, epoch } = remoteMlsConversation;
351
386
  if (await this.hasEpochMismatch(groupId, epoch)) {
352
- this.logger.warn(`Conversation (id ${qualifiedId.id}) was not established or it's epoch number was out of date, joining via external commit`);
387
+ this.logger.log(`Conversation (id ${qualifiedId.id}) was not established or it's epoch number was out of date, joining via external commit`);
353
388
  try {
354
389
  await this.joinByExternalCommit(qualifiedId);
355
- onSuccessfulRejoin?.();
390
+ onSuccessfulRejoin === null || onSuccessfulRejoin === void 0 ? void 0 : onSuccessfulRejoin();
356
391
  }
357
392
  catch (error) {
358
393
  const message = `There was an error while handling epoch mismatch in MLS conversation (id: ${qualifiedId.id}):`;
@@ -381,51 +416,6 @@ class ConversationService extends commons_1.TypedEventEmitter {
381
416
  async getMLS1to1Conversation(userId) {
382
417
  return this.apiClient.api.conversation.getMLS1to1Conversation(userId);
383
418
  }
384
- /**
385
- * Will try registering mls 1:1 conversation adding the other user.
386
- * If it fails and the conversation is already established, it will try joining via external commit instead.
387
- *
388
- * @param mlsConversation - mls 1:1 conversation
389
- * @param selfUser - user and client ids of the self user
390
- * @param otherUserId - id of the other user
391
- */
392
- establishMLS1to1Conversation = async (groupId, selfUser, otherUserId, shouldRetry = true) => {
393
- this.logger.debug(`Trying to establish a MLS 1:1 conversation with user ${otherUserId.id}...`);
394
- // Before trying to register a group, check if the group is already established o backend.
395
- // If remote epoch is higher than 0, it means that the group was already established.
396
- // It's possible that we've already received a welcome message.
397
- const mlsConversation = await this.getMLS1to1Conversation(otherUserId);
398
- if (mlsConversation.epoch > 0) {
399
- this.logger.debug(`Conversation (id ${mlsConversation.qualified_id.id}) is already established on backend, checking the local epoch...`);
400
- const isMLSGroupEstablishedLocally = await this.isMLSGroupEstablishedLocally(groupId);
401
- // If group is already established locally, there's nothing more to do
402
- if (isMLSGroupEstablishedLocally) {
403
- this.logger.debug(`Conversation (id ${mlsConversation.qualified_id.id}) is already established locally.`);
404
- return mlsConversation;
405
- }
406
- // If local epoch is 0 it means that we've not received a welcome message
407
- // We try joining via external commit.
408
- this.logger.debug(`Conversation (id ${mlsConversation.qualified_id.id}) is not yet established locally, joining via external commit...`);
409
- await this.joinByExternalCommit(mlsConversation.qualified_id);
410
- return this.getMLS1to1Conversation(otherUserId);
411
- }
412
- // If group is not established on backend,
413
- // we wipe the it locally (in case it exsits in the local store) and try to register it.
414
- await this.mlsService.wipeConversation(groupId);
415
- try {
416
- await this.mlsService.register1to1Conversation(groupId, otherUserId, selfUser);
417
- this.logger.info(`Conversation (id ${mlsConversation.qualified_id.id}) established successfully.`);
418
- return this.getMLS1to1Conversation(otherUserId);
419
- }
420
- catch (error) {
421
- if (!shouldRetry) {
422
- this.logger.error(`Could not register MLS group with id ${groupId}: `, error);
423
- throw error;
424
- }
425
- this.logger.error(`Conversation (id ${mlsConversation.qualified_id.id}) is not established, retrying to establish it`);
426
- return this.establishMLS1to1Conversation(groupId, selfUser, otherUserId, false);
427
- }
428
- };
429
419
  /**
430
420
  * Will try to register mls group by sending an empty commit to establish it.
431
421
  * After group was successfully established, it will try to add other users to the group.
@@ -438,13 +428,13 @@ class ConversationService extends commons_1.TypedEventEmitter {
438
428
  async tryEstablishingMLSGroup({ groupId, conversationId, selfUserId, qualifiedUsers, }) {
439
429
  const wasGroupEstablishedBySelfClient = await this.mlsService.tryEstablishingMLSGroup(groupId);
440
430
  if (!wasGroupEstablishedBySelfClient) {
441
- this.logger.debug('Group was not established by self client, skipping adding users to the group.');
431
+ this.logger.info('Group was not established by self client, skipping adding users to the group.');
442
432
  return;
443
433
  }
444
- this.logger.debug('Group was established by self client, adding other users to the group...');
434
+ this.logger.info('Group was established by self client, adding other users to the group...');
445
435
  const usersToAdd = [
446
436
  ...qualifiedUsers,
447
- { ...selfUserId, skipOwnClientId: this.apiClient.validatedClientId },
437
+ Object.assign(Object.assign({}, selfUserId), { skipOwnClientId: this.apiClient.validatedClientId }),
448
438
  ];
449
439
  const { conversation } = await this.addUsersToMLSConversation({
450
440
  conversationId,
@@ -453,10 +443,10 @@ class ConversationService extends commons_1.TypedEventEmitter {
453
443
  });
454
444
  const addedUsers = conversation.members.others;
455
445
  if (addedUsers.length > 0) {
456
- this.logger.debug(`Successfully added ${addedUsers} users to the group.`);
446
+ this.logger.info(`Successfully added ${addedUsers} users to the group.`);
457
447
  }
458
448
  else {
459
- this.logger.debug('No other users were added to the group.');
449
+ this.logger.info('No other users were added to the group.');
460
450
  }
461
451
  }
462
452
  async handleMLSMessageAddEvent(event) {
@@ -465,7 +455,7 @@ class ConversationService extends commons_1.TypedEventEmitter {
465
455
  }
466
456
  catch (error) {
467
457
  if ((0, CoreCryptoMLSError_1.isCoreCryptoMLSWrongEpochError)(error)) {
468
- this.logger.warn(`Received message for the wrong epoch in conversation ${event.conversation}, handling epoch mismatch...`);
458
+ this.logger.info(`Received message for the wrong epoch in conversation ${event.conversation}, handling epoch mismatch...`);
469
459
  const { qualified_conversation: conversationId, subconv } = event;
470
460
  if (!conversationId) {
471
461
  throw new Error('Qualified conversation id is missing in the event');
@@ -503,7 +493,7 @@ class ConversationService extends commons_1.TypedEventEmitter {
503
493
  if (!conversationId) {
504
494
  throw new Error('Qualified conversation id is missing in the event');
505
495
  }
506
- this.logger.warn(`Received an orphan welcome message, joining the conversation (${conversationId.id}) via external commit...`);
496
+ this.logger.info(`Received an orphan welcome message, joining the conversation (${conversationId.id}) via external commit...`);
507
497
  void (0, conversationRejoinQueue_1.queueConversationRejoin)(conversationId.id, () => this.joinByExternalCommit(conversationId));
508
498
  return null;
509
499
  }
@@ -71,17 +71,9 @@ const createMLSWelcomeMessageEventMock = (conversationId) => ({
71
71
  type: event_1.CONVERSATION_EVENT.MLS_WELCOME_MESSAGE,
72
72
  time: '2023-08-21T06:47:43.387Z',
73
73
  });
74
- jest.mock('../../messagingProtocols/proteus', () => ({
75
- ...jest.requireActual('../../messagingProtocols/proteus'),
76
- getGenericMessageParams: jest.fn(),
77
- getRecipientsForConversation: jest.fn(),
78
- getConversationQualifiedMembers: jest.fn(),
79
- }));
74
+ jest.mock('../../messagingProtocols/proteus', () => (Object.assign(Object.assign({}, jest.requireActual('../../messagingProtocols/proteus')), { getGenericMessageParams: jest.fn(), getRecipientsForConversation: jest.fn(), getConversationQualifiedMembers: jest.fn() })));
80
75
  const MockedMessagingProtocols = MessagingProtocols;
81
- jest.mock('../message/messageSender', () => ({
82
- ...jest.requireActual('../message/messageSender'),
83
- sendMessage: jest.fn().mockImplementation(fn => fn()),
84
- }));
76
+ jest.mock('../message/messageSender', () => (Object.assign(Object.assign({}, jest.requireActual('../message/messageSender')), { sendMessage: jest.fn().mockImplementation(fn => fn()) })));
85
77
  const mockedProteusService = {
86
78
  encryptGenericMessage: () => Promise.resolve(),
87
79
  sendProteusMessage: () => Promise.resolve({ sentAt: new Date() }),
@@ -446,13 +438,14 @@ describe('ConversationService', () => {
446
438
  });
447
439
  describe('getConversations', () => {
448
440
  it('returns a list of conversations by conversation ids', async () => {
441
+ var _a;
449
442
  const [conversationService, { apiClient }] = await buildConversationService();
450
443
  const conversationIds = Array.from({ length: 10 }, () => ({ id: PayloadHelper.getUUID(), domain: 'test.zinfra.io' }));
451
444
  jest.spyOn(apiClient.api.conversation, 'getConversationsByQualifiedIds').mockResolvedValueOnce({
452
445
  found: conversationIds,
453
446
  });
454
447
  const conversations = await conversationService.getConversations(conversationIds);
455
- expect(conversations.found?.length).toBe(conversationIds.length);
448
+ expect((_a = conversations.found) === null || _a === void 0 ? void 0 : _a.length).toBe(conversationIds.length);
456
449
  });
457
450
  it('returns a full list of conversations if a list of conversations is not provided', async () => {
458
451
  const [conversationService, { apiClient }] = await buildConversationService();
@@ -585,7 +578,7 @@ describe('ConversationService', () => {
585
578
  expect(conversationService.addUsersToMLSConversation).toHaveBeenCalledWith({
586
579
  conversationId: mockConversationId,
587
580
  groupId: mockGroupId,
588
- qualifiedUsers: [...otherUsersToAdd, { ...selfUserId, skipOwnClientId: apiClient.clientId }],
581
+ qualifiedUsers: [...otherUsersToAdd, Object.assign(Object.assign({}, selfUserId), { skipOwnClientId: apiClient.clientId })],
589
582
  });
590
583
  });
591
584
  it('should not add any users if MLS group was not established by the self client', async () => {
@@ -1 +1 @@
1
- {"version":3,"file":"getConversationQualifiedMembers.d.ts","sourceRoot":"","sources":["../../../../src/conversation/ConversationService/Utility/getConversationQualifiedMembers.ts"],"names":[],"mappings":"AAmBA,OAAO,EAAC,SAAS,EAAC,MAAM,mCAAmC,CAAC;AAC5D,OAAO,EAAC,WAAW,EAAC,MAAM,8BAA8B,CAAC;AAEzD,UAAU,MAAM;IACd,SAAS,EAAE,SAAS,CAAC;IACrB,cAAc,EAAE,WAAW,CAAC;CAC7B;AACD,QAAA,MAAM,+BAA+B,kCAAuC,MAAM,KAAG,OAAO,CAAC,WAAW,EAAE,CAWzG,CAAC;AAEF,OAAO,EAAC,+BAA+B,EAAC,CAAC"}
1
+ {"version":3,"file":"getConversationQualifiedMembers.d.ts","sourceRoot":"","sources":["../../../../src/conversation/ConversationService/Utility/getConversationQualifiedMembers.ts"],"names":[],"mappings":"AAmBA,OAAO,EAAC,SAAS,EAAC,MAAM,mCAAmC,CAAC;AAC5D,OAAO,EAAC,WAAW,EAAC,MAAM,8BAA8B,CAAC;AAEzD,UAAU,MAAM;IACd,SAAS,EAAE,SAAS,CAAC;IACrB,cAAc,EAAE,WAAW,CAAC;CAC7B;AACD,QAAA,MAAM,+BAA+B,kCAAuC,MAAM,KAAG,QAAQ,WAAW,EAAE,CAWzG,CAAC;AAEF,OAAO,EAAC,+BAA+B,EAAC,CAAC"}
@@ -20,8 +20,6 @@
20
20
  Object.defineProperty(exports, "__esModule", { value: true });
21
21
  exports.MessageTimer = void 0;
22
22
  class MessageTimer {
23
- conversationLevelTimers;
24
- messageLevelTimers;
25
23
  constructor() {
26
24
  this.conversationLevelTimers = new Map();
27
25
  this.messageLevelTimers = new Map();
@@ -38,6 +38,14 @@ export declare class SubconversationService extends TypedEventEmitter<Events> {
38
38
  * @param conversationId Id of the parent conversation which subconversation we want to leave
39
39
  */
40
40
  leaveConferenceSubconversation(conversationId: QualifiedId): Promise<void>;
41
+ /**
42
+ * Short term solution to an issues with 1:1 MLS call, see
43
+ * https://wearezeta.atlassian.net/wiki/spaces/PAD/pages/1314750477/2024-07-29+1+1+calls+over+SFT#Do-not-leave-the-subconversation
44
+ * Will delete a conference subconversation when hanging up on a 1:1 call instead of leaving.
45
+ *
46
+ * @param conversationId Id of the parent conversation which subconversation we want to leave
47
+ */
48
+ leave1on1ConferenceSubconversation(conversationId: QualifiedId): Promise<void>;
41
49
  leaveStaleConferenceSubconversations(): Promise<void>;
42
50
  getSubconversationEpochInfo(parentConversationId: QualifiedId, parentConversationGroupId: string, shouldAdvanceEpoch?: boolean): Promise<{
43
51
  members: SubconversationEpochInfoMember[];
@@ -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":"AAmBA,OAAO,EAAC,kBAAkB,EAAkB,MAAM,sCAAsC,CAAC;AACzF,OAAO,EAAC,WAAW,EAAC,MAAM,8BAA8B,CAAC;AAIzD,OAAO,EAAC,SAAS,EAAC,MAAM,qBAAqB,CAAC;AAC9C,OAAO,EAAC,iBAAiB,EAAC,MAAM,kBAAkB,CAAC;AAInD,OAAO,EAAC,UAAU,EAAC,MAAM,8BAA8B,CAAC;AACxD,OAAO,EAAC,YAAY,EAAC,MAAM,sBAAsB,CAAC;AAGlD,KAAK,MAAM,GAAG;IACZ,wBAAwB,EAAE;QAAC,cAAc,EAAE,WAAW,CAAA;KAAC,CAAC;CACzD,CAAC;AAEF,MAAM,WAAW,8BAA8B;IAC7C,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,MAAM,CAAC;IACjB,UAAU,EAAE,OAAO,CAAC;CACrB;AAID,qBAAa,sBAAuB,SAAQ,iBAAiB,CAAC,MAAM,CAAC;IAIjE,OAAO,CAAC,QAAQ,CAAC,SAAS;IAC1B,OAAO,CAAC,QAAQ,CAAC,YAAY;IAC7B,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAC;IAL/B,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAmD;gBAGvD,SAAS,EAAE,SAAS,EACpB,YAAY,EAAE,YAAY,EAC1B,WAAW,CAAC,wBAAY;IAK3C,IAAI,UAAU,IAAI,UAAU,CAK3B;IAED;;;;;;OAMG;IACU,6BAA6B,CACxC,cAAc,EAAE,WAAW,EAC3B,OAAO,EAAE,MAAM,EACf,WAAW,UAAO,GACjB,OAAO,CAAC;QAAC,OAAO,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAC,CAAC;IAiD5C;;;;OAIG;IACU,8BAA8B,CAAC,cAAc,EAAE,WAAW,GAAG,OAAO,CAAC,IAAI,CAAC;IAyBvF;;;;;;OAMG;IACU,kCAAkC,CAAC,cAAc,EAAE,WAAW,GAAG,OAAO,CAAC,IAAI,CAAC;IAiC9E,oCAAoC,IAAI,OAAO,CAAC,IAAI,CAAC;IAQrD,2BAA2B,CACtC,oBAAoB,EAAE,WAAW,EACjC,yBAAyB,EAAE,MAAM,EACjC,kBAAkB,UAAQ,GACzB,OAAO,CAAC;QACT,OAAO,EAAE,8BAA8B,EAAE,CAAC;QAC1C,KAAK,EAAE,MAAM,CAAC;QACd,SAAS,EAAE,MAAM,CAAC;QAClB,SAAS,EAAE,MAAM,CAAC;KACnB,GAAG,IAAI,CAAC;IAoCI,uBAAuB,CAClC,oBAAoB,EAAE,WAAW,EACjC,yBAAyB,EAAE,MAAM,EACjC,yBAAyB,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,WAAW,GAAG,SAAS,EACvE,aAAa,EAAE,CAAC,IAAI,EAAE;QACpB,OAAO,EAAE,8BAA8B,EAAE,CAAC;QAC1C,KAAK,EAAE,MAAM,CAAC;QACd,SAAS,EAAE,MAAM,CAAC;QAClB,SAAS,EAAE,MAAM,CAAC;KACnB,KAAK,IAAI,GACT,OAAO,CAAC,MAAM,IAAI,CAAC;IAiDT,yCAAyC,CACpD,cAAc,EAAE,WAAW,EAC3B,cAAc,EAAE;QAAC,IAAI,EAAE,WAAW,CAAC;QAAC,QAAQ,EAAE,MAAM,CAAA;KAAC,GACpD,OAAO,CAAC,IAAI,CAAC;YAgCF,mCAAmC;YAMnC,4BAA4B;YAI5B,+BAA+B;YAO/B,8BAA8B;IAwBrC,yBAAyB,yBACR,WAAW,qBACd,kBAAkB,KACpC,QAAQ,MAAM,GAAG,SAAS,CAAC,CAO5B;IAEK,iCAAiC,sBACnB,kBAAkB,KACpC,QACD;QACE,oBAAoB,EAAE,WAAW,CAAC;QAClC,iBAAiB,EAAE,kBAAkB,CAAC;QACtC,OAAO,EAAE,MAAM,CAAC;KACjB,EAAE,CACJ,CAOC;IAEK,0BAA0B,yBACT,WAAW,qBACd,kBAAkB,WAC5B,MAAM,qBAOf;IAEK,2BAA2B,yBACV,WAAW,qBACd,kBAAkB,mBAMrC;CACH"}
@@ -30,15 +30,27 @@ const subconversationUtil_1 = require("./subconversationUtil");
30
30
  const fullyQualifiedClientIdUtils_1 = require("../../util/fullyQualifiedClientIdUtils");
31
31
  const MLS_CONVERSATION_KEY_LENGTH = 32;
32
32
  class SubconversationService extends commons_1.TypedEventEmitter {
33
- apiClient;
34
- coreDatabase;
35
- _mlsService;
36
- logger = (0, logdown_1.default)('@wireapp/core/SubconversationService');
37
33
  constructor(apiClient, coreDatabase, _mlsService) {
38
34
  super();
39
35
  this.apiClient = apiClient;
40
36
  this.coreDatabase = coreDatabase;
41
37
  this._mlsService = _mlsService;
38
+ this.logger = (0, logdown_1.default)('@wireapp/core/SubconversationService');
39
+ this.getSubconversationGroupId = async (parentConversationId, subconversationId) => {
40
+ const foundSubconversation = await this.coreDatabase.get('subconversations', (0, subconversationUtil_1.generateSubconversationStoreKey)(parentConversationId, subconversationId));
41
+ return foundSubconversation === null || foundSubconversation === void 0 ? void 0 : foundSubconversation.groupId;
42
+ };
43
+ this.getAllGroupIdsBySubconversationId = async (subconversationId) => {
44
+ const allSubconversations = await this.coreDatabase.getAll('subconversations');
45
+ const foundSubconversations = allSubconversations.filter(subconversation => subconversation.subconversationId === subconversationId);
46
+ return foundSubconversations;
47
+ };
48
+ this.saveSubconversationGroupId = async (parentConversationId, subconversationId, groupId) => {
49
+ return this.coreDatabase.put('subconversations', { parentConversationId, subconversationId, groupId }, (0, subconversationUtil_1.generateSubconversationStoreKey)(parentConversationId, subconversationId));
50
+ };
51
+ this.clearSubconversationGroupId = async (parentConversationId, subconversationId) => {
52
+ return this.coreDatabase.delete('subconversations', (0, subconversationUtil_1.generateSubconversationStoreKey)(parentConversationId, subconversationId));
53
+ };
42
54
  }
43
55
  get mlsService() {
44
56
  if (!this._mlsService) {
@@ -115,6 +127,40 @@ class SubconversationService extends commons_1.TypedEventEmitter {
115
127
  // once we've left the subconversation, we can remove it from the store
116
128
  await this.clearSubconversationGroupId(conversationId, conversation_1.SUBCONVERSATION_ID.CONFERENCE);
117
129
  }
130
+ /**
131
+ * Short term solution to an issues with 1:1 MLS call, see
132
+ * https://wearezeta.atlassian.net/wiki/spaces/PAD/pages/1314750477/2024-07-29+1+1+calls+over+SFT#Do-not-leave-the-subconversation
133
+ * Will delete a conference subconversation when hanging up on a 1:1 call instead of leaving.
134
+ *
135
+ * @param conversationId Id of the parent conversation which subconversation we want to leave
136
+ */
137
+ async leave1on1ConferenceSubconversation(conversationId) {
138
+ const subconversationGroupId = await this.getSubconversationGroupId(conversationId, conversation_1.SUBCONVERSATION_ID.CONFERENCE);
139
+ if (!subconversationGroupId) {
140
+ return;
141
+ }
142
+ const doesGroupExistLocally = await this.mlsService.conversationExists(subconversationGroupId);
143
+ if (!doesGroupExistLocally) {
144
+ // If the subconversation was known by a client but is does not exist locally, we can remove it from the store.
145
+ return this.clearSubconversationGroupId(conversationId, conversation_1.SUBCONVERSATION_ID.CONFERENCE);
146
+ }
147
+ try {
148
+ const epochInfo = await this.getSubconversationEpochInfo(conversationId, subconversationGroupId);
149
+ if (!epochInfo) {
150
+ throw new Error('Failed to get epoch info for conference subconversation');
151
+ }
152
+ await this.apiClient.api.conversation.deleteSubconversation(conversationId, conversation_1.SUBCONVERSATION_ID.CONFERENCE, {
153
+ groupId: subconversationGroupId,
154
+ epoch: epochInfo.epoch,
155
+ });
156
+ }
157
+ catch (error) {
158
+ this.logger.error(`Failed to delete conference subconversation:`, error);
159
+ }
160
+ await this.mlsService.wipeConversation(subconversationGroupId);
161
+ // once we've deleted the subconversation, we can remove it from the store
162
+ await this.clearSubconversationGroupId(conversationId, conversation_1.SUBCONVERSATION_ID.CONFERENCE);
163
+ }
118
164
  async leaveStaleConferenceSubconversations() {
119
165
  const conversationIds = await this.getAllGroupIdsBySubconversationId(conversation_1.SUBCONVERSATION_ID.CONFERENCE);
120
166
  for (const { parentConversationId } of conversationIds) {
@@ -161,10 +207,7 @@ class SubconversationService extends commons_1.TypedEventEmitter {
161
207
  return;
162
208
  }
163
209
  const newSubconversationEpoch = Number(await this.mlsService.getEpoch(subconversationGroupId));
164
- return onEpochUpdate({
165
- ...subconversationEpochInfo,
166
- epoch: newSubconversationEpoch,
167
- });
210
+ return onEpochUpdate(Object.assign(Object.assign({}, subconversationEpochInfo), { epoch: newSubconversationEpoch }));
168
211
  };
169
212
  this.mlsService.on('newEpoch', forwardNewEpoch);
170
213
  await forwardNewEpoch({ groupId: subconversationGroupId, epoch: initialEpoch });
@@ -212,20 +255,5 @@ class SubconversationService extends commons_1.TypedEventEmitter {
212
255
  };
213
256
  });
214
257
  }
215
- getSubconversationGroupId = async (parentConversationId, subconversationId) => {
216
- const foundSubconversation = await this.coreDatabase.get('subconversations', (0, subconversationUtil_1.generateSubconversationStoreKey)(parentConversationId, subconversationId));
217
- return foundSubconversation?.groupId;
218
- };
219
- getAllGroupIdsBySubconversationId = async (subconversationId) => {
220
- const allSubconversations = await this.coreDatabase.getAll('subconversations');
221
- const foundSubconversations = allSubconversations.filter(subconversation => subconversation.subconversationId === subconversationId);
222
- return foundSubconversations;
223
- };
224
- saveSubconversationGroupId = async (parentConversationId, subconversationId, groupId) => {
225
- return this.coreDatabase.put('subconversations', { parentConversationId, subconversationId, groupId }, (0, subconversationUtil_1.generateSubconversationStoreKey)(parentConversationId, subconversationId));
226
- };
227
- clearSubconversationGroupId = async (parentConversationId, subconversationId) => {
228
- return this.coreDatabase.delete('subconversations', (0, subconversationUtil_1.generateSubconversationStoreKey)(parentConversationId, subconversationId));
229
- };
230
258
  }
231
259
  exports.SubconversationService = SubconversationService;
@@ -1,3 +1,4 @@
1
+ /// <reference types="node" />
1
2
  import { Asset } from '@wireapp/protocol-messaging';
2
3
  import { AbortReason, AssetTransferState } from '..';
3
4
  import { EncryptedAssetUploaded } from '../../cryptography';
@@ -1 +1 @@
1
- {"version":3,"file":"AssetContent.d.ts","sourceRoot":"","sources":["../../../src/conversation/content/AssetContent.ts"],"names":[],"mappings":"AAmBA,OAAO,EAAC,KAAK,EAAC,MAAM,6BAA6B,CAAC;AAElD,OAAO,EAAC,WAAW,EAAE,kBAAkB,EAAC,MAAM,IAAI,CAAC;AACnD,OAAO,EAAC,sBAAsB,EAAC,MAAM,oBAAoB,CAAC;AAE1D,OAAO,EAAC,WAAW,EAAE,mBAAmB,EAAE,YAAY,EAAE,eAAe,EAAC,MAAM,GAAG,CAAC;AAElF,MAAM,MAAM,aAAa,GAAG,KAAK,CAAC,cAAc,CAAC;AACjD,MAAM,MAAM,aAAa,GAAG,KAAK,CAAC,cAAc,CAAC;AACjD,MAAM,MAAM,OAAO,GAAG,KAAK,CAAC,QAAQ,CAAC;AACrC,MAAM,MAAM,QAAQ,GAAG,KAAK,CAAC,SAAS,CAAC;AAEvC,MAAM,WAAW,SAAS;IACxB,uBAAuB,CAAC,EAAE,OAAO,CAAC;IAClC,eAAe,CAAC,EAAE,eAAe,CAAC;CACnC;AAGD,MAAM,WAAW,YAAa,SAAQ,SAAS;IAC7C,WAAW,CAAC,EAAE,WAAW,CAAC;IAC1B,QAAQ,CAAC,EAAE,QAAQ,CAAC;IACpB,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,MAAM,CAAC,EAAE,kBAAkB,CAAC;IAC5B,QAAQ,CAAC,EAAE,UAAU,CAAC;CACvB;AAED,MAAM,WAAW,UAAW,SAAQ,KAAK,CAAC,WAAW;IACnD,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,UAAU,GAAG,MAAM,CAAC;IAC5B,MAAM,EAAE,UAAU,GAAG,MAAM,CAAC;CAC7B;AAED,MAAM,WAAW,aAAc,SAAQ,IAAI,CAAC,KAAK,CAAC,cAAc,EAAE,oBAAoB,CAAC;IACrF,kBAAkB,CAAC,EAAE,UAAU,GAAG,MAAM,GAAG,IAAI,CAAC;CACjD;AAED,MAAM,WAAW,iBAAkB,SAAQ,SAAS;IAClD,KAAK,EAAE,sBAAsB,CAAC;IAC9B,KAAK,EAAE,YAAY,CAAC;CACrB;AAED,MAAM,WAAW,gBAAiB,SAAQ,SAAS;IACjD,KAAK,EAAE,sBAAsB,CAAC;IAC9B,IAAI,EAAE,WAAW,CAAC;CACnB;AAED,MAAM,WAAW,wBAAyB,SAAQ,SAAS;IACzD,QAAQ,EAAE,mBAAmB,CAAC;CAC/B;AAED,MAAM,WAAW,qBAAsB,SAAQ,SAAS;IACtD,MAAM,EAAE,WAAW,CAAC;CACrB"}
1
+ {"version":3,"file":"AssetContent.d.ts","sourceRoot":"","sources":["../../../src/conversation/content/AssetContent.ts"],"names":[],"mappings":";AAmBA,OAAO,EAAC,KAAK,EAAC,MAAM,6BAA6B,CAAC;AAElD,OAAO,EAAC,WAAW,EAAE,kBAAkB,EAAC,MAAM,IAAI,CAAC;AACnD,OAAO,EAAC,sBAAsB,EAAC,MAAM,oBAAoB,CAAC;AAE1D,OAAO,EAAC,WAAW,EAAE,mBAAmB,EAAE,YAAY,EAAE,eAAe,EAAC,MAAM,GAAG,CAAC;AAElF,MAAM,MAAM,aAAa,GAAG,KAAK,CAAC,cAAc,CAAC;AACjD,MAAM,MAAM,aAAa,GAAG,KAAK,CAAC,cAAc,CAAC;AACjD,MAAM,MAAM,OAAO,GAAG,KAAK,CAAC,QAAQ,CAAC;AACrC,MAAM,MAAM,QAAQ,GAAG,KAAK,CAAC,SAAS,CAAC;AAEvC,MAAM,WAAW,SAAS;IACxB,uBAAuB,CAAC,EAAE,OAAO,CAAC;IAClC,eAAe,CAAC,EAAE,eAAe,CAAC;CACnC;AAGD,MAAM,WAAW,YAAa,SAAQ,SAAS;IAC7C,WAAW,CAAC,EAAE,WAAW,CAAC;IAC1B,QAAQ,CAAC,EAAE,QAAQ,CAAC;IACpB,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,MAAM,CAAC,EAAE,kBAAkB,CAAC;IAC5B,QAAQ,CAAC,EAAE,UAAU,CAAC;CACvB;AAED,MAAM,WAAW,UAAW,SAAQ,KAAK,CAAC,WAAW;IACnD,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,UAAU,GAAG,MAAM,CAAC;IAC5B,MAAM,EAAE,UAAU,GAAG,MAAM,CAAC;CAC7B;AAED,MAAM,WAAW,aAAc,SAAQ,IAAI,CAAC,KAAK,CAAC,cAAc,EAAE,oBAAoB,CAAC;IACrF,kBAAkB,CAAC,EAAE,UAAU,GAAG,MAAM,GAAG,IAAI,CAAC;CACjD;AAED,MAAM,WAAW,iBAAkB,SAAQ,SAAS;IAClD,KAAK,EAAE,sBAAsB,CAAC;IAC9B,KAAK,EAAE,YAAY,CAAC;CACrB;AAED,MAAM,WAAW,gBAAiB,SAAQ,SAAS;IACjD,KAAK,EAAE,sBAAsB,CAAC;IAC9B,IAAI,EAAE,WAAW,CAAC;CACnB;AAED,MAAM,WAAW,wBAAyB,SAAQ,SAAS;IACzD,QAAQ,EAAE,mBAAmB,CAAC;CAC/B;AAED,MAAM,WAAW,qBAAsB,SAAQ,SAAS;IACtD,MAAM,EAAE,WAAW,CAAC;CACrB"}
@@ -18,75 +18,76 @@
18
18
  *
19
19
  */
20
20
  Object.defineProperty(exports, "__esModule", { value: true });
21
- exports.isAbortedAssetContent = isAbortedAssetContent;
22
- exports.isAssetContent = isAssetContent;
23
- exports.isClearedContent = isClearedContent;
24
- exports.isClientActionContent = isClientActionContent;
25
- exports.isClientActionType = isClientActionType;
26
- exports.isConfirmationContent = isConfirmationContent;
27
- exports.isConnection = isConnection;
28
- exports.isDeletedContent = isDeletedContent;
29
- exports.isEditedTextContent = isEditedTextContent;
30
- exports.isFileAssetAbortContent = isFileAssetAbortContent;
31
- exports.isFileAssetContent = isFileAssetContent;
32
- exports.isFileAssetMetaDataContent = isFileAssetMetaDataContent;
33
- exports.isHiddenContent = isHiddenContent;
34
- exports.isImageAssetContent = isImageAssetContent;
35
- exports.isImageContent = isImageContent;
36
- exports.isLocationContent = isLocationContent;
37
- exports.isReactionContent = isReactionContent;
38
- exports.isTextContent = isTextContent;
21
+ exports.isTextContent = exports.isReactionContent = exports.isLocationContent = exports.isImageContent = exports.isImageAssetContent = exports.isHiddenContent = exports.isFileAssetMetaDataContent = exports.isFileAssetContent = exports.isFileAssetAbortContent = exports.isEditedTextContent = exports.isDeletedContent = exports.isConnection = exports.isConfirmationContent = exports.isClientActionType = exports.isClientActionContent = exports.isClearedContent = exports.isAssetContent = exports.isAbortedAssetContent = void 0;
39
22
  function isAbortedAssetContent(content) {
40
23
  return !!content.abortReason;
41
24
  }
25
+ exports.isAbortedAssetContent = isAbortedAssetContent;
42
26
  function isAssetContent(content) {
43
27
  return !!(content.uploaded || content.preview);
44
28
  }
29
+ exports.isAssetContent = isAssetContent;
45
30
  function isClearedContent(content) {
46
31
  return !!content.clearedTimestamp;
47
32
  }
33
+ exports.isClearedContent = isClearedContent;
48
34
  function isClientActionContent(content) {
49
35
  return !!content.clientAction;
50
36
  }
37
+ exports.isClientActionContent = isClientActionContent;
51
38
  function isClientActionType(content) {
52
39
  return typeof content === 'number';
53
40
  }
41
+ exports.isClientActionType = isClientActionType;
54
42
  function isConfirmationContent(content) {
55
43
  return !!content.firstMessageId;
56
44
  }
45
+ exports.isConfirmationContent = isConfirmationContent;
57
46
  function isConnection(content) {
58
47
  return !!content.from && !!content.to;
59
48
  }
49
+ exports.isConnection = isConnection;
60
50
  function isDeletedContent(content) {
61
51
  return !!content.messageId && !content.text;
62
52
  }
53
+ exports.isDeletedContent = isDeletedContent;
63
54
  function isEditedTextContent(content) {
64
55
  return !!content.text && !!content.originalMessageId;
65
56
  }
57
+ exports.isEditedTextContent = isEditedTextContent;
66
58
  function isFileAssetAbortContent(content) {
67
59
  return !!content.reason;
68
60
  }
61
+ exports.isFileAssetAbortContent = isFileAssetAbortContent;
69
62
  function isFileAssetContent(content) {
70
63
  return !!content.asset && !!content.file;
71
64
  }
65
+ exports.isFileAssetContent = isFileAssetContent;
72
66
  function isFileAssetMetaDataContent(content) {
73
67
  return !!content.metaData;
74
68
  }
69
+ exports.isFileAssetMetaDataContent = isFileAssetMetaDataContent;
75
70
  function isHiddenContent(content) {
76
71
  return !!content.conversationId;
77
72
  }
73
+ exports.isHiddenContent = isHiddenContent;
78
74
  function isImageAssetContent(content) {
79
75
  return !!content.asset && !!content.image;
80
76
  }
77
+ exports.isImageAssetContent = isImageAssetContent;
81
78
  function isImageContent(content) {
82
79
  return !!content.data && !!content.type;
83
80
  }
81
+ exports.isImageContent = isImageContent;
84
82
  function isLocationContent(content) {
85
83
  return !!content.latitude && !!content.longitude;
86
84
  }
85
+ exports.isLocationContent = isLocationContent;
87
86
  function isReactionContent(content) {
88
87
  return !!content.type && !!content.originalMessageId;
89
88
  }
89
+ exports.isReactionContent = isReactionContent;
90
90
  function isTextContent(content) {
91
91
  return !!content.text;
92
92
  }
93
+ exports.isTextContent = isTextContent;
@@ -1,3 +1,4 @@
1
+ /// <reference types="node" />
1
2
  import { AudioMetaData, VideoMetaData, ImageMetaData } from './AssetContent';
2
3
  export interface FileContent {
3
4
  data: Buffer;
@@ -1 +1 @@
1
- {"version":3,"file":"FileContent.d.ts","sourceRoot":"","sources":["../../../src/conversation/content/FileContent.ts"],"names":[],"mappings":"AAmBA,OAAO,EAAC,aAAa,EAAE,aAAa,EAAE,aAAa,EAAC,MAAM,gBAAgB,CAAC;AAE3E,MAAM,WAAW,WAAW;IAC1B,IAAI,EAAE,MAAM,CAAC;CACd;AAED,MAAM,WAAW,mBAAmB;IAClC,KAAK,CAAC,EAAE,aAAa,CAAC;IACtB,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,CAAC,EAAE,aAAa,CAAC;IACtB,KAAK,CAAC,EAAE,aAAa,CAAC;CACvB"}
1
+ {"version":3,"file":"FileContent.d.ts","sourceRoot":"","sources":["../../../src/conversation/content/FileContent.ts"],"names":[],"mappings":";AAmBA,OAAO,EAAC,aAAa,EAAE,aAAa,EAAE,aAAa,EAAC,MAAM,gBAAgB,CAAC;AAE3E,MAAM,WAAW,WAAW;IAC1B,IAAI,EAAE,MAAM,CAAC;CACd;AAED,MAAM,WAAW,mBAAmB;IAClC,KAAK,CAAC,EAAE,aAAa,CAAC;IACtB,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,CAAC,EAAE,aAAa,CAAC;IACtB,KAAK,CAAC,EAAE,aAAa,CAAC;CACvB"}
@@ -1,3 +1,4 @@
1
+ /// <reference types="node" />
1
2
  export interface ImageContent {
2
3
  data: Buffer | Uint8Array;
3
4
  height: number;
@@ -1 +1 @@
1
- {"version":3,"file":"ImageContent.d.ts","sourceRoot":"","sources":["../../../src/conversation/content/ImageContent.ts"],"names":[],"mappings":"AAmBA,MAAM,WAAW,YAAY;IAC3B,IAAI,EAAE,MAAM,GAAG,UAAU,CAAC;IAC1B,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;CACf"}
1
+ {"version":3,"file":"ImageContent.d.ts","sourceRoot":"","sources":["../../../src/conversation/content/ImageContent.ts"],"names":[],"mappings":";AAmBA,MAAM,WAAW,YAAY;IAC3B,IAAI,EAAE,MAAM,GAAG,UAAU,CAAC;IAC1B,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;CACf"}