@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.
- package/lib/broadcast/BroadcastService.d.ts +0 -9
- package/lib/broadcast/BroadcastService.d.ts.map +1 -1
- package/lib/broadcast/BroadcastService.js +0 -27
- package/lib/conversation/message/MessageService.d.ts.map +1 -1
- package/lib/conversation/message/MessageService.js +6 -1
- package/lib/conversation/message/MessageService.test.js +44 -6
- package/lib/messagingProtocols/proteus/ProteusService/ProteusService.d.ts +2 -0
- package/lib/messagingProtocols/proteus/ProteusService/ProteusService.d.ts.map +1 -1
- package/lib/messagingProtocols/proteus/ProteusService/ProteusService.js +2 -1
- package/lib/messagingProtocols/proteus/ProteusService/ProteusService.test.js +20 -16
- package/lib/messagingProtocols/proteus/Utility/PreKeyBundle/PreKeyBundle.d.ts +1 -7
- package/lib/messagingProtocols/proteus/Utility/PreKeyBundle/PreKeyBundle.d.ts.map +1 -1
- package/lib/messagingProtocols/proteus/Utility/PreKeyBundle/PreKeyBundle.js +1 -31
- package/lib/messagingProtocols/proteus/Utility/SessionHandler/SessionHandler.d.ts +2 -0
- package/lib/messagingProtocols/proteus/Utility/SessionHandler/SessionHandler.d.ts.map +1 -1
- package/lib/messagingProtocols/proteus/Utility/SessionHandler/SessionHandler.js +7 -5
- package/lib/messagingProtocols/proteus/Utility/SessionHandler/SessionHandler.test.js +42 -32
- package/package.json +3 -3
|
@@ -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;
|
|
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;
|
|
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 }) =>
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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;
|
|
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
|
-
|
|
133
|
-
[userId.
|
|
134
|
-
[
|
|
135
|
-
|
|
136
|
-
|
|
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
|
-
|
|
285
|
-
[
|
|
286
|
-
[firstUser.
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
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
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
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 {
|
|
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
|
|
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 =
|
|
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;
|
|
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
|
|
67
|
-
|
|
68
|
-
recipients:
|
|
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(
|
|
24
|
-
const
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
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', '
|
|
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': ['
|
|
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.
|
|
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
|
|
64
|
-
"gitHead": "
|
|
63
|
+
"version": "39.1.0",
|
|
64
|
+
"gitHead": "1879487d1061466b094cd5b54acfc83bc1cc0113"
|
|
65
65
|
}
|