@etsoo/react 1.3.43 → 1.3.44

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
  */
@@ -38,7 +38,7 @@ export declare class ServiceApp<P extends IServicePageData = IServicePageData, U
38
38
  /**
39
39
  * Try login
40
40
  */
41
- tryLogin(): Promise<boolean>;
41
+ tryLogin<D extends {} = {}>(data?: D): Promise<boolean>;
42
42
  /**
43
43
  * User login extended
44
44
  * @param user New user
@@ -1,5 +1,4 @@
1
- import { ActionResultError, createClient } from '@etsoo/appscript';
2
- import { ApiDataError } from '@etsoo/restclient';
1
+ import { createClient } from '@etsoo/appscript';
3
2
  import { DomUtils } from '@etsoo/shared';
4
3
  import { CoreConstants } from './CoreConstants';
5
4
  import { ReactApp } from './ReactApp';
@@ -47,7 +46,7 @@ export class ServiceApp extends ReactApp {
47
46
  */
48
47
  async refreshToken(props) {
49
48
  // Destruct
50
- 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 : {};
51
50
  // Token
52
51
  const token = this.getCacheToken();
53
52
  if (token == null || token === '') {
@@ -72,76 +71,109 @@ export class ServiceApp extends ReactApp {
72
71
  return false;
73
72
  }
74
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
+ };
75
112
  // Call API
76
113
  const result = await this.coreApi.put('Auth/RefreshToken', rq, payload);
77
114
  if (result == null)
78
115
  return false;
79
116
  if (!result.ok) {
80
- if (callback)
81
- callback(result);
82
- return false;
83
- }
84
- // Token
85
- const refreshToken = this.getResponseToken(payload.response);
86
- if (refreshToken == null || result.data == null) {
87
- if (callback)
88
- callback(this.get('noData'));
89
- return false;
90
- }
91
- // User data
92
- const userData = result.data;
93
- // Use core system access token to service api to exchange service access token
94
- const serviceResult = await this.api.put('Auth/ExchangeToken', {
95
- token: userData.token
96
- }, {
97
- showLoading,
98
- onError: (error) => {
99
- if (callback)
100
- callback(error);
101
- // Prevent further processing
102
- 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 = pwd;
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;
103
146
  }
104
- });
105
- if (serviceResult == null)
106
- return false;
107
- if (!serviceResult.ok) {
108
- if (callback)
109
- callback(serviceResult);
110
- return false;
111
- }
112
- if (serviceResult.data == null) {
113
147
  if (callback)
114
- callback(this.get('noData'));
148
+ callback(result);
115
149
  return false;
116
150
  }
117
- this.userLoginEx(serviceResult.data, refreshToken, userData);
118
- return true;
151
+ return await success(result, callback);
119
152
  }
120
153
  /**
121
154
  * Try login
122
155
  */
123
- async tryLogin() {
156
+ async tryLogin(data) {
124
157
  // Reset user state
125
- const result = await super.tryLogin();
158
+ const result = await super.tryLogin(data);
126
159
  if (!result)
127
160
  return false;
128
161
  // Refresh token
129
162
  return await this.refreshToken({
130
163
  callback: (result) => {
131
- if (typeof result === 'boolean') {
164
+ const message = this.formatRefreshTokenResult(result);
165
+ if (message == null) {
132
166
  this.toLoginPage();
133
167
  return;
134
168
  }
135
- const message = result instanceof ApiDataError
136
- ? this.formatError(result)
137
- : typeof result !== 'string'
138
- ? ActionResultError.format(result)
139
- : result;
140
- this.notifier.alert(message, () => {
141
- this.toLoginPage();
142
- });
169
+ else {
170
+ this.notifier.alert(message, () => {
171
+ this.toLoginPage();
172
+ });
173
+ }
143
174
  },
144
- showLoading: true
175
+ data,
176
+ relogin: true
145
177
  });
146
178
  }
147
179
  /**
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@etsoo/react",
3
- "version": "1.3.43",
3
+ "version": "1.3.44",
4
4
  "description": "TypeScript ReactJs framework",
5
5
  "main": "lib/index.js",
6
6
  "types": "lib/index.d.ts",
@@ -50,7 +50,7 @@
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.61",
54
54
  "@etsoo/notificationbase": "^1.0.94",
55
55
  "@etsoo/shared": "^1.0.75",
56
56
  "@mui/icons-material": "^5.2.0",
@@ -89,7 +89,7 @@
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
  */
@@ -1,11 +1,10 @@
1
1
  import {
2
- ActionResultError,
3
2
  createClient,
4
3
  IApi,
5
4
  IApiPayload,
6
- RefreshTokenProps
5
+ RefreshTokenProps,
6
+ RefreshTokenResult
7
7
  } from '@etsoo/appscript';
8
- import { ApiDataError } from '@etsoo/restclient';
9
8
  import { DomUtils } from '@etsoo/shared';
10
9
  import { CoreConstants } from './CoreConstants';
11
10
  import { IServiceAppSettings } from './IServiceAppSettings';
@@ -80,7 +79,12 @@ export class ServiceApp<
80
79
  props?: RefreshTokenProps<D>
81
80
  ) {
82
81
  // Destruct
83
- const { callback, data, showLoading = false } = props ?? {};
82
+ const {
83
+ callback,
84
+ data,
85
+ relogin = false,
86
+ showLoading = false
87
+ } = props ?? {};
84
88
 
85
89
  // Token
86
90
  const token = this.getCacheToken();
@@ -108,6 +112,55 @@ export class ServiceApp<
108
112
  }
109
113
  };
110
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
+
111
164
  // Call API
112
165
  const result = await this.coreApi.put<SmartERPLoginResult>(
113
166
  'Auth/RefreshToken',
@@ -117,82 +170,86 @@ export class ServiceApp<
117
170
  if (result == null) return false;
118
171
 
119
172
  if (!result.ok) {
120
- if (callback) callback(result);
121
- return false;
122
- }
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
+ }
123
184
 
124
- // Token
125
- const refreshToken = this.getResponseToken(payload.response);
126
- if (refreshToken == null || result.data == null) {
127
- if (callback) callback(this.get('noData')!);
128
- return false;
129
- }
185
+ // Set password for the action
186
+ rq.pwd = pwd;
130
187
 
131
- // User data
132
- const userData = result.data;
188
+ // Submit again
189
+ const result = await this.api.put<SmartERPLoginResult>(
190
+ 'Auth/RefreshToken',
191
+ data,
192
+ payload
193
+ );
133
194
 
134
- // Use core system access token to service api to exchange service access token
135
- const serviceResult = await this.api.put<ServiceLoginResult>(
136
- 'Auth/ExchangeToken',
137
- {
138
- token: userData.token
139
- },
140
- {
141
- showLoading,
142
- onError: (error) => {
143
- if (callback) callback(error);
195
+ if (result == null) return;
144
196
 
145
- // Prevent further processing
146
- return false;
147
- }
148
- }
149
- );
197
+ if (result.ok) {
198
+ await success(
199
+ result,
200
+ (loginResult: RefreshTokenResult) => {
201
+ const message =
202
+ this.formatRefreshTokenResult(
203
+ loginResult
204
+ );
205
+ if (message) this.notifier.alert(message);
206
+ }
207
+ );
208
+ return;
209
+ }
150
210
 
151
- if (serviceResult == null) return false;
211
+ // Popup message
212
+ this.alertResult(result);
213
+ return false;
214
+ },
215
+ labels.login,
216
+ { type: 'password' }
217
+ );
152
218
 
153
- if (!serviceResult.ok) {
154
- if (callback) callback(serviceResult);
155
- return false;
156
- }
219
+ // Fake truth to avoid reloading
220
+ return true;
221
+ }
157
222
 
158
- if (serviceResult.data == null) {
159
- if (callback) callback(this.get('noData')!);
223
+ if (callback) callback(result);
160
224
  return false;
161
225
  }
162
226
 
163
- this.userLoginEx(serviceResult.data, refreshToken, userData);
164
-
165
- return true;
227
+ return await success(result, callback);
166
228
  }
167
229
 
168
230
  /**
169
231
  * Try login
170
232
  */
171
- override async tryLogin() {
233
+ override async tryLogin<D extends {} = {}>(data?: D) {
172
234
  // Reset user state
173
- const result = await super.tryLogin();
235
+ const result = await super.tryLogin(data);
174
236
  if (!result) return false;
175
237
 
176
238
  // Refresh token
177
239
  return await this.refreshToken({
178
240
  callback: (result) => {
179
- if (typeof result === 'boolean') {
241
+ const message = this.formatRefreshTokenResult(result);
242
+ if (message == null) {
180
243
  this.toLoginPage();
181
244
  return;
245
+ } else {
246
+ this.notifier.alert(message, () => {
247
+ this.toLoginPage();
248
+ });
182
249
  }
183
-
184
- const message =
185
- result instanceof ApiDataError
186
- ? this.formatError(result)
187
- : typeof result !== 'string'
188
- ? ActionResultError.format(result)
189
- : result;
190
-
191
- this.notifier.alert(message, () => {
192
- this.toLoginPage();
193
- });
194
250
  },
195
- showLoading: true
251
+ data,
252
+ relogin: true
196
253
  });
197
254
  }
198
255