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