@wireapp/core 40.5.1 → 40.5.2-1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/Account.d.ts +7 -9
- package/lib/Account.d.ts.map +1 -1
- package/lib/Account.js +35 -32
- package/lib/CoreError.js +1 -1
- package/lib/broadcast/BroadcastService.d.ts +11 -2
- package/lib/broadcast/BroadcastService.d.ts.map +1 -1
- package/lib/broadcast/BroadcastService.js +39 -5
- package/lib/client/ClientDatabaseRepository.d.ts +5 -5
- package/lib/client/ClientDatabaseRepository.d.ts.map +1 -1
- package/lib/client/ClientDatabaseRepository.js +17 -10
- package/lib/client/ClientService.d.ts +1 -5
- package/lib/client/ClientService.d.ts.map +1 -1
- package/lib/client/ClientService.js +9 -11
- package/lib/connection/ConnectionService.d.ts +2 -2
- package/lib/connection/ConnectionService.d.ts.map +1 -1
- package/lib/connection/ConnectionService.js +2 -2
- package/lib/conversation/AssetTransferState.js +1 -1
- package/lib/conversation/ConversationService/ConversationService.d.ts +5 -12
- package/lib/conversation/ConversationService/ConversationService.d.ts.map +1 -1
- package/lib/conversation/ConversationService/ConversationService.js +11 -26
- package/lib/conversation/ConversationService/ConversationService.test.js +1 -1
- package/lib/conversation/ConversationService/ConversationService.types.d.ts +11 -12
- package/lib/conversation/ConversationService/ConversationService.types.d.ts.map +1 -1
- package/lib/conversation/ConversationService/ConversationService.types.js +1 -1
- package/lib/conversation/ConversationService/Utility/getConversationQualifiedMembers.d.ts +1 -1
- package/lib/conversation/ConversationService/Utility/getConversationQualifiedMembers.d.ts.map +1 -1
- package/lib/conversation/GenericMessageType.js +1 -1
- package/lib/conversation/ReactionType.d.ts +4 -1
- package/lib/conversation/ReactionType.d.ts.map +1 -1
- package/lib/conversation/ReactionType.js +6 -0
- package/lib/conversation/message/Message.types.js +1 -1
- package/lib/conversation/message/MessageBuilder.d.ts +1 -1
- package/lib/conversation/message/MessageBuilder.d.ts.map +1 -1
- package/lib/conversation/message/MessageBuilder.js +2 -2
- package/lib/conversation/message/MessageService.d.ts +31 -6
- package/lib/conversation/message/MessageService.d.ts.map +1 -1
- package/lib/conversation/message/MessageService.js +162 -19
- package/lib/conversation/message/MessageService.test.js +141 -151
- package/lib/conversation/message/PayloadBundle.js +1 -1
- package/lib/conversation/message/UserClientsUtil.d.ts +10 -14
- package/lib/conversation/message/UserClientsUtil.d.ts.map +1 -1
- package/lib/conversation/message/UserClientsUtil.js +11 -21
- package/lib/conversation/message/UserClientsUtils.test.js +9 -5
- package/lib/messagingProtocols/mls/EventHandler/EventHandler.d.ts +1 -1
- package/lib/messagingProtocols/mls/EventHandler/EventHandler.d.ts.map +1 -1
- package/lib/messagingProtocols/mls/EventHandler/events/messageAdd/messageAdd.d.ts +1 -1
- package/lib/messagingProtocols/mls/EventHandler/events/messageAdd/messageAdd.d.ts.map +1 -1
- package/lib/messagingProtocols/mls/EventHandler/events/messageAdd/messageAdd.js +2 -7
- package/lib/messagingProtocols/mls/EventHandler/events/welcomeMessage/welcomeMessage.d.ts.map +1 -1
- package/lib/messagingProtocols/mls/EventHandler/events/welcomeMessage/welcomeMessage.js +0 -2
- package/lib/messagingProtocols/mls/EventHandler/events/welcomeMessage/welcomeMessage.test.js +1 -3
- package/lib/messagingProtocols/mls/MLSService/MLSService.d.ts +8 -19
- package/lib/messagingProtocols/mls/MLSService/MLSService.d.ts.map +1 -1
- package/lib/messagingProtocols/mls/MLSService/MLSService.js +37 -79
- package/lib/messagingProtocols/mls/MLSService/MLSService.test.js +0 -9
- package/lib/messagingProtocols/mls/MLSService/stores/keyMaterialUpdatesStore/index.d.ts +2 -0
- package/lib/messagingProtocols/mls/MLSService/stores/keyMaterialUpdatesStore/index.d.ts.map +1 -0
- package/lib/messagingProtocols/mls/MLSService/stores/keyMaterialUpdatesStore/index.js +35 -0
- package/lib/messagingProtocols/mls/MLSService/stores/keyMaterialUpdatesStore/keyMaterialUpdatesStore.d.ts +11 -0
- package/lib/messagingProtocols/mls/MLSService/stores/keyMaterialUpdatesStore/keyMaterialUpdatesStore.d.ts.map +1 -0
- package/lib/messagingProtocols/mls/MLSService/stores/keyMaterialUpdatesStore/keyMaterialUpdatesStore.js +50 -0
- package/lib/messagingProtocols/mls/MLSService/stores/keyMaterialUpdatesStore/keyMaterialUpdatesStore.test.d.ts +2 -0
- package/lib/messagingProtocols/mls/MLSService/stores/keyMaterialUpdatesStore/keyMaterialUpdatesStore.test.d.ts.map +1 -0
- package/lib/messagingProtocols/mls/MLSService/stores/keyMaterialUpdatesStore/keyMaterialUpdatesStore.test.js +39 -0
- package/lib/messagingProtocols/mls/MLSService/subconversationGroupIdMapper.d.ts +4 -0
- package/lib/messagingProtocols/mls/MLSService/subconversationGroupIdMapper.d.ts.map +1 -0
- package/lib/messagingProtocols/mls/MLSService/subconversationGroupIdMapper.js +35 -0
- package/lib/messagingProtocols/mls/MLSService/subconversationGroupIdMapper.test.d.ts +2 -0
- package/lib/messagingProtocols/mls/MLSService/subconversationGroupIdMapper.test.d.ts.map +1 -0
- package/lib/messagingProtocols/mls/MLSService/subconversationGroupIdMapper.test.js +35 -0
- package/lib/messagingProtocols/proteus/ProteusService/CryptoClient/CoreCryptoWrapper/CoreCryptoWrapper.d.ts +5 -10
- package/lib/messagingProtocols/proteus/ProteusService/CryptoClient/CoreCryptoWrapper/CoreCryptoWrapper.d.ts.map +1 -1
- package/lib/messagingProtocols/proteus/ProteusService/CryptoClient/CoreCryptoWrapper/CoreCryptoWrapper.js +11 -33
- package/lib/messagingProtocols/proteus/ProteusService/CryptoClient/CoreCryptoWrapper/PrekeysTracker/PrekeysTracker.d.ts +3 -2
- package/lib/messagingProtocols/proteus/ProteusService/CryptoClient/CoreCryptoWrapper/PrekeysTracker/PrekeysTracker.d.ts.map +1 -1
- package/lib/messagingProtocols/proteus/ProteusService/CryptoClient/CoreCryptoWrapper/PrekeysTracker/PrekeysTracker.js +9 -8
- package/lib/messagingProtocols/proteus/ProteusService/CryptoClient/CoreCryptoWrapper/PrekeysTracker/PrekeysTracker.store.d.ts +9 -4
- package/lib/messagingProtocols/proteus/ProteusService/CryptoClient/CoreCryptoWrapper/PrekeysTracker/PrekeysTracker.store.d.ts.map +1 -1
- package/lib/messagingProtocols/proteus/ProteusService/CryptoClient/CoreCryptoWrapper/PrekeysTracker/PrekeysTracker.store.js +24 -10
- package/lib/messagingProtocols/proteus/ProteusService/CryptoClient/CoreCryptoWrapper/PrekeysTracker/PrekeysTracker.test.js +10 -2
- package/lib/messagingProtocols/proteus/ProteusService/CryptoClient/CryptoClient.d.ts +2 -1
- package/lib/messagingProtocols/proteus/ProteusService/CryptoClient/CryptoClient.d.ts.map +1 -1
- package/lib/messagingProtocols/proteus/ProteusService/CryptoClient/CryptoClient.js +3 -3
- package/lib/messagingProtocols/proteus/ProteusService/CryptoClient/CryptoClient.types.d.ts +2 -2
- package/lib/messagingProtocols/proteus/ProteusService/CryptoClient/CryptoClient.types.d.ts.map +1 -1
- package/lib/messagingProtocols/proteus/ProteusService/CryptoClient/CryptoboxWrapper.d.ts +1 -1
- package/lib/messagingProtocols/proteus/ProteusService/CryptoClient/CryptoboxWrapper.d.ts.map +1 -1
- package/lib/messagingProtocols/proteus/ProteusService/CryptoClient/CryptoboxWrapper.js +2 -2
- package/lib/messagingProtocols/proteus/ProteusService/ProteusService.d.ts +7 -14
- package/lib/messagingProtocols/proteus/ProteusService/ProteusService.d.ts.map +1 -1
- package/lib/messagingProtocols/proteus/ProteusService/ProteusService.js +35 -31
- package/lib/messagingProtocols/proteus/ProteusService/ProteusService.mocks.d.ts +1 -1
- package/lib/messagingProtocols/proteus/ProteusService/ProteusService.mocks.d.ts.map +1 -1
- package/lib/messagingProtocols/proteus/ProteusService/ProteusService.mocks.js +3 -2
- package/lib/messagingProtocols/proteus/ProteusService/ProteusService.test.js +89 -109
- package/lib/messagingProtocols/proteus/ProteusService/ProteusService.types.d.ts +9 -6
- package/lib/messagingProtocols/proteus/ProteusService/ProteusService.types.d.ts.map +1 -1
- package/lib/messagingProtocols/proteus/Utility/PreKeyBundle/PreKeyBundle.d.ts +25 -0
- package/lib/messagingProtocols/proteus/Utility/PreKeyBundle/PreKeyBundle.d.ts.map +1 -0
- package/lib/messagingProtocols/proteus/Utility/PreKeyBundle/PreKeyBundle.js +93 -0
- package/lib/messagingProtocols/proteus/Utility/PreKeyBundle/PreKeyBundle.test.d.ts +2 -0
- package/lib/messagingProtocols/proteus/Utility/PreKeyBundle/PreKeyBundle.test.d.ts.map +1 -0
- package/lib/messagingProtocols/proteus/Utility/PreKeyBundle/PreKeyBundle.test.js +66 -0
- package/lib/messagingProtocols/proteus/Utility/PreKeyBundle/index.d.ts +2 -0
- package/lib/messagingProtocols/proteus/Utility/PreKeyBundle/index.d.ts.map +1 -0
- package/lib/messagingProtocols/proteus/Utility/PreKeyBundle/index.js +35 -0
- package/lib/messagingProtocols/proteus/Utility/Recipients.d.ts +10 -4
- package/lib/messagingProtocols/proteus/Utility/Recipients.d.ts.map +1 -1
- package/lib/messagingProtocols/proteus/Utility/Recipients.js +16 -16
- package/lib/messagingProtocols/proteus/Utility/SessionHandler/SessionHandler.d.ts +10 -15
- package/lib/messagingProtocols/proteus/Utility/SessionHandler/SessionHandler.d.ts.map +1 -1
- package/lib/messagingProtocols/proteus/Utility/SessionHandler/SessionHandler.js +92 -80
- package/lib/messagingProtocols/proteus/Utility/SessionHandler/SessionHandler.test.js +54 -70
- package/lib/messagingProtocols/proteus/Utility/getGenericMessageParams.d.ts +14 -5
- package/lib/messagingProtocols/proteus/Utility/getGenericMessageParams.d.ts.map +1 -1
- package/lib/messagingProtocols/proteus/Utility/getGenericMessageParams.js +35 -3
- package/lib/messagingProtocols/proteus/Utility/isClearFromMismatch.d.ts +2 -2
- package/lib/messagingProtocols/proteus/Utility/isClearFromMismatch.d.ts.map +1 -1
- package/lib/notification/NotificationDatabaseRepository.js +1 -1
- package/lib/notification/Notifications.types.js +1 -1
- package/lib/user/UserService.d.ts +17 -6
- package/lib/user/UserService.d.ts.map +1 -1
- package/lib/user/UserService.js +47 -2
- package/lib/util/TaskScheduler/TaskScheduler.d.ts +1 -4
- package/lib/util/TaskScheduler/TaskScheduler.d.ts.map +1 -1
- package/lib/util/TaskScheduler/TaskScheduler.js +3 -24
- package/lib/util/TypePredicateUtil.d.ts +1 -0
- package/lib/util/TypePredicateUtil.d.ts.map +1 -1
- package/lib/util/TypePredicateUtil.js +2 -1
- package/package.json +8 -8
- package/LICENSE +0 -674
- package/lib/messagingProtocols/mls/MLSService/stores/subconversationGroupIdStore/subconversationGroupIdStore.d.ts +0 -13
- package/lib/messagingProtocols/mls/MLSService/stores/subconversationGroupIdStore/subconversationGroupIdStore.d.ts.map +0 -1
- package/lib/messagingProtocols/mls/MLSService/stores/subconversationGroupIdStore/subconversationGroupIdStore.js +0 -67
- package/lib/messagingProtocols/mls/MLSService/stores/subconversationGroupIdStore/subconversationGroupIdStore.test.d.ts +0 -2
- package/lib/messagingProtocols/mls/MLSService/stores/subconversationGroupIdStore/subconversationGroupIdStore.test.d.ts.map +0 -1
- package/lib/messagingProtocols/mls/MLSService/stores/subconversationGroupIdStore/subconversationGroupIdStore.test.js +0 -72
- package/lib/util/TaskScheduler/TaskScheduler.store.d.ts +0 -7
- package/lib/util/TaskScheduler/TaskScheduler.store.d.ts.map +0 -1
- package/lib/util/TaskScheduler/TaskScheduler.store.js +0 -34
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { APIClient } from '@wireapp/api-client';
|
|
2
2
|
import { CryptoClient } from './CryptoClient';
|
|
3
3
|
import { ProteusService } from './ProteusService';
|
|
4
|
-
export declare const buildProteusService: () => Promise<[ProteusService, {
|
|
4
|
+
export declare const buildProteusService: (federated?: boolean) => Promise<[ProteusService, {
|
|
5
5
|
apiClient: APIClient;
|
|
6
6
|
cryptoClient: CryptoClient;
|
|
7
7
|
}]>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ProteusService.mocks.d.ts","sourceRoot":"","sources":["../../../../src/messagingProtocols/proteus/ProteusService/ProteusService.mocks.ts"],"names":[],"mappings":"AAqBA,OAAO,EAAC,SAAS,EAAC,MAAM,qBAAqB,CAAC;AAE9C,OAAO,EAAC,YAAY,EAAC,MAAM,gBAAgB,CAAC;AAE5C,OAAO,EAAC,cAAc,EAAC,MAAM,kBAAkB,CAAC;AAIhD,eAAO,MAAM,mBAAmB;
|
|
1
|
+
{"version":3,"file":"ProteusService.mocks.d.ts","sourceRoot":"","sources":["../../../../src/messagingProtocols/proteus/ProteusService/ProteusService.mocks.ts"],"names":[],"mappings":"AAqBA,OAAO,EAAC,SAAS,EAAC,MAAM,qBAAqB,CAAC;AAE9C,OAAO,EAAC,YAAY,EAAC,MAAM,gBAAgB,CAAC;AAE5C,OAAO,EAAC,cAAc,EAAC,MAAM,kBAAkB,CAAC;AAIhD,eAAO,MAAM,mBAAmB;eAEQ,SAAS;kBAAgB,YAAY;GAgB5E,CAAC"}
|
|
@@ -24,16 +24,17 @@ const api_client_1 = require("@wireapp/api-client");
|
|
|
24
24
|
const CoreCryptoWrapper_1 = require("./CryptoClient/CoreCryptoWrapper/CoreCryptoWrapper");
|
|
25
25
|
const ProteusService_1 = require("./ProteusService");
|
|
26
26
|
const PayloadHelper_1 = require("../../../test/PayloadHelper");
|
|
27
|
-
const buildProteusService = async () => {
|
|
27
|
+
const buildProteusService = async (federated = false) => {
|
|
28
28
|
const apiClient = new api_client_1.APIClient({ urls: api_client_1.APIClient.BACKEND.STAGING });
|
|
29
29
|
apiClient.context = {
|
|
30
30
|
clientType: client_1.ClientType.NONE,
|
|
31
31
|
userId: (0, PayloadHelper_1.getUUID)(),
|
|
32
32
|
clientId: (0, PayloadHelper_1.getUUID)(),
|
|
33
33
|
};
|
|
34
|
-
const cryptoClient = new CoreCryptoWrapper_1.CoreCryptoWrapper({}, {});
|
|
34
|
+
const cryptoClient = new CoreCryptoWrapper_1.CoreCryptoWrapper({}, {}, {});
|
|
35
35
|
const proteusService = new ProteusService_1.ProteusService(apiClient, cryptoClient, {
|
|
36
36
|
nbPrekeys: 0,
|
|
37
|
+
useQualifiedIds: federated,
|
|
37
38
|
});
|
|
38
39
|
return [proteusService, { apiClient, cryptoClient }];
|
|
39
40
|
};
|
|
@@ -64,11 +64,11 @@ jest.mock('./CryptoClient/CoreCryptoWrapper/PrekeysTracker', () => {
|
|
|
64
64
|
});
|
|
65
65
|
jest.mock('../Utility/Recipients', () => (Object.assign(Object.assign({}, jest.requireActual('../Utility/Recipients')), { getRecipientsForConversation: jest.fn(), getQualifiedRecipientsForConversation: jest.fn() })));
|
|
66
66
|
const MockedRecipients = Recipients;
|
|
67
|
-
const prepareDataForEncryption = async () => {
|
|
68
|
-
const [proteusService, { cryptoClient, apiClient }] = await (0, ProteusService_mocks_1.buildProteusService)();
|
|
67
|
+
const prepareDataForEncryption = async (useQualifiedIds = true) => {
|
|
68
|
+
const [proteusService, { cryptoClient, apiClient }] = await (0, ProteusService_mocks_1.buildProteusService)(useQualifiedIds);
|
|
69
69
|
const domain = 'staging.zinfra.io';
|
|
70
70
|
//user 1
|
|
71
|
-
const firstUserId =
|
|
71
|
+
const firstUserId = 'bc0c99f1-49a5-4ad2-889a-62885af37088';
|
|
72
72
|
//user 1 clients
|
|
73
73
|
const firstClientId = 'be67218b77d02d30';
|
|
74
74
|
const secondClientId = 'ae87218e77d02d30';
|
|
@@ -76,19 +76,25 @@ const prepareDataForEncryption = async () => {
|
|
|
76
76
|
const firstClientSessionId = (0, SessionHandler_1.constructSessionId)({
|
|
77
77
|
userId: firstUserId,
|
|
78
78
|
clientId: firstClientId,
|
|
79
|
+
useQualifiedIds,
|
|
80
|
+
domain: useQualifiedIds ? domain : undefined,
|
|
79
81
|
});
|
|
80
82
|
const firstClientSession2Id = (0, SessionHandler_1.constructSessionId)({
|
|
81
83
|
userId: firstUserId,
|
|
82
84
|
clientId: secondClientId,
|
|
85
|
+
useQualifiedIds,
|
|
86
|
+
domain: useQualifiedIds ? domain : undefined,
|
|
83
87
|
});
|
|
84
88
|
//user 2
|
|
85
|
-
const secondUserId =
|
|
89
|
+
const secondUserId = 'cd0c88f1-49a5-4ar2-889a-62885af37069';
|
|
86
90
|
//user 2 client
|
|
87
91
|
const thirdClientId = 'ce67218b77d02d69';
|
|
88
92
|
//user 2 sessions
|
|
89
93
|
const secondClientSessionId = (0, SessionHandler_1.constructSessionId)({
|
|
90
94
|
userId: secondUserId,
|
|
91
95
|
clientId: thirdClientId,
|
|
96
|
+
useQualifiedIds,
|
|
97
|
+
domain: useQualifiedIds ? domain : undefined,
|
|
92
98
|
});
|
|
93
99
|
//message sent by a user
|
|
94
100
|
const message = 'Hello';
|
|
@@ -128,14 +134,12 @@ describe('ProteusService', () => {
|
|
|
128
134
|
const expectedFingerprint = 'fingerprint-client1';
|
|
129
135
|
const userId = { id: 'user1', domain: 'domain.com' };
|
|
130
136
|
const clientId = 'client1';
|
|
131
|
-
jest.spyOn(apiClient.api.user, '
|
|
132
|
-
|
|
133
|
-
[userId.
|
|
134
|
-
[
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
key: 'pQABARhIAqEAWCCaJpFa9c626ORmjj1aV6OnOYgmTjfoiE3ynOfNfGAOmgOhAKEAWCD60VMzRrLfO+1GSjgyhnVp2N7L58DM+eeJhZJi1tBLfQT2',
|
|
138
|
-
},
|
|
137
|
+
jest.spyOn(apiClient.api.user, 'postQualifiedMultiPreKeyBundles').mockResolvedValue({
|
|
138
|
+
[userId.domain]: {
|
|
139
|
+
[userId.id]: {
|
|
140
|
+
[clientId]: {
|
|
141
|
+
id: 123,
|
|
142
|
+
key: 'pQABARhIAqEAWCCaJpFa9c626ORmjj1aV6OnOYgmTjfoiE3ynOfNfGAOmgOhAKEAWCD60VMzRrLfO+1GSjgyhnVp2N7L58DM+eeJhZJi1tBLfQT2',
|
|
139
143
|
},
|
|
140
144
|
},
|
|
141
145
|
},
|
|
@@ -150,9 +154,9 @@ describe('ProteusService', () => {
|
|
|
150
154
|
it('create a session from given prekey if session does not exists', async () => {
|
|
151
155
|
const [proteusService, { apiClient, cryptoClient }] = await (0, ProteusService_mocks_1.buildProteusService)();
|
|
152
156
|
const expectedFingerprint = 'fingerprint-client1';
|
|
153
|
-
const
|
|
157
|
+
const getPrekeyMock = jest.spyOn(apiClient.api.user, 'getClientPreKey');
|
|
154
158
|
jest.spyOn(cryptoClient, 'getRemoteFingerprint').mockResolvedValue(expectedFingerprint);
|
|
155
|
-
|
|
159
|
+
jest.spyOn(cryptoClient, 'sessionFromPrekey').mockResolvedValue(undefined);
|
|
156
160
|
jest.spyOn(cryptoClient, 'saveSession').mockResolvedValue(undefined);
|
|
157
161
|
jest.spyOn(cryptoClient, 'sessionExists').mockResolvedValue(false);
|
|
158
162
|
const userId = { id: 'user1', domain: 'domain.com' };
|
|
@@ -161,8 +165,7 @@ describe('ProteusService', () => {
|
|
|
161
165
|
key: 'pQABARhIAqEAWCCaJpFa9c626ORmjj1aV6OnOYgmTjfoiE3ynOfNfGAOmgOhAKEAWCD60VMzRrLfO+1GSjgyhnVp2N7L58DM+eeJhZJi1tBLfQT2',
|
|
162
166
|
id: 123,
|
|
163
167
|
});
|
|
164
|
-
expect(
|
|
165
|
-
expect(getPrekeysSpy).not.toHaveBeenCalled();
|
|
168
|
+
expect(getPrekeyMock).not.toHaveBeenCalled();
|
|
166
169
|
expect(result).toBe(expectedFingerprint);
|
|
167
170
|
});
|
|
168
171
|
it('returns the fingerprint from existing session', async () => {
|
|
@@ -217,64 +220,83 @@ describe('ProteusService', () => {
|
|
|
217
220
|
});
|
|
218
221
|
describe('"encrypt"', () => {
|
|
219
222
|
it('returns encrypted payload', async () => {
|
|
220
|
-
const { services, data: { firstUser, encryptedMessageBuffer, messageBuffer
|
|
223
|
+
const { services, data: { firstUser, encryptedMessageBuffer, messageBuffer }, } = await prepareDataForEncryption(false);
|
|
221
224
|
const userClients = {
|
|
222
|
-
[
|
|
223
|
-
|
|
225
|
+
[firstUser.id]: [firstUser.clients.first, firstUser.clients.second],
|
|
226
|
+
};
|
|
227
|
+
const encryptedPayload = new Map([
|
|
228
|
+
[firstUser.sessions.first, encryptedMessageBuffer],
|
|
229
|
+
[firstUser.sessions.second, encryptedMessageBuffer],
|
|
230
|
+
]);
|
|
231
|
+
jest.spyOn(services.cryptoClient, 'sessionExists').mockResolvedValue(true);
|
|
232
|
+
jest.spyOn(services.cryptoClient, 'encrypt').mockImplementationOnce(() => Promise.resolve(encryptedPayload));
|
|
233
|
+
const encrypted = await services.proteusService.encrypt(messageBuffer, userClients);
|
|
234
|
+
expect(services.cryptoClient.encrypt).toHaveBeenCalledWith([firstUser.sessions.first, firstUser.sessions.second], messageBuffer);
|
|
235
|
+
expect(encrypted).toEqual({
|
|
236
|
+
[firstUser.id]: {
|
|
237
|
+
[firstUser.clients.first]: encryptedMessageBuffer,
|
|
238
|
+
[firstUser.clients.second]: encryptedMessageBuffer,
|
|
224
239
|
},
|
|
240
|
+
});
|
|
241
|
+
});
|
|
242
|
+
it('returns encrypted payload for multiple users', async () => {
|
|
243
|
+
const { services, data: { firstUser, secondUser, encryptedMessageBuffer, messageBuffer }, } = await prepareDataForEncryption(false);
|
|
244
|
+
const userClients = {
|
|
245
|
+
[firstUser.id]: [firstUser.clients.first, firstUser.clients.second],
|
|
246
|
+
[secondUser.id]: [secondUser.clients.first],
|
|
225
247
|
};
|
|
226
248
|
const encryptedPayload = new Map([
|
|
227
249
|
[firstUser.sessions.first, encryptedMessageBuffer],
|
|
228
250
|
[firstUser.sessions.second, encryptedMessageBuffer],
|
|
251
|
+
[secondUser.sessions.first, encryptedMessageBuffer],
|
|
229
252
|
]);
|
|
230
253
|
jest.spyOn(services.cryptoClient, 'sessionExists').mockResolvedValue(true);
|
|
231
254
|
jest.spyOn(services.cryptoClient, 'encrypt').mockResolvedValueOnce(encryptedPayload);
|
|
232
|
-
const
|
|
233
|
-
expect(services.cryptoClient.encrypt).toHaveBeenCalledWith([firstUser.sessions.first, firstUser.sessions.second], messageBuffer);
|
|
234
|
-
expect(
|
|
235
|
-
[
|
|
236
|
-
[firstUser.
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
255
|
+
const encrypted = await services.proteusService.encrypt(messageBuffer, userClients);
|
|
256
|
+
expect(services.cryptoClient.encrypt).toHaveBeenCalledWith([firstUser.sessions.first, firstUser.sessions.second, secondUser.sessions.first], messageBuffer);
|
|
257
|
+
expect(encrypted).toEqual({
|
|
258
|
+
[firstUser.id]: {
|
|
259
|
+
[firstUser.clients.first]: encryptedMessageBuffer,
|
|
260
|
+
[firstUser.clients.second]: encryptedMessageBuffer,
|
|
261
|
+
},
|
|
262
|
+
[secondUser.id]: {
|
|
263
|
+
[secondUser.clients.first]: encryptedMessageBuffer,
|
|
240
264
|
},
|
|
241
265
|
});
|
|
242
266
|
});
|
|
243
|
-
|
|
244
|
-
|
|
267
|
+
});
|
|
268
|
+
describe('"encryptQualified"', () => {
|
|
269
|
+
it('returns encrypted payload', async () => {
|
|
270
|
+
const { services, data: { firstUser, encryptedMessageBuffer, messageBuffer, domain }, } = await prepareDataForEncryption();
|
|
245
271
|
const userClients = {
|
|
246
272
|
[domain]: {
|
|
247
|
-
[firstUser.id
|
|
248
|
-
[secondUser.id.id]: [secondUser.clients.first],
|
|
273
|
+
[firstUser.id]: [firstUser.clients.first, firstUser.clients.second],
|
|
249
274
|
},
|
|
250
275
|
};
|
|
251
276
|
const encryptedPayload = new Map([
|
|
252
277
|
[firstUser.sessions.first, encryptedMessageBuffer],
|
|
253
278
|
[firstUser.sessions.second, encryptedMessageBuffer],
|
|
254
|
-
[secondUser.sessions.first, encryptedMessageBuffer],
|
|
255
279
|
]);
|
|
256
280
|
jest.spyOn(services.cryptoClient, 'sessionExists').mockResolvedValue(true);
|
|
257
281
|
jest.spyOn(services.cryptoClient, 'encrypt').mockResolvedValueOnce(encryptedPayload);
|
|
258
|
-
const
|
|
259
|
-
|
|
260
|
-
expect(
|
|
282
|
+
const encrypted = await services.proteusService.encryptQualified(messageBuffer, userClients);
|
|
283
|
+
// console.log({encrypted, missing});
|
|
284
|
+
expect(services.cryptoClient.encrypt).toHaveBeenCalledWith([firstUser.sessions.first, firstUser.sessions.second], messageBuffer);
|
|
285
|
+
expect(encrypted).toEqual({
|
|
261
286
|
[domain]: {
|
|
262
|
-
[firstUser.id
|
|
287
|
+
[firstUser.id]: {
|
|
263
288
|
[firstUser.clients.first]: encryptedMessageBuffer,
|
|
264
289
|
[firstUser.clients.second]: encryptedMessageBuffer,
|
|
265
290
|
},
|
|
266
|
-
[secondUser.id.id]: {
|
|
267
|
-
[secondUser.clients.first]: encryptedMessageBuffer,
|
|
268
|
-
},
|
|
269
291
|
},
|
|
270
292
|
});
|
|
271
293
|
});
|
|
272
|
-
it('returns
|
|
294
|
+
it('returns missing clients and encrypted payload for multiple users', async () => {
|
|
273
295
|
const { services, data: { firstUser, secondUser, encryptedMessageBuffer, messageBuffer, domain }, } = await prepareDataForEncryption();
|
|
274
296
|
const userClients = {
|
|
275
297
|
[domain]: {
|
|
276
|
-
[firstUser.id
|
|
277
|
-
[secondUser.id
|
|
298
|
+
[firstUser.id]: [firstUser.clients.first, firstUser.clients.second],
|
|
299
|
+
[secondUser.id]: [secondUser.clients.first],
|
|
278
300
|
},
|
|
279
301
|
};
|
|
280
302
|
const encryptedPayload = new Map([
|
|
@@ -282,43 +304,17 @@ describe('ProteusService', () => {
|
|
|
282
304
|
[firstUser.sessions.second, encryptedMessageBuffer],
|
|
283
305
|
[secondUser.sessions.first, encryptedMessageBuffer],
|
|
284
306
|
]);
|
|
285
|
-
jest.spyOn(services.
|
|
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
|
-
},
|
|
294
|
-
},
|
|
295
|
-
[secondUser.id.id]: {
|
|
296
|
-
[secondUser.clients.first]: {
|
|
297
|
-
id: 123,
|
|
298
|
-
key: 'pQABARhIAqEAWCCaJpFa9c626ORmjj1aV6OnOYgmTjfoiE3ynOfNfGAOmgOhAKEAWCD60VMzRrLfO+1GSjgyhnVp2N7L58DM+eeJhZJi1tBLfQT2',
|
|
299
|
-
},
|
|
300
|
-
},
|
|
301
|
-
},
|
|
302
|
-
},
|
|
303
|
-
});
|
|
304
|
-
jest.spyOn(services.cryptoClient, 'sessionExists').mockResolvedValue(false);
|
|
307
|
+
jest.spyOn(services.cryptoClient, 'sessionExists').mockResolvedValue(true);
|
|
305
308
|
jest.spyOn(services.cryptoClient, 'encrypt').mockResolvedValueOnce(encryptedPayload);
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
expect(services.cryptoClient.encrypt).toHaveBeenCalledWith([firstUser.sessions.second, secondUser.sessions.first], messageBuffer);
|
|
310
|
-
expect(unknowns).toEqual({
|
|
311
|
-
[domain]: {
|
|
312
|
-
[firstUser.id.id]: [firstUser.clients.first],
|
|
313
|
-
},
|
|
314
|
-
});
|
|
315
|
-
expect(payloads).toEqual({
|
|
309
|
+
const encrypted = await services.proteusService.encryptQualified(messageBuffer, userClients);
|
|
310
|
+
expect(services.cryptoClient.encrypt).toHaveBeenCalledWith([firstUser.sessions.first, firstUser.sessions.second, secondUser.sessions.first], messageBuffer);
|
|
311
|
+
expect(encrypted).toEqual({
|
|
316
312
|
[domain]: {
|
|
317
|
-
[firstUser.id
|
|
313
|
+
[firstUser.id]: {
|
|
318
314
|
[firstUser.clients.first]: encryptedMessageBuffer,
|
|
319
315
|
[firstUser.clients.second]: encryptedMessageBuffer,
|
|
320
316
|
},
|
|
321
|
-
[secondUser.id
|
|
317
|
+
[secondUser.id]: {
|
|
322
318
|
[secondUser.clients.first]: encryptedMessageBuffer,
|
|
323
319
|
},
|
|
324
320
|
},
|
|
@@ -348,13 +344,7 @@ describe('ProteusService', () => {
|
|
|
348
344
|
expect(errorMessage).toContain('no userIds are given');
|
|
349
345
|
}
|
|
350
346
|
});
|
|
351
|
-
[
|
|
352
|
-
{ domain: { user1: ['client1'], user2: ['client11', 'client12'] } },
|
|
353
|
-
[
|
|
354
|
-
{ domain: 'domain', id: 'user1' },
|
|
355
|
-
{ domain: 'domain', id: 'user2' },
|
|
356
|
-
],
|
|
357
|
-
].forEach(recipients => {
|
|
347
|
+
[{ user1: ['client1'], user2: ['client11', 'client12'] }, ['user1', 'user2']].forEach(recipients => {
|
|
358
348
|
it(`forwards the list of users to report (${JSON.stringify(recipients)})`, async () => {
|
|
359
349
|
const [proteusService] = await (0, ProteusService_mocks_1.buildProteusService)();
|
|
360
350
|
MockedRecipients.getRecipientsForConversation.mockResolvedValue({});
|
|
@@ -366,12 +356,7 @@ describe('ProteusService', () => {
|
|
|
366
356
|
userIds: recipients,
|
|
367
357
|
conversationId: { id: 'conv1', domain: '' },
|
|
368
358
|
});
|
|
369
|
-
expect(proteusService['messageService'].sendMessage).toHaveBeenCalledWith(expect.any(String), expect.any(Object), expect.any(Uint8Array), expect.objectContaining({
|
|
370
|
-
reportMissing: [
|
|
371
|
-
{ domain: 'domain', id: 'user1' },
|
|
372
|
-
{ domain: 'domain', id: 'user2' },
|
|
373
|
-
],
|
|
374
|
-
}));
|
|
359
|
+
expect(proteusService['messageService'].sendMessage).toHaveBeenCalledWith(expect.any(String), expect.any(Object), expect.any(Uint8Array), expect.objectContaining({ reportMissing: ['user1', 'user2'] }));
|
|
375
360
|
});
|
|
376
361
|
});
|
|
377
362
|
[
|
|
@@ -383,9 +368,9 @@ describe('ProteusService', () => {
|
|
|
383
368
|
],
|
|
384
369
|
].forEach(recipients => {
|
|
385
370
|
it(`forwards the list of users to report for federated message (${JSON.stringify(recipients)})`, async () => {
|
|
386
|
-
const [proteusService] = await (0, ProteusService_mocks_1.buildProteusService)();
|
|
387
|
-
MockedRecipients.
|
|
388
|
-
jest.spyOn(proteusService['messageService'], '
|
|
371
|
+
const [proteusService] = await (0, ProteusService_mocks_1.buildProteusService)(true);
|
|
372
|
+
MockedRecipients.getQualifiedRecipientsForConversation.mockResolvedValue({});
|
|
373
|
+
jest.spyOn(proteusService['messageService'], 'sendFederatedMessage').mockResolvedValue({});
|
|
389
374
|
await proteusService.sendMessage({
|
|
390
375
|
protocol: conversation_1.ConversationProtocol.PROTEUS,
|
|
391
376
|
conversationId: { id: 'conv1', domain: 'domain1' },
|
|
@@ -393,7 +378,7 @@ describe('ProteusService', () => {
|
|
|
393
378
|
targetMode: conversation_2.MessageTargetMode.USERS,
|
|
394
379
|
userIds: recipients,
|
|
395
380
|
});
|
|
396
|
-
expect(proteusService['messageService'].
|
|
381
|
+
expect(proteusService['messageService'].sendFederatedMessage).toHaveBeenCalledWith(expect.any(String), expect.any(Object), expect.any(Uint8Array), expect.objectContaining({
|
|
397
382
|
reportMissing: [
|
|
398
383
|
{ id: 'user1', domain: 'domain1' },
|
|
399
384
|
{ id: 'user2', domain: 'domain1' },
|
|
@@ -402,15 +387,9 @@ describe('ProteusService', () => {
|
|
|
402
387
|
}));
|
|
403
388
|
});
|
|
404
389
|
});
|
|
405
|
-
[
|
|
406
|
-
{ domain: { user1: ['client1'], user2: ['client11', 'client12'] } },
|
|
407
|
-
[
|
|
408
|
-
{ domain: 'domain', id: 'user1' },
|
|
409
|
-
{ domain: 'domain', id: 'user2' },
|
|
410
|
-
],
|
|
411
|
-
].forEach(recipients => {
|
|
390
|
+
[{ user1: ['client1'], user2: ['client11', 'client12'] }, ['user1', 'user2']].forEach(recipients => {
|
|
412
391
|
it(`ignores all missing user/client pair if targetMode is USER_CLIENTS`, async () => {
|
|
413
|
-
const [proteusService] = await (0, ProteusService_mocks_1.buildProteusService)();
|
|
392
|
+
const [proteusService] = await (0, ProteusService_mocks_1.buildProteusService)(false);
|
|
414
393
|
MockedRecipients.getRecipientsForConversation.mockReturnValue(Promise.resolve({}));
|
|
415
394
|
jest.spyOn(proteusService['messageService'], 'sendMessage').mockReturnValue(Promise.resolve({}));
|
|
416
395
|
await proteusService.sendMessage({
|
|
@@ -432,9 +411,11 @@ describe('ProteusService', () => {
|
|
|
432
411
|
],
|
|
433
412
|
].forEach(recipients => {
|
|
434
413
|
it(`ignores all missing user/client pair if targetMode is USER_CLIENTS on federated env`, async () => {
|
|
435
|
-
const [proteusService] = await (0, ProteusService_mocks_1.buildProteusService)();
|
|
436
|
-
MockedRecipients.
|
|
437
|
-
jest
|
|
414
|
+
const [proteusService] = await (0, ProteusService_mocks_1.buildProteusService)(true);
|
|
415
|
+
MockedRecipients.getQualifiedRecipientsForConversation.mockResolvedValue({});
|
|
416
|
+
jest
|
|
417
|
+
.spyOn(proteusService['messageService'], 'sendFederatedMessage')
|
|
418
|
+
.mockReturnValue(Promise.resolve({}));
|
|
438
419
|
await proteusService.sendMessage({
|
|
439
420
|
protocol: conversation_1.ConversationProtocol.PROTEUS,
|
|
440
421
|
conversationId: { id: 'conv1', domain: 'domain1' },
|
|
@@ -442,20 +423,19 @@ describe('ProteusService', () => {
|
|
|
442
423
|
targetMode: conversation_2.MessageTargetMode.USERS_CLIENTS,
|
|
443
424
|
userIds: recipients,
|
|
444
425
|
});
|
|
445
|
-
expect(proteusService['messageService'].
|
|
426
|
+
expect(proteusService['messageService'].sendFederatedMessage).toHaveBeenCalledWith(expect.any(String), expect.any(Object), expect.any(Uint8Array), expect.objectContaining({
|
|
446
427
|
reportMissing: false,
|
|
447
428
|
}));
|
|
448
429
|
});
|
|
449
430
|
});
|
|
450
|
-
it(`returns the recipients that
|
|
451
|
-
|
|
452
|
-
const [proteusService] = await (0, ProteusService_mocks_1.buildProteusService)();
|
|
431
|
+
it(`returns the recipients that could not receive the message`, async () => {
|
|
432
|
+
const [proteusService] = await (0, ProteusService_mocks_1.buildProteusService)(true);
|
|
453
433
|
const recipients = {
|
|
454
434
|
domain1: { user1: ['client1'], user2: ['client11', 'client12'] },
|
|
455
435
|
domain2: { user3: ['client3'] },
|
|
456
436
|
};
|
|
457
|
-
MockedRecipients.
|
|
458
|
-
jest.spyOn(proteusService['messageService'], '
|
|
437
|
+
MockedRecipients.getQualifiedRecipientsForConversation.mockResolvedValue({});
|
|
438
|
+
jest.spyOn(proteusService['messageService'], 'sendFederatedMessage').mockResolvedValue({
|
|
459
439
|
missing: {},
|
|
460
440
|
redundant: {},
|
|
461
441
|
failed_to_send: { domain2: recipients.domain2 },
|
|
@@ -470,7 +450,7 @@ describe('ProteusService', () => {
|
|
|
470
450
|
userIds: recipients,
|
|
471
451
|
});
|
|
472
452
|
expect(result.state).toBe(conversation_2.MessageSendingState.OUTGOING_SENT);
|
|
473
|
-
expect(
|
|
453
|
+
expect(result.failedToSend).toEqual({ domain2: recipients.domain2 });
|
|
474
454
|
});
|
|
475
455
|
});
|
|
476
456
|
});
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { QualifiedUserClients, MessageSendingStatus, ConversationProtocol, NewConversation } from '@wireapp/api-client/lib/conversation';
|
|
1
|
+
import { UserClients, QualifiedUserClients, ClientMismatch, MessageSendingStatus, ConversationProtocol, NewConversation } from '@wireapp/api-client/lib/conversation';
|
|
2
2
|
import { QualifiedId } from '@wireapp/api-client/lib/user';
|
|
3
3
|
import { AddUsersParams, MessageSendingOptions, SendCommonParams } from '../../../conversation';
|
|
4
4
|
export interface NewClient {
|
|
@@ -6,18 +6,21 @@ export interface NewClient {
|
|
|
6
6
|
userId: QualifiedId;
|
|
7
7
|
}
|
|
8
8
|
export type ProteusServiceConfig = {
|
|
9
|
+
useQualifiedIds: boolean;
|
|
9
10
|
onNewClient?: (client: NewClient) => void;
|
|
10
11
|
nbPrekeys: number;
|
|
11
12
|
};
|
|
12
13
|
export type SendProteusMessageParams = SendCommonParams & MessageSendingOptions & {
|
|
13
14
|
conversationId: QualifiedId;
|
|
14
15
|
/**
|
|
15
|
-
* Can be either a QualifiedId[] or QualfiedUserClients. The type has some effect on the behavior of the method. (Needed only for Proteus)
|
|
16
|
-
* When given a QualifiedId[] the method will fetch the freshest list of devices for those users (since they are not given by the consumer). As a consequence no ClientMismatch error will trigger and we will ignore missing clients when sending
|
|
17
|
-
* When given a QualifiedUserClients the method will only send to the clients listed in the userIds. This could lead to ClientMismatch (since the given list of devices might not be the freshest one and new clients could have been created)
|
|
16
|
+
* Can be either a QualifiedId[], string[], UserClients or QualfiedUserClients. The type has some effect on the behavior of the method. (Needed only for Proteus)
|
|
17
|
+
* When given a QualifiedId[] or string[] the method will fetch the freshest list of devices for those users (since they are not given by the consumer). As a consequence no ClientMismatch error will trigger and we will ignore missing clients when sending
|
|
18
|
+
* When given a QualifiedUserClients or UserClients the method will only send to the clients listed in the userIds. This could lead to ClientMismatch (since the given list of devices might not be the freshest one and new clients could have been created)
|
|
19
|
+
* When given a QualifiedId[] or QualifiedUserClients the method will send the message through the federated API endpoint
|
|
20
|
+
* When given a string[] or UserClients the method will send the message through the old API endpoint
|
|
18
21
|
*/
|
|
19
|
-
userIds?: QualifiedId[] | QualifiedUserClients;
|
|
20
|
-
onClientMismatch?: (status: MessageSendingStatus, wasSent: boolean) => void | boolean | Promise<boolean>;
|
|
22
|
+
userIds?: string[] | QualifiedId[] | UserClients | QualifiedUserClients;
|
|
23
|
+
onClientMismatch?: (status: ClientMismatch | MessageSendingStatus, wasSent: boolean) => void | boolean | Promise<boolean>;
|
|
21
24
|
protocol: ConversationProtocol.PROTEUS;
|
|
22
25
|
};
|
|
23
26
|
export type CreateProteusConversationParams = {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ProteusService.types.d.ts","sourceRoot":"","sources":["../../../../src/messagingProtocols/proteus/ProteusService/ProteusService.types.ts"],"names":[],"mappings":"AAmBA,OAAO,EACL,oBAAoB,EACpB,oBAAoB,EACpB,oBAAoB,EACpB,eAAe,EAChB,MAAM,sCAAsC,CAAC;AAC9C,OAAO,EAAC,WAAW,EAAC,MAAM,8BAA8B,CAAC;AAEzD,OAAO,EAAC,cAAc,EAAE,qBAAqB,EAAE,gBAAgB,EAAC,MAAM,uBAAuB,CAAC;AAE9F,MAAM,WAAW,SAAS;IACxB,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,WAAW,CAAC;CACrB;AACD,MAAM,MAAM,oBAAoB,GAAG;IACjC,WAAW,CAAC,EAAE,CAAC,MAAM,EAAE,SAAS,KAAK,IAAI,CAAC;IAC1C,SAAS,EAAE,MAAM,CAAC;CACnB,CAAC;AAEF,MAAM,MAAM,wBAAwB,GAAG,gBAAgB,GACrD,qBAAqB,GAAG;IACtB,cAAc,EAAE,WAAW,CAAC;IAE5B
|
|
1
|
+
{"version":3,"file":"ProteusService.types.d.ts","sourceRoot":"","sources":["../../../../src/messagingProtocols/proteus/ProteusService/ProteusService.types.ts"],"names":[],"mappings":"AAmBA,OAAO,EACL,WAAW,EACX,oBAAoB,EACpB,cAAc,EACd,oBAAoB,EACpB,oBAAoB,EACpB,eAAe,EAChB,MAAM,sCAAsC,CAAC;AAC9C,OAAO,EAAC,WAAW,EAAC,MAAM,8BAA8B,CAAC;AAEzD,OAAO,EAAC,cAAc,EAAE,qBAAqB,EAAE,gBAAgB,EAAC,MAAM,uBAAuB,CAAC;AAE9F,MAAM,WAAW,SAAS;IACxB,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,WAAW,CAAC;CACrB;AACD,MAAM,MAAM,oBAAoB,GAAG;IACjC,eAAe,EAAE,OAAO,CAAC;IACzB,WAAW,CAAC,EAAE,CAAC,MAAM,EAAE,SAAS,KAAK,IAAI,CAAC;IAC1C,SAAS,EAAE,MAAM,CAAC;CACnB,CAAC;AAEF,MAAM,MAAM,wBAAwB,GAAG,gBAAgB,GACrD,qBAAqB,GAAG;IACtB,cAAc,EAAE,WAAW,CAAC;IAE5B;;;;;;OAMG;IACH,OAAO,CAAC,EAAE,MAAM,EAAE,GAAG,WAAW,EAAE,GAAG,WAAW,GAAG,oBAAoB,CAAC;IACxE,gBAAgB,CAAC,EAAE,CACjB,MAAM,EAAE,cAAc,GAAG,oBAAoB,EAC7C,OAAO,EAAE,OAAO,KACb,IAAI,GAAG,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;IACvC,QAAQ,EAAE,oBAAoB,CAAC,OAAO,CAAC;CACxC,CAAC;AAEJ,MAAM,MAAM,+BAA+B,GAAG;IAC5C,gBAAgB,EAAE,eAAe,GAAG,MAAM,CAAC;IAC3C,YAAY,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE,CAAC;CAClC,CAAC;AAEF,MAAM,MAAM,mCAAmC,GAAG,IAAI,CAAC,cAAc,EAAE,SAAS,CAAC,CAAC"}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { APIClient } from '@wireapp/api-client/lib/APIClient';
|
|
2
|
+
import { QualifiedUserClients, UserClients } from '@wireapp/api-client/lib/conversation';
|
|
3
|
+
import { QualifiedId, QualifiedUserPreKeyBundleMap, UserPreKeyBundleMap } from '@wireapp/api-client/lib/user';
|
|
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
|
+
/**
|
|
12
|
+
* Will generate a prekey bundle for specific users.
|
|
13
|
+
* If a QualifiedId array is given the bundle will contain all the clients from those users fetched from the server.
|
|
14
|
+
* If a QualifiedUserClients is provided then only the clients in the payload will be targeted (which could generate a ClientMismatch when sending messages)
|
|
15
|
+
*
|
|
16
|
+
* @param {QualifiedId[]|QualifiedUserClients} userIds - Targeted users.
|
|
17
|
+
* @returns {Promise<QualifiedUserPreKeyBundleMap}
|
|
18
|
+
*/
|
|
19
|
+
interface GetQualifiedPreKeyBundleMapParams {
|
|
20
|
+
apiClient: APIClient;
|
|
21
|
+
userIds?: QualifiedId[] | QualifiedUserClients;
|
|
22
|
+
}
|
|
23
|
+
declare const getQualifiedPreKeyBundle: ({ apiClient, userIds, }: GetQualifiedPreKeyBundleMapParams) => Promise<QualifiedUserPreKeyBundleMap>;
|
|
24
|
+
export { getPreKeyBundleMap, getQualifiedPreKeyBundle, preKeyBundleToUserClients };
|
|
25
|
+
//# sourceMappingURL=PreKeyBundle.d.ts.map
|
|
@@ -0,0 +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"}
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/*
|
|
3
|
+
* Wire
|
|
4
|
+
* Copyright (C) 2022 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.preKeyBundleToUserClients = exports.getQualifiedPreKeyBundle = exports.getPreKeyBundleMap = void 0;
|
|
22
|
+
const util_1 = require("../../../../util");
|
|
23
|
+
const preKeyBundleToUserClients = (users) => {
|
|
24
|
+
return Object.entries(users).reduce((acc, [userId, clientsObj]) => {
|
|
25
|
+
acc[userId] = Object.keys(clientsObj);
|
|
26
|
+
return acc;
|
|
27
|
+
}, {});
|
|
28
|
+
};
|
|
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
|
+
const getQualifiedPreKeyBundle = async ({ apiClient, userIds, }) => {
|
|
61
|
+
let targets = [];
|
|
62
|
+
if (userIds) {
|
|
63
|
+
if ((0, util_1.isQualifiedIdArray)(userIds)) {
|
|
64
|
+
targets = userIds.map(id => ({ id }));
|
|
65
|
+
}
|
|
66
|
+
else {
|
|
67
|
+
targets = Object.entries(userIds).reduce((accumulator, [domain, userClients]) => {
|
|
68
|
+
for (const userId in userClients) {
|
|
69
|
+
accumulator.push({ id: { id: userId, domain }, clients: userClients[userId] });
|
|
70
|
+
}
|
|
71
|
+
return accumulator;
|
|
72
|
+
}, []);
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
const preKeys = await Promise.all(targets.map(async ({ id: userId, clients }) => {
|
|
76
|
+
const prekeyBundle = await apiClient.api.user.getUserPreKeys(userId);
|
|
77
|
+
// We filter the clients that should not receive the message (if a QualifiedUserClients was given as parameter)
|
|
78
|
+
const userClients = clients
|
|
79
|
+
? prekeyBundle.clients.filter(client => clients.includes(client.client))
|
|
80
|
+
: prekeyBundle.clients;
|
|
81
|
+
return { user: userId, clients: userClients };
|
|
82
|
+
}));
|
|
83
|
+
return preKeys.reduce((bundleMap, qualifiedPrekey) => {
|
|
84
|
+
var _a, _b, _c;
|
|
85
|
+
bundleMap[_a = qualifiedPrekey.user.domain] || (bundleMap[_a] = {});
|
|
86
|
+
for (const client of qualifiedPrekey.clients) {
|
|
87
|
+
(_b = bundleMap[qualifiedPrekey.user.domain])[_c = qualifiedPrekey.user.id] || (_b[_c] = {});
|
|
88
|
+
bundleMap[qualifiedPrekey.user.domain][qualifiedPrekey.user.id][client.client] = client.prekey;
|
|
89
|
+
}
|
|
90
|
+
return bundleMap;
|
|
91
|
+
}, {});
|
|
92
|
+
};
|
|
93
|
+
exports.getQualifiedPreKeyBundle = getQualifiedPreKeyBundle;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"PreKeyBundle.test.d.ts","sourceRoot":"","sources":["../../../../../src/messagingProtocols/proteus/Utility/PreKeyBundle/PreKeyBundle.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/*
|
|
3
|
+
* Wire
|
|
4
|
+
* Copyright (C) 2022 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 PreKeyBundle_1 = require("./PreKeyBundle");
|
|
22
|
+
const firstUser = {
|
|
23
|
+
id: 'bc0c99f1-49a5-4ad2-889a-62885af37088',
|
|
24
|
+
clients: { first: 'be67218b77d02d30', second: 'ae87218e77d02d30' },
|
|
25
|
+
};
|
|
26
|
+
const secondUser = {
|
|
27
|
+
id: 'bc0c99ff-ffa5-ffd2-ff9a-6ff85af3ff88',
|
|
28
|
+
clients: { first: 'kk67218b77d02d30', second: 'kk87218e77d02d30' },
|
|
29
|
+
};
|
|
30
|
+
const validPreKey = {
|
|
31
|
+
id: 1337,
|
|
32
|
+
key: 'pQABARn//wKhAFggJ1Fbpg5l6wnzKOJE+vXpRnkqUYhIvVnR5lNXEbO2o/0DoQChAFggHxZvgvtDktY/vqBcpjjo6rQnXvcNQhfwmy8AJQJKlD0E9g==',
|
|
33
|
+
};
|
|
34
|
+
describe('PrekeyHandler', () => {
|
|
35
|
+
describe('preKeyBundleToUserClients', () => {
|
|
36
|
+
it('maps preKeyBundle to userClients', () => {
|
|
37
|
+
const input = {
|
|
38
|
+
[firstUser.id]: { [firstUser.clients.first]: validPreKey },
|
|
39
|
+
};
|
|
40
|
+
const output = {
|
|
41
|
+
[firstUser.id]: [firstUser.clients.first],
|
|
42
|
+
};
|
|
43
|
+
expect((0, PreKeyBundle_1.preKeyBundleToUserClients)(input)).toEqual(output);
|
|
44
|
+
});
|
|
45
|
+
it('maps preKeyBundle to userClients (multiple clients)', () => {
|
|
46
|
+
const input = {
|
|
47
|
+
[firstUser.id]: { [firstUser.clients.first]: validPreKey, [firstUser.clients.second]: validPreKey },
|
|
48
|
+
};
|
|
49
|
+
const output = {
|
|
50
|
+
[firstUser.id]: [firstUser.clients.first, firstUser.clients.second],
|
|
51
|
+
};
|
|
52
|
+
expect((0, PreKeyBundle_1.preKeyBundleToUserClients)(input)).toEqual(output);
|
|
53
|
+
});
|
|
54
|
+
it('maps preKeyBundle to userClients (multiple users)', () => {
|
|
55
|
+
const input = {
|
|
56
|
+
[firstUser.id]: { [firstUser.clients.first]: validPreKey, [firstUser.clients.second]: validPreKey },
|
|
57
|
+
[secondUser.id]: { [secondUser.clients.first]: validPreKey, [secondUser.clients.second]: validPreKey },
|
|
58
|
+
};
|
|
59
|
+
const output = {
|
|
60
|
+
[firstUser.id]: [firstUser.clients.first, firstUser.clients.second],
|
|
61
|
+
[secondUser.id]: [secondUser.clients.first, secondUser.clients.second],
|
|
62
|
+
};
|
|
63
|
+
expect((0, PreKeyBundle_1.preKeyBundleToUserClients)(input)).toEqual(output);
|
|
64
|
+
});
|
|
65
|
+
});
|
|
66
|
+
});
|