@wireapp/core 42.9.0 → 42.9.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (22) hide show
  1. package/lib/Account.js +1 -1
  2. package/lib/messagingProtocols/mls/MLSService/MLSService.d.ts +3 -1
  3. package/lib/messagingProtocols/mls/MLSService/MLSService.d.ts.map +1 -1
  4. package/lib/messagingProtocols/mls/MLSService/MLSService.js +5 -8
  5. package/lib/messagingProtocols/mls/MLSService/MLSService.test.js +103 -30
  6. package/lib/storage/CoreDB.d.ts +7 -0
  7. package/lib/storage/CoreDB.d.ts.map +1 -1
  8. package/lib/storage/CoreDB.js +4 -1
  9. package/lib/util/LowPrecisionTaskScheduler/LowPrecisionTaskScheduler.js +2 -2
  10. package/lib/util/RecurringTaskScheduler/RecurringTaskScheduler.d.ts.map +1 -1
  11. package/lib/util/RecurringTaskScheduler/RecurringTaskScheduler.js +6 -5
  12. package/lib/util/RecurringTaskScheduler/RecurringTaskScheduler.test.js +14 -0
  13. package/package.json +2 -2
  14. package/lib/messagingProtocols/mls/MLSService/stores/pendingProposalsStore/index.d.ts +0 -2
  15. package/lib/messagingProtocols/mls/MLSService/stores/pendingProposalsStore/index.d.ts.map +0 -1
  16. package/lib/messagingProtocols/mls/MLSService/stores/pendingProposalsStore/index.js +0 -35
  17. package/lib/messagingProtocols/mls/MLSService/stores/pendingProposalsStore/pendingProposalsStore.d.ts +0 -10
  18. package/lib/messagingProtocols/mls/MLSService/stores/pendingProposalsStore/pendingProposalsStore.d.ts.map +0 -1
  19. package/lib/messagingProtocols/mls/MLSService/stores/pendingProposalsStore/pendingProposalsStore.js +0 -50
  20. package/lib/messagingProtocols/mls/MLSService/stores/pendingProposalsStore/pendingProposalsStore.test.d.ts +0 -2
  21. package/lib/messagingProtocols/mls/MLSService/stores/pendingProposalsStore/pendingProposalsStore.test.d.ts.map +0 -1
  22. package/lib/messagingProtocols/mls/MLSService/stores/pendingProposalsStore/pendingProposalsStore.test.js +0 -42
package/lib/Account.js CHANGED
@@ -260,7 +260,7 @@ class Account extends commons_1.TypedEventEmitter {
260
260
  const cryptoClientDef = await this.buildCryptoClient(context, this.storeEngine, enableMLS);
261
261
  const [clientType, cryptoClient] = cryptoClientDef;
262
262
  const mlsService = clientType === CryptoClient_1.CryptoClientType.CORE_CRYPTO && enableMLS
263
- ? new mls_1.MLSService(this.apiClient, cryptoClient.getNativeClient(), Object.assign({}, (_b = this.cryptoProtocolConfig) === null || _b === void 0 ? void 0 : _b.mls))
263
+ ? new mls_1.MLSService(this.apiClient, cryptoClient.getNativeClient(), this.db, Object.assign({}, (_b = this.cryptoProtocolConfig) === null || _b === void 0 ? void 0 : _b.mls))
264
264
  : undefined;
265
265
  const proteusService = new proteus_1.ProteusService(this.apiClient, cryptoClient, {
266
266
  onNewClient: payload => this.emit(EVENTS.NEW_SESSION, payload),
@@ -9,6 +9,7 @@ import { TypedEventEmitter } from '@wireapp/commons';
9
9
  import { AddProposalArgs, ConversationId, CoreCrypto, DecryptedMessage, ExternalAddProposalArgs, ExternalProposalType, Invitee, ProposalArgs, ProposalType, RemoveProposalArgs } from '@wireapp/core-crypto';
10
10
  import { MLSServiceConfig } from './MLSService.types';
11
11
  import { KeyPackageClaimUser } from '../../../conversation';
12
+ import { CoreDatabase } from '../../../storage/CoreDB';
12
13
  import { CommitPendingProposalsParams, HandlePendingProposalsParams, MLSCallbacks } from '../types';
13
14
  export declare const optionalToUint8Array: (array: Uint8Array | []) => Uint8Array;
14
15
  interface LocalMLSServiceConfig extends MLSServiceConfig {
@@ -31,12 +32,13 @@ type Events = {
31
32
  export declare class MLSService extends TypedEventEmitter<Events> {
32
33
  private readonly apiClient;
33
34
  private readonly coreCryptoClient;
35
+ private readonly coreDatabase;
34
36
  logger: logdown.Logger;
35
37
  config: LocalMLSServiceConfig;
36
38
  groupIdFromConversationId?: MLSCallbacks['groupIdFromConversationId'];
37
39
  private readonly textEncoder;
38
40
  private readonly textDecoder;
39
- constructor(apiClient: APIClient, coreCryptoClient: CoreCrypto, { keyingMaterialUpdateThreshold, nbKeyPackages, defaultCiphersuite, defaultCredentialType, }: Partial<MLSServiceConfig>);
41
+ constructor(apiClient: APIClient, coreCryptoClient: CoreCrypto, coreDatabase: CoreDatabase, { keyingMaterialUpdateThreshold, nbKeyPackages, defaultCiphersuite, defaultCredentialType, }: Partial<MLSServiceConfig>);
40
42
  initClient(userId: QualifiedId, client: RegisteredClient): Promise<void>;
41
43
  private readonly uploadCommitBundle;
42
44
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"MLSService.d.ts","sourceRoot":"","sources":["../../../../src/messagingProtocols/mls/MLSService/MLSService.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"MLSService.d.ts","sourceRoot":"","sources":["../../../../src/messagingProtocols/mls/MLSService/MLSService.ts"],"names":[],"mappings":"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"}
@@ -41,7 +41,6 @@ const logdown_1 = __importDefault(require("logdown"));
41
41
  const commons_1 = require("@wireapp/commons");
42
42
  const core_crypto_1 = require("@wireapp/core-crypto");
43
43
  const CoreCryptoMLSError_1 = require("./CoreCryptoMLSError");
44
- const pendingProposalsStore_1 = require("./stores/pendingProposalsStore");
45
44
  const subconversationGroupIdStore_1 = require("./stores/subconversationGroupIdStore/subconversationGroupIdStore");
46
45
  const messageSender_1 = require("../../../conversation/message/messageSender");
47
46
  const fullyQualifiedClientIdUtils_1 = require("../../../util/fullyQualifiedClientIdUtils");
@@ -62,10 +61,11 @@ const defaultConfig = {
62
61
  defaultCredentialType: core_crypto_1.CredentialType.Basic,
63
62
  };
64
63
  class MLSService extends commons_1.TypedEventEmitter {
65
- constructor(apiClient, coreCryptoClient, { keyingMaterialUpdateThreshold = defaultConfig.keyingMaterialUpdateThreshold, nbKeyPackages = defaultConfig.nbKeyPackages, defaultCiphersuite = defaultConfig.defaultCiphersuite, defaultCredentialType = defaultConfig.defaultCredentialType, }) {
64
+ constructor(apiClient, coreCryptoClient, coreDatabase, { keyingMaterialUpdateThreshold = defaultConfig.keyingMaterialUpdateThreshold, nbKeyPackages = defaultConfig.nbKeyPackages, defaultCiphersuite = defaultConfig.defaultCiphersuite, defaultCredentialType = defaultConfig.defaultCredentialType, }) {
66
65
  super();
67
66
  this.apiClient = apiClient;
68
67
  this.coreCryptoClient = coreCryptoClient;
68
+ this.coreDatabase = coreDatabase;
69
69
  this.logger = (0, logdown_1.default)('@wireapp/core/MLSService');
70
70
  this.textEncoder = new TextEncoder();
71
71
  this.textDecoder = new TextDecoder();
@@ -556,10 +556,7 @@ class MLSService extends commons_1.TypedEventEmitter {
556
556
  if (delayInMs > 0) {
557
557
  const eventDate = new Date(eventTime);
558
558
  const firingDate = eventDate.setTime(eventDate.getTime() + delayInMs);
559
- pendingProposalsStore_1.pendingProposalsStore.storeItem({
560
- groupId,
561
- firingDate,
562
- });
559
+ await this.coreDatabase.put('pendingProposals', { groupId, firingDate }, groupId);
563
560
  TaskScheduler_1.TaskScheduler.addTask({
564
561
  task: () => this.commitPendingProposals({ groupId }),
565
562
  firingDate,
@@ -581,7 +578,7 @@ class MLSService extends commons_1.TypedEventEmitter {
581
578
  await this.commitProposals(bazinga64_1.Decoder.fromBase64(groupId).asBytes);
582
579
  if (!skipDelete) {
583
580
  TaskScheduler_1.TaskScheduler.cancelTask(groupId);
584
- pendingProposalsStore_1.pendingProposalsStore.deleteItem({ groupId });
581
+ await this.coreDatabase.delete('pendingProposals', groupId);
585
582
  }
586
583
  }
587
584
  catch (error) {
@@ -595,7 +592,7 @@ class MLSService extends commons_1.TypedEventEmitter {
595
592
  */
596
593
  async checkExistingPendingProposals() {
597
594
  try {
598
- const pendingProposals = pendingProposalsStore_1.pendingProposalsStore.getAllItems();
595
+ const pendingProposals = await this.coreDatabase.getAll('pendingProposals');
599
596
  if (pendingProposals.length > 0) {
600
597
  pendingProposals.forEach(({ groupId, firingDate }) => TaskScheduler_1.TaskScheduler.addTask({
601
598
  task: () => this.commitPendingProposals({ groupId }),
@@ -23,11 +23,12 @@ const event_1 = require("@wireapp/api-client/lib/event");
23
23
  const crypto_1 = require("crypto");
24
24
  const api_client_1 = require("@wireapp/api-client");
25
25
  const MLSService_1 = require("./MLSService");
26
+ const CoreDB_1 = require("../../../storage/CoreDB");
26
27
  jest.createMockFromModule('@wireapp/api-client');
27
28
  function createUserId() {
28
29
  return { id: (0, crypto_1.randomUUID)(), domain: '' };
29
30
  }
30
- describe('MLSService', () => {
31
+ const createMLSService = async () => {
31
32
  const apiClient = new api_client_1.APIClient();
32
33
  const mockCoreCrypto = {
33
34
  createConversation: jest.fn(),
@@ -38,11 +39,24 @@ describe('MLSService', () => {
38
39
  mlsInit: jest.fn(),
39
40
  clientPublicKey: jest.fn(),
40
41
  processWelcomeMessage: jest.fn(),
42
+ decryptMessage: jest.fn(),
43
+ conversationEpoch: jest.fn(),
44
+ commitPendingProposals: jest.fn(),
41
45
  };
46
+ const mockedDb = await (0, CoreDB_1.openDB)('core-test-db');
47
+ const mlsService = new MLSService_1.MLSService(apiClient, mockCoreCrypto, mockedDb, {});
48
+ return [mlsService, { apiClient, coreCrypto: mockCoreCrypto }];
49
+ };
50
+ describe('MLSService', () => {
42
51
  describe('registerConversation', () => {
43
52
  let mlsService;
44
- beforeEach(() => {
45
- mlsService = new MLSService_1.MLSService(apiClient, mockCoreCrypto, {});
53
+ let apiClient;
54
+ let coreCrypto;
55
+ beforeEach(async () => {
56
+ const [mockedMLSService, { apiClient: mockApiClient, coreCrypto: mockCoreCrypto }] = await createMLSService();
57
+ mlsService = mockedMLSService;
58
+ apiClient = mockApiClient;
59
+ coreCrypto = mockCoreCrypto;
46
60
  jest
47
61
  .spyOn(apiClient.api.client, 'getPublicKeys')
48
62
  .mockResolvedValue({ removal: { algo: 'mXOagqRIX/RFd7QyXJA8/Ed8X+hvQgLXIiwYHm3OQFc=' } });
@@ -73,21 +87,21 @@ describe('MLSService', () => {
73
87
  });
74
88
  it('cancels key material timers after group is wiped', async () => {
75
89
  const groupId = 'mXOagqRIX/RFd7QyXJA8/Ed8X+hvQgLXIiwYHm4OQFc=';
76
- jest.spyOn(mockCoreCrypto, 'conversationExists').mockResolvedValueOnce(true);
90
+ jest.spyOn(coreCrypto, 'conversationExists').mockResolvedValueOnce(true);
77
91
  await mlsService.wipeConversation(groupId);
78
92
  expect(mlsService.cancelKeyMaterialRenewal).toHaveBeenCalledWith(groupId);
79
93
  });
80
94
  });
81
95
  describe('isConversationEstablished', () => {
82
96
  it('returns false if conversation does not exist locally', async () => {
83
- const mlsService = new MLSService_1.MLSService(apiClient, mockCoreCrypto, {});
97
+ const [mlsService] = await createMLSService();
84
98
  const groupId = 'mXOagqRIX/RFd7QyXJA8/Ed8X+hvQgLXIiwYHm3OQFc=';
85
99
  jest.spyOn(mlsService, 'conversationExists').mockResolvedValueOnce(false);
86
100
  const isEstablshed = await mlsService.isConversationEstablished(groupId);
87
101
  expect(isEstablshed).toBe(false);
88
102
  });
89
103
  it('returns false if epoch number is 0', async () => {
90
- const mlsService = new MLSService_1.MLSService(apiClient, mockCoreCrypto, {});
104
+ const [mlsService] = await createMLSService();
91
105
  const groupId = 'mXOagqRIX/RFd7QyXJA8/Ed8X+hvQgLXIiwYHm3OQFc=';
92
106
  jest.spyOn(mlsService, 'conversationExists').mockResolvedValueOnce(true);
93
107
  jest.spyOn(mlsService, 'getEpoch').mockResolvedValueOnce(0);
@@ -95,7 +109,7 @@ describe('MLSService', () => {
95
109
  expect(isEstablshed).toBe(false);
96
110
  });
97
111
  it.each([1, 2, 100])('returns false if epoch number is 1 or more', async (epoch) => {
98
- const mlsService = new MLSService_1.MLSService(apiClient, mockCoreCrypto, {});
112
+ const [mlsService] = await createMLSService();
99
113
  const groupId = 'mXOagqRIX/RFd7QyXJA8/Ed8X+hvQgLXIiwYHm3OQFc=';
100
114
  jest.spyOn(mlsService, 'conversationExists').mockResolvedValueOnce(true);
101
115
  jest.spyOn(mlsService, 'getEpoch').mockResolvedValueOnce(epoch);
@@ -105,62 +119,121 @@ describe('MLSService', () => {
105
119
  });
106
120
  describe('initClient', () => {
107
121
  it('uploads public key only if it was not yet defined on client entity', async () => {
108
- const mlsService = new MLSService_1.MLSService(apiClient, mockCoreCrypto, {});
122
+ const [mlsService, { apiClient, coreCrypto }] = await createMLSService();
109
123
  const mockUserId = { id: 'user-1', domain: 'local.zinfra.io' };
110
124
  const mockClientId = 'client-1';
111
125
  const mockClient = { mls_public_keys: {}, id: mockClientId };
112
126
  apiClient.context = { clientType: client_1.ClientType.PERMANENT, clientId: mockClientId, userId: '' };
113
127
  const mockedClientPublicKey = new Uint8Array();
114
- jest.spyOn(mockCoreCrypto, 'clientPublicKey').mockResolvedValueOnce(mockedClientPublicKey);
128
+ jest.spyOn(coreCrypto, 'clientPublicKey').mockResolvedValueOnce(mockedClientPublicKey);
115
129
  jest.spyOn(apiClient.api.client, 'putClient').mockResolvedValueOnce(undefined);
116
130
  jest.spyOn(apiClient.api.client, 'getMLSKeyPackageCount').mockResolvedValueOnce(mlsService.config.nbKeyPackages);
117
131
  await mlsService.initClient(mockUserId, mockClient);
118
- expect(mockCoreCrypto.mlsInit).toHaveBeenCalled();
132
+ expect(coreCrypto.mlsInit).toHaveBeenCalled();
119
133
  expect(apiClient.api.client.putClient).toHaveBeenCalledWith(mockClientId, expect.anything());
120
134
  });
121
135
  it('uploads key packages if there are not enough keys on backend', async () => {
122
- const mlsService = new MLSService_1.MLSService(apiClient, mockCoreCrypto, {});
136
+ const [mlsService, { apiClient, coreCrypto }] = await createMLSService();
123
137
  const mockUserId = { id: 'user-1', domain: 'local.zinfra.io' };
124
138
  const mockClientId = 'client-1';
125
139
  const mockClient = { mls_public_keys: { ed25519: 'key' }, id: mockClientId };
126
140
  apiClient.context = { clientType: client_1.ClientType.PERMANENT, clientId: mockClientId, userId: '' };
127
141
  const mockedClientKeyPackages = [new Uint8Array()];
128
- jest.spyOn(mockCoreCrypto, 'clientKeypackages').mockResolvedValueOnce(mockedClientKeyPackages);
142
+ jest.spyOn(coreCrypto, 'clientKeypackages').mockResolvedValueOnce(mockedClientKeyPackages);
129
143
  jest
130
144
  .spyOn(apiClient.api.client, 'getMLSKeyPackageCount')
131
145
  .mockResolvedValueOnce(mlsService.config.minRequiredNumberOfAvailableKeyPackages - 1);
132
146
  jest.spyOn(apiClient.api.client, 'uploadMLSKeyPackages').mockResolvedValueOnce(undefined);
133
147
  await mlsService.initClient(mockUserId, mockClient);
134
- expect(mockCoreCrypto.mlsInit).toHaveBeenCalled();
148
+ expect(coreCrypto.mlsInit).toHaveBeenCalled();
135
149
  expect(apiClient.api.client.uploadMLSKeyPackages).toHaveBeenCalledWith(mockClientId, expect.anything());
136
150
  });
137
151
  it('does not upload public key or key packages if both are already uploaded', async () => {
138
- const mlsService = new MLSService_1.MLSService(apiClient, mockCoreCrypto, {});
152
+ const [mlsService, { apiClient, coreCrypto }] = await createMLSService();
139
153
  const mockUserId = { id: 'user-1', domain: 'local.zinfra.io' };
140
154
  const mockClientId = 'client-1';
141
155
  const mockClient = { mls_public_keys: { ed25519: 'key' }, id: mockClientId };
142
156
  apiClient.context = { clientType: client_1.ClientType.PERMANENT, clientId: mockClientId, userId: '' };
143
157
  jest.spyOn(apiClient.api.client, 'getClient').mockResolvedValueOnce(mockClient);
144
158
  jest.spyOn(apiClient.api.client, 'getMLSKeyPackageCount').mockResolvedValueOnce(mlsService.config.nbKeyPackages);
159
+ jest.spyOn(apiClient.api.client, 'uploadMLSKeyPackages');
160
+ jest.spyOn(apiClient.api.client, 'putClient');
145
161
  await mlsService.initClient(mockUserId, mockClient);
146
- expect(mockCoreCrypto.mlsInit).toHaveBeenCalled();
162
+ expect(coreCrypto.mlsInit).toHaveBeenCalled();
147
163
  expect(apiClient.api.client.uploadMLSKeyPackages).not.toHaveBeenCalled();
148
164
  expect(apiClient.api.client.putClient).not.toHaveBeenCalled();
149
165
  });
150
166
  });
167
+ describe('handleMLSMessageAddEvent', () => {
168
+ it('decrypts a message and emits new epoch event if epoch has changed', async () => {
169
+ const [mlsService, { coreCrypto: mockCoreCrypto }] = await createMLSService();
170
+ const mockGroupId = 'mXOagqRIX/RFd7QyXJA8/Ed8X+hvQgLXIiwYHm3OQFc=';
171
+ const mockedNewEpoch = 3;
172
+ jest.spyOn(mlsService, 'getGroupIdFromConversationId').mockResolvedValueOnce(mockGroupId);
173
+ const mockedDecryptoedMessage = {
174
+ hasEpochChanged: true,
175
+ isActive: false,
176
+ proposals: [],
177
+ };
178
+ jest.spyOn(mockCoreCrypto, 'decryptMessage').mockResolvedValueOnce(mockedDecryptoedMessage);
179
+ jest.spyOn(mockCoreCrypto, 'conversationEpoch').mockResolvedValueOnce(mockedNewEpoch);
180
+ jest.spyOn(mlsService, 'emit').mockImplementation(jest.fn());
181
+ const mockedMLSWelcomeEvent = {
182
+ type: event_1.CONVERSATION_EVENT.MLS_MESSAGE_ADD,
183
+ senderClientId: '',
184
+ conversation: '',
185
+ data: '',
186
+ from: '',
187
+ time: '',
188
+ };
189
+ await mlsService.handleMLSMessageAddEvent(mockedMLSWelcomeEvent);
190
+ expect(mockCoreCrypto.decryptMessage).toHaveBeenCalled();
191
+ expect(mlsService.emit).toHaveBeenCalledWith('newEpoch', { epoch: mockedNewEpoch, groupId: mockGroupId });
192
+ });
193
+ it('handles pending propoals with a delay after decrypting a message', async () => {
194
+ const [mlsService, { coreCrypto: mockCoreCrypto }] = await createMLSService();
195
+ jest.useFakeTimers();
196
+ const mockGroupId = 'mXOagqRIX/RFd7QyXJA8/Ed8X+hvQgLXIiwYHm3OQFc=';
197
+ const mockedNewEpoch = 3;
198
+ const commitDelay = 1000;
199
+ jest.spyOn(mlsService, 'getGroupIdFromConversationId').mockResolvedValueOnce(mockGroupId);
200
+ const mockedDecryptoedMessage = {
201
+ hasEpochChanged: true,
202
+ isActive: false,
203
+ proposals: [],
204
+ commitDelay,
205
+ };
206
+ jest.spyOn(mockCoreCrypto, 'decryptMessage').mockResolvedValueOnce(mockedDecryptoedMessage);
207
+ jest.spyOn(mockCoreCrypto, 'conversationEpoch').mockResolvedValueOnce(mockedNewEpoch);
208
+ jest.spyOn(mlsService, 'commitPendingProposals');
209
+ const mockedMLSWelcomeEvent = {
210
+ type: event_1.CONVERSATION_EVENT.MLS_MESSAGE_ADD,
211
+ senderClientId: '',
212
+ conversation: '',
213
+ data: '',
214
+ from: '',
215
+ time: new Date().toISOString(),
216
+ };
217
+ await mlsService.handleMLSMessageAddEvent(mockedMLSWelcomeEvent);
218
+ expect(mockCoreCrypto.commitPendingProposals).not.toHaveBeenCalled();
219
+ jest.advanceTimersByTime(commitDelay);
220
+ expect(mockCoreCrypto.decryptMessage).toHaveBeenCalled();
221
+ expect(mockCoreCrypto.commitPendingProposals).toHaveBeenCalled();
222
+ });
223
+ });
151
224
  describe('handleMLSWelcomeMessageEvent', () => {
152
225
  it("before processing welcome it verifies that there's enough key packages locally", async () => {
153
- const mlsService = new MLSService_1.MLSService(apiClient, mockCoreCrypto, {});
226
+ const [mlsService, { apiClient, coreCrypto }] = await createMLSService();
154
227
  const mockClientId = 'client-1';
155
228
  const mockClient = { mls_public_keys: { ed25519: 'key' }, id: mockClientId };
156
229
  apiClient.context = { clientType: client_1.ClientType.PERMANENT, clientId: mockClientId, userId: '' };
157
230
  const mockedClientKeyPackages = [new Uint8Array()];
158
- jest.spyOn(mockCoreCrypto, 'clientKeypackages').mockResolvedValueOnce(mockedClientKeyPackages);
231
+ jest.spyOn(coreCrypto, 'clientKeypackages').mockResolvedValueOnce(mockedClientKeyPackages);
159
232
  const numberOfKeysBelowThreshold = mlsService.config.minRequiredNumberOfAvailableKeyPackages - 1;
160
233
  jest.spyOn(apiClient.api.client, 'getMLSKeyPackageCount').mockResolvedValueOnce(numberOfKeysBelowThreshold);
161
- jest.spyOn(mockCoreCrypto, 'clientValidKeypackagesCount').mockResolvedValueOnce(numberOfKeysBelowThreshold);
234
+ jest.spyOn(coreCrypto, 'clientValidKeypackagesCount').mockResolvedValueOnce(numberOfKeysBelowThreshold);
162
235
  jest.spyOn(apiClient.api.client, 'uploadMLSKeyPackages').mockResolvedValueOnce(undefined);
163
- jest.spyOn(mockCoreCrypto, 'processWelcomeMessage').mockResolvedValueOnce(new Uint8Array());
236
+ jest.spyOn(coreCrypto, 'processWelcomeMessage').mockResolvedValueOnce(new Uint8Array());
164
237
  jest.spyOn(mlsService, 'scheduleKeyMaterialRenewal').mockImplementation(jest.fn());
165
238
  const mockedMLSWelcomeEvent = {
166
239
  type: event_1.CONVERSATION_EVENT.MLS_WELCOME_MESSAGE,
@@ -170,21 +243,21 @@ describe('MLSService', () => {
170
243
  time: '',
171
244
  };
172
245
  await mlsService.handleMLSWelcomeMessageEvent(mockedMLSWelcomeEvent, mockClient.id);
173
- expect(mockCoreCrypto.processWelcomeMessage).toHaveBeenCalled();
246
+ expect(coreCrypto.processWelcomeMessage).toHaveBeenCalled();
174
247
  expect(apiClient.api.client.uploadMLSKeyPackages).toHaveBeenCalledWith(mockClientId, expect.anything());
175
248
  });
176
249
  it('before processing welcome it does not generate new keys if there is enough key packages locally', async () => {
177
- const mlsService = new MLSService_1.MLSService(apiClient, mockCoreCrypto, {});
250
+ const [mlsService, { apiClient, coreCrypto }] = await createMLSService();
178
251
  const mockClientId = 'client-1';
179
252
  const mockClient = { mls_public_keys: { ed25519: 'key' }, id: mockClientId };
180
253
  apiClient.context = { clientType: client_1.ClientType.PERMANENT, clientId: mockClientId, userId: '' };
181
254
  const mockedClientKeyPackages = [new Uint8Array()];
182
- jest.spyOn(mockCoreCrypto, 'clientKeypackages').mockResolvedValueOnce(mockedClientKeyPackages);
255
+ jest.spyOn(coreCrypto, 'clientKeypackages').mockResolvedValueOnce(mockedClientKeyPackages);
183
256
  const numberOfKeysAboveThreshold = mlsService.config.minRequiredNumberOfAvailableKeyPackages + 1;
184
- jest.spyOn(mockCoreCrypto, 'clientValidKeypackagesCount').mockResolvedValueOnce(numberOfKeysAboveThreshold);
257
+ jest.spyOn(coreCrypto, 'clientValidKeypackagesCount').mockResolvedValueOnce(numberOfKeysAboveThreshold);
185
258
  jest.spyOn(apiClient.api.client, 'getMLSKeyPackageCount').mockResolvedValueOnce(numberOfKeysAboveThreshold);
186
259
  jest.spyOn(apiClient.api.client, 'uploadMLSKeyPackages').mockResolvedValueOnce(undefined);
187
- jest.spyOn(mockCoreCrypto, 'processWelcomeMessage').mockResolvedValueOnce(new Uint8Array());
260
+ jest.spyOn(coreCrypto, 'processWelcomeMessage').mockResolvedValueOnce(new Uint8Array());
188
261
  jest.spyOn(mlsService, 'scheduleKeyMaterialRenewal').mockImplementation(jest.fn());
189
262
  const mockedMLSWelcomeEvent = {
190
263
  type: event_1.CONVERSATION_EVENT.MLS_WELCOME_MESSAGE,
@@ -194,22 +267,22 @@ describe('MLSService', () => {
194
267
  time: '',
195
268
  };
196
269
  await mlsService.handleMLSWelcomeMessageEvent(mockedMLSWelcomeEvent, mockClient.id);
197
- expect(mockCoreCrypto.processWelcomeMessage).toHaveBeenCalled();
270
+ expect(coreCrypto.processWelcomeMessage).toHaveBeenCalled();
198
271
  expect(apiClient.api.client.uploadMLSKeyPackages).not.toHaveBeenCalled();
199
272
  });
200
273
  it('before processing welcome it does not generate new keys if there is enough key packages uploaded to backend', async () => {
201
- const mlsService = new MLSService_1.MLSService(apiClient, mockCoreCrypto, {});
274
+ const [mlsService, { apiClient, coreCrypto }] = await createMLSService();
202
275
  const mockClientId = 'client-1';
203
276
  const mockClient = { mls_public_keys: { ed25519: 'key' }, id: mockClientId };
204
277
  apiClient.context = { clientType: client_1.ClientType.PERMANENT, clientId: mockClientId, userId: '' };
205
278
  const mockedClientKeyPackages = [new Uint8Array()];
206
- jest.spyOn(mockCoreCrypto, 'clientKeypackages').mockResolvedValueOnce(mockedClientKeyPackages);
279
+ jest.spyOn(coreCrypto, 'clientKeypackages').mockResolvedValueOnce(mockedClientKeyPackages);
207
280
  const numberOfKeysBelowThreshold = mlsService.config.minRequiredNumberOfAvailableKeyPackages - 1;
208
281
  const numberOfKeysAboveThreshold = mlsService.config.minRequiredNumberOfAvailableKeyPackages + 1;
209
- jest.spyOn(mockCoreCrypto, 'clientValidKeypackagesCount').mockResolvedValueOnce(numberOfKeysBelowThreshold);
282
+ jest.spyOn(coreCrypto, 'clientValidKeypackagesCount').mockResolvedValueOnce(numberOfKeysBelowThreshold);
210
283
  jest.spyOn(apiClient.api.client, 'getMLSKeyPackageCount').mockResolvedValueOnce(numberOfKeysAboveThreshold);
211
284
  jest.spyOn(apiClient.api.client, 'uploadMLSKeyPackages').mockResolvedValueOnce(undefined);
212
- jest.spyOn(mockCoreCrypto, 'processWelcomeMessage').mockResolvedValueOnce(new Uint8Array());
285
+ jest.spyOn(coreCrypto, 'processWelcomeMessage').mockResolvedValueOnce(new Uint8Array());
213
286
  jest.spyOn(mlsService, 'scheduleKeyMaterialRenewal').mockImplementation(jest.fn());
214
287
  const mockedMLSWelcomeEvent = {
215
288
  type: event_1.CONVERSATION_EVENT.MLS_WELCOME_MESSAGE,
@@ -219,7 +292,7 @@ describe('MLSService', () => {
219
292
  time: '',
220
293
  };
221
294
  await mlsService.handleMLSWelcomeMessageEvent(mockedMLSWelcomeEvent, mockClient.id);
222
- expect(mockCoreCrypto.processWelcomeMessage).toHaveBeenCalled();
295
+ expect(coreCrypto.processWelcomeMessage).toHaveBeenCalled();
223
296
  expect(apiClient.api.client.uploadMLSKeyPackages).not.toHaveBeenCalled();
224
297
  });
225
298
  });
@@ -7,6 +7,13 @@ interface CoreDBSchema extends DBSchema {
7
7
  highestId: number;
8
8
  };
9
9
  };
10
+ pendingProposals: {
11
+ key: string;
12
+ value: {
13
+ groupId: string;
14
+ firingDate: number;
15
+ };
16
+ };
10
17
  }
11
18
  export type CoreDatabase = IDBPDatabase<CoreDBSchema>;
12
19
  export declare function openDB(dbName: string): Promise<CoreDatabase>;
@@ -1 +1 @@
1
- {"version":3,"file":"CoreDB.d.ts","sourceRoot":"","sources":["../../src/storage/CoreDB.ts"],"names":[],"mappings":"AAmBA,OAAO,EAAC,QAAQ,EAA2B,YAAY,EAAsB,MAAM,KAAK,CAAC;AAGzF,UAAU,YAAa,SAAQ,QAAQ;IACrC,OAAO,EAAE;QACP,GAAG,EAAE,MAAM,CAAC;QACZ,KAAK,EAAE;YAAC,SAAS,EAAE,MAAM,CAAC;YAAC,SAAS,EAAE,MAAM,CAAA;SAAC,CAAC;KAC/C,CAAC;CACH;AAED,MAAM,MAAM,YAAY,GAAG,YAAY,CAAC,YAAY,CAAC,CAAC;AAEtD,wBAAsB,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,YAAY,CAAC,CAUlE;AAED,wBAAsB,QAAQ,CAAC,EAAE,EAAE,YAAY,GAAG,OAAO,CAAC,IAAI,CAAC,CAE9D"}
1
+ {"version":3,"file":"CoreDB.d.ts","sourceRoot":"","sources":["../../src/storage/CoreDB.ts"],"names":[],"mappings":"AAmBA,OAAO,EAAC,QAAQ,EAA2B,YAAY,EAAsB,MAAM,KAAK,CAAC;AAGzF,UAAU,YAAa,SAAQ,QAAQ;IACrC,OAAO,EAAE;QACP,GAAG,EAAE,MAAM,CAAC;QACZ,KAAK,EAAE;YAAC,SAAS,EAAE,MAAM,CAAC;YAAC,SAAS,EAAE,MAAM,CAAA;SAAC,CAAC;KAC/C,CAAC;IACF,gBAAgB,EAAE;QAChB,GAAG,EAAE,MAAM,CAAC;QACZ,KAAK,EAAE;YAAC,OAAO,EAAE,MAAM,CAAC;YAAC,UAAU,EAAE,MAAM,CAAA;SAAC,CAAC;KAC9C,CAAC;CACH;AAED,MAAM,MAAM,YAAY,GAAG,YAAY,CAAC,YAAY,CAAC,CAAC;AAEtD,wBAAsB,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,YAAY,CAAC,CAalE;AAED,wBAAsB,QAAQ,CAAC,EAAE,EAAE,YAAY,GAAG,OAAO,CAAC,IAAI,CAAC,CAE9D"}
@@ -20,13 +20,16 @@
20
20
  Object.defineProperty(exports, "__esModule", { value: true });
21
21
  exports.deleteDB = exports.openDB = void 0;
22
22
  const idb_1 = require("idb");
23
- const VERSION = 1;
23
+ const VERSION = 2;
24
24
  async function openDB(dbName) {
25
25
  const db = await (0, idb_1.openDB)(dbName, VERSION, {
26
26
  upgrade: (db, oldVersion) => {
27
27
  switch (oldVersion) {
28
28
  case 0:
29
29
  db.createObjectStore('prekeys');
30
+ case 1:
31
+ db.deleteObjectStore('prekeys');
32
+ db.createObjectStore('pendingProposals');
30
33
  }
31
34
  },
32
35
  });
@@ -39,11 +39,11 @@ const addTask = ({ key, firingDate, task, intervalDelay }) => {
39
39
  const tasks = (_a = intervals[intervalDelay]) === null || _a === void 0 ? void 0 : _a.tasks;
40
40
  if ((tasks === null || tasks === void 0 ? void 0 : tasks.length) !== 0) {
41
41
  for (const taskData of tasks) {
42
- if (nowTime >= firingDate) {
42
+ if (nowTime >= taskData.firingDate) {
43
43
  const { task, key } = taskData;
44
44
  logger.info(`Executing task with key "${key}"`);
45
- task();
46
45
  cancelTask({ intervalDelay, key });
46
+ task();
47
47
  }
48
48
  }
49
49
  }
@@ -1 +1 @@
1
- {"version":3,"file":"RecurringTaskScheduler.d.ts","sourceRoot":"","sources":["../../../src/util/RecurringTaskScheduler/RecurringTaskScheduler.ts"],"names":[],"mappings":"AA0BA,UAAU,UAAU;IAClB,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,MAAM,IAAI,CAAC;IACjB,GAAG,EAAE,MAAM,CAAC;CACb;AAED,wBAAgB,qBAAqB,CAAC,EAAC,KAAK,EAAE,IAAI,EAAE,GAAG,EAAC,EAAE,UAAU,QAoBnE;AAED,wBAAgB,mBAAmB,CAAC,OAAO,EAAE,MAAM,QAGlD"}
1
+ {"version":3,"file":"RecurringTaskScheduler.d.ts","sourceRoot":"","sources":["../../../src/util/RecurringTaskScheduler/RecurringTaskScheduler.ts"],"names":[],"mappings":"AA0BA,UAAU,UAAU;IAClB,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,MAAM,IAAI,CAAC;IACjB,GAAG,EAAE,MAAM,CAAC;CACb;AAED,wBAAgB,qBAAqB,CAAC,EAAC,KAAK,EAAE,IAAI,EAAE,GAAG,EAAC,EAAE,UAAU,QAqBnE;AAED,wBAAgB,mBAAmB,CAAC,OAAO,EAAE,MAAM,QAIlD"}
@@ -24,13 +24,13 @@ const RecurringTaskScheduler_store_1 = require("./RecurringTaskScheduler.store")
24
24
  const LowPrecisionTaskScheduler_1 = require("../LowPrecisionTaskScheduler");
25
25
  const TaskScheduler_1 = require("../TaskScheduler");
26
26
  function registerRecurringTask({ every, task, key }) {
27
- var _a;
28
- const lastFireDate = (_a = (0, RecurringTaskScheduler_store_1.loadState)(key)) !== null && _a !== void 0 ? _a : Date.now();
27
+ const firingDate = (0, RecurringTaskScheduler_store_1.loadState)(key) || Date.now() + every;
28
+ (0, RecurringTaskScheduler_store_1.saveState)(key, firingDate);
29
29
  const taskConfig = {
30
- firingDate: lastFireDate + every,
30
+ firingDate,
31
31
  key,
32
- task() {
33
- (0, RecurringTaskScheduler_store_1.saveState)(key, Date.now());
32
+ task: () => {
33
+ (0, RecurringTaskScheduler_store_1.deleteState)(key);
34
34
  task();
35
35
  registerRecurringTask({ every, task, key });
36
36
  },
@@ -46,6 +46,7 @@ function registerRecurringTask({ every, task, key }) {
46
46
  }
47
47
  exports.registerRecurringTask = registerRecurringTask;
48
48
  function cancelRecurringTask(taskKey) {
49
+ (0, RecurringTaskScheduler_store_1.deleteState)(taskKey);
49
50
  TaskScheduler_1.TaskScheduler.cancelTask(taskKey);
50
51
  LowPrecisionTaskScheduler_1.LowPrecisionTaskScheduler.cancelTask({ intervalDelay: commons_1.TimeUtil.TimeInMillis.MINUTE, key: taskKey });
51
52
  }
@@ -36,6 +36,20 @@ describe('RecurringTaskScheduler', () => {
36
36
  jest.advanceTimersByTime(commons_1.TimeUtil.TimeInMillis.MINUTE + 1);
37
37
  expect(task).toHaveBeenCalledTimes(2);
38
38
  });
39
+ it('resumes a task after re-registering a recurring task', () => {
40
+ const task = jest.fn();
41
+ // it should fire in a minute
42
+ (0, RecurringTaskScheduler_1.registerRecurringTask)({ every: commons_1.TimeUtil.TimeInMillis.MINUTE, task, key: 'test-task2' });
43
+ jest.advanceTimersByTime(commons_1.TimeUtil.TimeInMillis.MINUTE / 2);
44
+ // re-register the task
45
+ (0, RecurringTaskScheduler_1.registerRecurringTask)({ every: commons_1.TimeUtil.TimeInMillis.MINUTE, task, key: 'test-task2' });
46
+ // only 30s have passed, so the task should not have fired yet
47
+ expect(task).toHaveBeenCalledTimes(0);
48
+ // advance the timer by another 30s (so we have 1 minute in total)
49
+ jest.advanceTimersByTime(commons_1.TimeUtil.TimeInMillis.MINUTE / 2);
50
+ // the task should have fired once after a minute from the beginning even if we re-registered it
51
+ expect(task).toHaveBeenCalledTimes(1);
52
+ });
39
53
  it('cancel a task before it is run', () => {
40
54
  const task = jest.fn();
41
55
  const testKey = 'test-task-1';
package/package.json CHANGED
@@ -60,6 +60,6 @@
60
60
  "test:coverage": "jest --coverage",
61
61
  "watch": "tsc --watch"
62
62
  },
63
- "version": "42.9.0",
64
- "gitHead": "e3e0f0451f1e34b4ad97ac972429b6176b05a07a"
63
+ "version": "42.9.2",
64
+ "gitHead": "8c7762276ee1d4563f2cfd02d0017fb8ad3f95a3"
65
65
  }
@@ -1,2 +0,0 @@
1
- export * from './pendingProposalsStore';
2
- //# sourceMappingURL=index.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../../../src/messagingProtocols/mls/MLSService/stores/pendingProposalsStore/index.ts"],"names":[],"mappings":"AAmBA,cAAc,yBAAyB,CAAC"}
@@ -1,35 +0,0 @@
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
- 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 __exportStar = (this && this.__exportStar) || function(m, exports) {
32
- for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
33
- };
34
- Object.defineProperty(exports, "__esModule", { value: true });
35
- __exportStar(require("./pendingProposalsStore"), exports);
@@ -1,10 +0,0 @@
1
- import { CommonMLS } from '../../../types';
2
- export type PendingProposalsParams = {
3
- firingDate: number;
4
- } & CommonMLS;
5
- export declare const pendingProposalsStore: {
6
- getAllItems: () => PendingProposalsParams[];
7
- storeItem: ({ groupId, firingDate }: PendingProposalsParams) => void;
8
- deleteItem: ({ groupId }: CommonMLS) => void;
9
- };
10
- //# sourceMappingURL=pendingProposalsStore.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"pendingProposalsStore.d.ts","sourceRoot":"","sources":["../../../../../../src/messagingProtocols/mls/MLSService/stores/pendingProposalsStore/pendingProposalsStore.ts"],"names":[],"mappings":"AAmBA,OAAO,EAAC,SAAS,EAAC,MAAM,gBAAgB,CAAC;AAEzC,MAAM,MAAM,sBAAsB,GAAG;IACnC,UAAU,EAAE,MAAM,CAAC;CACpB,GAAG,SAAS,CAAC;AAmCd,eAAO,MAAM,qBAAqB;uBAnBV,sBAAsB,EAAE;yCAKN,sBAAsB;8BAMjC,SAAS;CAYvC,CAAC"}
@@ -1,50 +0,0 @@
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.pendingProposalsStore = void 0;
22
- const storageKey = 'pendingProposals';
23
- const getAllItemsMap = () => {
24
- const storedState = localStorage.getItem(storageKey);
25
- if (!storedState) {
26
- return {};
27
- }
28
- return JSON.parse(storedState);
29
- };
30
- const getAllItems = () => {
31
- const storedStateMap = getAllItemsMap();
32
- return Object.values(storedStateMap);
33
- };
34
- const storeItem = ({ groupId, firingDate }) => {
35
- const storedState = getAllItemsMap();
36
- const newStoredState = Object.assign(Object.assign({}, storedState), { [groupId]: { groupId, firingDate } });
37
- localStorage.setItem(storageKey, JSON.stringify(newStoredState));
38
- };
39
- const deleteItem = ({ groupId }) => {
40
- const storedState = getAllItemsMap();
41
- if (storedState[groupId]) {
42
- delete storedState[groupId];
43
- }
44
- localStorage.setItem(storageKey, JSON.stringify(storedState));
45
- };
46
- exports.pendingProposalsStore = {
47
- getAllItems,
48
- storeItem,
49
- deleteItem,
50
- };
@@ -1,2 +0,0 @@
1
- export {};
2
- //# sourceMappingURL=pendingProposalsStore.test.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"pendingProposalsStore.test.d.ts","sourceRoot":"","sources":["../../../../../../src/messagingProtocols/mls/MLSService/stores/pendingProposalsStore/pendingProposalsStore.test.ts"],"names":[],"mappings":""}
@@ -1,42 +0,0 @@
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 pendingProposalsStore_1 = require("./pendingProposalsStore");
22
- const mockEntries = [
23
- { groupId: 'group0', firingDate: 1 },
24
- { groupId: 'group1', firingDate: 2 },
25
- ];
26
- describe('pendingProposalsStore', () => {
27
- it('adds and retrieves items to/from dates store', () => {
28
- pendingProposalsStore_1.pendingProposalsStore.storeItem(mockEntries[0]);
29
- expect(pendingProposalsStore_1.pendingProposalsStore.getAllItems()).toContainEqual(mockEntries[0]);
30
- pendingProposalsStore_1.pendingProposalsStore.storeItem(mockEntries[1]);
31
- const stored = pendingProposalsStore_1.pendingProposalsStore.getAllItems();
32
- expect(stored).toContainEqual(mockEntries[1]);
33
- expect(stored).toContainEqual(mockEntries[0]);
34
- expect(stored).toHaveLength(2);
35
- });
36
- it('removes items from dates store', () => {
37
- pendingProposalsStore_1.pendingProposalsStore.storeItem(mockEntries[0]);
38
- expect(pendingProposalsStore_1.pendingProposalsStore.getAllItems()).toContainEqual(mockEntries[0]);
39
- pendingProposalsStore_1.pendingProposalsStore.deleteItem({ groupId: mockEntries[0].groupId });
40
- expect(pendingProposalsStore_1.pendingProposalsStore.getAllItems()).not.toContainEqual(mockEntries[0]);
41
- });
42
- });