@wireapp/core 38.0.0-beta.4 → 38.0.0-beta.5
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 +10 -22
- package/lib/Account.d.ts.map +1 -1
- package/lib/Account.js +51 -128
- package/lib/Account.test.js +4 -2
- package/lib/client/ClientService.d.ts +10 -1
- package/lib/client/ClientService.d.ts.map +1 -1
- package/lib/client/ClientService.js +52 -2
- package/lib/messagingProtocols/proteus/ProteusService/ProteusService.d.ts +4 -3
- package/lib/messagingProtocols/proteus/ProteusService/ProteusService.d.ts.map +1 -1
- package/lib/messagingProtocols/proteus/ProteusService/ProteusService.js +39 -3
- package/lib/messagingProtocols/proteus/ProteusService/sessionIdMigrator.d.ts +10 -0
- package/lib/messagingProtocols/proteus/ProteusService/sessionIdMigrator.d.ts.map +1 -0
- package/lib/messagingProtocols/proteus/ProteusService/sessionIdMigrator.js +48 -0
- package/lib/notification/NotificationService.d.ts +1 -1
- package/lib/notification/NotificationService.d.ts.map +1 -1
- package/lib/notification/NotificationService.test.js +3 -1
- package/package.json +1 -1
package/lib/Account.d.ts
CHANGED
|
@@ -61,8 +61,6 @@ interface AccountOptions<T> {
|
|
|
61
61
|
type InitOptions = {
|
|
62
62
|
/** cookie used to identify the current user. Will use the browser cookie if not defined */
|
|
63
63
|
cookie?: Cookie;
|
|
64
|
-
/** fully initiate the client and register periodic checks */
|
|
65
|
-
initClient?: boolean;
|
|
66
64
|
};
|
|
67
65
|
export declare class Account<T = any> extends EventEmitter {
|
|
68
66
|
private readonly apiClient;
|
|
@@ -119,35 +117,28 @@ export declare class Account<T = any> extends EventEmitter {
|
|
|
119
117
|
*/
|
|
120
118
|
register(registration: RegisterData, clientType: ClientType): Promise<Context>;
|
|
121
119
|
/**
|
|
122
|
-
* Will init the core with an already
|
|
123
|
-
* Will fail if local client cannot be found
|
|
120
|
+
* Will init the core with an already logged in user
|
|
124
121
|
*
|
|
125
122
|
* @param clientType The type of client the user is using (temporary or permanent)
|
|
126
123
|
*/
|
|
127
|
-
init(clientType: ClientType, { cookie
|
|
124
|
+
init(clientType: ClientType, { cookie }?: InitOptions): Promise<Context>;
|
|
128
125
|
/**
|
|
129
126
|
* Will log the user in with the given credential.
|
|
130
|
-
* Will also create the local client and store it in DB
|
|
131
127
|
*
|
|
132
128
|
* @param loginData The credentials of the user
|
|
133
|
-
* @param initClient Should the call also create the local client
|
|
134
129
|
* @param clientInfo Info about the client to create (name, type...)
|
|
135
130
|
*/
|
|
136
|
-
login(loginData: LoginData
|
|
131
|
+
login(loginData: LoginData): Promise<Context>;
|
|
137
132
|
/**
|
|
138
|
-
* Will
|
|
139
|
-
|
|
140
|
-
|
|
133
|
+
* Will register a new client for the current user
|
|
134
|
+
*/
|
|
135
|
+
registerClient(loginData: LoginData, clientInfo?: ClientInfo, entropyData?: Uint8Array): Promise<RegisteredClient>;
|
|
136
|
+
/**
|
|
137
|
+
* Will initiate all the cryptographic material of the device and setup all the background tasks.
|
|
141
138
|
*
|
|
142
|
-
* @
|
|
143
|
-
* @param clientInfo Will allow creating the client if the local client cannot be found (else will fail if local client is not found)
|
|
144
|
-
* @param entropyData Additional entropy data
|
|
145
|
-
* @returns The local existing client or newly created client
|
|
139
|
+
* @returns The local existing client or undefined if the client does not exist or is not valid (non existing on backend)
|
|
146
140
|
*/
|
|
147
|
-
initClient(
|
|
148
|
-
isNewClient: boolean;
|
|
149
|
-
localClient: RegisteredClient;
|
|
150
|
-
}>;
|
|
141
|
+
initClient(client?: RegisteredClient): Promise<RegisteredClient | undefined>;
|
|
151
142
|
private initCoreCrypto;
|
|
152
143
|
/**
|
|
153
144
|
* In order to be able to send MLS messages, the core needs a few information from the consumer.
|
|
@@ -158,8 +149,6 @@ export declare class Account<T = any> extends EventEmitter {
|
|
|
158
149
|
*/
|
|
159
150
|
configureMLSCallbacks(mlsCallbacks: MLSCallbacks): void;
|
|
160
151
|
initServices(context: Context): Promise<void>;
|
|
161
|
-
loadAndValidateLocalClient(): Promise<RegisteredClient>;
|
|
162
|
-
private registerClient;
|
|
163
152
|
private resetContext;
|
|
164
153
|
/**
|
|
165
154
|
* Will logout the current user
|
|
@@ -205,7 +194,6 @@ export declare class Account<T = any> extends EventEmitter {
|
|
|
205
194
|
*/
|
|
206
195
|
dryRun?: boolean;
|
|
207
196
|
}): () => void;
|
|
208
|
-
runCryptoboxMigration(): Promise<void>;
|
|
209
197
|
private generateDbName;
|
|
210
198
|
private generateSecretsDbName;
|
|
211
199
|
private generateCoreDbName;
|
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,EACV,MAAM,8BAA8B,CAAC;AACtC,OAAO,EAAuB,UAAU,EAAE,gBAAgB,EAAC,MAAM,iCAAiC,CAAC;
|
|
1
|
+
{"version":3,"file":"Account.d.ts","sourceRoot":"","sources":["../src/Account.ts"],"names":[],"mappings":"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"}
|
package/lib/Account.js
CHANGED
|
@@ -34,9 +34,7 @@ const client_1 = require("@wireapp/api-client/lib/client/");
|
|
|
34
34
|
const event_1 = require("@wireapp/api-client/lib/event");
|
|
35
35
|
const tcp_1 = require("@wireapp/api-client/lib/tcp/");
|
|
36
36
|
const ReconnectingWebsocket_1 = require("@wireapp/api-client/lib/tcp/ReconnectingWebsocket");
|
|
37
|
-
const axios_1 = __importDefault(require("axios"));
|
|
38
37
|
const bazinga64_1 = require("bazinga64");
|
|
39
|
-
const http_status_codes_1 = require("http-status-codes");
|
|
40
38
|
const logdown_1 = __importDefault(require("logdown"));
|
|
41
39
|
const events_1 = require("events");
|
|
42
40
|
const api_client_1 = require("@wireapp/api-client");
|
|
@@ -50,7 +48,6 @@ const connection_1 = require("./connection/");
|
|
|
50
48
|
const conversation_1 = require("./conversation/");
|
|
51
49
|
const messageSender_1 = require("./conversation/message/messageSender");
|
|
52
50
|
const giphy_1 = require("./giphy/");
|
|
53
|
-
const identityClearer_1 = require("./identity/identityClearer");
|
|
54
51
|
const linkPreview_1 = require("./linkPreview");
|
|
55
52
|
const mls_1 = require("./messagingProtocols/mls");
|
|
56
53
|
const proteus_1 = require("./messagingProtocols/proteus");
|
|
@@ -145,103 +142,83 @@ class Account extends events_1.EventEmitter {
|
|
|
145
142
|
return context;
|
|
146
143
|
}
|
|
147
144
|
/**
|
|
148
|
-
* Will init the core with an already
|
|
149
|
-
* Will fail if local client cannot be found
|
|
145
|
+
* Will init the core with an already logged in user
|
|
150
146
|
*
|
|
151
147
|
* @param clientType The type of client the user is using (temporary or permanent)
|
|
152
148
|
*/
|
|
153
|
-
async init(clientType, { cookie
|
|
149
|
+
async init(clientType, { cookie } = {}) {
|
|
154
150
|
const context = await this.apiClient.init(clientType, cookie);
|
|
155
151
|
await this.initServices(context);
|
|
156
|
-
// Assumption: client gets only initialized once
|
|
157
|
-
if (initClient) {
|
|
158
|
-
await this.initClient({ clientType });
|
|
159
|
-
}
|
|
160
152
|
return context;
|
|
161
153
|
}
|
|
162
154
|
/**
|
|
163
155
|
* Will log the user in with the given credential.
|
|
164
|
-
* Will also create the local client and store it in DB
|
|
165
156
|
*
|
|
166
157
|
* @param loginData The credentials of the user
|
|
167
|
-
* @param initClient Should the call also create the local client
|
|
168
158
|
* @param clientInfo Info about the client to create (name, type...)
|
|
169
159
|
*/
|
|
170
|
-
async login(loginData
|
|
160
|
+
async login(loginData) {
|
|
171
161
|
this.resetContext();
|
|
172
162
|
auth_2.LoginSanitizer.removeNonPrintableCharacters(loginData);
|
|
173
163
|
const context = await this.apiClient.login(loginData);
|
|
174
164
|
await this.initServices(context);
|
|
175
|
-
if (initClient) {
|
|
176
|
-
await this.initClient(loginData, clientInfo);
|
|
177
|
-
}
|
|
178
165
|
return context;
|
|
179
166
|
}
|
|
180
167
|
/**
|
|
181
|
-
* Will
|
|
182
|
-
|
|
183
|
-
|
|
168
|
+
* Will register a new client for the current user
|
|
169
|
+
*/
|
|
170
|
+
async registerClient(loginData, clientInfo = coreDefaultClient, entropyData) {
|
|
171
|
+
var _a;
|
|
172
|
+
if (!this.service || !this.apiClient.context || !this.coreCryptoClient || !this.storeEngine) {
|
|
173
|
+
throw new Error('Services are not set or context not initialized.');
|
|
174
|
+
}
|
|
175
|
+
const shouldCreateMlsClient = !!((_a = this.cryptoProtocolConfig) === null || _a === void 0 ? void 0 : _a.mls);
|
|
176
|
+
this.logger.info(`Creating new client {mls: ${shouldCreateMlsClient}}`);
|
|
177
|
+
if (entropyData) {
|
|
178
|
+
await this.coreCryptoClient.reseedRng(entropyData);
|
|
179
|
+
}
|
|
180
|
+
await this.service.proteus.initClient(this.storeEngine, this.apiClient.context);
|
|
181
|
+
const initialPreKeys = await this.service.proteus.createClient();
|
|
182
|
+
const client = await this.service.client.register(loginData, clientInfo, initialPreKeys);
|
|
183
|
+
if (shouldCreateMlsClient) {
|
|
184
|
+
const { userId, domain = '' } = this.apiClient.context;
|
|
185
|
+
await this.service.mls.createClient({ id: userId, domain }, client.id);
|
|
186
|
+
}
|
|
187
|
+
this.logger.info('Client is created');
|
|
188
|
+
await this.service.notification.initializeNotificationStream();
|
|
189
|
+
await this.service.client.synchronizeClients();
|
|
190
|
+
await this.initClient(client);
|
|
191
|
+
return client;
|
|
192
|
+
}
|
|
193
|
+
/**
|
|
194
|
+
* Will initiate all the cryptographic material of the device and setup all the background tasks.
|
|
184
195
|
*
|
|
185
|
-
* @
|
|
186
|
-
* @param clientInfo Will allow creating the client if the local client cannot be found (else will fail if local client is not found)
|
|
187
|
-
* @param entropyData Additional entropy data
|
|
188
|
-
* @returns The local existing client or newly created client
|
|
196
|
+
* @returns The local existing client or undefined if the client does not exist or is not valid (non existing on backend)
|
|
189
197
|
*/
|
|
190
|
-
async initClient(
|
|
191
|
-
var _a
|
|
192
|
-
if (!this.service || !this.apiClient.context || !this.coreCryptoClient) {
|
|
198
|
+
async initClient(client) {
|
|
199
|
+
var _a;
|
|
200
|
+
if (!this.service || !this.apiClient.context || !this.coreCryptoClient || !this.storeEngine) {
|
|
193
201
|
throw new Error('Services are not set.');
|
|
194
202
|
}
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
await this.apiClient.transport.http.associateClientWithSession(localClient.id);
|
|
199
|
-
await this.service.proteus.init();
|
|
200
|
-
if (this.backendFeatures.supportsMLS && ((_a = this.cryptoProtocolConfig) === null || _a === void 0 ? void 0 : _a.mls)) {
|
|
201
|
-
const { userId, domain = '' } = this.apiClient.context;
|
|
202
|
-
await this.service.mls.initClient({ id: userId, domain }, localClient.id);
|
|
203
|
-
// initialize schedulers for pending mls proposals once client is initialized
|
|
204
|
-
await this.service.mls.checkExistingPendingProposals();
|
|
205
|
-
// initialize schedulers for renewing key materials
|
|
206
|
-
this.service.mls.checkForKeyMaterialsUpdate();
|
|
207
|
-
// initialize scheduler for syncing key packages with backend
|
|
208
|
-
this.service.mls.checkForKeyPackagesBackendSync();
|
|
209
|
-
}
|
|
210
|
-
return { isNewClient: false, localClient };
|
|
203
|
+
const validClient = client !== null && client !== void 0 ? client : (await this.service.client.loadClient());
|
|
204
|
+
if (!validClient) {
|
|
205
|
+
return undefined;
|
|
211
206
|
}
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
if (notFoundOnBackend) {
|
|
226
|
-
this.logger.log('Could not find valid client on backend');
|
|
227
|
-
const client = await this.service.client.getLocalClient();
|
|
228
|
-
const shouldDeleteWholeDatabase = client.type === client_1.ClientType.TEMPORARY;
|
|
229
|
-
if (shouldDeleteWholeDatabase) {
|
|
230
|
-
this.logger.log('Last client was temporary - Deleting database');
|
|
231
|
-
if (this.storeEngine) {
|
|
232
|
-
await this.storeEngine.clearTables();
|
|
233
|
-
}
|
|
234
|
-
const context = await this.apiClient.init(loginData.clientType);
|
|
235
|
-
await this.initEngine(context);
|
|
236
|
-
}
|
|
237
|
-
else if (this.storeEngine) {
|
|
238
|
-
this.logger.log('Last client was permanent - Deleting previous identity');
|
|
239
|
-
(0, identityClearer_1.deleteIdentity)(this.storeEngine);
|
|
240
|
-
}
|
|
241
|
-
return this.registerClient(loginData, clientInfo, entropyData);
|
|
242
|
-
}
|
|
243
|
-
throw error;
|
|
207
|
+
this.apiClient.context.clientId = validClient.id;
|
|
208
|
+
// Call /access endpoint with client_id after client initialisation
|
|
209
|
+
await this.apiClient.transport.http.associateClientWithSession(validClient.id);
|
|
210
|
+
await this.service.proteus.initClient(this.storeEngine, this.apiClient.context);
|
|
211
|
+
if (this.backendFeatures.supportsMLS && ((_a = this.cryptoProtocolConfig) === null || _a === void 0 ? void 0 : _a.mls)) {
|
|
212
|
+
const { userId, domain = '' } = this.apiClient.context;
|
|
213
|
+
await this.service.mls.initClient({ id: userId, domain }, validClient.id);
|
|
214
|
+
// initialize schedulers for pending mls proposals once client is initialized
|
|
215
|
+
await this.service.mls.checkExistingPendingProposals();
|
|
216
|
+
// initialize schedulers for renewing key materials
|
|
217
|
+
this.service.mls.checkForKeyMaterialsUpdate();
|
|
218
|
+
// initialize scheduler for syncing key packages with backend
|
|
219
|
+
this.service.mls.checkForKeyPackagesBackendSync();
|
|
244
220
|
}
|
|
221
|
+
return validClient;
|
|
245
222
|
}
|
|
246
223
|
async initCoreCrypto(context) {
|
|
247
224
|
var _a, _b;
|
|
@@ -319,35 +296,6 @@ class Account extends events_1.EventEmitter {
|
|
|
319
296
|
user: userService,
|
|
320
297
|
};
|
|
321
298
|
}
|
|
322
|
-
async loadAndValidateLocalClient() {
|
|
323
|
-
const loadedClient = await this.service.client.getLocalClient();
|
|
324
|
-
await this.apiClient.api.client.getClient(loadedClient.id);
|
|
325
|
-
this.apiClient.context.clientId = loadedClient.id;
|
|
326
|
-
return loadedClient;
|
|
327
|
-
}
|
|
328
|
-
async registerClient(loginData, clientInfo = coreDefaultClient, entropyData) {
|
|
329
|
-
var _a;
|
|
330
|
-
if (!this.service || !this.apiClient.context || !this.coreCryptoClient) {
|
|
331
|
-
throw new Error('Services are not set or context not initialized.');
|
|
332
|
-
}
|
|
333
|
-
const createMlsClient = !!((_a = this.cryptoProtocolConfig) === null || _a === void 0 ? void 0 : _a.mls);
|
|
334
|
-
this.logger.info(`Creating new client {mls: ${createMlsClient}}`);
|
|
335
|
-
if (entropyData) {
|
|
336
|
-
await this.coreCryptoClient.reseedRng(entropyData);
|
|
337
|
-
}
|
|
338
|
-
await this.service.proteus.init();
|
|
339
|
-
const initialPreKeys = await this.service.proteus.createClient();
|
|
340
|
-
const registeredClient = await this.service.client.register(loginData, clientInfo, initialPreKeys);
|
|
341
|
-
if (createMlsClient) {
|
|
342
|
-
const { userId, domain = '' } = this.apiClient.context;
|
|
343
|
-
await this.service.mls.createClient({ id: userId, domain }, registeredClient.id);
|
|
344
|
-
}
|
|
345
|
-
this.apiClient.context.clientId = registeredClient.id;
|
|
346
|
-
this.logger.info('Client is created');
|
|
347
|
-
await this.service.notification.initializeNotificationStream();
|
|
348
|
-
await this.service.client.synchronizeClients();
|
|
349
|
-
return { isNewClient: true, localClient: registeredClient };
|
|
350
|
-
}
|
|
351
299
|
resetContext() {
|
|
352
300
|
delete this.apiClient.context;
|
|
353
301
|
delete this.service;
|
|
@@ -476,31 +424,6 @@ class Account extends events_1.EventEmitter {
|
|
|
476
424
|
this.apiClient.transport.ws.removeAllListeners();
|
|
477
425
|
};
|
|
478
426
|
}
|
|
479
|
-
async runCryptoboxMigration() {
|
|
480
|
-
var _a;
|
|
481
|
-
const dbName = (_a = this.storeEngine) === null || _a === void 0 ? void 0 : _a.storeName;
|
|
482
|
-
if (!dbName) {
|
|
483
|
-
this.logger.error('Client was not able to perform DB migration: database was not initialised yet');
|
|
484
|
-
return;
|
|
485
|
-
}
|
|
486
|
-
try {
|
|
487
|
-
this.logger.log(`Migrating data from cryptobox store (${dbName}) to corecrypto.`);
|
|
488
|
-
await this.service.proteus.proteusCryptoboxMigrate(dbName);
|
|
489
|
-
// We can clear 3 stores (keys - local identity, prekeys and sessions) from wire db.
|
|
490
|
-
// They will be stored in corecrypto database now.
|
|
491
|
-
/* TODO uncomment this code when we are sure migration for wire.com has happened successfully for enough users
|
|
492
|
-
const storesToClear = ['keys', 'prekeys', 'sessions'] as const;
|
|
493
|
-
|
|
494
|
-
for (const storeName of storesToClear) {
|
|
495
|
-
await this.storeEngine?.deleteAll(storeName);
|
|
496
|
-
}
|
|
497
|
-
*/
|
|
498
|
-
this.logger.log(`Successfully migrated from cryptobox store (${dbName}) to corecrypto.`);
|
|
499
|
-
}
|
|
500
|
-
catch (error) {
|
|
501
|
-
this.logger.error('Client was not able to perform DB migration: ', error);
|
|
502
|
-
}
|
|
503
|
-
}
|
|
504
427
|
generateDbName(context) {
|
|
505
428
|
const clientType = context.clientType === client_1.ClientType.NONE ? '' : `@${context.clientType}`;
|
|
506
429
|
return `wire@${this.apiClient.config.urls.name}@${context.userId}${clientType}`;
|
package/lib/Account.test.js
CHANGED
|
@@ -179,12 +179,11 @@ describe('Account', () => {
|
|
|
179
179
|
const apiClient = new api_client_1.APIClient({ urls: MOCK_BACKEND });
|
|
180
180
|
const account = new Account_1.Account(apiClient);
|
|
181
181
|
await account.initServices({ clientType: client_1.ClientType.TEMPORARY, userId: '' });
|
|
182
|
-
const {
|
|
182
|
+
const { clientType, userId } = await account.login({
|
|
183
183
|
clientType: client_1.ClientType.TEMPORARY,
|
|
184
184
|
email: 'hello@example.com',
|
|
185
185
|
password: 'my-secret',
|
|
186
186
|
});
|
|
187
|
-
expect(clientId).toBe(CLIENT_ID);
|
|
188
187
|
expect(commons_1.ValidationUtil.isUUIDv4(userId)).toBe(true);
|
|
189
188
|
expect(clientType).toBe(client_1.ClientType.TEMPORARY);
|
|
190
189
|
});
|
|
@@ -271,6 +270,9 @@ describe('Account', () => {
|
|
|
271
270
|
jest
|
|
272
271
|
.spyOn(dependencies.account.service.notification, 'handleNotification')
|
|
273
272
|
.mockImplementation(notif => notif.payload);
|
|
273
|
+
jest
|
|
274
|
+
.spyOn(dependencies.account.service.notification['database'], 'getLastNotificationId')
|
|
275
|
+
.mockResolvedValue('0');
|
|
274
276
|
});
|
|
275
277
|
afterEach(() => {
|
|
276
278
|
server.close();
|
|
@@ -18,6 +18,7 @@ export declare class ClientService {
|
|
|
18
18
|
private readonly storeEngine;
|
|
19
19
|
private readonly database;
|
|
20
20
|
private readonly backend;
|
|
21
|
+
private readonly logger;
|
|
21
22
|
constructor(apiClient: APIClient, proteusService: ProteusService, storeEngine: CRUDEngine);
|
|
22
23
|
getClients(): Promise<RegisteredClient[]>;
|
|
23
24
|
/**
|
|
@@ -34,7 +35,15 @@ export declare class ClientService {
|
|
|
34
35
|
* @param password? Password of the owning user. Can be omitted for temporary devices
|
|
35
36
|
*/
|
|
36
37
|
deleteLocalClient(password?: string): Promise<string>;
|
|
37
|
-
getLocalClient
|
|
38
|
+
private getLocalClient;
|
|
39
|
+
/**
|
|
40
|
+
* Will try to load the local client from the database into memory.
|
|
41
|
+
* Will return undefined if the client is not found in the database or if the client does not exist on the backend.
|
|
42
|
+
* If the client doesn't exist on backend it will purge the database and return undefined.
|
|
43
|
+
*
|
|
44
|
+
* @return the loaded client or undefined
|
|
45
|
+
*/
|
|
46
|
+
loadClient(): Promise<RegisteredClient | undefined>;
|
|
38
47
|
private createLocalClient;
|
|
39
48
|
synchronizeClients(): Promise<MetaClient[]>;
|
|
40
49
|
register(loginData: LoginData, clientInfo: ClientInfo, { prekeys, lastPrekey }: NewDevicePrekeys): Promise<RegisteredClient>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ClientService.d.ts","sourceRoot":"","sources":["../../src/client/ClientService.ts"],"names":[],"mappings":"AAmBA,OAAO,EAAC,SAAS,EAAC,MAAM,+BAA+B,CAAC;AACxD,OAAO,EAAkC,gBAAgB,EAAC,MAAM,iCAAiC,CAAC;
|
|
1
|
+
{"version":3,"file":"ClientService.d.ts","sourceRoot":"","sources":["../../src/client/ClientService.ts"],"names":[],"mappings":"AAmBA,OAAO,EAAC,SAAS,EAAC,MAAM,+BAA+B,CAAC;AACxD,OAAO,EAAkC,gBAAgB,EAAC,MAAM,iCAAiC,CAAC;AAMlG,OAAO,EAAC,SAAS,EAAC,MAAM,qBAAqB,CAAC;AAC9C,OAAO,EAAC,UAAU,EAAC,MAAM,uBAAuB,CAAC;AAGjD,OAAO,KAAK,EAAC,cAAc,EAAC,MAAM,+BAA+B,CAAC;AAClE,OAAO,EAAC,gBAAgB,EAAC,MAAM,8CAA8C,CAAC;AAE9E,OAAO,EAAC,UAAU,EAAoD,MAAM,IAAI,CAAC;AAEjF,MAAM,WAAW,UAAW,SAAQ,gBAAgB;IAClD,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,IAAI,EAAE;QACJ,WAAW,CAAC,EAAE,OAAO,CAAC;QACtB,WAAW,EAAE,MAAM,CAAC;KACrB,CAAC;CACH;AAED,qBAAa,aAAa;IAStB,OAAO,CAAC,QAAQ,CAAC,SAAS;IAC1B,OAAO,CAAC,QAAQ,CAAC,cAAc;IAC/B,OAAO,CAAC,QAAQ,CAAC,WAAW;IAV9B,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAA2B;IACpD,OAAO,CAAC,QAAQ,CAAC,OAAO,CAA0B;IAClD,OAAO,CAAC,QAAQ,CAAC,MAAM,CAGpB;gBAGgB,SAAS,EAAE,SAAS,EACpB,cAAc,EAAE,cAAc,EAC9B,WAAW,EAAE,UAAU;IAMnC,UAAU,IAAI,OAAO,CAAC,gBAAgB,EAAE,CAAC;IAIhD;;;;;;;OAOG;IACU,YAAY,CAAC,QAAQ,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAMhF;;;OAGG;IACU,iBAAiB,CAAC,QAAQ,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;YASpD,cAAc;IAQ5B;;;;;;OAMG;IACU,UAAU,IAAI,OAAO,CAAC,gBAAgB,GAAG,SAAS,CAAC;IA2BhE,OAAO,CAAC,iBAAiB;IAIZ,kBAAkB,IAAI,OAAO,CAAC,UAAU,EAAE,CAAC;IAW3C,QAAQ,CACnB,SAAS,EAAE,SAAS,EACpB,UAAU,EAAE,UAAU,EACtB,EAAC,OAAO,EAAE,UAAU,EAAC,EAAE,gBAAgB,GACtC,OAAO,CAAC,gBAAgB,CAAC;CA4B7B"}
|
|
@@ -17,15 +17,26 @@
|
|
|
17
17
|
* along with this program. If not, see http://www.gnu.org/licenses/.
|
|
18
18
|
*
|
|
19
19
|
*/
|
|
20
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
21
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
22
|
+
};
|
|
20
23
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
21
24
|
exports.ClientService = void 0;
|
|
22
25
|
const client_1 = require("@wireapp/api-client/lib/client/");
|
|
26
|
+
const axios_1 = __importDefault(require("axios"));
|
|
27
|
+
const http_status_codes_1 = require("http-status-codes");
|
|
28
|
+
const logdown_1 = __importDefault(require("logdown"));
|
|
29
|
+
const identityClearer_1 = require("../identity/identityClearer");
|
|
23
30
|
const _1 = require("./");
|
|
24
31
|
class ClientService {
|
|
25
32
|
constructor(apiClient, proteusService, storeEngine) {
|
|
26
33
|
this.apiClient = apiClient;
|
|
27
34
|
this.proteusService = proteusService;
|
|
28
35
|
this.storeEngine = storeEngine;
|
|
36
|
+
this.logger = (0, logdown_1.default)('@wireapp/core/Client', {
|
|
37
|
+
logger: console,
|
|
38
|
+
markdown: false,
|
|
39
|
+
});
|
|
29
40
|
this.database = new _1.ClientDatabaseRepository(this.storeEngine, this.apiClient.backendFeatures.federationEndpoints);
|
|
30
41
|
this.backend = new _1.ClientBackendRepository(this.apiClient);
|
|
31
42
|
}
|
|
@@ -58,8 +69,47 @@ class ClientService {
|
|
|
58
69
|
await this.backend.deleteClient(localClientId, password);
|
|
59
70
|
return this.database.deleteLocalClient();
|
|
60
71
|
}
|
|
61
|
-
getLocalClient() {
|
|
62
|
-
|
|
72
|
+
async getLocalClient() {
|
|
73
|
+
try {
|
|
74
|
+
return await this.database.getLocalClient();
|
|
75
|
+
}
|
|
76
|
+
catch (error) {
|
|
77
|
+
return undefined;
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
/**
|
|
81
|
+
* Will try to load the local client from the database into memory.
|
|
82
|
+
* Will return undefined if the client is not found in the database or if the client does not exist on the backend.
|
|
83
|
+
* If the client doesn't exist on backend it will purge the database and return undefined.
|
|
84
|
+
*
|
|
85
|
+
* @return the loaded client or undefined
|
|
86
|
+
*/
|
|
87
|
+
async loadClient() {
|
|
88
|
+
var _a;
|
|
89
|
+
const loadedClient = await this.getLocalClient();
|
|
90
|
+
if (!loadedClient) {
|
|
91
|
+
return undefined;
|
|
92
|
+
}
|
|
93
|
+
try {
|
|
94
|
+
await this.apiClient.api.client.getClient(loadedClient.id);
|
|
95
|
+
return loadedClient;
|
|
96
|
+
}
|
|
97
|
+
catch (error) {
|
|
98
|
+
const notFoundOnBackend = axios_1.default.isAxiosError(error) ? ((_a = error.response) === null || _a === void 0 ? void 0 : _a.status) === http_status_codes_1.StatusCodes.NOT_FOUND : false;
|
|
99
|
+
if (notFoundOnBackend && this.storeEngine) {
|
|
100
|
+
this.logger.log('Could not find valid client on backend');
|
|
101
|
+
const shouldDeleteWholeDatabase = loadedClient.type === client_1.ClientType.TEMPORARY;
|
|
102
|
+
if (shouldDeleteWholeDatabase) {
|
|
103
|
+
this.logger.log('Last client was temporary - Deleting database');
|
|
104
|
+
await this.storeEngine.clearTables();
|
|
105
|
+
}
|
|
106
|
+
else {
|
|
107
|
+
this.logger.log('Last client was permanent - Deleting previous identity');
|
|
108
|
+
(0, identityClearer_1.deleteIdentity)(this.storeEngine);
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
return undefined;
|
|
63
113
|
}
|
|
64
114
|
createLocalClient(client, domain) {
|
|
65
115
|
return this.database.createLocalClient(client, domain);
|
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
import type { APIClient } from '@wireapp/api-client/lib/APIClient';
|
|
2
|
-
import type { PreKey } from '@wireapp/api-client/lib/auth';
|
|
2
|
+
import type { PreKey, Context } from '@wireapp/api-client/lib/auth';
|
|
3
3
|
import type { Conversation, OTRRecipients, QualifiedOTRRecipients, QualifiedUserClients, UserClients } from '@wireapp/api-client/lib/conversation';
|
|
4
4
|
import type { QualifiedId, QualifiedUserPreKeyBundleMap, UserPreKeyBundleMap } from '@wireapp/api-client/lib/user';
|
|
5
5
|
import type { CoreCrypto } from '@wireapp/core-crypto';
|
|
6
|
+
import { CRUDEngine } from '@wireapp/store-engine';
|
|
6
7
|
import type { AddUsersToProteusConversationParams, CreateProteusConversationParams, ProteusServiceConfig, SendProteusMessageParams } from './ProteusService.types';
|
|
7
8
|
import { SendResult } from '../../../conversation';
|
|
8
9
|
import { CoreDatabase } from '../../../storage/CoreDB';
|
|
@@ -17,7 +18,7 @@ export declare class ProteusService {
|
|
|
17
18
|
private readonly prekeyGenerator;
|
|
18
19
|
constructor(apiClient: APIClient, coreCryptoClient: CoreCrypto, db: CoreDatabase, config: ProteusServiceConfig);
|
|
19
20
|
handleEvent(params: Pick<EventHandlerParams, 'event' | 'source' | 'dryRun'>): EventHandlerResult;
|
|
20
|
-
|
|
21
|
+
initClient(storeEngine: CRUDEngine, context: Context): Promise<void>;
|
|
21
22
|
createClient(): Promise<import("./ProteusService.types").NewDevicePrekeys>;
|
|
22
23
|
/**
|
|
23
24
|
* Get the fingerprint of the local client.
|
|
@@ -39,6 +40,6 @@ export declare class ProteusService {
|
|
|
39
40
|
encrypt(plainText: Uint8Array, recipients: UserPreKeyBundleMap | UserClients, domain?: string): Promise<OTRRecipients<Uint8Array>>;
|
|
40
41
|
deleteSession(userId: QualifiedId, clientId: string): Promise<void>;
|
|
41
42
|
encryptQualified(plainText: Uint8Array, preKeyBundles: QualifiedUserPreKeyBundleMap | QualifiedUserClients): Promise<QualifiedOTRRecipients>;
|
|
42
|
-
|
|
43
|
+
private migrateToCoreCrypto;
|
|
43
44
|
}
|
|
44
45
|
//# sourceMappingURL=ProteusService.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ProteusService.d.ts","sourceRoot":"","sources":["../../../../src/messagingProtocols/proteus/ProteusService/ProteusService.ts"],"names":[],"mappings":"AAmBA,OAAO,KAAK,EAAC,SAAS,EAAC,MAAM,mCAAmC,CAAC;AACjE,OAAO,KAAK,EAAC,MAAM,EAAC,MAAM,8BAA8B,CAAC;
|
|
1
|
+
{"version":3,"file":"ProteusService.d.ts","sourceRoot":"","sources":["../../../../src/messagingProtocols/proteus/ProteusService/ProteusService.ts"],"names":[],"mappings":"AAmBA,OAAO,KAAK,EAAC,SAAS,EAAC,MAAM,mCAAmC,CAAC;AACjE,OAAO,KAAK,EAAC,MAAM,EAAE,OAAO,EAAC,MAAM,8BAA8B,CAAC;AAClE,OAAO,KAAK,EACV,YAAY,EAEZ,aAAa,EACb,sBAAsB,EACtB,oBAAoB,EACpB,WAAW,EACZ,MAAM,sCAAsC,CAAC;AAC9C,OAAO,KAAK,EAAC,WAAW,EAAE,4BAA4B,EAAE,mBAAmB,EAAC,MAAM,8BAA8B,CAAC;AAGjH,OAAO,KAAK,EAAC,UAAU,EAAC,MAAM,sBAAsB,CAAC;AAErD,OAAO,EAAC,UAAU,EAAC,MAAM,uBAAuB,CAAC;AAIjD,OAAO,KAAK,EACV,mCAAmC,EACnC,+BAA+B,EAC/B,oBAAoB,EACpB,wBAAwB,EACzB,MAAM,wBAAwB,CAAC;AAGhC,OAAO,EAA0C,UAAU,EAAC,MAAM,uBAAuB,CAAC;AAE1F,OAAO,EAAC,YAAY,EAAC,MAAM,yBAAyB,CAAC;AACrD,OAAO,KAAK,EAAC,kBAAkB,EAAC,MAAM,oBAAoB,CAAC;AAC3D,OAAO,EAAC,kBAAkB,EAAqB,MAAM,iBAAiB,CAAC;AAmBvE,qBAAa,cAAc;IAMvB,OAAO,CAAC,QAAQ,CAAC,SAAS;IAC1B,OAAO,CAAC,QAAQ,CAAC,gBAAgB;IAEjC,OAAO,CAAC,QAAQ,CAAC,MAAM;IARzB,OAAO,CAAC,QAAQ,CAAC,cAAc,CAAiB;IAChD,OAAO,CAAC,QAAQ,CAAC,MAAM,CAA2C;IAClE,OAAO,CAAC,QAAQ,CAAC,eAAe,CAAkB;gBAG/B,SAAS,EAAE,SAAS,EACpB,gBAAgB,EAAE,UAAU,EAC7C,EAAE,EAAE,YAAY,EACC,MAAM,EAAE,oBAAoB;IASlC,WAAW,CAAC,MAAM,EAAE,IAAI,CAAC,kBAAkB,EAAE,OAAO,GAAG,QAAQ,GAAG,QAAQ,CAAC,GAAG,kBAAkB;IAiBhG,UAAU,CAAC,WAAW,EAAE,UAAU,EAAE,OAAO,EAAE,OAAO;IAK1D,YAAY;IAInB;;OAEG;IACI,mBAAmB;IAInB,kBAAkB,CAAC,MAAM,EAAE,MAAM,GAAG,WAAW,EAAE,QAAQ,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,MAAM,GAAG,MAAM;IAIlG;;;;;;OAMG;IACU,oBAAoB,CAAC,MAAM,EAAE,WAAW,EAAE,QAAQ,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,MAAM;IAQ3E,kBAAkB,CAAC,EAC9B,gBAAgB,EAChB,YAAY,GACb,EAAE,+BAA+B,GAAG,OAAO,CAAC,YAAY,CAAC;IAiB7C,sBAAsB,CAAC,EAAC,cAAc,EAAE,gBAAgB,EAAC,EAAE,mCAAmC;IAI9F,WAAW,CAAC,EACvB,OAAO,EACP,cAAc,EACd,cAAc,EACd,UAAU,EACV,UAAU,EACV,OAAO,EACP,gBAAgB,GACjB,EAAE,wBAAwB,GAAG,OAAO,CAAC,UAAU,CAAC;YA2CnC,OAAO;IAwBR,OAAO,CAClB,SAAS,EAAE,UAAU,EACrB,UAAU,EAAE,mBAAmB,GAAG,WAAW,EAC7C,MAAM,GAAE,MAAW,GAClB,OAAO,CAAC,aAAa,CAAC,UAAU,CAAC,CAAC;IAc9B,aAAa,CAAC,MAAM,EAAE,WAAW,EAAE,QAAQ,EAAE,MAAM;IAS7C,gBAAgB,CAC3B,SAAS,EAAE,UAAU,EACrB,aAAa,EAAE,4BAA4B,GAAG,oBAAoB,GACjE,OAAO,CAAC,sBAAsB,CAAC;YAWpB,mBAAmB;CA8BlC"}
|
|
@@ -26,12 +26,21 @@ const logdown_1 = __importDefault(require("logdown"));
|
|
|
26
26
|
const protocol_messaging_1 = require("@wireapp/protocol-messaging");
|
|
27
27
|
const DecryptionErrorGenerator_1 = require("./DecryptionErrorGenerator");
|
|
28
28
|
const PrekeysGenerator_1 = require("./PrekeysGenerator");
|
|
29
|
+
const sessionIdMigrator_1 = require("./sessionIdMigrator");
|
|
29
30
|
const conversation_1 = require("../../../conversation");
|
|
30
31
|
const MessageService_1 = require("../../../conversation/message/MessageService");
|
|
31
32
|
const EventHandler_1 = require("../EventHandler");
|
|
32
33
|
const getGenericMessageParams_1 = require("../Utility/getGenericMessageParams");
|
|
33
34
|
const isClearFromMismatch_1 = require("../Utility/isClearFromMismatch");
|
|
34
35
|
const SessionHandler_1 = require("../Utility/SessionHandler");
|
|
36
|
+
function getLocalStorage() {
|
|
37
|
+
try {
|
|
38
|
+
return window.localStorage;
|
|
39
|
+
}
|
|
40
|
+
catch (_a) {
|
|
41
|
+
return { setItem: () => { }, getItem: () => { }, removeItem: () => { } };
|
|
42
|
+
}
|
|
43
|
+
}
|
|
35
44
|
class ProteusService {
|
|
36
45
|
constructor(apiClient, coreCryptoClient, db, config) {
|
|
37
46
|
this.apiClient = apiClient;
|
|
@@ -56,7 +65,8 @@ class ProteusService {
|
|
|
56
65
|
}
|
|
57
66
|
return handledEvent;
|
|
58
67
|
}
|
|
59
|
-
|
|
68
|
+
async initClient(storeEngine, context) {
|
|
69
|
+
await this.migrateToCoreCrypto(storeEngine, context);
|
|
60
70
|
return this.coreCryptoClient.proteusInit();
|
|
61
71
|
}
|
|
62
72
|
createClient() {
|
|
@@ -182,8 +192,34 @@ class ProteusService {
|
|
|
182
192
|
}
|
|
183
193
|
return qualifiedOTRRecipients;
|
|
184
194
|
}
|
|
185
|
-
async
|
|
186
|
-
|
|
195
|
+
async migrateToCoreCrypto(storeEngine, context) {
|
|
196
|
+
var _a;
|
|
197
|
+
const dbName = storeEngine.storeName;
|
|
198
|
+
const migrationFlag = `${dbName}-corecrypto-ready`;
|
|
199
|
+
const localStorage = getLocalStorage();
|
|
200
|
+
if (localStorage.getItem(migrationFlag)) {
|
|
201
|
+
return;
|
|
202
|
+
}
|
|
203
|
+
// We want sessions to be fully qualified from now on
|
|
204
|
+
(0, sessionIdMigrator_1.migrateToQualifiedSessionIds)(storeEngine, (_a = context.domain) !== null && _a !== void 0 ? _a : '');
|
|
205
|
+
this.logger.log(`Migrating data from cryptobox store (${dbName}) to corecrypto.`);
|
|
206
|
+
try {
|
|
207
|
+
await this.coreCryptoClient.proteusCryptoboxMigrate(dbName);
|
|
208
|
+
// We can clear 3 stores (keys - local identity, prekeys and sessions) from wire db.
|
|
209
|
+
// They will be stored in corecrypto database now.
|
|
210
|
+
/* TODO uncomment this code when we are sure migration for wire.com has happened successfully for enough users
|
|
211
|
+
const storesToClear = ['keys', 'prekeys', 'sessions'] as const;
|
|
212
|
+
|
|
213
|
+
for (const storeName of storesToClear) {
|
|
214
|
+
await this.storeEngine?.deleteAll(storeName);
|
|
215
|
+
}
|
|
216
|
+
*/
|
|
217
|
+
this.logger.log(`Successfully migrated from cryptobox store (${dbName}) to corecrypto.`);
|
|
218
|
+
localStorage.setItem(migrationFlag, '1');
|
|
219
|
+
}
|
|
220
|
+
catch (error) {
|
|
221
|
+
this.logger.error('Client was not able to perform DB migration: ', error);
|
|
222
|
+
}
|
|
187
223
|
}
|
|
188
224
|
}
|
|
189
225
|
exports.ProteusService = ProteusService;
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { CRUDEngine } from '@wireapp/store-engine';
|
|
2
|
+
/**
|
|
3
|
+
* Will migrate all the session ids in the database to fully qualified ids (from 'user-id@device-id` to `domain@user-id@device-id`)
|
|
4
|
+
* Will only occur once for an instance of the webapp (a flag is stored in order not to re-do the migration at each loadtime)
|
|
5
|
+
*
|
|
6
|
+
* @param sessionTable The indexedDB table where the sessions are stored
|
|
7
|
+
* @param defaultDomain The domain to add to the unqualified session ids
|
|
8
|
+
*/
|
|
9
|
+
export declare function migrateToQualifiedSessionIds(storeEngine: CRUDEngine, defaultDomain: string): Promise<void>;
|
|
10
|
+
//# sourceMappingURL=sessionIdMigrator.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sessionIdMigrator.d.ts","sourceRoot":"","sources":["../../../../src/messagingProtocols/proteus/ProteusService/sessionIdMigrator.ts"],"names":[],"mappings":"AAmBA,OAAO,EAAC,UAAU,EAAC,MAAM,uBAAuB,CAAC;AAIjD;;;;;;GAMG;AACH,wBAAsB,4BAA4B,CAAC,WAAW,EAAE,UAAU,EAAE,aAAa,EAAE,MAAM,iBAqBhG"}
|
|
@@ -0,0 +1,48 @@
|
|
|
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.migrateToQualifiedSessionIds = void 0;
|
|
22
|
+
const sessionTableName = 'sessions';
|
|
23
|
+
/**
|
|
24
|
+
* Will migrate all the session ids in the database to fully qualified ids (from 'user-id@device-id` to `domain@user-id@device-id`)
|
|
25
|
+
* Will only occur once for an instance of the webapp (a flag is stored in order not to re-do the migration at each loadtime)
|
|
26
|
+
*
|
|
27
|
+
* @param sessionTable The indexedDB table where the sessions are stored
|
|
28
|
+
* @param defaultDomain The domain to add to the unqualified session ids
|
|
29
|
+
*/
|
|
30
|
+
async function migrateToQualifiedSessionIds(storeEngine, defaultDomain) {
|
|
31
|
+
const isFullyQualified = /^[^@]+@[A-F0-9-]+@/i;
|
|
32
|
+
const updatedSessions = (await storeEngine.readAll(sessionTableName))
|
|
33
|
+
.filter(session => !isFullyQualified.test(session.id))
|
|
34
|
+
.reduce((acc, session) => {
|
|
35
|
+
return {
|
|
36
|
+
newSessions: [...acc.newSessions, Object.assign(Object.assign({}, session), { id: `${defaultDomain}@${session.id}` })],
|
|
37
|
+
oldIds: [...acc.oldIds, session.id],
|
|
38
|
+
};
|
|
39
|
+
}, { newSessions: [], oldIds: [] });
|
|
40
|
+
// In order to change primaryKeys, we need to first delete all the record and re-add them with the new key
|
|
41
|
+
for (const oldId of updatedSessions.oldIds) {
|
|
42
|
+
await storeEngine.delete(sessionTableName, oldId);
|
|
43
|
+
}
|
|
44
|
+
for (const newSession of updatedSessions.newSessions) {
|
|
45
|
+
await storeEngine.create(sessionTableName, newSession.id, newSession);
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
exports.migrateToQualifiedSessionIds = migrateToQualifiedSessionIds;
|
|
@@ -41,7 +41,7 @@ export declare class NotificationService extends EventEmitter {
|
|
|
41
41
|
hasHistory(): Promise<boolean>;
|
|
42
42
|
getNotificationEventList(): Promise<BackendEvent[]>;
|
|
43
43
|
setLastEventDate(eventDate: Date): Promise<Date>;
|
|
44
|
-
setLastNotificationId
|
|
44
|
+
private setLastNotificationId;
|
|
45
45
|
processNotificationStream(notificationHandler: NotificationHandler, onMissedNotifications: (notificationId: string) => void, abortHandler: AbortHandler): Promise<{
|
|
46
46
|
total: number;
|
|
47
47
|
error: number;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"NotificationService.d.ts","sourceRoot":"","sources":["../../src/notification/NotificationService.ts"],"names":[],"mappings":";AAmBA,OAAO,EAAC,YAAY,EAAqB,MAAM,+BAA+B,CAAC;AAC/E,OAAO,EAAC,YAAY,EAAC,MAAM,uCAAuC,CAAC;AACnE,OAAO,EAAC,YAAY,EAAC,MAAM,6BAA6B,CAAC;AAGzD,OAAO,EAAC,YAAY,EAAC,MAAM,QAAQ,CAAC;AAEpC,OAAO,EAAC,SAAS,EAAC,MAAM,qBAAqB,CAAC;AAC9C,OAAO,EAAC,cAAc,EAAC,MAAM,6BAA6B,CAAC;AAC3D,OAAO,EAAC,UAAU,EAA4B,MAAM,uBAAuB,CAAC;AAI5E,OAAO,EAAC,kBAAkB,EAAC,MAAM,uBAAuB,CAAC;AAEzD,OAAO,EAAY,iBAAiB,EAAC,MAAM,cAAc,CAAC;AAC1D,OAAO,EAAC,eAAe,EAAC,MAAM,2BAA2B,CAAC;AAC1D,OAAO,EAAC,UAAU,EAAC,MAAM,2BAA2B,CAAC;AACrD,OAAO,EAAC,cAAc,EAAC,MAAM,+BAA+B,CAAC;AAE7D,MAAM,MAAM,mBAAmB,GAAG;IAChC,KAAK,EAAE,YAAY,CAAC;IACpB,aAAa,CAAC,EAAE,cAAc,CAAC;IAC/B,eAAe,CAAC,EAAE,eAAe,CAAC;CACnC,CAAC;AAEF,aAAK,KAAK;IACR,kBAAkB,iDAAiD;CACpE;AAED,MAAM,MAAM,mBAAmB,GAAG,CAChC,YAAY,EAAE,YAAY,EAC1B,MAAM,EAAE,kBAAkB,EAC1B,QAAQ,EAAE;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAC,KACpC,OAAO,CAAC,IAAI,CAAC,CAAC;AAEnB,MAAM,WAAW,mBAAmB;IAClC,EAAE,CAAC,KAAK,EAAE,KAAK,CAAC,kBAAkB,EAAE,QAAQ,EAAE,CAAC,OAAO,EAAE,iBAAiB,KAAK,IAAI,GAAG,IAAI,CAAC;CAC3F;AAED,qBAAa,mBAAoB,SAAQ,YAAY;IAYjD,OAAO,CAAC,QAAQ,CAAC,UAAU;IAC3B,OAAO,CAAC,QAAQ,CAAC,cAAc;IAZjC,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAY;IACtC,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAgC;IACxD,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAiC;IAC1D,OAAO,CAAC,QAAQ,CAAC,MAAM,CAGpB;IACH,gBAAuB,KAAK,eAAS;gBAGnC,SAAS,EAAE,SAAS,EACH,UAAU,EAAE,UAAU,EACtB,cAAc,EAAE,cAAc,EAC/C,WAAW,EAAE,UAAU;YAQX,mBAAmB;IAKjC,0DAA0D;IAC7C,4BAA4B,IAAI,OAAO,CAAC,MAAM,CAAC;IAO/C,UAAU,IAAI,OAAO,CAAC,OAAO,CAAC;IAKpC,wBAAwB,IAAI,OAAO,CAAC,YAAY,EAAE,CAAC;IAI7C,gBAAgB,CAAC,SAAS,EAAE,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC;
|
|
1
|
+
{"version":3,"file":"NotificationService.d.ts","sourceRoot":"","sources":["../../src/notification/NotificationService.ts"],"names":[],"mappings":";AAmBA,OAAO,EAAC,YAAY,EAAqB,MAAM,+BAA+B,CAAC;AAC/E,OAAO,EAAC,YAAY,EAAC,MAAM,uCAAuC,CAAC;AACnE,OAAO,EAAC,YAAY,EAAC,MAAM,6BAA6B,CAAC;AAGzD,OAAO,EAAC,YAAY,EAAC,MAAM,QAAQ,CAAC;AAEpC,OAAO,EAAC,SAAS,EAAC,MAAM,qBAAqB,CAAC;AAC9C,OAAO,EAAC,cAAc,EAAC,MAAM,6BAA6B,CAAC;AAC3D,OAAO,EAAC,UAAU,EAA4B,MAAM,uBAAuB,CAAC;AAI5E,OAAO,EAAC,kBAAkB,EAAC,MAAM,uBAAuB,CAAC;AAEzD,OAAO,EAAY,iBAAiB,EAAC,MAAM,cAAc,CAAC;AAC1D,OAAO,EAAC,eAAe,EAAC,MAAM,2BAA2B,CAAC;AAC1D,OAAO,EAAC,UAAU,EAAC,MAAM,2BAA2B,CAAC;AACrD,OAAO,EAAC,cAAc,EAAC,MAAM,+BAA+B,CAAC;AAE7D,MAAM,MAAM,mBAAmB,GAAG;IAChC,KAAK,EAAE,YAAY,CAAC;IACpB,aAAa,CAAC,EAAE,cAAc,CAAC;IAC/B,eAAe,CAAC,EAAE,eAAe,CAAC;CACnC,CAAC;AAEF,aAAK,KAAK;IACR,kBAAkB,iDAAiD;CACpE;AAED,MAAM,MAAM,mBAAmB,GAAG,CAChC,YAAY,EAAE,YAAY,EAC1B,MAAM,EAAE,kBAAkB,EAC1B,QAAQ,EAAE;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAC,KACpC,OAAO,CAAC,IAAI,CAAC,CAAC;AAEnB,MAAM,WAAW,mBAAmB;IAClC,EAAE,CAAC,KAAK,EAAE,KAAK,CAAC,kBAAkB,EAAE,QAAQ,EAAE,CAAC,OAAO,EAAE,iBAAiB,KAAK,IAAI,GAAG,IAAI,CAAC;CAC3F;AAED,qBAAa,mBAAoB,SAAQ,YAAY;IAYjD,OAAO,CAAC,QAAQ,CAAC,UAAU;IAC3B,OAAO,CAAC,QAAQ,CAAC,cAAc;IAZjC,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAY;IACtC,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAgC;IACxD,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAiC;IAC1D,OAAO,CAAC,QAAQ,CAAC,MAAM,CAGpB;IACH,gBAAuB,KAAK,eAAS;gBAGnC,SAAS,EAAE,SAAS,EACH,UAAU,EAAE,UAAU,EACtB,cAAc,EAAE,cAAc,EAC/C,WAAW,EAAE,UAAU;YAQX,mBAAmB;IAKjC,0DAA0D;IAC7C,4BAA4B,IAAI,OAAO,CAAC,MAAM,CAAC;IAO/C,UAAU,IAAI,OAAO,CAAC,OAAO,CAAC;IAKpC,wBAAwB,IAAI,OAAO,CAAC,YAAY,EAAE,CAAC;IAI7C,gBAAgB,CAAC,SAAS,EAAE,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC;YAsB/C,qBAAqB;IAItB,yBAAyB,CACpC,mBAAmB,EAAE,mBAAmB,EACxC,qBAAqB,EAAE,CAAC,cAAc,EAAE,MAAM,KAAK,IAAI,EACvD,YAAY,EAAE,YAAY,GACzB,OAAO,CAAC;QAAC,KAAK,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAA;KAAC,CAAC;IAoC3D;;;;;;;OAOG;IACH,OAAO,CAAC,eAAe;IAYT,kBAAkB,CAC9B,YAAY,EAAE,YAAY,EAC1B,MAAM,EAAE,kBAAkB,EAC1B,MAAM,GAAE,OAAe,GACtB,cAAc,CAAC,mBAAmB,CAAC;IAmCtC;;;;;;OAMG;YACW,WAAW;CAmC1B"}
|
|
@@ -103,7 +103,9 @@ describe('NotificationService', () => {
|
|
|
103
103
|
jest.spyOn(notificationService, 'handleEvent').mockImplementation(() => {
|
|
104
104
|
throw new Error('Test error');
|
|
105
105
|
});
|
|
106
|
-
const spySetLastNotificationId = jest
|
|
106
|
+
const spySetLastNotificationId = jest
|
|
107
|
+
.spyOn(notificationService, 'setLastNotificationId')
|
|
108
|
+
.mockResolvedValue('');
|
|
107
109
|
const notification = {
|
|
108
110
|
payload: [{}],
|
|
109
111
|
transient: true,
|