@etsoo/appscript 1.1.90 → 1.1.94

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
  */
@@ -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
  */
@@ -391,14 +398,6 @@ export declare abstract class CoreApp<S extends IAppSettings, N, C extends Notif
391
398
  */
392
399
  get userData(): IUserData | undefined;
393
400
  protected set userData(value: IUserData | undefined);
394
- /**
395
- * Response token header field name
396
- */
397
- readonly headerTokenField = "SmartERPRefreshToken";
398
- /**
399
- * Serverside device id encrypted field name
400
- */
401
- protected readonly serversideDeviceIdField = "SmartERPServersideDeviceId";
402
401
  private ipDetectCallbacks?;
403
402
  /**
404
403
  * Search input element
@@ -419,18 +418,6 @@ export declare abstract class CoreApp<S extends IAppSettings, N, C extends Notif
419
418
  * Token refresh count down seed
420
419
  */
421
420
  protected refreshCountdownSeed: number;
422
- /**
423
- * Device id field name
424
- */
425
- private readonly deviceIdField;
426
- /**
427
- * Device passphrase field name
428
- */
429
- private readonly devicePassphraseField;
430
- /**
431
- * Device id update time field name
432
- */
433
- private readonly deviceIdUpdateTimeField;
434
421
  /**
435
422
  * Init call Api URL
436
423
  */
@@ -445,26 +432,17 @@ export declare abstract class CoreApp<S extends IAppSettings, N, C extends Notif
445
432
  * @param settings Settings
446
433
  * @param api API
447
434
  * @param notifier Notifier
435
+ * @param storage Storage
448
436
  * @param name Application name
449
437
  */
450
- protected constructor(settings: S, api: IApi, notifier: INotifier<N, C>, name: string);
438
+ protected constructor(settings: S, api: IApi, notifier: INotifier<N, C>, storage: IStorage, name: string);
451
439
  protected setApi(api: IApi): void;
452
- /**
453
- * Setup device
454
- * @returns Device id
455
- */
456
- protected setupDevice(): string;
457
440
  /**
458
441
  * Api init call
459
442
  * @param data Data
460
443
  * @returns Result
461
444
  */
462
445
  protected apiInitCall(data: InitCallDto): Promise<InitCallResult | undefined>;
463
- /**
464
- * Get device last updte miliseconds
465
- * @returns Miliseconds
466
- */
467
- protected getDeviceUpdateTime(): number;
468
446
  /**
469
447
  * Init call
470
448
  * @param callback Callback
@@ -478,10 +456,10 @@ export declare abstract class CoreApp<S extends IAppSettings, N, C extends Notif
478
456
  */
479
457
  protected initCallUpdate(data: InitCallResultData, timestamp: number): void;
480
458
  /**
481
- * Init call update fields in local storage
459
+ * Init call encrypted fields update
482
460
  * @returns Fields
483
461
  */
484
- protected initCallUpdateFields(): string[];
462
+ protected initCallEncryptedUpdateFields(): string[];
485
463
  /**
486
464
  * Alert action result
487
465
  * @param result Action result
@@ -732,3 +710,21 @@ export declare abstract class CoreApp<S extends IAppSettings, N, C extends Notif
732
710
  */
733
711
  warning(message: NotificationContent<N>, align?: NotificationAlign): void;
734
712
  }
713
+ export declare namespace CoreApp {
714
+ /**
715
+ * Response token header field name
716
+ */
717
+ const headerTokenField = "SmartERPRefreshToken";
718
+ /**
719
+ * Serverside device id encrypted field name
720
+ */
721
+ const serversideDeviceIdField = "SmartERPServersideDeviceId";
722
+ /**
723
+ * Device id field name
724
+ */
725
+ const deviceIdField = "SmartERPDeviceId";
726
+ /**
727
+ * Device passphrase field name
728
+ */
729
+ const devicePassphraseField = "SmartERPDevicePassphrase";
730
+ }
@@ -17,18 +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 = '';
24
- /**
25
- * Response token header field name
26
- */
27
- this.headerTokenField = 'SmartERPRefreshToken';
28
- /**
29
- * Serverside device id encrypted field name
30
- */
31
- this.serversideDeviceIdField = 'SmartERPServersideDeviceId';
23
+ constructor(settings, api, notifier, storage, name) {
24
+ var _a;
32
25
  this._authorized = false;
33
26
  this._isTryingLogin = false;
34
27
  /**
@@ -39,18 +32,6 @@ class CoreApp {
39
32
  * Token refresh count down seed
40
33
  */
41
34
  this.refreshCountdownSeed = 0;
42
- /**
43
- * Device id field name
44
- */
45
- this.deviceIdField = 'SmartERPDeviceId';
46
- /**
47
- * Device passphrase field name
48
- */
49
- this.devicePassphraseField = 'SmartERPDevicePassphrase';
50
- /**
51
- * Device id update time field name
52
- */
53
- this.deviceIdUpdateTimeField = 'SmartERPDeviceIdUpdateTime';
54
35
  /**
55
36
  * Init call Api URL
56
37
  */
@@ -62,8 +43,10 @@ class CoreApp {
62
43
  this.settings = settings;
63
44
  this.api = api;
64
45
  this.notifier = notifier;
46
+ this.storage = storage;
65
47
  this.name = name;
66
- this.deviceId = this.setupDevice();
48
+ // Device id
49
+ this._deviceId = (_a = storage.getData(CoreApp.deviceIdField)) !== null && _a !== void 0 ? _a : '';
67
50
  this.setApi(api);
68
51
  const { currentCulture, currentRegion } = settings;
69
52
  this.changeCulture(currentCulture);
@@ -95,9 +78,6 @@ class CoreApp {
95
78
  get deviceId() {
96
79
  return this._deviceId;
97
80
  }
98
- set deviceId(value) {
99
- this._deviceId = value;
100
- }
101
81
  /**
102
82
  * Label delegate
103
83
  */
@@ -161,25 +141,6 @@ class CoreApp {
161
141
  }
162
142
  };
163
143
  }
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
144
  /**
184
145
  * Api init call
185
146
  * @param data Data
@@ -188,13 +149,6 @@ class CoreApp {
188
149
  async apiInitCall(data) {
189
150
  return await this.api.put(this.initCallApi, data);
190
151
  }
191
- /**
192
- * Get device last updte miliseconds
193
- * @returns Miliseconds
194
- */
195
- getDeviceUpdateTime() {
196
- return shared_1.StorageUtils.getLocalData(this.deviceIdUpdateTimeField, 0);
197
- }
198
152
  /**
199
153
  * Init call
200
154
  * @param callback Callback
@@ -202,24 +156,27 @@ class CoreApp {
202
156
  */
203
157
  async initCall(callback) {
204
158
  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;
159
+ // Passphrase exists?
160
+ // Same session should avoid multiple init calls
161
+ const passphraseEncrypted = this.storage.getData(CoreApp.devicePassphraseField);
162
+ if (passphraseEncrypted) {
163
+ const passphraseDecrypted = this.decrypt(passphraseEncrypted, this.name);
164
+ if (passphraseDecrypted != null) {
165
+ this.passphrase = passphraseDecrypted;
166
+ if (callback)
167
+ callback(true);
168
+ return;
169
+ }
216
170
  }
217
171
  // Serverside encrypted device id
218
- const identifier = shared_1.StorageUtils.getLocalData(this.serversideDeviceIdField);
172
+ const identifier = this.storage.getData(CoreApp.serversideDeviceIdField);
173
+ // Timestamp
174
+ const timestamp = new Date().getTime();
175
+ // Request data
219
176
  const data = {
220
177
  timestamp,
221
178
  identifier,
222
- deviceId: hasDeviceId ? this.deviceId : undefined
179
+ deviceId: this.deviceId ? this.deviceId : undefined
223
180
  };
224
181
  const result = await this.apiInitCall(data);
225
182
  if (result == null) {
@@ -248,7 +205,7 @@ class CoreApp {
248
205
  if (callback)
249
206
  callback(false);
250
207
  // Clear device id
251
- shared_1.StorageUtils.setLocalData(this.deviceIdField, null);
208
+ this.storage.setData(CoreApp.deviceIdField, undefined);
252
209
  return;
253
210
  }
254
211
  this.initCallUpdate(result.data, data.timestamp);
@@ -261,6 +218,7 @@ class CoreApp {
261
218
  * @param timestamp Timestamp
262
219
  */
263
220
  initCallUpdate(data, timestamp) {
221
+ // Data check
264
222
  if (data.deviceId == null || data.passphrase == null)
265
223
  return;
266
224
  // Decrypt
@@ -269,19 +227,18 @@ class CoreApp {
269
227
  if (passphrase == null)
270
228
  return;
271
229
  // 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);
230
+ this._deviceId = data.deviceId;
231
+ this.storage.setData(CoreApp.deviceIdField, this.deviceId);
276
232
  // Current passphrase
277
233
  this.passphrase = passphrase;
234
+ this.storage.setData(CoreApp.devicePassphraseField, this.encrypt(passphrase, this.name));
278
235
  // Previous passphrase
279
236
  if (data.previousPassphrase) {
280
237
  const prev = this.decrypt(data.previousPassphrase, timestamp.toString());
281
238
  // Update
282
- const fields = this.initCallUpdateFields();
239
+ const fields = this.initCallEncryptedUpdateFields();
283
240
  for (const field of fields) {
284
- const currentValue = shared_1.StorageUtils.getLocalData(field);
241
+ const currentValue = this.storage.getData(field);
285
242
  if (currentValue == null || currentValue === '')
286
243
  continue;
287
244
  const enhanced = currentValue.indexOf('!') >= 8;
@@ -297,16 +254,16 @@ class CoreApp {
297
254
  const newValue = enhanced
298
255
  ? this.encryptEnhanced(newValueSource)
299
256
  : this.encrypt(newValueSource);
300
- shared_1.StorageUtils.setLocalData(field, newValue);
257
+ this.storage.setData(field, newValue);
301
258
  }
302
259
  }
303
260
  }
304
261
  /**
305
- * Init call update fields in local storage
262
+ * Init call encrypted fields update
306
263
  * @returns Fields
307
264
  */
308
- initCallUpdateFields() {
309
- return [this.headerTokenField];
265
+ initCallEncryptedUpdateFields() {
266
+ return [CoreApp.headerTokenField];
310
267
  }
311
268
  /**
312
269
  * Alert action result
@@ -330,7 +287,7 @@ class CoreApp {
330
287
  if (refreshToken !== '') {
331
288
  if (refreshToken != null)
332
289
  refreshToken = this.encrypt(refreshToken);
333
- shared_1.StorageUtils.setLocalData(this.headerTokenField, refreshToken);
290
+ this.storage.setData(CoreApp.headerTokenField, refreshToken);
334
291
  }
335
292
  // Reset tryLogin state
336
293
  this._isTryingLogin = false;
@@ -365,7 +322,7 @@ class CoreApp {
365
322
  if (regionItem == null || !this.settings.regions.includes(regionId))
366
323
  return;
367
324
  // Save the id to local storage
368
- shared_1.DomUtils.saveCountry(regionId);
325
+ this.storage.setData(shared_1.DomUtils.CountryField, regionId);
369
326
  // Set the currency and culture
370
327
  this._currency = regionItem.currency;
371
328
  this._region = regionId;
@@ -383,7 +340,7 @@ class CoreApp {
383
340
  if (this._culture === name)
384
341
  return;
385
342
  // Save the cultrue to local storage
386
- shared_1.DomUtils.saveCulture(name);
343
+ this.storage.setData(shared_1.DomUtils.CultureField, name);
387
344
  // Change the API's Content-Language header
388
345
  // .net 5 API, UseRequestLocalization, RequestCultureProviders, ContentLanguageHeaderRequestCultureProvider
389
346
  this.api.setContentLanguage(name);
@@ -402,18 +359,17 @@ class CoreApp {
402
359
  * Clear cache data
403
360
  */
404
361
  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);
362
+ this.storage.setData(CoreApp.serversideDeviceIdField, undefined);
363
+ this.storage.setData(CoreApp.deviceIdField, undefined);
364
+ this.storage.setData(CoreApp.devicePassphraseField, undefined);
365
+ this.storage.setData(CoreApp.headerTokenField, undefined);
410
366
  }
411
367
  /**
412
368
  * Clear cached token
413
369
  */
414
370
  clearCacheToken() {
415
371
  this.cachedRefreshToken = undefined;
416
- shared_1.StorageUtils.setLocalData(this.headerTokenField, undefined);
372
+ this.storage.setData(CoreApp.headerTokenField, undefined);
417
373
  }
418
374
  /**
419
375
  * Decrypt message
@@ -661,7 +617,7 @@ class CoreApp {
661
617
  // Temp refresh token
662
618
  if (this.cachedRefreshToken)
663
619
  return this.cachedRefreshToken;
664
- return shared_1.StorageUtils.getLocalData(this.headerTokenField);
620
+ return this.storage.getData(CoreApp.headerTokenField);
665
621
  }
666
622
  /**
667
623
  * Get all regions
@@ -679,7 +635,7 @@ class CoreApp {
679
635
  */
680
636
  getResponseToken(rawResponse) {
681
637
  const response = this.api.transformResponse(rawResponse);
682
- return this.api.getHeaderValue(response.headers, this.headerTokenField);
638
+ return this.api.getHeaderValue(response.headers, CoreApp.headerTokenField);
683
639
  }
684
640
  /**
685
641
  * Get time zone
@@ -822,7 +778,11 @@ class CoreApp {
822
778
  */
823
779
  async switchOrg(id, serviceId) {
824
780
  const api = `Organization/Switch`;
825
- const result = await this.api.put(api, { id, serviceId });
781
+ const result = await this.api.put(api, {
782
+ id,
783
+ serviceId,
784
+ deviceId: this.deviceId
785
+ });
826
786
  if (result)
827
787
  return await this.refreshToken();
828
788
  return result;
@@ -875,7 +835,7 @@ class CoreApp {
875
835
  userLogin(user, refreshToken, keep) {
876
836
  this.userData = user;
877
837
  // Cache the encrypted serverside device id
878
- shared_1.StorageUtils.setLocalData(this.serversideDeviceIdField, user.deviceId);
838
+ this.storage.setData(CoreApp.serversideDeviceIdField, user.deviceId);
879
839
  if (keep) {
880
840
  this.authorize(user.token, refreshToken);
881
841
  }
@@ -913,3 +873,21 @@ class CoreApp {
913
873
  }
914
874
  }
915
875
  exports.CoreApp = CoreApp;
876
+ (function (CoreApp) {
877
+ /**
878
+ * Response token header field name
879
+ */
880
+ CoreApp.headerTokenField = 'SmartERPRefreshToken';
881
+ /**
882
+ * Serverside device id encrypted field name
883
+ */
884
+ CoreApp.serversideDeviceIdField = 'SmartERPServersideDeviceId';
885
+ /**
886
+ * Device id field name
887
+ */
888
+ CoreApp.deviceIdField = 'SmartERPDeviceId';
889
+ /**
890
+ * Device passphrase field name
891
+ */
892
+ CoreApp.devicePassphraseField = 'SmartERPDevicePassphrase';
893
+ })(CoreApp = exports.CoreApp || (exports.CoreApp = {}));
@@ -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
  */
@@ -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
  */
@@ -391,14 +398,6 @@ export declare abstract class CoreApp<S extends IAppSettings, N, C extends Notif
391
398
  */
392
399
  get userData(): IUserData | undefined;
393
400
  protected set userData(value: IUserData | undefined);
394
- /**
395
- * Response token header field name
396
- */
397
- readonly headerTokenField = "SmartERPRefreshToken";
398
- /**
399
- * Serverside device id encrypted field name
400
- */
401
- protected readonly serversideDeviceIdField = "SmartERPServersideDeviceId";
402
401
  private ipDetectCallbacks?;
403
402
  /**
404
403
  * Search input element
@@ -419,18 +418,6 @@ export declare abstract class CoreApp<S extends IAppSettings, N, C extends Notif
419
418
  * Token refresh count down seed
420
419
  */
421
420
  protected refreshCountdownSeed: number;
422
- /**
423
- * Device id field name
424
- */
425
- private readonly deviceIdField;
426
- /**
427
- * Device passphrase field name
428
- */
429
- private readonly devicePassphraseField;
430
- /**
431
- * Device id update time field name
432
- */
433
- private readonly deviceIdUpdateTimeField;
434
421
  /**
435
422
  * Init call Api URL
436
423
  */
@@ -445,26 +432,17 @@ export declare abstract class CoreApp<S extends IAppSettings, N, C extends Notif
445
432
  * @param settings Settings
446
433
  * @param api API
447
434
  * @param notifier Notifier
435
+ * @param storage Storage
448
436
  * @param name Application name
449
437
  */
450
- protected constructor(settings: S, api: IApi, notifier: INotifier<N, C>, name: string);
438
+ protected constructor(settings: S, api: IApi, notifier: INotifier<N, C>, storage: IStorage, name: string);
451
439
  protected setApi(api: IApi): void;
452
- /**
453
- * Setup device
454
- * @returns Device id
455
- */
456
- protected setupDevice(): string;
457
440
  /**
458
441
  * Api init call
459
442
  * @param data Data
460
443
  * @returns Result
461
444
  */
462
445
  protected apiInitCall(data: InitCallDto): Promise<InitCallResult | undefined>;
463
- /**
464
- * Get device last updte miliseconds
465
- * @returns Miliseconds
466
- */
467
- protected getDeviceUpdateTime(): number;
468
446
  /**
469
447
  * Init call
470
448
  * @param callback Callback
@@ -478,10 +456,10 @@ export declare abstract class CoreApp<S extends IAppSettings, N, C extends Notif
478
456
  */
479
457
  protected initCallUpdate(data: InitCallResultData, timestamp: number): void;
480
458
  /**
481
- * Init call update fields in local storage
459
+ * Init call encrypted fields update
482
460
  * @returns Fields
483
461
  */
484
- protected initCallUpdateFields(): string[];
462
+ protected initCallEncryptedUpdateFields(): string[];
485
463
  /**
486
464
  * Alert action result
487
465
  * @param result Action result
@@ -732,3 +710,21 @@ export declare abstract class CoreApp<S extends IAppSettings, N, C extends Notif
732
710
  */
733
711
  warning(message: NotificationContent<N>, align?: NotificationAlign): void;
734
712
  }
713
+ export declare namespace CoreApp {
714
+ /**
715
+ * Response token header field name
716
+ */
717
+ const headerTokenField = "SmartERPRefreshToken";
718
+ /**
719
+ * Serverside device id encrypted field name
720
+ */
721
+ const serversideDeviceIdField = "SmartERPServersideDeviceId";
722
+ /**
723
+ * Device id field name
724
+ */
725
+ const deviceIdField = "SmartERPDeviceId";
726
+ /**
727
+ * Device passphrase field name
728
+ */
729
+ const devicePassphraseField = "SmartERPDevicePassphrase";
730
+ }
@@ -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,18 +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 = '';
21
- /**
22
- * Response token header field name
23
- */
24
- this.headerTokenField = 'SmartERPRefreshToken';
25
- /**
26
- * Serverside device id encrypted field name
27
- */
28
- this.serversideDeviceIdField = 'SmartERPServersideDeviceId';
20
+ constructor(settings, api, notifier, storage, name) {
21
+ var _a;
29
22
  this._authorized = false;
30
23
  this._isTryingLogin = false;
31
24
  /**
@@ -36,18 +29,6 @@ export class CoreApp {
36
29
  * Token refresh count down seed
37
30
  */
38
31
  this.refreshCountdownSeed = 0;
39
- /**
40
- * Device id field name
41
- */
42
- this.deviceIdField = 'SmartERPDeviceId';
43
- /**
44
- * Device passphrase field name
45
- */
46
- this.devicePassphraseField = 'SmartERPDevicePassphrase';
47
- /**
48
- * Device id update time field name
49
- */
50
- this.deviceIdUpdateTimeField = 'SmartERPDeviceIdUpdateTime';
51
32
  /**
52
33
  * Init call Api URL
53
34
  */
@@ -59,8 +40,10 @@ export class CoreApp {
59
40
  this.settings = settings;
60
41
  this.api = api;
61
42
  this.notifier = notifier;
43
+ this.storage = storage;
62
44
  this.name = name;
63
- this.deviceId = this.setupDevice();
45
+ // Device id
46
+ this._deviceId = (_a = storage.getData(CoreApp.deviceIdField)) !== null && _a !== void 0 ? _a : '';
64
47
  this.setApi(api);
65
48
  const { currentCulture, currentRegion } = settings;
66
49
  this.changeCulture(currentCulture);
@@ -92,9 +75,6 @@ export class CoreApp {
92
75
  get deviceId() {
93
76
  return this._deviceId;
94
77
  }
95
- set deviceId(value) {
96
- this._deviceId = value;
97
- }
98
78
  /**
99
79
  * Label delegate
100
80
  */
@@ -158,25 +138,6 @@ export class CoreApp {
158
138
  }
159
139
  };
160
140
  }
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
141
  /**
181
142
  * Api init call
182
143
  * @param data Data
@@ -185,13 +146,6 @@ export class CoreApp {
185
146
  async apiInitCall(data) {
186
147
  return await this.api.put(this.initCallApi, data);
187
148
  }
188
- /**
189
- * Get device last updte miliseconds
190
- * @returns Miliseconds
191
- */
192
- getDeviceUpdateTime() {
193
- return StorageUtils.getLocalData(this.deviceIdUpdateTimeField, 0);
194
- }
195
149
  /**
196
150
  * Init call
197
151
  * @param callback Callback
@@ -199,24 +153,27 @@ export class CoreApp {
199
153
  */
200
154
  async initCall(callback) {
201
155
  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;
156
+ // Passphrase exists?
157
+ // Same session should avoid multiple init calls
158
+ const passphraseEncrypted = this.storage.getData(CoreApp.devicePassphraseField);
159
+ if (passphraseEncrypted) {
160
+ const passphraseDecrypted = this.decrypt(passphraseEncrypted, this.name);
161
+ if (passphraseDecrypted != null) {
162
+ this.passphrase = passphraseDecrypted;
163
+ if (callback)
164
+ callback(true);
165
+ return;
166
+ }
213
167
  }
214
168
  // Serverside encrypted device id
215
- const identifier = StorageUtils.getLocalData(this.serversideDeviceIdField);
169
+ const identifier = this.storage.getData(CoreApp.serversideDeviceIdField);
170
+ // Timestamp
171
+ const timestamp = new Date().getTime();
172
+ // Request data
216
173
  const data = {
217
174
  timestamp,
218
175
  identifier,
219
- deviceId: hasDeviceId ? this.deviceId : undefined
176
+ deviceId: this.deviceId ? this.deviceId : undefined
220
177
  };
221
178
  const result = await this.apiInitCall(data);
222
179
  if (result == null) {
@@ -245,7 +202,7 @@ export class CoreApp {
245
202
  if (callback)
246
203
  callback(false);
247
204
  // Clear device id
248
- StorageUtils.setLocalData(this.deviceIdField, null);
205
+ this.storage.setData(CoreApp.deviceIdField, undefined);
249
206
  return;
250
207
  }
251
208
  this.initCallUpdate(result.data, data.timestamp);
@@ -258,6 +215,7 @@ export class CoreApp {
258
215
  * @param timestamp Timestamp
259
216
  */
260
217
  initCallUpdate(data, timestamp) {
218
+ // Data check
261
219
  if (data.deviceId == null || data.passphrase == null)
262
220
  return;
263
221
  // Decrypt
@@ -266,19 +224,18 @@ export class CoreApp {
266
224
  if (passphrase == null)
267
225
  return;
268
226
  // 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);
227
+ this._deviceId = data.deviceId;
228
+ this.storage.setData(CoreApp.deviceIdField, this.deviceId);
273
229
  // Current passphrase
274
230
  this.passphrase = passphrase;
231
+ this.storage.setData(CoreApp.devicePassphraseField, this.encrypt(passphrase, this.name));
275
232
  // Previous passphrase
276
233
  if (data.previousPassphrase) {
277
234
  const prev = this.decrypt(data.previousPassphrase, timestamp.toString());
278
235
  // Update
279
- const fields = this.initCallUpdateFields();
236
+ const fields = this.initCallEncryptedUpdateFields();
280
237
  for (const field of fields) {
281
- const currentValue = StorageUtils.getLocalData(field);
238
+ const currentValue = this.storage.getData(field);
282
239
  if (currentValue == null || currentValue === '')
283
240
  continue;
284
241
  const enhanced = currentValue.indexOf('!') >= 8;
@@ -294,16 +251,16 @@ export class CoreApp {
294
251
  const newValue = enhanced
295
252
  ? this.encryptEnhanced(newValueSource)
296
253
  : this.encrypt(newValueSource);
297
- StorageUtils.setLocalData(field, newValue);
254
+ this.storage.setData(field, newValue);
298
255
  }
299
256
  }
300
257
  }
301
258
  /**
302
- * Init call update fields in local storage
259
+ * Init call encrypted fields update
303
260
  * @returns Fields
304
261
  */
305
- initCallUpdateFields() {
306
- return [this.headerTokenField];
262
+ initCallEncryptedUpdateFields() {
263
+ return [CoreApp.headerTokenField];
307
264
  }
308
265
  /**
309
266
  * Alert action result
@@ -327,7 +284,7 @@ export class CoreApp {
327
284
  if (refreshToken !== '') {
328
285
  if (refreshToken != null)
329
286
  refreshToken = this.encrypt(refreshToken);
330
- StorageUtils.setLocalData(this.headerTokenField, refreshToken);
287
+ this.storage.setData(CoreApp.headerTokenField, refreshToken);
331
288
  }
332
289
  // Reset tryLogin state
333
290
  this._isTryingLogin = false;
@@ -362,7 +319,7 @@ export class CoreApp {
362
319
  if (regionItem == null || !this.settings.regions.includes(regionId))
363
320
  return;
364
321
  // Save the id to local storage
365
- DomUtils.saveCountry(regionId);
322
+ this.storage.setData(DomUtils.CountryField, regionId);
366
323
  // Set the currency and culture
367
324
  this._currency = regionItem.currency;
368
325
  this._region = regionId;
@@ -380,7 +337,7 @@ export class CoreApp {
380
337
  if (this._culture === name)
381
338
  return;
382
339
  // Save the cultrue to local storage
383
- DomUtils.saveCulture(name);
340
+ this.storage.setData(DomUtils.CultureField, name);
384
341
  // Change the API's Content-Language header
385
342
  // .net 5 API, UseRequestLocalization, RequestCultureProviders, ContentLanguageHeaderRequestCultureProvider
386
343
  this.api.setContentLanguage(name);
@@ -399,18 +356,17 @@ export class CoreApp {
399
356
  * Clear cache data
400
357
  */
401
358
  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);
359
+ this.storage.setData(CoreApp.serversideDeviceIdField, undefined);
360
+ this.storage.setData(CoreApp.deviceIdField, undefined);
361
+ this.storage.setData(CoreApp.devicePassphraseField, undefined);
362
+ this.storage.setData(CoreApp.headerTokenField, undefined);
407
363
  }
408
364
  /**
409
365
  * Clear cached token
410
366
  */
411
367
  clearCacheToken() {
412
368
  this.cachedRefreshToken = undefined;
413
- StorageUtils.setLocalData(this.headerTokenField, undefined);
369
+ this.storage.setData(CoreApp.headerTokenField, undefined);
414
370
  }
415
371
  /**
416
372
  * Decrypt message
@@ -658,7 +614,7 @@ export class CoreApp {
658
614
  // Temp refresh token
659
615
  if (this.cachedRefreshToken)
660
616
  return this.cachedRefreshToken;
661
- return StorageUtils.getLocalData(this.headerTokenField);
617
+ return this.storage.getData(CoreApp.headerTokenField);
662
618
  }
663
619
  /**
664
620
  * Get all regions
@@ -676,7 +632,7 @@ export class CoreApp {
676
632
  */
677
633
  getResponseToken(rawResponse) {
678
634
  const response = this.api.transformResponse(rawResponse);
679
- return this.api.getHeaderValue(response.headers, this.headerTokenField);
635
+ return this.api.getHeaderValue(response.headers, CoreApp.headerTokenField);
680
636
  }
681
637
  /**
682
638
  * Get time zone
@@ -819,7 +775,11 @@ export class CoreApp {
819
775
  */
820
776
  async switchOrg(id, serviceId) {
821
777
  const api = `Organization/Switch`;
822
- const result = await this.api.put(api, { id, serviceId });
778
+ const result = await this.api.put(api, {
779
+ id,
780
+ serviceId,
781
+ deviceId: this.deviceId
782
+ });
823
783
  if (result)
824
784
  return await this.refreshToken();
825
785
  return result;
@@ -872,7 +832,7 @@ export class CoreApp {
872
832
  userLogin(user, refreshToken, keep) {
873
833
  this.userData = user;
874
834
  // Cache the encrypted serverside device id
875
- StorageUtils.setLocalData(this.serversideDeviceIdField, user.deviceId);
835
+ this.storage.setData(CoreApp.serversideDeviceIdField, user.deviceId);
876
836
  if (keep) {
877
837
  this.authorize(user.token, refreshToken);
878
838
  }
@@ -909,3 +869,21 @@ export class CoreApp {
909
869
  });
910
870
  }
911
871
  }
872
+ (function (CoreApp) {
873
+ /**
874
+ * Response token header field name
875
+ */
876
+ CoreApp.headerTokenField = 'SmartERPRefreshToken';
877
+ /**
878
+ * Serverside device id encrypted field name
879
+ */
880
+ CoreApp.serversideDeviceIdField = 'SmartERPServersideDeviceId';
881
+ /**
882
+ * Device id field name
883
+ */
884
+ CoreApp.deviceIdField = 'SmartERPDeviceId';
885
+ /**
886
+ * Device passphrase field name
887
+ */
888
+ CoreApp.devicePassphraseField = 'SmartERPDevicePassphrase';
889
+ })(CoreApp || (CoreApp = {}));
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@etsoo/appscript",
3
- "version": "1.1.90",
3
+ "version": "1.1.94",
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.84",
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
  */
@@ -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
@@ -544,16 +551,6 @@ export abstract class CoreApp<
544
551
  this._userData = value;
545
552
  }
546
553
 
547
- /**
548
- * Response token header field name
549
- */
550
- readonly headerTokenField = 'SmartERPRefreshToken';
551
-
552
- /**
553
- * Serverside device id encrypted field name
554
- */
555
- protected readonly serversideDeviceIdField = 'SmartERPServersideDeviceId';
556
-
557
554
  // IP detect ready callbacks
558
555
  private ipDetectCallbacks?: IDetectIPCallback[];
559
556
 
@@ -586,22 +583,6 @@ export abstract class CoreApp<
586
583
  */
587
584
  protected refreshCountdownSeed = 0;
588
585
 
589
- /**
590
- * Device id field name
591
- */
592
- private readonly deviceIdField: string = 'SmartERPDeviceId';
593
-
594
- /**
595
- * Device passphrase field name
596
- */
597
- private readonly devicePassphraseField: string = 'SmartERPDevicePassphrase';
598
-
599
- /**
600
- * Device id update time field name
601
- */
602
- private readonly deviceIdUpdateTimeField: string =
603
- 'SmartERPDeviceIdUpdateTime';
604
-
605
586
  /**
606
587
  * Init call Api URL
607
588
  */
@@ -619,20 +600,24 @@ export abstract class CoreApp<
619
600
  * @param settings Settings
620
601
  * @param api API
621
602
  * @param notifier Notifier
603
+ * @param storage Storage
622
604
  * @param name Application name
623
605
  */
624
606
  protected constructor(
625
607
  settings: S,
626
608
  api: IApi,
627
609
  notifier: INotifier<N, C>,
610
+ storage: IStorage,
628
611
  name: string
629
612
  ) {
630
613
  this.settings = settings;
631
614
  this.api = api;
632
615
  this.notifier = notifier;
616
+ this.storage = storage;
633
617
  this.name = name;
634
618
 
635
- this.deviceId = this.setupDevice();
619
+ // Device id
620
+ this._deviceId = storage.getData<string>(CoreApp.deviceIdField) ?? '';
636
621
 
637
622
  this.setApi(api);
638
623
 
@@ -678,33 +663,6 @@ export abstract class CoreApp<
678
663
  };
679
664
  }
680
665
 
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
666
  /**
709
667
  * Api init call
710
668
  * @param data Data
@@ -714,44 +672,44 @@ export abstract class CoreApp<
714
672
  return await this.api.put<InitCallResult>(this.initCallApi, data);
715
673
  }
716
674
 
717
- /**
718
- * Get device last updte miliseconds
719
- * @returns Miliseconds
720
- */
721
- protected getDeviceUpdateTime() {
722
- return StorageUtils.getLocalData(this.deviceIdUpdateTimeField, 0);
723
- }
724
-
725
675
  /**
726
676
  * Init call
727
677
  * @param callback Callback
728
678
  * @returns Result
729
679
  */
730
680
  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;
681
+ // Passphrase exists?
682
+ // Same session should avoid multiple init calls
683
+ const passphraseEncrypted = this.storage.getData<string>(
684
+ CoreApp.devicePassphraseField
685
+ );
686
+ if (passphraseEncrypted) {
687
+ const passphraseDecrypted = this.decrypt(
688
+ passphraseEncrypted,
689
+ this.name
690
+ );
691
+ if (passphraseDecrypted != null) {
692
+ this.passphrase = passphraseDecrypted;
693
+ if (callback) callback(true);
694
+ return;
695
+ }
743
696
  }
744
697
 
745
698
  // Serverside encrypted device id
746
- const identifier = StorageUtils.getLocalData<string>(
747
- this.serversideDeviceIdField
699
+ const identifier = this.storage.getData<string>(
700
+ CoreApp.serversideDeviceIdField
748
701
  );
749
702
 
703
+ // Timestamp
704
+ const timestamp = new Date().getTime();
705
+
706
+ // Request data
750
707
  const data: InitCallDto = {
751
708
  timestamp,
752
709
  identifier,
753
- deviceId: hasDeviceId ? this.deviceId : undefined
710
+ deviceId: this.deviceId ? this.deviceId : undefined
754
711
  };
712
+
755
713
  const result = await this.apiInitCall(data);
756
714
  if (result == null) {
757
715
  if (callback) callback(false);
@@ -784,7 +742,7 @@ export abstract class CoreApp<
784
742
  if (callback) callback(false);
785
743
 
786
744
  // Clear device id
787
- StorageUtils.setLocalData(this.deviceIdField, null);
745
+ this.storage.setData(CoreApp.deviceIdField, undefined);
788
746
 
789
747
  return;
790
748
  }
@@ -800,6 +758,7 @@ export abstract class CoreApp<
800
758
  * @param timestamp Timestamp
801
759
  */
802
760
  protected initCallUpdate(data: InitCallResultData, timestamp: number) {
761
+ // Data check
803
762
  if (data.deviceId == null || data.passphrase == null) return;
804
763
 
805
764
  // Decrypt
@@ -808,13 +767,15 @@ export abstract class CoreApp<
808
767
  if (passphrase == null) return;
809
768
 
810
769
  // 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);
770
+ this._deviceId = data.deviceId;
771
+ this.storage.setData(CoreApp.deviceIdField, this.deviceId);
815
772
 
816
773
  // Current passphrase
817
774
  this.passphrase = passphrase;
775
+ this.storage.setData(
776
+ CoreApp.devicePassphraseField,
777
+ this.encrypt(passphrase, this.name)
778
+ );
818
779
 
819
780
  // Previous passphrase
820
781
  if (data.previousPassphrase) {
@@ -824,9 +785,9 @@ export abstract class CoreApp<
824
785
  );
825
786
 
826
787
  // Update
827
- const fields = this.initCallUpdateFields();
788
+ const fields = this.initCallEncryptedUpdateFields();
828
789
  for (const field of fields) {
829
- const currentValue = StorageUtils.getLocalData<string>(field);
790
+ const currentValue = this.storage.getData<string>(field);
830
791
  if (currentValue == null || currentValue === '') continue;
831
792
 
832
793
  const enhanced = currentValue.indexOf('!') >= 8;
@@ -848,17 +809,17 @@ export abstract class CoreApp<
848
809
  ? this.encryptEnhanced(newValueSource)
849
810
  : this.encrypt(newValueSource);
850
811
 
851
- StorageUtils.setLocalData(field, newValue);
812
+ this.storage.setData(field, newValue);
852
813
  }
853
814
  }
854
815
  }
855
816
 
856
817
  /**
857
- * Init call update fields in local storage
818
+ * Init call encrypted fields update
858
819
  * @returns Fields
859
820
  */
860
- protected initCallUpdateFields(): string[] {
861
- return [this.headerTokenField];
821
+ protected initCallEncryptedUpdateFields(): string[] {
822
+ return [CoreApp.headerTokenField];
862
823
  }
863
824
 
864
825
  /**
@@ -885,7 +846,7 @@ export abstract class CoreApp<
885
846
  // Cover the current value
886
847
  if (refreshToken !== '') {
887
848
  if (refreshToken != null) refreshToken = this.encrypt(refreshToken);
888
- StorageUtils.setLocalData(this.headerTokenField, refreshToken);
849
+ this.storage.setData(CoreApp.headerTokenField, refreshToken);
889
850
  }
890
851
 
891
852
  // Reset tryLogin state
@@ -923,7 +884,7 @@ export abstract class CoreApp<
923
884
  return;
924
885
 
925
886
  // Save the id to local storage
926
- DomUtils.saveCountry(regionId);
887
+ this.storage.setData(DomUtils.CountryField, regionId);
927
888
 
928
889
  // Set the currency and culture
929
890
  this._currency = regionItem.currency;
@@ -945,7 +906,7 @@ export abstract class CoreApp<
945
906
  if (this._culture === name) return;
946
907
 
947
908
  // Save the cultrue to local storage
948
- DomUtils.saveCulture(name);
909
+ this.storage.setData(DomUtils.CultureField, name);
949
910
 
950
911
  // Change the API's Content-Language header
951
912
  // .net 5 API, UseRequestLocalization, RequestCultureProviders, ContentLanguageHeaderRequestCultureProvider
@@ -972,13 +933,12 @@ export abstract class CoreApp<
972
933
  * Clear cache data
973
934
  */
974
935
  clearCacheData() {
975
- StorageUtils.setLocalData(this.serversideDeviceIdField, undefined);
936
+ this.storage.setData(CoreApp.serversideDeviceIdField, undefined);
976
937
 
977
- StorageUtils.setLocalData(this.deviceIdField, undefined);
978
- StorageUtils.setLocalData(this.devicePassphraseField, undefined);
979
- StorageUtils.setLocalData(this.deviceIdUpdateTimeField, undefined);
938
+ this.storage.setData(CoreApp.deviceIdField, undefined);
939
+ this.storage.setData(CoreApp.devicePassphraseField, undefined);
980
940
 
981
- StorageUtils.setLocalData(this.headerTokenField, undefined);
941
+ this.storage.setData(CoreApp.headerTokenField, undefined);
982
942
  }
983
943
 
984
944
  /**
@@ -986,7 +946,7 @@ export abstract class CoreApp<
986
946
  */
987
947
  clearCacheToken() {
988
948
  this.cachedRefreshToken = undefined;
989
- StorageUtils.setLocalData(this.headerTokenField, undefined);
949
+ this.storage.setData(CoreApp.headerTokenField, undefined);
990
950
  }
991
951
 
992
952
  /**
@@ -1292,7 +1252,7 @@ export abstract class CoreApp<
1292
1252
  getCacheToken(): string | undefined {
1293
1253
  // Temp refresh token
1294
1254
  if (this.cachedRefreshToken) return this.cachedRefreshToken;
1295
- return StorageUtils.getLocalData<string>(this.headerTokenField);
1255
+ return this.storage.getData<string>(CoreApp.headerTokenField);
1296
1256
  }
1297
1257
 
1298
1258
  /**
@@ -1312,7 +1272,10 @@ export abstract class CoreApp<
1312
1272
  */
1313
1273
  getResponseToken(rawResponse: any): string | null {
1314
1274
  const response = this.api.transformResponse(rawResponse);
1315
- return this.api.getHeaderValue(response.headers, this.headerTokenField);
1275
+ return this.api.getHeaderValue(
1276
+ response.headers,
1277
+ CoreApp.headerTokenField
1278
+ );
1316
1279
  }
1317
1280
 
1318
1281
  /**
@@ -1479,7 +1442,11 @@ export abstract class CoreApp<
1479
1442
  */
1480
1443
  async switchOrg(id: number, serviceId?: number) {
1481
1444
  const api = `Organization/Switch`;
1482
- const result = await this.api.put<boolean>(api, { id, serviceId });
1445
+ const result = await this.api.put<boolean>(api, {
1446
+ id,
1447
+ serviceId,
1448
+ deviceId: this.deviceId
1449
+ });
1483
1450
  if (result) return await this.refreshToken();
1484
1451
  return result;
1485
1452
  }
@@ -1537,7 +1504,7 @@ export abstract class CoreApp<
1537
1504
  this.userData = user;
1538
1505
 
1539
1506
  // Cache the encrypted serverside device id
1540
- StorageUtils.setLocalData(this.serversideDeviceIdField, user.deviceId);
1507
+ this.storage.setData(CoreApp.serversideDeviceIdField, user.deviceId);
1541
1508
 
1542
1509
  if (keep) {
1543
1510
  this.authorize(user.token, refreshToken);
@@ -1584,3 +1551,25 @@ export abstract class CoreApp<
1584
1551
  );
1585
1552
  }
1586
1553
  }
1554
+
1555
+ export namespace CoreApp {
1556
+ /**
1557
+ * Response token header field name
1558
+ */
1559
+ export const headerTokenField = 'SmartERPRefreshToken';
1560
+
1561
+ /**
1562
+ * Serverside device id encrypted field name
1563
+ */
1564
+ export const serversideDeviceIdField = 'SmartERPServersideDeviceId';
1565
+
1566
+ /**
1567
+ * Device id field name
1568
+ */
1569
+ export const deviceIdField = 'SmartERPDeviceId';
1570
+
1571
+ /**
1572
+ * Device passphrase field name
1573
+ */
1574
+ export const devicePassphraseField = 'SmartERPDevicePassphrase';
1575
+ }