@etsoo/appscript 1.2.7 → 1.2.11

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.
@@ -445,6 +445,7 @@ export declare abstract class CoreApp<S extends IAppSettings, N, C extends Notif
445
445
  */
446
446
  protected constructor(settings: S, api: IApi, notifier: INotifier<N, C>, storage: IStorage, name: string);
447
447
  private getDeviceId;
448
+ private resetKeys;
448
449
  /**
449
450
  * Restore settings from persisted source
450
451
  */
@@ -126,42 +126,51 @@ class CoreApp {
126
126
  getDeviceId() {
127
127
  return this.deviceId.substring(0, 15);
128
128
  }
129
+ resetKeys() {
130
+ this.storage.clear([
131
+ CoreApp.devicePassphraseField,
132
+ CoreApp.headerTokenField,
133
+ CoreApp.serversideDeviceIdField
134
+ ], false);
135
+ this.passphrase = '';
136
+ }
129
137
  /**
130
138
  * Restore settings from persisted source
131
139
  */
132
140
  restore() {
133
- // Current device id, '' means new, or reload (not included) or duplicate (included)
134
- if (this.deviceId) {
135
- // Devices
136
- const devices = this.storage.getPersistedData(CoreApp.devicesField, []);
137
- // Exists in the list?
138
- const d = this.getDeviceId();
139
- if (!devices.includes(d)) {
140
- const passphraseEncrypted = this.storage.getData(CoreApp.devicePassphraseField);
141
- if (passphraseEncrypted) {
142
- const passphraseDecrypted = this.decrypt(passphraseEncrypted, this.name);
143
- if (passphraseDecrypted != null) {
144
- this.passphrase = passphraseDecrypted;
145
- devices.push(d);
146
- this.storage.setPersistedData(CoreApp.devicesField, devices);
147
- return false;
148
- }
149
- }
150
- }
151
- else {
152
- // Duplicate tab, session data copied
153
- // Remove the token, deviceId, and passphrase
154
- this.storage.clear([
155
- CoreApp.devicePassphraseField,
156
- CoreApp.headerTokenField,
157
- CoreApp.serversideDeviceIdField
158
- ], false);
159
- this.passphrase = '';
141
+ // Devices
142
+ const devices = this.storage.getPersistedData(CoreApp.devicesField, []);
143
+ if (this.deviceId === '') {
144
+ // First vist, restore and keep the source
145
+ this.storage.copyFrom(this.persistedFields, false);
146
+ // Reset device id
147
+ this._deviceId = this.storage.getData(CoreApp.deviceIdField, '');
148
+ // Totally new, no data restored
149
+ if (this._deviceId === '')
150
+ return false;
151
+ }
152
+ // Device exists or not
153
+ const d = this.getDeviceId();
154
+ if (devices.includes(d)) {
155
+ // Duplicate tab, session data copied
156
+ // Remove the token, deviceId, and passphrase
157
+ this.resetKeys();
158
+ return false;
159
+ }
160
+ const passphraseEncrypted = this.storage.getData(CoreApp.devicePassphraseField);
161
+ if (passphraseEncrypted) {
162
+ const passphraseDecrypted = this.decrypt(passphraseEncrypted, this.name);
163
+ if (passphraseDecrypted != null) {
164
+ // Add the device to the list
165
+ devices.push(d);
166
+ this.storage.setPersistedData(CoreApp.devicesField, devices);
167
+ this.passphrase = passphraseDecrypted;
168
+ return true;
160
169
  }
170
+ // Failed, reset keys
171
+ this.resetKeys();
161
172
  }
162
- // Restore
163
- this.storage.copyFrom(this.persistedFields, true);
164
- return true;
173
+ return false;
165
174
  }
166
175
  /**
167
176
  * Persist settings to source when application exit
@@ -172,6 +181,7 @@ class CoreApp {
172
181
  if (devices != null) {
173
182
  const index = devices.indexOf(this.getDeviceId());
174
183
  if (index !== -1) {
184
+ // Remove current device from the list
175
185
  devices.splice(index, 1);
176
186
  this.storage.setPersistedData(CoreApp.devicesField, devices);
177
187
  }
@@ -37,6 +37,7 @@
37
37
  "ok": "OK",
38
38
  "open": "Open",
39
39
  "openMenu": "Open menu",
40
+ "operationSucceeded": "Operation succeeded",
40
41
  "pageNotFound": "Page Not Found",
41
42
  "prompt": "Input",
42
43
  "pullToRefresh": "Pull down to refresh",
@@ -46,6 +47,7 @@
46
47
  "reloginTip": "Please enter your password, resubmit the data after successful login",
47
48
  "remove": "Remove",
48
49
  "renew": "Renew",
50
+ "reports": "Reports",
49
51
  "resending": "Resending",
50
52
  "reset": "Reset",
51
53
  "rotateLeft": "Rotate left 90°",
@@ -54,6 +56,7 @@
54
56
  "scrollToTop": "Scroll to top",
55
57
  "send": "Send",
56
58
  "setAsDefault": "Set as default",
59
+ "settings": "Settings",
57
60
  "signout": "Sign out",
58
61
  "smartERP": "SmartERP",
59
62
  "status": "Status",
@@ -37,6 +37,7 @@
37
37
  "ok": "确定",
38
38
  "open": "打开",
39
39
  "openMenu": "打开菜单",
40
+ "operationSucceeded": "操作成功",
40
41
  "pageNotFound": "找不到页面",
41
42
  "prompt": "输入",
42
43
  "pullToRefresh": "下拉刷新",
@@ -46,6 +47,7 @@
46
47
  "reloginTip": "请输入您的登录密码,登录成功后请重新提交数据",
47
48
  "remove": "移除",
48
49
  "renew": "续费",
50
+ "reports": "统计报表",
49
51
  "resending": "重新发送",
50
52
  "reset": "重置",
51
53
  "rotateLeft": "左旋转90°",
@@ -54,6 +56,7 @@
54
56
  "scrollToTop": "回到顶部",
55
57
  "send": "发送",
56
58
  "setAsDefault": "设为默认",
59
+ "settings": "系统设置",
57
60
  "signout": "退出",
58
61
  "smartERP": "司友云ERP",
59
62
  "status": "状态",
@@ -37,6 +37,7 @@
37
37
  "ok": "確定",
38
38
  "open": "打開",
39
39
  "openMenu": "打開菜單",
40
+ "operationSucceeded": "操作成功",
40
41
  "pageNotFound": "找不到頁面",
41
42
  "prompt": "輸入",
42
43
  "pullToRefresh": "下拉刷新",
@@ -46,6 +47,7 @@
46
47
  "reloginTip": "請輸入您的登錄密碼,登錄成功後請重新提交數據",
47
48
  "remove": "移除",
48
49
  "renew": "續費",
50
+ "reports": "統計報表",
49
51
  "resending": "重新發送",
50
52
  "reset": "重置",
51
53
  "rotateLeft": "左旋轉90°",
@@ -54,6 +56,7 @@
54
56
  "scrollToTop": "回到頂部",
55
57
  "send": "發送",
56
58
  "setAsDefault": "設為默認",
59
+ "settings": "系統設置",
57
60
  "signout": "退出",
58
61
  "smartERP": "司友雲ERP",
59
62
  "status": "狀態",
@@ -445,6 +445,7 @@ export declare abstract class CoreApp<S extends IAppSettings, N, C extends Notif
445
445
  */
446
446
  protected constructor(settings: S, api: IApi, notifier: INotifier<N, C>, storage: IStorage, name: string);
447
447
  private getDeviceId;
448
+ private resetKeys;
448
449
  /**
449
450
  * Restore settings from persisted source
450
451
  */
@@ -123,42 +123,51 @@ export class CoreApp {
123
123
  getDeviceId() {
124
124
  return this.deviceId.substring(0, 15);
125
125
  }
126
+ resetKeys() {
127
+ this.storage.clear([
128
+ CoreApp.devicePassphraseField,
129
+ CoreApp.headerTokenField,
130
+ CoreApp.serversideDeviceIdField
131
+ ], false);
132
+ this.passphrase = '';
133
+ }
126
134
  /**
127
135
  * Restore settings from persisted source
128
136
  */
129
137
  restore() {
130
- // Current device id, '' means new, or reload (not included) or duplicate (included)
131
- if (this.deviceId) {
132
- // Devices
133
- const devices = this.storage.getPersistedData(CoreApp.devicesField, []);
134
- // Exists in the list?
135
- const d = this.getDeviceId();
136
- if (!devices.includes(d)) {
137
- const passphraseEncrypted = this.storage.getData(CoreApp.devicePassphraseField);
138
- if (passphraseEncrypted) {
139
- const passphraseDecrypted = this.decrypt(passphraseEncrypted, this.name);
140
- if (passphraseDecrypted != null) {
141
- this.passphrase = passphraseDecrypted;
142
- devices.push(d);
143
- this.storage.setPersistedData(CoreApp.devicesField, devices);
144
- return false;
145
- }
146
- }
147
- }
148
- else {
149
- // Duplicate tab, session data copied
150
- // Remove the token, deviceId, and passphrase
151
- this.storage.clear([
152
- CoreApp.devicePassphraseField,
153
- CoreApp.headerTokenField,
154
- CoreApp.serversideDeviceIdField
155
- ], false);
156
- this.passphrase = '';
138
+ // Devices
139
+ const devices = this.storage.getPersistedData(CoreApp.devicesField, []);
140
+ if (this.deviceId === '') {
141
+ // First vist, restore and keep the source
142
+ this.storage.copyFrom(this.persistedFields, false);
143
+ // Reset device id
144
+ this._deviceId = this.storage.getData(CoreApp.deviceIdField, '');
145
+ // Totally new, no data restored
146
+ if (this._deviceId === '')
147
+ return false;
148
+ }
149
+ // Device exists or not
150
+ const d = this.getDeviceId();
151
+ if (devices.includes(d)) {
152
+ // Duplicate tab, session data copied
153
+ // Remove the token, deviceId, and passphrase
154
+ this.resetKeys();
155
+ return false;
156
+ }
157
+ const passphraseEncrypted = this.storage.getData(CoreApp.devicePassphraseField);
158
+ if (passphraseEncrypted) {
159
+ const passphraseDecrypted = this.decrypt(passphraseEncrypted, this.name);
160
+ if (passphraseDecrypted != null) {
161
+ // Add the device to the list
162
+ devices.push(d);
163
+ this.storage.setPersistedData(CoreApp.devicesField, devices);
164
+ this.passphrase = passphraseDecrypted;
165
+ return true;
157
166
  }
167
+ // Failed, reset keys
168
+ this.resetKeys();
158
169
  }
159
- // Restore
160
- this.storage.copyFrom(this.persistedFields, true);
161
- return true;
170
+ return false;
162
171
  }
163
172
  /**
164
173
  * Persist settings to source when application exit
@@ -169,6 +178,7 @@ export class CoreApp {
169
178
  if (devices != null) {
170
179
  const index = devices.indexOf(this.getDeviceId());
171
180
  if (index !== -1) {
181
+ // Remove current device from the list
172
182
  devices.splice(index, 1);
173
183
  this.storage.setPersistedData(CoreApp.devicesField, devices);
174
184
  }
@@ -37,6 +37,7 @@
37
37
  "ok": "OK",
38
38
  "open": "Open",
39
39
  "openMenu": "Open menu",
40
+ "operationSucceeded": "Operation succeeded",
40
41
  "pageNotFound": "Page Not Found",
41
42
  "prompt": "Input",
42
43
  "pullToRefresh": "Pull down to refresh",
@@ -46,6 +47,7 @@
46
47
  "reloginTip": "Please enter your password, resubmit the data after successful login",
47
48
  "remove": "Remove",
48
49
  "renew": "Renew",
50
+ "reports": "Reports",
49
51
  "resending": "Resending",
50
52
  "reset": "Reset",
51
53
  "rotateLeft": "Rotate left 90°",
@@ -54,6 +56,7 @@
54
56
  "scrollToTop": "Scroll to top",
55
57
  "send": "Send",
56
58
  "setAsDefault": "Set as default",
59
+ "settings": "Settings",
57
60
  "signout": "Sign out",
58
61
  "smartERP": "SmartERP",
59
62
  "status": "Status",
@@ -37,6 +37,7 @@
37
37
  "ok": "确定",
38
38
  "open": "打开",
39
39
  "openMenu": "打开菜单",
40
+ "operationSucceeded": "操作成功",
40
41
  "pageNotFound": "找不到页面",
41
42
  "prompt": "输入",
42
43
  "pullToRefresh": "下拉刷新",
@@ -46,6 +47,7 @@
46
47
  "reloginTip": "请输入您的登录密码,登录成功后请重新提交数据",
47
48
  "remove": "移除",
48
49
  "renew": "续费",
50
+ "reports": "统计报表",
49
51
  "resending": "重新发送",
50
52
  "reset": "重置",
51
53
  "rotateLeft": "左旋转90°",
@@ -54,6 +56,7 @@
54
56
  "scrollToTop": "回到顶部",
55
57
  "send": "发送",
56
58
  "setAsDefault": "设为默认",
59
+ "settings": "系统设置",
57
60
  "signout": "退出",
58
61
  "smartERP": "司友云ERP",
59
62
  "status": "状态",
@@ -37,6 +37,7 @@
37
37
  "ok": "確定",
38
38
  "open": "打開",
39
39
  "openMenu": "打開菜單",
40
+ "operationSucceeded": "操作成功",
40
41
  "pageNotFound": "找不到頁面",
41
42
  "prompt": "輸入",
42
43
  "pullToRefresh": "下拉刷新",
@@ -46,6 +47,7 @@
46
47
  "reloginTip": "請輸入您的登錄密碼,登錄成功後請重新提交數據",
47
48
  "remove": "移除",
48
49
  "renew": "續費",
50
+ "reports": "統計報表",
49
51
  "resending": "重新發送",
50
52
  "reset": "重置",
51
53
  "rotateLeft": "左旋轉90°",
@@ -54,6 +56,7 @@
54
56
  "scrollToTop": "回到頂部",
55
57
  "send": "發送",
56
58
  "setAsDefault": "設為默認",
59
+ "settings": "系統設置",
57
60
  "signout": "退出",
58
61
  "smartERP": "司友雲ERP",
59
62
  "status": "狀態",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@etsoo/appscript",
3
- "version": "1.2.7",
3
+ "version": "1.2.11",
4
4
  "description": "Applications shared TypeScript framework",
5
5
  "main": "lib/cjs/index.js",
6
6
  "module": "lib/mjs/index.js",
@@ -54,8 +54,8 @@
54
54
  "dependencies": {
55
55
  "@etsoo/notificationbase": "^1.0.95",
56
56
  "@etsoo/restclient": "^1.0.63",
57
- "@etsoo/shared": "^1.0.94",
58
- "@types/crypto-js": "^4.0.2",
57
+ "@etsoo/shared": "^1.0.95",
58
+ "@types/crypto-js": "^4.1.0",
59
59
  "crypto-js": "^4.1.1"
60
60
  },
61
61
  "devDependencies": {
@@ -65,8 +65,8 @@
65
65
  "@babel/preset-env": "^7.16.5",
66
66
  "@babel/runtime-corejs3": "^7.16.5",
67
67
  "@types/jest": "^27.0.3",
68
- "@typescript-eslint/eslint-plugin": "^5.8.0",
69
- "@typescript-eslint/parser": "^5.8.0",
68
+ "@typescript-eslint/eslint-plugin": "^5.8.1",
69
+ "@typescript-eslint/parser": "^5.8.1",
70
70
  "eslint": "^8.5.0",
71
71
  "eslint-config-airbnb-base": "^15.0.0",
72
72
  "eslint-plugin-import": "^2.25.3",
@@ -654,60 +654,71 @@ export abstract class CoreApp<
654
654
  return this.deviceId.substring(0, 15);
655
655
  }
656
656
 
657
+ private resetKeys() {
658
+ this.storage.clear(
659
+ [
660
+ CoreApp.devicePassphraseField,
661
+ CoreApp.headerTokenField,
662
+ CoreApp.serversideDeviceIdField
663
+ ],
664
+ false
665
+ );
666
+ this.passphrase = '';
667
+ }
668
+
657
669
  /**
658
670
  * Restore settings from persisted source
659
671
  */
660
672
  protected restore() {
661
- // Current device id, '' means new, or reload (not included) or duplicate (included)
662
- if (this.deviceId) {
663
- // Devices
664
- const devices = this.storage.getPersistedData<string[]>(
665
- CoreApp.devicesField,
666
- []
667
- );
673
+ // Devices
674
+ const devices = this.storage.getPersistedData<string[]>(
675
+ CoreApp.devicesField,
676
+ []
677
+ );
668
678
 
669
- // Exists in the list?
670
- const d = this.getDeviceId();
671
- if (!devices.includes(d)) {
672
- const passphraseEncrypted = this.storage.getData<string>(
673
- CoreApp.devicePassphraseField
674
- );
675
- if (passphraseEncrypted) {
676
- const passphraseDecrypted = this.decrypt(
677
- passphraseEncrypted,
678
- this.name
679
- );
680
- if (passphraseDecrypted != null) {
681
- this.passphrase = passphraseDecrypted;
679
+ if (this.deviceId === '') {
680
+ // First vist, restore and keep the source
681
+ this.storage.copyFrom(this.persistedFields, false);
682
682
 
683
- devices.push(d);
684
- this.storage.setPersistedData(
685
- CoreApp.devicesField,
686
- devices
687
- );
683
+ // Reset device id
684
+ this._deviceId = this.storage.getData(CoreApp.deviceIdField, '');
688
685
 
689
- return false;
690
- }
691
- }
692
- } else {
693
- // Duplicate tab, session data copied
694
- // Remove the token, deviceId, and passphrase
695
- this.storage.clear(
696
- [
697
- CoreApp.devicePassphraseField,
698
- CoreApp.headerTokenField,
699
- CoreApp.serversideDeviceIdField
700
- ],
701
- false
702
- );
703
- this.passphrase = '';
704
- }
686
+ // Totally new, no data restored
687
+ if (this._deviceId === '') return false;
705
688
  }
706
689
 
707
- // Restore
708
- this.storage.copyFrom(this.persistedFields, true);
690
+ // Device exists or not
691
+ const d = this.getDeviceId();
692
+ if (devices.includes(d)) {
693
+ // Duplicate tab, session data copied
694
+ // Remove the token, deviceId, and passphrase
695
+ this.resetKeys();
696
+ return false;
697
+ }
709
698
 
710
- return true;
699
+ const passphraseEncrypted = this.storage.getData<string>(
700
+ CoreApp.devicePassphraseField
701
+ );
702
+ if (passphraseEncrypted) {
703
+ const passphraseDecrypted = this.decrypt(
704
+ passphraseEncrypted,
705
+ this.name
706
+ );
707
+ if (passphraseDecrypted != null) {
708
+ // Add the device to the list
709
+ devices.push(d);
710
+ this.storage.setPersistedData(CoreApp.devicesField, devices);
711
+
712
+ this.passphrase = passphraseDecrypted;
713
+
714
+ return true;
715
+ }
716
+
717
+ // Failed, reset keys
718
+ this.resetKeys();
719
+ }
720
+
721
+ return false;
711
722
  }
712
723
 
713
724
  /**
@@ -721,6 +732,7 @@ export abstract class CoreApp<
721
732
  if (devices != null) {
722
733
  const index = devices.indexOf(this.getDeviceId());
723
734
  if (index !== -1) {
735
+ // Remove current device from the list
724
736
  devices.splice(index, 1);
725
737
  this.storage.setPersistedData(CoreApp.devicesField, devices);
726
738
  }
@@ -37,6 +37,7 @@
37
37
  "ok": "OK",
38
38
  "open": "Open",
39
39
  "openMenu": "Open menu",
40
+ "operationSucceeded": "Operation succeeded",
40
41
  "pageNotFound": "Page Not Found",
41
42
  "prompt": "Input",
42
43
  "pullToRefresh": "Pull down to refresh",
@@ -46,6 +47,7 @@
46
47
  "reloginTip": "Please enter your password, resubmit the data after successful login",
47
48
  "remove": "Remove",
48
49
  "renew": "Renew",
50
+ "reports": "Reports",
49
51
  "resending": "Resending",
50
52
  "reset": "Reset",
51
53
  "rotateLeft": "Rotate left 90°",
@@ -54,6 +56,7 @@
54
56
  "scrollToTop": "Scroll to top",
55
57
  "send": "Send",
56
58
  "setAsDefault": "Set as default",
59
+ "settings": "Settings",
57
60
  "signout": "Sign out",
58
61
  "smartERP": "SmartERP",
59
62
  "status": "Status",
@@ -37,6 +37,7 @@
37
37
  "ok": "确定",
38
38
  "open": "打开",
39
39
  "openMenu": "打开菜单",
40
+ "operationSucceeded": "操作成功",
40
41
  "pageNotFound": "找不到页面",
41
42
  "prompt": "输入",
42
43
  "pullToRefresh": "下拉刷新",
@@ -46,6 +47,7 @@
46
47
  "reloginTip": "请输入您的登录密码,登录成功后请重新提交数据",
47
48
  "remove": "移除",
48
49
  "renew": "续费",
50
+ "reports": "统计报表",
49
51
  "resending": "重新发送",
50
52
  "reset": "重置",
51
53
  "rotateLeft": "左旋转90°",
@@ -54,6 +56,7 @@
54
56
  "scrollToTop": "回到顶部",
55
57
  "send": "发送",
56
58
  "setAsDefault": "设为默认",
59
+ "settings": "系统设置",
57
60
  "signout": "退出",
58
61
  "smartERP": "司友云ERP",
59
62
  "status": "状态",
@@ -37,6 +37,7 @@
37
37
  "ok": "確定",
38
38
  "open": "打開",
39
39
  "openMenu": "打開菜單",
40
+ "operationSucceeded": "操作成功",
40
41
  "pageNotFound": "找不到頁面",
41
42
  "prompt": "輸入",
42
43
  "pullToRefresh": "下拉刷新",
@@ -46,6 +47,7 @@
46
47
  "reloginTip": "請輸入您的登錄密碼,登錄成功後請重新提交數據",
47
48
  "remove": "移除",
48
49
  "renew": "續費",
50
+ "reports": "統計報表",
49
51
  "resending": "重新發送",
50
52
  "reset": "重置",
51
53
  "rotateLeft": "左旋轉90°",
@@ -54,6 +56,7 @@
54
56
  "scrollToTop": "回到頂部",
55
57
  "send": "發送",
56
58
  "setAsDefault": "設為默認",
59
+ "settings": "系統設置",
57
60
  "signout": "退出",
58
61
  "smartERP": "司友雲ERP",
59
62
  "status": "狀態",