@wireapp/core 39.0.1 → 39.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,5 +1,4 @@
1
1
  import { ClientMismatch, MessageSendingStatus, QualifiedUserClients } from '@wireapp/api-client/lib/conversation';
2
- import { UserPreKeyBundleMap } from '@wireapp/api-client/lib/user/';
3
2
  import { APIClient } from '@wireapp/api-client';
4
3
  import { GenericMessage } from '@wireapp/protocol-messaging';
5
4
  import { ProteusService } from '../messagingProtocols/proteus';
@@ -8,14 +7,6 @@ export declare class BroadcastService {
8
7
  private readonly proteusService;
9
8
  private readonly messageService;
10
9
  constructor(apiClient: APIClient, proteusService: ProteusService);
11
- /**
12
- * Will create a key bundle for all the users of the team
13
- *
14
- * @param teamId
15
- * @param skipOwnClients=false
16
- * @param onlyDirectConnections=false Will generate a bundle only for directly connected users (users the self user has conversation with). Allows avoiding broadcasting messages to too many people
17
- */
18
- getPreKeyBundlesFromTeam(teamId: string, skipOwnClients?: boolean, onlyDirectConnections?: boolean): Promise<UserPreKeyBundleMap>;
19
10
  broadcastGenericMessage(genericMessage: GenericMessage, recipients: QualifiedUserClients, onClientMismatch?: (mismatch: ClientMismatch | MessageSendingStatus) => void | boolean | Promise<boolean>): Promise<ClientMismatch | MessageSendingStatus>;
20
11
  }
21
12
  //# sourceMappingURL=BroadcastService.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"BroadcastService.d.ts","sourceRoot":"","sources":["../../src/broadcast/BroadcastService.ts"],"names":[],"mappings":"AAmBA,OAAO,EAAC,cAAc,EAAE,oBAAoB,EAAE,oBAAoB,EAAC,MAAM,sCAAsC,CAAC;AAChH,OAAO,EAAC,mBAAmB,EAAC,MAAM,+BAA+B,CAAC;AAElE,OAAO,EAAC,SAAS,EAAC,MAAM,qBAAqB,CAAC;AAC9C,OAAO,EAAC,cAAc,EAAC,MAAM,6BAA6B,CAAC;AAK3D,OAAO,EAAC,cAAc,EAAC,MAAM,+BAA+B,CAAC;AAE7D,qBAAa,gBAAgB;IAGf,OAAO,CAAC,QAAQ,CAAC,SAAS;IAAa,OAAO,CAAC,QAAQ,CAAC,cAAc;IAFlF,OAAO,CAAC,QAAQ,CAAC,cAAc,CAAiB;gBAEnB,SAAS,EAAE,SAAS,EAAmB,cAAc,EAAE,cAAc;IAIlG;;;;;;OAMG;IACU,wBAAwB,CACnC,MAAM,EAAE,MAAM,EACd,cAAc,UAAQ,EACtB,qBAAqB,UAAQ,GAC5B,OAAO,CAAC,mBAAmB,CAAC;IAyBlB,uBAAuB,CAClC,cAAc,EAAE,cAAc,EAC9B,UAAU,EAAE,oBAAoB,EAChC,gBAAgB,CAAC,EAAE,CAAC,QAAQ,EAAE,cAAc,GAAG,oBAAoB,KAAK,IAAI,GAAG,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC;CAY5G"}
1
+ {"version":3,"file":"BroadcastService.d.ts","sourceRoot":"","sources":["../../src/broadcast/BroadcastService.ts"],"names":[],"mappings":"AAmBA,OAAO,EAAC,cAAc,EAAE,oBAAoB,EAAE,oBAAoB,EAAC,MAAM,sCAAsC,CAAC;AAEhH,OAAO,EAAC,SAAS,EAAC,MAAM,qBAAqB,CAAC;AAC9C,OAAO,EAAC,cAAc,EAAC,MAAM,6BAA6B,CAAC;AAK3D,OAAO,EAAC,cAAc,EAAC,MAAM,+BAA+B,CAAC;AAE7D,qBAAa,gBAAgB;IAGf,OAAO,CAAC,QAAQ,CAAC,SAAS;IAAa,OAAO,CAAC,QAAQ,CAAC,cAAc;IAFlF,OAAO,CAAC,QAAQ,CAAC,cAAc,CAAiB;gBAEnB,SAAS,EAAE,SAAS,EAAmB,cAAc,EAAE,cAAc;IAIrF,uBAAuB,CAClC,cAAc,EAAE,cAAc,EAC9B,UAAU,EAAE,oBAAoB,EAChC,gBAAgB,CAAC,EAAE,CAAC,QAAQ,EAAE,cAAc,GAAG,oBAAoB,KAAK,IAAI,GAAG,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC;CAY5G"}
@@ -29,33 +29,6 @@ class BroadcastService {
29
29
  this.proteusService = proteusService;
30
30
  this.messageService = new MessageService_1.MessageService(this.apiClient, this.proteusService);
31
31
  }
32
- /**
33
- * Will create a key bundle for all the users of the team
34
- *
35
- * @param teamId
36
- * @param skipOwnClients=false
37
- * @param onlyDirectConnections=false Will generate a bundle only for directly connected users (users the self user has conversation with). Allows avoiding broadcasting messages to too many people
38
- */
39
- async getPreKeyBundlesFromTeam(teamId, skipOwnClients = false, onlyDirectConnections = false) {
40
- const teamMembers = onlyDirectConnections
41
- ? (await this.apiClient.api.conversation.getConversations()).conversations
42
- .map(({ members }) => members.others.map(user => user.id).concat(members.self.id))
43
- .flat()
44
- : (await this.apiClient.api.teams.member.getAllMembers(teamId)).members.map(({ user }) => user);
45
- let members = Array.from(new Set(teamMembers)).map(member => ({ id: member }));
46
- if (skipOwnClients) {
47
- const selfUser = await this.apiClient.api.self.getSelf();
48
- members = members.filter(member => member.id !== selfUser.id);
49
- }
50
- const preKeys = await Promise.all(members.map(member => this.apiClient.api.user.getUserPreKeys(member.id)));
51
- return preKeys.reduce((bundleMap, bundle) => {
52
- bundleMap[bundle.user] = {};
53
- for (const client of bundle.clients) {
54
- bundleMap[bundle.user][client.client] = client.prekey;
55
- }
56
- return bundleMap;
57
- }, {});
58
- }
59
32
  async broadcastGenericMessage(genericMessage, recipients, onClientMismatch) {
60
33
  const plainTextArray = protocol_messaging_1.GenericMessage.encode(genericMessage).finish();
61
34
  const send = () => {
@@ -1 +1 @@
1
- {"version":3,"file":"MessageService.d.ts","sourceRoot":"","sources":["../../../src/conversation/message/MessageService.ts"],"names":[],"mappings":"AAmBA,OAAO,EAEL,oBAAoB,EAEpB,oBAAoB,EACrB,MAAM,sCAAsC,CAAC;AAC9C,OAAO,EAAC,WAAW,EAAE,4BAA4B,EAAC,MAAM,8BAA8B,CAAC;AAOvF,OAAO,EAAC,SAAS,EAAC,MAAM,qBAAqB,CAAC;AAI9C,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,oBAAoB,GAAG,4BAA4B,EAC/D,SAAS,EAAE,UAAU,EACrB,OAAO,GAAE;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;KACrF,GACL,OAAO,CAAC,oBAAoB,GAAG;QAAC,QAAQ,CAAC,EAAE,OAAO,CAAA;KAAC,CAAC;YAwBzC,cAAc;IAiE5B,OAAO,CAAC,qBAAqB;IAI7B;;;;;;;OAOG;YACW,sBAAsB;CAoBrC"}
1
+ {"version":3,"file":"MessageService.d.ts","sourceRoot":"","sources":["../../../src/conversation/message/MessageService.ts"],"names":[],"mappings":"AAmBA,OAAO,EAEL,oBAAoB,EAEpB,oBAAoB,EACrB,MAAM,sCAAsC,CAAC;AAC9C,OAAO,EAAC,WAAW,EAAE,4BAA4B,EAAC,MAAM,8BAA8B,CAAC;AAOvF,OAAO,EAAC,SAAS,EAAC,MAAM,qBAAqB,CAAC;AAI9C,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,oBAAoB,GAAG,4BAA4B,EAC/D,SAAS,EAAE,UAAU,EACrB,OAAO,GAAE;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;KACrF,GACL,OAAO,CAAC,oBAAoB,GAAG;QAAC,QAAQ,CAAC,EAAE,OAAO,CAAA;KAAC,CAAC;YAwBzC,cAAc;IAiE5B,OAAO,CAAC,qBAAqB;IAI7B;;;;;;;OAOG;YACW,sBAAsB;CAsBrC"}
@@ -133,7 +133,12 @@ class MessageService {
133
133
  if (Object.keys(mismatch.missing).length) {
134
134
  const { payloads } = await this.proteusService.encrypt(plainText, mismatch.missing);
135
135
  const reEncryptedPayloads = (0, UserClientsUtil_1.flattenQualifiedUserClients)(payloads);
136
- reEncryptedPayloads.forEach(({ data, userId }) => (recipients[userId.domain][userId.id] = Object.assign(Object.assign({}, recipients[userId.domain][userId.id]), data)));
136
+ reEncryptedPayloads.forEach(({ data, userId }) => {
137
+ var _a;
138
+ const domainRecipients = (_a = recipients[userId.domain]) !== null && _a !== void 0 ? _a : {};
139
+ domainRecipients[userId.id] = Object.assign(Object.assign({}, domainRecipients[userId.id]), data);
140
+ recipients[userId.domain] = domainRecipients;
141
+ });
137
142
  }
138
143
  return recipients;
139
144
  }
@@ -134,6 +134,32 @@ describe('MessageService', () => {
134
134
  failed_to_send: {},
135
135
  time: new Date().toISOString(),
136
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
+ });
137
163
  it('handles client mismatch internally if no onClientMismatch is given', async () => {
138
164
  const [messageService, { apiClient }] = await buildMessageService();
139
165
  let spyCounter = 0;
@@ -150,7 +176,9 @@ describe('MessageService', () => {
150
176
  }
151
177
  return Promise.resolve(baseClientMismatch);
152
178
  });
153
- jest.spyOn(apiClient.api.user, 'postMultiPreKeyBundles').mockReturnValue(Promise.resolve({}));
179
+ jest
180
+ .spyOn(apiClient.api.user, 'postMultiPreKeyBundles')
181
+ .mockReturnValue(Promise.resolve({ qualified_user_client_prekeys: {} }));
154
182
  const recipients = generateRecipients([user1, user2]);
155
183
  await messageService.sendMessage('senderclientid', recipients, new Uint8Array(), {
156
184
  reportMissing: true,
@@ -175,7 +203,9 @@ describe('MessageService', () => {
175
203
  }
176
204
  return Promise.resolve(baseClientMismatch);
177
205
  });
178
- jest.spyOn(apiClient.api.user, 'postMultiPreKeyBundles').mockReturnValue(Promise.resolve({}));
206
+ jest
207
+ .spyOn(apiClient.api.user, 'postMultiPreKeyBundles')
208
+ .mockReturnValue(Promise.resolve({ qualified_user_client_prekeys: {} }));
179
209
  const recipients = generateRecipients([user1, user2]);
180
210
  await messageService.sendMessage('senderclientid', recipients, new Uint8Array(), {
181
211
  reportMissing: true,
@@ -197,7 +227,9 @@ describe('MessageService', () => {
197
227
  };
198
228
  return Promise.reject(error);
199
229
  });
200
- jest.spyOn(apiClient.api.user, 'postMultiPreKeyBundles').mockReturnValue(Promise.resolve({}));
230
+ jest
231
+ .spyOn(apiClient.api.user, 'postMultiPreKeyBundles')
232
+ .mockReturnValue(Promise.resolve({ qualified_user_client_prekeys: {} }));
201
233
  const recipients = generateRecipients([user1, user2]);
202
234
  await messageService.sendMessage('senderclientid', recipients, new Uint8Array(), {
203
235
  reportMissing: true,
@@ -225,7 +257,9 @@ describe('MessageService', () => {
225
257
  }
226
258
  return Promise.resolve(baseMessageSendingStatus);
227
259
  });
228
- jest.spyOn(apiClient.api.user, 'postMultiPreKeyBundles').mockReturnValue(Promise.resolve({}));
260
+ jest
261
+ .spyOn(apiClient.api.user, 'postMultiPreKeyBundles')
262
+ .mockReturnValue(Promise.resolve({ qualified_user_client_prekeys: {} }));
229
263
  const recipients = generateQualifiedRecipients([user1, user2]);
230
264
  await messageService.sendMessage('senderclientid', recipients, new Uint8Array(), {
231
265
  reportMissing: true,
@@ -250,7 +284,9 @@ describe('MessageService', () => {
250
284
  }
251
285
  return Promise.resolve(baseMessageSendingStatus);
252
286
  });
253
- jest.spyOn(apiClient.api.user, 'postMultiPreKeyBundles').mockReturnValue(Promise.resolve({}));
287
+ jest
288
+ .spyOn(apiClient.api.user, 'postMultiPreKeyBundles')
289
+ .mockReturnValue(Promise.resolve({ qualified_user_client_prekeys: {} }));
254
290
  const recipients = generateQualifiedRecipients([user1, user2]);
255
291
  await messageService.sendMessage('senderclientid', recipients, new Uint8Array(), {
256
292
  reportMissing: true,
@@ -293,7 +329,9 @@ describe('MessageService', () => {
293
329
  };
294
330
  return Promise.reject(error);
295
331
  });
296
- jest.spyOn(apiClient.api.user, 'postMultiPreKeyBundles').mockReturnValue(Promise.resolve({}));
332
+ jest
333
+ .spyOn(apiClient.api.user, 'postMultiPreKeyBundles')
334
+ .mockReturnValue(Promise.resolve({ qualified_user_client_prekeys: {} }));
297
335
  const recipients = generateQualifiedRecipients([user1, user2]);
298
336
  await messageService.sendMessage('senderclientid', recipients, new Uint8Array(), {
299
337
  reportMissing: true,
@@ -13,6 +13,8 @@ type EncryptionResult = {
13
13
  payloads: QualifiedOTRRecipients;
14
14
  /** user-client that do not have prekeys on backend (deleted clients) */
15
15
  unknowns?: QualifiedUserClients;
16
+ /** users for whom we could retrieve a prekey and, thus, for which we could not encrypt the message */
17
+ failed?: QualifiedId[];
16
18
  };
17
19
  export declare class ProteusService {
18
20
  private readonly apiClient;
@@ -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,sBAAsB,EACtB,oBAAoB,EACrB,MAAM,sCAAsC,CAAC;AAC9C,OAAO,KAAK,EAAC,WAAW,EAAE,4BAA4B,EAAC,MAAM,8BAA8B,CAAC;AAI5F,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,KAAK,gBAAgB,GAAG;IACtB,wEAAwE;IACxE,QAAQ,EAAE,sBAAsB,CAAC;IACjC,wEAAwE;IACxE,QAAQ,CAAC,EAAE,oBAAoB,CAAC;CACjC,CAAC;AACF,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;IAyB1D,YAAY,CAAC,OAAO,CAAC,EAAE,UAAU;IAIxC;;OAEG;IACI,mBAAmB;IAInB,kBAAkB,CAAC,MAAM,EAAE,WAAW,EAAE,QAAQ,EAAE,MAAM,GAAG,MAAM;IAIxE;;;;;;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,UAAU,EACV,UAAU,EACV,OAAO,EACP,gBAAgB,GACjB,EAAE,wBAAwB,GAAG,OAAO,CAAC,UAAU,CAAC;YA0CnC,OAAO;IAuBd,aAAa,CAAC,MAAM,EAAE,WAAW,EAAE,QAAQ,EAAE,MAAM;IAQ7C,OAAO,CAClB,SAAS,EAAE,UAAU,EACrB,UAAU,EAAE,4BAA4B,GAAG,oBAAoB,GAC9D,OAAO,CAAC,gBAAgB,CAAC;IAgBtB,IAAI,CAAC,WAAW,CAAC,EAAE,UAAU;CAMpC"}
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,sBAAsB,EACtB,oBAAoB,EACrB,MAAM,sCAAsC,CAAC;AAC9C,OAAO,KAAK,EAAC,WAAW,EAAE,4BAA4B,EAAC,MAAM,8BAA8B,CAAC;AAI5F,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,KAAK,gBAAgB,GAAG;IACtB,wEAAwE;IACxE,QAAQ,EAAE,sBAAsB,CAAC;IACjC,wEAAwE;IACxE,QAAQ,CAAC,EAAE,oBAAoB,CAAC;IAChC,sGAAsG;IACtG,MAAM,CAAC,EAAE,WAAW,EAAE,CAAC;CACxB,CAAC;AACF,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;IAyB1D,YAAY,CAAC,OAAO,CAAC,EAAE,UAAU;IAIxC;;OAEG;IACI,mBAAmB;IAInB,kBAAkB,CAAC,MAAM,EAAE,WAAW,EAAE,QAAQ,EAAE,MAAM,GAAG,MAAM;IAIxE;;;;;;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,UAAU,EACV,UAAU,EACV,OAAO,EACP,gBAAgB,GACjB,EAAE,wBAAwB,GAAG,OAAO,CAAC,UAAU,CAAC;YA0CnC,OAAO;IAuBd,aAAa,CAAC,MAAM,EAAE,WAAW,EAAE,QAAQ,EAAE,MAAM;IAQ7C,OAAO,CAClB,SAAS,EAAE,UAAU,EACrB,UAAU,EAAE,4BAA4B,GAAG,oBAAoB,GAC9D,OAAO,CAAC,gBAAgB,CAAC;IAiBtB,IAAI,CAAC,WAAW,CAAC,EAAE,UAAU;CAMpC"}
@@ -181,7 +181,7 @@ class ProteusService {
181
181
  });
182
182
  }
183
183
  async encrypt(plainText, recipients) {
184
- const { sessions, unknowns } = await (0, SessionHandler_1.initSessions)({
184
+ const { sessions, unknowns, failed } = await (0, SessionHandler_1.initSessions)({
185
185
  recipients,
186
186
  apiClient: this.apiClient,
187
187
  cryptoClient: this.cryptoClient,
@@ -191,6 +191,7 @@ class ProteusService {
191
191
  return {
192
192
  payloads: (0, SessionHandler_1.buildEncryptedPayloads)(payloads),
193
193
  unknowns,
194
+ failed,
194
195
  };
195
196
  }
196
197
  async wipe(storeEngine) {
@@ -129,11 +129,13 @@ describe('ProteusService', () => {
129
129
  const userId = { id: 'user1', domain: 'domain.com' };
130
130
  const clientId = 'client1';
131
131
  jest.spyOn(apiClient.api.user, 'postMultiPreKeyBundles').mockResolvedValue({
132
- [userId.domain]: {
133
- [userId.id]: {
134
- [clientId]: {
135
- id: 123,
136
- key: 'pQABARhIAqEAWCCaJpFa9c626ORmjj1aV6OnOYgmTjfoiE3ynOfNfGAOmgOhAKEAWCD60VMzRrLfO+1GSjgyhnVp2N7L58DM+eeJhZJi1tBLfQT2',
132
+ qualified_user_client_prekeys: {
133
+ [userId.domain]: {
134
+ [userId.id]: {
135
+ [clientId]: {
136
+ id: 123,
137
+ key: 'pQABARhIAqEAWCCaJpFa9c626ORmjj1aV6OnOYgmTjfoiE3ynOfNfGAOmgOhAKEAWCD60VMzRrLfO+1GSjgyhnVp2N7L58DM+eeJhZJi1tBLfQT2',
138
+ },
137
139
  },
138
140
  },
139
141
  },
@@ -281,18 +283,20 @@ describe('ProteusService', () => {
281
283
  [secondUser.sessions.first, encryptedMessageBuffer],
282
284
  ]);
283
285
  jest.spyOn(services.apiClient.api.user, 'postMultiPreKeyBundles').mockResolvedValue({
284
- [domain]: {
285
- [firstUser.id.id]: {
286
- [firstUser.clients.first]: null,
287
- [firstUser.clients.second]: {
288
- id: 123,
289
- key: 'pQABARhIAqEAWCCaJpFa9c626ORmjj1aV6OnOYgmTjfoiE3ynOfNfGAOmgOhAKEAWCD60VMzRrLfO+1GSjgyhnVp2N7L58DM+eeJhZJi1tBLfQT2',
286
+ qualified_user_client_prekeys: {
287
+ [domain]: {
288
+ [firstUser.id.id]: {
289
+ [firstUser.clients.first]: null,
290
+ [firstUser.clients.second]: {
291
+ id: 123,
292
+ key: 'pQABARhIAqEAWCCaJpFa9c626ORmjj1aV6OnOYgmTjfoiE3ynOfNfGAOmgOhAKEAWCD60VMzRrLfO+1GSjgyhnVp2N7L58DM+eeJhZJi1tBLfQT2',
293
+ },
290
294
  },
291
- },
292
- [secondUser.id.id]: {
293
- [secondUser.clients.first]: {
294
- id: 123,
295
- key: 'pQABARhIAqEAWCCaJpFa9c626ORmjj1aV6OnOYgmTjfoiE3ynOfNfGAOmgOhAKEAWCD60VMzRrLfO+1GSjgyhnVp2N7L58DM+eeJhZJi1tBLfQT2',
295
+ [secondUser.id.id]: {
296
+ [secondUser.clients.first]: {
297
+ id: 123,
298
+ key: 'pQABARhIAqEAWCCaJpFa9c626ORmjj1aV6OnOYgmTjfoiE3ynOfNfGAOmgOhAKEAWCD60VMzRrLfO+1GSjgyhnVp2N7L58DM+eeJhZJi1tBLfQT2',
299
+ },
296
300
  },
297
301
  },
298
302
  },
@@ -2,12 +2,6 @@ import { APIClient } from '@wireapp/api-client/lib/APIClient';
2
2
  import { QualifiedUserClients, UserClients } from '@wireapp/api-client/lib/conversation';
3
3
  import { QualifiedId, QualifiedUserPreKeyBundleMap, UserPreKeyBundleMap } from '@wireapp/api-client/lib/user';
4
4
  declare const preKeyBundleToUserClients: (users: UserPreKeyBundleMap) => UserClients;
5
- interface GetPreKeyBundleMapParams {
6
- apiClient: APIClient;
7
- conversationId: QualifiedId;
8
- userIds?: string[] | QualifiedId[] | UserClients;
9
- }
10
- declare const getPreKeyBundleMap: ({ apiClient, conversationId, userIds, }: GetPreKeyBundleMapParams) => Promise<UserPreKeyBundleMap>;
11
5
  /**
12
6
  * Will generate a prekey bundle for specific users.
13
7
  * If a QualifiedId array is given the bundle will contain all the clients from those users fetched from the server.
@@ -21,5 +15,5 @@ interface GetQualifiedPreKeyBundleMapParams {
21
15
  userIds?: QualifiedId[] | QualifiedUserClients;
22
16
  }
23
17
  declare const getQualifiedPreKeyBundle: ({ apiClient, userIds, }: GetQualifiedPreKeyBundleMapParams) => Promise<QualifiedUserPreKeyBundleMap>;
24
- export { getPreKeyBundleMap, getQualifiedPreKeyBundle, preKeyBundleToUserClients };
18
+ export { getQualifiedPreKeyBundle, preKeyBundleToUserClients };
25
19
  //# sourceMappingURL=PreKeyBundle.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"PreKeyBundle.d.ts","sourceRoot":"","sources":["../../../../../src/messagingProtocols/proteus/Utility/PreKeyBundle/PreKeyBundle.ts"],"names":[],"mappings":"AAmBA,OAAO,EAAC,SAAS,EAAC,MAAM,mCAAmC,CAAC;AAC5D,OAAO,EAAC,oBAAoB,EAAE,WAAW,EAAC,MAAM,sCAAsC,CAAC;AACvF,OAAO,EAAC,WAAW,EAAE,4BAA4B,EAAE,mBAAmB,EAAC,MAAM,8BAA8B,CAAC;AAI5G,QAAA,MAAM,yBAAyB,UAAW,mBAAmB,KAAG,WAK/D,CAAC;AAEF,UAAU,wBAAwB;IAChC,SAAS,EAAE,SAAS,CAAC;IACrB,cAAc,EAAE,WAAW,CAAC;IAC5B,OAAO,CAAC,EAAE,MAAM,EAAE,GAAG,WAAW,EAAE,GAAG,WAAW,CAAC;CAClD;AACD,QAAA,MAAM,kBAAkB,4CAIrB,wBAAwB,KAAG,QAAQ,mBAAmB,CA+BxD,CAAC;AAEF;;;;;;;GAOG;AACH,UAAU,iCAAiC;IACzC,SAAS,EAAE,SAAS,CAAC;IACrB,OAAO,CAAC,EAAE,WAAW,EAAE,GAAG,oBAAoB,CAAC;CAChD;AACD,QAAA,MAAM,wBAAwB,4BAG3B,iCAAiC,KAAG,QAAQ,4BAA4B,CAoC1E,CAAC;AAEF,OAAO,EAAC,kBAAkB,EAAE,wBAAwB,EAAE,yBAAyB,EAAC,CAAC"}
1
+ {"version":3,"file":"PreKeyBundle.d.ts","sourceRoot":"","sources":["../../../../../src/messagingProtocols/proteus/Utility/PreKeyBundle/PreKeyBundle.ts"],"names":[],"mappings":"AAmBA,OAAO,EAAC,SAAS,EAAC,MAAM,mCAAmC,CAAC;AAC5D,OAAO,EAAC,oBAAoB,EAAE,WAAW,EAAC,MAAM,sCAAsC,CAAC;AACvF,OAAO,EAAC,WAAW,EAAE,4BAA4B,EAAE,mBAAmB,EAAC,MAAM,8BAA8B,CAAC;AAI5G,QAAA,MAAM,yBAAyB,UAAW,mBAAmB,KAAG,WAK/D,CAAC;AAEF;;;;;;;GAOG;AACH,UAAU,iCAAiC;IACzC,SAAS,EAAE,SAAS,CAAC;IACrB,OAAO,CAAC,EAAE,WAAW,EAAE,GAAG,oBAAoB,CAAC;CAChD;AACD,QAAA,MAAM,wBAAwB,4BAG3B,iCAAiC,KAAG,QAAQ,4BAA4B,CAoC1E,CAAC;AAEF,OAAO,EAAC,wBAAwB,EAAE,yBAAyB,EAAC,CAAC"}
@@ -18,7 +18,7 @@
18
18
  *
19
19
  */
20
20
  Object.defineProperty(exports, "__esModule", { value: true });
21
- exports.preKeyBundleToUserClients = exports.getQualifiedPreKeyBundle = exports.getPreKeyBundleMap = void 0;
21
+ exports.preKeyBundleToUserClients = exports.getQualifiedPreKeyBundle = void 0;
22
22
  const util_1 = require("../../../../util");
23
23
  const preKeyBundleToUserClients = (users) => {
24
24
  return Object.entries(users).reduce((acc, [userId, clientsObj]) => {
@@ -27,36 +27,6 @@ const preKeyBundleToUserClients = (users) => {
27
27
  }, {});
28
28
  };
29
29
  exports.preKeyBundleToUserClients = preKeyBundleToUserClients;
30
- const getPreKeyBundleMap = async ({ apiClient, conversationId, userIds = [], }) => {
31
- let members = [];
32
- if (userIds) {
33
- if ((0, util_1.isStringArray)(userIds)) {
34
- members = userIds;
35
- }
36
- else if ((0, util_1.isUserClients)(userIds)) {
37
- members = Object.keys(userIds);
38
- }
39
- }
40
- if (!members.length) {
41
- const conversation = await apiClient.api.conversation.getConversation(conversationId);
42
- /*
43
- * If you are sending a message to a conversation, you have to include
44
- * yourself in the list of users if you want to sync a message also to your
45
- * other clients.
46
- */
47
- members = conversation.members.others.map(member => member.id).concat(conversation.members.self.id);
48
- }
49
- const preKeys = await Promise.all(members.map(member => apiClient.api.user.getUserPreKeys(member)));
50
- return preKeys.reduce((bundleMap, bundle) => {
51
- const userId = bundle.user;
52
- bundleMap[userId] || (bundleMap[userId] = {});
53
- for (const client of bundle.clients) {
54
- bundleMap[userId][client.client] = client.prekey;
55
- }
56
- return bundleMap;
57
- }, {});
58
- };
59
- exports.getPreKeyBundleMap = getPreKeyBundleMap;
60
30
  const getQualifiedPreKeyBundle = async ({ apiClient, userIds, }) => {
61
31
  let targets = [];
62
32
  if (userIds) {
@@ -14,6 +14,8 @@ type InitSessionsResult = {
14
14
  sessions: string[];
15
15
  /** client that do we do not have sessions with and that do not have existence on backend (deleted clients) */
16
16
  unknowns?: QualifiedUserClients;
17
+ /** clients for which we had problem fetch prekeys (federated server down) */
18
+ failed?: QualifiedId[];
17
19
  };
18
20
  declare const constructSessionId: ({ userId, clientId }: ConstructSessionIdParams) => string;
19
21
  /**
@@ -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,oBAAoB,EAAC,MAAM,sCAAsC,CAAC;AAC1E,OAAO,EAAC,WAAW,EAAE,4BAA4B,EAAC,MAAM,8BAA8B,CAAC;AAEvF,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,WAAW,CAAC;IACpB,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,KAAK,kBAAkB,GAAG;IACxB,8EAA8E;IAC9E,QAAQ,EAAE,MAAM,EAAE,CAAC;IACnB,8GAA8G;IAC9G,QAAQ,CAAC,EAAE,oBAAoB,CAAC;CACjC,CAAC;AAEF,QAAA,MAAM,kBAAkB,yBAAwB,wBAAwB,KAAG,MAI1E,CAAC;AA6BF;;;GAGG;AACH,QAAA,MAAM,WAAW;YAC6B,WAAW;cAAY,MAAM;;;eAClC,SAAS;kBAAgB,YAAY;MAC3E,QAAQ,MAAM,CAUhB,CAAC;AAeF,UAAU,wCAAwC;IAChD,UAAU,EAAE,oBAAoB,GAAG,4BAA4B,CAAC;IAChE,SAAS,EAAE,SAAS,CAAC;IACrB,YAAY,EAAE,YAAY,CAAC;IAC3B,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED;;GAEG;AACH,QAAA,MAAM,YAAY,qDAKf,wCAAwC,KAAG,QAAQ,kBAAkB,CAoDvE,CAAC;AAEF,UAAU,mBAAmB;IAC3B,MAAM,EAAE,WAAW,CAAC;IACpB,QAAQ,EAAE,MAAM,CAAC;IACjB,YAAY,EAAE,YAAY,CAAC;CAC5B;AACD,iBAAe,aAAa,CAAC,MAAM,EAAE,mBAAmB,iBAGvD;AA4CD,KAAK,iBAAiB,CAAC,CAAC,IAAI,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC;AAC9E;;GAEG;AACH,QAAA,MAAM,sBAAsB,uDAY3B,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,oBAAoB,EAAC,MAAM,sCAAsC,CAAC;AAC1E,OAAO,EAAC,WAAW,EAAE,4BAA4B,EAAC,MAAM,8BAA8B,CAAC;AAEvF,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,WAAW,CAAC;IACpB,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,KAAK,kBAAkB,GAAG;IACxB,8EAA8E;IAC9E,QAAQ,EAAE,MAAM,EAAE,CAAC;IACnB,8GAA8G;IAC9G,QAAQ,CAAC,EAAE,oBAAoB,CAAC;IAChC,6EAA6E;IAC7E,MAAM,CAAC,EAAE,WAAW,EAAE,CAAC;CACxB,CAAC;AAEF,QAAA,MAAM,kBAAkB,yBAAwB,wBAAwB,KAAG,MAI1E,CAAC;AA6BF;;;GAGG;AACH,QAAA,MAAM,WAAW;YAC6B,WAAW;cAAY,MAAM;;;eAClC,SAAS;kBAAgB,YAAY;MAC3E,QAAQ,MAAM,CAUhB,CAAC;AAqBF,UAAU,wCAAwC;IAChD,UAAU,EAAE,oBAAoB,GAAG,4BAA4B,CAAC;IAChE,SAAS,EAAE,SAAS,CAAC;IACrB,YAAY,EAAE,YAAY,CAAC;IAC3B,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED;;GAEG;AACH,QAAA,MAAM,YAAY,qDAKf,wCAAwC,KAAG,QAAQ,kBAAkB,CAwDvE,CAAC;AAEF,UAAU,mBAAmB;IAC3B,MAAM,EAAE,WAAW,CAAC;IACpB,QAAQ,EAAE,MAAM,CAAC;IACjB,YAAY,EAAE,YAAY,CAAC;CAC5B;AACD,iBAAe,aAAa,CAAC,MAAM,EAAE,mBAAmB,iBAGvD;AA4CD,KAAK,iBAAiB,CAAC,CAAC,IAAI,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC;AAC9E;;GAEG;AACH,QAAA,MAAM,sBAAsB,uDAY3B,CAAC;AAEF,OAAO,EAAC,kBAAkB,EAAE,WAAW,EAAE,YAAY,EAAE,aAAa,EAAE,sBAAsB,EAAC,CAAC"}
@@ -63,11 +63,12 @@ exports.initSession = initSession;
63
63
  * @param {userClientMap} map of domain to (map of user IDs to client IDs) or map of user IDs containg the lists of clients
64
64
  */
65
65
  const createSessions = async ({ recipients, apiClient, cryptoClient }) => {
66
- const prekeyBundleMap = await apiClient.api.user.postMultiPreKeyBundles(recipients);
67
- return await createSessionsFromPreKeys({
68
- recipients: prekeyBundleMap,
66
+ const { qualified_user_client_prekeys: prekeysBundle, failed_to_list: failed } = await apiClient.api.user.postMultiPreKeyBundles(recipients);
67
+ const result = await createSessionsFromPreKeys({
68
+ recipients: prekeysBundle,
69
69
  cryptoClient,
70
70
  });
71
+ return Object.assign(Object.assign({}, result), { failed });
71
72
  };
72
73
  /**
73
74
  * Will make sure all the sessions need to encrypt for those user/clients pair are set
@@ -106,17 +107,18 @@ const initSessions = async ({ recipients, apiClient, cryptoClient, logger, }) =>
106
107
  cryptoClient,
107
108
  })
108
109
  : { sessions: [], unknowns: {} };
109
- const { sessions: created, unknowns } = Object.keys(missingClients).length > 0
110
+ const { sessions: created, failed, unknowns, } = Object.keys(missingClients).length > 0
110
111
  ? await createSessions({
111
112
  recipients: missingClients,
112
113
  apiClient,
113
114
  cryptoClient,
114
115
  logger,
115
116
  })
116
- : { sessions: [], unknowns: {} };
117
+ : { sessions: [], failed: undefined, unknowns: undefined };
117
118
  const allUnknowns = Object.assign(Object.assign({}, prekeyUnknows), unknowns);
118
119
  return {
119
120
  sessions: [...existingSessions, ...prekeyCreated, ...created],
121
+ failed,
120
122
  unknowns: Object.keys(allUnknowns).length > 0 ? allUnknowns : undefined,
121
123
  };
122
124
  };
@@ -20,14 +20,29 @@
20
20
  Object.defineProperty(exports, "__esModule", { value: true });
21
21
  const api_client_1 = require("@wireapp/api-client");
22
22
  const SessionHandler_1 = require("./SessionHandler");
23
- function generatePrekeys(userId, clientIds) {
24
- const clients = clientIds.reduce((prekeys, clientId, index) => {
25
- return Object.assign(Object.assign({}, prekeys), { [clientId]: {
26
- id: index,
27
- key: 'pQABARn//wKhAFggJ1Fbpg5l6wnzKOJE+vXpRnkqUYhIvVnR5lNXEbO2o/0DoQChAFggHxZvgvtDktY/vqBcpjjo6rQnXvcNQhfwmy8AJQJKlD0E9g==',
28
- } });
29
- }, {});
30
- return { [userId.id]: clients };
23
+ function generatePrekeys(recipients) {
24
+ const prekeys = {};
25
+ const failed = [];
26
+ Object.entries(recipients).forEach(([domain, userClients]) => {
27
+ Object.entries(userClients).forEach(([userId, clientIds]) => {
28
+ if (domain.startsWith('offline:')) {
29
+ failed.push({ id: userId, domain });
30
+ return;
31
+ }
32
+ const domainUsers = prekeys[domain] || {};
33
+ domainUsers[userId] = clientIds.reduce((acc, clientId, index) => {
34
+ const payload = clientId.startsWith('deleted:')
35
+ ? null
36
+ : {
37
+ id: index,
38
+ key: 'pQABARn//wKhAFggJ1Fbpg5l6wnzKOJE+vXpRnkqUYhIvVnR5lNXEbO2o/0DoQChAFggHxZvgvtDktY/vqBcpjjo6rQnXvcNQhfwmy8AJQJKlD0E9g==',
39
+ };
40
+ return Object.assign(Object.assign({}, acc), { [clientId]: payload });
41
+ }, {});
42
+ prekeys[domain] = domainUsers;
43
+ });
44
+ });
45
+ return Promise.resolve({ qualified_user_client_prekeys: prekeys, failed_to_list: failed });
31
46
  }
32
47
  describe('SessionHandler', () => {
33
48
  const cryptoClient = {
@@ -38,6 +53,9 @@ describe('SessionHandler', () => {
38
53
  deleteSession: jest.fn(),
39
54
  };
40
55
  const apiClient = new api_client_1.APIClient({ urls: api_client_1.APIClient.BACKEND.STAGING });
56
+ beforeAll(() => {
57
+ jest.spyOn(apiClient.api.user, 'postMultiPreKeyBundles').mockImplementation(generatePrekeys);
58
+ });
41
59
  describe('constructSessionId', () => {
42
60
  describe('constructs a session ID', () => {
43
61
  it('without a domain', () => {
@@ -70,22 +88,6 @@ describe('SessionHandler', () => {
70
88
  const userId = { id: 'user1', domain: 'domain' };
71
89
  const clientId = 'client1';
72
90
  jest.spyOn(cryptoClient, 'sessionExists').mockResolvedValue(false);
73
- jest
74
- .spyOn(apiClient.api.user, 'postMultiPreKeyBundles')
75
- .mockResolvedValue({ domain: generatePrekeys(userId, [clientId]) });
76
- const sessionId = (0, SessionHandler_1.constructSessionId)({
77
- userId,
78
- clientId,
79
- });
80
- await (0, SessionHandler_1.initSession)({ userId, clientId }, { apiClient, cryptoClient });
81
- expect(cryptoClient.sessionFromPrekey).toHaveBeenCalledWith(sessionId, expect.any(Object));
82
- });
83
- it('indicates the consumer if a session could not be created', async () => {
84
- const userId = { id: 'user1', domain: 'domain' };
85
- const clientId = 'client1';
86
- jest
87
- .spyOn(apiClient.api.user, 'postMultiPreKeyBundles')
88
- .mockResolvedValue({ domain: generatePrekeys(userId, [clientId]) });
89
91
  const sessionId = (0, SessionHandler_1.constructSessionId)({
90
92
  userId,
91
93
  clientId,
@@ -104,9 +106,6 @@ describe('SessionHandler', () => {
104
106
  'missing-user1': ['client1'],
105
107
  'missing-user2': ['client1', 'client2'],
106
108
  };
107
- jest.spyOn(apiClient.api.user, 'postMultiPreKeyBundles').mockResolvedValue({
108
- domain: Object.assign(Object.assign({}, generatePrekeys({ id: 'missing-user1', domain: '' }, ['client1'])), generatePrekeys({ id: 'missing-user2', domain: '' }, ['client1', 'client2'])),
109
- });
110
109
  jest
111
110
  .spyOn(cryptoClient, 'sessionExists')
112
111
  .mockImplementation(sessionId => Promise.resolve(sessionId.includes('missing')));
@@ -121,18 +120,15 @@ describe('SessionHandler', () => {
121
120
  });
122
121
  it('returns the list of deleted clients (clients with null prekeys)', async () => {
123
122
  const userClients = {
124
- 'existing-user1': ['client1', 'deleteclient'],
123
+ 'existing-user1': ['client1', 'deleted:client2'],
125
124
  };
126
- const allKeys = { domain: generatePrekeys({ id: 'existing-user1', domain: 'domain' }, ['client1']) };
127
- allKeys['domain']['existing-user1']['deleteclient'] = null;
128
- jest.spyOn(apiClient.api.user, 'postMultiPreKeyBundles').mockResolvedValue(allKeys);
129
125
  const { sessions, unknowns } = await (0, SessionHandler_1.initSessions)({
130
126
  recipients: { domain: userClients },
131
127
  apiClient,
132
128
  cryptoClient,
133
129
  });
134
130
  expect(sessions).toEqual(['domain@existing-user1@client1']);
135
- expect(unknowns).toEqual({ domain: { 'existing-user1': ['deleteclient'] } });
131
+ expect(unknowns).toEqual({ domain: { 'existing-user1': ['deleted:client2'] } });
136
132
  });
137
133
  it('initializes sessions across multiple domains', async () => {
138
134
  const userClients = {
@@ -148,5 +144,19 @@ describe('SessionHandler', () => {
148
144
  expect(sessions).toEqual(['domain1@existing-user1@client11', 'domain2@existing-user2@client21']);
149
145
  expect(unknowns).toBeUndefined();
150
146
  });
147
+ it('returns failed session creation', async () => {
148
+ const recipients = {
149
+ domain1: { 'existing-user1': ['client1'] },
150
+ 'offline:domain': { user2: ['client12'] },
151
+ };
152
+ jest.spyOn(cryptoClient, 'sessionExists').mockResolvedValue(false);
153
+ const { sessions, failed } = await (0, SessionHandler_1.initSessions)({
154
+ recipients,
155
+ apiClient,
156
+ cryptoClient,
157
+ });
158
+ expect(sessions).toEqual(['domain1@existing-user1@client1']);
159
+ expect(failed).toEqual([{ id: 'user2', domain: 'offline:domain' }]);
160
+ });
151
161
  });
152
162
  });
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": "^23.0.0",
14
+ "@wireapp/api-client": "^23.1.0",
15
15
  "@wireapp/commons": "^5.0.4",
16
16
  "@wireapp/core-crypto": "0.6.2",
17
17
  "@wireapp/cryptobox": "12.8.0",
@@ -60,6 +60,6 @@
60
60
  "test:coverage": "jest --coverage",
61
61
  "watch": "tsc --watch"
62
62
  },
63
- "version": "39.0.1",
64
- "gitHead": "5422ef707d772e15f4ba5c2628113dddb217a2ae"
63
+ "version": "39.1.0",
64
+ "gitHead": "1879487d1061466b094cd5b54acfc83bc1cc0113"
65
65
  }