@etsoo/materialui 1.3.88 → 1.3.89
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/CommonApp.d.ts +3 -4
- package/lib/app/CommonApp.js +6 -46
- package/lib/app/IServiceApp.d.ts +2 -19
- package/lib/app/IServiceAppSettings.d.ts +2 -2
- package/lib/app/IServiceUser.d.ts +0 -4
- package/lib/app/ReactApp.js +2 -2
- package/lib/app/ServiceApp.d.ts +14 -41
- package/lib/app/ServiceApp.js +43 -208
- package/lib/index.d.ts +0 -1
- package/lib/index.js +0 -1
- package/package.json +19 -19
- package/src/app/CommonApp.ts +8 -71
- package/src/app/IServiceApp.ts +2 -25
- package/src/app/IServiceAppSettings.ts +2 -2
- package/src/app/IServiceUser.ts +0 -5
- package/src/app/ReactApp.ts +1 -2
- package/src/app/ServiceApp.ts +60 -294
- package/src/index.ts +0 -1
- package/lib/app/IAppApi.d.ts +0 -29
- package/lib/app/IAppApi.js +0 -1
- package/src/app/IAppApi.ts +0 -37
package/lib/app/CommonApp.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { IAppSettings, IUser, RefreshTokenProps
|
|
1
|
+
import { IAppSettings, IUser, RefreshTokenProps } from "@etsoo/appscript";
|
|
2
2
|
import { IPageData } from "@etsoo/react";
|
|
3
3
|
import { ReactApp } from "./ReactApp";
|
|
4
4
|
/**
|
|
@@ -27,12 +27,11 @@ export declare abstract class CommonApp<U extends IUser = IUser, P extends IPage
|
|
|
27
27
|
* Refresh token
|
|
28
28
|
* @param props Props
|
|
29
29
|
*/
|
|
30
|
-
refreshToken
|
|
30
|
+
refreshToken(props?: RefreshTokenProps): Promise<boolean>;
|
|
31
31
|
/**
|
|
32
32
|
* Try login
|
|
33
|
-
* @param data Additional data
|
|
34
33
|
* @param showLoading Show loading bar or not
|
|
35
34
|
* @returns Result
|
|
36
35
|
*/
|
|
37
|
-
tryLogin
|
|
36
|
+
tryLogin(showLoading?: boolean): Promise<boolean>;
|
|
38
37
|
}
|
package/lib/app/CommonApp.js
CHANGED
|
@@ -37,7 +37,7 @@ export class CommonApp extends ReactApp {
|
|
|
37
37
|
*/
|
|
38
38
|
async refreshToken(props) {
|
|
39
39
|
// Destruct
|
|
40
|
-
const { callback,
|
|
40
|
+
const { callback, showLoading = false } = props ?? {};
|
|
41
41
|
// Token
|
|
42
42
|
const token = this.getCacheToken();
|
|
43
43
|
if (token == null || token === "") {
|
|
@@ -47,10 +47,7 @@ export class CommonApp extends ReactApp {
|
|
|
47
47
|
}
|
|
48
48
|
// Reqest data
|
|
49
49
|
const rq = {
|
|
50
|
-
deviceId: this.deviceId
|
|
51
|
-
region: this.region,
|
|
52
|
-
timezone: this.getTimeZone(),
|
|
53
|
-
...data
|
|
50
|
+
deviceId: this.deviceId
|
|
54
51
|
};
|
|
55
52
|
// Payload
|
|
56
53
|
const payload = {
|
|
@@ -89,41 +86,7 @@ export class CommonApp extends ReactApp {
|
|
|
89
86
|
if (!result.ok) {
|
|
90
87
|
// Remove the wrong token
|
|
91
88
|
this.clearCacheToken();
|
|
92
|
-
|
|
93
|
-
// Try login
|
|
94
|
-
// Dialog to receive password
|
|
95
|
-
var labels = this.getLabels("reloginTip", "login");
|
|
96
|
-
this.notifier.prompt(labels.reloginTip, async (pwd) => {
|
|
97
|
-
if (pwd == null) {
|
|
98
|
-
this.toLoginPage();
|
|
99
|
-
return;
|
|
100
|
-
}
|
|
101
|
-
// Set password for the action
|
|
102
|
-
rq.pwd = this.encrypt(this.hash(pwd));
|
|
103
|
-
// Submit again
|
|
104
|
-
const result = await this.api.put("Auth/RefreshToken", rq, payload);
|
|
105
|
-
if (result == null)
|
|
106
|
-
return;
|
|
107
|
-
if (result.ok) {
|
|
108
|
-
success(result, (loginResult) => {
|
|
109
|
-
if (loginResult === true) {
|
|
110
|
-
if (callback)
|
|
111
|
-
callback(true);
|
|
112
|
-
return;
|
|
113
|
-
}
|
|
114
|
-
const message = this.formatRefreshTokenResult(loginResult);
|
|
115
|
-
if (message)
|
|
116
|
-
this.notifier.alert(message);
|
|
117
|
-
});
|
|
118
|
-
return;
|
|
119
|
-
}
|
|
120
|
-
// Popup message
|
|
121
|
-
this.alertResult(result);
|
|
122
|
-
return false;
|
|
123
|
-
}, labels.login, { type: "password" });
|
|
124
|
-
// Fake truth to avoid reloading
|
|
125
|
-
return true;
|
|
126
|
-
}
|
|
89
|
+
// Callback
|
|
127
90
|
if (callback)
|
|
128
91
|
callback(result);
|
|
129
92
|
return false;
|
|
@@ -132,21 +95,18 @@ export class CommonApp extends ReactApp {
|
|
|
132
95
|
}
|
|
133
96
|
/**
|
|
134
97
|
* Try login
|
|
135
|
-
* @param data Additional data
|
|
136
98
|
* @param showLoading Show loading bar or not
|
|
137
99
|
* @returns Result
|
|
138
100
|
*/
|
|
139
|
-
async tryLogin(
|
|
101
|
+
async tryLogin(showLoading) {
|
|
140
102
|
// Reset user state
|
|
141
|
-
const result = await super.tryLogin(
|
|
103
|
+
const result = await super.tryLogin(showLoading);
|
|
142
104
|
if (!result)
|
|
143
105
|
return false;
|
|
144
106
|
// Refresh token
|
|
145
107
|
return await this.refreshToken({
|
|
146
108
|
callback: (result) => this.doRefreshTokenResult(result),
|
|
147
|
-
|
|
148
|
-
showLoading,
|
|
149
|
-
relogin: true
|
|
109
|
+
showLoading
|
|
150
110
|
});
|
|
151
111
|
}
|
|
152
112
|
}
|
package/lib/app/IServiceApp.d.ts
CHANGED
|
@@ -1,29 +1,12 @@
|
|
|
1
|
-
import { IApi, RefreshTokenResult } from "@etsoo/appscript";
|
|
2
|
-
import { IServiceUser } from "./IServiceUser";
|
|
3
1
|
import { ReactAppType } from "./ReactApp";
|
|
4
|
-
import { IAppApi } from "./IAppApi";
|
|
5
2
|
/**
|
|
6
3
|
* Service application interface
|
|
7
4
|
*/
|
|
8
5
|
export interface IServiceApp extends ReactAppType {
|
|
9
6
|
/**
|
|
10
|
-
*
|
|
7
|
+
* Load core system UI
|
|
11
8
|
*/
|
|
12
|
-
|
|
13
|
-
/**
|
|
14
|
-
* Service user
|
|
15
|
-
*/
|
|
16
|
-
readonly serviceUser?: IServiceUser;
|
|
17
|
-
/**
|
|
18
|
-
* Service application API login
|
|
19
|
-
* @param appApi Service application API
|
|
20
|
-
* @param callback Callback
|
|
21
|
-
*/
|
|
22
|
-
apiLogin(appApi: IAppApi, callback?: (result: RefreshTokenResult, successData?: string) => void): Promise<boolean>;
|
|
23
|
-
/**
|
|
24
|
-
* Load SmartERP core
|
|
25
|
-
*/
|
|
26
|
-
loadSmartERP(): void;
|
|
9
|
+
loadCore(): void;
|
|
27
10
|
/**
|
|
28
11
|
* Service decrypt message
|
|
29
12
|
* @param messageEncrypted Encrypted message
|
package/lib/app/ReactApp.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { BridgeUtils, CoreApp
|
|
1
|
+
import { BridgeUtils, CoreApp } from "@etsoo/appscript";
|
|
2
2
|
import { NotificationMessageType } from "@etsoo/notificationbase";
|
|
3
3
|
import { WindowStorage } from "@etsoo/shared";
|
|
4
4
|
import React from "react";
|
|
@@ -69,7 +69,7 @@ export class ReactApp extends CoreApp {
|
|
|
69
69
|
* @param debug Debug mode
|
|
70
70
|
*/
|
|
71
71
|
constructor(settings, name, debug = false) {
|
|
72
|
-
super(settings,
|
|
72
|
+
super(settings, null, ReactApp.createNotifier(debug), new WindowStorage(), name, debug);
|
|
73
73
|
/**
|
|
74
74
|
* User state
|
|
75
75
|
*/
|
package/lib/app/ServiceApp.d.ts
CHANGED
|
@@ -1,34 +1,24 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { ExternalEndpoint, IApi } from "@etsoo/appscript";
|
|
2
2
|
import { IServiceApp } from "./IServiceApp";
|
|
3
3
|
import { IServiceAppSettings } from "./IServiceAppSettings";
|
|
4
4
|
import { IServicePageData } from "./IServicePage";
|
|
5
5
|
import { IServiceUser } from "./IServiceUser";
|
|
6
|
-
import { ISmartERPUser } from "./ISmartERPUser";
|
|
7
6
|
import { ReactApp } from "./ReactApp";
|
|
8
|
-
import { IAppApi } from "./IAppApi";
|
|
9
|
-
/**
|
|
10
|
-
* Service application refresh token properties
|
|
11
|
-
*/
|
|
12
|
-
export interface ServiceRefreshTokenProps extends RefreshTokenProps<Partial<RefreshTokenRQ>> {
|
|
13
|
-
appApi?: IAppApi;
|
|
14
|
-
}
|
|
15
7
|
/**
|
|
16
8
|
* Core Service App
|
|
17
9
|
* Service login to core system, get the refesh token and access token
|
|
18
10
|
* Use the acess token to the service api, get a service access token
|
|
19
11
|
* Use the new acess token and refresh token to login
|
|
20
12
|
*/
|
|
21
|
-
export declare class ServiceApp<U extends IServiceUser = IServiceUser, P extends IServicePageData = IServicePageData, S extends IServiceAppSettings = IServiceAppSettings> extends ReactApp<S,
|
|
13
|
+
export declare class ServiceApp<U extends IServiceUser = IServiceUser, P extends IServicePageData = IServicePageData, S extends IServiceAppSettings = IServiceAppSettings> extends ReactApp<S, U, P> implements IServiceApp {
|
|
22
14
|
/**
|
|
23
|
-
*
|
|
15
|
+
* Core endpoint
|
|
24
16
|
*/
|
|
25
|
-
|
|
26
|
-
private _serviceUser?;
|
|
17
|
+
protected coreEndpoint: ExternalEndpoint;
|
|
27
18
|
/**
|
|
28
|
-
*
|
|
19
|
+
* Core system API
|
|
29
20
|
*/
|
|
30
|
-
|
|
31
|
-
protected set serviceUser(value: U | undefined);
|
|
21
|
+
readonly coreApi: IApi;
|
|
32
22
|
/**
|
|
33
23
|
* Service passphrase
|
|
34
24
|
*/
|
|
@@ -41,15 +31,9 @@ export declare class ServiceApp<U extends IServiceUser = IServiceUser, P extends
|
|
|
41
31
|
*/
|
|
42
32
|
constructor(settings: S, name: string, debug?: boolean);
|
|
43
33
|
/**
|
|
44
|
-
*
|
|
45
|
-
* @param appApi Service application API
|
|
46
|
-
* @param callback Callback
|
|
34
|
+
* Load core system UI
|
|
47
35
|
*/
|
|
48
|
-
|
|
49
|
-
/**
|
|
50
|
-
* Load SmartERP core
|
|
51
|
-
*/
|
|
52
|
-
loadSmartERP(): void;
|
|
36
|
+
loadCore(): void;
|
|
53
37
|
/**
|
|
54
38
|
* Go to the login page
|
|
55
39
|
* @param tryLogin Try to login again
|
|
@@ -57,10 +41,13 @@ export declare class ServiceApp<U extends IServiceUser = IServiceUser, P extends
|
|
|
57
41
|
*/
|
|
58
42
|
toLoginPage(tryLogin?: boolean, removeUrl?: boolean): void;
|
|
59
43
|
/**
|
|
60
|
-
*
|
|
61
|
-
* @param
|
|
44
|
+
* User login extended
|
|
45
|
+
* @param user New user
|
|
46
|
+
* @param refreshToken Refresh token
|
|
47
|
+
* @param keep Keep in local storage or not
|
|
48
|
+
* @param dispatch User state dispatch
|
|
62
49
|
*/
|
|
63
|
-
refreshToken
|
|
50
|
+
userLogin(user: U, refreshToken: string, keep?: boolean, dispatch?: boolean): void;
|
|
64
51
|
/**
|
|
65
52
|
* Service decrypt message
|
|
66
53
|
* @param messageEncrypted Encrypted message
|
|
@@ -76,18 +63,4 @@ export declare class ServiceApp<U extends IServiceUser = IServiceUser, P extends
|
|
|
76
63
|
* @returns Result
|
|
77
64
|
*/
|
|
78
65
|
serviceEncrypt(message: string, passphrase?: string, iterations?: number): string;
|
|
79
|
-
/**
|
|
80
|
-
* Try login
|
|
81
|
-
* @param data Additional data
|
|
82
|
-
* @param showLoading Show loading bar or not
|
|
83
|
-
* @returns Result
|
|
84
|
-
*/
|
|
85
|
-
tryLogin<D extends object = {}>(data?: D, showLoading?: boolean): Promise<boolean>;
|
|
86
|
-
/**
|
|
87
|
-
* User login extended
|
|
88
|
-
* @param user Core system user
|
|
89
|
-
* @param refreshToken Refresh token
|
|
90
|
-
* @param serviceUser Service user
|
|
91
|
-
*/
|
|
92
|
-
userLoginEx(user: ISmartERPUser, refreshToken: string, serviceUser: U): void;
|
|
93
66
|
}
|
package/lib/app/ServiceApp.js
CHANGED
|
@@ -1,7 +1,6 @@
|
|
|
1
|
-
import { BridgeUtils
|
|
2
|
-
import { CoreConstants } from "@etsoo/react";
|
|
3
|
-
import { DomUtils } from "@etsoo/shared";
|
|
1
|
+
import { BridgeUtils } from "@etsoo/appscript";
|
|
4
2
|
import { ReactApp } from "./ReactApp";
|
|
3
|
+
const coreName = "core";
|
|
5
4
|
/**
|
|
6
5
|
* Core Service App
|
|
7
6
|
* Service login to core system, get the refesh token and access token
|
|
@@ -9,15 +8,6 @@ import { ReactApp } from "./ReactApp";
|
|
|
9
8
|
* Use the new acess token and refresh token to login
|
|
10
9
|
*/
|
|
11
10
|
export class ServiceApp extends ReactApp {
|
|
12
|
-
/**
|
|
13
|
-
* Service user
|
|
14
|
-
*/
|
|
15
|
-
get serviceUser() {
|
|
16
|
-
return this._serviceUser;
|
|
17
|
-
}
|
|
18
|
-
set serviceUser(value) {
|
|
19
|
-
this._serviceUser = value;
|
|
20
|
-
}
|
|
21
11
|
/**
|
|
22
12
|
* Constructor
|
|
23
13
|
* @param settings Settings
|
|
@@ -31,39 +21,25 @@ export class ServiceApp extends ReactApp {
|
|
|
31
21
|
*/
|
|
32
22
|
this.servicePassphrase = "";
|
|
33
23
|
// Check
|
|
34
|
-
if (settings.
|
|
35
|
-
throw new Error("
|
|
24
|
+
if (settings.appId == null) {
|
|
25
|
+
throw new Error("Service Application ID is required.");
|
|
36
26
|
}
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
this.
|
|
43
|
-
}
|
|
44
|
-
/**
|
|
45
|
-
* Service application API login
|
|
46
|
-
* @param appApi Service application API
|
|
47
|
-
* @param callback Callback
|
|
48
|
-
*/
|
|
49
|
-
apiLogin(appApi, callback) {
|
|
50
|
-
return this.refreshToken({
|
|
51
|
-
callback,
|
|
52
|
-
data: appApi.getRefreshTokenData(),
|
|
53
|
-
relogin: false,
|
|
54
|
-
showLoading: false,
|
|
55
|
-
appApi
|
|
56
|
-
});
|
|
27
|
+
const coreEndpoint = settings.endpoints?.core;
|
|
28
|
+
if (coreEndpoint == null) {
|
|
29
|
+
throw new Error("Core API endpont is required.");
|
|
30
|
+
}
|
|
31
|
+
this.coreEndpoint = coreEndpoint;
|
|
32
|
+
this.coreApi = this.createApi(coreName, coreEndpoint);
|
|
57
33
|
}
|
|
58
34
|
/**
|
|
59
|
-
* Load
|
|
35
|
+
* Load core system UI
|
|
60
36
|
*/
|
|
61
|
-
|
|
37
|
+
loadCore() {
|
|
62
38
|
if (BridgeUtils.host == null) {
|
|
63
|
-
|
|
39
|
+
globalThis.location.href = this.coreEndpoint.webUrl;
|
|
64
40
|
}
|
|
65
41
|
else {
|
|
66
|
-
BridgeUtils.host.loadApp(
|
|
42
|
+
BridgeUtils.host.loadApp(coreName);
|
|
67
43
|
}
|
|
68
44
|
}
|
|
69
45
|
/**
|
|
@@ -72,145 +48,41 @@ export class ServiceApp extends ReactApp {
|
|
|
72
48
|
* @param removeUrl Remove current URL for reuse
|
|
73
49
|
*/
|
|
74
50
|
toLoginPage(tryLogin, removeUrl) {
|
|
75
|
-
|
|
51
|
+
// Cache current URL
|
|
52
|
+
this.cachedUrl = removeUrl ? undefined : globalThis.location.href;
|
|
76
53
|
// Make sure apply new device id for new login
|
|
77
54
|
this.clearDeviceId();
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
}
|
|
82
|
-
else {
|
|
83
|
-
BridgeUtils.host.loadApp("core", parameters);
|
|
84
|
-
}
|
|
85
|
-
}
|
|
86
|
-
/**
|
|
87
|
-
* Refresh token
|
|
88
|
-
* @param props Props
|
|
89
|
-
*/
|
|
90
|
-
async refreshToken(props) {
|
|
91
|
-
// Destruct
|
|
92
|
-
const { appApi, callback, data, relogin = false, showLoading = false } = props ?? {};
|
|
93
|
-
// Token
|
|
94
|
-
const token = this.getCacheToken();
|
|
95
|
-
if (token == null || token === "") {
|
|
96
|
-
if (callback)
|
|
97
|
-
callback(false);
|
|
98
|
-
return false;
|
|
99
|
-
}
|
|
100
|
-
// Reqest data
|
|
101
|
-
// Merge additional data passed
|
|
102
|
-
const rq = {
|
|
103
|
-
deviceId: this.deviceId,
|
|
55
|
+
// Get the redirect URL
|
|
56
|
+
this.api
|
|
57
|
+
.get("Auth/GetLogInUrl", {
|
|
104
58
|
region: this.region,
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
if (callback)
|
|
114
|
-
callback(error);
|
|
115
|
-
// Prevent further processing
|
|
116
|
-
return false;
|
|
117
|
-
}
|
|
118
|
-
};
|
|
119
|
-
// Success callback
|
|
120
|
-
const success = async (result, failCallback) => {
|
|
121
|
-
// Token
|
|
122
|
-
const refreshToken = this.getResponseToken(payload.response);
|
|
123
|
-
if (refreshToken == null || result.data == null) {
|
|
124
|
-
if (failCallback)
|
|
125
|
-
failCallback(this.get("noData"));
|
|
126
|
-
return false;
|
|
127
|
-
}
|
|
128
|
-
// User data
|
|
129
|
-
const userData = result.data;
|
|
130
|
-
// Use core system access token to service api to exchange service access token
|
|
131
|
-
const api = appApi ? appApi.api : this.serviceApi;
|
|
132
|
-
const serviceResult = await api.put("Auth/ExchangeToken", {
|
|
133
|
-
token: this.encryptEnhanced(userData.token, (appApi?.serviceId ?? this.settings.serviceId).toString())
|
|
134
|
-
}, {
|
|
135
|
-
showLoading,
|
|
136
|
-
onError: (error) => {
|
|
137
|
-
if (failCallback)
|
|
138
|
-
failCallback(error);
|
|
139
|
-
// Prevent further processing
|
|
140
|
-
return false;
|
|
141
|
-
}
|
|
142
|
-
});
|
|
143
|
-
if (serviceResult == null)
|
|
144
|
-
return false;
|
|
145
|
-
if (!serviceResult.ok) {
|
|
146
|
-
if (failCallback)
|
|
147
|
-
failCallback(serviceResult);
|
|
148
|
-
return false;
|
|
149
|
-
}
|
|
150
|
-
if (serviceResult.data == null) {
|
|
151
|
-
if (failCallback)
|
|
152
|
-
failCallback(this.get("noData"));
|
|
153
|
-
return false;
|
|
154
|
-
}
|
|
155
|
-
// Login
|
|
156
|
-
if (appApi) {
|
|
157
|
-
// Authorize external service application API
|
|
158
|
-
appApi.authorize(userData, refreshToken, serviceResult.data);
|
|
59
|
+
device: this.deviceId
|
|
60
|
+
})
|
|
61
|
+
.then((url) => {
|
|
62
|
+
if (!url)
|
|
63
|
+
return;
|
|
64
|
+
url += `?tryLogin=${tryLogin ?? false}`;
|
|
65
|
+
if (BridgeUtils.host == null) {
|
|
66
|
+
globalThis.location.href = url;
|
|
159
67
|
}
|
|
160
68
|
else {
|
|
161
|
-
|
|
162
|
-
this.userLoginEx(userData, refreshToken, serviceResult.data);
|
|
69
|
+
BridgeUtils.host.loadApp(coreName, url);
|
|
163
70
|
}
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
if (pwd == null) {
|
|
180
|
-
this.toLoginPage();
|
|
181
|
-
return;
|
|
182
|
-
}
|
|
183
|
-
// Set password for the action
|
|
184
|
-
rq.pwd = this.encrypt(this.hash(pwd));
|
|
185
|
-
// Submit again
|
|
186
|
-
const result = await this.api.put("Auth/RefreshToken", rq, payload);
|
|
187
|
-
if (result == null)
|
|
188
|
-
return;
|
|
189
|
-
if (result.ok) {
|
|
190
|
-
await success(result, (loginResult) => {
|
|
191
|
-
if (loginResult === true) {
|
|
192
|
-
if (callback)
|
|
193
|
-
callback(true);
|
|
194
|
-
return;
|
|
195
|
-
}
|
|
196
|
-
const message = this.formatRefreshTokenResult(loginResult);
|
|
197
|
-
if (message)
|
|
198
|
-
this.notifier.alert(message);
|
|
199
|
-
});
|
|
200
|
-
return;
|
|
201
|
-
}
|
|
202
|
-
// Popup message
|
|
203
|
-
this.alertResult(result);
|
|
204
|
-
return false;
|
|
205
|
-
}, labels.login, { type: "password" });
|
|
206
|
-
// Fake truth to avoid reloading
|
|
207
|
-
return true;
|
|
208
|
-
}
|
|
209
|
-
if (callback)
|
|
210
|
-
callback(result);
|
|
211
|
-
return false;
|
|
212
|
-
}
|
|
213
|
-
return await success(result, callback);
|
|
71
|
+
});
|
|
72
|
+
}
|
|
73
|
+
/**
|
|
74
|
+
* User login extended
|
|
75
|
+
* @param user New user
|
|
76
|
+
* @param refreshToken Refresh token
|
|
77
|
+
* @param keep Keep in local storage or not
|
|
78
|
+
* @param dispatch User state dispatch
|
|
79
|
+
*/
|
|
80
|
+
userLogin(user, refreshToken, keep, dispatch) {
|
|
81
|
+
// Super call, set token
|
|
82
|
+
super.userLogin(user, refreshToken, keep, dispatch);
|
|
83
|
+
// Set service passphrase
|
|
84
|
+
this.servicePassphrase =
|
|
85
|
+
this.decrypt(user.servicePassphrase, `${user.uid}-${this.settings.appId}`) ?? "";
|
|
214
86
|
}
|
|
215
87
|
/**
|
|
216
88
|
* Service decrypt message
|
|
@@ -231,41 +103,4 @@ export class ServiceApp extends ReactApp {
|
|
|
231
103
|
serviceEncrypt(message, passphrase, iterations) {
|
|
232
104
|
return this.encrypt(message, passphrase ?? this.servicePassphrase, iterations);
|
|
233
105
|
}
|
|
234
|
-
/**
|
|
235
|
-
* Try login
|
|
236
|
-
* @param data Additional data
|
|
237
|
-
* @param showLoading Show loading bar or not
|
|
238
|
-
* @returns Result
|
|
239
|
-
*/
|
|
240
|
-
async tryLogin(data, showLoading) {
|
|
241
|
-
// Reset user state
|
|
242
|
-
const result = await super.tryLogin(data, showLoading);
|
|
243
|
-
if (!result)
|
|
244
|
-
return false;
|
|
245
|
-
// Refresh token
|
|
246
|
-
return await this.refreshToken({
|
|
247
|
-
callback: (result) => this.doRefreshTokenResult(result),
|
|
248
|
-
data,
|
|
249
|
-
showLoading,
|
|
250
|
-
relogin: true
|
|
251
|
-
});
|
|
252
|
-
}
|
|
253
|
-
/**
|
|
254
|
-
* User login extended
|
|
255
|
-
* @param user Core system user
|
|
256
|
-
* @param refreshToken Refresh token
|
|
257
|
-
* @param serviceUser Service user
|
|
258
|
-
*/
|
|
259
|
-
userLoginEx(user, refreshToken, serviceUser) {
|
|
260
|
-
// Service user login
|
|
261
|
-
this.servicePassphrase =
|
|
262
|
-
this.decrypt(serviceUser.servicePassphrase, this.settings.serviceId.toString()) ?? "";
|
|
263
|
-
// Service user
|
|
264
|
-
this.serviceUser = serviceUser;
|
|
265
|
-
// Service API token
|
|
266
|
-
this.serviceApi.authorize(serviceUser.tokenScheme ?? "Bearer", serviceUser.token);
|
|
267
|
-
// Keep = true, means service could hold the refresh token for long access
|
|
268
|
-
// Trigger Context change and serviceUser is ready then
|
|
269
|
-
super.userLogin(user, refreshToken, true);
|
|
270
|
-
}
|
|
271
106
|
}
|
package/lib/index.d.ts
CHANGED
package/lib/index.js
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@etsoo/materialui",
|
|
3
|
-
"version": "1.3.
|
|
3
|
+
"version": "1.3.89",
|
|
4
4
|
"description": "TypeScript Material-UI Implementation",
|
|
5
5
|
"main": "lib/index.js",
|
|
6
6
|
"types": "lib/index.d.ts",
|
|
@@ -47,16 +47,16 @@
|
|
|
47
47
|
"dependencies": {
|
|
48
48
|
"@dnd-kit/core": "^6.1.0",
|
|
49
49
|
"@dnd-kit/sortable": "^8.0.0",
|
|
50
|
-
"@emotion/css": "^11.13.
|
|
50
|
+
"@emotion/css": "^11.13.4",
|
|
51
51
|
"@emotion/react": "^11.13.3",
|
|
52
52
|
"@emotion/styled": "^11.13.0",
|
|
53
|
-
"@etsoo/appscript": "^1.5.
|
|
54
|
-
"@etsoo/notificationbase": "^1.1.
|
|
55
|
-
"@etsoo/react": "^1.7.
|
|
56
|
-
"@etsoo/shared": "^1.2.
|
|
57
|
-
"@mui/icons-material": "^6.1.
|
|
58
|
-
"@mui/material": "^6.1.
|
|
59
|
-
"@mui/x-data-grid": "^7.
|
|
53
|
+
"@etsoo/appscript": "^1.5.22",
|
|
54
|
+
"@etsoo/notificationbase": "^1.1.48",
|
|
55
|
+
"@etsoo/react": "^1.7.68",
|
|
56
|
+
"@etsoo/shared": "^1.2.46",
|
|
57
|
+
"@mui/icons-material": "^6.1.2",
|
|
58
|
+
"@mui/material": "^6.1.2",
|
|
59
|
+
"@mui/x-data-grid": "^7.19.0",
|
|
60
60
|
"chart.js": "^4.4.4",
|
|
61
61
|
"chartjs-plugin-datalabels": "^2.2.0",
|
|
62
62
|
"eventemitter3": "^5.0.1",
|
|
@@ -70,25 +70,25 @@
|
|
|
70
70
|
"react-imask": "7.6.1"
|
|
71
71
|
},
|
|
72
72
|
"devDependencies": {
|
|
73
|
-
"@babel/cli": "^7.25.
|
|
74
|
-
"@babel/core": "^7.25.
|
|
75
|
-
"@babel/plugin-transform-runtime": "^7.25.
|
|
76
|
-
"@babel/preset-env": "^7.25.
|
|
77
|
-
"@babel/preset-react": "^7.
|
|
78
|
-
"@babel/preset-typescript": "^7.
|
|
79
|
-
"@babel/runtime-corejs3": "^7.25.
|
|
73
|
+
"@babel/cli": "^7.25.7",
|
|
74
|
+
"@babel/core": "^7.25.7",
|
|
75
|
+
"@babel/plugin-transform-runtime": "^7.25.7",
|
|
76
|
+
"@babel/preset-env": "^7.25.7",
|
|
77
|
+
"@babel/preset-react": "^7.25.7",
|
|
78
|
+
"@babel/preset-typescript": "^7.25.7",
|
|
79
|
+
"@babel/runtime-corejs3": "^7.25.7",
|
|
80
80
|
"@testing-library/jest-dom": "^6.5.0",
|
|
81
81
|
"@testing-library/react": "^16.0.1",
|
|
82
82
|
"@types/jest": "^29.5.13",
|
|
83
83
|
"@types/pica": "^9.0.4",
|
|
84
84
|
"@types/pulltorefreshjs": "^0.1.7",
|
|
85
|
-
"@types/react": "^18.3.
|
|
85
|
+
"@types/react": "^18.3.11",
|
|
86
86
|
"@types/react-avatar-editor": "^13.0.3",
|
|
87
87
|
"@types/react-dom": "^18.3.0",
|
|
88
88
|
"@types/react-input-mask": "^3.0.5",
|
|
89
89
|
"@types/react-window": "^1.8.8",
|
|
90
|
-
"@typescript-eslint/eslint-plugin": "^8.
|
|
91
|
-
"@typescript-eslint/parser": "^8.
|
|
90
|
+
"@typescript-eslint/eslint-plugin": "^8.8.0",
|
|
91
|
+
"@typescript-eslint/parser": "^8.8.0",
|
|
92
92
|
"jest": "^29.7.0",
|
|
93
93
|
"jest-environment-jsdom": "^29.7.0",
|
|
94
94
|
"typescript": "^5.6.2"
|
package/src/app/CommonApp.ts
CHANGED
|
@@ -56,16 +56,9 @@ export abstract class CommonApp<
|
|
|
56
56
|
* Refresh token
|
|
57
57
|
* @param props Props
|
|
58
58
|
*/
|
|
59
|
-
override async refreshToken
|
|
60
|
-
props?: RefreshTokenProps<D>
|
|
61
|
-
) {
|
|
59
|
+
override async refreshToken(props?: RefreshTokenProps) {
|
|
62
60
|
// Destruct
|
|
63
|
-
const {
|
|
64
|
-
callback,
|
|
65
|
-
data,
|
|
66
|
-
relogin = false,
|
|
67
|
-
showLoading = false
|
|
68
|
-
} = props ?? {};
|
|
61
|
+
const { callback, showLoading = false } = props ?? {};
|
|
69
62
|
|
|
70
63
|
// Token
|
|
71
64
|
const token = this.getCacheToken();
|
|
@@ -76,10 +69,7 @@ export abstract class CommonApp<
|
|
|
76
69
|
|
|
77
70
|
// Reqest data
|
|
78
71
|
const rq: RefreshTokenRQ = {
|
|
79
|
-
deviceId: this.deviceId
|
|
80
|
-
region: this.region,
|
|
81
|
-
timezone: this.getTimeZone(),
|
|
82
|
-
...data
|
|
72
|
+
deviceId: this.deviceId
|
|
83
73
|
};
|
|
84
74
|
|
|
85
75
|
// Login result type
|
|
@@ -135,56 +125,9 @@ export abstract class CommonApp<
|
|
|
135
125
|
// Remove the wrong token
|
|
136
126
|
this.clearCacheToken();
|
|
137
127
|
|
|
138
|
-
|
|
139
|
-
// Try login
|
|
140
|
-
// Dialog to receive password
|
|
141
|
-
var labels = this.getLabels("reloginTip", "login");
|
|
142
|
-
this.notifier.prompt(
|
|
143
|
-
labels.reloginTip,
|
|
144
|
-
async (pwd) => {
|
|
145
|
-
if (pwd == null) {
|
|
146
|
-
this.toLoginPage();
|
|
147
|
-
return;
|
|
148
|
-
}
|
|
149
|
-
|
|
150
|
-
// Set password for the action
|
|
151
|
-
rq.pwd = this.encrypt(this.hash(pwd));
|
|
152
|
-
|
|
153
|
-
// Submit again
|
|
154
|
-
const result = await this.api.put<LoginResult>(
|
|
155
|
-
"Auth/RefreshToken",
|
|
156
|
-
rq,
|
|
157
|
-
payload
|
|
158
|
-
);
|
|
159
|
-
|
|
160
|
-
if (result == null) return;
|
|
161
|
-
|
|
162
|
-
if (result.ok) {
|
|
163
|
-
success(result, (loginResult: RefreshTokenResult) => {
|
|
164
|
-
if (loginResult === true) {
|
|
165
|
-
if (callback) callback(true);
|
|
166
|
-
return;
|
|
167
|
-
}
|
|
168
|
-
|
|
169
|
-
const message = this.formatRefreshTokenResult(loginResult);
|
|
170
|
-
if (message) this.notifier.alert(message);
|
|
171
|
-
});
|
|
172
|
-
return;
|
|
173
|
-
}
|
|
174
|
-
|
|
175
|
-
// Popup message
|
|
176
|
-
this.alertResult(result);
|
|
177
|
-
return false;
|
|
178
|
-
},
|
|
179
|
-
labels.login,
|
|
180
|
-
{ type: "password" }
|
|
181
|
-
);
|
|
182
|
-
|
|
183
|
-
// Fake truth to avoid reloading
|
|
184
|
-
return true;
|
|
185
|
-
}
|
|
186
|
-
|
|
128
|
+
// Callback
|
|
187
129
|
if (callback) callback(result);
|
|
130
|
+
|
|
188
131
|
return false;
|
|
189
132
|
}
|
|
190
133
|
|
|
@@ -193,24 +136,18 @@ export abstract class CommonApp<
|
|
|
193
136
|
|
|
194
137
|
/**
|
|
195
138
|
* Try login
|
|
196
|
-
* @param data Additional data
|
|
197
139
|
* @param showLoading Show loading bar or not
|
|
198
140
|
* @returns Result
|
|
199
141
|
*/
|
|
200
|
-
override async tryLogin
|
|
201
|
-
data?: D,
|
|
202
|
-
showLoading?: boolean
|
|
203
|
-
) {
|
|
142
|
+
override async tryLogin(showLoading?: boolean) {
|
|
204
143
|
// Reset user state
|
|
205
|
-
const result = await super.tryLogin(
|
|
144
|
+
const result = await super.tryLogin(showLoading);
|
|
206
145
|
if (!result) return false;
|
|
207
146
|
|
|
208
147
|
// Refresh token
|
|
209
148
|
return await this.refreshToken({
|
|
210
149
|
callback: (result) => this.doRefreshTokenResult(result),
|
|
211
|
-
|
|
212
|
-
showLoading,
|
|
213
|
-
relogin: true
|
|
150
|
+
showLoading
|
|
214
151
|
});
|
|
215
152
|
}
|
|
216
153
|
}
|
package/src/app/IServiceApp.ts
CHANGED
|
@@ -1,36 +1,13 @@
|
|
|
1
|
-
import { IApi, RefreshTokenResult } from "@etsoo/appscript";
|
|
2
|
-
import { IServiceUser } from "./IServiceUser";
|
|
3
1
|
import { ReactAppType } from "./ReactApp";
|
|
4
|
-
import { IAppApi } from "./IAppApi";
|
|
5
2
|
|
|
6
3
|
/**
|
|
7
4
|
* Service application interface
|
|
8
5
|
*/
|
|
9
6
|
export interface IServiceApp extends ReactAppType {
|
|
10
7
|
/**
|
|
11
|
-
*
|
|
8
|
+
* Load core system UI
|
|
12
9
|
*/
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
/**
|
|
16
|
-
* Service user
|
|
17
|
-
*/
|
|
18
|
-
readonly serviceUser?: IServiceUser;
|
|
19
|
-
|
|
20
|
-
/**
|
|
21
|
-
* Service application API login
|
|
22
|
-
* @param appApi Service application API
|
|
23
|
-
* @param callback Callback
|
|
24
|
-
*/
|
|
25
|
-
apiLogin(
|
|
26
|
-
appApi: IAppApi,
|
|
27
|
-
callback?: (result: RefreshTokenResult, successData?: string) => void
|
|
28
|
-
): Promise<boolean>;
|
|
29
|
-
|
|
30
|
-
/**
|
|
31
|
-
* Load SmartERP core
|
|
32
|
-
*/
|
|
33
|
-
loadSmartERP(): void;
|
|
10
|
+
loadCore(): void;
|
|
34
11
|
|
|
35
12
|
/**
|
|
36
13
|
* Service decrypt message
|
package/src/app/IServiceUser.ts
CHANGED
package/src/app/ReactApp.ts
CHANGED
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import {
|
|
2
2
|
BridgeUtils,
|
|
3
3
|
CoreApp,
|
|
4
|
-
createClient,
|
|
5
4
|
FormatResultCustomCallback,
|
|
6
5
|
IApp,
|
|
7
6
|
IAppSettings,
|
|
@@ -253,7 +252,7 @@ export class ReactApp<
|
|
|
253
252
|
constructor(settings: S, name: string, debug: boolean = false) {
|
|
254
253
|
super(
|
|
255
254
|
settings,
|
|
256
|
-
|
|
255
|
+
null,
|
|
257
256
|
ReactApp.createNotifier(debug),
|
|
258
257
|
new WindowStorage(),
|
|
259
258
|
name,
|
package/src/app/ServiceApp.ts
CHANGED
|
@@ -1,29 +1,11 @@
|
|
|
1
|
-
import {
|
|
2
|
-
BridgeUtils,
|
|
3
|
-
createClient,
|
|
4
|
-
IApi,
|
|
5
|
-
IApiPayload,
|
|
6
|
-
RefreshTokenProps,
|
|
7
|
-
RefreshTokenResult,
|
|
8
|
-
RefreshTokenRQ
|
|
9
|
-
} from "@etsoo/appscript";
|
|
10
|
-
import { CoreConstants } from "@etsoo/react";
|
|
11
|
-
import { DomUtils, IActionResult } from "@etsoo/shared";
|
|
1
|
+
import { BridgeUtils, ExternalEndpoint, IApi } from "@etsoo/appscript";
|
|
12
2
|
import { IServiceApp } from "./IServiceApp";
|
|
13
3
|
import { IServiceAppSettings } from "./IServiceAppSettings";
|
|
14
4
|
import { IServicePageData } from "./IServicePage";
|
|
15
|
-
import { IServiceUser
|
|
16
|
-
import { ISmartERPUser } from "./ISmartERPUser";
|
|
5
|
+
import { IServiceUser } from "./IServiceUser";
|
|
17
6
|
import { ReactApp } from "./ReactApp";
|
|
18
|
-
import { IAppApi } from "./IAppApi";
|
|
19
7
|
|
|
20
|
-
|
|
21
|
-
* Service application refresh token properties
|
|
22
|
-
*/
|
|
23
|
-
export interface ServiceRefreshTokenProps
|
|
24
|
-
extends RefreshTokenProps<Partial<RefreshTokenRQ>> {
|
|
25
|
-
appApi?: IAppApi;
|
|
26
|
-
}
|
|
8
|
+
const coreName = "core";
|
|
27
9
|
|
|
28
10
|
/**
|
|
29
11
|
* Core Service App
|
|
@@ -36,24 +18,18 @@ export class ServiceApp<
|
|
|
36
18
|
P extends IServicePageData = IServicePageData,
|
|
37
19
|
S extends IServiceAppSettings = IServiceAppSettings
|
|
38
20
|
>
|
|
39
|
-
extends ReactApp<S,
|
|
21
|
+
extends ReactApp<S, U, P>
|
|
40
22
|
implements IServiceApp
|
|
41
23
|
{
|
|
42
24
|
/**
|
|
43
|
-
*
|
|
25
|
+
* Core endpoint
|
|
44
26
|
*/
|
|
45
|
-
|
|
27
|
+
protected coreEndpoint: ExternalEndpoint;
|
|
46
28
|
|
|
47
|
-
private _serviceUser?: U;
|
|
48
29
|
/**
|
|
49
|
-
*
|
|
30
|
+
* Core system API
|
|
50
31
|
*/
|
|
51
|
-
|
|
52
|
-
return this._serviceUser;
|
|
53
|
-
}
|
|
54
|
-
protected set serviceUser(value: U | undefined) {
|
|
55
|
-
this._serviceUser = value;
|
|
56
|
-
}
|
|
32
|
+
readonly coreApi: IApi;
|
|
57
33
|
|
|
58
34
|
/**
|
|
59
35
|
* Service passphrase
|
|
@@ -70,46 +46,27 @@ export class ServiceApp<
|
|
|
70
46
|
super(settings, name, debug);
|
|
71
47
|
|
|
72
48
|
// Check
|
|
73
|
-
if (settings.
|
|
74
|
-
throw new Error("
|
|
49
|
+
if (settings.appId == null) {
|
|
50
|
+
throw new Error("Service Application ID is required.");
|
|
75
51
|
}
|
|
76
52
|
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
api.baseUrl = settings.serviceEndpoint;
|
|
83
|
-
|
|
84
|
-
this.serviceApi = api;
|
|
85
|
-
}
|
|
53
|
+
const coreEndpoint = settings.endpoints?.core;
|
|
54
|
+
if (coreEndpoint == null) {
|
|
55
|
+
throw new Error("Core API endpont is required.");
|
|
56
|
+
}
|
|
57
|
+
this.coreEndpoint = coreEndpoint;
|
|
86
58
|
|
|
87
|
-
|
|
88
|
-
* Service application API login
|
|
89
|
-
* @param appApi Service application API
|
|
90
|
-
* @param callback Callback
|
|
91
|
-
*/
|
|
92
|
-
apiLogin(
|
|
93
|
-
appApi: IAppApi,
|
|
94
|
-
callback?: (result: RefreshTokenResult, successData?: string) => void
|
|
95
|
-
) {
|
|
96
|
-
return this.refreshToken({
|
|
97
|
-
callback,
|
|
98
|
-
data: appApi.getRefreshTokenData(),
|
|
99
|
-
relogin: false,
|
|
100
|
-
showLoading: false,
|
|
101
|
-
appApi
|
|
102
|
-
});
|
|
59
|
+
this.coreApi = this.createApi(coreName, coreEndpoint);
|
|
103
60
|
}
|
|
104
61
|
|
|
105
62
|
/**
|
|
106
|
-
* Load
|
|
63
|
+
* Load core system UI
|
|
107
64
|
*/
|
|
108
|
-
|
|
65
|
+
loadCore() {
|
|
109
66
|
if (BridgeUtils.host == null) {
|
|
110
|
-
|
|
67
|
+
globalThis.location.href = this.coreEndpoint.webUrl;
|
|
111
68
|
} else {
|
|
112
|
-
BridgeUtils.host.loadApp(
|
|
69
|
+
BridgeUtils.host.loadApp(coreName);
|
|
113
70
|
}
|
|
114
71
|
}
|
|
115
72
|
|
|
@@ -119,193 +76,53 @@ export class ServiceApp<
|
|
|
119
76
|
* @param removeUrl Remove current URL for reuse
|
|
120
77
|
*/
|
|
121
78
|
override toLoginPage(tryLogin?: boolean, removeUrl?: boolean) {
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
removeUrl ? "" : "&url=" + encodeURIComponent(location.href)
|
|
126
|
-
}`;
|
|
79
|
+
// Cache current URL
|
|
80
|
+
this.cachedUrl = removeUrl ? undefined : globalThis.location.href;
|
|
81
|
+
|
|
127
82
|
// Make sure apply new device id for new login
|
|
128
83
|
this.clearDeviceId();
|
|
129
84
|
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
85
|
+
// Get the redirect URL
|
|
86
|
+
this.api
|
|
87
|
+
.get<string>("Auth/GetLogInUrl", {
|
|
88
|
+
region: this.region,
|
|
89
|
+
device: this.deviceId
|
|
90
|
+
})
|
|
91
|
+
.then((url) => {
|
|
92
|
+
if (!url) return;
|
|
93
|
+
|
|
94
|
+
url += `?tryLogin=${tryLogin ?? false}`;
|
|
95
|
+
|
|
96
|
+
if (BridgeUtils.host == null) {
|
|
97
|
+
globalThis.location.href = url;
|
|
98
|
+
} else {
|
|
99
|
+
BridgeUtils.host.loadApp(coreName, url);
|
|
100
|
+
}
|
|
101
|
+
});
|
|
136
102
|
}
|
|
137
103
|
|
|
138
104
|
/**
|
|
139
|
-
*
|
|
140
|
-
* @param
|
|
105
|
+
* User login extended
|
|
106
|
+
* @param user New user
|
|
107
|
+
* @param refreshToken Refresh token
|
|
108
|
+
* @param keep Keep in local storage or not
|
|
109
|
+
* @param dispatch User state dispatch
|
|
141
110
|
*/
|
|
142
|
-
override
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
}
|
|
158
|
-
|
|
159
|
-
// Reqest data
|
|
160
|
-
// Merge additional data passed
|
|
161
|
-
const rq: RefreshTokenRQ = {
|
|
162
|
-
deviceId: this.deviceId,
|
|
163
|
-
region: this.region,
|
|
164
|
-
timezone: this.getTimeZone(),
|
|
165
|
-
...data
|
|
166
|
-
};
|
|
167
|
-
|
|
168
|
-
// Login result type
|
|
169
|
-
type LoginResult = IActionResult<U>;
|
|
170
|
-
|
|
171
|
-
// Payload
|
|
172
|
-
const payload: IApiPayload<LoginResult, any> = {
|
|
173
|
-
showLoading,
|
|
174
|
-
config: { headers: { [CoreConstants.TokenHeaderRefresh]: token } },
|
|
175
|
-
onError: (error) => {
|
|
176
|
-
if (callback) callback(error);
|
|
177
|
-
|
|
178
|
-
// Prevent further processing
|
|
179
|
-
return false;
|
|
180
|
-
}
|
|
181
|
-
};
|
|
182
|
-
|
|
183
|
-
// Success callback
|
|
184
|
-
const success = async (
|
|
185
|
-
result: LoginResult,
|
|
186
|
-
failCallback?: (result: RefreshTokenResult) => void
|
|
187
|
-
) => {
|
|
188
|
-
// Token
|
|
189
|
-
const refreshToken = this.getResponseToken(payload.response);
|
|
190
|
-
if (refreshToken == null || result.data == null) {
|
|
191
|
-
if (failCallback) failCallback(this.get("noData")!);
|
|
192
|
-
return false;
|
|
193
|
-
}
|
|
194
|
-
|
|
195
|
-
// User data
|
|
196
|
-
const userData = result.data;
|
|
197
|
-
|
|
198
|
-
// Use core system access token to service api to exchange service access token
|
|
199
|
-
const api = appApi ? appApi.api : this.serviceApi;
|
|
200
|
-
const serviceResult = await api.put<ServiceLoginResult<U>>(
|
|
201
|
-
"Auth/ExchangeToken",
|
|
202
|
-
{
|
|
203
|
-
token: this.encryptEnhanced(
|
|
204
|
-
userData.token,
|
|
205
|
-
(appApi?.serviceId ?? this.settings.serviceId).toString()
|
|
206
|
-
)
|
|
207
|
-
},
|
|
208
|
-
{
|
|
209
|
-
showLoading,
|
|
210
|
-
onError: (error) => {
|
|
211
|
-
if (failCallback) failCallback(error);
|
|
212
|
-
|
|
213
|
-
// Prevent further processing
|
|
214
|
-
return false;
|
|
215
|
-
}
|
|
216
|
-
}
|
|
217
|
-
);
|
|
218
|
-
|
|
219
|
-
if (serviceResult == null) return false;
|
|
220
|
-
|
|
221
|
-
if (!serviceResult.ok) {
|
|
222
|
-
if (failCallback) failCallback(serviceResult);
|
|
223
|
-
return false;
|
|
224
|
-
}
|
|
225
|
-
|
|
226
|
-
if (serviceResult.data == null) {
|
|
227
|
-
if (failCallback) failCallback(this.get("noData")!);
|
|
228
|
-
return false;
|
|
229
|
-
}
|
|
230
|
-
|
|
231
|
-
// Login
|
|
232
|
-
if (appApi) {
|
|
233
|
-
// Authorize external service application API
|
|
234
|
-
appApi.authorize(userData, refreshToken, serviceResult.data);
|
|
235
|
-
} else {
|
|
236
|
-
// Authorize local service
|
|
237
|
-
this.userLoginEx(userData, refreshToken, serviceResult.data);
|
|
238
|
-
}
|
|
239
|
-
|
|
240
|
-
// Success callback
|
|
241
|
-
if (failCallback) failCallback(true);
|
|
242
|
-
|
|
243
|
-
return true;
|
|
244
|
-
};
|
|
245
|
-
|
|
246
|
-
// Call API
|
|
247
|
-
const result = await this.api.put<LoginResult>(
|
|
248
|
-
"Auth/RefreshToken",
|
|
249
|
-
rq,
|
|
250
|
-
payload
|
|
251
|
-
);
|
|
252
|
-
if (result == null) return false;
|
|
253
|
-
|
|
254
|
-
if (!result.ok) {
|
|
255
|
-
if (result.type === "TokenExpired" && relogin) {
|
|
256
|
-
// Try login
|
|
257
|
-
// Dialog to receive password
|
|
258
|
-
var labels = this.getLabels("reloginTip", "login");
|
|
259
|
-
this.notifier.prompt(
|
|
260
|
-
labels.reloginTip,
|
|
261
|
-
async (pwd) => {
|
|
262
|
-
if (pwd == null) {
|
|
263
|
-
this.toLoginPage();
|
|
264
|
-
return;
|
|
265
|
-
}
|
|
266
|
-
|
|
267
|
-
// Set password for the action
|
|
268
|
-
rq.pwd = this.encrypt(this.hash(pwd));
|
|
269
|
-
|
|
270
|
-
// Submit again
|
|
271
|
-
const result = await this.api.put<LoginResult>(
|
|
272
|
-
"Auth/RefreshToken",
|
|
273
|
-
rq,
|
|
274
|
-
payload
|
|
275
|
-
);
|
|
276
|
-
|
|
277
|
-
if (result == null) return;
|
|
278
|
-
|
|
279
|
-
if (result.ok) {
|
|
280
|
-
await success(result, (loginResult: RefreshTokenResult) => {
|
|
281
|
-
if (loginResult === true) {
|
|
282
|
-
if (callback) callback(true);
|
|
283
|
-
return;
|
|
284
|
-
}
|
|
285
|
-
|
|
286
|
-
const message = this.formatRefreshTokenResult(loginResult);
|
|
287
|
-
if (message) this.notifier.alert(message);
|
|
288
|
-
});
|
|
289
|
-
return;
|
|
290
|
-
}
|
|
291
|
-
|
|
292
|
-
// Popup message
|
|
293
|
-
this.alertResult(result);
|
|
294
|
-
return false;
|
|
295
|
-
},
|
|
296
|
-
labels.login,
|
|
297
|
-
{ type: "password" }
|
|
298
|
-
);
|
|
299
|
-
|
|
300
|
-
// Fake truth to avoid reloading
|
|
301
|
-
return true;
|
|
302
|
-
}
|
|
303
|
-
|
|
304
|
-
if (callback) callback(result);
|
|
305
|
-
return false;
|
|
306
|
-
}
|
|
307
|
-
|
|
308
|
-
return await success(result, callback);
|
|
111
|
+
override userLogin(
|
|
112
|
+
user: U,
|
|
113
|
+
refreshToken: string,
|
|
114
|
+
keep?: boolean,
|
|
115
|
+
dispatch?: boolean
|
|
116
|
+
): void {
|
|
117
|
+
// Super call, set token
|
|
118
|
+
super.userLogin(user, refreshToken, keep, dispatch);
|
|
119
|
+
|
|
120
|
+
// Set service passphrase
|
|
121
|
+
this.servicePassphrase =
|
|
122
|
+
this.decrypt(
|
|
123
|
+
user.servicePassphrase,
|
|
124
|
+
`${user.uid}-${this.settings.appId}`
|
|
125
|
+
) ?? "";
|
|
309
126
|
}
|
|
310
127
|
|
|
311
128
|
/**
|
|
@@ -332,55 +149,4 @@ export class ServiceApp<
|
|
|
332
149
|
iterations
|
|
333
150
|
);
|
|
334
151
|
}
|
|
335
|
-
|
|
336
|
-
/**
|
|
337
|
-
* Try login
|
|
338
|
-
* @param data Additional data
|
|
339
|
-
* @param showLoading Show loading bar or not
|
|
340
|
-
* @returns Result
|
|
341
|
-
*/
|
|
342
|
-
override async tryLogin<D extends object = {}>(
|
|
343
|
-
data?: D,
|
|
344
|
-
showLoading?: boolean
|
|
345
|
-
) {
|
|
346
|
-
// Reset user state
|
|
347
|
-
const result = await super.tryLogin(data, showLoading);
|
|
348
|
-
if (!result) return false;
|
|
349
|
-
|
|
350
|
-
// Refresh token
|
|
351
|
-
return await this.refreshToken({
|
|
352
|
-
callback: (result) => this.doRefreshTokenResult(result),
|
|
353
|
-
data,
|
|
354
|
-
showLoading,
|
|
355
|
-
relogin: true
|
|
356
|
-
});
|
|
357
|
-
}
|
|
358
|
-
|
|
359
|
-
/**
|
|
360
|
-
* User login extended
|
|
361
|
-
* @param user Core system user
|
|
362
|
-
* @param refreshToken Refresh token
|
|
363
|
-
* @param serviceUser Service user
|
|
364
|
-
*/
|
|
365
|
-
userLoginEx(user: ISmartERPUser, refreshToken: string, serviceUser: U) {
|
|
366
|
-
// Service user login
|
|
367
|
-
this.servicePassphrase =
|
|
368
|
-
this.decrypt(
|
|
369
|
-
serviceUser.servicePassphrase,
|
|
370
|
-
this.settings.serviceId.toString()
|
|
371
|
-
) ?? "";
|
|
372
|
-
|
|
373
|
-
// Service user
|
|
374
|
-
this.serviceUser = serviceUser;
|
|
375
|
-
|
|
376
|
-
// Service API token
|
|
377
|
-
this.serviceApi.authorize(
|
|
378
|
-
serviceUser.tokenScheme ?? "Bearer",
|
|
379
|
-
serviceUser.token
|
|
380
|
-
);
|
|
381
|
-
|
|
382
|
-
// Keep = true, means service could hold the refresh token for long access
|
|
383
|
-
// Trigger Context change and serviceUser is ready then
|
|
384
|
-
super.userLogin(user, refreshToken, true);
|
|
385
|
-
}
|
|
386
152
|
}
|
package/src/index.ts
CHANGED
package/lib/app/IAppApi.d.ts
DELETED
|
@@ -1,29 +0,0 @@
|
|
|
1
|
-
import { IApi } from "@etsoo/restclient";
|
|
2
|
-
import { ISmartERPUser } from "./ISmartERPUser";
|
|
3
|
-
import { RefreshTokenRQ } from "@etsoo/appscript";
|
|
4
|
-
import { IServiceUser } from "./IServiceUser";
|
|
5
|
-
/**
|
|
6
|
-
* Service application API, Implement interface calls between different services
|
|
7
|
-
* 服务程序接口,实现不同服务之间的接口调用
|
|
8
|
-
*/
|
|
9
|
-
export interface IAppApi {
|
|
10
|
-
/**
|
|
11
|
-
* API
|
|
12
|
-
*/
|
|
13
|
-
readonly api: IApi<any>;
|
|
14
|
-
/**
|
|
15
|
-
* Service id
|
|
16
|
-
*/
|
|
17
|
-
readonly serviceId: number;
|
|
18
|
-
/**
|
|
19
|
-
* Authorize the API
|
|
20
|
-
* @param user SmartERP user
|
|
21
|
-
* @param refreshToken SmartERP user refresh token
|
|
22
|
-
* @param serviceUser Service user
|
|
23
|
-
*/
|
|
24
|
-
authorize(user: ISmartERPUser, refreshToken: string, serviceUser: IServiceUser): void;
|
|
25
|
-
/**
|
|
26
|
-
* Get refresh token data
|
|
27
|
-
*/
|
|
28
|
-
getRefreshTokenData(): Partial<RefreshTokenRQ>;
|
|
29
|
-
}
|
package/lib/app/IAppApi.js
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export {};
|
package/src/app/IAppApi.ts
DELETED
|
@@ -1,37 +0,0 @@
|
|
|
1
|
-
import { IApi } from "@etsoo/restclient";
|
|
2
|
-
import { ISmartERPUser } from "./ISmartERPUser";
|
|
3
|
-
import { RefreshTokenRQ } from "@etsoo/appscript";
|
|
4
|
-
import { IServiceUser } from "./IServiceUser";
|
|
5
|
-
|
|
6
|
-
/**
|
|
7
|
-
* Service application API, Implement interface calls between different services
|
|
8
|
-
* 服务程序接口,实现不同服务之间的接口调用
|
|
9
|
-
*/
|
|
10
|
-
export interface IAppApi {
|
|
11
|
-
/**
|
|
12
|
-
* API
|
|
13
|
-
*/
|
|
14
|
-
readonly api: IApi<any>;
|
|
15
|
-
|
|
16
|
-
/**
|
|
17
|
-
* Service id
|
|
18
|
-
*/
|
|
19
|
-
readonly serviceId: number;
|
|
20
|
-
|
|
21
|
-
/**
|
|
22
|
-
* Authorize the API
|
|
23
|
-
* @param user SmartERP user
|
|
24
|
-
* @param refreshToken SmartERP user refresh token
|
|
25
|
-
* @param serviceUser Service user
|
|
26
|
-
*/
|
|
27
|
-
authorize(
|
|
28
|
-
user: ISmartERPUser,
|
|
29
|
-
refreshToken: string,
|
|
30
|
-
serviceUser: IServiceUser
|
|
31
|
-
): void;
|
|
32
|
-
|
|
33
|
-
/**
|
|
34
|
-
* Get refresh token data
|
|
35
|
-
*/
|
|
36
|
-
getRefreshTokenData(): Partial<RefreshTokenRQ>;
|
|
37
|
-
}
|