@etsoo/appscript 1.1.75 → 1.1.79

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.
@@ -105,9 +105,8 @@ export interface ICoreApp<S extends IAppSettings, N, C extends NotificationCallP
105
105
  * Authorize
106
106
  * @param token New token
107
107
  * @param refreshToken Refresh token
108
- * @param keep Keep in local storage or not
109
108
  */
110
- authorize(token?: string, refreshToken?: string, keep?: boolean): void;
109
+ authorize(token?: string, refreshToken?: string): void;
111
110
  /**
112
111
  * Change country or region
113
112
  * @param region New country or region
@@ -118,6 +117,10 @@ export interface ICoreApp<S extends IAppSettings, N, C extends NotificationCallP
118
117
  * @param culture New culture definition
119
118
  */
120
119
  changeCulture(culture: DataTypes.CultureDefinition): void;
120
+ /**
121
+ * Clear cached token
122
+ */
123
+ clearCacheToken(): void;
121
124
  /**
122
125
  * Decrypt message
123
126
  * @param messageEncrypted Encrypted message
@@ -299,7 +302,7 @@ export interface ICoreApp<S extends IAppSettings, N, C extends NotificationCallP
299
302
  * User login
300
303
  * @param user User data
301
304
  * @param refreshToken Refresh token
302
- * @param keep Keep in local storage or not
305
+ * @param keep Keep login or not
303
306
  */
304
307
  userLogin(user: IUserData, refreshToken: string, keep?: boolean): void;
305
308
  /**
@@ -403,6 +406,7 @@ export declare abstract class CoreApp<S extends IAppSettings, N, C extends Notif
403
406
  * Passphrase for encryption
404
407
  */
405
408
  protected passphrase: string;
409
+ private cachedRefreshToken?;
406
410
  /**
407
411
  * Protected constructor
408
412
  * @param settings Settings
@@ -438,9 +442,8 @@ export declare abstract class CoreApp<S extends IAppSettings, N, C extends Notif
438
442
  * Authorize
439
443
  * @param token New token
440
444
  * @param refreshToken Refresh token
441
- * @param keep Keep in local storage or not
442
445
  */
443
- authorize(token?: string, refreshToken?: string, keep?: boolean): void;
446
+ authorize(token?: string, refreshToken?: string): void;
444
447
  /**
445
448
  * Change country or region
446
449
  * @param regionId New country or region
@@ -451,6 +454,10 @@ export declare abstract class CoreApp<S extends IAppSettings, N, C extends Notif
451
454
  * @param culture New culture definition
452
455
  */
453
456
  changeCulture(culture: DataTypes.CultureDefinition): void;
457
+ /**
458
+ * Clear cached token
459
+ */
460
+ clearCacheToken(): void;
454
461
  /**
455
462
  * Decrypt message
456
463
  * @param messageEncrypted Encrypted message
@@ -644,7 +651,7 @@ export declare abstract class CoreApp<S extends IAppSettings, N, C extends Notif
644
651
  * User login
645
652
  * @param user User data
646
653
  * @param refreshToken Refresh token
647
- * @param keep Keep in local storage or not
654
+ * @param keep Keep login or not
648
655
  */
649
656
  userLogin(user: IUserData, refreshToken: string, keep?: boolean): void;
650
657
  /**
@@ -197,12 +197,21 @@ class CoreApp {
197
197
  const fields = this.initCallUpdateFields();
198
198
  for (const field of fields) {
199
199
  const currentValue = shared_1.StorageUtils.getLocalData(field, '');
200
- if (currentValue === '' || currentValue.indexOf('+') === -1)
200
+ if (currentValue === '')
201
201
  continue;
202
- const newValueSource = this.decryptEnhanced(currentValue, prev, 12);
203
- if (newValueSource == null)
202
+ const enhanced = currentValue.indexOf('!') >= 8;
203
+ let newValueSource = null;
204
+ if (enhanced) {
205
+ newValueSource = this.decryptEnhanced(currentValue, prev, 12);
206
+ }
207
+ else {
208
+ newValueSource = this.decrypt(currentValue, prev);
209
+ }
210
+ if (newValueSource == null || newValueSource === '')
204
211
  continue;
205
- const newValue = this.encryptEnhanced(newValueSource);
212
+ const newValue = enhanced
213
+ ? this.encryptEnhanced(newValueSource)
214
+ : this.encrypt(newValueSource);
206
215
  shared_1.StorageUtils.setLocalData(field, newValue);
207
216
  }
208
217
  }
@@ -212,7 +221,7 @@ class CoreApp {
212
221
  * @returns Fields
213
222
  */
214
223
  initCallUpdateFields() {
215
- return [];
224
+ return [this.headerTokenField];
216
225
  }
217
226
  /**
218
227
  * Alert action result
@@ -226,25 +235,27 @@ class CoreApp {
226
235
  * Authorize
227
236
  * @param token New token
228
237
  * @param refreshToken Refresh token
229
- * @param keep Keep in local storage or not
230
238
  */
231
- authorize(token, refreshToken, keep) {
239
+ authorize(token, refreshToken) {
232
240
  // State, when token is null, means logout
233
241
  this.authorized = token != null;
234
242
  // Token
235
243
  this.api.authorize(this.settings.authScheme, token);
236
244
  // Cover the current value
237
- if (keep != null) {
238
- shared_1.StorageUtils.setLocalData(this.headerTokenField, keep ? refreshToken : undefined);
239
- shared_1.StorageUtils.setSessionData(this.headerTokenField, keep ? undefined : refreshToken);
245
+ if (refreshToken !== '') {
246
+ if (refreshToken != null)
247
+ refreshToken = this.encrypt(refreshToken);
248
+ shared_1.StorageUtils.setLocalData(this.headerTokenField, refreshToken);
240
249
  }
241
250
  // Reset tryLogin state
242
251
  this._isTryingLogin = false;
243
252
  // Token countdown
244
253
  if (this.authorized)
245
254
  this.refreshCountdown(this.userData.seconds);
246
- else
255
+ else {
256
+ this.cachedRefreshToken = undefined;
247
257
  this.refreshCountdownClear();
258
+ }
248
259
  }
249
260
  /**
250
261
  * Change country or region
@@ -302,6 +313,13 @@ class CoreApp {
302
313
  region.name = AddressUtils_1.AddressUtils.getRegionLabel(id, this.labelDelegate);
303
314
  });
304
315
  }
316
+ /**
317
+ * Clear cached token
318
+ */
319
+ clearCacheToken() {
320
+ this.cachedRefreshToken = undefined;
321
+ shared_1.StorageUtils.setLocalData(this.headerTokenField, undefined);
322
+ }
305
323
  /**
306
324
  * Decrypt message
307
325
  * @param messageEncrypted Encrypted message
@@ -321,14 +339,11 @@ class CoreApp {
321
339
  hasher: crypto_js_1.algo.SHA256,
322
340
  iterations: 1000 * iterations
323
341
  });
324
- const bytes = crypto_js_1.AES.decrypt(encrypted, key, {
342
+ return crypto_js_1.AES.decrypt(encrypted, key, {
325
343
  iv,
326
344
  padding: crypto_js_1.pad.Pkcs7,
327
345
  mode: crypto_js_1.mode.CBC
328
- });
329
- if (bytes.words.length == 0)
330
- return undefined;
331
- return bytes.toString(crypto_js_1.enc.Utf8);
346
+ }).toString(crypto_js_1.enc.Utf8);
332
347
  }
333
348
  /**
334
349
  * Enhanced decrypt message
@@ -548,12 +563,16 @@ class CoreApp {
548
563
  * @returns Cached token
549
564
  */
550
565
  getCacheToken() {
551
- let refreshToken = shared_1.StorageUtils.getLocalData(this.headerTokenField, '');
552
- if (refreshToken === '')
553
- refreshToken = shared_1.StorageUtils.getSessionData(this.headerTokenField, '');
566
+ // Temp refresh token
567
+ if (this.cachedRefreshToken)
568
+ return this.cachedRefreshToken;
569
+ const refreshToken = shared_1.StorageUtils.getLocalData(this.headerTokenField, '');
554
570
  if (refreshToken === '')
555
571
  return null;
556
- return refreshToken;
572
+ const result = this.decrypt(refreshToken);
573
+ if (result == undefined)
574
+ return null;
575
+ return result;
557
576
  }
558
577
  /**
559
578
  * Get all regions
@@ -727,7 +746,7 @@ class CoreApp {
727
746
  return url;
728
747
  // From relative root, like home:/react/, url: /about => /react/about
729
748
  if (url.startsWith('/'))
730
- return home + url.substr(1);
749
+ return home + url.substring(1);
731
750
  const pathname = window.location.pathname;
732
751
  // Relative
733
752
  const pos = pathname.indexOf(home);
@@ -751,24 +770,30 @@ class CoreApp {
751
770
  * User login
752
771
  * @param user User data
753
772
  * @param refreshToken Refresh token
754
- * @param keep Keep in local storage or not
773
+ * @param keep Keep login or not
755
774
  */
756
- userLogin(user, refreshToken, keep = false) {
775
+ userLogin(user, refreshToken, keep) {
757
776
  this.userData = user;
758
- this.authorize(user.token, refreshToken, keep);
777
+ if (keep) {
778
+ this.authorize(user.token, refreshToken);
779
+ }
780
+ else {
781
+ this.cachedRefreshToken = refreshToken;
782
+ this.authorize(user.token, undefined);
783
+ }
759
784
  }
760
785
  /**
761
786
  * User logout
762
787
  * @param clearToken Clear refresh token or not
763
788
  */
764
789
  userLogout(clearToken = true) {
765
- this.authorize(undefined, undefined, clearToken ? false : undefined);
790
+ this.authorize(undefined, clearToken ? undefined : '');
766
791
  }
767
792
  /**
768
793
  * User unauthorized
769
794
  */
770
795
  userUnauthorized() {
771
- this.authorize(undefined, undefined, undefined);
796
+ this.authorize(undefined, undefined);
772
797
  }
773
798
  /**
774
799
  * Show warning message
@@ -36,4 +36,8 @@ export interface IUser extends IUserData, IState {
36
36
  * Authorized or not
37
37
  */
38
38
  authorized: boolean;
39
+ /**
40
+ * Last update changed fields
41
+ */
42
+ lastChangedFields?: string[];
39
43
  }
@@ -105,9 +105,8 @@ export interface ICoreApp<S extends IAppSettings, N, C extends NotificationCallP
105
105
  * Authorize
106
106
  * @param token New token
107
107
  * @param refreshToken Refresh token
108
- * @param keep Keep in local storage or not
109
108
  */
110
- authorize(token?: string, refreshToken?: string, keep?: boolean): void;
109
+ authorize(token?: string, refreshToken?: string): void;
111
110
  /**
112
111
  * Change country or region
113
112
  * @param region New country or region
@@ -118,6 +117,10 @@ export interface ICoreApp<S extends IAppSettings, N, C extends NotificationCallP
118
117
  * @param culture New culture definition
119
118
  */
120
119
  changeCulture(culture: DataTypes.CultureDefinition): void;
120
+ /**
121
+ * Clear cached token
122
+ */
123
+ clearCacheToken(): void;
121
124
  /**
122
125
  * Decrypt message
123
126
  * @param messageEncrypted Encrypted message
@@ -299,7 +302,7 @@ export interface ICoreApp<S extends IAppSettings, N, C extends NotificationCallP
299
302
  * User login
300
303
  * @param user User data
301
304
  * @param refreshToken Refresh token
302
- * @param keep Keep in local storage or not
305
+ * @param keep Keep login or not
303
306
  */
304
307
  userLogin(user: IUserData, refreshToken: string, keep?: boolean): void;
305
308
  /**
@@ -403,6 +406,7 @@ export declare abstract class CoreApp<S extends IAppSettings, N, C extends Notif
403
406
  * Passphrase for encryption
404
407
  */
405
408
  protected passphrase: string;
409
+ private cachedRefreshToken?;
406
410
  /**
407
411
  * Protected constructor
408
412
  * @param settings Settings
@@ -438,9 +442,8 @@ export declare abstract class CoreApp<S extends IAppSettings, N, C extends Notif
438
442
  * Authorize
439
443
  * @param token New token
440
444
  * @param refreshToken Refresh token
441
- * @param keep Keep in local storage or not
442
445
  */
443
- authorize(token?: string, refreshToken?: string, keep?: boolean): void;
446
+ authorize(token?: string, refreshToken?: string): void;
444
447
  /**
445
448
  * Change country or region
446
449
  * @param regionId New country or region
@@ -451,6 +454,10 @@ export declare abstract class CoreApp<S extends IAppSettings, N, C extends Notif
451
454
  * @param culture New culture definition
452
455
  */
453
456
  changeCulture(culture: DataTypes.CultureDefinition): void;
457
+ /**
458
+ * Clear cached token
459
+ */
460
+ clearCacheToken(): void;
454
461
  /**
455
462
  * Decrypt message
456
463
  * @param messageEncrypted Encrypted message
@@ -644,7 +651,7 @@ export declare abstract class CoreApp<S extends IAppSettings, N, C extends Notif
644
651
  * User login
645
652
  * @param user User data
646
653
  * @param refreshToken Refresh token
647
- * @param keep Keep in local storage or not
654
+ * @param keep Keep login or not
648
655
  */
649
656
  userLogin(user: IUserData, refreshToken: string, keep?: boolean): void;
650
657
  /**
@@ -194,12 +194,21 @@ export class CoreApp {
194
194
  const fields = this.initCallUpdateFields();
195
195
  for (const field of fields) {
196
196
  const currentValue = StorageUtils.getLocalData(field, '');
197
- if (currentValue === '' || currentValue.indexOf('+') === -1)
197
+ if (currentValue === '')
198
198
  continue;
199
- const newValueSource = this.decryptEnhanced(currentValue, prev, 12);
200
- if (newValueSource == null)
199
+ const enhanced = currentValue.indexOf('!') >= 8;
200
+ let newValueSource = null;
201
+ if (enhanced) {
202
+ newValueSource = this.decryptEnhanced(currentValue, prev, 12);
203
+ }
204
+ else {
205
+ newValueSource = this.decrypt(currentValue, prev);
206
+ }
207
+ if (newValueSource == null || newValueSource === '')
201
208
  continue;
202
- const newValue = this.encryptEnhanced(newValueSource);
209
+ const newValue = enhanced
210
+ ? this.encryptEnhanced(newValueSource)
211
+ : this.encrypt(newValueSource);
203
212
  StorageUtils.setLocalData(field, newValue);
204
213
  }
205
214
  }
@@ -209,7 +218,7 @@ export class CoreApp {
209
218
  * @returns Fields
210
219
  */
211
220
  initCallUpdateFields() {
212
- return [];
221
+ return [this.headerTokenField];
213
222
  }
214
223
  /**
215
224
  * Alert action result
@@ -223,25 +232,27 @@ export class CoreApp {
223
232
  * Authorize
224
233
  * @param token New token
225
234
  * @param refreshToken Refresh token
226
- * @param keep Keep in local storage or not
227
235
  */
228
- authorize(token, refreshToken, keep) {
236
+ authorize(token, refreshToken) {
229
237
  // State, when token is null, means logout
230
238
  this.authorized = token != null;
231
239
  // Token
232
240
  this.api.authorize(this.settings.authScheme, token);
233
241
  // Cover the current value
234
- if (keep != null) {
235
- StorageUtils.setLocalData(this.headerTokenField, keep ? refreshToken : undefined);
236
- StorageUtils.setSessionData(this.headerTokenField, keep ? undefined : refreshToken);
242
+ if (refreshToken !== '') {
243
+ if (refreshToken != null)
244
+ refreshToken = this.encrypt(refreshToken);
245
+ StorageUtils.setLocalData(this.headerTokenField, refreshToken);
237
246
  }
238
247
  // Reset tryLogin state
239
248
  this._isTryingLogin = false;
240
249
  // Token countdown
241
250
  if (this.authorized)
242
251
  this.refreshCountdown(this.userData.seconds);
243
- else
252
+ else {
253
+ this.cachedRefreshToken = undefined;
244
254
  this.refreshCountdownClear();
255
+ }
245
256
  }
246
257
  /**
247
258
  * Change country or region
@@ -299,6 +310,13 @@ export class CoreApp {
299
310
  region.name = AddressUtils.getRegionLabel(id, this.labelDelegate);
300
311
  });
301
312
  }
313
+ /**
314
+ * Clear cached token
315
+ */
316
+ clearCacheToken() {
317
+ this.cachedRefreshToken = undefined;
318
+ StorageUtils.setLocalData(this.headerTokenField, undefined);
319
+ }
302
320
  /**
303
321
  * Decrypt message
304
322
  * @param messageEncrypted Encrypted message
@@ -318,14 +336,11 @@ export class CoreApp {
318
336
  hasher: algo.SHA256,
319
337
  iterations: 1000 * iterations
320
338
  });
321
- const bytes = AES.decrypt(encrypted, key, {
339
+ return AES.decrypt(encrypted, key, {
322
340
  iv,
323
341
  padding: pad.Pkcs7,
324
342
  mode: mode.CBC
325
- });
326
- if (bytes.words.length == 0)
327
- return undefined;
328
- return bytes.toString(enc.Utf8);
343
+ }).toString(enc.Utf8);
329
344
  }
330
345
  /**
331
346
  * Enhanced decrypt message
@@ -545,12 +560,16 @@ export class CoreApp {
545
560
  * @returns Cached token
546
561
  */
547
562
  getCacheToken() {
548
- let refreshToken = StorageUtils.getLocalData(this.headerTokenField, '');
549
- if (refreshToken === '')
550
- refreshToken = StorageUtils.getSessionData(this.headerTokenField, '');
563
+ // Temp refresh token
564
+ if (this.cachedRefreshToken)
565
+ return this.cachedRefreshToken;
566
+ const refreshToken = StorageUtils.getLocalData(this.headerTokenField, '');
551
567
  if (refreshToken === '')
552
568
  return null;
553
- return refreshToken;
569
+ const result = this.decrypt(refreshToken);
570
+ if (result == undefined)
571
+ return null;
572
+ return result;
554
573
  }
555
574
  /**
556
575
  * Get all regions
@@ -724,7 +743,7 @@ export class CoreApp {
724
743
  return url;
725
744
  // From relative root, like home:/react/, url: /about => /react/about
726
745
  if (url.startsWith('/'))
727
- return home + url.substr(1);
746
+ return home + url.substring(1);
728
747
  const pathname = window.location.pathname;
729
748
  // Relative
730
749
  const pos = pathname.indexOf(home);
@@ -748,24 +767,30 @@ export class CoreApp {
748
767
  * User login
749
768
  * @param user User data
750
769
  * @param refreshToken Refresh token
751
- * @param keep Keep in local storage or not
770
+ * @param keep Keep login or not
752
771
  */
753
- userLogin(user, refreshToken, keep = false) {
772
+ userLogin(user, refreshToken, keep) {
754
773
  this.userData = user;
755
- this.authorize(user.token, refreshToken, keep);
774
+ if (keep) {
775
+ this.authorize(user.token, refreshToken);
776
+ }
777
+ else {
778
+ this.cachedRefreshToken = refreshToken;
779
+ this.authorize(user.token, undefined);
780
+ }
756
781
  }
757
782
  /**
758
783
  * User logout
759
784
  * @param clearToken Clear refresh token or not
760
785
  */
761
786
  userLogout(clearToken = true) {
762
- this.authorize(undefined, undefined, clearToken ? false : undefined);
787
+ this.authorize(undefined, clearToken ? undefined : '');
763
788
  }
764
789
  /**
765
790
  * User unauthorized
766
791
  */
767
792
  userUnauthorized() {
768
- this.authorize(undefined, undefined, undefined);
793
+ this.authorize(undefined, undefined);
769
794
  }
770
795
  /**
771
796
  * Show warning message
@@ -36,4 +36,8 @@ export interface IUser extends IUserData, IState {
36
36
  * Authorized or not
37
37
  */
38
38
  authorized: boolean;
39
+ /**
40
+ * Last update changed fields
41
+ */
42
+ lastChangedFields?: string[];
39
43
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@etsoo/appscript",
3
- "version": "1.1.75",
3
+ "version": "1.1.79",
4
4
  "description": "Applications shared TypeScript framework",
5
5
  "main": "lib/cjs/index.js",
6
6
  "module": "lib/mjs/index.js",
@@ -60,18 +60,18 @@
60
60
  },
61
61
  "devDependencies": {
62
62
  "@babel/cli": "^7.16.0",
63
- "@babel/core": "^7.16.0",
64
- "@babel/plugin-transform-runtime": "^7.16.4",
65
- "@babel/preset-env": "^7.16.4",
66
- "@babel/runtime-corejs3": "^7.16.3",
63
+ "@babel/core": "^7.16.5",
64
+ "@babel/plugin-transform-runtime": "^7.16.5",
65
+ "@babel/preset-env": "^7.16.5",
66
+ "@babel/runtime-corejs3": "^7.16.5",
67
67
  "@types/jest": "^27.0.3",
68
- "@typescript-eslint/eslint-plugin": "^5.6.0",
69
- "@typescript-eslint/parser": "^5.6.0",
68
+ "@typescript-eslint/eslint-plugin": "^5.7.0",
69
+ "@typescript-eslint/parser": "^5.7.0",
70
70
  "eslint": "^8.4.1",
71
71
  "eslint-config-airbnb-base": "^15.0.0",
72
72
  "eslint-plugin-import": "^2.25.3",
73
- "jest": "^27.4.4",
74
- "ts-jest": "^27.1.1",
75
- "typescript": "^4.5.3"
73
+ "jest": "^27.4.5",
74
+ "ts-jest": "^27.1.2",
75
+ "typescript": "^4.5.4"
76
76
  }
77
77
  }
@@ -162,9 +162,8 @@ export interface ICoreApp<
162
162
  * Authorize
163
163
  * @param token New token
164
164
  * @param refreshToken Refresh token
165
- * @param keep Keep in local storage or not
166
165
  */
167
- authorize(token?: string, refreshToken?: string, keep?: boolean): void;
166
+ authorize(token?: string, refreshToken?: string): void;
168
167
 
169
168
  /**
170
169
  * Change country or region
@@ -178,6 +177,11 @@ export interface ICoreApp<
178
177
  */
179
178
  changeCulture(culture: DataTypes.CultureDefinition): void;
180
179
 
180
+ /**
181
+ * Clear cached token
182
+ */
183
+ clearCacheToken(): void;
184
+
181
185
  /**
182
186
  * Decrypt message
183
187
  * @param messageEncrypted Encrypted message
@@ -407,7 +411,7 @@ export interface ICoreApp<
407
411
  * User login
408
412
  * @param user User data
409
413
  * @param refreshToken Refresh token
410
- * @param keep Keep in local storage or not
414
+ * @param keep Keep login or not
411
415
  */
412
416
  userLogin(user: IUserData, refreshToken: string, keep?: boolean): void;
413
417
 
@@ -558,6 +562,8 @@ export abstract class CoreApp<
558
562
  */
559
563
  protected passphrase: string = '***';
560
564
 
565
+ private cachedRefreshToken?: string;
566
+
561
567
  /**
562
568
  * Protected constructor
563
569
  * @param settings Settings
@@ -714,17 +720,27 @@ export abstract class CoreApp<
714
720
  field,
715
721
  ''
716
722
  );
717
- if (currentValue === '' || currentValue.indexOf('+') === -1)
718
- continue;
723
+ if (currentValue === '') continue;
719
724
 
720
- const newValueSource = this.decryptEnhanced(
721
- currentValue,
722
- prev,
723
- 12
724
- );
725
- if (newValueSource == null) continue;
725
+ const enhanced = currentValue.indexOf('!') >= 8;
726
+ let newValueSource = null;
727
+
728
+ if (enhanced) {
729
+ newValueSource = this.decryptEnhanced(
730
+ currentValue,
731
+ prev,
732
+ 12
733
+ );
734
+ } else {
735
+ newValueSource = this.decrypt(currentValue, prev);
736
+ }
737
+
738
+ if (newValueSource == null || newValueSource === '') continue;
739
+
740
+ const newValue = enhanced
741
+ ? this.encryptEnhanced(newValueSource)
742
+ : this.encrypt(newValueSource);
726
743
 
727
- const newValue = this.encryptEnhanced(newValueSource);
728
744
  StorageUtils.setLocalData(field, newValue);
729
745
  }
730
746
  }
@@ -735,7 +751,7 @@ export abstract class CoreApp<
735
751
  * @returns Fields
736
752
  */
737
753
  protected initCallUpdateFields(): string[] {
738
- return [];
754
+ return [this.headerTokenField];
739
755
  }
740
756
 
741
757
  /**
@@ -751,9 +767,8 @@ export abstract class CoreApp<
751
767
  * Authorize
752
768
  * @param token New token
753
769
  * @param refreshToken Refresh token
754
- * @param keep Keep in local storage or not
755
770
  */
756
- authorize(token?: string, refreshToken?: string, keep?: boolean) {
771
+ authorize(token?: string, refreshToken?: string) {
757
772
  // State, when token is null, means logout
758
773
  this.authorized = token != null;
759
774
 
@@ -761,15 +776,9 @@ export abstract class CoreApp<
761
776
  this.api.authorize(this.settings.authScheme, token);
762
777
 
763
778
  // Cover the current value
764
- if (keep != null) {
765
- StorageUtils.setLocalData(
766
- this.headerTokenField,
767
- keep ? refreshToken : undefined
768
- );
769
- StorageUtils.setSessionData(
770
- this.headerTokenField,
771
- keep ? undefined : refreshToken
772
- );
779
+ if (refreshToken !== '') {
780
+ if (refreshToken != null) refreshToken = this.encrypt(refreshToken);
781
+ StorageUtils.setLocalData(this.headerTokenField, refreshToken);
773
782
  }
774
783
 
775
784
  // Reset tryLogin state
@@ -777,7 +786,10 @@ export abstract class CoreApp<
777
786
 
778
787
  // Token countdown
779
788
  if (this.authorized) this.refreshCountdown(this.userData!.seconds);
780
- else this.refreshCountdownClear();
789
+ else {
790
+ this.cachedRefreshToken = undefined;
791
+ this.refreshCountdownClear();
792
+ }
781
793
  }
782
794
 
783
795
  /**
@@ -849,6 +861,14 @@ export abstract class CoreApp<
849
861
  });
850
862
  }
851
863
 
864
+ /**
865
+ * Clear cached token
866
+ */
867
+ clearCacheToken() {
868
+ this.cachedRefreshToken = undefined;
869
+ StorageUtils.setLocalData(this.headerTokenField, undefined);
870
+ }
871
+
852
872
  /**
853
873
  * Decrypt message
854
874
  * @param messageEncrypted Encrypted message
@@ -870,14 +890,11 @@ export abstract class CoreApp<
870
890
  iterations: 1000 * iterations
871
891
  });
872
892
 
873
- const bytes = AES.decrypt(encrypted, key, {
893
+ return AES.decrypt(encrypted, key, {
874
894
  iv,
875
895
  padding: pad.Pkcs7,
876
896
  mode: mode.CBC
877
- });
878
- if (bytes.words.length == 0) return undefined;
879
-
880
- return bytes.toString(enc.Utf8);
897
+ }).toString(enc.Utf8);
881
898
  }
882
899
 
883
900
  /**
@@ -1153,19 +1170,19 @@ export abstract class CoreApp<
1153
1170
  * @returns Cached token
1154
1171
  */
1155
1172
  getCacheToken(): string | null {
1156
- let refreshToken = StorageUtils.getLocalData<string>(
1173
+ // Temp refresh token
1174
+ if (this.cachedRefreshToken) return this.cachedRefreshToken;
1175
+
1176
+ const refreshToken = StorageUtils.getLocalData<string>(
1157
1177
  this.headerTokenField,
1158
1178
  ''
1159
1179
  );
1160
- if (refreshToken === '')
1161
- refreshToken = StorageUtils.getSessionData(
1162
- this.headerTokenField,
1163
- ''
1164
- );
1165
1180
 
1166
1181
  if (refreshToken === '') return null;
1167
1182
 
1168
- return refreshToken;
1183
+ const result = this.decrypt(refreshToken);
1184
+ if (result == undefined) return null;
1185
+ return result;
1169
1186
  }
1170
1187
 
1171
1188
  /**
@@ -1358,7 +1375,7 @@ export abstract class CoreApp<
1358
1375
  if (home === '') return url;
1359
1376
 
1360
1377
  // From relative root, like home:/react/, url: /about => /react/about
1361
- if (url.startsWith('/')) return home + url.substr(1);
1378
+ if (url.startsWith('/')) return home + url.substring(1);
1362
1379
 
1363
1380
  const pathname = window.location.pathname;
1364
1381
 
@@ -1385,11 +1402,17 @@ export abstract class CoreApp<
1385
1402
  * User login
1386
1403
  * @param user User data
1387
1404
  * @param refreshToken Refresh token
1388
- * @param keep Keep in local storage or not
1405
+ * @param keep Keep login or not
1389
1406
  */
1390
- userLogin(user: IUserData, refreshToken: string, keep: boolean = false) {
1407
+ userLogin(user: IUserData, refreshToken: string, keep?: boolean) {
1391
1408
  this.userData = user;
1392
- this.authorize(user.token, refreshToken, keep);
1409
+
1410
+ if (keep) {
1411
+ this.authorize(user.token, refreshToken);
1412
+ } else {
1413
+ this.cachedRefreshToken = refreshToken;
1414
+ this.authorize(user.token, undefined);
1415
+ }
1393
1416
  }
1394
1417
 
1395
1418
  /**
@@ -1397,14 +1420,14 @@ export abstract class CoreApp<
1397
1420
  * @param clearToken Clear refresh token or not
1398
1421
  */
1399
1422
  userLogout(clearToken: boolean = true) {
1400
- this.authorize(undefined, undefined, clearToken ? false : undefined);
1423
+ this.authorize(undefined, clearToken ? undefined : '');
1401
1424
  }
1402
1425
 
1403
1426
  /**
1404
1427
  * User unauthorized
1405
1428
  */
1406
1429
  userUnauthorized() {
1407
- this.authorize(undefined, undefined, undefined);
1430
+ this.authorize(undefined, undefined);
1408
1431
  }
1409
1432
 
1410
1433
  private lastWarning?: INotification<N, C>;
package/src/state/User.ts CHANGED
@@ -43,4 +43,9 @@ export interface IUser extends IUserData, IState {
43
43
  * Authorized or not
44
44
  */
45
45
  authorized: boolean;
46
+
47
+ /**
48
+ * Last update changed fields
49
+ */
50
+ lastChangedFields?: string[];
46
51
  }