@wireapp/core 38.14.3 → 38.15.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 (31) hide show
  1. package/lib/Account.d.ts.map +1 -1
  2. package/lib/Account.js +2 -0
  3. package/lib/conversation/message/MessageService.d.ts.map +1 -1
  4. package/lib/conversation/message/MessageService.js +14 -12
  5. package/lib/conversation/message/MessageService.test.js +24 -3
  6. package/lib/messagingProtocols/mls/EventHandler/events/messageAdd/messageAdd.d.ts.map +1 -1
  7. package/lib/messagingProtocols/mls/EventHandler/events/messageAdd/messageAdd.js +6 -1
  8. package/lib/messagingProtocols/mls/MLSService/MLSService.d.ts +8 -2
  9. package/lib/messagingProtocols/mls/MLSService/MLSService.d.ts.map +1 -1
  10. package/lib/messagingProtocols/mls/MLSService/MLSService.js +26 -9
  11. package/lib/messagingProtocols/mls/MLSService/stores/subconversationGroupIdStore/subconversationGroupIdStore.d.ts +18 -0
  12. package/lib/messagingProtocols/mls/MLSService/stores/subconversationGroupIdStore/subconversationGroupIdStore.d.ts.map +1 -0
  13. package/lib/messagingProtocols/mls/MLSService/stores/subconversationGroupIdStore/subconversationGroupIdStore.js +67 -0
  14. package/lib/messagingProtocols/mls/MLSService/stores/subconversationGroupIdStore/subconversationGroupIdStore.test.d.ts +2 -0
  15. package/lib/messagingProtocols/mls/MLSService/stores/subconversationGroupIdStore/subconversationGroupIdStore.test.d.ts.map +1 -0
  16. package/lib/messagingProtocols/mls/MLSService/stores/subconversationGroupIdStore/subconversationGroupIdStore.test.js +72 -0
  17. package/lib/messagingProtocols/proteus/ProteusService/ProteusService.d.ts +12 -2
  18. package/lib/messagingProtocols/proteus/ProteusService/ProteusService.d.ts.map +1 -1
  19. package/lib/messagingProtocols/proteus/ProteusService/ProteusService.js +12 -5
  20. package/lib/messagingProtocols/proteus/ProteusService/ProteusService.test.js +61 -8
  21. package/lib/messagingProtocols/proteus/Utility/SessionHandler/SessionHandler.d.ts +7 -1
  22. package/lib/messagingProtocols/proteus/Utility/SessionHandler/SessionHandler.d.ts.map +1 -1
  23. package/lib/messagingProtocols/proteus/Utility/SessionHandler/SessionHandler.js +30 -26
  24. package/lib/messagingProtocols/proteus/Utility/SessionHandler/SessionHandler.test.js +17 -4
  25. package/package.json +4 -4
  26. package/lib/messagingProtocols/mls/MLSService/subconversationGroupIdMapper.d.ts +0 -4
  27. package/lib/messagingProtocols/mls/MLSService/subconversationGroupIdMapper.d.ts.map +0 -1
  28. package/lib/messagingProtocols/mls/MLSService/subconversationGroupIdMapper.js +0 -35
  29. package/lib/messagingProtocols/mls/MLSService/subconversationGroupIdMapper.test.d.ts +0 -2
  30. package/lib/messagingProtocols/mls/MLSService/subconversationGroupIdMapper.test.d.ts.map +0 -1
  31. package/lib/messagingProtocols/mls/MLSService/subconversationGroupIdMapper.test.js +0 -35
@@ -1 +1 @@
1
- {"version":3,"file":"Account.d.ts","sourceRoot":"","sources":["../src/Account.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"Account.d.ts","sourceRoot":"","sources":["../src/Account.ts"],"names":[],"mappings":"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"}
package/lib/Account.js CHANGED
@@ -215,6 +215,8 @@ class Account extends TypedEventEmitter_1.TypedEventEmitter {
215
215
  this.service.mls.checkForKeyMaterialsUpdate();
216
216
  // initialize scheduler for syncing key packages with backend
217
217
  this.service.mls.checkForKeyPackagesBackendSync();
218
+ // leave stale conference subconversations (e.g after a crash)
219
+ await this.service.mls.leaveStaleConferenceSubconversations();
218
220
  }
219
221
  return validClient;
220
222
  }
@@ -1 +1 @@
1
- {"version":3,"file":"MessageService.d.ts","sourceRoot":"","sources":["../../../src/conversation/message/MessageService.ts"],"names":[],"mappings":"AAmBA,OAAO,EACL,cAAc,EACd,oBAAoB,EAIpB,oBAAoB,EACpB,WAAW,EACZ,MAAM,sCAAsC,CAAC;AAC9C,OAAO,EAAC,WAAW,EAAE,4BAA4B,EAAE,mBAAmB,EAAC,MAAM,8BAA8B,CAAC;AAQ5G,OAAO,EAAC,SAAS,EAAC,MAAM,qBAAqB,CAAC;AAS9C,OAAO,KAAK,EAAC,cAAc,EAAC,MAAM,kCAAkC,CAAC;AAKrE,qBAAa,cAAc;IACb,OAAO,CAAC,QAAQ,CAAC,SAAS;IAAa,OAAO,CAAC,QAAQ,CAAC,cAAc;gBAArD,SAAS,EAAE,SAAS,EAAmB,cAAc,EAAE,cAAc;IAElG;;;;;;;;;;;OAWG;IACU,WAAW,CACtB,eAAe,EAAE,MAAM,EACvB,UAAU,EAAE,WAAW,GAAG,mBAAmB,EAC7C,SAAS,EAAE,UAAU,EACrB,OAAO,GAAE;QACP,cAAc,CAAC,EAAE,WAAW,CAAC;QAC7B,aAAa,CAAC,EAAE,OAAO,GAAG,MAAM,EAAE,CAAC;QACnC,cAAc,CAAC,EAAE,OAAO,CAAC;QACzB,UAAU,CAAC,EAAE,OAAO,CAAC;QACrB,gBAAgB,CAAC,EAAE,CAAC,QAAQ,EAAE,cAAc,KAAK,IAAI,GAAG,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;KAC/E,GACL,OAAO,CAAC,cAAc,GAAG;QAAC,QAAQ,CAAC,EAAE,OAAO,CAAA;KAAC,CAAC;IAgCjD;;;;;;;;;;;OAWG;IACU,oBAAoB,CAC/B,eAAe,EAAE,MAAM,EACvB,UAAU,EAAE,oBAAoB,GAAG,4BAA4B,EAC/D,SAAS,EAAE,UAAU,EACrB,OAAO,EAAE;QACP,SAAS,CAAC,EAAE,UAAU,CAAC;QACvB,cAAc,CAAC,EAAE,WAAW,CAAC;QAC7B,aAAa,CAAC,EAAE,OAAO,GAAG,WAAW,EAAE,CAAC;QACxC,UAAU,CAAC,EAAE,OAAO,CAAC;QACrB,gBAAgB,CAAC,EAAE,CAAC,QAAQ,EAAE,oBAAoB,KAAK,IAAI,GAAG,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;KAC1F,GACA,OAAO,CAAC,oBAAoB,GAAG;QAAC,QAAQ,CAAC,EAAE,OAAO,CAAA;KAAC,CAAC;YAsBzC,uBAAuB;YAiEvB,cAAc;YAmCd,uBAAuB;IAiBrC,OAAO,CAAC,oBAAoB;IAc5B,OAAO,CAAC,qBAAqB;YAIf,sBAAsB;IAiBpC;;;;;;;OAOG;YACW,+BAA+B;YAqB/B,sBAAsB;CAoDrC"}
1
+ {"version":3,"file":"MessageService.d.ts","sourceRoot":"","sources":["../../../src/conversation/message/MessageService.ts"],"names":[],"mappings":"AAmBA,OAAO,EACL,cAAc,EACd,oBAAoB,EAIpB,oBAAoB,EACpB,WAAW,EACZ,MAAM,sCAAsC,CAAC;AAC9C,OAAO,EAAC,WAAW,EAAE,4BAA4B,EAAE,mBAAmB,EAAC,MAAM,8BAA8B,CAAC;AAQ5G,OAAO,EAAC,SAAS,EAAC,MAAM,qBAAqB,CAAC;AAS9C,OAAO,KAAK,EAAC,cAAc,EAAC,MAAM,kCAAkC,CAAC;AAKrE,qBAAa,cAAc;IACb,OAAO,CAAC,QAAQ,CAAC,SAAS;IAAa,OAAO,CAAC,QAAQ,CAAC,cAAc;gBAArD,SAAS,EAAE,SAAS,EAAmB,cAAc,EAAE,cAAc;IAElG;;;;;;;;;;;OAWG;IACU,WAAW,CACtB,eAAe,EAAE,MAAM,EACvB,UAAU,EAAE,WAAW,GAAG,mBAAmB,EAC7C,SAAS,EAAE,UAAU,EACrB,OAAO,GAAE;QACP,cAAc,CAAC,EAAE,WAAW,CAAC;QAC7B,aAAa,CAAC,EAAE,OAAO,GAAG,MAAM,EAAE,CAAC;QACnC,cAAc,CAAC,EAAE,OAAO,CAAC;QACzB,UAAU,CAAC,EAAE,OAAO,CAAC;QACrB,gBAAgB,CAAC,EAAE,CAAC,QAAQ,EAAE,cAAc,KAAK,IAAI,GAAG,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;KAC/E,GACL,OAAO,CAAC,cAAc,GAAG;QAAC,QAAQ,CAAC,EAAE,OAAO,CAAA;KAAC,CAAC;IAkCjD;;;;;;;;;;;OAWG;IACU,oBAAoB,CAC/B,eAAe,EAAE,MAAM,EACvB,UAAU,EAAE,oBAAoB,GAAG,4BAA4B,EAC/D,SAAS,EAAE,UAAU,EACrB,OAAO,EAAE;QACP,SAAS,CAAC,EAAE,UAAU,CAAC;QACvB,cAAc,CAAC,EAAE,WAAW,CAAC;QAC7B,aAAa,CAAC,EAAE,OAAO,GAAG,WAAW,EAAE,CAAC;QACxC,UAAU,CAAC,EAAE,OAAO,CAAC;QACrB,gBAAgB,CAAC,EAAE,CAAC,QAAQ,EAAE,oBAAoB,KAAK,IAAI,GAAG,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;KAC1F,GACA,OAAO,CAAC,oBAAoB,GAAG;QAAC,QAAQ,CAAC,EAAE,OAAO,CAAA;KAAC,CAAC;YA2BzC,uBAAuB;YAiEvB,cAAc;YAmCd,uBAAuB;IAiBrC,OAAO,CAAC,oBAAoB;IAc5B,OAAO,CAAC,qBAAqB;YAIf,sBAAsB;IAiBpC;;;;;;;OAOG;YACW,+BAA+B;YAqB/B,sBAAsB;CAoDrC"}
@@ -59,11 +59,12 @@ class MessageService {
59
59
  plainTextPayload = externalPayload.text;
60
60
  cipherText = externalPayload.cipherText;
61
61
  }
62
- const encryptedPayload = await this.proteusService.encrypt(plainTextPayload, recipients);
63
- const send = (payload) => {
64
- return options.sendAsProtobuf
65
- ? this.sendOTRProtobufMessage(sendingClientId, payload, Object.assign(Object.assign({}, options), { assetData: cipherText }))
66
- : this.sendOTRMessage(sendingClientId, payload, Object.assign(Object.assign({}, options), { assetData: cipherText }));
62
+ const { payloads: encryptedPayload, unknowns } = await this.proteusService.encrypt(plainTextPayload, recipients);
63
+ const send = async (payload) => {
64
+ const result = options.sendAsProtobuf
65
+ ? await this.sendOTRProtobufMessage(sendingClientId, payload, Object.assign(Object.assign({}, options), { assetData: cipherText }))
66
+ : await this.sendOTRMessage(sendingClientId, payload, Object.assign(Object.assign({}, options), { assetData: cipherText }));
67
+ return unknowns ? Object.assign(Object.assign({}, result), { deleted: Object.assign(Object.assign({}, result.deleted), unknowns) }) : result;
67
68
  };
68
69
  try {
69
70
  return await send(encryptedPayload);
@@ -94,10 +95,11 @@ class MessageService {
94
95
  * @return the MessageSendingStatus returned by the backend
95
96
  */
96
97
  async sendFederatedMessage(sendingClientId, recipients, plainText, options) {
97
- const send = (payload) => {
98
- return this.sendFederatedOtrMessage(sendingClientId, payload, options);
98
+ const { payloads: encryptedPayload, unknowns: unknows } = await this.proteusService.encryptQualified(plainText, recipients);
99
+ const send = async (payload) => {
100
+ const result = await this.sendFederatedOtrMessage(sendingClientId, payload, options);
101
+ return unknows ? Object.assign(Object.assign({}, result), { deleted: Object.assign(Object.assign({}, result.deleted), unknows) }) : result;
99
102
  };
100
- const encryptedPayload = await this.proteusService.encryptQualified(plainText, recipients);
101
103
  try {
102
104
  return await send(encryptedPayload);
103
105
  }
@@ -212,8 +214,8 @@ class MessageService {
212
214
  // remove deleted clients to the recipients
213
215
  deleted.forEach(({ userId, data }) => data.forEach(clientId => delete recipients[userId.id][clientId]));
214
216
  if (Object.keys(mismatch.missing).length) {
215
- const encrypted = await this.proteusService.encrypt(plainText, mismatch.missing);
216
- const reEncryptedPayloads = (0, UserClientsUtil_1.flattenUserClients)(encrypted);
217
+ const { payloads } = await this.proteusService.encrypt(plainText, mismatch.missing);
218
+ const reEncryptedPayloads = (0, UserClientsUtil_1.flattenUserClients)(payloads);
217
219
  // add missing clients to the recipients
218
220
  reEncryptedPayloads.forEach(({ data, userId }) => (recipients[userId.id] = Object.assign(Object.assign({}, recipients[userId.id]), data)));
219
221
  }
@@ -232,8 +234,8 @@ class MessageService {
232
234
  // remove deleted clients to the recipients
233
235
  deleted.forEach(({ userId, data }) => data.forEach(clientId => delete recipients[userId.domain][userId.id][clientId]));
234
236
  if (Object.keys(mismatch.missing).length) {
235
- const encrypted = await this.proteusService.encryptQualified(plainText, mismatch.missing);
236
- const reEncryptedPayloads = (0, UserClientsUtil_1.flattenQualifiedUserClients)(encrypted);
237
+ const { payloads } = await this.proteusService.encryptQualified(plainText, mismatch.missing);
238
+ const reEncryptedPayloads = (0, UserClientsUtil_1.flattenQualifiedUserClients)(payloads);
237
239
  reEncryptedPayloads.forEach(({ data, userId }) => (recipients[userId.domain][userId.id] = Object.assign(Object.assign({}, recipients[userId.domain][userId.id]), data)));
238
240
  }
239
241
  return recipients;
@@ -67,7 +67,7 @@ function fakeEncryptQualified(_, recipients) {
67
67
  }, {});
68
68
  return acc;
69
69
  }, {});
70
- return Promise.resolve(encryptedPayload);
70
+ return Promise.resolve({ payloads: encryptedPayload });
71
71
  }
72
72
  function fakeEncrypt(_, recipients) {
73
73
  const encryptedPayload = Object.entries(recipients).reduce((userClients, [userId, clients]) => {
@@ -77,7 +77,7 @@ function fakeEncrypt(_, recipients) {
77
77
  }, {}));
78
78
  return userClients;
79
79
  }, {});
80
- return Promise.resolve(encryptedPayload);
80
+ return Promise.resolve({ payloads: encryptedPayload });
81
81
  }
82
82
  const buildMessageService = async () => {
83
83
  const apiClient = new api_client_1.APIClient();
@@ -85,7 +85,7 @@ const buildMessageService = async () => {
85
85
  const messageService = new MessageService_1.MessageService(apiClient, proteusService);
86
86
  jest.spyOn(proteusService, 'encryptQualified').mockImplementation(fakeEncryptQualified);
87
87
  jest.spyOn(proteusService, 'encrypt').mockImplementation(fakeEncrypt);
88
- return [messageService, { apiClient }];
88
+ return [messageService, { apiClient, proteusService }];
89
89
  };
90
90
  describe('MessageService', () => {
91
91
  describe('sendFederatedMessage', () => {
@@ -151,6 +151,27 @@ describe('MessageService', () => {
151
151
  expect(apiClient.api.conversation.postOTRMessageV2).toHaveBeenCalledTimes(2);
152
152
  expect(onClientMismatch).toHaveBeenCalledWith(clientMismatch);
153
153
  });
154
+ it('warns the consumer if they try to send a message to a deleted client', async () => {
155
+ const [messageService, { apiClient, proteusService }] = await buildMessageService();
156
+ const onClientMismatch = jest.fn().mockReturnValue(true);
157
+ const recipients = generateQualifiedRecipients([user1, user2]);
158
+ const unknowns = {
159
+ [user1.domain]: {
160
+ [user1.id]: [user1.clients[0]],
161
+ },
162
+ };
163
+ jest.spyOn(proteusService, 'encryptQualified').mockResolvedValue({
164
+ payloads: {},
165
+ unknowns,
166
+ });
167
+ jest.spyOn(apiClient.api.conversation, 'postOTRMessageV2').mockResolvedValue(baseMessageSendingStatus);
168
+ const result = await messageService.sendFederatedMessage('senderclientid', recipients, new Uint8Array(), {
169
+ reportMissing: true,
170
+ onClientMismatch,
171
+ conversationId: { id: 'convid', domain: '' },
172
+ });
173
+ expect(result.deleted).toEqual(unknowns);
174
+ });
154
175
  it('stops message sending if onClientMismatch returns false', async () => {
155
176
  const [messageService, { apiClient }] = await buildMessageService();
156
177
  const onClientMismatch = jest.fn().mockReturnValue(false);
@@ -1 +1 @@
1
- {"version":3,"file":"messageAdd.d.ts","sourceRoot":"","sources":["../../../../../../src/messagingProtocols/mls/EventHandler/events/messageAdd/messageAdd.ts"],"names":[],"mappings":"AAmBA,OAAO,EAAC,YAAY,EAAE,8BAA8B,EAAqB,MAAM,+BAA+B,CAAC;AAK/G,OAAO,EAAC,kBAAkB,EAAC,MAAM,0BAA0B,CAAC;AAE5D,OAAO,EAAC,kBAAkB,EAAC,MAAM,0BAA0B,CAAC;AAE5D,QAAA,MAAM,oBAAoB,UAAW,YAAY,4CACE,CAAC;AAEpD,UAAU,yBAA0B,SAAQ,kBAAkB;IAC5D,KAAK,EAAE,8BAA8B,CAAC;CACvC;AACD,QAAA,MAAM,mBAAmB,0BACF,yBAAyB,4BACpB,MAAM,KAAK,IAAI,uBAuC1C,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,uBA8C1C,CAAC;AAEF,OAAO,EAAC,oBAAoB,EAAE,mBAAmB,EAAC,CAAC"}
@@ -28,7 +28,12 @@ exports.isMLSMessageAddEvent = isMLSMessageAddEvent;
28
28
  const handleMLSMessageAdd = async ({ mlsService, event }, onEpochChanged) => {
29
29
  var _a;
30
30
  const encryptedData = bazinga64_1.Decoder.fromBase64(event.data).asBytes;
31
- const groupId = await mlsService.getGroupIdFromConversationId((_a = event.qualified_conversation) !== null && _a !== void 0 ? _a : { id: event.conversation, domain: '' }, event.subconv);
31
+ const qualifiedConversationId = (_a = event.qualified_conversation) !== null && _a !== void 0 ? _a : { id: event.conversation, domain: '' };
32
+ const groupId = await mlsService.getGroupIdFromConversationId(qualifiedConversationId, event.subconv);
33
+ // We should not receive a message for a group the client is not aware of
34
+ if (!groupId) {
35
+ throw new Error(`Could not find a group_id for conversation ${qualifiedConversationId.id}@${qualifiedConversationId.domain}`);
36
+ }
32
37
  const groupIdBytes = bazinga64_1.Decoder.fromBase64(groupId).asBytes;
33
38
  const { proposals, commitDelay, message, senderClientId: encodedSenderClientId, hasEpochChanged, } = await mlsService.decryptMessage(groupIdBytes, encryptedData);
34
39
  if (encodedSenderClientId) {
@@ -1,4 +1,4 @@
1
- import { PostMlsMessageResponse } from '@wireapp/api-client/lib/conversation';
1
+ import { PostMlsMessageResponse, SUBCONVERSATION_ID } from '@wireapp/api-client/lib/conversation';
2
2
  import { Subconversation } from '@wireapp/api-client/lib/conversation/Subconversation';
3
3
  import { QualifiedId } from '@wireapp/api-client/lib/user';
4
4
  import logdown from 'logdown';
@@ -42,7 +42,13 @@ export declare class MLSService extends TypedEventEmitter<Events> {
42
42
  joinByExternalCommit(getGroupInfo: () => Promise<Uint8Array>): Promise<PostMlsMessageResponse | null>;
43
43
  getConferenceSubconversation(conversationId: QualifiedId): Promise<Subconversation>;
44
44
  private deleteConferenceSubconversation;
45
+ /**
46
+ * Will leave conference subconversation if it's known by client and established.
47
+ *
48
+ * @param conversationId Id of the parent conversation which subconversation we want to leave
49
+ */
45
50
  leaveConferenceSubconversation(conversationId: QualifiedId): Promise<void>;
51
+ leaveStaleConferenceSubconversations(): Promise<void>;
46
52
  /**
47
53
  * Will join or register an mls subconversation for conference calls.
48
54
  * Will return the secret key derived from the subconversation
@@ -134,7 +140,7 @@ export declare class MLSService extends TypedEventEmitter<Events> {
134
140
  *
135
141
  * @param conversationQualifiedId
136
142
  */
137
- getGroupIdFromConversationId(conversationQualifiedId: QualifiedId, subconversationId?: string): Promise<string>;
143
+ getGroupIdFromConversationId(conversationQualifiedId: QualifiedId, subconversationId?: SUBCONVERSATION_ID): Promise<string | undefined>;
138
144
  /**
139
145
  * If there are pending proposals, we need to either process them,
140
146
  * or save them in the database for later processing
@@ -1 +1 @@
1
- {"version":3,"file":"MLSService.d.ts","sourceRoot":"","sources":["../../../../src/messagingProtocols/mls/MLSService/MLSService.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"MLSService.d.ts","sourceRoot":"","sources":["../../../../src/messagingProtocols/mls/MLSService/MLSService.ts"],"names":[],"mappings":"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"}
@@ -42,7 +42,7 @@ const commons_1 = require("@wireapp/commons");
42
42
  const commitBundleUtil_1 = require("./commitBundleUtil");
43
43
  const keyMaterialUpdatesStore_1 = require("./stores/keyMaterialUpdatesStore");
44
44
  const pendingProposalsStore_1 = require("./stores/pendingProposalsStore");
45
- const subconversationGroupIdMapper_1 = require("./subconversationGroupIdMapper");
45
+ const subconversationGroupIdStore_1 = require("./stores/subconversationGroupIdStore/subconversationGroupIdStore");
46
46
  const messageSender_1 = require("../../../conversation/message/messageSender");
47
47
  const fullyQualifiedClientIdUtils_1 = require("../../../util/fullyQualifiedClientIdUtils");
48
48
  const RecurringTaskScheduler_1 = require("../../../util/RecurringTaskScheduler");
@@ -181,14 +181,35 @@ class MLSService extends TypedEventEmitter_1.TypedEventEmitter {
181
181
  async deleteConferenceSubconversation(conversationId, data) {
182
182
  return this.apiClient.api.conversation.deleteSubconversation(conversationId, conversation_1.SUBCONVERSATION_ID.CONFERENCE, data);
183
183
  }
184
+ /**
185
+ * Will leave conference subconversation if it's known by client and established.
186
+ *
187
+ * @param conversationId Id of the parent conversation which subconversation we want to leave
188
+ */
184
189
  async leaveConferenceSubconversation(conversationId) {
185
190
  const subconversationGroupId = await this.getGroupIdFromConversationId(conversationId, conversation_1.SUBCONVERSATION_ID.CONFERENCE);
191
+ if (!subconversationGroupId) {
192
+ return;
193
+ }
186
194
  const isSubconversationEstablished = await this.conversationExists(subconversationGroupId);
187
195
  if (!isSubconversationEstablished) {
188
196
  return;
189
197
  }
190
- await this.apiClient.api.conversation.deleteSubconversationSelf(conversationId, conversation_1.SUBCONVERSATION_ID.CONFERENCE);
191
- return this.wipeConversation(subconversationGroupId);
198
+ try {
199
+ await this.apiClient.api.conversation.deleteSubconversationSelf(conversationId, conversation_1.SUBCONVERSATION_ID.CONFERENCE);
200
+ }
201
+ catch (error) {
202
+ this.logger.error(`Failed to leave conference subconversation:`, error);
203
+ }
204
+ await this.wipeConversation(subconversationGroupId);
205
+ // once we've left the subconversation, we can remove it from the store
206
+ subconversationGroupIdStore_1.subconversationGroupIdStore.removeGroupId(conversationId, conversation_1.SUBCONVERSATION_ID.CONFERENCE);
207
+ }
208
+ async leaveStaleConferenceSubconversations() {
209
+ const conversationIds = subconversationGroupIdStore_1.subconversationGroupIdStore.getAllGroupIdsBySubconversationId(conversation_1.SUBCONVERSATION_ID.CONFERENCE);
210
+ for (const { parentConversation } of conversationIds) {
211
+ await this.leaveConferenceSubconversation(parentConversation);
212
+ }
192
213
  }
193
214
  /**
194
215
  * Will join or register an mls subconversation for conference calls.
@@ -218,7 +239,7 @@ class MLSService extends TypedEventEmitter_1.TypedEventEmitter {
218
239
  }
219
240
  const epoch = Number(await this.getEpoch(subconversation.group_id));
220
241
  // We store the mapping between the subconversation and the parent conversation
221
- (0, subconversationGroupIdMapper_1.storeSubconversationGroupId)(conversationId, subconversation.subconv_id, subconversation.group_id);
242
+ subconversationGroupIdStore_1.subconversationGroupIdStore.storeGroupId(conversationId, subconversation.subconv_id, subconversation.group_id);
222
243
  return { groupId: subconversation.group_id, epoch };
223
244
  }
224
245
  async exportSecretKey(groupId, keyLength) {
@@ -426,13 +447,9 @@ class MLSService extends TypedEventEmitter_1.TypedEventEmitter {
426
447
  */
427
448
  async getGroupIdFromConversationId(conversationQualifiedId, subconversationId) {
428
449
  var _a;
429
- const { id: conversationId, domain: conversationDomain } = conversationQualifiedId;
430
450
  const groupId = subconversationId
431
- ? (0, subconversationGroupIdMapper_1.getGroupId)(conversationQualifiedId, subconversationId)
451
+ ? subconversationGroupIdStore_1.subconversationGroupIdStore.getGroupId(conversationQualifiedId, subconversationId)
432
452
  : await ((_a = this.groupIdFromConversationId) === null || _a === void 0 ? void 0 : _a.call(this, conversationQualifiedId));
433
- if (!groupId) {
434
- throw new Error(`Could not find a group_id for conversation ${conversationId}@${conversationDomain}`);
435
- }
436
453
  return groupId;
437
454
  }
438
455
  /**
@@ -0,0 +1,18 @@
1
+ import { SUBCONVERSATION_ID } from '@wireapp/api-client/lib/conversation';
2
+ import { QualifiedId } from '@wireapp/api-client/lib/user';
3
+ declare function storeGroupId(parentConversation: QualifiedId, subconversation: SUBCONVERSATION_ID, subgroupId: string): void;
4
+ declare function getGroupId(parentConversation: QualifiedId, subconversation: SUBCONVERSATION_ID): string | undefined;
5
+ declare function getAllGroupIdsBySubconversationId(subconversationId: SUBCONVERSATION_ID): {
6
+ subconversationGroupId: string;
7
+ parentConversation: QualifiedId;
8
+ subconversation: string;
9
+ }[];
10
+ declare function removeGroupId(parentConversation: QualifiedId, subconversation: SUBCONVERSATION_ID): void;
11
+ export declare const subconversationGroupIdStore: {
12
+ storeGroupId: typeof storeGroupId;
13
+ getGroupId: typeof getGroupId;
14
+ removeGroupId: typeof removeGroupId;
15
+ getAllGroupIdsBySubconversationId: typeof getAllGroupIdsBySubconversationId;
16
+ };
17
+ export {};
18
+ //# sourceMappingURL=subconversationGroupIdStore.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"subconversationGroupIdStore.d.ts","sourceRoot":"","sources":["../../../../../../src/messagingProtocols/mls/MLSService/stores/subconversationGroupIdStore/subconversationGroupIdStore.ts"],"names":[],"mappings":"AAmBA,OAAO,EAAC,kBAAkB,EAAC,MAAM,sCAAsC,CAAC;AACxE,OAAO,EAAC,WAAW,EAAC,MAAM,8BAA8B,CAAC;AAkCzD,iBAAS,YAAY,CAAC,kBAAkB,EAAE,WAAW,EAAE,eAAe,EAAE,kBAAkB,EAAE,UAAU,EAAE,MAAM,GAAG,IAAI,CAGpH;AAED,iBAAS,UAAU,CAAC,kBAAkB,EAAE,WAAW,EAAE,eAAe,EAAE,kBAAkB,GAAG,MAAM,GAAG,SAAS,CAG5G;AAED,iBAAS,iCAAiC,CAAC,iBAAiB,EAAE,kBAAkB;;;;IAO/E;AAED,iBAAS,aAAa,CAAC,kBAAkB,EAAE,WAAW,EAAE,eAAe,EAAE,kBAAkB,QAG1F;AAED,eAAO,MAAM,2BAA2B;;;;;CAKvC,CAAC"}
@@ -0,0 +1,67 @@
1
+ "use strict";
2
+ /*
3
+ * Wire
4
+ * Copyright (C) 2023 Wire Swiss GmbH
5
+ *
6
+ * This program is free software: you can redistribute it and/or modify
7
+ * it under the terms of the GNU General Public License as published by
8
+ * the Free Software Foundation, either version 3 of the License, or
9
+ * (at your option) any later version.
10
+ *
11
+ * This program is distributed in the hope that it will be useful,
12
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
13
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14
+ * GNU General Public License for more details.
15
+ *
16
+ * You should have received a copy of the GNU General Public License
17
+ * along with this program. If not, see http://www.gnu.org/licenses/.
18
+ *
19
+ */
20
+ Object.defineProperty(exports, "__esModule", { value: true });
21
+ exports.subconversationGroupIdStore = void 0;
22
+ const storageKey = 'subconversationGroupIdStore';
23
+ function generateSubconversationId(parentConversation, subconversation) {
24
+ return `${parentConversation.id}@${parentConversation.domain}:${subconversation}`;
25
+ }
26
+ function parseSubconversationId(subconversationId) {
27
+ const [parentConversationId, subconversation] = subconversationId.split(':');
28
+ const [id, domain] = parentConversationId.split('@');
29
+ return { parentConversation: { domain, id }, subconversation };
30
+ }
31
+ const getCurrentMap = () => {
32
+ const storedEntry = localStorage.getItem(storageKey);
33
+ return storedEntry ? new Map(JSON.parse(storedEntry)) : new Map();
34
+ };
35
+ const addItemToMap = (subconversationId, subgroupId) => {
36
+ const currentMap = getCurrentMap();
37
+ currentMap.set(subconversationId, subgroupId);
38
+ localStorage.setItem(storageKey, JSON.stringify(Array.from(currentMap.entries())));
39
+ };
40
+ const removeItemFromMap = (subconversationId) => {
41
+ const currentMap = getCurrentMap();
42
+ currentMap.delete(subconversationId);
43
+ localStorage.setItem(storageKey, JSON.stringify(Array.from(currentMap.entries())));
44
+ };
45
+ function storeGroupId(parentConversation, subconversation, subgroupId) {
46
+ const subconversationId = generateSubconversationId(parentConversation, subconversation);
47
+ addItemToMap(subconversationId, subgroupId);
48
+ }
49
+ function getGroupId(parentConversation, subconversation) {
50
+ const subconversationId = generateSubconversationId(parentConversation, subconversation);
51
+ return getCurrentMap().get(subconversationId);
52
+ }
53
+ function getAllGroupIdsBySubconversationId(subconversationId) {
54
+ return Array.from(getCurrentMap().entries())
55
+ .map(([subconversationId, subconversationGroupId]) => (Object.assign(Object.assign({}, parseSubconversationId(subconversationId)), { subconversationGroupId })))
56
+ .filter(({ subconversation }) => subconversation === subconversationId);
57
+ }
58
+ function removeGroupId(parentConversation, subconversation) {
59
+ const subconversationId = generateSubconversationId(parentConversation, subconversation);
60
+ return removeItemFromMap(subconversationId);
61
+ }
62
+ exports.subconversationGroupIdStore = {
63
+ storeGroupId,
64
+ getGroupId,
65
+ removeGroupId,
66
+ getAllGroupIdsBySubconversationId,
67
+ };
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=subconversationGroupIdStore.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"subconversationGroupIdStore.test.d.ts","sourceRoot":"","sources":["../../../../../../src/messagingProtocols/mls/MLSService/stores/subconversationGroupIdStore/subconversationGroupIdStore.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,72 @@
1
+ "use strict";
2
+ /*
3
+ * Wire
4
+ * Copyright (C) 2018 Wire Swiss GmbH
5
+ *
6
+ * This program is free software: you can redistribute it and/or modify
7
+ * it under the terms of the GNU General Public License as published by
8
+ * the Free Software Foundation, either version 3 of the License, or
9
+ * (at your option) any later version.
10
+ *
11
+ * This program is distributed in the hope that it will be useful,
12
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
13
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14
+ * GNU General Public License for more details.
15
+ *
16
+ * You should have received a copy of the GNU General Public License
17
+ * along with this program. If not, see http://www.gnu.org/licenses/.
18
+ *
19
+ */
20
+ Object.defineProperty(exports, "__esModule", { value: true });
21
+ const conversation_1 = require("@wireapp/api-client/lib/conversation");
22
+ const subconversationGroupIdStore_1 = require("./subconversationGroupIdStore");
23
+ describe('subconversationGroupIdMapper', () => {
24
+ it('returns empty groupId if conversation is not known', () => {
25
+ const groupId = subconversationGroupIdStore_1.subconversationGroupIdStore.getGroupId({ domain: 'example.com', id: '123' }, conversation_1.SUBCONVERSATION_ID.CONFERENCE);
26
+ expect(groupId).toBeUndefined();
27
+ });
28
+ it('returns the stored groupId', () => {
29
+ const conversationId = { domain: 'example.com', id: '123' };
30
+ const subconversation = conversation_1.SUBCONVERSATION_ID.CONFERENCE;
31
+ const groupId = 'groupID';
32
+ subconversationGroupIdStore_1.subconversationGroupIdStore.storeGroupId(conversationId, subconversation, groupId);
33
+ const result = subconversationGroupIdStore_1.subconversationGroupIdStore.getGroupId(conversationId, subconversation);
34
+ expect(result).toBe(groupId);
35
+ });
36
+ it('removes groupId from the store', () => {
37
+ const conversationId = { domain: 'example.com', id: '123' };
38
+ const subconversation = conversation_1.SUBCONVERSATION_ID.CONFERENCE;
39
+ const groupId = 'groupID';
40
+ subconversationGroupIdStore_1.subconversationGroupIdStore.storeGroupId(conversationId, subconversation, groupId);
41
+ expect(subconversationGroupIdStore_1.subconversationGroupIdStore.getGroupId(conversationId, subconversation)).toEqual(groupId);
42
+ subconversationGroupIdStore_1.subconversationGroupIdStore.removeGroupId(conversationId, subconversation);
43
+ expect(subconversationGroupIdStore_1.subconversationGroupIdStore.getGroupId(conversationId, subconversation)).toBeUndefined();
44
+ });
45
+ it('retrieves all entries from the store by subconversation id', () => {
46
+ const conversationId = { domain: 'example.com', id: '123' };
47
+ const subconversation = conversation_1.SUBCONVERSATION_ID.CONFERENCE;
48
+ const groupId = 'groupID';
49
+ const conversationId2 = { domain: 'example2.com', id: '1234' };
50
+ const subconversation2 = conversation_1.SUBCONVERSATION_ID.CONFERENCE;
51
+ const groupId2 = 'groupID2';
52
+ const conversationId3 = { domain: 'example3.com', id: '12345' };
53
+ const subconversation3 = 'none';
54
+ const groupId3 = 'groupID3';
55
+ subconversationGroupIdStore_1.subconversationGroupIdStore.storeGroupId(conversationId, subconversation, groupId);
56
+ subconversationGroupIdStore_1.subconversationGroupIdStore.storeGroupId(conversationId2, subconversation2, groupId2);
57
+ subconversationGroupIdStore_1.subconversationGroupIdStore.storeGroupId(conversationId3, subconversation3, groupId3);
58
+ const result = subconversationGroupIdStore_1.subconversationGroupIdStore.getAllGroupIdsBySubconversationId(conversation_1.SUBCONVERSATION_ID.CONFERENCE);
59
+ expect(result).toEqual([
60
+ {
61
+ parentConversation: conversationId,
62
+ subconversation: subconversation,
63
+ subconversationGroupId: groupId,
64
+ },
65
+ {
66
+ parentConversation: conversationId2,
67
+ subconversation: subconversation2,
68
+ subconversationGroupId: groupId2,
69
+ },
70
+ ]);
71
+ });
72
+ });
@@ -8,6 +8,12 @@ import type { AddUsersToProteusConversationParams, CreateProteusConversationPara
8
8
  import { SendResult } from '../../../conversation';
9
9
  import type { EventHandlerResult } from '../../common.types';
10
10
  import { EventHandlerParams } from '../EventHandler';
11
+ type EncryptionResult = {
12
+ /** the encrypted payloads for the clients that have a valid sessions */
13
+ payloads: OTRRecipients<Uint8Array>;
14
+ /** user-client that do not have prekeys on backend (deleted clients) */
15
+ unknowns?: UserClients;
16
+ };
11
17
  export declare class ProteusService {
12
18
  private readonly apiClient;
13
19
  private readonly cryptoClient;
@@ -35,9 +41,13 @@ export declare class ProteusService {
35
41
  addUsersToConversation({ conversationId, qualifiedUserIds }: AddUsersToProteusConversationParams): Promise<import("@wireapp/api-client/lib/event").ConversationMemberJoinEvent>;
36
42
  sendMessage({ userIds, sendAsProtobuf, conversationId, nativePush, targetMode, payload, onClientMismatch, }: SendProteusMessageParams): Promise<SendResult>;
37
43
  private decrypt;
38
- encrypt(plainText: Uint8Array, recipients: UserPreKeyBundleMap | UserClients, domain?: string): Promise<OTRRecipients<Uint8Array>>;
44
+ encrypt(plainText: Uint8Array, recipients: UserPreKeyBundleMap | UserClients, domain?: string): Promise<EncryptionResult>;
39
45
  deleteSession(userId: QualifiedId, clientId: string): Promise<void>;
40
- encryptQualified(plainText: Uint8Array, preKeyBundles: QualifiedUserPreKeyBundleMap | QualifiedUserClients): Promise<QualifiedOTRRecipients>;
46
+ encryptQualified(plainText: Uint8Array, preKeyBundles: QualifiedUserPreKeyBundleMap | QualifiedUserClients): Promise<{
47
+ payloads: QualifiedOTRRecipients;
48
+ unknowns?: QualifiedUserClients;
49
+ }>;
41
50
  wipe(storeEngine?: CRUDEngine): Promise<void>;
42
51
  }
52
+ export {};
43
53
  //# sourceMappingURL=ProteusService.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"ProteusService.d.ts","sourceRoot":"","sources":["../../../../src/messagingProtocols/proteus/ProteusService/ProteusService.ts"],"names":[],"mappings":"AAmBA,OAAO,KAAK,EAAC,SAAS,EAAC,MAAM,mCAAmC,CAAC;AACjE,OAAO,KAAK,EAAC,MAAM,EAAE,OAAO,EAAC,MAAM,8BAA8B,CAAC;AAClE,OAAO,KAAK,EACV,YAAY,EAEZ,aAAa,EACb,sBAAsB,EACtB,oBAAoB,EACpB,WAAW,EACZ,MAAM,sCAAsC,CAAC;AAC9C,OAAO,KAAK,EAAC,WAAW,EAAE,4BAA4B,EAAE,mBAAmB,EAAC,MAAM,8BAA8B,CAAC;AAIjH,OAAO,EAAC,UAAU,EAAC,MAAM,uBAAuB,CAAC;AAEjD,OAAO,EAAC,YAAY,EAAC,MAAM,gBAAgB,CAAC;AAI5C,OAAO,KAAK,EACV,mCAAmC,EACnC,+BAA+B,EAC/B,oBAAoB,EACpB,wBAAwB,EACzB,MAAM,wBAAwB,CAAC;AAGhC,OAAO,EAA0C,UAAU,EAAC,MAAM,uBAAuB,CAAC;AAE1F,OAAO,KAAK,EAAC,kBAAkB,EAAC,MAAM,oBAAoB,CAAC;AAC3D,OAAO,EAAC,kBAAkB,EAAqB,MAAM,iBAAiB,CAAC;AAWvE,qBAAa,cAAc;IAKvB,OAAO,CAAC,QAAQ,CAAC,SAAS;IAC1B,OAAO,CAAC,QAAQ,CAAC,YAAY;IAC7B,OAAO,CAAC,QAAQ,CAAC,MAAM;IANzB,OAAO,CAAC,QAAQ,CAAC,cAAc,CAAiB;IAChD,OAAO,CAAC,QAAQ,CAAC,MAAM,CAA2C;gBAG/C,SAAS,EAAE,SAAS,EACpB,YAAY,EAAE,YAAY,EAC1B,MAAM,EAAE,oBAAoB;IAKlC,WAAW,CAAC,MAAM,EAAE,IAAI,CAAC,kBAAkB,EAAE,OAAO,GAAG,QAAQ,GAAG,QAAQ,CAAC,GAAG,kBAAkB;IAiBhG,UAAU,CAAC,WAAW,EAAE,UAAU,EAAE,OAAO,EAAE,OAAO;IA0B1D,YAAY,CAAC,OAAO,CAAC,EAAE,UAAU;IAIxC;;OAEG;IACI,mBAAmB;IAInB,kBAAkB,CAAC,MAAM,EAAE,MAAM,GAAG,WAAW,EAAE,QAAQ,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,MAAM,GAAG,MAAM;IAIlG;;;;;;OAMG;IACU,oBAAoB,CAAC,MAAM,EAAE,WAAW,EAAE,QAAQ,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,MAAM;IAQ3E,kBAAkB,CAAC,EAC9B,gBAAgB,EAChB,YAAY,GACb,EAAE,+BAA+B,GAAG,OAAO,CAAC,YAAY,CAAC;IAiB7C,sBAAsB,CAAC,EAAC,cAAc,EAAE,gBAAgB,EAAC,EAAE,mCAAmC;IAI9F,WAAW,CAAC,EACvB,OAAO,EACP,cAAc,EACd,cAAc,EACd,UAAU,EACV,UAAU,EACV,OAAO,EACP,gBAAgB,GACjB,EAAE,wBAAwB,GAAG,OAAO,CAAC,UAAU,CAAC;YAmDnC,OAAO;IAuBR,OAAO,CAClB,SAAS,EAAE,UAAU,EACrB,UAAU,EAAE,mBAAmB,GAAG,WAAW,EAC7C,MAAM,GAAE,MAAW,GAClB,OAAO,CAAC,aAAa,CAAC,UAAU,CAAC,CAAC;IAc9B,aAAa,CAAC,MAAM,EAAE,WAAW,EAAE,QAAQ,EAAE,MAAM;IAS7C,gBAAgB,CAC3B,SAAS,EAAE,UAAU,EACrB,aAAa,EAAE,4BAA4B,GAAG,oBAAoB,GACjE,OAAO,CAAC,sBAAsB,CAAC;IAW5B,IAAI,CAAC,WAAW,CAAC,EAAE,UAAU;CAMpC"}
1
+ {"version":3,"file":"ProteusService.d.ts","sourceRoot":"","sources":["../../../../src/messagingProtocols/proteus/ProteusService/ProteusService.ts"],"names":[],"mappings":"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"}
@@ -179,7 +179,7 @@ class ProteusService {
179
179
  }
180
180
  }
181
181
  async encrypt(plainText, recipients, domain = '') {
182
- const sessions = await (0, SessionHandler_1.initSessions)({
182
+ const { sessions, unknowns } = await (0, SessionHandler_1.initSessions)({
183
183
  recipients,
184
184
  domain,
185
185
  apiClient: this.apiClient,
@@ -187,7 +187,7 @@ class ProteusService {
187
187
  logger: this.logger,
188
188
  });
189
189
  const payload = await this.cryptoClient.encrypt(sessions, plainText);
190
- return (0, SessionHandler_1.buildEncryptedPayloads)(payload);
190
+ return { payloads: (0, SessionHandler_1.buildEncryptedPayloads)(payload), unknowns };
191
191
  }
192
192
  deleteSession(userId, clientId) {
193
193
  return (0, SessionHandler_1.deleteSession)({
@@ -199,11 +199,18 @@ class ProteusService {
199
199
  }
200
200
  async encryptQualified(plainText, preKeyBundles) {
201
201
  const qualifiedOTRRecipients = {};
202
+ const missingRecipients = {};
202
203
  for (const [domain, preKeyBundleMap] of Object.entries(preKeyBundles)) {
203
- const result = await this.encrypt(plainText, preKeyBundleMap, domain);
204
- qualifiedOTRRecipients[domain] = result;
204
+ const { unknowns, payloads } = await this.encrypt(plainText, preKeyBundleMap, domain);
205
+ qualifiedOTRRecipients[domain] = payloads;
206
+ if (unknowns) {
207
+ missingRecipients[domain] = unknowns;
208
+ }
205
209
  }
206
- return qualifiedOTRRecipients;
210
+ return {
211
+ payloads: qualifiedOTRRecipients,
212
+ unknowns: Object.keys(missingRecipients).length > 0 ? missingRecipients : undefined,
213
+ };
207
214
  }
208
215
  async wipe(storeEngine) {
209
216
  if (storeEngine) {
@@ -231,9 +231,9 @@ describe('ProteusService', () => {
231
231
  ]);
232
232
  jest.spyOn(services.cryptoClient, 'sessionExists').mockResolvedValue(true);
233
233
  jest.spyOn(services.cryptoClient, 'encrypt').mockImplementationOnce(() => Promise.resolve(encryptedPayload));
234
- const encrypted = await services.proteusService.encrypt(messageBuffer, userClients);
234
+ const { payloads } = await services.proteusService.encrypt(messageBuffer, userClients);
235
235
  expect(services.cryptoClient.encrypt).toHaveBeenCalledWith([firstUser.sessions.first, firstUser.sessions.second], messageBuffer);
236
- expect(encrypted).toEqual({
236
+ expect(payloads).toEqual({
237
237
  [firstUser.id]: {
238
238
  [firstUser.clients.first]: encryptedMessageBuffer,
239
239
  [firstUser.clients.second]: encryptedMessageBuffer,
@@ -253,9 +253,9 @@ describe('ProteusService', () => {
253
253
  ]);
254
254
  jest.spyOn(services.cryptoClient, 'sessionExists').mockResolvedValue(true);
255
255
  jest.spyOn(services.cryptoClient, 'encrypt').mockResolvedValueOnce(encryptedPayload);
256
- const encrypted = await services.proteusService.encrypt(messageBuffer, userClients);
256
+ const { payloads } = await services.proteusService.encrypt(messageBuffer, userClients);
257
257
  expect(services.cryptoClient.encrypt).toHaveBeenCalledWith([firstUser.sessions.first, firstUser.sessions.second, secondUser.sessions.first], messageBuffer);
258
- expect(encrypted).toEqual({
258
+ expect(payloads).toEqual({
259
259
  [firstUser.id]: {
260
260
  [firstUser.clients.first]: encryptedMessageBuffer,
261
261
  [firstUser.clients.second]: encryptedMessageBuffer,
@@ -280,10 +280,10 @@ describe('ProteusService', () => {
280
280
  ]);
281
281
  jest.spyOn(services.cryptoClient, 'sessionExists').mockResolvedValue(true);
282
282
  jest.spyOn(services.cryptoClient, 'encrypt').mockResolvedValueOnce(encryptedPayload);
283
- const encrypted = await services.proteusService.encryptQualified(messageBuffer, userClients);
283
+ const { payloads } = await services.proteusService.encryptQualified(messageBuffer, userClients);
284
284
  // console.log({encrypted, missing});
285
285
  expect(services.cryptoClient.encrypt).toHaveBeenCalledWith([firstUser.sessions.first, firstUser.sessions.second], messageBuffer);
286
- expect(encrypted).toEqual({
286
+ expect(payloads).toEqual({
287
287
  [domain]: {
288
288
  [firstUser.id]: {
289
289
  [firstUser.clients.first]: encryptedMessageBuffer,
@@ -307,9 +307,62 @@ describe('ProteusService', () => {
307
307
  ]);
308
308
  jest.spyOn(services.cryptoClient, 'sessionExists').mockResolvedValue(true);
309
309
  jest.spyOn(services.cryptoClient, 'encrypt').mockResolvedValueOnce(encryptedPayload);
310
- const encrypted = await services.proteusService.encryptQualified(messageBuffer, userClients);
310
+ const { payloads } = await services.proteusService.encryptQualified(messageBuffer, userClients);
311
311
  expect(services.cryptoClient.encrypt).toHaveBeenCalledWith([firstUser.sessions.first, firstUser.sessions.second, secondUser.sessions.first], messageBuffer);
312
- expect(encrypted).toEqual({
312
+ expect(payloads).toEqual({
313
+ [domain]: {
314
+ [firstUser.id]: {
315
+ [firstUser.clients.first]: encryptedMessageBuffer,
316
+ [firstUser.clients.second]: encryptedMessageBuffer,
317
+ },
318
+ [secondUser.id]: {
319
+ [secondUser.clients.first]: encryptedMessageBuffer,
320
+ },
321
+ },
322
+ });
323
+ });
324
+ it('returns the unknown clients that are deleted on backend', async () => {
325
+ const { services, data: { firstUser, secondUser, encryptedMessageBuffer, messageBuffer, domain }, } = await prepareDataForEncryption();
326
+ const userClients = {
327
+ [domain]: {
328
+ [firstUser.id]: [firstUser.clients.first, firstUser.clients.second],
329
+ [secondUser.id]: [secondUser.clients.first],
330
+ },
331
+ };
332
+ const encryptedPayload = new Map([
333
+ [firstUser.sessions.first, encryptedMessageBuffer],
334
+ [firstUser.sessions.second, encryptedMessageBuffer],
335
+ [secondUser.sessions.first, encryptedMessageBuffer],
336
+ ]);
337
+ jest.spyOn(services.apiClient.api.user, 'postQualifiedMultiPreKeyBundles').mockResolvedValue({
338
+ [domain]: {
339
+ [firstUser.id]: {
340
+ [firstUser.clients.first]: null,
341
+ [firstUser.clients.second]: {
342
+ id: 123,
343
+ key: 'pQABARhIAqEAWCCaJpFa9c626ORmjj1aV6OnOYgmTjfoiE3ynOfNfGAOmgOhAKEAWCD60VMzRrLfO+1GSjgyhnVp2N7L58DM+eeJhZJi1tBLfQT2',
344
+ },
345
+ },
346
+ [secondUser.id]: {
347
+ [secondUser.clients.first]: {
348
+ id: 123,
349
+ key: 'pQABARhIAqEAWCCaJpFa9c626ORmjj1aV6OnOYgmTjfoiE3ynOfNfGAOmgOhAKEAWCD60VMzRrLfO+1GSjgyhnVp2N7L58DM+eeJhZJi1tBLfQT2',
350
+ },
351
+ },
352
+ },
353
+ });
354
+ jest.spyOn(services.cryptoClient, 'sessionExists').mockResolvedValue(false);
355
+ jest.spyOn(services.cryptoClient, 'encrypt').mockResolvedValueOnce(encryptedPayload);
356
+ jest.spyOn(services.cryptoClient, 'sessionFromPrekey').mockResolvedValue();
357
+ jest.spyOn(services.cryptoClient, 'saveSession').mockResolvedValue();
358
+ const { payloads, unknowns } = await services.proteusService.encryptQualified(messageBuffer, userClients);
359
+ expect(services.cryptoClient.encrypt).toHaveBeenCalledWith([firstUser.sessions.second, secondUser.sessions.first], messageBuffer);
360
+ expect(unknowns).toEqual({
361
+ [domain]: {
362
+ [firstUser.id]: [firstUser.clients.first],
363
+ },
364
+ });
365
+ expect(payloads).toEqual({
313
366
  [domain]: {
314
367
  [firstUser.id]: {
315
368
  [firstUser.clients.first]: encryptedMessageBuffer,
@@ -10,6 +10,12 @@ interface ConstructSessionIdParams {
10
10
  useQualifiedIds: boolean;
11
11
  domain?: string;
12
12
  }
13
+ type InitSessionsResult = {
14
+ /** valid sessions that either already existed or have been freshly created */
15
+ sessions: string[];
16
+ /** client that do we do not have sessions with and that do not have existence on backend (deleted clients) */
17
+ unknowns?: UserClients;
18
+ };
13
19
  declare const constructSessionId: ({ userId, clientId, useQualifiedIds, domain }: ConstructSessionIdParams) => string;
14
20
  /**
15
21
  * Will make sure the session is available in cryptoClient
@@ -33,7 +39,7 @@ interface GetSessionsAndClientsFromRecipientsProps {
33
39
  /**
34
40
  * Will make sure all the sessions need to encrypt for those user/clients pair are set
35
41
  */
36
- declare const initSessions: ({ recipients, domain, apiClient, cryptoClient, logger, }: GetSessionsAndClientsFromRecipientsProps) => Promise<string[]>;
42
+ declare const initSessions: ({ recipients, domain, apiClient, cryptoClient, logger, }: GetSessionsAndClientsFromRecipientsProps) => Promise<InitSessionsResult>;
37
43
  interface DeleteSessionParams {
38
44
  userId: QualifiedId;
39
45
  clientId: string;
@@ -1 +1 @@
1
- {"version":3,"file":"SessionHandler.d.ts","sourceRoot":"","sources":["../../../../../src/messagingProtocols/proteus/Utility/SessionHandler/SessionHandler.ts"],"names":[],"mappings":"AAmBA,OAAO,EAAC,MAAM,EAAC,MAAM,8BAA8B,CAAC;AACpD,OAAO,EAAC,WAAW,EAAC,MAAM,sCAAsC,CAAC;AACjE,OAAO,EAAC,WAAW,EAAE,mBAAmB,EAAC,MAAM,8BAA8B,CAAC;AAE9E,OAAO,EAAC,MAAM,EAAC,MAAM,SAAS,CAAC;AAE/B,OAAO,EAAC,SAAS,EAAC,MAAM,qBAAqB,CAAC;AAK9C,OAAO,EAAC,YAAY,EAAC,MAAM,mCAAmC,CAAC;AAE/D,UAAU,wBAAwB;IAChC,MAAM,EAAE,MAAM,GAAG,WAAW,CAAC;IAC7B,QAAQ,EAAE,MAAM,CAAC;IACjB,eAAe,EAAE,OAAO,CAAC;IACzB,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,QAAA,MAAM,kBAAkB,kDAAiD,wBAAwB,KAAG,MAKnG,CAAC;AAuFF;;;GAGG;AACH,QAAA,MAAM,WAAW;YAC6B,WAAW;cAAY,MAAM;;;eAClC,SAAS;kBAAgB,YAAY;MAC3E,QAAQ,MAAM,CAShB,CAAC;AAyBF,UAAU,wCAAwC;IAChD,UAAU,EAAE,WAAW,GAAG,mBAAmB,CAAC;IAC9C,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,SAAS,EAAE,SAAS,CAAC;IACrB,YAAY,EAAE,YAAY,CAAC;IAC3B,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED;;GAEG;AACH,QAAA,MAAM,YAAY,6DAMf,wCAAwC,KAAG,QAAQ,MAAM,EAAE,CA+C7D,CAAC;AAEF,UAAU,mBAAmB;IAC3B,MAAM,EAAE,WAAW,CAAC;IACpB,QAAQ,EAAE,MAAM,CAAC;IACjB,YAAY,EAAE,YAAY,CAAC;IAC3B,eAAe,EAAE,OAAO,CAAC;CAC1B;AACD,iBAAe,aAAa,CAAC,MAAM,EAAE,mBAAmB,iBAGvD;AA+CD,KAAK,iBAAiB,CAAC,CAAC,IAAI,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,CAAC;AAC9D;;GAEG;AACH,QAAA,MAAM,sBAAsB,uDAO3B,CAAC;AAEF,OAAO,EAAC,kBAAkB,EAAE,WAAW,EAAE,YAAY,EAAE,aAAa,EAAE,sBAAsB,EAAC,CAAC"}
1
+ {"version":3,"file":"SessionHandler.d.ts","sourceRoot":"","sources":["../../../../../src/messagingProtocols/proteus/Utility/SessionHandler/SessionHandler.ts"],"names":[],"mappings":"AAmBA,OAAO,EAAC,MAAM,EAAC,MAAM,8BAA8B,CAAC;AACpD,OAAO,EAAC,WAAW,EAAC,MAAM,sCAAsC,CAAC;AACjE,OAAO,EAAC,WAAW,EAAE,mBAAmB,EAAC,MAAM,8BAA8B,CAAC;AAE9E,OAAO,EAAC,MAAM,EAAC,MAAM,SAAS,CAAC;AAE/B,OAAO,EAAC,SAAS,EAAC,MAAM,qBAAqB,CAAC;AAK9C,OAAO,EAAC,YAAY,EAAC,MAAM,mCAAmC,CAAC;AAE/D,UAAU,wBAAwB;IAChC,MAAM,EAAE,MAAM,GAAG,WAAW,CAAC;IAC7B,QAAQ,EAAE,MAAM,CAAC;IACjB,eAAe,EAAE,OAAO,CAAC;IACzB,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,KAAK,kBAAkB,GAAG;IACxB,8EAA8E;IAC9E,QAAQ,EAAE,MAAM,EAAE,CAAC;IACnB,8GAA8G;IAC9G,QAAQ,CAAC,EAAE,WAAW,CAAC;CACxB,CAAC;AAEF,QAAA,MAAM,kBAAkB,kDAAiD,wBAAwB,KAAG,MAKnG,CAAC;AAqFF;;;GAGG;AACH,QAAA,MAAM,WAAW;YAC6B,WAAW;cAAY,MAAM;;;eAClC,SAAS;kBAAgB,YAAY;MAC3E,QAAQ,MAAM,CAShB,CAAC;AAiBF,UAAU,wCAAwC;IAChD,UAAU,EAAE,WAAW,GAAG,mBAAmB,CAAC;IAC9C,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,SAAS,EAAE,SAAS,CAAC;IACrB,YAAY,EAAE,YAAY,CAAC;IAC3B,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED;;GAEG;AACH,QAAA,MAAM,YAAY,6DAMf,wCAAwC,KAAG,QAAQ,kBAAkB,CAmDvE,CAAC;AAEF,UAAU,mBAAmB;IAC3B,MAAM,EAAE,WAAW,CAAC;IACpB,QAAQ,EAAE,MAAM,CAAC;IACjB,YAAY,EAAE,YAAY,CAAC;IAC3B,eAAe,EAAE,OAAO,CAAC;CAC1B;AACD,iBAAe,aAAa,CAAC,MAAM,EAAE,mBAAmB,iBAGvD;AA4CD,KAAK,iBAAiB,CAAC,CAAC,IAAI,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,CAAC;AAC9D;;GAEG;AACH,QAAA,MAAM,sBAAsB,uDAO3B,CAAC;AAEF,OAAO,EAAC,kBAAkB,EAAE,WAAW,EAAE,YAAY,EAAE,aAAa,EAAE,sBAAsB,EAAC,CAAC"}
@@ -43,13 +43,12 @@ const parseSessionId = (sessionId) => {
43
43
  }
44
44
  return match.groups;
45
45
  };
46
- const createLegacySessions = async ({ userClients, apiClient, cryptoClient, logger, }) => {
46
+ const createLegacySessions = async ({ userClients, apiClient, cryptoClient, }) => {
47
47
  const preKeyBundleMap = await apiClient.api.user.postMultiPreKeyBundles(userClients);
48
48
  const sessions = await createSessionsFromPreKeys({
49
49
  preKeyBundleMap,
50
50
  useQualifiedIds: false,
51
51
  cryptoClient,
52
- logger,
53
52
  });
54
53
  return sessions;
55
54
  };
@@ -57,21 +56,22 @@ const createLegacySessions = async ({ userClients, apiClient, cryptoClient, logg
57
56
  * Create sessions for the qualified clients.
58
57
  * @param {userClientMap} map of domain to (map of user IDs to client IDs)
59
58
  */
60
- const createQualifiedSessions = async ({ userClientMap, domain, apiClient, cryptoClient, logger, }) => {
59
+ const createQualifiedSessions = async ({ userClientMap, domain, apiClient, cryptoClient, }) => {
61
60
  const prekeyBundleMap = await apiClient.api.user.postQualifiedMultiPreKeyBundles({ [domain]: userClientMap });
62
61
  const sessions = [];
62
+ let unknowns = {};
63
63
  for (const domain in prekeyBundleMap) {
64
64
  const domainUsers = prekeyBundleMap[domain];
65
- const domainSessions = await createSessionsFromPreKeys({
65
+ const { sessions: createdSessions, unknowns: domainUnknowns } = await createSessionsFromPreKeys({
66
66
  preKeyBundleMap: domainUsers,
67
67
  domain,
68
68
  useQualifiedIds: true,
69
69
  cryptoClient,
70
- logger,
71
70
  });
72
- sessions.push(...domainSessions);
71
+ sessions.push(...createdSessions);
72
+ unknowns = Object.assign(Object.assign({}, unknowns), domainUnknowns);
73
73
  }
74
- return sessions;
74
+ return { sessions, unknowns };
75
75
  };
76
76
  /**
77
77
  * Will make sure the session is available in cryptoClient
@@ -79,7 +79,7 @@ const createQualifiedSessions = async ({ userClientMap, domain, apiClient, crypt
79
79
  */
80
80
  const initSession = async ({ userId, clientId, initialPrekey }, { cryptoClient, apiClient }) => {
81
81
  const recipients = initialPrekey ? { [userId.id]: { [clientId]: initialPrekey } } : { [userId.id]: [clientId] };
82
- const sessions = await initSessions({
82
+ const { sessions } = await initSessions({
83
83
  recipients,
84
84
  domain: userId.domain,
85
85
  apiClient,
@@ -93,16 +93,14 @@ exports.initSession = initSession;
93
93
  * Will call createQualifiedSessions or createLegacySessions based on passed userClientMap.
94
94
  * @param {userClientMap} map of domain to (map of user IDs to client IDs) or map of user IDs containg the lists of clients
95
95
  */
96
- const createSessions = async ({ userClientMap, domain, apiClient, cryptoClient, logger, }) => {
97
- if (domain) {
98
- return await createQualifiedSessions({ userClientMap, domain, apiClient, cryptoClient, logger });
99
- }
100
- return await createLegacySessions({
101
- userClients: userClientMap,
102
- apiClient,
103
- cryptoClient,
104
- logger,
105
- });
96
+ const createSessions = async ({ userClientMap, domain, apiClient, cryptoClient, logger }) => {
97
+ return domain
98
+ ? createQualifiedSessions({ userClientMap, domain, apiClient, cryptoClient, logger })
99
+ : createLegacySessions({
100
+ userClients: userClientMap,
101
+ apiClient,
102
+ cryptoClient,
103
+ });
106
104
  };
107
105
  /**
108
106
  * Will make sure all the sessions need to encrypt for those user/clients pair are set
@@ -130,15 +128,15 @@ const initSessions = async ({ recipients, domain = '', apiClient, cryptoClient,
130
128
  missingClients[userId.id].push(clientId);
131
129
  }
132
130
  }
133
- const newPrekeySessions = Object.keys(missingClientsWithPrekeys).length > 0
131
+ const { sessions: prekeyCreated, unknowns: prekeyUnknows } = Object.keys(missingClientsWithPrekeys).length > 0
134
132
  ? await createSessionsFromPreKeys({
135
133
  preKeyBundleMap: missingClientsWithPrekeys,
136
134
  domain,
137
135
  useQualifiedIds: !!domain,
138
136
  cryptoClient,
139
137
  })
140
- : [];
141
- const newSessions = Object.keys(missingClients).length > 0
138
+ : { sessions: [], unknowns: {} };
139
+ const { sessions: created, unknowns } = Object.keys(missingClients).length > 0
142
140
  ? await createSessions({
143
141
  userClientMap: missingClients,
144
142
  domain,
@@ -146,8 +144,12 @@ const initSessions = async ({ recipients, domain = '', apiClient, cryptoClient,
146
144
  cryptoClient,
147
145
  logger,
148
146
  })
149
- : [];
150
- return [...existingSessions, ...newPrekeySessions, ...newSessions];
147
+ : { sessions: [], unknowns: {} };
148
+ const allUnknowns = Object.assign(Object.assign({}, prekeyUnknows), unknowns);
149
+ return {
150
+ sessions: [...existingSessions, ...prekeyCreated, ...created],
151
+ unknowns: Object.keys(allUnknowns).length > 0 ? allUnknowns : undefined,
152
+ };
151
153
  };
152
154
  exports.initSessions = initSessions;
153
155
  async function deleteSession(params) {
@@ -155,15 +157,17 @@ async function deleteSession(params) {
155
157
  await params.cryptoClient.deleteSession(sessionId);
156
158
  }
157
159
  exports.deleteSession = deleteSession;
158
- const createSessionsFromPreKeys = async ({ preKeyBundleMap, domain = '', useQualifiedIds, cryptoClient, logger, }) => {
160
+ const createSessionsFromPreKeys = async ({ preKeyBundleMap, domain = '', useQualifiedIds, cryptoClient, }) => {
159
161
  const sessions = [];
162
+ const unknowns = {};
160
163
  for (const userId in preKeyBundleMap) {
161
164
  const userClients = preKeyBundleMap[userId];
162
165
  for (const clientId in userClients) {
163
166
  const sessionId = constructSessionId({ userId, clientId, domain, useQualifiedIds });
164
167
  const prekey = userClients[clientId];
165
168
  if (!prekey) {
166
- logger === null || logger === void 0 ? void 0 : logger.warn(`A prekey for client ${clientId} of user ${userId}${domain ? ` on domain ${domain}` : ''} was not found, session won't be created.`);
169
+ unknowns[userId] = unknowns[userId] || [];
170
+ unknowns[userId].push(clientId);
167
171
  continue;
168
172
  }
169
173
  const prekeyBuffer = bazinga64_1.Decoder.fromBase64(prekey.key).asBytes;
@@ -172,7 +176,7 @@ const createSessionsFromPreKeys = async ({ preKeyBundleMap, domain = '', useQual
172
176
  sessions.push(sessionId);
173
177
  }
174
178
  }
175
- return sessions;
179
+ return { sessions, unknowns };
176
180
  };
177
181
  /**
178
182
  * creates an encrypted payload that can be sent to backend from a bunch of sessionIds/encrypted payload
@@ -27,9 +27,7 @@ function generatePrekeys(userId, clientIds) {
27
27
  key: 'pQABARn//wKhAFggJ1Fbpg5l6wnzKOJE+vXpRnkqUYhIvVnR5lNXEbO2o/0DoQChAFggHxZvgvtDktY/vqBcpjjo6rQnXvcNQhfwmy8AJQJKlD0E9g==',
28
28
  } });
29
29
  }, {});
30
- return {
31
- [userId.id]: Object.assign({}, clients),
32
- };
30
+ return { [userId.id]: clients };
33
31
  }
34
32
  describe('SessionHandler', () => {
35
33
  const cryptoClient = {
@@ -134,7 +132,7 @@ describe('SessionHandler', () => {
134
132
  .spyOn(cryptoClient, 'sessionExists')
135
133
  .mockImplementation(sessionId => Promise.resolve(sessionId.includes('missing')));
136
134
  const sessionFromPrekeySpy = jest.spyOn(cryptoClient, 'sessionFromPrekey');
137
- const sessions = await (0, SessionHandler_1.initSessions)({
135
+ const { sessions } = await (0, SessionHandler_1.initSessions)({
138
136
  recipients: Object.assign(Object.assign({}, existingUserClients), missingUserClients),
139
137
  apiClient,
140
138
  cryptoClient,
@@ -142,5 +140,20 @@ describe('SessionHandler', () => {
142
140
  expect(sessionFromPrekeySpy).toHaveBeenCalledTimes(3);
143
141
  expect(sessions).toHaveLength(6);
144
142
  });
143
+ it('returns the list of deleted clients (clients with null prekeys)', async () => {
144
+ const userClients = {
145
+ 'existing-user1': ['client1', 'deleteclient'],
146
+ };
147
+ const allKeys = generatePrekeys({ id: 'existing-user1', domain: '' }, ['client1']);
148
+ allKeys['existing-user1']['deleteclient'] = null;
149
+ jest.spyOn(apiClient.api.user, 'postMultiPreKeyBundles').mockResolvedValue(allKeys);
150
+ const { sessions, unknowns } = await (0, SessionHandler_1.initSessions)({
151
+ recipients: userClients,
152
+ apiClient,
153
+ cryptoClient,
154
+ });
155
+ expect(sessions).toEqual(['existing-user1@client1']);
156
+ expect(unknowns).toEqual({ 'existing-user1': ['deleteclient'] });
157
+ });
145
158
  });
146
159
  });
package/package.json CHANGED
@@ -11,7 +11,7 @@
11
11
  "./lib/cryptography/AssetCryptography/crypto.node": "./lib/cryptography/AssetCryptography/crypto.browser.js"
12
12
  },
13
13
  "dependencies": {
14
- "@wireapp/api-client": "^22.16.0",
14
+ "@wireapp/api-client": "^22.17.1",
15
15
  "@wireapp/commons": "^5.0.4",
16
16
  "@wireapp/core-crypto": "0.6.2",
17
17
  "@wireapp/cryptobox": "12.8.0",
@@ -19,7 +19,7 @@
19
19
  "@wireapp/protocol-messaging": "1.44.0",
20
20
  "@wireapp/store-engine": "5.0.3",
21
21
  "@wireapp/store-engine-dexie": "^2.0.5",
22
- "axios": "1.3.3",
22
+ "axios": "1.3.4",
23
23
  "bazinga64": "6.0.4",
24
24
  "hash.js": "1.1.7",
25
25
  "http-status-codes": "2.2.0",
@@ -60,6 +60,6 @@
60
60
  "test:coverage": "jest --coverage",
61
61
  "watch": "tsc --watch"
62
62
  },
63
- "version": "38.14.3",
64
- "gitHead": "abc28cc952a2154ede6ba475b7ccc780b7f3b20d"
63
+ "version": "38.15.1",
64
+ "gitHead": "353f67900d1a7019061fa656574f3c5fd7a285c6"
65
65
  }
@@ -1,4 +0,0 @@
1
- import { QualifiedId } from '@wireapp/api-client/lib/user';
2
- export declare function storeSubconversationGroupId(parentConversation: QualifiedId, subconversation: string, subgroupId: string): void;
3
- export declare function getGroupId(parentConversation: QualifiedId, subconversation: string): string | undefined;
4
- //# sourceMappingURL=subconversationGroupIdMapper.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"subconversationGroupIdMapper.d.ts","sourceRoot":"","sources":["../../../../src/messagingProtocols/mls/MLSService/subconversationGroupIdMapper.ts"],"names":[],"mappings":"AAmBA,OAAO,EAAC,WAAW,EAAC,MAAM,8BAA8B,CAAC;AAQzD,wBAAgB,2BAA2B,CACzC,kBAAkB,EAAE,WAAW,EAC/B,eAAe,EAAE,MAAM,EACvB,UAAU,EAAE,MAAM,GACjB,IAAI,CAGN;AAED,wBAAgB,UAAU,CAAC,kBAAkB,EAAE,WAAW,EAAE,eAAe,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAGvG"}
@@ -1,35 +0,0 @@
1
- "use strict";
2
- /*
3
- * Wire
4
- * Copyright (C) 2023 Wire Swiss GmbH
5
- *
6
- * This program is free software: you can redistribute it and/or modify
7
- * it under the terms of the GNU General Public License as published by
8
- * the Free Software Foundation, either version 3 of the License, or
9
- * (at your option) any later version.
10
- *
11
- * This program is distributed in the hope that it will be useful,
12
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
13
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14
- * GNU General Public License for more details.
15
- *
16
- * You should have received a copy of the GNU General Public License
17
- * along with this program. If not, see http://www.gnu.org/licenses/.
18
- *
19
- */
20
- Object.defineProperty(exports, "__esModule", { value: true });
21
- exports.getGroupId = exports.storeSubconversationGroupId = void 0;
22
- const groupIdMap = new Map();
23
- function generateSubconversationId(parentConversation, subconversation) {
24
- return `${parentConversation.id}@${parentConversation.domain}:${subconversation}`;
25
- }
26
- function storeSubconversationGroupId(parentConversation, subconversation, subgroupId) {
27
- const subconversationId = generateSubconversationId(parentConversation, subconversation);
28
- groupIdMap.set(subconversationId, subgroupId);
29
- }
30
- exports.storeSubconversationGroupId = storeSubconversationGroupId;
31
- function getGroupId(parentConversation, subconversation) {
32
- const subconversationId = generateSubconversationId(parentConversation, subconversation);
33
- return groupIdMap.get(subconversationId);
34
- }
35
- exports.getGroupId = getGroupId;
@@ -1,2 +0,0 @@
1
- export {};
2
- //# sourceMappingURL=subconversationGroupIdMapper.test.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"subconversationGroupIdMapper.test.d.ts","sourceRoot":"","sources":["../../../../src/messagingProtocols/mls/MLSService/subconversationGroupIdMapper.test.ts"],"names":[],"mappings":""}
@@ -1,35 +0,0 @@
1
- "use strict";
2
- /*
3
- * Wire
4
- * Copyright (C) 2018 Wire Swiss GmbH
5
- *
6
- * This program is free software: you can redistribute it and/or modify
7
- * it under the terms of the GNU General Public License as published by
8
- * the Free Software Foundation, either version 3 of the License, or
9
- * (at your option) any later version.
10
- *
11
- * This program is distributed in the hope that it will be useful,
12
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
13
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14
- * GNU General Public License for more details.
15
- *
16
- * You should have received a copy of the GNU General Public License
17
- * along with this program. If not, see http://www.gnu.org/licenses/.
18
- *
19
- */
20
- Object.defineProperty(exports, "__esModule", { value: true });
21
- const subconversationGroupIdMapper_1 = require("./subconversationGroupIdMapper");
22
- describe('subconversationGroupIdMapper', () => {
23
- it('returns empty groupId if conversation is not known', () => {
24
- const groupId = (0, subconversationGroupIdMapper_1.getGroupId)({ domain: 'example.com', id: '123' }, 'subconversation');
25
- expect(groupId).toBeUndefined();
26
- });
27
- it('returns the stored groupId', () => {
28
- const conversationId = { domain: 'example.com', id: '123' };
29
- const subconversation = 'subconversation';
30
- const groupId = 'groupID';
31
- (0, subconversationGroupIdMapper_1.storeSubconversationGroupId)(conversationId, subconversation, groupId);
32
- const result = (0, subconversationGroupIdMapper_1.getGroupId)({ domain: 'example.com', id: '123' }, 'subconversation');
33
- expect(result).toBe(groupId);
34
- });
35
- });