@wireapp/core 43.4.0 → 43.5.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 +8 -6
- package/lib/Account.d.ts.map +1 -1
- package/lib/Account.js +28 -16
- package/lib/Account.test.js +2 -2
- package/lib/messagingProtocols/mls/E2EIdentityService/E2EIServiceInternal.d.ts.map +1 -1
- package/lib/messagingProtocols/mls/E2EIdentityService/E2EIServiceInternal.js +2 -1
- package/lib/messagingProtocols/mls/types.d.ts +0 -10
- package/lib/messagingProtocols/mls/types.d.ts.map +1 -1
- package/lib/secretStore/encryptedStore.d.ts +1 -1
- package/lib/secretStore/encryptedStore.d.ts.map +1 -1
- package/lib/secretStore/encryptedStore.js +1 -1
- package/lib/secretStore/secretKeyGenerator.d.ts +3 -5
- package/lib/secretStore/secretKeyGenerator.d.ts.map +1 -1
- package/lib/secretStore/secretKeyGenerator.js +1 -34
- package/lib/secretStore/secretKeyGenerator.test.js +19 -85
- package/package.json +4 -4
package/lib/Account.d.ts
CHANGED
|
@@ -14,7 +14,7 @@ import { GiphyService } from './giphy/';
|
|
|
14
14
|
import { LinkPreviewService } from './linkPreview';
|
|
15
15
|
import { MLSService } from './messagingProtocols/mls';
|
|
16
16
|
import { AcmeChallenge, E2EIServiceExternal } from './messagingProtocols/mls/E2EIdentityService';
|
|
17
|
-
import { CoreCallbacks, CoreCryptoConfig } from './messagingProtocols/mls/types';
|
|
17
|
+
import { CoreCallbacks, CoreCryptoConfig, SecretCrypto } from './messagingProtocols/mls/types';
|
|
18
18
|
import { NewClient, ProteusService } from './messagingProtocols/proteus';
|
|
19
19
|
import { HandledEventPayload, NotificationService, NotificationSource } from './notification/';
|
|
20
20
|
import { SelfService } from './self/';
|
|
@@ -39,10 +39,11 @@ export declare enum ConnectionState {
|
|
|
39
39
|
/** The websocket is open and message will go through and notifications stream is fully processed */
|
|
40
40
|
LIVE = "live"
|
|
41
41
|
}
|
|
42
|
-
export type CreateStoreFn = (storeName: string,
|
|
42
|
+
export type CreateStoreFn = (storeName: string, key: Uint8Array) => undefined | Promise<CRUDEngine | undefined>;
|
|
43
43
|
interface AccountOptions {
|
|
44
44
|
/** Used to store info in the database (will create a inMemory engine if returns undefined) */
|
|
45
45
|
createStore?: CreateStoreFn;
|
|
46
|
+
systemCrypto?: SecretCrypto;
|
|
46
47
|
/** Number of prekeys to generate when creating a new device (defaults to 2)
|
|
47
48
|
* Prekeys are Diffie-Hellmann public keys which allow offline initiation of a secure Proteus session between two devices.
|
|
48
49
|
* Having a high value will:
|
|
@@ -52,7 +53,7 @@ interface AccountOptions {
|
|
|
52
53
|
* - make creating a new device fast
|
|
53
54
|
* - make it likely that all prekeys get consumed while the device is offline and the last resort prekey will be used to create new session
|
|
54
55
|
*/
|
|
55
|
-
nbPrekeys
|
|
56
|
+
nbPrekeys: number;
|
|
56
57
|
/**
|
|
57
58
|
* Config for MLS and proteus devices. Will fallback to the old cryptobox logic if not provided
|
|
58
59
|
*/
|
|
@@ -66,16 +67,16 @@ type Events = {
|
|
|
66
67
|
[EVENTS.NEW_SESSION]: NewClient;
|
|
67
68
|
};
|
|
68
69
|
export declare class Account extends TypedEventEmitter<Events> {
|
|
70
|
+
private options;
|
|
69
71
|
private readonly apiClient;
|
|
70
72
|
private readonly logger;
|
|
71
|
-
private readonly createStore;
|
|
72
|
-
private readonly nbPrekeys;
|
|
73
73
|
private readonly coreCryptoConfig?;
|
|
74
74
|
private readonly isMlsEnabled;
|
|
75
75
|
/** this is the client the consumer is currently using. Will be set as soon as `initClient` is called and will be rest upon logout */
|
|
76
76
|
private currentClient?;
|
|
77
77
|
private storeEngine?;
|
|
78
78
|
private db?;
|
|
79
|
+
private encryptedDb?;
|
|
79
80
|
private coreCallbacks?;
|
|
80
81
|
service?: {
|
|
81
82
|
mls?: MLSService;
|
|
@@ -101,7 +102,7 @@ export declare class Account extends TypedEventEmitter<Events> {
|
|
|
101
102
|
* @param apiClient The apiClient instance to use in the core (will create a new new one if undefined)
|
|
102
103
|
* @param accountOptions
|
|
103
104
|
*/
|
|
104
|
-
constructor(apiClient?: APIClient,
|
|
105
|
+
constructor(apiClient?: APIClient, options?: AccountOptions);
|
|
105
106
|
/**
|
|
106
107
|
* Will set the APIClient to use a specific version of the API (by default uses version 0)
|
|
107
108
|
* It will fetch the API Config and use the highest possible version
|
|
@@ -220,6 +221,7 @@ export declare class Account extends TypedEventEmitter<Events> {
|
|
|
220
221
|
}): () => void;
|
|
221
222
|
private generateDbName;
|
|
222
223
|
private generateCoreDbName;
|
|
224
|
+
private generateEncryptedDbName;
|
|
223
225
|
private initEngine;
|
|
224
226
|
private groupIdFromConversationId;
|
|
225
227
|
}
|
package/lib/Account.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Account.d.ts","sourceRoot":"","sources":["../src/Account.ts"],"names":[],"mappings":"AAmBA,OAAO,EACL,YAAY,EAGZ,OAAO,EACP,MAAM,EAEN,SAAS,EAEV,MAAM,8BAA8B,CAAC;AACtC,OAAO,EAAuB,UAAU,EAAE,gBAAgB,EAAC,MAAM,iCAAiC,CAAC;AAEnG,OAAO,KAAK,MAAM,MAAM,+BAA+B,CAAC;AASxD,OAAO,EAAC,SAAS,EAAE,eAAe,EAAC,MAAM,qBAAqB,CAAC;AAC/D,OAAO,EAAC,iBAAiB,EAAC,MAAM,kBAAkB,CAAC;AACnD,OAAO,EAAC,UAAU,EAAe,MAAM,uBAAuB,CAAC;AAE/D,OAAO,EAAC,cAAc,EAAC,MAAM,YAAY,CAAC;AAE1C,OAAO,EAAC,gBAAgB,EAAC,MAAM,cAAc,CAAC;AAC9C,OAAO,EAAC,UAAU,EAAE,aAAa,EAAC,MAAM,WAAW,CAAC;AACpD,OAAO,EAAC,iBAAiB,EAAC,MAAM,eAAe,CAAC;AAChD,OAAO,EAAC,YAAY,EAAE,mBAAmB,EAAC,MAAM,iBAAiB,CAAC;AAElE,OAAO,EAAC,sBAAsB,EAAC,MAAM,8DAA8D,CAAC;AACpG,OAAO,EAAC,YAAY,EAAC,MAAM,UAAU,CAAC;AACtC,OAAO,EAAC,kBAAkB,EAAC,MAAM,eAAe,CAAC;AACjD,OAAO,EAAC,UAAU,EAAC,MAAM,0BAA0B,CAAC;AACpD,OAAO,EAAC,aAAa,EAAE,mBAAmB,EAAO,MAAM,6CAA6C,CAAC;AACrG,OAAO,EAAC,aAAa,EAAE,gBAAgB,EAAC,MAAM,gCAAgC,CAAC;
|
|
1
|
+
{"version":3,"file":"Account.d.ts","sourceRoot":"","sources":["../src/Account.ts"],"names":[],"mappings":"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"}
|
package/lib/Account.js
CHANGED
|
@@ -77,6 +77,8 @@ const E2EIdentityService_1 = require("./messagingProtocols/mls/E2EIdentityServic
|
|
|
77
77
|
const proteus_1 = require("./messagingProtocols/proteus");
|
|
78
78
|
const CryptoClient_1 = require("./messagingProtocols/proteus/ProteusService/CryptoClient");
|
|
79
79
|
const notification_1 = require("./notification/");
|
|
80
|
+
const encryptedStore_1 = require("./secretStore/encryptedStore");
|
|
81
|
+
const secretKeyGenerator_1 = require("./secretStore/secretKeyGenerator");
|
|
80
82
|
const self_1 = require("./self/");
|
|
81
83
|
const CoreDB_1 = require("./storage/CoreDB");
|
|
82
84
|
const team_2 = require("./team/");
|
|
@@ -111,8 +113,9 @@ class Account extends commons_1.TypedEventEmitter {
|
|
|
111
113
|
* @param apiClient The apiClient instance to use in the core (will create a new new one if undefined)
|
|
112
114
|
* @param accountOptions
|
|
113
115
|
*/
|
|
114
|
-
constructor(apiClient = new api_client_1.APIClient(),
|
|
116
|
+
constructor(apiClient = new api_client_1.APIClient(), options = { nbPrekeys: 100 }) {
|
|
115
117
|
super();
|
|
118
|
+
this.options = options;
|
|
116
119
|
this.groupIdFromConversationId = async (conversationId, subconversationId) => {
|
|
117
120
|
var _a, _b;
|
|
118
121
|
if (!subconversationId) {
|
|
@@ -122,10 +125,8 @@ class Account extends commons_1.TypedEventEmitter {
|
|
|
122
125
|
};
|
|
123
126
|
this.apiClient = apiClient;
|
|
124
127
|
this.backendFeatures = this.apiClient.backendFeatures;
|
|
125
|
-
this.coreCryptoConfig = coreCryptoConfig;
|
|
126
|
-
this.nbPrekeys = nbPrekeys;
|
|
128
|
+
this.coreCryptoConfig = options.coreCryptoConfig;
|
|
127
129
|
this.isMlsEnabled = async () => { var _a; return !!((_a = this.coreCryptoConfig) === null || _a === void 0 ? void 0 : _a.mls) && (await this.apiClient.supportsMLS()); };
|
|
128
|
-
this.createStore = createStore;
|
|
129
130
|
this.recurringTaskScheduler = new RecurringTaskScheduler_1.RecurringTaskScheduler({
|
|
130
131
|
get: async (key) => {
|
|
131
132
|
var _a;
|
|
@@ -203,7 +204,7 @@ class Account extends commons_1.TypedEventEmitter {
|
|
|
203
204
|
domain,
|
|
204
205
|
id: this.userId,
|
|
205
206
|
};
|
|
206
|
-
return this.service.mls.enrollE2EI(discoveryUrl, this.service.e2eIdentity, user, this.currentClient, this.nbPrekeys, oAuthIdToken);
|
|
207
|
+
return this.service.mls.enrollE2EI(discoveryUrl, this.service.e2eIdentity, user, this.currentClient, this.options.nbPrekeys, oAuthIdToken);
|
|
207
208
|
}
|
|
208
209
|
get clientId() {
|
|
209
210
|
return this.apiClient.validatedClientId;
|
|
@@ -306,9 +307,9 @@ class Account extends commons_1.TypedEventEmitter {
|
|
|
306
307
|
this.currentClient = validClient;
|
|
307
308
|
return validClient;
|
|
308
309
|
}
|
|
309
|
-
async buildCryptoClient(context, storeEngine) {
|
|
310
|
+
async buildCryptoClient(context, storeEngine, encryptedStore) {
|
|
310
311
|
const baseConfig = {
|
|
311
|
-
nbPrekeys: this.nbPrekeys,
|
|
312
|
+
nbPrekeys: this.options.nbPrekeys,
|
|
312
313
|
onNewPrekeys: async (prekeys) => {
|
|
313
314
|
this.logger.debug(`Received '${prekeys.length}' new PreKeys.`);
|
|
314
315
|
await this.apiClient.api.client.putClient(context.clientId, { prekeys });
|
|
@@ -318,11 +319,11 @@ class Account extends commons_1.TypedEventEmitter {
|
|
|
318
319
|
const coreCryptoConfig = this.coreCryptoConfig;
|
|
319
320
|
if (coreCryptoConfig) {
|
|
320
321
|
const { buildClient } = await Promise.resolve().then(() => __importStar(require('./messagingProtocols/proteus/ProteusService/CryptoClient/CoreCryptoWrapper')));
|
|
321
|
-
const client = await buildClient(storeEngine, Object.assign(Object.assign(Object.assign({}, baseConfig), coreCryptoConfig), { generateSecretKey: keyId =>
|
|
322
|
+
const client = await buildClient(storeEngine, Object.assign(Object.assign(Object.assign({}, baseConfig), coreCryptoConfig), { generateSecretKey: keyId => (0, secretKeyGenerator_1.generateSecretKey)({ keyId, keySize: 16, secretsDb: encryptedStore }) }));
|
|
322
323
|
return [CryptoClient_1.CryptoClientType.CORE_CRYPTO, client];
|
|
323
324
|
}
|
|
324
325
|
const { buildClient } = await Promise.resolve().then(() => __importStar(require('./messagingProtocols/proteus/ProteusService/CryptoClient/CryptoboxWrapper')));
|
|
325
|
-
const client =
|
|
326
|
+
const client = buildClient(storeEngine, baseConfig);
|
|
326
327
|
return [CryptoClient_1.CryptoClientType.CRYPTOBOX, client];
|
|
327
328
|
}
|
|
328
329
|
/**
|
|
@@ -337,16 +338,20 @@ class Account extends commons_1.TypedEventEmitter {
|
|
|
337
338
|
}
|
|
338
339
|
async initServices(context) {
|
|
339
340
|
var _a;
|
|
340
|
-
|
|
341
|
+
const encryptedStoreName = this.generateEncryptedDbName(context);
|
|
342
|
+
this.encryptedDb = this.options.systemCrypto
|
|
343
|
+
? await (0, encryptedStore_1.createCustomEncryptedStore)(encryptedStoreName, this.options.systemCrypto)
|
|
344
|
+
: await (0, encryptedStore_1.createEncryptedStore)(encryptedStoreName);
|
|
341
345
|
this.db = await (0, CoreDB_1.openDB)(this.generateCoreDbName(context));
|
|
346
|
+
this.storeEngine = await this.initEngine(context, this.encryptedDb);
|
|
342
347
|
const accountService = new account_1.AccountService(this.apiClient);
|
|
343
348
|
const assetService = new conversation_1.AssetService(this.apiClient);
|
|
344
|
-
const [clientType, cryptoClient] = await this.buildCryptoClient(context, this.storeEngine);
|
|
349
|
+
const [clientType, cryptoClient] = await this.buildCryptoClient(context, this.storeEngine, this.encryptedDb);
|
|
345
350
|
let mlsService;
|
|
346
351
|
let e2eServiceExternal;
|
|
347
352
|
const proteusService = new proteus_1.ProteusService(this.apiClient, cryptoClient, {
|
|
348
353
|
onNewClient: payload => this.emit(EVENTS.NEW_SESSION, payload),
|
|
349
|
-
nbPrekeys: this.nbPrekeys,
|
|
354
|
+
nbPrekeys: this.options.nbPrekeys,
|
|
350
355
|
});
|
|
351
356
|
const clientService = new client_2.ClientService(this.apiClient, proteusService, this.storeEngine);
|
|
352
357
|
if (clientType === CryptoClient_1.CryptoClientType.CORE_CRYPTO && (await this.isMlsEnabled())) {
|
|
@@ -392,8 +397,9 @@ class Account extends commons_1.TypedEventEmitter {
|
|
|
392
397
|
* @param clearData if set to `true` will completely wipe any database that was created by the Account
|
|
393
398
|
*/
|
|
394
399
|
async logout(clearData = false) {
|
|
395
|
-
var _a;
|
|
400
|
+
var _a, _b;
|
|
396
401
|
(_a = this.db) === null || _a === void 0 ? void 0 : _a.close();
|
|
402
|
+
(_b = this.encryptedDb) === null || _b === void 0 ? void 0 : _b.close();
|
|
397
403
|
if (clearData) {
|
|
398
404
|
await this.wipe();
|
|
399
405
|
}
|
|
@@ -404,11 +410,12 @@ class Account extends commons_1.TypedEventEmitter {
|
|
|
404
410
|
* Will delete the identity of the current user
|
|
405
411
|
*/
|
|
406
412
|
async wipe() {
|
|
407
|
-
var _a;
|
|
413
|
+
var _a, _b;
|
|
408
414
|
await ((_a = this.service) === null || _a === void 0 ? void 0 : _a.proteus.wipe(this.storeEngine));
|
|
409
415
|
if (this.db) {
|
|
410
416
|
await (0, CoreDB_1.deleteDB)(this.db);
|
|
411
417
|
}
|
|
418
|
+
await ((_b = this.encryptedDb) === null || _b === void 0 ? void 0 : _b.wipe());
|
|
412
419
|
}
|
|
413
420
|
/**
|
|
414
421
|
* Will download and handle the notification stream since last stored notification id.
|
|
@@ -512,11 +519,16 @@ class Account extends commons_1.TypedEventEmitter {
|
|
|
512
519
|
generateCoreDbName(context) {
|
|
513
520
|
return `core-${this.generateDbName(context)}`;
|
|
514
521
|
}
|
|
515
|
-
|
|
522
|
+
generateEncryptedDbName(context) {
|
|
523
|
+
return `secrets-${this.generateDbName(context)}`;
|
|
524
|
+
}
|
|
525
|
+
async initEngine(context, encryptedStore) {
|
|
516
526
|
const dbName = this.generateDbName(context);
|
|
517
527
|
this.logger.log(`Initialising store with name "${dbName}"...`);
|
|
518
528
|
const openDb = async () => {
|
|
519
|
-
|
|
529
|
+
var _a, _b;
|
|
530
|
+
const dbKey = await (0, secretKeyGenerator_1.generateSecretKey)({ keyId: 'db-key', keySize: 32, secretsDb: encryptedStore });
|
|
531
|
+
const initializedDb = await ((_b = (_a = this.options).createStore) === null || _b === void 0 ? void 0 : _b.call(_a, dbName, dbKey.key));
|
|
520
532
|
if (initializedDb) {
|
|
521
533
|
this.logger.info(`Initialized store with existing engine "${dbName}".`);
|
|
522
534
|
return initializedDb;
|
package/lib/Account.test.js
CHANGED
|
@@ -98,7 +98,7 @@ const waitFor = (assertion) => {
|
|
|
98
98
|
describe('Account', () => {
|
|
99
99
|
const CLIENT_ID = '4e37b32f57f6da55';
|
|
100
100
|
// Fix for node 16, crypto.subtle.decrypt has a type problem
|
|
101
|
-
jest.spyOn(global.crypto.subtle, 'decrypt').
|
|
101
|
+
jest.spyOn(global.crypto.subtle, 'decrypt').mockResolvedValue(new Uint8Array(32));
|
|
102
102
|
const accessTokenData = {
|
|
103
103
|
access_token: 'iJCRCjc8oROO-dkrkqCXOade997oa8Jhbz6awMUQPBQo80VenWqp_oNvfY6AnU5BxEsdDPOBfBP-uz_b0gAKBQ==.v=1.k=1.d=1498600993.t=a.l=.u=aaf9a833-ef30-4c22-86a0-9adc8a15b3b4.c=15037015562284012115',
|
|
104
104
|
expires_in: 900,
|
|
@@ -234,7 +234,7 @@ describe('Account', () => {
|
|
|
234
234
|
event: { type: event_1.CONVERSATION_EVENT.OTR_MESSAGE_ADD },
|
|
235
235
|
},
|
|
236
236
|
});
|
|
237
|
-
const kill =
|
|
237
|
+
const kill = account.listen({
|
|
238
238
|
onEvent: ({ event }) => {
|
|
239
239
|
expect(event.type).toBe(event_1.CONVERSATION_EVENT.OTR_MESSAGE_ADD);
|
|
240
240
|
resolve();
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"E2EIServiceInternal.d.ts","sourceRoot":"","sources":["../../../../src/messagingProtocols/mls/E2EIdentityService/E2EIServiceInternal.ts"],"names":[],"mappings":"AAyBA,OAAO,EACL,aAAa,EAKb,UAAU,EACV,YAAY,EACb,MAAM,qBAAqB,CAAC;AAW7B,cAAM,mBAAmB;IACvB,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAsB;IAC7C,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAuD;IAC9E,OAAO,CAAC,QAAQ,CAAC,gBAAgB,CAAa;IAC9C,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAY;IACtC,OAAO,CAAC,QAAQ,CAAC,kBAAkB,CAAsB;IACzD,OAAO,CAAC,QAAQ,CAAC,iBAAiB,CAAC;IACnC,OAAO,CAAC,QAAQ,CAAC,CAAiB;IAClC,OAAO,CAAC,WAAW,CAAC,CAAc;IAClC,OAAO,CAAC,aAAa,CAAS;IAE9B,OAAO;WAea,WAAW,CAAC,MAAM,CAAC,EAAE,UAAU,GAAG,OAAO,CAAC,mBAAmB,CAAC;IAwBrE,uBAAuB,CAAC,oBAAoB,EAAE,OAAO;IAYrD,0BAA0B,CAAC,YAAY,EAAE,MAAM,GAAG,OAAO,CAAC,YAAY,GAAG,SAAS,CAAC;YAelF,YAAY;
|
|
1
|
+
{"version":3,"file":"E2EIServiceInternal.d.ts","sourceRoot":"","sources":["../../../../src/messagingProtocols/mls/E2EIdentityService/E2EIServiceInternal.ts"],"names":[],"mappings":"AAyBA,OAAO,EACL,aAAa,EAKb,UAAU,EACV,YAAY,EACb,MAAM,qBAAqB,CAAC;AAW7B,cAAM,mBAAmB;IACvB,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAsB;IAC7C,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAuD;IAC9E,OAAO,CAAC,QAAQ,CAAC,gBAAgB,CAAa;IAC9C,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAY;IACtC,OAAO,CAAC,QAAQ,CAAC,kBAAkB,CAAsB;IACzD,OAAO,CAAC,QAAQ,CAAC,iBAAiB,CAAC;IACnC,OAAO,CAAC,QAAQ,CAAC,CAAiB;IAClC,OAAO,CAAC,WAAW,CAAC,CAAc;IAClC,OAAO,CAAC,aAAa,CAAS;IAE9B,OAAO;WAea,WAAW,CAAC,MAAM,CAAC,EAAE,UAAU,GAAG,OAAO,CAAC,mBAAmB,CAAC;IAwBrE,uBAAuB,CAAC,oBAAoB,EAAE,OAAO;IAYrD,0BAA0B,CAAC,YAAY,EAAE,MAAM,GAAG,OAAO,CAAC,YAAY,GAAG,SAAS,CAAC;YAelF,YAAY;IA+B1B,OAAO,CAAC,aAAa;YAKP,IAAI;YAeJ,YAAY;YAeZ,eAAe;IAa7B;;;;;OAKG;YACW,gCAAgC;IAgD9C;;;;;;;OAOG;YACW,sCAAsC;IA0EpD;;;OAGG;YACW,iBAAiB;IA0B/B;;;;;;OAMG;YACW,iBAAiB;IAmB/B;;;;;OAKG;IACU,0BAA0B,CAAC,YAAY,EAAE,MAAM,EAAE,oBAAoB,EAAE,OAAO;CAkB5F;AAED,OAAO,EAAC,mBAAmB,EAAC,CAAC"}
|
|
@@ -92,7 +92,8 @@ class E2EIServiceInternal {
|
|
|
92
92
|
async initIdentity(hasActiveCertificate) {
|
|
93
93
|
const { clientId, user } = E2EIStorage_1.E2EIStorage.get.initialData();
|
|
94
94
|
const e2eiClientId = (0, Helper_1.getE2EIClientId)(clientId, user.id, user.domain).asString;
|
|
95
|
-
|
|
95
|
+
// How long the issued certificate should be maximal valid
|
|
96
|
+
const expiryDays = 90;
|
|
96
97
|
const ciphersuite = E2EIService_types_1.Ciphersuite.MLS_128_DHKEMX25519_AES128GCM_SHA256_Ed25519;
|
|
97
98
|
if (hasActiveCertificate) {
|
|
98
99
|
try {
|
|
@@ -1,15 +1,9 @@
|
|
|
1
1
|
import { QualifiedId } from '@wireapp/api-client/lib/user';
|
|
2
2
|
import { MLSServiceConfig } from './MLSService/MLSService.types';
|
|
3
|
-
import { GeneratedKey } from '../../secretStore/secretKeyGenerator';
|
|
4
3
|
export type ClientId = string;
|
|
5
4
|
export type SecretCrypto = {
|
|
6
5
|
encrypt: (value: Uint8Array) => Promise<Uint8Array>;
|
|
7
6
|
decrypt: (payload: Uint8Array) => Promise<Uint8Array>;
|
|
8
|
-
version: undefined;
|
|
9
|
-
} | {
|
|
10
|
-
encrypt: (value: string) => Promise<Uint8Array>;
|
|
11
|
-
decrypt: (payload: Uint8Array) => Promise<string>;
|
|
12
|
-
version: 1;
|
|
13
7
|
};
|
|
14
8
|
export interface CoreCallbacks {
|
|
15
9
|
/**
|
|
@@ -31,10 +25,6 @@ export type CommitPendingProposalsParams = {
|
|
|
31
25
|
skipDelete?: boolean;
|
|
32
26
|
} & CommonMLS;
|
|
33
27
|
export interface CoreCryptoConfig {
|
|
34
|
-
/**
|
|
35
|
-
* function called to generate the secret key for CoreCrypto's database encryption
|
|
36
|
-
*/
|
|
37
|
-
generateSecretKey: (storeName: string, keyId: string, keySize: number) => Promise<GeneratedKey>;
|
|
38
28
|
/**
|
|
39
29
|
* path on the public server to the core crypto wasm file.
|
|
40
30
|
* This file will be downloaded lazily when corecrypto is needed.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/messagingProtocols/mls/types.ts"],"names":[],"mappings":"AAmBA,OAAO,EAAC,WAAW,EAAC,MAAM,8BAA8B,CAAC;AAEzD,OAAO,EAAC,gBAAgB,EAAC,MAAM,+BAA+B,CAAC;AAE/D,
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/messagingProtocols/mls/types.ts"],"names":[],"mappings":"AAmBA,OAAO,EAAC,WAAW,EAAC,MAAM,8BAA8B,CAAC;AAEzD,OAAO,EAAC,gBAAgB,EAAC,MAAM,+BAA+B,CAAC;AAE/D,MAAM,MAAM,QAAQ,GAAG,MAAM,CAAC;AAE9B,MAAM,MAAM,YAAY,GAAG;IACzB,OAAO,EAAE,CAAC,KAAK,EAAE,UAAU,KAAK,OAAO,CAAC,UAAU,CAAC,CAAC;IACpD,OAAO,EAAE,CAAC,OAAO,EAAE,UAAU,KAAK,OAAO,CAAC,UAAU,CAAC,CAAC;CACvD,CAAC;AAEF,MAAM,WAAW,aAAa;IAC5B;;;;;OAKG;IACH,yBAAyB,EAAE,CAAC,cAAc,EAAE,WAAW,KAAK,OAAO,CAAC,MAAM,GAAG,SAAS,CAAC,CAAC;CACzF;AAED,MAAM,MAAM,SAAS,GAAG;IACtB,OAAO,EAAE,MAAM,CAAC;CACjB,CAAC;AAEF,MAAM,MAAM,4BAA4B,GAAG;IACzC,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;CACnB,GAAG,SAAS,CAAC;AAEd,MAAM,MAAM,4BAA4B,GAAG;IACzC,UAAU,CAAC,EAAE,OAAO,CAAC;CACtB,GAAG,SAAS,CAAC;AAEd,MAAM,WAAW,gBAAgB;IAC/B;;;;OAIG;IACH,YAAY,EAAE,MAAM,CAAC;IAErB,uEAAuE;IACvE,GAAG,CAAC,EAAE,OAAO,CAAC,gBAAgB,CAAC,CAAC;CACjC"}
|
|
@@ -19,7 +19,7 @@ type EncryptedStoreConfig<EncryptedPayload> = {
|
|
|
19
19
|
encrypt: EncryptFn<EncryptedPayload>;
|
|
20
20
|
decrypt: DecryptFn<EncryptedPayload>;
|
|
21
21
|
};
|
|
22
|
-
export declare class EncryptedStore<EncryptedPayload> {
|
|
22
|
+
export declare class EncryptedStore<EncryptedPayload = unknown> {
|
|
23
23
|
#private;
|
|
24
24
|
private readonly db;
|
|
25
25
|
constructor(db: IDBPDatabase<EncryptedDB<EncryptedPayload>>, { encrypt, decrypt }: EncryptedStoreConfig<EncryptedPayload>);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"encryptedStore.d.ts","sourceRoot":"","sources":["../../src/secretStore/encryptedStore.ts"],"names":[],"mappings":"AAmBA,OAAO,EAAC,QAAQ,EAAE,YAAY,EAAmB,MAAM,KAAK,CAAC;AAE7D,UAAU,uBAAuB;IAC/B,EAAE,EAAE,UAAU,GAAG,WAAW,CAAC;IAC7B,KAAK,EAAE,UAAU,GAAG,WAAW,CAAC;CACjC;AACD,UAAU,WAAW,CAAC,gBAAgB,CAAE,SAAQ,QAAQ;IACtD,GAAG,EAAE;QACH,GAAG,EAAE,MAAM,CAAC;QACZ,KAAK,EAAE,SAAS,CAAC;KAClB,CAAC;IACF,OAAO,EAAE;QACP,GAAG,EAAE,MAAM,CAAC;QACZ,KAAK,EAAE,gBAAgB,CAAC;KACzB,CAAC;CACH;AAED,KAAK,SAAS,CAAC,gBAAgB,IAAI,CAAC,OAAO,EAAE,gBAAgB,KAAK,OAAO,CAAC,UAAU,CAAC,CAAC;AACtF,KAAK,SAAS,CAAC,gBAAgB,IAAI,CAAC,KAAK,EAAE,UAAU,KAAK,OAAO,CAAC,gBAAgB,CAAC,CAAC;AAEpF,KAAK,oBAAoB,CAAC,gBAAgB,IAAI;IAC5C,OAAO,EAAE,SAAS,CAAC,gBAAgB,CAAC,CAAC;IACrC,OAAO,EAAE,SAAS,CAAC,gBAAgB,CAAC,CAAC;CACtC,CAAC;AAEF,qBAAa,cAAc,CAAC,gBAAgB;;
|
|
1
|
+
{"version":3,"file":"encryptedStore.d.ts","sourceRoot":"","sources":["../../src/secretStore/encryptedStore.ts"],"names":[],"mappings":"AAmBA,OAAO,EAAC,QAAQ,EAAE,YAAY,EAAmB,MAAM,KAAK,CAAC;AAE7D,UAAU,uBAAuB;IAC/B,EAAE,EAAE,UAAU,GAAG,WAAW,CAAC;IAC7B,KAAK,EAAE,UAAU,GAAG,WAAW,CAAC;CACjC;AACD,UAAU,WAAW,CAAC,gBAAgB,CAAE,SAAQ,QAAQ;IACtD,GAAG,EAAE;QACH,GAAG,EAAE,MAAM,CAAC;QACZ,KAAK,EAAE,SAAS,CAAC;KAClB,CAAC;IACF,OAAO,EAAE;QACP,GAAG,EAAE,MAAM,CAAC;QACZ,KAAK,EAAE,gBAAgB,CAAC;KACzB,CAAC;CACH;AAED,KAAK,SAAS,CAAC,gBAAgB,IAAI,CAAC,OAAO,EAAE,gBAAgB,KAAK,OAAO,CAAC,UAAU,CAAC,CAAC;AACtF,KAAK,SAAS,CAAC,gBAAgB,IAAI,CAAC,KAAK,EAAE,UAAU,KAAK,OAAO,CAAC,gBAAgB,CAAC,CAAC;AAEpF,KAAK,oBAAoB,CAAC,gBAAgB,IAAI;IAC5C,OAAO,EAAE,SAAS,CAAC,gBAAgB,CAAC,CAAC;IACrC,OAAO,EAAE,SAAS,CAAC,gBAAgB,CAAC,CAAC;CACtC,CAAC;AAEF,qBAAa,cAAc,CAAC,gBAAgB,GAAG,OAAO;;IAIlD,OAAO,CAAC,QAAQ,CAAC,EAAE;gBAAF,EAAE,EAAE,YAAY,CAAC,WAAW,CAAC,gBAAgB,CAAC,CAAC,EAChE,EAAC,OAAO,EAAE,OAAO,EAAC,EAAE,oBAAoB,CAAC,gBAAgB,CAAC;IAMtD,eAAe,CAAC,UAAU,EAAE,MAAM,EAAE,KAAK,EAAE,UAAU;IAKrD,cAAc,CAAC,UAAU,EAAE,MAAM;IAQjC,iBAAiB,CAAC,UAAU,EAAE,MAAM;IAM1C,KAAK;IAIC,IAAI;CAIX;AAuBD;;;;;GAKG;AACH,wBAAsB,oBAAoB,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,cAAc,CAAC,uBAAuB,CAAC,CAAC,CAkB3G;AAED;;;;;;GAMG;AACH,wBAAsB,0BAA0B,CAAC,gBAAgB,EAC/D,MAAM,EAAE,MAAM,EACd,MAAM,EAAE,oBAAoB,CAAC,gBAAgB,CAAC,GAC7C,OAAO,CAAC,cAAc,CAAC,gBAAgB,CAAC,CAAC,CAQ3C"}
|
|
@@ -75,7 +75,7 @@ async function defaultDecrypt({ value, iv }, key) {
|
|
|
75
75
|
return new Uint8Array(decrypted);
|
|
76
76
|
}
|
|
77
77
|
async function defaultEncrypt(data, key) {
|
|
78
|
-
const iv =
|
|
78
|
+
const iv = crypto.getRandomValues(new Uint8Array(12));
|
|
79
79
|
return {
|
|
80
80
|
iv,
|
|
81
81
|
value: await crypto.subtle.encrypt({ name: 'AES-GCM', iv }, key, data),
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { EncryptedStore } from './encryptedStore';
|
|
2
2
|
export declare class CorruptedKeyError extends Error {
|
|
3
3
|
}
|
|
4
4
|
export type GeneratedKey = {
|
|
@@ -8,14 +8,12 @@ export type GeneratedKey = {
|
|
|
8
8
|
/**
|
|
9
9
|
* Will generate (or retrieve) a secret key from the database.
|
|
10
10
|
*/
|
|
11
|
-
export declare function generateSecretKey({ keyId, keySize,
|
|
11
|
+
export declare function generateSecretKey({ keyId, keySize, secretsDb, }: {
|
|
12
12
|
/** the ID of the key to generate (if the ID already exists, then the generated key will be returned) */
|
|
13
13
|
keyId: string;
|
|
14
14
|
/** size of the key to generate */
|
|
15
15
|
keySize?: number;
|
|
16
16
|
/** name of the database that will hold the secrets */
|
|
17
|
-
|
|
18
|
-
/** custom crypto primitives to use to encrypt the secret keys */
|
|
19
|
-
systemCrypto?: SecretCrypto;
|
|
17
|
+
secretsDb: EncryptedStore<any>;
|
|
20
18
|
}): Promise<GeneratedKey>;
|
|
21
19
|
//# sourceMappingURL=secretKeyGenerator.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"secretKeyGenerator.d.ts","sourceRoot":"","sources":["../../src/secretStore/secretKeyGenerator.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"secretKeyGenerator.d.ts","sourceRoot":"","sources":["../../src/secretStore/secretKeyGenerator.ts"],"names":[],"mappings":"AAmBA,OAAO,EAAC,cAAc,EAAC,MAAM,kBAAkB,CAAC;AAEhD,qBAAa,iBAAkB,SAAQ,KAAK;CAAG;AAE/C,MAAM,MAAM,YAAY,GAAG;IACzB,GAAG,EAAE,UAAU,CAAC;IAChB,SAAS,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;CAChC,CAAC;AAEF;;GAEG;AACH,wBAAsB,iBAAiB,CAAC,EACtC,KAAK,EACL,OAAY,EACZ,SAAS,GACV,EAAE;IACD,wGAAwG;IACxG,KAAK,EAAE,MAAM,CAAC;IACd,kCAAkC;IAClC,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,sDAAsD;IACtD,SAAS,EAAE,cAAc,CAAC,GAAG,CAAC,CAAC;CAChC,GAAG,OAAO,CAAC,YAAY,CAAC,CAsBxB"}
|
|
@@ -19,44 +19,13 @@
|
|
|
19
19
|
*/
|
|
20
20
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
21
21
|
exports.generateSecretKey = exports.CorruptedKeyError = void 0;
|
|
22
|
-
const bazinga64_1 = require("bazinga64");
|
|
23
|
-
const encryptedStore_1 = require("./encryptedStore");
|
|
24
|
-
const isBase64 = /^([A-Za-z0-9+/]{4})*([A-Za-z0-9+/]{3}=|[A-Za-z0-9+/]{2}==)?$/;
|
|
25
22
|
class CorruptedKeyError extends Error {
|
|
26
23
|
}
|
|
27
24
|
exports.CorruptedKeyError = CorruptedKeyError;
|
|
28
25
|
/**
|
|
29
26
|
* Will generate (or retrieve) a secret key from the database.
|
|
30
27
|
*/
|
|
31
|
-
async function generateSecretKey({ keyId, keySize = 16,
|
|
32
|
-
const systemCrypto = baseCrypto
|
|
33
|
-
? {
|
|
34
|
-
encrypt: (value) => {
|
|
35
|
-
if (baseCrypto.version === 1) {
|
|
36
|
-
const strValue = bazinga64_1.Encoder.toBase64(value).asString;
|
|
37
|
-
return baseCrypto.encrypt(strValue);
|
|
38
|
-
}
|
|
39
|
-
// In previous versions of the systemCrypto (prior to February 2023), encrypt took a uint8Array
|
|
40
|
-
return baseCrypto.encrypt(value);
|
|
41
|
-
},
|
|
42
|
-
decrypt: async (value) => {
|
|
43
|
-
if (typeof baseCrypto.version === 'undefined') {
|
|
44
|
-
// In previous versions of the systemCrypto (prior to February 2023), the decrypt function returned a Uint8Array
|
|
45
|
-
return baseCrypto.decrypt(value);
|
|
46
|
-
}
|
|
47
|
-
const decrypted = await baseCrypto.decrypt(value);
|
|
48
|
-
if (isBase64.test(decrypted)) {
|
|
49
|
-
return bazinga64_1.Decoder.fromBase64(decrypted).asBytes;
|
|
50
|
-
}
|
|
51
|
-
// Between June 2022 and October 2022, the systemCrypto returned a string encoded in UTF-8
|
|
52
|
-
const encoder = new TextEncoder();
|
|
53
|
-
return encoder.encode(decrypted);
|
|
54
|
-
},
|
|
55
|
-
}
|
|
56
|
-
: undefined;
|
|
57
|
-
const secretsDb = systemCrypto
|
|
58
|
-
? await (0, encryptedStore_1.createCustomEncryptedStore)(dbName, systemCrypto)
|
|
59
|
-
: await (0, encryptedStore_1.createEncryptedStore)(dbName);
|
|
28
|
+
async function generateSecretKey({ keyId, keySize = 16, secretsDb, }) {
|
|
60
29
|
try {
|
|
61
30
|
let key;
|
|
62
31
|
try {
|
|
@@ -75,11 +44,9 @@ async function generateSecretKey({ keyId, keySize = 16, dbName, systemCrypto: ba
|
|
|
75
44
|
key = crypto.getRandomValues(new Uint8Array(keySize));
|
|
76
45
|
await secretsDb.saveSecretValue(keyId, key);
|
|
77
46
|
}
|
|
78
|
-
await (secretsDb === null || secretsDb === void 0 ? void 0 : secretsDb.close());
|
|
79
47
|
return { key, deleteKey: () => secretsDb.deleteSecretValue(keyId) };
|
|
80
48
|
}
|
|
81
49
|
catch (error) {
|
|
82
|
-
await (secretsDb === null || secretsDb === void 0 ? void 0 : secretsDb.close());
|
|
83
50
|
throw error;
|
|
84
51
|
}
|
|
85
52
|
}
|
|
@@ -18,105 +18,39 @@
|
|
|
18
18
|
*
|
|
19
19
|
*/
|
|
20
20
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
21
|
-
const
|
|
21
|
+
const encryptedStore_1 = require("./encryptedStore");
|
|
22
22
|
const secretKeyGenerator_1 = require("./secretKeyGenerator");
|
|
23
|
-
const
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
},
|
|
28
|
-
decrypt: async (value) => {
|
|
29
|
-
return value;
|
|
30
|
-
},
|
|
31
|
-
version: undefined,
|
|
32
|
-
},
|
|
33
|
-
v01: {
|
|
34
|
-
encrypt: async (value) => {
|
|
35
|
-
return bazinga64_1.Encoder.toBase64(value).asBytes;
|
|
36
|
-
},
|
|
37
|
-
decrypt: async (value) => {
|
|
38
|
-
const str = new TextDecoder().decode(value);
|
|
39
|
-
return bazinga64_1.Decoder.fromBase64(str).asBytes;
|
|
40
|
-
},
|
|
41
|
-
version: undefined,
|
|
42
|
-
},
|
|
43
|
-
v1: {
|
|
44
|
-
encrypt: async (value) => {
|
|
45
|
-
const encoder = new TextEncoder();
|
|
46
|
-
return encoder.encode(value);
|
|
47
|
-
},
|
|
48
|
-
decrypt: async (value) => {
|
|
49
|
-
const decoder = new TextDecoder();
|
|
50
|
-
return decoder.decode(value);
|
|
51
|
-
},
|
|
52
|
-
version: 1,
|
|
53
|
-
},
|
|
23
|
+
const customCrypto = {
|
|
24
|
+
encrypt: async (value) => value,
|
|
25
|
+
decrypt: async (value) => value,
|
|
26
|
+
version: 1,
|
|
54
27
|
};
|
|
55
28
|
const dbName = 'test';
|
|
56
29
|
const keyId = 'test-key';
|
|
57
30
|
describe('SecretKeyGenerator', () => {
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
jest.spyOn(version, 'encrypt');
|
|
62
|
-
jest.spyOn(version, 'decrypt');
|
|
63
|
-
});
|
|
64
|
-
const deleteReq = indexedDB.deleteDatabase(dbName);
|
|
65
|
-
deleteReq.onsuccess = resolve;
|
|
66
|
-
});
|
|
31
|
+
let secretsDb;
|
|
32
|
+
afterEach(async () => {
|
|
33
|
+
await (secretsDb === null || secretsDb === void 0 ? void 0 : secretsDb.wipe());
|
|
67
34
|
});
|
|
68
|
-
it('generates and
|
|
69
|
-
|
|
35
|
+
it('generates store and deletes a secret key stored in indexeddb', async () => {
|
|
36
|
+
secretsDb = await (0, encryptedStore_1.createEncryptedStore)(dbName);
|
|
37
|
+
const { key: secretKey } = await (0, secretKeyGenerator_1.generateSecretKey)({ secretsDb, keyId });
|
|
70
38
|
expect(secretKey).toBeDefined();
|
|
71
|
-
const { key: secretKey2 } = await (0, secretKeyGenerator_1.generateSecretKey)({
|
|
39
|
+
const { key: secretKey2 } = await (0, secretKeyGenerator_1.generateSecretKey)({ secretsDb, keyId });
|
|
72
40
|
expect(secretKey).toEqual(secretKey2);
|
|
73
41
|
});
|
|
74
|
-
it.each(Object.entries(systemCryptos))('generates and store a secret key encrypted using system crypto (%s)', async (_name, systemCrypto) => {
|
|
75
|
-
const { key } = await (0, secretKeyGenerator_1.generateSecretKey)({
|
|
76
|
-
dbName,
|
|
77
|
-
systemCrypto,
|
|
78
|
-
keyId,
|
|
79
|
-
});
|
|
80
|
-
expect(key).toBeDefined();
|
|
81
|
-
expect(systemCrypto.encrypt).toHaveBeenCalled();
|
|
82
|
-
expect(systemCrypto.decrypt).not.toHaveBeenCalled();
|
|
83
|
-
// fetch stored key
|
|
84
|
-
const { key: key2 } = await (0, secretKeyGenerator_1.generateSecretKey)({ dbName, systemCrypto: systemCrypto, keyId });
|
|
85
|
-
expect(key2).toEqual(key);
|
|
86
|
-
expect(systemCrypto.encrypt).toHaveBeenCalledTimes(1);
|
|
87
|
-
expect(systemCrypto.decrypt).toHaveBeenCalledTimes(1);
|
|
88
|
-
});
|
|
89
|
-
it.each([
|
|
90
|
-
['v0 > v01', systemCryptos.v0, systemCryptos.v01],
|
|
91
|
-
['v0 > v1', systemCryptos.v0, systemCryptos.v1],
|
|
92
|
-
])('throws an error if previous systemCrypto is not compatible with the current one (%s)', async (_name, crypto1, crypto2) => {
|
|
93
|
-
const { key } = await (0, secretKeyGenerator_1.generateSecretKey)({
|
|
94
|
-
dbName,
|
|
95
|
-
systemCrypto: crypto1,
|
|
96
|
-
keyId,
|
|
97
|
-
});
|
|
98
|
-
expect(key).toBeDefined();
|
|
99
|
-
try {
|
|
100
|
-
await (0, secretKeyGenerator_1.generateSecretKey)({ dbName, systemCrypto: crypto2, keyId });
|
|
101
|
-
}
|
|
102
|
-
catch (e) {
|
|
103
|
-
expect(e).toBeInstanceOf(secretKeyGenerator_1.CorruptedKeyError);
|
|
104
|
-
}
|
|
105
|
-
});
|
|
106
42
|
it('deletes the key from DB', async () => {
|
|
107
|
-
|
|
43
|
+
secretsDb = await (0, encryptedStore_1.createEncryptedStore)(dbName);
|
|
44
|
+
const { key, deleteKey } = await (0, secretKeyGenerator_1.generateSecretKey)({ secretsDb, keyId });
|
|
108
45
|
await deleteKey();
|
|
109
|
-
const { key: secondKey } = await (0, secretKeyGenerator_1.generateSecretKey)({
|
|
46
|
+
const { key: secondKey } = await (0, secretKeyGenerator_1.generateSecretKey)({ secretsDb, keyId });
|
|
110
47
|
expect(key).not.toEqual(secondKey);
|
|
111
48
|
});
|
|
112
|
-
it
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
systemCrypto: crypto1,
|
|
116
|
-
keyId,
|
|
117
|
-
});
|
|
49
|
+
it('creates a new key from a custom encryption store', async () => {
|
|
50
|
+
secretsDb = await (0, encryptedStore_1.createCustomEncryptedStore)(dbName, customCrypto);
|
|
51
|
+
const { key } = await (0, secretKeyGenerator_1.generateSecretKey)({ secretsDb, keyId });
|
|
118
52
|
expect(key).toBeDefined();
|
|
119
|
-
const { key: key2 } = await (0, secretKeyGenerator_1.generateSecretKey)({
|
|
53
|
+
const { key: key2 } = await (0, secretKeyGenerator_1.generateSecretKey)({ secretsDb, keyId });
|
|
120
54
|
expect(key2).toEqual(key);
|
|
121
55
|
});
|
|
122
56
|
});
|
package/package.json
CHANGED
|
@@ -11,7 +11,7 @@
|
|
|
11
11
|
"./lib/cryptography/AssetCryptography/crypto.node": "./lib/cryptography/AssetCryptography/crypto.browser.js"
|
|
12
12
|
},
|
|
13
13
|
"dependencies": {
|
|
14
|
-
"@wireapp/api-client": "^26.8.
|
|
14
|
+
"@wireapp/api-client": "^26.8.2",
|
|
15
15
|
"@wireapp/commons": "^5.2.4",
|
|
16
16
|
"@wireapp/core-crypto": "1.0.0-rc.21",
|
|
17
17
|
"@wireapp/cryptobox": "12.8.0",
|
|
@@ -19,7 +19,7 @@
|
|
|
19
19
|
"@wireapp/protocol-messaging": "1.44.0",
|
|
20
20
|
"@wireapp/store-engine": "5.1.5",
|
|
21
21
|
"@wireapp/store-engine-dexie": "^2.1.7",
|
|
22
|
-
"axios": "1.6.
|
|
22
|
+
"axios": "1.6.5",
|
|
23
23
|
"bazinga64": "^6.3.4",
|
|
24
24
|
"deepmerge-ts": "5.1.0",
|
|
25
25
|
"hash.js": "1.1.7",
|
|
@@ -61,6 +61,6 @@
|
|
|
61
61
|
"test:coverage": "jest --coverage",
|
|
62
62
|
"watch": "tsc --watch"
|
|
63
63
|
},
|
|
64
|
-
"version": "43.
|
|
65
|
-
"gitHead": "
|
|
64
|
+
"version": "43.5.1",
|
|
65
|
+
"gitHead": "b468b92ff3f2d58cdc0e88ac8d36535f87e6667e"
|
|
66
66
|
}
|