@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.
- package/lib/app/RefreshTokenRQ.d.ts +4 -0
- package/lib/app/ServiceApp.d.ts +1 -1
- package/lib/app/ServiceApp.js +82 -50
- package/package.json +3 -3
- package/src/app/RefreshTokenRQ.ts +5 -0
- package/src/app/ServiceApp.ts +112 -55
package/lib/app/ServiceApp.d.ts
CHANGED
package/lib/app/ServiceApp.js
CHANGED
|
@@ -1,5 +1,4 @@
|
|
|
1
|
-
import {
|
|
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 (
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
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(
|
|
148
|
+
callback(result);
|
|
115
149
|
return false;
|
|
116
150
|
}
|
|
117
|
-
|
|
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
|
-
|
|
164
|
+
const message = this.formatRefreshTokenResult(result);
|
|
165
|
+
if (message == null) {
|
|
132
166
|
this.toLoginPage();
|
|
133
167
|
return;
|
|
134
168
|
}
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
this.notifier.alert(message, () => {
|
|
141
|
-
this.toLoginPage();
|
|
142
|
-
});
|
|
169
|
+
else {
|
|
170
|
+
this.notifier.alert(message, () => {
|
|
171
|
+
this.toLoginPage();
|
|
172
|
+
});
|
|
173
|
+
}
|
|
143
174
|
},
|
|
144
|
-
|
|
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.
|
|
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.
|
|
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
|
|
92
|
+
"ts-jest": "^27.1.0",
|
|
93
93
|
"typescript": "^4.5.2"
|
|
94
94
|
}
|
|
95
95
|
}
|
package/src/app/ServiceApp.ts
CHANGED
|
@@ -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 {
|
|
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 (
|
|
121
|
-
|
|
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
|
-
|
|
125
|
-
|
|
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
|
-
|
|
132
|
-
|
|
188
|
+
// Submit again
|
|
189
|
+
const result = await this.api.put<SmartERPLoginResult>(
|
|
190
|
+
'Auth/RefreshToken',
|
|
191
|
+
data,
|
|
192
|
+
payload
|
|
193
|
+
);
|
|
133
194
|
|
|
134
|
-
|
|
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
|
-
|
|
146
|
-
|
|
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
|
-
|
|
211
|
+
// Popup message
|
|
212
|
+
this.alertResult(result);
|
|
213
|
+
return false;
|
|
214
|
+
},
|
|
215
|
+
labels.login,
|
|
216
|
+
{ type: 'password' }
|
|
217
|
+
);
|
|
152
218
|
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
}
|
|
219
|
+
// Fake truth to avoid reloading
|
|
220
|
+
return true;
|
|
221
|
+
}
|
|
157
222
|
|
|
158
|
-
|
|
159
|
-
if (callback) callback(this.get('noData')!);
|
|
223
|
+
if (callback) callback(result);
|
|
160
224
|
return false;
|
|
161
225
|
}
|
|
162
226
|
|
|
163
|
-
|
|
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
|
-
|
|
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
|
-
|
|
251
|
+
data,
|
|
252
|
+
relogin: true
|
|
196
253
|
});
|
|
197
254
|
}
|
|
198
255
|
|