@wireapp/core 46.46.6-beta.10.d7a6c4c53 → 46.46.6-beta.14.f6fd03fe6
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 +51 -168
- package/lib/Account.d.ts.map +1 -1
- package/lib/Account.js +127 -517
- package/lib/Account.test.js +147 -158
- package/lib/broadcast/AvailabilityType.d.ts +1 -1
- package/lib/broadcast/AvailabilityType.d.ts.map +1 -1
- package/lib/broadcast/BroadcastService.d.ts +1 -1
- package/lib/broadcast/BroadcastService.d.ts.map +1 -1
- package/lib/broadcast/BroadcastService.js +1 -1
- package/lib/client/ClientService.d.ts +3 -4
- package/lib/client/ClientService.d.ts.map +1 -1
- package/lib/client/ClientService.js +5 -19
- package/lib/conversation/AbortReason.d.ts +1 -1
- package/lib/conversation/AbortReason.d.ts.map +1 -1
- package/lib/conversation/AssetService/AssetService.d.ts +30 -12
- package/lib/conversation/AssetService/AssetService.d.ts.map +1 -1
- package/lib/conversation/AssetService/AssetService.js +10 -1
- package/lib/conversation/AssetService/AssetService.test.js +3 -8
- package/lib/conversation/ClientActionType.d.ts +1 -1
- package/lib/conversation/ClientActionType.d.ts.map +1 -1
- package/lib/conversation/ClientActionType.js +1 -1
- package/lib/conversation/ConversationService/ConversationService.d.ts +14 -98
- package/lib/conversation/ConversationService/ConversationService.d.ts.map +1 -1
- package/lib/conversation/ConversationService/ConversationService.js +101 -314
- package/lib/conversation/ConversationService/ConversationService.test.js +47 -441
- package/lib/conversation/ConversationService/ConversationService.types.d.ts +4 -5
- package/lib/conversation/ConversationService/ConversationService.types.d.ts.map +1 -1
- package/lib/conversation/ConversationService/Utility/getConversationQualifiedMembers.d.ts.map +1 -1
- package/lib/conversation/ConversationService/Utility/getConversationQualifiedMembers.js +3 -6
- package/lib/conversation/SubconversationService/SubconversationService.d.ts.map +1 -1
- package/lib/conversation/SubconversationService/SubconversationService.js +11 -158
- package/lib/conversation/SubconversationService/SubconversationService.test.js +2 -8
- package/lib/conversation/content/AssetContent.d.ts +1 -1
- package/lib/conversation/content/AssetContent.d.ts.map +1 -1
- package/lib/conversation/content/ButtonActionConfirmationContent.d.ts +1 -1
- package/lib/conversation/content/ButtonActionConfirmationContent.d.ts.map +1 -1
- package/lib/conversation/content/ButtonActionContent.d.ts +1 -1
- package/lib/conversation/content/ButtonActionContent.d.ts.map +1 -1
- package/lib/conversation/content/ClearedContent.d.ts +1 -1
- package/lib/conversation/content/ClearedContent.d.ts.map +1 -1
- package/lib/conversation/content/ClientActionContent.d.ts +1 -1
- package/lib/conversation/content/ClientActionContent.d.ts.map +1 -1
- package/lib/conversation/content/CompositeContent.d.ts +1 -1
- package/lib/conversation/content/CompositeContent.d.ts.map +1 -1
- package/lib/conversation/content/ConfirmationContent.d.ts +1 -1
- package/lib/conversation/content/ConfirmationContent.d.ts.map +1 -1
- package/lib/conversation/content/DeletedContent.d.ts +1 -1
- package/lib/conversation/content/DeletedContent.d.ts.map +1 -1
- package/lib/conversation/content/HiddenContent.d.ts +1 -1
- package/lib/conversation/content/HiddenContent.d.ts.map +1 -1
- package/lib/conversation/content/KnockContent.d.ts +1 -1
- package/lib/conversation/content/KnockContent.d.ts.map +1 -1
- package/lib/conversation/content/LinkPreviewContent.d.ts +1 -1
- package/lib/conversation/content/LinkPreviewContent.d.ts.map +1 -1
- package/lib/conversation/content/MentionContent.d.ts +1 -1
- package/lib/conversation/content/MentionContent.d.ts.map +1 -1
- package/lib/conversation/content/MultipartContent.d.ts +1 -1
- package/lib/conversation/content/MultipartContent.d.ts.map +1 -1
- package/lib/conversation/content/QuoteContent.d.ts +1 -1
- package/lib/conversation/content/QuoteContent.d.ts.map +1 -1
- package/lib/conversation/content/TweetContent.d.ts +1 -1
- package/lib/conversation/content/TweetContent.d.ts.map +1 -1
- package/lib/conversation/content/index.d.ts +1 -1
- package/lib/conversation/content/index.d.ts.map +1 -1
- package/lib/conversation/content/index.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 +1 -1
- package/lib/conversation/message/MessageService.d.ts.map +1 -1
- package/lib/conversation/message/MessageService.js +1 -1
- package/lib/conversation/message/MessageService.test.js +1 -7
- package/lib/conversation/message/MessageToProtoMapper.d.ts +1 -1
- package/lib/conversation/message/MessageToProtoMapper.d.ts.map +1 -1
- package/lib/conversation/message/MessageToProtoMapper.js +1 -1
- package/lib/conversation/message/messageSender.js +2 -2
- package/lib/cryptography/AssetCryptography/EncryptedAsset.d.ts +2 -2
- package/lib/cryptography/AssetCryptography/EncryptedAsset.d.ts.map +1 -1
- package/lib/messagingProtocols/common.types.d.ts +0 -9
- package/lib/messagingProtocols/common.types.d.ts.map +1 -1
- package/lib/messagingProtocols/mls/E2EIdentityService/E2EIService.types.d.ts +2 -2
- package/lib/messagingProtocols/mls/E2EIdentityService/E2EIService.types.d.ts.map +1 -1
- package/lib/messagingProtocols/mls/E2EIdentityService/E2EIService.types.js +1 -2
- package/lib/messagingProtocols/mls/E2EIdentityService/E2EIServiceExternal.d.ts +1 -1
- package/lib/messagingProtocols/mls/E2EIdentityService/E2EIServiceExternal.d.ts.map +1 -1
- package/lib/messagingProtocols/mls/E2EIdentityService/E2EIServiceExternal.js +11 -13
- package/lib/messagingProtocols/mls/E2EIdentityService/E2EIServiceExternal.test.js +16 -21
- package/lib/messagingProtocols/mls/E2EIdentityService/E2EIServiceInternal.d.ts +3 -9
- package/lib/messagingProtocols/mls/E2EIdentityService/E2EIServiceInternal.d.ts.map +1 -1
- package/lib/messagingProtocols/mls/E2EIdentityService/E2EIServiceInternal.js +12 -31
- package/lib/messagingProtocols/mls/E2EIdentityService/Helper/index.d.ts +0 -6
- package/lib/messagingProtocols/mls/E2EIdentityService/Helper/index.d.ts.map +1 -1
- package/lib/messagingProtocols/mls/E2EIdentityService/Helper/index.js +1 -19
- package/lib/messagingProtocols/mls/EventHandler/events/messageAdd/IncomingMessagesQueue/IncomingMesssagesQueue.d.ts +4 -0
- package/lib/messagingProtocols/mls/EventHandler/events/messageAdd/IncomingMessagesQueue/IncomingMesssagesQueue.d.ts.map +1 -0
- package/lib/messagingProtocols/mls/EventHandler/events/messageAdd/IncomingMessagesQueue/IncomingMesssagesQueue.js +69 -0
- package/lib/messagingProtocols/mls/EventHandler/events/messageAdd/IncomingMessagesQueue/index.d.ts +2 -0
- package/lib/messagingProtocols/mls/EventHandler/events/messageAdd/{IncomingProposalsQueue → IncomingMessagesQueue}/index.d.ts.map +1 -1
- package/lib/messagingProtocols/mls/EventHandler/events/messageAdd/{IncomingProposalsQueue → IncomingMessagesQueue}/index.js +1 -1
- package/lib/messagingProtocols/mls/EventHandler/events/messageAdd/index.d.ts +1 -0
- package/lib/messagingProtocols/mls/EventHandler/events/messageAdd/index.d.ts.map +1 -1
- package/lib/messagingProtocols/mls/EventHandler/events/messageAdd/index.js +1 -0
- package/lib/messagingProtocols/mls/EventHandler/events/messageAdd/messageAdd.d.ts.map +1 -1
- package/lib/messagingProtocols/mls/EventHandler/events/messageAdd/messageAdd.js +14 -23
- package/lib/messagingProtocols/mls/EventHandler/events/messageAdd/messageAdd.test.d.ts +2 -0
- package/lib/messagingProtocols/mls/EventHandler/events/messageAdd/messageAdd.test.d.ts.map +1 -0
- package/lib/messagingProtocols/mls/EventHandler/events/messageAdd/messageAdd.test.js +98 -0
- package/lib/messagingProtocols/mls/EventHandler/events/welcomeMessage/welcomeMessage.d.ts.map +1 -1
- package/lib/messagingProtocols/mls/EventHandler/events/welcomeMessage/welcomeMessage.js +2 -5
- package/lib/messagingProtocols/mls/EventHandler/events/welcomeMessage/welcomeMessage.test.js +3 -13
- package/lib/messagingProtocols/mls/MLSService/CoreCryptoMLSError.d.ts +2 -38
- package/lib/messagingProtocols/mls/MLSService/CoreCryptoMLSError.d.ts.map +1 -1
- package/lib/messagingProtocols/mls/MLSService/CoreCryptoMLSError.js +6 -41
- package/lib/messagingProtocols/mls/MLSService/MLSService.d.ts +34 -38
- package/lib/messagingProtocols/mls/MLSService/MLSService.d.ts.map +1 -1
- package/lib/messagingProtocols/mls/MLSService/MLSService.js +208 -267
- package/lib/messagingProtocols/mls/MLSService/MLSService.test.js +160 -157
- package/lib/messagingProtocols/mls/MLSService/commitBundleUtil.js +3 -3
- package/lib/messagingProtocols/mls/MLSService/commitBundleUtil.test.js +5 -5
- package/lib/messagingProtocols/mls/conversationRejoinQueue.js +2 -2
- package/lib/messagingProtocols/mls/types.d.ts +8 -0
- package/lib/messagingProtocols/mls/types.d.ts.map +1 -1
- package/lib/messagingProtocols/proteus/EventHandler/events/otrMessageAdd/otrMessageAdd.d.ts.map +1 -1
- package/lib/messagingProtocols/proteus/EventHandler/events/otrMessageAdd/otrMessageAdd.js +1 -7
- package/lib/messagingProtocols/proteus/ProteusService/CryptoClient/CoreCryptoWrapper/CoreCryptoWrapper.d.ts +15 -8
- package/lib/messagingProtocols/proteus/ProteusService/CryptoClient/CoreCryptoWrapper/CoreCryptoWrapper.d.ts.map +1 -1
- package/lib/messagingProtocols/proteus/ProteusService/CryptoClient/CoreCryptoWrapper/CoreCryptoWrapper.js +62 -97
- package/lib/messagingProtocols/proteus/ProteusService/CryptoClient/CryptoClient.types.d.ts +6 -0
- package/lib/messagingProtocols/proteus/ProteusService/CryptoClient/CryptoClient.types.d.ts.map +1 -1
- package/lib/messagingProtocols/proteus/ProteusService/DecryptionErrorGenerator/DecryptionErrorGenerator.d.ts +6 -1
- package/lib/messagingProtocols/proteus/ProteusService/DecryptionErrorGenerator/DecryptionErrorGenerator.d.ts.map +1 -1
- package/lib/messagingProtocols/proteus/ProteusService/DecryptionErrorGenerator/DecryptionErrorGenerator.js +22 -19
- package/lib/messagingProtocols/proteus/ProteusService/ProteusService.d.ts +3 -5
- package/lib/messagingProtocols/proteus/ProteusService/ProteusService.d.ts.map +1 -1
- package/lib/messagingProtocols/proteus/ProteusService/ProteusService.js +24 -11
- package/lib/messagingProtocols/proteus/ProteusService/ProteusService.mocks.d.ts +0 -1
- package/lib/messagingProtocols/proteus/ProteusService/ProteusService.mocks.d.ts.map +1 -1
- package/lib/messagingProtocols/proteus/ProteusService/ProteusService.mocks.js +2 -11
- package/lib/messagingProtocols/proteus/ProteusService/ProteusService.test.js +9 -13
- package/lib/messagingProtocols/proteus/ProteusService/ProteusService.types.d.ts +2 -3
- package/lib/messagingProtocols/proteus/ProteusService/ProteusService.types.d.ts.map +1 -1
- package/lib/messagingProtocols/proteus/ProteusService/WithMockedGenerics.test.js +4 -11
- package/lib/messagingProtocols/proteus/ProteusService/cryptoMigrationStateStore.d.ts +4 -0
- package/lib/messagingProtocols/proteus/ProteusService/cryptoMigrationStateStore.d.ts.map +1 -1
- package/lib/messagingProtocols/proteus/ProteusService/cryptoMigrationStateStore.js +5 -0
- package/lib/messagingProtocols/proteus/ProteusService/identityClearer.d.ts +1 -2
- package/lib/messagingProtocols/proteus/ProteusService/identityClearer.d.ts.map +1 -1
- package/lib/messagingProtocols/proteus/ProteusService/identityClearer.js +2 -8
- package/lib/messagingProtocols/proteus/Utility/SessionHandler/SessionHandler.test.js +0 -4
- package/lib/messagingProtocols/proteus/Utility/getGenericMessageParams.d.ts +1 -1
- package/lib/messagingProtocols/proteus/Utility/getGenericMessageParams.d.ts.map +1 -1
- package/lib/messagingProtocols/proteus/Utility/getGenericMessageParams.js +1 -1
- package/lib/notification/NotificationService.d.ts +6 -20
- package/lib/notification/NotificationService.d.ts.map +1 -1
- package/lib/notification/NotificationService.js +14 -23
- package/lib/notification/NotificationService.test.js +0 -8
- package/lib/secretStore/secretKeyGenerator.d.ts +0 -1
- package/lib/secretStore/secretKeyGenerator.d.ts.map +1 -1
- package/lib/secretStore/secretKeyGenerator.js +1 -3
- package/lib/self/SelfService.d.ts +2 -2
- package/lib/self/SelfService.d.ts.map +1 -1
- package/lib/self/SelfService.test.js +2 -5
- package/lib/team/TeamService.d.ts +2 -5
- package/lib/team/TeamService.d.ts.map +1 -1
- package/lib/team/TeamService.js +2 -12
- package/lib/user/UserService.d.ts +2 -2
- package/lib/user/UserService.d.ts.map +1 -1
- package/lib/user/UserService.js +3 -3
- package/lib/util/TypePredicateUtil.d.ts.map +1 -1
- package/lib/util/TypePredicateUtil.js +2 -2
- package/package.json +3 -3
- package/lib/messagingProtocols/mls/EventHandler/events/messageAdd/IncomingProposalsQueue/IncomingProposalsQueue.d.ts +0 -7
- package/lib/messagingProtocols/mls/EventHandler/events/messageAdd/IncomingProposalsQueue/IncomingProposalsQueue.d.ts.map +0 -1
- package/lib/messagingProtocols/mls/EventHandler/events/messageAdd/IncomingProposalsQueue/IncomingProposalsQueue.js +0 -48
- package/lib/messagingProtocols/mls/EventHandler/events/messageAdd/IncomingProposalsQueue/index.d.ts +0 -2
- package/lib/messagingProtocols/mls/MLSService/CoreCryptoMLSError.test.d.ts +0 -2
- package/lib/messagingProtocols/mls/MLSService/CoreCryptoMLSError.test.d.ts.map +0 -1
- package/lib/messagingProtocols/mls/MLSService/CoreCryptoMLSError.test.js +0 -124
- package/lib/messagingProtocols/mls/recovery/MlsErrorMapper.d.ts +0 -78
- package/lib/messagingProtocols/mls/recovery/MlsErrorMapper.d.ts.map +0 -1
- package/lib/messagingProtocols/mls/recovery/MlsErrorMapper.js +0 -173
- package/lib/messagingProtocols/mls/recovery/MlsErrorMapper.test.d.ts +0 -2
- package/lib/messagingProtocols/mls/recovery/MlsErrorMapper.test.d.ts.map +0 -1
- package/lib/messagingProtocols/mls/recovery/MlsErrorMapper.test.js +0 -117
- package/lib/messagingProtocols/mls/recovery/MlsRecoveryOrchestrator.d.ts +0 -167
- package/lib/messagingProtocols/mls/recovery/MlsRecoveryOrchestrator.d.ts.map +0 -1
- package/lib/messagingProtocols/mls/recovery/MlsRecoveryOrchestrator.js +0 -317
- package/lib/messagingProtocols/mls/recovery/MlsRecoveryOrchestrator.test.d.ts +0 -2
- package/lib/messagingProtocols/mls/recovery/MlsRecoveryOrchestrator.test.d.ts.map +0 -1
- package/lib/messagingProtocols/mls/recovery/MlsRecoveryOrchestrator.test.js +0 -248
- package/lib/messagingProtocols/mls/recovery/index.d.ts +0 -5
- package/lib/messagingProtocols/mls/recovery/index.d.ts.map +0 -1
- package/lib/messagingProtocols/mls/recovery/index.js +0 -28
- package/lib/test/StoreHelper.d.ts +0 -2
- package/lib/test/StoreHelper.d.ts.map +0 -1
- package/lib/test/StoreHelper.js +0 -27
|
@@ -17,29 +17,6 @@
|
|
|
17
17
|
* along with this program. If not, see http://www.gnu.org/licenses/.
|
|
18
18
|
*
|
|
19
19
|
*/
|
|
20
|
-
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
21
|
-
if (k2 === undefined) k2 = k;
|
|
22
|
-
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
23
|
-
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
24
|
-
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
25
|
-
}
|
|
26
|
-
Object.defineProperty(o, k2, desc);
|
|
27
|
-
}) : (function(o, m, k, k2) {
|
|
28
|
-
if (k2 === undefined) k2 = k;
|
|
29
|
-
o[k2] = m[k];
|
|
30
|
-
}));
|
|
31
|
-
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
32
|
-
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
33
|
-
}) : function(o, v) {
|
|
34
|
-
o["default"] = v;
|
|
35
|
-
});
|
|
36
|
-
var __importStar = (this && this.__importStar) || function (mod) {
|
|
37
|
-
if (mod && mod.__esModule) return mod;
|
|
38
|
-
var result = {};
|
|
39
|
-
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
|
|
40
|
-
__setModuleDefault(result, mod);
|
|
41
|
-
return result;
|
|
42
|
-
};
|
|
43
20
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
44
21
|
const client_1 = require("@wireapp/api-client/lib/client");
|
|
45
22
|
const event_1 = require("@wireapp/api-client/lib/event");
|
|
@@ -54,11 +31,6 @@ const conversation_1 = require("../../../conversation");
|
|
|
54
31
|
const CoreDB_1 = require("../../../storage/CoreDB");
|
|
55
32
|
const RecurringTaskScheduler_1 = require("../../../util/RecurringTaskScheduler");
|
|
56
33
|
const TaskScheduler_1 = require("../../../util/TaskScheduler");
|
|
57
|
-
const Helper = __importStar(require("../E2EIdentityService/Helper"));
|
|
58
|
-
jest.mock('../E2EIdentityService/Helper', () => ({
|
|
59
|
-
...jest.requireActual('../E2EIdentityService/Helper'),
|
|
60
|
-
getMLSDeviceStatus: jest.fn(),
|
|
61
|
-
}));
|
|
62
34
|
jest.createMockFromModule('@wireapp/api-client');
|
|
63
35
|
function createUserId() {
|
|
64
36
|
return { id: (0, crypto_1.randomUUID)(), domain: '' };
|
|
@@ -67,36 +39,25 @@ const defaultMLSInitConfig = {
|
|
|
67
39
|
ciphersuites: [core_crypto_1.Ciphersuite.MLS_128_DHKEMX25519_AES128GCM_SHA256_Ed25519],
|
|
68
40
|
defaultCiphersuite: core_crypto_1.Ciphersuite.MLS_128_DHKEMX25519_AES128GCM_SHA256_Ed25519,
|
|
69
41
|
};
|
|
70
|
-
// Needs to be divisible by 4 to be a valid base64 string
|
|
71
|
-
const mockGroupId = 'Z3JvdXAtdGVzdC0x';
|
|
72
|
-
const mockedMLSWelcomeEventData = '';
|
|
73
|
-
const apiClients = [];
|
|
74
42
|
const createMLSService = async () => {
|
|
75
43
|
const apiClient = new api_client_1.APIClient();
|
|
76
|
-
|
|
77
|
-
const transactionContext = {
|
|
78
|
-
mlsInit: jest.fn(),
|
|
79
|
-
wipeConversation: jest.fn(),
|
|
80
|
-
clientKeypackages: jest.fn(),
|
|
44
|
+
const mockCoreCrypto = {
|
|
81
45
|
createConversation: jest.fn(),
|
|
82
|
-
clientValidKeypackagesCount: jest.fn(),
|
|
83
46
|
conversationExists: jest.fn(),
|
|
47
|
+
wipeConversation: jest.fn(),
|
|
48
|
+
clientValidKeypackagesCount: jest.fn(),
|
|
49
|
+
clientKeypackages: jest.fn(),
|
|
50
|
+
mlsInit: jest.fn(),
|
|
51
|
+
clientPublicKey: jest.fn(),
|
|
84
52
|
processWelcomeMessage: jest.fn(),
|
|
53
|
+
conversationEpoch: jest.fn(),
|
|
85
54
|
commitPendingProposals: jest.fn(),
|
|
86
|
-
|
|
87
|
-
updateKeyingMaterial: jest.fn(),
|
|
88
|
-
};
|
|
89
|
-
const mockCoreCrypto = {
|
|
90
|
-
transaction: jest.fn(fn => {
|
|
91
|
-
return fn(transactionContext);
|
|
92
|
-
}),
|
|
93
|
-
registerEpochObserver: jest.fn(),
|
|
94
|
-
provideTransport: jest.fn(),
|
|
95
|
-
version: jest.fn(),
|
|
96
|
-
conversationExists: jest.fn(),
|
|
55
|
+
registerCallbacks: jest.fn(),
|
|
97
56
|
e2eiIsEnabled: jest.fn(() => false),
|
|
98
|
-
|
|
99
|
-
|
|
57
|
+
clearPendingGroupFromExternalCommit: async () => { },
|
|
58
|
+
clearPendingCommit: async () => { },
|
|
59
|
+
commitAccepted: jest.fn(),
|
|
60
|
+
transaction: jest.fn(),
|
|
100
61
|
};
|
|
101
62
|
const mockedDb = await (0, CoreDB_1.openDB)('core-test-db');
|
|
102
63
|
const recurringTaskScheduler = new RecurringTaskScheduler_1.RecurringTaskScheduler({
|
|
@@ -108,15 +69,9 @@ const createMLSService = async () => {
|
|
|
108
69
|
});
|
|
109
70
|
const mlsService = new MLSService_1.MLSService(apiClient, mockCoreCrypto, mockedDb, recurringTaskScheduler);
|
|
110
71
|
mlsService['_config'] = { ...defaultMLSInitConfig, nbKeyPackages: 100, keyingMaterialUpdateThreshold: 1 };
|
|
111
|
-
return [mlsService, { apiClient, coreCrypto: mockCoreCrypto, recurringTaskScheduler
|
|
72
|
+
return [mlsService, { apiClient, coreCrypto: mockCoreCrypto, recurringTaskScheduler }];
|
|
112
73
|
};
|
|
113
|
-
afterAll(() => {
|
|
114
|
-
jest.clearAllTimers();
|
|
115
|
-
});
|
|
116
74
|
describe('MLSService', () => {
|
|
117
|
-
afterAll(() => {
|
|
118
|
-
apiClients.forEach(client => client.disconnect());
|
|
119
|
-
});
|
|
120
75
|
describe('registerConversation', () => {
|
|
121
76
|
let mlsService;
|
|
122
77
|
let apiClient;
|
|
@@ -129,6 +84,12 @@ describe('MLSService', () => {
|
|
|
129
84
|
.mockResolvedValue({ removal: { ed25519: 'mXOagqRIX/RFd7QyXJA8/Ed8X+hvQgLXIiwYHm3OQFc=' } });
|
|
130
85
|
jest.spyOn(apiClient.api.client, 'claimMLSKeyPackages').mockResolvedValue({ key_packages: [] });
|
|
131
86
|
jest.spyOn(mlsService, 'scheduleKeyMaterialRenewal').mockImplementation();
|
|
87
|
+
jest.spyOn(mlsService, 'processCommitAction').mockImplementation(() => ({
|
|
88
|
+
failed_to_send: [],
|
|
89
|
+
failed: [],
|
|
90
|
+
events: [],
|
|
91
|
+
time: '',
|
|
92
|
+
}));
|
|
132
93
|
jest.spyOn(mlsService, 'cancelKeyMaterialRenewal').mockImplementation();
|
|
133
94
|
});
|
|
134
95
|
it('creates a new mls conversation and avoid adding the selfUser', async () => {
|
|
@@ -156,10 +117,37 @@ describe('MLSService', () => {
|
|
|
156
117
|
keyPackages: [],
|
|
157
118
|
failures: [failure],
|
|
158
119
|
});
|
|
159
|
-
const failures = await mlsService.registerConversation(groupId, [...users, selfUser], { creator });
|
|
120
|
+
const { failures } = await mlsService.registerConversation(groupId, [...users, selfUser], { creator });
|
|
160
121
|
expect(failures).toEqual([failure]);
|
|
161
122
|
expect(mlsService.scheduleKeyMaterialRenewal).toHaveBeenCalledWith(groupId);
|
|
162
123
|
});
|
|
124
|
+
it("returns a list of failure reasons if it was not possible to upload users' keys", async () => {
|
|
125
|
+
const groupId = 'mXOagqRIX/RFd7QyXJA8/Ed8X+hvQgLXIiwYHm3OQFc=';
|
|
126
|
+
const selfUser = createUserId();
|
|
127
|
+
const creator = { user: selfUser, client: 'client-1' };
|
|
128
|
+
const users = [createUserId(), createUserId()];
|
|
129
|
+
const failureKeysClaiming = {
|
|
130
|
+
reason: conversation_1.AddUsersFailureReasons.OFFLINE_FOR_TOO_LONG,
|
|
131
|
+
users: [users[0]],
|
|
132
|
+
};
|
|
133
|
+
const failureKeysUpload = {
|
|
134
|
+
reason: conversation_1.AddUsersFailureReasons.UNREACHABLE_BACKENDS,
|
|
135
|
+
users: [users[1]],
|
|
136
|
+
backends: [users[1].domain],
|
|
137
|
+
};
|
|
138
|
+
jest.spyOn(mlsService, 'getKeyPackagesPayload').mockResolvedValueOnce({
|
|
139
|
+
keyPackages: [new Uint8Array()],
|
|
140
|
+
failures: [failureKeysClaiming],
|
|
141
|
+
});
|
|
142
|
+
jest.spyOn(mlsService, 'addUsersToExistingConversation').mockResolvedValueOnce({
|
|
143
|
+
failures: [failureKeysUpload],
|
|
144
|
+
events: [],
|
|
145
|
+
time: '',
|
|
146
|
+
});
|
|
147
|
+
const { failures } = await mlsService.registerConversation(groupId, [...users, selfUser], { creator });
|
|
148
|
+
expect(failures).toEqual([failureKeysClaiming, failureKeysUpload]);
|
|
149
|
+
expect(mlsService.scheduleKeyMaterialRenewal).toHaveBeenCalledWith(groupId);
|
|
150
|
+
});
|
|
163
151
|
});
|
|
164
152
|
describe('getKeyPackagesPayload', () => {
|
|
165
153
|
it('succesfully claims keys for all users', async () => {
|
|
@@ -194,24 +182,24 @@ describe('MLSService', () => {
|
|
|
194
182
|
});
|
|
195
183
|
describe('isConversationEstablished', () => {
|
|
196
184
|
it('returns false if conversation does not exist locally', async () => {
|
|
197
|
-
const [mlsService
|
|
185
|
+
const [mlsService] = await createMLSService();
|
|
198
186
|
const groupId = 'mXOagqRIX/RFd7QyXJA8/Ed8X+hvQgLXIiwYHm3OQFc=';
|
|
199
|
-
jest.spyOn(
|
|
187
|
+
jest.spyOn(mlsService, 'conversationExists').mockResolvedValueOnce(false);
|
|
200
188
|
const isEstablshed = await mlsService.isConversationEstablished(groupId);
|
|
201
189
|
expect(isEstablshed).toBe(false);
|
|
202
190
|
});
|
|
203
191
|
it('returns false if epoch number is 0', async () => {
|
|
204
|
-
const [mlsService
|
|
192
|
+
const [mlsService] = await createMLSService();
|
|
205
193
|
const groupId = 'mXOagqRIX/RFd7QyXJA8/Ed8X+hvQgLXIiwYHm3OQFc=';
|
|
206
|
-
jest.spyOn(
|
|
194
|
+
jest.spyOn(mlsService, 'conversationExists').mockResolvedValueOnce(true);
|
|
207
195
|
jest.spyOn(mlsService, 'getEpoch').mockResolvedValueOnce(0);
|
|
208
196
|
const isEstablshed = await mlsService.isConversationEstablished(groupId);
|
|
209
197
|
expect(isEstablshed).toBe(false);
|
|
210
198
|
});
|
|
211
199
|
it.each([1, 2, 100])('returns false if epoch number is 1 or more', async (epoch) => {
|
|
212
|
-
const [mlsService
|
|
200
|
+
const [mlsService] = await createMLSService();
|
|
213
201
|
const groupId = 'mXOagqRIX/RFd7QyXJA8/Ed8X+hvQgLXIiwYHm3OQFc=';
|
|
214
|
-
jest.spyOn(
|
|
202
|
+
jest.spyOn(mlsService, 'conversationExists').mockResolvedValueOnce(true);
|
|
215
203
|
jest.spyOn(mlsService, 'getEpoch').mockResolvedValueOnce(epoch);
|
|
216
204
|
const isEstablshed = await mlsService.isConversationEstablished(groupId);
|
|
217
205
|
expect(isEstablshed).toBe(true);
|
|
@@ -281,7 +269,7 @@ describe('MLSService', () => {
|
|
|
281
269
|
});
|
|
282
270
|
describe('initClient', () => {
|
|
283
271
|
it('uses the default config if config is not provided by the consumer', async () => {
|
|
284
|
-
const [mlsService, { apiClient, coreCrypto
|
|
272
|
+
const [mlsService, { apiClient, coreCrypto }] = await createMLSService();
|
|
285
273
|
const mockUserId = { id: 'user-1', domain: 'local.zinfra.io' };
|
|
286
274
|
const mockClientId = 'client-1';
|
|
287
275
|
const mockClient = { mls_public_keys: {}, id: mockClientId };
|
|
@@ -292,11 +280,11 @@ describe('MLSService', () => {
|
|
|
292
280
|
jest.spyOn(apiClient.api.client, 'getMLSKeyPackageCount').mockResolvedValueOnce(mlsService.config.nbKeyPackages);
|
|
293
281
|
const config = { ...defaultMLSInitConfig };
|
|
294
282
|
await mlsService.initClient(mockUserId, mockClient, config);
|
|
295
|
-
expect(
|
|
283
|
+
expect(coreCrypto.mlsInit).toHaveBeenCalledWith(expect.any(Uint8Array), [core_crypto_1.Ciphersuite.MLS_128_DHKEMX25519_AES128GCM_SHA256_Ed25519], 100);
|
|
296
284
|
expect(mlsService.config.nbKeyPackages).toEqual(100);
|
|
297
285
|
});
|
|
298
286
|
it('uses the config provided by the consumer', async () => {
|
|
299
|
-
const [mlsService, { apiClient,
|
|
287
|
+
const [mlsService, { apiClient, coreCrypto }] = await createMLSService();
|
|
300
288
|
const mockUserId = { id: 'user-1', domain: 'local.zinfra.io' };
|
|
301
289
|
const mockClientId = 'client-1';
|
|
302
290
|
const mockClient = { mls_public_keys: {}, id: mockClientId };
|
|
@@ -307,11 +295,11 @@ describe('MLSService', () => {
|
|
|
307
295
|
jest.spyOn(apiClient.api.client, 'getMLSKeyPackageCount').mockResolvedValueOnce(mlsService.config.nbKeyPackages);
|
|
308
296
|
const config = { ...defaultMLSInitConfig, nbKeyPackages: 40, keyingMaterialUpdateThreshold: TimeUtil_1.TimeInMillis.DAY };
|
|
309
297
|
await mlsService.initClient(mockUserId, mockClient, config);
|
|
310
|
-
expect(
|
|
298
|
+
expect(coreCrypto.mlsInit).toHaveBeenCalledWith(expect.any(Uint8Array), [core_crypto_1.Ciphersuite.MLS_128_DHKEMX25519_AES128GCM_SHA256_Ed25519], config.nbKeyPackages);
|
|
311
299
|
expect(mlsService.config).toEqual(config);
|
|
312
300
|
});
|
|
313
301
|
it('uses the default config value when provided with undefined by the consumer', async () => {
|
|
314
|
-
const [mlsService, { apiClient,
|
|
302
|
+
const [mlsService, { apiClient, coreCrypto }] = await createMLSService();
|
|
315
303
|
const mockUserId = { id: 'user-1', domain: 'local.zinfra.io' };
|
|
316
304
|
const mockClientId = 'client-1';
|
|
317
305
|
const mockClient = { mls_public_keys: {}, id: mockClientId };
|
|
@@ -326,43 +314,41 @@ describe('MLSService', () => {
|
|
|
326
314
|
keyingMaterialUpdateThreshold: TimeUtil_1.TimeInMillis.DAY,
|
|
327
315
|
};
|
|
328
316
|
await mlsService.initClient(mockUserId, mockClient, config);
|
|
329
|
-
expect(
|
|
317
|
+
expect(coreCrypto.mlsInit).toHaveBeenCalledWith(expect.any(Uint8Array), [core_crypto_1.Ciphersuite.MLS_128_DHKEMX25519_AES128GCM_SHA256_Ed25519], 100);
|
|
330
318
|
expect(mlsService.config).toEqual({ ...config, nbKeyPackages: 100 });
|
|
331
319
|
});
|
|
332
320
|
it('uploads public key only if it was not yet defined on client entity', async () => {
|
|
333
|
-
const [mlsService, { apiClient,
|
|
321
|
+
const [mlsService, { apiClient, coreCrypto }] = await createMLSService();
|
|
334
322
|
const mockUserId = { id: 'user-1', domain: 'local.zinfra.io' };
|
|
335
323
|
const mockClientId = 'client-1';
|
|
336
324
|
const mockClient = { mls_public_keys: {}, id: mockClientId };
|
|
337
325
|
apiClient.context = { clientType: client_1.ClientType.PERMANENT, clientId: mockClientId, userId: '' };
|
|
326
|
+
const mockedClientPublicKey = new Uint8Array();
|
|
327
|
+
jest.spyOn(coreCrypto, 'clientPublicKey').mockResolvedValueOnce(mockedClientPublicKey);
|
|
338
328
|
jest.spyOn(apiClient.api.client, 'putClient').mockResolvedValueOnce(undefined);
|
|
339
329
|
jest.spyOn(apiClient.api.client, 'getMLSKeyPackageCount').mockResolvedValueOnce(mlsService.config.nbKeyPackages);
|
|
340
|
-
jest.spyOn(Helper, 'getMLSDeviceStatus').mockReturnValueOnce(Helper.MLSDeviceStatus.FRESH);
|
|
341
|
-
jest.spyOn(coreCrypto, 'clientPublicKey').mockResolvedValue(new Uint8Array());
|
|
342
330
|
await mlsService.initClient(mockUserId, mockClient, defaultMLSInitConfig);
|
|
343
|
-
expect(
|
|
331
|
+
expect(coreCrypto.mlsInit).toHaveBeenCalled();
|
|
344
332
|
expect(apiClient.api.client.putClient).toHaveBeenCalledWith(mockClientId, expect.anything());
|
|
345
333
|
});
|
|
346
334
|
it('uploads key packages if there are not enough keys on backend', async () => {
|
|
347
|
-
const [mlsService, { apiClient,
|
|
335
|
+
const [mlsService, { apiClient, coreCrypto }] = await createMLSService();
|
|
348
336
|
const mockUserId = { id: 'user-1', domain: 'local.zinfra.io' };
|
|
349
337
|
const mockClientId = 'client-1';
|
|
350
338
|
const mockClient = { mls_public_keys: { ed25519: 'key' }, id: mockClientId };
|
|
351
339
|
apiClient.context = { clientType: client_1.ClientType.PERMANENT, clientId: mockClientId, userId: '' };
|
|
352
340
|
const mockedClientKeyPackages = [new Uint8Array()];
|
|
353
|
-
jest.spyOn(
|
|
354
|
-
jest.spyOn(coreCrypto, 'clientPublicKey').mockResolvedValueOnce(new Uint8Array());
|
|
355
|
-
jest.spyOn(Helper, 'getMLSDeviceStatus').mockReturnValueOnce(Helper.MLSDeviceStatus.REGISTERED);
|
|
356
|
-
jest.spyOn(apiClient.api.client, 'uploadMLSKeyPackages').mockResolvedValueOnce(undefined);
|
|
341
|
+
jest.spyOn(coreCrypto, 'clientKeypackages').mockResolvedValueOnce(mockedClientKeyPackages);
|
|
357
342
|
jest
|
|
358
343
|
.spyOn(apiClient.api.client, 'getMLSKeyPackageCount')
|
|
359
344
|
.mockResolvedValueOnce(mlsService['minRequiredKeyPackages'] - 1);
|
|
345
|
+
jest.spyOn(apiClient.api.client, 'uploadMLSKeyPackages').mockResolvedValueOnce(undefined);
|
|
360
346
|
await mlsService.initClient(mockUserId, mockClient, defaultMLSInitConfig);
|
|
361
|
-
expect(
|
|
347
|
+
expect(coreCrypto.mlsInit).toHaveBeenCalled();
|
|
362
348
|
expect(apiClient.api.client.uploadMLSKeyPackages).toHaveBeenCalledWith(mockClientId, expect.anything());
|
|
363
349
|
});
|
|
364
350
|
it('does not upload public key or key packages if both are already uploaded', async () => {
|
|
365
|
-
const [mlsService, { apiClient,
|
|
351
|
+
const [mlsService, { apiClient, coreCrypto }] = await createMLSService();
|
|
366
352
|
const mockUserId = { id: 'user-1', domain: 'local.zinfra.io' };
|
|
367
353
|
const mockClientId = 'client-1';
|
|
368
354
|
const mockClient = { mls_public_keys: { ed25519: 'key' }, id: mockClientId };
|
|
@@ -371,64 +357,95 @@ describe('MLSService', () => {
|
|
|
371
357
|
jest.spyOn(apiClient.api.client, 'getMLSKeyPackageCount').mockResolvedValueOnce(mlsService.config.nbKeyPackages);
|
|
372
358
|
jest.spyOn(apiClient.api.client, 'uploadMLSKeyPackages');
|
|
373
359
|
jest.spyOn(apiClient.api.client, 'putClient');
|
|
374
|
-
jest.spyOn(coreCrypto, 'clientPublicKey').mockResolvedValueOnce(new Uint8Array());
|
|
375
360
|
await mlsService.initClient(mockUserId, mockClient, defaultMLSInitConfig);
|
|
376
|
-
expect(
|
|
361
|
+
expect(coreCrypto.mlsInit).toHaveBeenCalled();
|
|
377
362
|
expect(apiClient.api.client.uploadMLSKeyPackages).not.toHaveBeenCalled();
|
|
378
363
|
expect(apiClient.api.client.putClient).not.toHaveBeenCalled();
|
|
379
364
|
});
|
|
380
365
|
});
|
|
381
366
|
describe('wipeConversation', () => {
|
|
382
367
|
it('wipes a group and cancels its timers', async () => {
|
|
383
|
-
const [mlsService, {
|
|
368
|
+
const [mlsService, { coreCrypto, recurringTaskScheduler }] = await createMLSService();
|
|
384
369
|
const groupId = 'mXOagqRIX/RFd7QyXJA8/Ed8X+hvQgLXIiwYHm4OQFc=';
|
|
385
|
-
|
|
386
|
-
transactionContext.wipeConversation = jest.fn().mockResolvedValue(undefined);
|
|
370
|
+
jest.spyOn(coreCrypto, 'conversationExists').mockResolvedValueOnce(true);
|
|
387
371
|
jest.spyOn(recurringTaskScheduler, 'cancelTask');
|
|
388
372
|
jest.spyOn(TaskScheduler_1.TaskScheduler, 'cancelTask');
|
|
389
373
|
await mlsService.wipeConversation(groupId);
|
|
390
374
|
expect(recurringTaskScheduler.cancelTask).toHaveBeenCalledWith(expect.stringContaining(groupId));
|
|
391
375
|
expect(TaskScheduler_1.TaskScheduler.cancelTask).toHaveBeenCalledWith(expect.stringContaining(groupId));
|
|
392
|
-
expect(
|
|
376
|
+
expect(coreCrypto.wipeConversation).toHaveBeenCalled();
|
|
393
377
|
});
|
|
394
378
|
it('does not try to wipe a group if it does not exist already', async () => {
|
|
395
|
-
const [mlsService, {
|
|
379
|
+
const [mlsService, { coreCrypto, recurringTaskScheduler }] = await createMLSService();
|
|
396
380
|
const groupId = 'mXOagqRIX/RFd7QyXJA8/Ed8X+hvQgLXIiwYHm4OQFc=';
|
|
397
|
-
|
|
398
|
-
transactionContext.wipeConversation = jest.fn().mockResolvedValue(undefined);
|
|
381
|
+
jest.spyOn(coreCrypto, 'conversationExists').mockResolvedValueOnce(false);
|
|
399
382
|
jest.spyOn(recurringTaskScheduler, 'cancelTask');
|
|
400
383
|
jest.spyOn(TaskScheduler_1.TaskScheduler, 'cancelTask');
|
|
401
384
|
await mlsService.wipeConversation(groupId);
|
|
402
385
|
expect(recurringTaskScheduler.cancelTask).toHaveBeenCalledWith(expect.stringContaining(groupId));
|
|
403
386
|
expect(TaskScheduler_1.TaskScheduler.cancelTask).toHaveBeenCalledWith(expect.stringContaining(groupId));
|
|
404
|
-
expect(
|
|
387
|
+
expect(coreCrypto.wipeConversation).not.toHaveBeenCalled();
|
|
388
|
+
});
|
|
389
|
+
});
|
|
390
|
+
describe('commitPendingProposals', () => {
|
|
391
|
+
it('commits pending proposals and uploads received commit bundle to backend', async () => {
|
|
392
|
+
const [mlsService, { coreCrypto: mockCoreCrypto, apiClient }] = await createMLSService();
|
|
393
|
+
const mockGroupId = 'mXOagqRIX/RFd7QyXJA8/Ed8X+hvQgLXIiwYHm3OQFc=';
|
|
394
|
+
jest.spyOn(mockCoreCrypto, 'commitPendingProposals').mockResolvedValueOnce({
|
|
395
|
+
commit: new Uint8Array(),
|
|
396
|
+
groupInfo: { payload: new Uint8Array() },
|
|
397
|
+
});
|
|
398
|
+
jest.spyOn(apiClient.api.conversation, 'postMlsCommitBundle').mockResolvedValueOnce({ events: [], time: '' });
|
|
399
|
+
await mlsService.commitPendingProposals(mockGroupId);
|
|
400
|
+
expect(mockCoreCrypto.commitPendingProposals).toHaveBeenCalled();
|
|
401
|
+
expect(apiClient.api.conversation.postMlsCommitBundle).toHaveBeenCalled();
|
|
402
|
+
});
|
|
403
|
+
it('clears pending commit and retries when failed committing pending proposals', async () => {
|
|
404
|
+
const [mlsService, { coreCrypto: mockCoreCrypto, apiClient }] = await createMLSService();
|
|
405
|
+
const mockGroupId = 'mXOagqRIX/RFd7QyXJA8/Ed8X+hvQgLXIiwYHm3OQFc=';
|
|
406
|
+
jest.spyOn(mockCoreCrypto, 'commitPendingProposals').mockRejectedValueOnce(new Error('mocked error'));
|
|
407
|
+
jest.spyOn(mockCoreCrypto, 'commitPendingProposals').mockResolvedValueOnce({
|
|
408
|
+
commit: new Uint8Array(),
|
|
409
|
+
groupInfo: { payload: new Uint8Array() },
|
|
410
|
+
});
|
|
411
|
+
jest.spyOn(apiClient.api.conversation, 'postMlsCommitBundle').mockResolvedValueOnce({ events: [], time: '' });
|
|
412
|
+
jest.spyOn(mockCoreCrypto, 'clearPendingCommit');
|
|
413
|
+
jest.spyOn(mockCoreCrypto, 'clearPendingGroupFromExternalCommit');
|
|
414
|
+
await mlsService.commitPendingProposals(mockGroupId);
|
|
415
|
+
expect(mockCoreCrypto.clearPendingCommit).toHaveBeenCalledTimes(1);
|
|
416
|
+
expect(mockCoreCrypto.clearPendingGroupFromExternalCommit).toHaveBeenCalledTimes(1);
|
|
417
|
+
expect(mockCoreCrypto.commitPendingProposals).toHaveBeenCalledTimes(2);
|
|
418
|
+
expect(apiClient.api.conversation.postMlsCommitBundle).toHaveBeenCalledTimes(1);
|
|
405
419
|
});
|
|
406
420
|
});
|
|
407
421
|
describe('handleMLSMessageAddEvent', () => {
|
|
408
|
-
it('decrypts a message', async () => {
|
|
409
|
-
const [mlsService, {
|
|
422
|
+
it('decrypts a message and emits new epoch event if epoch has changed', async () => {
|
|
423
|
+
const [mlsService, { coreCrypto: mockCoreCrypto }] = await createMLSService();
|
|
410
424
|
const mockGroupId = 'mXOagqRIX/RFd7QyXJA8/Ed8X+hvQgLXIiwYHm3OQFc=';
|
|
411
425
|
const mockedNewEpoch = 3;
|
|
412
426
|
const getGroupIdFromConversationId = () => Promise.resolve(mockGroupId);
|
|
413
427
|
const mockedDecryptoedMessage = {
|
|
414
428
|
hasEpochChanged: true,
|
|
415
429
|
isActive: false,
|
|
430
|
+
proposals: [],
|
|
416
431
|
};
|
|
417
|
-
jest.spyOn(
|
|
418
|
-
jest.spyOn(
|
|
432
|
+
jest.spyOn(mockCoreCrypto, 'transaction').mockResolvedValueOnce(mockedDecryptoedMessage);
|
|
433
|
+
jest.spyOn(mockCoreCrypto, 'conversationEpoch').mockResolvedValueOnce(mockedNewEpoch);
|
|
434
|
+
jest.spyOn(mlsService, 'emit').mockImplementation(jest.fn());
|
|
419
435
|
const mockedMLSWelcomeEvent = {
|
|
420
436
|
type: event_1.CONVERSATION_EVENT.MLS_MESSAGE_ADD,
|
|
421
437
|
senderClientId: '',
|
|
422
438
|
conversation: '',
|
|
423
|
-
data:
|
|
439
|
+
data: '',
|
|
424
440
|
from: '',
|
|
425
441
|
time: '',
|
|
426
442
|
};
|
|
427
443
|
await mlsService.handleMLSMessageAddEvent(mockedMLSWelcomeEvent, getGroupIdFromConversationId);
|
|
428
|
-
expect(
|
|
444
|
+
expect(mockCoreCrypto.transaction).toHaveBeenCalled();
|
|
445
|
+
expect(mlsService.emit).toHaveBeenCalledWith('newEpoch', { epoch: mockedNewEpoch, groupId: mockGroupId });
|
|
429
446
|
});
|
|
430
447
|
it('handles pending propoals with a delay after decrypting a message', async () => {
|
|
431
|
-
const [mlsService, {
|
|
448
|
+
const [mlsService, { coreCrypto: mockCoreCrypto }] = await createMLSService();
|
|
432
449
|
jest.useFakeTimers();
|
|
433
450
|
const mockGroupId = 'mXOagqRIX/RFd7QyXJA8/Ed8X+hvQgLXIiwYHm3OQFc=';
|
|
434
451
|
const mockedNewEpoch = 3;
|
|
@@ -437,138 +454,122 @@ describe('MLSService', () => {
|
|
|
437
454
|
const mockedDecryptoedMessage = {
|
|
438
455
|
hasEpochChanged: true,
|
|
439
456
|
isActive: false,
|
|
457
|
+
proposals: [],
|
|
440
458
|
commitDelay,
|
|
441
459
|
};
|
|
442
|
-
jest.spyOn(
|
|
443
|
-
jest.spyOn(
|
|
460
|
+
jest.spyOn(mockCoreCrypto, 'transaction').mockResolvedValueOnce(mockedDecryptoedMessage);
|
|
461
|
+
jest.spyOn(mockCoreCrypto, 'conversationEpoch').mockResolvedValueOnce(mockedNewEpoch);
|
|
444
462
|
jest.spyOn(mlsService, 'commitPendingProposals');
|
|
445
463
|
const mockedMLSWelcomeEvent = {
|
|
446
464
|
type: event_1.CONVERSATION_EVENT.MLS_MESSAGE_ADD,
|
|
447
465
|
senderClientId: '',
|
|
448
466
|
conversation: '',
|
|
449
|
-
data:
|
|
467
|
+
data: '',
|
|
450
468
|
from: '',
|
|
451
469
|
time: new Date().toISOString(),
|
|
452
470
|
};
|
|
453
471
|
await mlsService.handleMLSMessageAddEvent(mockedMLSWelcomeEvent, getGroupIdFromConversationId);
|
|
472
|
+
expect(mockCoreCrypto.commitPendingProposals).not.toHaveBeenCalled();
|
|
454
473
|
jest.advanceTimersByTime(commitDelay);
|
|
455
|
-
expect(
|
|
456
|
-
|
|
457
|
-
it('Throws if decryption fails', async () => {
|
|
458
|
-
const [mlsService, { transactionContext }] = await createMLSService();
|
|
459
|
-
const mockGroupId = 'mXOagqRIX/RFd7QyXJA8/Ed8X+hvQgLXIiwYHm3OQFc=';
|
|
460
|
-
const getGroupIdFromConversationId = () => Promise.resolve(mockGroupId);
|
|
461
|
-
jest
|
|
462
|
-
.spyOn(transactionContext, 'decryptMessage')
|
|
463
|
-
.mockRejectedValueOnce(new Error(CoreCryptoMLSError_1.CORE_CRYPTO_ERROR_NAMES.MlsErrorWrongEpoch));
|
|
464
|
-
const mockedMLSMessageAddEvent = {
|
|
465
|
-
type: event_1.CONVERSATION_EVENT.MLS_MESSAGE_ADD,
|
|
466
|
-
senderClientId: '',
|
|
467
|
-
conversation: '',
|
|
468
|
-
data: mockedMLSWelcomeEventData,
|
|
469
|
-
from: '',
|
|
470
|
-
time: '',
|
|
471
|
-
};
|
|
472
|
-
await expect(mlsService.handleMLSMessageAddEvent(mockedMLSMessageAddEvent, getGroupIdFromConversationId)).rejects.toThrow(CoreCryptoMLSError_1.CORE_CRYPTO_ERROR_NAMES.MlsErrorWrongEpoch);
|
|
473
|
-
expect(transactionContext.decryptMessage).toHaveBeenCalled();
|
|
474
|
+
expect(mockCoreCrypto.transaction).toHaveBeenCalled();
|
|
475
|
+
expect(mockCoreCrypto.commitPendingProposals).toHaveBeenCalled();
|
|
474
476
|
});
|
|
475
477
|
});
|
|
476
478
|
describe('handleMLSWelcomeMessageEvent', () => {
|
|
477
479
|
it("before processing welcome it verifies that there's enough key packages locally", async () => {
|
|
478
|
-
const [mlsService, { apiClient,
|
|
480
|
+
const [mlsService, { apiClient, coreCrypto }] = await createMLSService();
|
|
479
481
|
const mockClientId = 'client-1';
|
|
480
482
|
const mockClient = { mls_public_keys: { ed25519: 'key' }, id: mockClientId };
|
|
481
483
|
apiClient.context = { clientType: client_1.ClientType.PERMANENT, clientId: mockClientId, userId: '' };
|
|
482
484
|
const mockedClientKeyPackages = [new Uint8Array()];
|
|
483
|
-
jest.spyOn(
|
|
485
|
+
jest.spyOn(coreCrypto, 'clientKeypackages').mockResolvedValueOnce(mockedClientKeyPackages);
|
|
484
486
|
const numberOfKeysBelowThreshold = mlsService['minRequiredKeyPackages'] - 1;
|
|
485
487
|
jest.spyOn(apiClient.api.client, 'getMLSKeyPackageCount').mockResolvedValueOnce(numberOfKeysBelowThreshold);
|
|
486
|
-
jest.spyOn(
|
|
488
|
+
jest.spyOn(coreCrypto, 'clientValidKeypackagesCount').mockResolvedValueOnce(numberOfKeysBelowThreshold);
|
|
487
489
|
jest.spyOn(apiClient.api.client, 'uploadMLSKeyPackages').mockResolvedValueOnce(undefined);
|
|
488
|
-
jest
|
|
489
|
-
|
|
490
|
-
crlNewDistributionPoints: []
|
|
491
|
-
});
|
|
490
|
+
jest
|
|
491
|
+
.spyOn(coreCrypto, 'processWelcomeMessage')
|
|
492
|
+
.mockResolvedValueOnce({ id: new Uint8Array(), crlNewDistributionPoints: [] });
|
|
492
493
|
jest.spyOn(mlsService, 'scheduleKeyMaterialRenewal').mockImplementation(jest.fn());
|
|
493
494
|
const mockedMLSWelcomeEvent = {
|
|
494
495
|
type: event_1.CONVERSATION_EVENT.MLS_WELCOME_MESSAGE,
|
|
495
496
|
conversation: '',
|
|
496
|
-
data:
|
|
497
|
+
data: '',
|
|
497
498
|
from: '',
|
|
498
499
|
time: '',
|
|
499
500
|
};
|
|
500
501
|
await mlsService.handleMLSWelcomeMessageEvent(mockedMLSWelcomeEvent, mockClient.id);
|
|
501
|
-
expect(
|
|
502
|
+
expect(coreCrypto.processWelcomeMessage).toHaveBeenCalled();
|
|
502
503
|
expect(apiClient.api.client.uploadMLSKeyPackages).toHaveBeenCalledWith(mockClientId, expect.anything());
|
|
503
504
|
});
|
|
504
505
|
it('before processing welcome it does not generate new keys if there is enough key packages locally', async () => {
|
|
505
|
-
const [mlsService, { apiClient,
|
|
506
|
+
const [mlsService, { apiClient, coreCrypto }] = await createMLSService();
|
|
506
507
|
const mockClientId = 'client-1';
|
|
507
508
|
const mockClient = { mls_public_keys: { ed25519: 'key' }, id: mockClientId };
|
|
508
509
|
apiClient.context = { clientType: client_1.ClientType.PERMANENT, clientId: mockClientId, userId: '' };
|
|
509
510
|
const mockedClientKeyPackages = [new Uint8Array()];
|
|
510
|
-
jest.spyOn(
|
|
511
|
+
jest.spyOn(coreCrypto, 'clientKeypackages').mockResolvedValueOnce(mockedClientKeyPackages);
|
|
511
512
|
const numberOfKeysAboveThreshold = mlsService['minRequiredKeyPackages'] + 1;
|
|
512
|
-
jest.spyOn(
|
|
513
|
+
jest.spyOn(coreCrypto, 'clientValidKeypackagesCount').mockResolvedValueOnce(numberOfKeysAboveThreshold);
|
|
513
514
|
jest.spyOn(apiClient.api.client, 'getMLSKeyPackageCount').mockResolvedValueOnce(numberOfKeysAboveThreshold);
|
|
514
515
|
jest.spyOn(apiClient.api.client, 'uploadMLSKeyPackages').mockResolvedValueOnce(undefined);
|
|
515
|
-
jest
|
|
516
|
-
|
|
517
|
-
crlNewDistributionPoints: []
|
|
518
|
-
});
|
|
516
|
+
jest
|
|
517
|
+
.spyOn(coreCrypto, 'processWelcomeMessage')
|
|
518
|
+
.mockResolvedValueOnce({ id: new Uint8Array(), crlNewDistributionPoints: [] });
|
|
519
519
|
jest.spyOn(mlsService, 'scheduleKeyMaterialRenewal').mockImplementation(jest.fn());
|
|
520
520
|
const mockedMLSWelcomeEvent = {
|
|
521
521
|
type: event_1.CONVERSATION_EVENT.MLS_WELCOME_MESSAGE,
|
|
522
522
|
conversation: '',
|
|
523
|
-
data:
|
|
523
|
+
data: '',
|
|
524
524
|
from: '',
|
|
525
525
|
time: '',
|
|
526
526
|
};
|
|
527
527
|
await mlsService.handleMLSWelcomeMessageEvent(mockedMLSWelcomeEvent, mockClient.id);
|
|
528
|
-
expect(
|
|
528
|
+
expect(coreCrypto.processWelcomeMessage).toHaveBeenCalled();
|
|
529
529
|
expect(apiClient.api.client.uploadMLSKeyPackages).not.toHaveBeenCalled();
|
|
530
530
|
});
|
|
531
531
|
it('before processing welcome it does not generate new keys if there is enough key packages uploaded to backend', async () => {
|
|
532
|
-
const [mlsService, { apiClient,
|
|
532
|
+
const [mlsService, { apiClient, coreCrypto }] = await createMLSService();
|
|
533
533
|
const mockClientId = 'client-1';
|
|
534
534
|
const mockClient = { mls_public_keys: { ed25519: 'key' }, id: mockClientId };
|
|
535
535
|
apiClient.context = { clientType: client_1.ClientType.PERMANENT, clientId: mockClientId, userId: '' };
|
|
536
536
|
const mockedClientKeyPackages = [new Uint8Array()];
|
|
537
|
-
jest.spyOn(
|
|
537
|
+
jest.spyOn(coreCrypto, 'clientKeypackages').mockResolvedValueOnce(mockedClientKeyPackages);
|
|
538
538
|
const numberOfKeysBelowThreshold = mlsService['minRequiredKeyPackages'] - 1;
|
|
539
539
|
const numberOfKeysAboveThreshold = mlsService['minRequiredKeyPackages'] + 1;
|
|
540
|
-
jest.spyOn(
|
|
540
|
+
jest.spyOn(coreCrypto, 'clientValidKeypackagesCount').mockResolvedValueOnce(numberOfKeysBelowThreshold);
|
|
541
541
|
jest.spyOn(apiClient.api.client, 'getMLSKeyPackageCount').mockResolvedValueOnce(numberOfKeysAboveThreshold);
|
|
542
542
|
jest.spyOn(apiClient.api.client, 'uploadMLSKeyPackages').mockResolvedValueOnce(undefined);
|
|
543
|
-
jest
|
|
544
|
-
|
|
545
|
-
crlNewDistributionPoints: []
|
|
546
|
-
});
|
|
543
|
+
jest
|
|
544
|
+
.spyOn(coreCrypto, 'processWelcomeMessage')
|
|
545
|
+
.mockResolvedValueOnce({ id: new Uint8Array(), crlNewDistributionPoints: [] });
|
|
547
546
|
jest.spyOn(mlsService, 'scheduleKeyMaterialRenewal').mockImplementation(jest.fn());
|
|
548
547
|
const mockedMLSWelcomeEvent = {
|
|
549
548
|
type: event_1.CONVERSATION_EVENT.MLS_WELCOME_MESSAGE,
|
|
550
549
|
conversation: '',
|
|
551
|
-
data:
|
|
550
|
+
data: '',
|
|
552
551
|
from: '',
|
|
553
552
|
time: '',
|
|
554
553
|
};
|
|
555
554
|
await mlsService.handleMLSWelcomeMessageEvent(mockedMLSWelcomeEvent, mockClient.id);
|
|
556
|
-
expect(
|
|
555
|
+
expect(coreCrypto.processWelcomeMessage).toHaveBeenCalled();
|
|
557
556
|
expect(apiClient.api.client.uploadMLSKeyPackages).not.toHaveBeenCalled();
|
|
558
557
|
});
|
|
559
558
|
});
|
|
560
559
|
describe('tryEstablishingMLSGroup', () => {
|
|
561
560
|
it('returns false if group did already exist locally', async () => {
|
|
562
|
-
const [mlsService
|
|
563
|
-
|
|
561
|
+
const [mlsService] = await createMLSService();
|
|
562
|
+
const mockGroupId = 'mock-group-id';
|
|
563
|
+
jest.spyOn(mlsService, 'conversationExists').mockResolvedValueOnce(true);
|
|
564
564
|
jest.spyOn(mlsService, 'registerConversation').mockImplementation(jest.fn());
|
|
565
565
|
const wasConversationEstablished = await mlsService.tryEstablishingMLSGroup(mockGroupId);
|
|
566
566
|
expect(mlsService.registerConversation).not.toHaveBeenCalled();
|
|
567
567
|
expect(wasConversationEstablished).toBe(false);
|
|
568
568
|
});
|
|
569
569
|
it('returns false if corecrypto has thrown an error when trying to register group locally', async () => {
|
|
570
|
-
const [mlsService
|
|
571
|
-
|
|
570
|
+
const [mlsService] = await createMLSService();
|
|
571
|
+
const mockGroupId = 'mock-group-id';
|
|
572
|
+
jest.spyOn(mlsService, 'conversationExists').mockResolvedValueOnce(false);
|
|
572
573
|
const conversationAlreadyExistsError = new Error();
|
|
573
574
|
conversationAlreadyExistsError.name = CoreCryptoMLSError_1.CORE_CRYPTO_ERROR_NAMES.MlsErrorConversationAlreadyExists;
|
|
574
575
|
jest.spyOn(mlsService, 'registerConversation').mockRejectedValueOnce(conversationAlreadyExistsError);
|
|
@@ -577,8 +578,9 @@ describe('MLSService', () => {
|
|
|
577
578
|
expect(wasConversationEstablished).toBe(false);
|
|
578
579
|
});
|
|
579
580
|
it('returns false and wipes group locally if any backend error was thrown', async () => {
|
|
580
|
-
const [mlsService
|
|
581
|
-
|
|
581
|
+
const [mlsService] = await createMLSService();
|
|
582
|
+
const mockGroupId = 'mock-group-id2';
|
|
583
|
+
jest.spyOn(mlsService, 'conversationExists').mockResolvedValueOnce(false);
|
|
582
584
|
jest
|
|
583
585
|
.spyOn(mlsService, 'registerConversation')
|
|
584
586
|
.mockRejectedValueOnce(new http_1.BackendError('', http_1.BackendErrorLabel.MLS_STALE_MESSAGE, http_1.StatusCode.CONFLICT));
|
|
@@ -589,9 +591,10 @@ describe('MLSService', () => {
|
|
|
589
591
|
expect(wasConversationEstablished).toBe(false);
|
|
590
592
|
});
|
|
591
593
|
it('returns true after MLS group was etablished successfully', async () => {
|
|
592
|
-
const [mlsService
|
|
593
|
-
|
|
594
|
-
jest.spyOn(mlsService, '
|
|
594
|
+
const [mlsService] = await createMLSService();
|
|
595
|
+
const mockGroupId = 'mock-group-id2';
|
|
596
|
+
jest.spyOn(mlsService, 'conversationExists').mockResolvedValueOnce(false);
|
|
597
|
+
jest.spyOn(mlsService, 'registerConversation').mockResolvedValueOnce({ events: [], time: '', failures: [] });
|
|
595
598
|
jest.spyOn(mlsService, 'wipeConversation').mockImplementation(jest.fn());
|
|
596
599
|
const wasConversationEstablished = await mlsService.tryEstablishingMLSGroup(mockGroupId);
|
|
597
600
|
expect(mlsService.registerConversation).toHaveBeenCalledWith(mockGroupId, []);
|
|
@@ -19,7 +19,7 @@
|
|
|
19
19
|
*/
|
|
20
20
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
21
21
|
exports.toProtobufCommitBundle = toProtobufCommitBundle;
|
|
22
|
-
const mls_1 = require("@
|
|
22
|
+
const mls_1 = require("@pydio/protocol-messaging/web/mls");
|
|
23
23
|
const core_crypto_1 = require("@wireapp/core-crypto");
|
|
24
24
|
const ratchetTreeMapping = {
|
|
25
25
|
[core_crypto_1.RatchetTreeType.Full]: mls_1.mls.RatchetTreeType.FULL,
|
|
@@ -40,10 +40,10 @@ function toProtobufCommitBundle({ commit, welcome, groupInfo }) {
|
|
|
40
40
|
return mls_1.mls.CommitBundle.encode({
|
|
41
41
|
groupInfoBundle: {
|
|
42
42
|
ratchetTreeType: ratchetTreeMapping[ratchetTreeType],
|
|
43
|
-
groupInfo: groupInfo.payload
|
|
43
|
+
groupInfo: groupInfo.payload,
|
|
44
44
|
groupInfoType: groupInfoType[encryptionType],
|
|
45
45
|
},
|
|
46
46
|
commit,
|
|
47
|
-
welcome
|
|
47
|
+
welcome,
|
|
48
48
|
}).finish();
|
|
49
49
|
}
|