@etsoo/appscript 1.1.88 → 1.1.92

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.
@@ -7,7 +7,7 @@ import {
7
7
  NotificationRenderProps
8
8
  } from '@etsoo/notificationbase';
9
9
  import { ApiAuthorizationScheme, createClient } from '@etsoo/restclient';
10
- import { DataTypes, DomUtils, Utils } from '@etsoo/shared';
10
+ import { DataTypes, DomUtils, Utils, WindowStorage } from '@etsoo/shared';
11
11
  import { AddressUtils } from '../../src/address/AddressUtils';
12
12
  import { IAppSettings } from '../../src/app/AppSettings';
13
13
  import { CoreApp } from '../../src/app/CoreApp';
@@ -102,6 +102,7 @@ class CoreAppTest extends CoreApp<IAppSettings, {}, NotificationCallProps> {
102
102
  },
103
103
  createClient(),
104
104
  container,
105
+ new WindowStorage([]),
105
106
  'SmartERP'
106
107
  );
107
108
  }
@@ -1,6 +1,6 @@
1
1
  import { INotifier, NotificationAlign, NotificationCallProps, NotificationContent } from '@etsoo/notificationbase';
2
2
  import { ApiDataError, IApi, IPData } from '@etsoo/restclient';
3
- import { DataTypes, DateUtils } from '@etsoo/shared';
3
+ import { DataTypes, DateUtils, IStorage } from '@etsoo/shared';
4
4
  import { AddressRegion } from '../address/AddressRegion';
5
5
  import { IdLabelDto } from '../dto/IdLabelDto';
6
6
  import { InitCallDto } from '../dto/InitCallDto';
@@ -78,6 +78,10 @@ export interface ICoreApp<S extends IAppSettings, N, C extends NotificationCallP
78
78
  * Country or region, like CN
79
79
  */
80
80
  readonly region: string;
81
+ /**
82
+ * Storage
83
+ */
84
+ readonly storage: IStorage;
81
85
  /**
82
86
  * Is current authorized
83
87
  */
@@ -280,9 +284,8 @@ export interface ICoreApp<S extends IAppSettings, N, C extends NotificationCallP
280
284
  refreshToken<D extends {} = {}>(props?: RefreshTokenProps<D>): Promise<boolean>;
281
285
  /**
282
286
  * Signout
283
- * @param apiUrl Signout API URL
284
287
  */
285
- signout(apiUrl?: string): Promise<void>;
288
+ signout(): Promise<void>;
286
289
  /**
287
290
  * Get organization list
288
291
  * @param items Max items
@@ -292,9 +295,10 @@ export interface ICoreApp<S extends IAppSettings, N, C extends NotificationCallP
292
295
  orgList(items?: number, serviceId?: number): Promise<IdLabelDto[] | undefined>;
293
296
  /**
294
297
  * Switch organization
295
- * @param apiOrOrg API URL or organization id
298
+ * @param id Organization id
299
+ * @param serviceId Service id
296
300
  */
297
- switchOrg(apiOrOrg: string | number): Promise<boolean | undefined>;
301
+ switchOrg(id: number, serviceId?: number): Promise<boolean | undefined>;
298
302
  /**
299
303
  * Go to the login page
300
304
  */
@@ -354,6 +358,10 @@ export declare abstract class CoreApp<S extends IAppSettings, N, C extends Notif
354
358
  * Notifier
355
359
  */
356
360
  readonly notifier: INotifier<N, C>;
361
+ /**
362
+ * Storage
363
+ */
364
+ readonly storage: IStorage;
357
365
  private _culture;
358
366
  /**
359
367
  * Culture, like zh-CN
@@ -374,7 +382,6 @@ export declare abstract class CoreApp<S extends IAppSettings, N, C extends Notif
374
382
  * Country or region, like CN
375
383
  */
376
384
  get deviceId(): string;
377
- protected set deviceId(value: string);
378
385
  /**
379
386
  * Label delegate
380
387
  */
@@ -422,15 +429,11 @@ export declare abstract class CoreApp<S extends IAppSettings, N, C extends Notif
422
429
  /**
423
430
  * Device id field name
424
431
  */
425
- private readonly deviceIdField;
432
+ protected readonly deviceIdField: string;
426
433
  /**
427
434
  * Device passphrase field name
428
435
  */
429
436
  private readonly devicePassphraseField;
430
- /**
431
- * Device id update time field name
432
- */
433
- private readonly deviceIdUpdateTimeField;
434
437
  /**
435
438
  * Init call Api URL
436
439
  */
@@ -445,26 +448,17 @@ export declare abstract class CoreApp<S extends IAppSettings, N, C extends Notif
445
448
  * @param settings Settings
446
449
  * @param api API
447
450
  * @param notifier Notifier
451
+ * @param storage Storage
448
452
  * @param name Application name
449
453
  */
450
- protected constructor(settings: S, api: IApi, notifier: INotifier<N, C>, name: string);
454
+ protected constructor(settings: S, api: IApi, notifier: INotifier<N, C>, storage: IStorage, name: string);
451
455
  protected setApi(api: IApi): void;
452
- /**
453
- * Setup device
454
- * @returns Device id
455
- */
456
- protected setupDevice(): string;
457
456
  /**
458
457
  * Api init call
459
458
  * @param data Data
460
459
  * @returns Result
461
460
  */
462
461
  protected apiInitCall(data: InitCallDto): Promise<InitCallResult | undefined>;
463
- /**
464
- * Get device last updte miliseconds
465
- * @returns Miliseconds
466
- */
467
- protected getDeviceUpdateTime(): number;
468
462
  /**
469
463
  * Init call
470
464
  * @param callback Callback
@@ -478,10 +472,10 @@ export declare abstract class CoreApp<S extends IAppSettings, N, C extends Notif
478
472
  */
479
473
  protected initCallUpdate(data: InitCallResultData, timestamp: number): void;
480
474
  /**
481
- * Init call update fields in local storage
475
+ * Init call encrypted fields update
482
476
  * @returns Fields
483
477
  */
484
- protected initCallUpdateFields(): string[];
478
+ protected initCallEncryptedUpdateFields(): string[];
485
479
  /**
486
480
  * Alert action result
487
481
  * @param result Action result
@@ -678,7 +672,7 @@ export declare abstract class CoreApp<S extends IAppSettings, N, C extends Notif
678
672
  * Signout
679
673
  * @param apiUrl Signout API URL
680
674
  */
681
- signout(apiUrl?: string): Promise<void>;
675
+ signout(): Promise<void>;
682
676
  /**
683
677
  * Get organization list
684
678
  * @param items Max items
@@ -689,8 +683,9 @@ export declare abstract class CoreApp<S extends IAppSettings, N, C extends Notif
689
683
  /**
690
684
  * Switch organization
691
685
  * @param id Organization id
686
+ * @param serviceId Service id
692
687
  */
693
- switchOrg(id: number): Promise<boolean | undefined>;
688
+ switchOrg(id: number, serviceId?: number): Promise<boolean | undefined>;
694
689
  /**
695
690
  * Go to the login page
696
691
  */
@@ -17,10 +17,11 @@ class CoreApp {
17
17
  * @param settings Settings
18
18
  * @param api API
19
19
  * @param notifier Notifier
20
+ * @param storage Storage
20
21
  * @param name Application name
21
22
  */
22
- constructor(settings, api, notifier, name) {
23
- this._deviceId = '';
23
+ constructor(settings, api, notifier, storage, name) {
24
+ var _a;
24
25
  /**
25
26
  * Response token header field name
26
27
  */
@@ -47,10 +48,6 @@ class CoreApp {
47
48
  * Device passphrase field name
48
49
  */
49
50
  this.devicePassphraseField = 'SmartERPDevicePassphrase';
50
- /**
51
- * Device id update time field name
52
- */
53
- this.deviceIdUpdateTimeField = 'SmartERPDeviceIdUpdateTime';
54
51
  /**
55
52
  * Init call Api URL
56
53
  */
@@ -62,8 +59,10 @@ class CoreApp {
62
59
  this.settings = settings;
63
60
  this.api = api;
64
61
  this.notifier = notifier;
62
+ this.storage = storage;
65
63
  this.name = name;
66
- this.deviceId = this.setupDevice();
64
+ // Device id
65
+ this._deviceId = (_a = storage.getData(this.deviceIdField)) !== null && _a !== void 0 ? _a : '';
67
66
  this.setApi(api);
68
67
  const { currentCulture, currentRegion } = settings;
69
68
  this.changeCulture(currentCulture);
@@ -95,9 +94,6 @@ class CoreApp {
95
94
  get deviceId() {
96
95
  return this._deviceId;
97
96
  }
98
- set deviceId(value) {
99
- this._deviceId = value;
100
- }
101
97
  /**
102
98
  * Label delegate
103
99
  */
@@ -161,25 +157,6 @@ class CoreApp {
161
157
  }
162
158
  };
163
159
  }
164
- /**
165
- * Setup device
166
- * @returns Device id
167
- */
168
- setupDevice() {
169
- const deviceId = shared_1.StorageUtils.getLocalData(this.deviceIdField);
170
- if (deviceId != null && deviceId !== '') {
171
- const passphraseEncrypted = shared_1.StorageUtils.getLocalData(this.devicePassphraseField);
172
- if (passphraseEncrypted != null && passphraseEncrypted !== '') {
173
- const timestamp = this.getDeviceUpdateTime();
174
- if (timestamp > 0) {
175
- const passphraseDecrypted = this.decrypt(passphraseEncrypted, timestamp.toString());
176
- if (passphraseDecrypted != null)
177
- this.passphrase = passphraseDecrypted;
178
- }
179
- }
180
- }
181
- return deviceId !== null && deviceId !== void 0 ? deviceId : '';
182
- }
183
160
  /**
184
161
  * Api init call
185
162
  * @param data Data
@@ -188,13 +165,6 @@ class CoreApp {
188
165
  async apiInitCall(data) {
189
166
  return await this.api.put(this.initCallApi, data);
190
167
  }
191
- /**
192
- * Get device last updte miliseconds
193
- * @returns Miliseconds
194
- */
195
- getDeviceUpdateTime() {
196
- return shared_1.StorageUtils.getLocalData(this.deviceIdUpdateTimeField, 0);
197
- }
198
168
  /**
199
169
  * Init call
200
170
  * @param callback Callback
@@ -202,24 +172,27 @@ class CoreApp {
202
172
  */
203
173
  async initCall(callback) {
204
174
  var _a;
205
- // Device
206
- let hasDeviceId = this.deviceId != null && this.deviceId !== '';
207
- const timestamp = new Date().getTime();
208
- const lastTimestamp = this.getDeviceUpdateTime();
209
- if (hasDeviceId &&
210
- lastTimestamp > 0 &&
211
- timestamp - lastTimestamp <= 1296000000) {
212
- // When deviceId is there and less than 15 days = 1000 * 60 * 60 * 24 * 15
213
- if (callback)
214
- callback(true);
215
- return;
175
+ // Passphrase exists?
176
+ // Same session should avoid multiple init calls
177
+ const passphraseEncrypted = this.storage.getData(this.devicePassphraseField);
178
+ if (passphraseEncrypted) {
179
+ const passphraseDecrypted = this.decrypt(passphraseEncrypted, this.name);
180
+ if (passphraseDecrypted != null) {
181
+ this.passphrase = passphraseDecrypted;
182
+ if (callback)
183
+ callback(true);
184
+ return;
185
+ }
216
186
  }
217
187
  // Serverside encrypted device id
218
- const identifier = shared_1.StorageUtils.getLocalData(this.serversideDeviceIdField);
188
+ const identifier = this.storage.getData(this.serversideDeviceIdField);
189
+ // Timestamp
190
+ const timestamp = new Date().getTime();
191
+ // Request data
219
192
  const data = {
220
193
  timestamp,
221
194
  identifier,
222
- deviceId: hasDeviceId ? this.deviceId : undefined
195
+ deviceId: this.deviceId ? this.deviceId : undefined
223
196
  };
224
197
  const result = await this.apiInitCall(data);
225
198
  if (result == null) {
@@ -248,7 +221,7 @@ class CoreApp {
248
221
  if (callback)
249
222
  callback(false);
250
223
  // Clear device id
251
- shared_1.StorageUtils.setLocalData(this.deviceIdField, null);
224
+ this.storage.setData(this.deviceIdField, undefined);
252
225
  return;
253
226
  }
254
227
  this.initCallUpdate(result.data, data.timestamp);
@@ -261,6 +234,7 @@ class CoreApp {
261
234
  * @param timestamp Timestamp
262
235
  */
263
236
  initCallUpdate(data, timestamp) {
237
+ // Data check
264
238
  if (data.deviceId == null || data.passphrase == null)
265
239
  return;
266
240
  // Decrypt
@@ -269,19 +243,18 @@ class CoreApp {
269
243
  if (passphrase == null)
270
244
  return;
271
245
  // Update device id and cache it
272
- this.deviceId = data.deviceId;
273
- shared_1.StorageUtils.setLocalData(this.deviceIdField, this.deviceId);
274
- shared_1.StorageUtils.setLocalData(this.devicePassphraseField, data.passphrase);
275
- shared_1.StorageUtils.setLocalData(this.deviceIdUpdateTimeField, timestamp);
246
+ this._deviceId = data.deviceId;
247
+ this.storage.setData(this.deviceIdField, this.deviceId);
276
248
  // Current passphrase
277
249
  this.passphrase = passphrase;
250
+ this.storage.setData(this.devicePassphraseField, this.encrypt(passphrase, this.name));
278
251
  // Previous passphrase
279
252
  if (data.previousPassphrase) {
280
253
  const prev = this.decrypt(data.previousPassphrase, timestamp.toString());
281
254
  // Update
282
- const fields = this.initCallUpdateFields();
255
+ const fields = this.initCallEncryptedUpdateFields();
283
256
  for (const field of fields) {
284
- const currentValue = shared_1.StorageUtils.getLocalData(field);
257
+ const currentValue = this.storage.getData(field);
285
258
  if (currentValue == null || currentValue === '')
286
259
  continue;
287
260
  const enhanced = currentValue.indexOf('!') >= 8;
@@ -297,15 +270,15 @@ class CoreApp {
297
270
  const newValue = enhanced
298
271
  ? this.encryptEnhanced(newValueSource)
299
272
  : this.encrypt(newValueSource);
300
- shared_1.StorageUtils.setLocalData(field, newValue);
273
+ this.storage.setData(field, newValue);
301
274
  }
302
275
  }
303
276
  }
304
277
  /**
305
- * Init call update fields in local storage
278
+ * Init call encrypted fields update
306
279
  * @returns Fields
307
280
  */
308
- initCallUpdateFields() {
281
+ initCallEncryptedUpdateFields() {
309
282
  return [this.headerTokenField];
310
283
  }
311
284
  /**
@@ -330,7 +303,7 @@ class CoreApp {
330
303
  if (refreshToken !== '') {
331
304
  if (refreshToken != null)
332
305
  refreshToken = this.encrypt(refreshToken);
333
- shared_1.StorageUtils.setLocalData(this.headerTokenField, refreshToken);
306
+ this.storage.setData(this.headerTokenField, refreshToken);
334
307
  }
335
308
  // Reset tryLogin state
336
309
  this._isTryingLogin = false;
@@ -402,18 +375,17 @@ class CoreApp {
402
375
  * Clear cache data
403
376
  */
404
377
  clearCacheData() {
405
- shared_1.StorageUtils.setLocalData(this.serversideDeviceIdField, undefined);
406
- shared_1.StorageUtils.setLocalData(this.deviceIdField, undefined);
407
- shared_1.StorageUtils.setLocalData(this.devicePassphraseField, undefined);
408
- shared_1.StorageUtils.setLocalData(this.deviceIdUpdateTimeField, undefined);
409
- shared_1.StorageUtils.setLocalData(this.headerTokenField, undefined);
378
+ this.storage.setData(this.serversideDeviceIdField, undefined);
379
+ this.storage.setData(this.deviceIdField, undefined);
380
+ this.storage.setData(this.devicePassphraseField, undefined);
381
+ this.storage.setData(this.headerTokenField, undefined);
410
382
  }
411
383
  /**
412
384
  * Clear cached token
413
385
  */
414
386
  clearCacheToken() {
415
387
  this.cachedRefreshToken = undefined;
416
- shared_1.StorageUtils.setLocalData(this.headerTokenField, undefined);
388
+ this.storage.setData(this.headerTokenField, undefined);
417
389
  }
418
390
  /**
419
391
  * Decrypt message
@@ -661,7 +633,7 @@ class CoreApp {
661
633
  // Temp refresh token
662
634
  if (this.cachedRefreshToken)
663
635
  return this.cachedRefreshToken;
664
- return shared_1.StorageUtils.getLocalData(this.headerTokenField);
636
+ return this.storage.getData(this.headerTokenField);
665
637
  }
666
638
  /**
667
639
  * Get all regions
@@ -790,8 +762,8 @@ class CoreApp {
790
762
  * Signout
791
763
  * @param apiUrl Signout API URL
792
764
  */
793
- async signout(apiUrl) {
794
- await this.api.put(apiUrl !== null && apiUrl !== void 0 ? apiUrl : 'User/Signout', undefined, {
765
+ async signout() {
766
+ await this.api.put('User/Signout', { deviceId: this.deviceId }, {
795
767
  onError: (error) => {
796
768
  console.log(error);
797
769
  // Prevent further processing
@@ -818,10 +790,15 @@ class CoreApp {
818
790
  /**
819
791
  * Switch organization
820
792
  * @param id Organization id
793
+ * @param serviceId Service id
821
794
  */
822
- async switchOrg(id) {
823
- const api = `Organization/Switch/${id}`;
824
- const result = await this.api.put(api);
795
+ async switchOrg(id, serviceId) {
796
+ const api = `Organization/Switch`;
797
+ const result = await this.api.put(api, {
798
+ id,
799
+ serviceId,
800
+ deviceId: this.deviceId
801
+ });
825
802
  if (result)
826
803
  return await this.refreshToken();
827
804
  return result;
@@ -874,7 +851,7 @@ class CoreApp {
874
851
  userLogin(user, refreshToken, keep) {
875
852
  this.userData = user;
876
853
  // Cache the encrypted serverside device id
877
- shared_1.StorageUtils.setLocalData(this.serversideDeviceIdField, user.deviceId);
854
+ this.storage.setData(this.serversideDeviceIdField, user.deviceId);
878
855
  if (keep) {
879
856
  this.authorize(user.token, refreshToken);
880
857
  }
@@ -1,6 +1,6 @@
1
1
  import { INotifier, NotificationAlign, NotificationCallProps, NotificationContent } from '@etsoo/notificationbase';
2
2
  import { ApiDataError, IApi, IPData } from '@etsoo/restclient';
3
- import { DataTypes, DateUtils } from '@etsoo/shared';
3
+ import { DataTypes, DateUtils, IStorage } from '@etsoo/shared';
4
4
  import { AddressRegion } from '../address/AddressRegion';
5
5
  import { IdLabelDto } from '../dto/IdLabelDto';
6
6
  import { InitCallDto } from '../dto/InitCallDto';
@@ -78,6 +78,10 @@ export interface ICoreApp<S extends IAppSettings, N, C extends NotificationCallP
78
78
  * Country or region, like CN
79
79
  */
80
80
  readonly region: string;
81
+ /**
82
+ * Storage
83
+ */
84
+ readonly storage: IStorage;
81
85
  /**
82
86
  * Is current authorized
83
87
  */
@@ -280,9 +284,8 @@ export interface ICoreApp<S extends IAppSettings, N, C extends NotificationCallP
280
284
  refreshToken<D extends {} = {}>(props?: RefreshTokenProps<D>): Promise<boolean>;
281
285
  /**
282
286
  * Signout
283
- * @param apiUrl Signout API URL
284
287
  */
285
- signout(apiUrl?: string): Promise<void>;
288
+ signout(): Promise<void>;
286
289
  /**
287
290
  * Get organization list
288
291
  * @param items Max items
@@ -292,9 +295,10 @@ export interface ICoreApp<S extends IAppSettings, N, C extends NotificationCallP
292
295
  orgList(items?: number, serviceId?: number): Promise<IdLabelDto[] | undefined>;
293
296
  /**
294
297
  * Switch organization
295
- * @param apiOrOrg API URL or organization id
298
+ * @param id Organization id
299
+ * @param serviceId Service id
296
300
  */
297
- switchOrg(apiOrOrg: string | number): Promise<boolean | undefined>;
301
+ switchOrg(id: number, serviceId?: number): Promise<boolean | undefined>;
298
302
  /**
299
303
  * Go to the login page
300
304
  */
@@ -354,6 +358,10 @@ export declare abstract class CoreApp<S extends IAppSettings, N, C extends Notif
354
358
  * Notifier
355
359
  */
356
360
  readonly notifier: INotifier<N, C>;
361
+ /**
362
+ * Storage
363
+ */
364
+ readonly storage: IStorage;
357
365
  private _culture;
358
366
  /**
359
367
  * Culture, like zh-CN
@@ -374,7 +382,6 @@ export declare abstract class CoreApp<S extends IAppSettings, N, C extends Notif
374
382
  * Country or region, like CN
375
383
  */
376
384
  get deviceId(): string;
377
- protected set deviceId(value: string);
378
385
  /**
379
386
  * Label delegate
380
387
  */
@@ -422,15 +429,11 @@ export declare abstract class CoreApp<S extends IAppSettings, N, C extends Notif
422
429
  /**
423
430
  * Device id field name
424
431
  */
425
- private readonly deviceIdField;
432
+ protected readonly deviceIdField: string;
426
433
  /**
427
434
  * Device passphrase field name
428
435
  */
429
436
  private readonly devicePassphraseField;
430
- /**
431
- * Device id update time field name
432
- */
433
- private readonly deviceIdUpdateTimeField;
434
437
  /**
435
438
  * Init call Api URL
436
439
  */
@@ -445,26 +448,17 @@ export declare abstract class CoreApp<S extends IAppSettings, N, C extends Notif
445
448
  * @param settings Settings
446
449
  * @param api API
447
450
  * @param notifier Notifier
451
+ * @param storage Storage
448
452
  * @param name Application name
449
453
  */
450
- protected constructor(settings: S, api: IApi, notifier: INotifier<N, C>, name: string);
454
+ protected constructor(settings: S, api: IApi, notifier: INotifier<N, C>, storage: IStorage, name: string);
451
455
  protected setApi(api: IApi): void;
452
- /**
453
- * Setup device
454
- * @returns Device id
455
- */
456
- protected setupDevice(): string;
457
456
  /**
458
457
  * Api init call
459
458
  * @param data Data
460
459
  * @returns Result
461
460
  */
462
461
  protected apiInitCall(data: InitCallDto): Promise<InitCallResult | undefined>;
463
- /**
464
- * Get device last updte miliseconds
465
- * @returns Miliseconds
466
- */
467
- protected getDeviceUpdateTime(): number;
468
462
  /**
469
463
  * Init call
470
464
  * @param callback Callback
@@ -478,10 +472,10 @@ export declare abstract class CoreApp<S extends IAppSettings, N, C extends Notif
478
472
  */
479
473
  protected initCallUpdate(data: InitCallResultData, timestamp: number): void;
480
474
  /**
481
- * Init call update fields in local storage
475
+ * Init call encrypted fields update
482
476
  * @returns Fields
483
477
  */
484
- protected initCallUpdateFields(): string[];
478
+ protected initCallEncryptedUpdateFields(): string[];
485
479
  /**
486
480
  * Alert action result
487
481
  * @param result Action result
@@ -678,7 +672,7 @@ export declare abstract class CoreApp<S extends IAppSettings, N, C extends Notif
678
672
  * Signout
679
673
  * @param apiUrl Signout API URL
680
674
  */
681
- signout(apiUrl?: string): Promise<void>;
675
+ signout(): Promise<void>;
682
676
  /**
683
677
  * Get organization list
684
678
  * @param items Max items
@@ -689,8 +683,9 @@ export declare abstract class CoreApp<S extends IAppSettings, N, C extends Notif
689
683
  /**
690
684
  * Switch organization
691
685
  * @param id Organization id
686
+ * @param serviceId Service id
692
687
  */
693
- switchOrg(id: number): Promise<boolean | undefined>;
688
+ switchOrg(id: number, serviceId?: number): Promise<boolean | undefined>;
694
689
  /**
695
690
  * Go to the login page
696
691
  */
@@ -1,6 +1,6 @@
1
1
  import { NotificationAlign, NotificationMessageType } from '@etsoo/notificationbase';
2
2
  import { ApiDataError } from '@etsoo/restclient';
3
- import { DateUtils, DomUtils, NumberUtils, StorageUtils, Utils } from '@etsoo/shared';
3
+ import { DateUtils, DomUtils, NumberUtils, Utils } from '@etsoo/shared';
4
4
  import { AES, algo, enc, HmacSHA512, lib, mode, pad, PBKDF2, SHA3 } from 'crypto-js';
5
5
  import { AddressRegion } from '../address/AddressRegion';
6
6
  import { AddressUtils } from '../address/AddressUtils';
@@ -14,10 +14,11 @@ export class CoreApp {
14
14
  * @param settings Settings
15
15
  * @param api API
16
16
  * @param notifier Notifier
17
+ * @param storage Storage
17
18
  * @param name Application name
18
19
  */
19
- constructor(settings, api, notifier, name) {
20
- this._deviceId = '';
20
+ constructor(settings, api, notifier, storage, name) {
21
+ var _a;
21
22
  /**
22
23
  * Response token header field name
23
24
  */
@@ -44,10 +45,6 @@ export class CoreApp {
44
45
  * Device passphrase field name
45
46
  */
46
47
  this.devicePassphraseField = 'SmartERPDevicePassphrase';
47
- /**
48
- * Device id update time field name
49
- */
50
- this.deviceIdUpdateTimeField = 'SmartERPDeviceIdUpdateTime';
51
48
  /**
52
49
  * Init call Api URL
53
50
  */
@@ -59,8 +56,10 @@ export class CoreApp {
59
56
  this.settings = settings;
60
57
  this.api = api;
61
58
  this.notifier = notifier;
59
+ this.storage = storage;
62
60
  this.name = name;
63
- this.deviceId = this.setupDevice();
61
+ // Device id
62
+ this._deviceId = (_a = storage.getData(this.deviceIdField)) !== null && _a !== void 0 ? _a : '';
64
63
  this.setApi(api);
65
64
  const { currentCulture, currentRegion } = settings;
66
65
  this.changeCulture(currentCulture);
@@ -92,9 +91,6 @@ export class CoreApp {
92
91
  get deviceId() {
93
92
  return this._deviceId;
94
93
  }
95
- set deviceId(value) {
96
- this._deviceId = value;
97
- }
98
94
  /**
99
95
  * Label delegate
100
96
  */
@@ -158,25 +154,6 @@ export class CoreApp {
158
154
  }
159
155
  };
160
156
  }
161
- /**
162
- * Setup device
163
- * @returns Device id
164
- */
165
- setupDevice() {
166
- const deviceId = StorageUtils.getLocalData(this.deviceIdField);
167
- if (deviceId != null && deviceId !== '') {
168
- const passphraseEncrypted = StorageUtils.getLocalData(this.devicePassphraseField);
169
- if (passphraseEncrypted != null && passphraseEncrypted !== '') {
170
- const timestamp = this.getDeviceUpdateTime();
171
- if (timestamp > 0) {
172
- const passphraseDecrypted = this.decrypt(passphraseEncrypted, timestamp.toString());
173
- if (passphraseDecrypted != null)
174
- this.passphrase = passphraseDecrypted;
175
- }
176
- }
177
- }
178
- return deviceId !== null && deviceId !== void 0 ? deviceId : '';
179
- }
180
157
  /**
181
158
  * Api init call
182
159
  * @param data Data
@@ -185,13 +162,6 @@ export class CoreApp {
185
162
  async apiInitCall(data) {
186
163
  return await this.api.put(this.initCallApi, data);
187
164
  }
188
- /**
189
- * Get device last updte miliseconds
190
- * @returns Miliseconds
191
- */
192
- getDeviceUpdateTime() {
193
- return StorageUtils.getLocalData(this.deviceIdUpdateTimeField, 0);
194
- }
195
165
  /**
196
166
  * Init call
197
167
  * @param callback Callback
@@ -199,24 +169,27 @@ export class CoreApp {
199
169
  */
200
170
  async initCall(callback) {
201
171
  var _a;
202
- // Device
203
- let hasDeviceId = this.deviceId != null && this.deviceId !== '';
204
- const timestamp = new Date().getTime();
205
- const lastTimestamp = this.getDeviceUpdateTime();
206
- if (hasDeviceId &&
207
- lastTimestamp > 0 &&
208
- timestamp - lastTimestamp <= 1296000000) {
209
- // When deviceId is there and less than 15 days = 1000 * 60 * 60 * 24 * 15
210
- if (callback)
211
- callback(true);
212
- return;
172
+ // Passphrase exists?
173
+ // Same session should avoid multiple init calls
174
+ const passphraseEncrypted = this.storage.getData(this.devicePassphraseField);
175
+ if (passphraseEncrypted) {
176
+ const passphraseDecrypted = this.decrypt(passphraseEncrypted, this.name);
177
+ if (passphraseDecrypted != null) {
178
+ this.passphrase = passphraseDecrypted;
179
+ if (callback)
180
+ callback(true);
181
+ return;
182
+ }
213
183
  }
214
184
  // Serverside encrypted device id
215
- const identifier = StorageUtils.getLocalData(this.serversideDeviceIdField);
185
+ const identifier = this.storage.getData(this.serversideDeviceIdField);
186
+ // Timestamp
187
+ const timestamp = new Date().getTime();
188
+ // Request data
216
189
  const data = {
217
190
  timestamp,
218
191
  identifier,
219
- deviceId: hasDeviceId ? this.deviceId : undefined
192
+ deviceId: this.deviceId ? this.deviceId : undefined
220
193
  };
221
194
  const result = await this.apiInitCall(data);
222
195
  if (result == null) {
@@ -245,7 +218,7 @@ export class CoreApp {
245
218
  if (callback)
246
219
  callback(false);
247
220
  // Clear device id
248
- StorageUtils.setLocalData(this.deviceIdField, null);
221
+ this.storage.setData(this.deviceIdField, undefined);
249
222
  return;
250
223
  }
251
224
  this.initCallUpdate(result.data, data.timestamp);
@@ -258,6 +231,7 @@ export class CoreApp {
258
231
  * @param timestamp Timestamp
259
232
  */
260
233
  initCallUpdate(data, timestamp) {
234
+ // Data check
261
235
  if (data.deviceId == null || data.passphrase == null)
262
236
  return;
263
237
  // Decrypt
@@ -266,19 +240,18 @@ export class CoreApp {
266
240
  if (passphrase == null)
267
241
  return;
268
242
  // Update device id and cache it
269
- this.deviceId = data.deviceId;
270
- StorageUtils.setLocalData(this.deviceIdField, this.deviceId);
271
- StorageUtils.setLocalData(this.devicePassphraseField, data.passphrase);
272
- StorageUtils.setLocalData(this.deviceIdUpdateTimeField, timestamp);
243
+ this._deviceId = data.deviceId;
244
+ this.storage.setData(this.deviceIdField, this.deviceId);
273
245
  // Current passphrase
274
246
  this.passphrase = passphrase;
247
+ this.storage.setData(this.devicePassphraseField, this.encrypt(passphrase, this.name));
275
248
  // Previous passphrase
276
249
  if (data.previousPassphrase) {
277
250
  const prev = this.decrypt(data.previousPassphrase, timestamp.toString());
278
251
  // Update
279
- const fields = this.initCallUpdateFields();
252
+ const fields = this.initCallEncryptedUpdateFields();
280
253
  for (const field of fields) {
281
- const currentValue = StorageUtils.getLocalData(field);
254
+ const currentValue = this.storage.getData(field);
282
255
  if (currentValue == null || currentValue === '')
283
256
  continue;
284
257
  const enhanced = currentValue.indexOf('!') >= 8;
@@ -294,15 +267,15 @@ export class CoreApp {
294
267
  const newValue = enhanced
295
268
  ? this.encryptEnhanced(newValueSource)
296
269
  : this.encrypt(newValueSource);
297
- StorageUtils.setLocalData(field, newValue);
270
+ this.storage.setData(field, newValue);
298
271
  }
299
272
  }
300
273
  }
301
274
  /**
302
- * Init call update fields in local storage
275
+ * Init call encrypted fields update
303
276
  * @returns Fields
304
277
  */
305
- initCallUpdateFields() {
278
+ initCallEncryptedUpdateFields() {
306
279
  return [this.headerTokenField];
307
280
  }
308
281
  /**
@@ -327,7 +300,7 @@ export class CoreApp {
327
300
  if (refreshToken !== '') {
328
301
  if (refreshToken != null)
329
302
  refreshToken = this.encrypt(refreshToken);
330
- StorageUtils.setLocalData(this.headerTokenField, refreshToken);
303
+ this.storage.setData(this.headerTokenField, refreshToken);
331
304
  }
332
305
  // Reset tryLogin state
333
306
  this._isTryingLogin = false;
@@ -399,18 +372,17 @@ export class CoreApp {
399
372
  * Clear cache data
400
373
  */
401
374
  clearCacheData() {
402
- StorageUtils.setLocalData(this.serversideDeviceIdField, undefined);
403
- StorageUtils.setLocalData(this.deviceIdField, undefined);
404
- StorageUtils.setLocalData(this.devicePassphraseField, undefined);
405
- StorageUtils.setLocalData(this.deviceIdUpdateTimeField, undefined);
406
- StorageUtils.setLocalData(this.headerTokenField, undefined);
375
+ this.storage.setData(this.serversideDeviceIdField, undefined);
376
+ this.storage.setData(this.deviceIdField, undefined);
377
+ this.storage.setData(this.devicePassphraseField, undefined);
378
+ this.storage.setData(this.headerTokenField, undefined);
407
379
  }
408
380
  /**
409
381
  * Clear cached token
410
382
  */
411
383
  clearCacheToken() {
412
384
  this.cachedRefreshToken = undefined;
413
- StorageUtils.setLocalData(this.headerTokenField, undefined);
385
+ this.storage.setData(this.headerTokenField, undefined);
414
386
  }
415
387
  /**
416
388
  * Decrypt message
@@ -658,7 +630,7 @@ export class CoreApp {
658
630
  // Temp refresh token
659
631
  if (this.cachedRefreshToken)
660
632
  return this.cachedRefreshToken;
661
- return StorageUtils.getLocalData(this.headerTokenField);
633
+ return this.storage.getData(this.headerTokenField);
662
634
  }
663
635
  /**
664
636
  * Get all regions
@@ -787,8 +759,8 @@ export class CoreApp {
787
759
  * Signout
788
760
  * @param apiUrl Signout API URL
789
761
  */
790
- async signout(apiUrl) {
791
- await this.api.put(apiUrl !== null && apiUrl !== void 0 ? apiUrl : 'User/Signout', undefined, {
762
+ async signout() {
763
+ await this.api.put('User/Signout', { deviceId: this.deviceId }, {
792
764
  onError: (error) => {
793
765
  console.log(error);
794
766
  // Prevent further processing
@@ -815,10 +787,15 @@ export class CoreApp {
815
787
  /**
816
788
  * Switch organization
817
789
  * @param id Organization id
790
+ * @param serviceId Service id
818
791
  */
819
- async switchOrg(id) {
820
- const api = `Organization/Switch/${id}`;
821
- const result = await this.api.put(api);
792
+ async switchOrg(id, serviceId) {
793
+ const api = `Organization/Switch`;
794
+ const result = await this.api.put(api, {
795
+ id,
796
+ serviceId,
797
+ deviceId: this.deviceId
798
+ });
822
799
  if (result)
823
800
  return await this.refreshToken();
824
801
  return result;
@@ -871,7 +848,7 @@ export class CoreApp {
871
848
  userLogin(user, refreshToken, keep) {
872
849
  this.userData = user;
873
850
  // Cache the encrypted serverside device id
874
- StorageUtils.setLocalData(this.serversideDeviceIdField, user.deviceId);
851
+ this.storage.setData(this.serversideDeviceIdField, user.deviceId);
875
852
  if (keep) {
876
853
  this.authorize(user.token, refreshToken);
877
854
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@etsoo/appscript",
3
- "version": "1.1.88",
3
+ "version": "1.1.92",
4
4
  "description": "Applications shared TypeScript framework",
5
5
  "main": "lib/cjs/index.js",
6
6
  "module": "lib/mjs/index.js",
@@ -54,7 +54,7 @@
54
54
  "dependencies": {
55
55
  "@etsoo/notificationbase": "^1.0.95",
56
56
  "@etsoo/restclient": "^1.0.63",
57
- "@etsoo/shared": "^1.0.82",
57
+ "@etsoo/shared": "^1.0.83",
58
58
  "@types/crypto-js": "^4.0.2",
59
59
  "crypto-js": "^4.1.1"
60
60
  },
@@ -11,8 +11,8 @@ import {
11
11
  DataTypes,
12
12
  DateUtils,
13
13
  DomUtils,
14
+ IStorage,
14
15
  NumberUtils,
15
- StorageUtils,
16
16
  Utils
17
17
  } from '@etsoo/shared';
18
18
  import {
@@ -128,6 +128,11 @@ export interface ICoreApp<
128
128
  */
129
129
  readonly region: string;
130
130
 
131
+ /**
132
+ * Storage
133
+ */
134
+ readonly storage: IStorage;
135
+
131
136
  /**
132
137
  * Is current authorized
133
138
  */
@@ -384,9 +389,8 @@ export interface ICoreApp<
384
389
 
385
390
  /**
386
391
  * Signout
387
- * @param apiUrl Signout API URL
388
392
  */
389
- signout(apiUrl?: string): Promise<void>;
393
+ signout(): Promise<void>;
390
394
 
391
395
  /**
392
396
  * Get organization list
@@ -401,9 +405,10 @@ export interface ICoreApp<
401
405
 
402
406
  /**
403
407
  * Switch organization
404
- * @param apiOrOrg API URL or organization id
408
+ * @param id Organization id
409
+ * @param serviceId Service id
405
410
  */
406
- switchOrg(apiOrOrg: string | number): Promise<boolean | undefined>;
411
+ switchOrg(id: number, serviceId?: number): Promise<boolean | undefined>;
407
412
 
408
413
  /**
409
414
  * Go to the login page
@@ -480,6 +485,11 @@ export abstract class CoreApp<
480
485
  */
481
486
  readonly notifier: INotifier<N, C>;
482
487
 
488
+ /**
489
+ * Storage
490
+ */
491
+ readonly storage: IStorage;
492
+
483
493
  private _culture!: string;
484
494
  /**
485
495
  * Culture, like zh-CN
@@ -504,16 +514,13 @@ export abstract class CoreApp<
504
514
  return this._region;
505
515
  }
506
516
 
507
- private _deviceId: string = '';
517
+ private _deviceId: string;
508
518
  /**
509
519
  * Country or region, like CN
510
520
  */
511
521
  get deviceId() {
512
522
  return this._deviceId;
513
523
  }
514
- protected set deviceId(value: string) {
515
- this._deviceId = value;
516
- }
517
524
 
518
525
  /**
519
526
  * Label delegate
@@ -589,19 +596,13 @@ export abstract class CoreApp<
589
596
  /**
590
597
  * Device id field name
591
598
  */
592
- private readonly deviceIdField: string = 'SmartERPDeviceId';
599
+ protected readonly deviceIdField: string = 'SmartERPDeviceId';
593
600
 
594
601
  /**
595
602
  * Device passphrase field name
596
603
  */
597
604
  private readonly devicePassphraseField: string = 'SmartERPDevicePassphrase';
598
605
 
599
- /**
600
- * Device id update time field name
601
- */
602
- private readonly deviceIdUpdateTimeField: string =
603
- 'SmartERPDeviceIdUpdateTime';
604
-
605
606
  /**
606
607
  * Init call Api URL
607
608
  */
@@ -619,20 +620,24 @@ export abstract class CoreApp<
619
620
  * @param settings Settings
620
621
  * @param api API
621
622
  * @param notifier Notifier
623
+ * @param storage Storage
622
624
  * @param name Application name
623
625
  */
624
626
  protected constructor(
625
627
  settings: S,
626
628
  api: IApi,
627
629
  notifier: INotifier<N, C>,
630
+ storage: IStorage,
628
631
  name: string
629
632
  ) {
630
633
  this.settings = settings;
631
634
  this.api = api;
632
635
  this.notifier = notifier;
636
+ this.storage = storage;
633
637
  this.name = name;
634
638
 
635
- this.deviceId = this.setupDevice();
639
+ // Device id
640
+ this._deviceId = storage.getData<string>(this.deviceIdField) ?? '';
636
641
 
637
642
  this.setApi(api);
638
643
 
@@ -678,33 +683,6 @@ export abstract class CoreApp<
678
683
  };
679
684
  }
680
685
 
681
- /**
682
- * Setup device
683
- * @returns Device id
684
- */
685
- protected setupDevice() {
686
- const deviceId = StorageUtils.getLocalData<string>(this.deviceIdField);
687
-
688
- if (deviceId != null && deviceId !== '') {
689
- const passphraseEncrypted = StorageUtils.getLocalData<string>(
690
- this.devicePassphraseField
691
- );
692
- if (passphraseEncrypted != null && passphraseEncrypted !== '') {
693
- const timestamp = this.getDeviceUpdateTime();
694
- if (timestamp > 0) {
695
- const passphraseDecrypted = this.decrypt(
696
- passphraseEncrypted,
697
- timestamp.toString()
698
- );
699
- if (passphraseDecrypted != null)
700
- this.passphrase = passphraseDecrypted;
701
- }
702
- }
703
- }
704
-
705
- return deviceId ?? '';
706
- }
707
-
708
686
  /**
709
687
  * Api init call
710
688
  * @param data Data
@@ -714,44 +692,44 @@ export abstract class CoreApp<
714
692
  return await this.api.put<InitCallResult>(this.initCallApi, data);
715
693
  }
716
694
 
717
- /**
718
- * Get device last updte miliseconds
719
- * @returns Miliseconds
720
- */
721
- protected getDeviceUpdateTime() {
722
- return StorageUtils.getLocalData(this.deviceIdUpdateTimeField, 0);
723
- }
724
-
725
695
  /**
726
696
  * Init call
727
697
  * @param callback Callback
728
698
  * @returns Result
729
699
  */
730
700
  async initCall(callback?: (result: boolean) => void) {
731
- // Device
732
- let hasDeviceId = this.deviceId != null && this.deviceId !== '';
733
- const timestamp = new Date().getTime();
734
- const lastTimestamp = this.getDeviceUpdateTime();
735
- if (
736
- hasDeviceId &&
737
- lastTimestamp > 0 &&
738
- timestamp - lastTimestamp <= 1296000000
739
- ) {
740
- // When deviceId is there and less than 15 days = 1000 * 60 * 60 * 24 * 15
741
- if (callback) callback(true);
742
- return;
701
+ // Passphrase exists?
702
+ // Same session should avoid multiple init calls
703
+ const passphraseEncrypted = this.storage.getData<string>(
704
+ this.devicePassphraseField
705
+ );
706
+ if (passphraseEncrypted) {
707
+ const passphraseDecrypted = this.decrypt(
708
+ passphraseEncrypted,
709
+ this.name
710
+ );
711
+ if (passphraseDecrypted != null) {
712
+ this.passphrase = passphraseDecrypted;
713
+ if (callback) callback(true);
714
+ return;
715
+ }
743
716
  }
744
717
 
745
718
  // Serverside encrypted device id
746
- const identifier = StorageUtils.getLocalData<string>(
719
+ const identifier = this.storage.getData<string>(
747
720
  this.serversideDeviceIdField
748
721
  );
749
722
 
723
+ // Timestamp
724
+ const timestamp = new Date().getTime();
725
+
726
+ // Request data
750
727
  const data: InitCallDto = {
751
728
  timestamp,
752
729
  identifier,
753
- deviceId: hasDeviceId ? this.deviceId : undefined
730
+ deviceId: this.deviceId ? this.deviceId : undefined
754
731
  };
732
+
755
733
  const result = await this.apiInitCall(data);
756
734
  if (result == null) {
757
735
  if (callback) callback(false);
@@ -784,7 +762,7 @@ export abstract class CoreApp<
784
762
  if (callback) callback(false);
785
763
 
786
764
  // Clear device id
787
- StorageUtils.setLocalData(this.deviceIdField, null);
765
+ this.storage.setData(this.deviceIdField, undefined);
788
766
 
789
767
  return;
790
768
  }
@@ -800,6 +778,7 @@ export abstract class CoreApp<
800
778
  * @param timestamp Timestamp
801
779
  */
802
780
  protected initCallUpdate(data: InitCallResultData, timestamp: number) {
781
+ // Data check
803
782
  if (data.deviceId == null || data.passphrase == null) return;
804
783
 
805
784
  // Decrypt
@@ -808,13 +787,15 @@ export abstract class CoreApp<
808
787
  if (passphrase == null) return;
809
788
 
810
789
  // Update device id and cache it
811
- this.deviceId = data.deviceId;
812
- StorageUtils.setLocalData(this.deviceIdField, this.deviceId);
813
- StorageUtils.setLocalData(this.devicePassphraseField, data.passphrase);
814
- StorageUtils.setLocalData(this.deviceIdUpdateTimeField, timestamp);
790
+ this._deviceId = data.deviceId;
791
+ this.storage.setData(this.deviceIdField, this.deviceId);
815
792
 
816
793
  // Current passphrase
817
794
  this.passphrase = passphrase;
795
+ this.storage.setData(
796
+ this.devicePassphraseField,
797
+ this.encrypt(passphrase, this.name)
798
+ );
818
799
 
819
800
  // Previous passphrase
820
801
  if (data.previousPassphrase) {
@@ -824,9 +805,9 @@ export abstract class CoreApp<
824
805
  );
825
806
 
826
807
  // Update
827
- const fields = this.initCallUpdateFields();
808
+ const fields = this.initCallEncryptedUpdateFields();
828
809
  for (const field of fields) {
829
- const currentValue = StorageUtils.getLocalData<string>(field);
810
+ const currentValue = this.storage.getData<string>(field);
830
811
  if (currentValue == null || currentValue === '') continue;
831
812
 
832
813
  const enhanced = currentValue.indexOf('!') >= 8;
@@ -848,16 +829,16 @@ export abstract class CoreApp<
848
829
  ? this.encryptEnhanced(newValueSource)
849
830
  : this.encrypt(newValueSource);
850
831
 
851
- StorageUtils.setLocalData(field, newValue);
832
+ this.storage.setData(field, newValue);
852
833
  }
853
834
  }
854
835
  }
855
836
 
856
837
  /**
857
- * Init call update fields in local storage
838
+ * Init call encrypted fields update
858
839
  * @returns Fields
859
840
  */
860
- protected initCallUpdateFields(): string[] {
841
+ protected initCallEncryptedUpdateFields(): string[] {
861
842
  return [this.headerTokenField];
862
843
  }
863
844
 
@@ -885,7 +866,7 @@ export abstract class CoreApp<
885
866
  // Cover the current value
886
867
  if (refreshToken !== '') {
887
868
  if (refreshToken != null) refreshToken = this.encrypt(refreshToken);
888
- StorageUtils.setLocalData(this.headerTokenField, refreshToken);
869
+ this.storage.setData(this.headerTokenField, refreshToken);
889
870
  }
890
871
 
891
872
  // Reset tryLogin state
@@ -972,13 +953,12 @@ export abstract class CoreApp<
972
953
  * Clear cache data
973
954
  */
974
955
  clearCacheData() {
975
- StorageUtils.setLocalData(this.serversideDeviceIdField, undefined);
956
+ this.storage.setData(this.serversideDeviceIdField, undefined);
976
957
 
977
- StorageUtils.setLocalData(this.deviceIdField, undefined);
978
- StorageUtils.setLocalData(this.devicePassphraseField, undefined);
979
- StorageUtils.setLocalData(this.deviceIdUpdateTimeField, undefined);
958
+ this.storage.setData(this.deviceIdField, undefined);
959
+ this.storage.setData(this.devicePassphraseField, undefined);
980
960
 
981
- StorageUtils.setLocalData(this.headerTokenField, undefined);
961
+ this.storage.setData(this.headerTokenField, undefined);
982
962
  }
983
963
 
984
964
  /**
@@ -986,7 +966,7 @@ export abstract class CoreApp<
986
966
  */
987
967
  clearCacheToken() {
988
968
  this.cachedRefreshToken = undefined;
989
- StorageUtils.setLocalData(this.headerTokenField, undefined);
969
+ this.storage.setData(this.headerTokenField, undefined);
990
970
  }
991
971
 
992
972
  /**
@@ -1292,7 +1272,7 @@ export abstract class CoreApp<
1292
1272
  getCacheToken(): string | undefined {
1293
1273
  // Temp refresh token
1294
1274
  if (this.cachedRefreshToken) return this.cachedRefreshToken;
1295
- return StorageUtils.getLocalData<string>(this.headerTokenField);
1275
+ return this.storage.getData<string>(this.headerTokenField);
1296
1276
  }
1297
1277
 
1298
1278
  /**
@@ -1435,14 +1415,18 @@ export abstract class CoreApp<
1435
1415
  * Signout
1436
1416
  * @param apiUrl Signout API URL
1437
1417
  */
1438
- async signout(apiUrl?: string) {
1439
- await this.api.put<boolean>(apiUrl ?? 'User/Signout', undefined, {
1440
- onError: (error) => {
1441
- console.log(error);
1442
- // Prevent further processing
1443
- return false;
1418
+ async signout() {
1419
+ await this.api.put<boolean>(
1420
+ 'User/Signout',
1421
+ { deviceId: this.deviceId },
1422
+ {
1423
+ onError: (error) => {
1424
+ console.log(error);
1425
+ // Prevent further processing
1426
+ return false;
1427
+ }
1444
1428
  }
1445
- });
1429
+ );
1446
1430
 
1447
1431
  // Clear
1448
1432
  this.userLogout();
@@ -1471,10 +1455,15 @@ export abstract class CoreApp<
1471
1455
  /**
1472
1456
  * Switch organization
1473
1457
  * @param id Organization id
1458
+ * @param serviceId Service id
1474
1459
  */
1475
- async switchOrg(id: number) {
1476
- const api = `Organization/Switch/${id}`;
1477
- const result = await this.api.put<boolean>(api);
1460
+ async switchOrg(id: number, serviceId?: number) {
1461
+ const api = `Organization/Switch`;
1462
+ const result = await this.api.put<boolean>(api, {
1463
+ id,
1464
+ serviceId,
1465
+ deviceId: this.deviceId
1466
+ });
1478
1467
  if (result) return await this.refreshToken();
1479
1468
  return result;
1480
1469
  }
@@ -1532,7 +1521,7 @@ export abstract class CoreApp<
1532
1521
  this.userData = user;
1533
1522
 
1534
1523
  // Cache the encrypted serverside device id
1535
- StorageUtils.setLocalData(this.serversideDeviceIdField, user.deviceId);
1524
+ this.storage.setData(this.serversideDeviceIdField, user.deviceId);
1536
1525
 
1537
1526
  if (keep) {
1538
1527
  this.authorize(user.token, refreshToken);