@etsoo/react 1.3.42 → 1.3.46

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.
@@ -2,6 +2,10 @@
2
2
  * Refresh token request data
3
3
  */
4
4
  export declare type RefreshTokenRQ = {
5
+ /**
6
+ * Login password
7
+ */
8
+ pwd?: string;
5
9
  /**
6
10
  * Service id
7
11
  */
@@ -35,10 +35,11 @@ export declare class ServiceApp<P extends IServicePageData = IServicePageData, U
35
35
  * @param props Props
36
36
  */
37
37
  refreshToken<D = RefreshTokenRQ>(props?: RefreshTokenProps<D>): Promise<boolean>;
38
+ private loginFailed;
38
39
  /**
39
40
  * Try login
40
41
  */
41
- tryLogin(): Promise<boolean>;
42
+ tryLogin<D extends {} = {}>(data?: D): Promise<boolean>;
42
43
  /**
43
44
  * User login extended
44
45
  * @param user New user
@@ -46,7 +46,7 @@ export class ServiceApp extends ReactApp {
46
46
  */
47
47
  async refreshToken(props) {
48
48
  // Destruct
49
- const { callback, data, showLoading = false } = props !== null && props !== void 0 ? props : {};
49
+ const { callback, data, relogin = false, showLoading = false } = props !== null && props !== void 0 ? props : {};
50
50
  // Token
51
51
  const token = this.getCacheToken();
52
52
  if (token == null || token === '') {
@@ -71,64 +71,111 @@ export class ServiceApp extends ReactApp {
71
71
  return false;
72
72
  }
73
73
  };
74
+ // Success callback
75
+ const success = async (result, failCallback) => {
76
+ // Token
77
+ const refreshToken = this.getResponseToken(payload.response);
78
+ if (refreshToken == null || result.data == null) {
79
+ if (failCallback)
80
+ failCallback(this.get('noData'));
81
+ return false;
82
+ }
83
+ // User data
84
+ const userData = result.data;
85
+ // Use core system access token to service api to exchange service access token
86
+ const serviceResult = await this.api.put('Auth/ExchangeToken', {
87
+ token: userData.token
88
+ }, {
89
+ showLoading,
90
+ onError: (error) => {
91
+ if (failCallback)
92
+ failCallback(error);
93
+ // Prevent further processing
94
+ return false;
95
+ }
96
+ });
97
+ if (serviceResult == null)
98
+ return false;
99
+ if (!serviceResult.ok) {
100
+ if (failCallback)
101
+ failCallback(serviceResult);
102
+ return false;
103
+ }
104
+ if (serviceResult.data == null) {
105
+ if (failCallback)
106
+ failCallback(this.get('noData'));
107
+ return false;
108
+ }
109
+ this.userLoginEx(serviceResult.data, refreshToken, userData);
110
+ return true;
111
+ };
74
112
  // Call API
75
113
  const result = await this.coreApi.put('Auth/RefreshToken', rq, payload);
76
114
  if (result == null)
77
115
  return false;
78
116
  if (!result.ok) {
79
- if (callback)
80
- callback(result);
81
- return false;
82
- }
83
- // Token
84
- const refreshToken = this.getResponseToken(payload.response);
85
- if (refreshToken == null || result.data == null) {
86
- if (callback)
87
- callback(this.get('noData'));
88
- return false;
89
- }
90
- // User data
91
- const userData = result.data;
92
- // Use core system access token to service api to exchange service access token
93
- const serviceResult = await this.api.put('Auth/ExchangeToken', {
94
- token: userData.token
95
- }, {
96
- showLoading,
97
- onError: (error) => {
98
- if (callback)
99
- callback(error);
100
- // Prevent further processing
101
- return false;
117
+ if (result.type === 'TokenExpired' && relogin) {
118
+ // Try login
119
+ // Dialog to receive password
120
+ var labels = this.getLabels('reloginTip', 'login');
121
+ this.notifier.prompt(labels.reloginTip, async (pwd) => {
122
+ if (pwd == null) {
123
+ this.toLoginPage();
124
+ return;
125
+ }
126
+ // Set password for the action
127
+ rq.pwd = this.encrypt(pwd, this.settings.serviceId.toString());
128
+ // Submit again
129
+ const result = await this.api.put('Auth/RefreshToken', data, payload);
130
+ if (result == null)
131
+ return;
132
+ if (result.ok) {
133
+ await success(result, (loginResult) => {
134
+ const message = this.formatRefreshTokenResult(loginResult);
135
+ if (message)
136
+ this.notifier.alert(message);
137
+ });
138
+ return;
139
+ }
140
+ // Popup message
141
+ this.alertResult(result);
142
+ return false;
143
+ }, labels.login, { type: 'password' });
144
+ // Fake truth to avoid reloading
145
+ return true;
102
146
  }
103
- });
104
- if (serviceResult == null)
105
- return false;
106
- if (!serviceResult.ok) {
107
- if (callback)
108
- callback(serviceResult);
109
- return false;
110
- }
111
- if (serviceResult.data == null) {
112
147
  if (callback)
113
- callback(this.get('noData'));
148
+ callback(result);
114
149
  return false;
115
150
  }
116
- this.userLoginEx(serviceResult.data, refreshToken, userData);
117
- return true;
151
+ return await success(result, callback);
152
+ }
153
+ loginFailed() {
154
+ this.userUnauthorized();
155
+ this.toLoginPage();
118
156
  }
119
157
  /**
120
158
  * Try login
121
159
  */
122
- async tryLogin() {
160
+ async tryLogin(data) {
123
161
  // Reset user state
124
- const result = await super.tryLogin();
162
+ const result = await super.tryLogin(data);
125
163
  if (!result)
126
164
  return false;
127
165
  // Refresh token
128
166
  return await this.refreshToken({
129
- callback: (_result) => {
130
- this.toLoginPage();
131
- }
167
+ callback: (result) => {
168
+ const message = this.formatRefreshTokenResult(result);
169
+ if (message == null) {
170
+ this.loginFailed();
171
+ return;
172
+ }
173
+ this.notifier.alert(message, () => {
174
+ this.loginFailed();
175
+ });
176
+ },
177
+ data,
178
+ relogin: true
132
179
  });
133
180
  }
134
181
  /**
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@etsoo/react",
3
- "version": "1.3.42",
3
+ "version": "1.3.46",
4
4
  "description": "TypeScript ReactJs framework",
5
5
  "main": "lib/index.js",
6
6
  "types": "lib/index.d.ts",
@@ -50,11 +50,11 @@
50
50
  "@emotion/react": "^11.7.0",
51
51
  "@emotion/style": "^0.8.0",
52
52
  "@emotion/styled": "^11.6.0",
53
- "@etsoo/appscript": "^1.1.56",
53
+ "@etsoo/appscript": "^1.1.65",
54
54
  "@etsoo/notificationbase": "^1.0.94",
55
- "@etsoo/shared": "^1.0.75",
56
- "@mui/icons-material": "^5.2.0",
57
- "@mui/material": "^5.2.2",
55
+ "@etsoo/shared": "^1.0.76",
56
+ "@mui/icons-material": "^5.2.1",
57
+ "@mui/material": "^5.2.3",
58
58
  "@reach/router": "^1.3.4",
59
59
  "@types/pica": "^5.1.3",
60
60
  "@types/pulltorefreshjs": "^0.1.5",
@@ -81,15 +81,15 @@
81
81
  "@babel/runtime-corejs3": "^7.16.3",
82
82
  "@types/jest": "^27.0.3",
83
83
  "@types/react-test-renderer": "^17.0.1",
84
- "@typescript-eslint/eslint-plugin": "^5.5.0",
85
- "@typescript-eslint/parser": "^5.5.0",
84
+ "@typescript-eslint/eslint-plugin": "^5.6.0",
85
+ "@typescript-eslint/parser": "^5.6.0",
86
86
  "eslint": "^8.4.0",
87
87
  "eslint-config-airbnb-base": "^15.0.0",
88
88
  "eslint-plugin-import": "^2.25.3",
89
89
  "eslint-plugin-react": "^7.27.1",
90
90
  "jest": "^27.4.3",
91
91
  "react-test-renderer": "^17.0.2",
92
- "ts-jest": "^27.0.7",
92
+ "ts-jest": "^27.1.0",
93
93
  "typescript": "^4.5.2"
94
94
  }
95
95
  }
@@ -2,6 +2,11 @@
2
2
  * Refresh token request data
3
3
  */
4
4
  export type RefreshTokenRQ = {
5
+ /**
6
+ * Login password
7
+ */
8
+ pwd?: string;
9
+
5
10
  /**
6
11
  * Service id
7
12
  */
@@ -2,7 +2,8 @@ import {
2
2
  createClient,
3
3
  IApi,
4
4
  IApiPayload,
5
- RefreshTokenProps
5
+ RefreshTokenProps,
6
+ RefreshTokenResult
6
7
  } from '@etsoo/appscript';
7
8
  import { DomUtils } from '@etsoo/shared';
8
9
  import { CoreConstants } from './CoreConstants';
@@ -78,7 +79,12 @@ export class ServiceApp<
78
79
  props?: RefreshTokenProps<D>
79
80
  ) {
80
81
  // Destruct
81
- const { callback, data, showLoading = false } = props ?? {};
82
+ const {
83
+ callback,
84
+ data,
85
+ relogin = false,
86
+ showLoading = false
87
+ } = props ?? {};
82
88
 
83
89
  // Token
84
90
  const token = this.getCacheToken();
@@ -106,6 +112,55 @@ export class ServiceApp<
106
112
  }
107
113
  };
108
114
 
115
+ // Success callback
116
+ const success = async (
117
+ result: SmartERPLoginResult,
118
+ failCallback?: (result: RefreshTokenResult) => void
119
+ ) => {
120
+ // Token
121
+ const refreshToken = this.getResponseToken(payload.response);
122
+ if (refreshToken == null || result.data == null) {
123
+ if (failCallback) failCallback(this.get('noData')!);
124
+ return false;
125
+ }
126
+
127
+ // User data
128
+ const userData = result.data;
129
+
130
+ // Use core system access token to service api to exchange service access token
131
+ const serviceResult = await this.api.put<ServiceLoginResult>(
132
+ 'Auth/ExchangeToken',
133
+ {
134
+ token: userData.token
135
+ },
136
+ {
137
+ showLoading,
138
+ onError: (error) => {
139
+ if (failCallback) failCallback(error);
140
+
141
+ // Prevent further processing
142
+ return false;
143
+ }
144
+ }
145
+ );
146
+
147
+ if (serviceResult == null) return false;
148
+
149
+ if (!serviceResult.ok) {
150
+ if (failCallback) failCallback(serviceResult);
151
+ return false;
152
+ }
153
+
154
+ if (serviceResult.data == null) {
155
+ if (failCallback) failCallback(this.get('noData')!);
156
+ return false;
157
+ }
158
+
159
+ this.userLoginEx(serviceResult.data, refreshToken, userData);
160
+
161
+ return true;
162
+ };
163
+
109
164
  // Call API
110
165
  const result = await this.coreApi.put<SmartERPLoginResult>(
111
166
  'Auth/RefreshToken',
@@ -115,67 +170,94 @@ export class ServiceApp<
115
170
  if (result == null) return false;
116
171
 
117
172
  if (!result.ok) {
118
- if (callback) callback(result);
119
- return false;
120
- }
173
+ if (result.type === 'TokenExpired' && relogin) {
174
+ // Try login
175
+ // Dialog to receive password
176
+ var labels = this.getLabels('reloginTip', 'login');
177
+ this.notifier.prompt(
178
+ labels.reloginTip,
179
+ async (pwd) => {
180
+ if (pwd == null) {
181
+ this.toLoginPage();
182
+ return;
183
+ }
121
184
 
122
- // Token
123
- const refreshToken = this.getResponseToken(payload.response);
124
- if (refreshToken == null || result.data == null) {
125
- if (callback) callback(this.get('noData')!);
126
- return false;
127
- }
185
+ // Set password for the action
186
+ rq.pwd = this.encrypt(
187
+ pwd,
188
+ this.settings.serviceId.toString()
189
+ );
128
190
 
129
- // User data
130
- const userData = result.data;
191
+ // Submit again
192
+ const result = await this.api.put<SmartERPLoginResult>(
193
+ 'Auth/RefreshToken',
194
+ data,
195
+ payload
196
+ );
131
197
 
132
- // Use core system access token to service api to exchange service access token
133
- const serviceResult = await this.api.put<ServiceLoginResult>(
134
- 'Auth/ExchangeToken',
135
- {
136
- token: userData.token
137
- },
138
- {
139
- showLoading,
140
- onError: (error) => {
141
- if (callback) callback(error);
198
+ if (result == null) return;
142
199
 
143
- // Prevent further processing
144
- return false;
145
- }
146
- }
147
- );
200
+ if (result.ok) {
201
+ await success(
202
+ result,
203
+ (loginResult: RefreshTokenResult) => {
204
+ const message =
205
+ this.formatRefreshTokenResult(
206
+ loginResult
207
+ );
208
+ if (message) this.notifier.alert(message);
209
+ }
210
+ );
211
+ return;
212
+ }
148
213
 
149
- if (serviceResult == null) return false;
214
+ // Popup message
215
+ this.alertResult(result);
216
+ return false;
217
+ },
218
+ labels.login,
219
+ { type: 'password' }
220
+ );
150
221
 
151
- if (!serviceResult.ok) {
152
- if (callback) callback(serviceResult);
153
- return false;
154
- }
222
+ // Fake truth to avoid reloading
223
+ return true;
224
+ }
155
225
 
156
- if (serviceResult.data == null) {
157
- if (callback) callback(this.get('noData')!);
226
+ if (callback) callback(result);
158
227
  return false;
159
228
  }
160
229
 
161
- this.userLoginEx(serviceResult.data, refreshToken, userData);
230
+ return await success(result, callback);
231
+ }
162
232
 
163
- return true;
233
+ private loginFailed() {
234
+ this.userUnauthorized();
235
+ this.toLoginPage();
164
236
  }
165
237
 
166
238
  /**
167
239
  * Try login
168
240
  */
169
- override async tryLogin() {
241
+ override async tryLogin<D extends {} = {}>(data?: D) {
170
242
  // Reset user state
171
- const result = await super.tryLogin();
243
+ const result = await super.tryLogin(data);
172
244
  if (!result) return false;
173
245
 
174
246
  // Refresh token
175
247
  return await this.refreshToken({
176
- callback: (_result) => {
177
- this.toLoginPage();
178
- }
248
+ callback: (result) => {
249
+ const message = this.formatRefreshTokenResult(result);
250
+ if (message == null) {
251
+ this.loginFailed();
252
+ return;
253
+ }
254
+
255
+ this.notifier.alert(message, () => {
256
+ this.loginFailed();
257
+ });
258
+ },
259
+ data,
260
+ relogin: true
179
261
  });
180
262
  }
181
263