login-authorization-v2 1.1.4 → 2.0.0-beta.1
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/README.md +54 -54
- package/babel.config.js +6 -0
- package/coverage/clover.xml +140 -0
- package/coverage/coverage-final.json +8 -0
- package/coverage/lcov-report/base.css +224 -0
- package/coverage/lcov-report/block-navigation.js +87 -0
- package/coverage/lcov-report/common-authorization-v2/index.html +116 -0
- package/coverage/lcov-report/common-authorization-v2/index.ts.html +547 -0
- package/coverage/lcov-report/common-authorization-v2/src/compatible.ts.html +223 -0
- package/coverage/lcov-report/common-authorization-v2/src/constance.ts.html +106 -0
- package/coverage/lcov-report/common-authorization-v2/src/cookie.ts.html +346 -0
- package/coverage/lcov-report/common-authorization-v2/src/dom.ts.html +262 -0
- package/coverage/lcov-report/common-authorization-v2/src/index.html +206 -0
- package/coverage/lcov-report/common-authorization-v2/src/request.ts.html +361 -0
- package/coverage/lcov-report/common-authorization-v2/src/shares.ts.html +163 -0
- package/coverage/lcov-report/common-authorization-v2/src/types.ts.html +412 -0
- package/coverage/lcov-report/common-authorization-v2/src/utils.ts.html +145 -0
- package/coverage/lcov-report/compatible.ts.html +223 -0
- package/coverage/lcov-report/constance.ts.html +106 -0
- package/coverage/lcov-report/cookie.ts.html +310 -0
- package/coverage/lcov-report/dom.ts.html +262 -0
- package/coverage/lcov-report/favicon.png +0 -0
- package/coverage/lcov-report/index.html +206 -0
- package/coverage/lcov-report/prettify.css +1 -0
- package/coverage/lcov-report/prettify.js +2 -0
- package/coverage/lcov-report/shares.ts.html +163 -0
- package/coverage/lcov-report/sort-arrow-sprite.png +0 -0
- package/coverage/lcov-report/sorter.js +210 -0
- package/coverage/lcov-report/types.ts.html +412 -0
- package/coverage/lcov-report/utils.ts.html +145 -0
- package/coverage/lcov.info +268 -0
- package/dist/compatible.d.ts +10 -0
- package/dist/compatible.d.ts.map +1 -0
- package/dist/constance.d.ts +6 -0
- package/dist/constance.d.ts.map +1 -0
- package/dist/cookie.d.ts +8 -0
- package/dist/cookie.d.ts.map +1 -0
- package/dist/dom.d.ts +2 -0
- package/dist/dom.d.ts.map +1 -0
- package/dist/index.d.ts +15 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.esm.js +498 -0
- package/dist/index.js.LICENSE.txt +1 -0
- package/dist/{index.js → index.umd.js} +125 -14
- package/dist/request.d.ts +36 -0
- package/dist/request.d.ts.map +1 -0
- package/dist/shares.d.ts +10 -0
- package/dist/shares.d.ts.map +1 -0
- package/dist/src/compatible.d.ts +10 -0
- package/dist/src/compatible.d.ts.map +1 -0
- package/dist/src/constance.d.ts +8 -0
- package/dist/src/constance.d.ts.map +1 -0
- package/dist/src/cookie.d.ts +8 -0
- package/dist/src/cookie.d.ts.map +1 -0
- package/dist/src/dom.d.ts +3 -0
- package/dist/src/dom.d.ts.map +1 -0
- package/dist/src/request.d.ts +36 -0
- package/dist/src/request.d.ts.map +1 -0
- package/dist/src/shares.d.ts +10 -0
- package/dist/src/shares.d.ts.map +1 -0
- package/dist/src/types.d.ts +89 -0
- package/dist/src/types.d.ts.map +1 -0
- package/dist/src/utils.d.ts +4 -0
- package/dist/src/utils.d.ts.map +1 -0
- package/dist/test/cookie.test.d.ts +2 -0
- package/dist/test/cookie.test.d.ts.map +1 -0
- package/dist/test/shares.test.d.ts +2 -0
- package/dist/test/shares.test.d.ts.map +1 -0
- package/dist/types.d.ts +89 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/utils.d.ts +2 -0
- package/dist/utils.d.ts.map +1 -0
- package/index.html +28 -0
- package/index.ts +154 -0
- package/jest.config.js +6 -0
- package/package.json +55 -28
- package/src/compatible.ts +46 -0
- package/src/constance.ts +7 -0
- package/src/cookie.ts +75 -0
- package/src/dom.ts +59 -0
- package/src/request.ts +99 -0
- package/src/shares.ts +26 -0
- package/src/types.ts +109 -0
- package/src/utils.ts +20 -0
- package/tests/compatible.test.ts +420 -0
- package/tests/cookie.test.ts +78 -0
- package/tests/dom.test.ts +95 -0
- package/tests/index.test.ts +126 -0
- package/tests/shares.test.ts +52 -0
- package/tests/utils.test.ts +79 -0
- package/tsconfig.json +49 -0
- package/webpack.config.mjs +47 -0
- package/index.js +0 -304
- package/webpack.config.js +0 -9
package/dist/types.d.ts
ADDED
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
declare const modules: readonly [{
|
|
2
|
+
readonly href: "";
|
|
3
|
+
readonly name: "commonLogin";
|
|
4
|
+
}, {
|
|
5
|
+
readonly href: "";
|
|
6
|
+
readonly name: "App";
|
|
7
|
+
}, {
|
|
8
|
+
readonly href: "";
|
|
9
|
+
readonly name: "Portal";
|
|
10
|
+
}, {
|
|
11
|
+
readonly href: "";
|
|
12
|
+
readonly name: "AgentPortal";
|
|
13
|
+
}, {
|
|
14
|
+
readonly href: "";
|
|
15
|
+
readonly name: "AdminPortal";
|
|
16
|
+
}, {
|
|
17
|
+
readonly href: "";
|
|
18
|
+
readonly name: "CRM";
|
|
19
|
+
}, {
|
|
20
|
+
readonly href: "";
|
|
21
|
+
readonly name: "Finance";
|
|
22
|
+
}, {
|
|
23
|
+
readonly href: "";
|
|
24
|
+
readonly name: "FundingAdmin";
|
|
25
|
+
}, {
|
|
26
|
+
readonly href: "";
|
|
27
|
+
readonly name: "MessageTemplate";
|
|
28
|
+
}, {
|
|
29
|
+
readonly href: "";
|
|
30
|
+
readonly name: "Translate";
|
|
31
|
+
}, {
|
|
32
|
+
readonly href: "";
|
|
33
|
+
readonly name: "TradeConfig";
|
|
34
|
+
}, {
|
|
35
|
+
readonly href: "";
|
|
36
|
+
readonly name: "Ticket";
|
|
37
|
+
}, {
|
|
38
|
+
readonly href: "";
|
|
39
|
+
readonly name: "IBPortalAdmin";
|
|
40
|
+
}, {
|
|
41
|
+
readonly href: "";
|
|
42
|
+
readonly name: "OPPortal";
|
|
43
|
+
}, {
|
|
44
|
+
readonly href: "";
|
|
45
|
+
readonly name: "ClientInfoHub";
|
|
46
|
+
}, {
|
|
47
|
+
readonly href: "";
|
|
48
|
+
readonly name: "Promotion";
|
|
49
|
+
}];
|
|
50
|
+
export type ModuleName = typeof modules[number]['name'];
|
|
51
|
+
export type UserInfo = {
|
|
52
|
+
'aud': string;
|
|
53
|
+
'aud_time': number;
|
|
54
|
+
'cognito:groups': ModuleName[];
|
|
55
|
+
'cognito:username': string;
|
|
56
|
+
'custom:encrypt_email_var': string;
|
|
57
|
+
'custom:tenant_id': Tenant;
|
|
58
|
+
'custom:user_id': string;
|
|
59
|
+
'email': string;
|
|
60
|
+
'email_verified': boolean;
|
|
61
|
+
'exp': number;
|
|
62
|
+
'event_id': string;
|
|
63
|
+
'iat': number;
|
|
64
|
+
'iss': string;
|
|
65
|
+
'jti': string;
|
|
66
|
+
'origin_jti': string;
|
|
67
|
+
'preferred_username': string;
|
|
68
|
+
'sub': string;
|
|
69
|
+
'token_use': string;
|
|
70
|
+
};
|
|
71
|
+
export declare enum Brand {
|
|
72
|
+
ZERO = 1,
|
|
73
|
+
HEDGEHOOD = 2,
|
|
74
|
+
NISE = 3
|
|
75
|
+
}
|
|
76
|
+
export declare enum Tenant {
|
|
77
|
+
ZERO_INT = 1,
|
|
78
|
+
HEDGEHOOD = 2,
|
|
79
|
+
ZERO_NZ = 3,
|
|
80
|
+
ZERO_LA = 4,
|
|
81
|
+
ZERO_BR = 4,
|
|
82
|
+
NISE_EU = 5
|
|
83
|
+
}
|
|
84
|
+
export declare enum SystemType {
|
|
85
|
+
Staff = "staff",
|
|
86
|
+
Client = "client"
|
|
87
|
+
}
|
|
88
|
+
export {};
|
|
89
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,QAAA,MAAM,OAAO;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAiEH,CAAA;AAEV,MAAM,MAAM,UAAU,GAAG,OAAO,OAAO,CAAC,MAAM,CAAC,CAAC,MAAM,CAAC,CAAA;AAEvD,MAAM,MAAM,QAAQ,GAAG;IACrB,KAAK,EAAE,MAAM,CAAA;IACb,UAAU,EAAE,MAAM,CAAA;IAClB,gBAAgB,EAAE,UAAU,EAAE,CAAA;IAC9B,kBAAkB,EAAE,MAAM,CAAA;IAC1B,0BAA0B,EAAE,MAAM,CAAA;IAClC,kBAAkB,EAAE,MAAM,CAAA;IAC1B,gBAAgB,EAAE,MAAM,CAAA;IACxB,OAAO,EAAE,MAAM,CAAA;IACf,gBAAgB,EAAE,OAAO,CAAA;IACzB,KAAK,EAAE,MAAM,CAAA;IACb,UAAU,EAAE,MAAM,CAAA;IAClB,KAAK,EAAE,MAAM,CAAA;IACb,KAAK,EAAE,MAAM,CAAA;IACb,KAAK,EAAE,MAAM,CAAA;IACb,YAAY,EAAE,MAAM,CAAA;IACpB,oBAAoB,EAAE,MAAM,CAAA;IAC5B,KAAK,EAAE,MAAM,CAAA;IACb,WAAW,EAAE,MAAM,CAAA;CACpB,CAAA;AAED,oBAAY,KAAK;IACf,IAAI,IAAI;IACR,SAAS,IAAI;IACb,IAAI,IAAI;CACT;AAED,oBAAY,MAAM;IAChB,QAAQ,IAAI;IACZ,SAAS,IAAI;IACb,OAAO,IAAI;IACX,OAAO,IAAI;IACX,OAAO,IAAI;IACX,OAAO,IAAI;CACZ;AAED,oBAAY,UAAU;IACpB,KAAK,UAAU;IACf,MAAM,WAAW;CAClB"}
|
package/dist/utils.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../src/utils.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,QAAQ,QAAM,OAG1B,CAAA"}
|
package/index.html
ADDED
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
<!doctype html>
|
|
2
|
+
<html lang="en">
|
|
3
|
+
<head>
|
|
4
|
+
<meta charset="UTF-8">
|
|
5
|
+
<meta name="viewport"
|
|
6
|
+
content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
|
|
7
|
+
<meta http-equiv="X-UA-Compatible" content="ie=edge">
|
|
8
|
+
<title>Document</title>
|
|
9
|
+
</head>
|
|
10
|
+
<body>
|
|
11
|
+
</body>
|
|
12
|
+
<script type="module">
|
|
13
|
+
import { make, setAccessToken, setRefreshToken } from './dist/index.esm.js';
|
|
14
|
+
|
|
15
|
+
setAccessToken('eyJraWQiOiJUQTVBanVVYURheGlZdFVYR3l6ajlEZEdPZFJIYUVlUTRTRnF6VWdzc0ZNPSIsImFsZyI6IlJTMjU2In0.eyJzdWIiOiJkNzQ0M2FmOC1mMGExLTcwMzItZGIzMC0wM2Y3NDczZTY0ZDciLCJjb2duaXRvOmdyb3VwcyI6WyJBZ2VudFBvcnRhbCIsIkZpbmFuY2UiLCJUaWNrZXQiLCJQb3J0YWwiXSwiZW1haWxfdmVyaWZpZWQiOnRydWUsImlzcyI6Imh0dHBzOlwvXC9jb2duaXRvLWlkcC5hcC1ub3J0aGVhc3QtMS5hbWF6b25hd3MuY29tXC9hcC1ub3J0aGVhc3QtMV9JSFp0Y2JNZnQiLCJjdXN0b206dXNlcl9pZCI6IjUiLCJjb2duaXRvOnVzZXJuYW1lIjoiZmJjM2Q0ZDIwNzUxNGMwOGEyMGM1NDRjMGNjNmRlYTciLCJjdXN0b206dGVuYW50X2lkIjoiMSIsInByZWZlcnJlZF91c2VybmFtZSI6IuaZk-e6oiDlvKAiLCJjdXN0b206ZW5jcnlwdF9lbWFpbF92YXIiOiJjbGllbnQrNUBoZWRnZWhvb2QuY2MiLCJvcmlnaW5fanRpIjoiYWE4YjY3NzctYzhhZC00MDU3LWJlNTEtZjI1Nzc0M2E5NDY2IiwiYXVkIjoibjRibnJxdGY1OXBqazB1OG01dnVoM2ZxdCIsImV2ZW50X2lkIjoiNmI0ZTJkMjktODI3YS00ODg4LWE1NjUtZjgwYTVkNWU0MGI0IiwidG9rZW5fdXNlIjoiaWQiLCJhdXRoX3RpbWUiOjE3NjU3NzY5NTQsImV4cCI6MTc2NTc4NDE1NCwiaWF0IjoxNzY1Nzc2OTU0LCJlbWFpbCI6Im9ubGluZV90ZXN0QHRtcGVtbC5jb20iLCJqdGkiOiI3NGIzYzUzMi1kOWFlLTQ5YTItOWIzZC1mNzNmNjZkOGM3NDYifQ.VnCQy9EleScDCFLUkOyFdglxos3a2lQ7UGjoZv4sQPibfZrOlp69qlozqDHVoxEboaZ9foZ_EtxnUUkuK2G8rpBGF2mViGdqsNBOYATAN9At1JDTgZsr8yldtJy1EtCgKx6BjBKcL22EQkTreOLXJNpMLY_pkhyjrRoOZ_UTQmKvHthkRU9kCYldk0wh_NsncR8vUSIwG7f9rDqpY01Xu8_FctxudV_zg0WR3YEi45Sql47_RjeYKjoKTVcN2YYSbngJZa3dgfU93tfyx4C2qU5ZC-k7IZsKaRk_G3zcLzP1VeeuVPYgLlb8b-WMJsMJdR4megvmbbDAxWDpQQ-zCQ')
|
|
16
|
+
setRefreshToken('eyJjdHkiOiJKV1QiLCJlbmMiOiJBMjU2R0NNIiwiYWxnIjoiUlNBLU9BRVAifQ.i9ZK_G5dMP0mol3m85EAun1VLyeMh1cnwhFC6jX5jTsxY0qp1exdE8_EyhZdYJJG__hqqXptk1LBAC6NrDPXQ9LC2QcaOfq4CxE8Ai4RTR7dOSOhQbpWu1vxSmIX1Gy9HiFMmlUxyknPDcVC1JXdXtLFPbeOWctXIg_S6xLILG3Kb2B9wMeJEHYPiAb2bIZk7qnT-I8geh9XzabUqeXqLBBHMp2xr3BU3ycgOEnuQQat_W7J0U0Szo5pD9Td7T5QytLYNkFBxo5CNzJzmq2B-alwBqYTm0pXUL1gASI757dlMbVig8tpnJgGtziv67EUiP0NCkTSTeqd4S-WY8H48Q.iJeo5oRqo5MnjbFI.kgtUI6ipZFsTehsicL8mT4DAORSY7J-8JAgYVta8GEyFnXAol2hJIaj4ob9cSOWZENoO8ZT_i7Co8DCLLFoTA4aNeLebFCnJTzdJSYDhBeJ6OrRVEtw8-dniJd1VZriuN53ZWjmM-RxPSYrFYFpUFpYG_xk00w06CWowxSy0WrhUzgrrC-OLUViTRL3Sl3TPW7AxNnzjgMZVZUQ2udWaw3Y2EfcyGYE_Un2HvyLYYbEUm6EMqRTh5BgNMxnCiFrhiaQpuJaABskHH-PUSFdtoHnWONqayjlRazCF_lTYpKglIgi7PQp12SVU8A_gZP6JEGc3nYLpyj2CeR8ocvkMWP58bnzYoU9Jdke0avrAjC2YPfO2R-YcF2LUM6q3HECe_ukMGAEiYM5YwM5o8w2Mcbn-WtRS6nZxTWhChfqMYYme61QaEm2nsZO72aoGc9nTN27PU_j-lq9-HLC-caDzpPYLq5wpZgLvK5HsRAsxknDtJh02wb-6miLZHAZTbdjAlCOMXz3334Vdha17by1lTu_L4C5rUpSPSQaspdRl0moBqH7He27XIoHem6RXlWb-a-jXjGhA1FLHu73rTYU40gZ681UE6qrVz2aQCVDcbhE1iytUS7NcLXI2i5zbzo4YBnYGNvOVLd58CesSI1T_T0_Y4ip966lEypERJAVYJ20Ji2F54KDYPr17Cv3ltz80qqqPN_1QI5oRszt6xU7IjTCp47YGVAHt7RcfR2FemiodpW3_-Xm2PYgo0rwgkEX7z7fZ6Ban1jSeZsYD0vPrlf6nlD8QvA7bP6acZufmfok5oMJ2SC5hv7mGjggd9HT8h3yj8yH4exfga2BSIHTwgNXU-cBw_mQyZCScELof20HJdpE8f3TzOHZfURn1uJdKSZ0tZAdIaTqdHIUlEgUZ8xok7JRpqayVsXve1GvCaZylG0Mw9FTx5DJRi6IblXVdL7yZwLFk8FUYcn4KqtPlamoxR9rpGGMtXIexY4yN99v-hc8_gn3ilYMeA3-a4cFx1mmld8VRQJeD7q_u0lRheDBqW9K6JRBjn8s59hLfyoiRPMi_NZFc2OJNwJofNJbmTcfQmR1dQtsTh2Rtv4krG2YnczzGmPZJppOpaebictrv_ogc93NnXZqJtZGAbSy4RdQYj3Fnx17EY-NSU-VQerlhgV_e35cz8ZNmsiISq7Lp6zUTQwr6ASztyLQ8i_71Xr0OXgf4l4qXWyVQJhbOTJdIUyX5s3ebJruU1qSwPG20Fd3Pm6boIbIlsGHWM6VvRxON8CbJ0PGU_rcIJPVkEGZ0MoiMGvh3BnFYaZYtSPD5p7F9w_LBMRdzb3JimdzNtn48jGYG.XHICmXlRw5-f1fQVFS1Zdw')
|
|
17
|
+
|
|
18
|
+
const { init } = make({
|
|
19
|
+
brand: 1,
|
|
20
|
+
tenantId: 1,
|
|
21
|
+
moduleName: 'Portal',
|
|
22
|
+
moduleBaseUrl: 'https://servers-api.gztest.net:8107',
|
|
23
|
+
loginPageUrl: 'http://huangcheng.ddmarketinghub.com:8080',
|
|
24
|
+
})
|
|
25
|
+
|
|
26
|
+
init()
|
|
27
|
+
</script>
|
|
28
|
+
</html>
|
package/index.ts
ADDED
|
@@ -0,0 +1,154 @@
|
|
|
1
|
+
export * from './src/cookie'
|
|
2
|
+
export * from './src/compatible'
|
|
3
|
+
|
|
4
|
+
import { openDialog } from './src/dom'
|
|
5
|
+
import { getAccessToken, getRefreshToken, setAccessToken, setRefreshToken, setSystemType } from './src/cookie'
|
|
6
|
+
import { fetchServerListHTTP, fetchRefreshTokenHTTP, initInstance, fetchLogoutHTTP } from './src/request'
|
|
7
|
+
import { NO_ACCESS_TOKEN, NO_MODULE_BASE_URL, NO_REFRESH_TOKEN } from './src/constance'
|
|
8
|
+
import { setTenantId, setBrand, setModuleBaseUrl, setLoginPageUrl } from './src/shares'
|
|
9
|
+
import { type ModuleName, type Tenant, type Brand, type UserInfo } from './src/types'
|
|
10
|
+
import { SystemType } from './src/types'
|
|
11
|
+
import { getUserInfo } from './src/utils'
|
|
12
|
+
|
|
13
|
+
type MakeFnParams = {
|
|
14
|
+
brand: Brand
|
|
15
|
+
tenantId: Tenant
|
|
16
|
+
moduleName: ModuleName
|
|
17
|
+
moduleBaseUrl: string,
|
|
18
|
+
loginPageUrl: string
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
export const make = (config: MakeFnParams) => {
|
|
22
|
+
if (!config.moduleBaseUrl) {
|
|
23
|
+
throw new Error(NO_MODULE_BASE_URL)
|
|
24
|
+
}
|
|
25
|
+
let timer: number | undefined | null = undefined
|
|
26
|
+
|
|
27
|
+
setModuleBaseUrl(config.moduleBaseUrl)
|
|
28
|
+
setLoginPageUrl(config.loginPageUrl)
|
|
29
|
+
setTenantId(config.tenantId)
|
|
30
|
+
setBrand(config.brand)
|
|
31
|
+
initInstance()
|
|
32
|
+
|
|
33
|
+
const init = () => {
|
|
34
|
+
const token = getAccessToken()
|
|
35
|
+
const refreshToken = getRefreshToken()
|
|
36
|
+
|
|
37
|
+
if (!token) {
|
|
38
|
+
setAccessToken(null)
|
|
39
|
+
setRefreshToken(null)
|
|
40
|
+
return Promise.reject(new Error(NO_ACCESS_TOKEN))
|
|
41
|
+
}
|
|
42
|
+
if (!refreshToken) {
|
|
43
|
+
setAccessToken(null)
|
|
44
|
+
setRefreshToken(null)
|
|
45
|
+
return Promise.reject(new Error(NO_REFRESH_TOKEN))
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
return getUserInfo()
|
|
49
|
+
.then(async (userInfo) => {
|
|
50
|
+
const valid = detectUserInfoGroupAuth(userInfo)
|
|
51
|
+
|
|
52
|
+
if (!valid) {
|
|
53
|
+
return Promise.reject()
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
return fetchServerListHTTP()
|
|
57
|
+
})
|
|
58
|
+
.catch(error => {
|
|
59
|
+
openDialog()
|
|
60
|
+
|
|
61
|
+
throw error
|
|
62
|
+
})
|
|
63
|
+
.then(resp => {
|
|
64
|
+
const menus = resp.data.content || []
|
|
65
|
+
|
|
66
|
+
if (menus.length <= 0) return Promise.reject()
|
|
67
|
+
const group = menus.find(menu => menu.groupName === config.moduleName)
|
|
68
|
+
if (group) {
|
|
69
|
+
setSystemType(group.staffEndpoint ? SystemType.Staff : SystemType.Client)
|
|
70
|
+
}
|
|
71
|
+
setupRefreshTokenTimer()
|
|
72
|
+
|
|
73
|
+
return Promise.resolve()
|
|
74
|
+
})
|
|
75
|
+
.catch(async (error) => {
|
|
76
|
+
clearRefreshTokenTimer()
|
|
77
|
+
setAccessToken(null)
|
|
78
|
+
setRefreshToken(null)
|
|
79
|
+
|
|
80
|
+
await logout()
|
|
81
|
+
|
|
82
|
+
throw error
|
|
83
|
+
})
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
const detectUserInfoGroupAuth = (userInfo: UserInfo): boolean => {
|
|
87
|
+
const groups = userInfo['cognito:groups'] || []
|
|
88
|
+
|
|
89
|
+
if (
|
|
90
|
+
!groups.includes(config.moduleName)
|
|
91
|
+
&& config.moduleName !== 'commonLogin'
|
|
92
|
+
&& config.moduleName !== 'App'
|
|
93
|
+
) {
|
|
94
|
+
return false
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
return true
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
const setupRefreshTokenTimer = () => {
|
|
101
|
+
const refreshToken = getRefreshToken()
|
|
102
|
+
|
|
103
|
+
if (!refreshToken) return
|
|
104
|
+
|
|
105
|
+
if (timer) {
|
|
106
|
+
clearInterval(timer)
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
timer = setInterval(() => {
|
|
110
|
+
fetchRefreshTokenHTTP(refreshToken)
|
|
111
|
+
.then(resp => {
|
|
112
|
+
const { content: { idToken } } = resp.data
|
|
113
|
+
|
|
114
|
+
setAccessToken(idToken)
|
|
115
|
+
return getUserInfo()
|
|
116
|
+
})
|
|
117
|
+
.then(userInfo => {
|
|
118
|
+
const valid = detectUserInfoGroupAuth(userInfo)
|
|
119
|
+
|
|
120
|
+
if (!valid) {
|
|
121
|
+
clearRefreshTokenTimer()
|
|
122
|
+
openDialog()
|
|
123
|
+
|
|
124
|
+
return logout()
|
|
125
|
+
}
|
|
126
|
+
})
|
|
127
|
+
.catch(error => {
|
|
128
|
+
clearRefreshTokenTimer()
|
|
129
|
+
|
|
130
|
+
throw error
|
|
131
|
+
})
|
|
132
|
+
}, 1e3 * 60 * 3) // 3 minutes
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
const logout = () => {
|
|
136
|
+
return fetchLogoutHTTP()
|
|
137
|
+
.finally(() => {
|
|
138
|
+
clearRefreshTokenTimer()
|
|
139
|
+
setAccessToken(null)
|
|
140
|
+
setRefreshToken(null)
|
|
141
|
+
})
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
const clearRefreshTokenTimer = () => {
|
|
145
|
+
if (!timer) return
|
|
146
|
+
clearInterval(timer)
|
|
147
|
+
timer = null
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
return {
|
|
151
|
+
init,
|
|
152
|
+
logout
|
|
153
|
+
}
|
|
154
|
+
}
|
package/jest.config.js
ADDED
package/package.json
CHANGED
|
@@ -1,28 +1,55 @@
|
|
|
1
|
-
{
|
|
2
|
-
"
|
|
3
|
-
"
|
|
4
|
-
"
|
|
5
|
-
"
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
"
|
|
11
|
-
|
|
12
|
-
"
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
"
|
|
16
|
-
|
|
17
|
-
"
|
|
18
|
-
"
|
|
19
|
-
},
|
|
20
|
-
"
|
|
21
|
-
"
|
|
22
|
-
"
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
1
|
+
{
|
|
2
|
+
"type": "module",
|
|
3
|
+
"name": "login-authorization-v2",
|
|
4
|
+
"version": "2.0.0-beta.1",
|
|
5
|
+
"engines": {
|
|
6
|
+
"node": "^20"
|
|
7
|
+
},
|
|
8
|
+
"description": "login authorization",
|
|
9
|
+
"main": "dist/index.umd.js",
|
|
10
|
+
"module": "dist/index.esm.js",
|
|
11
|
+
"exports": {
|
|
12
|
+
"import": "./dist/index.esm.js",
|
|
13
|
+
"require": "./dist/index.umd.js"
|
|
14
|
+
},
|
|
15
|
+
"scripts": {
|
|
16
|
+
"serve": "webpack -w",
|
|
17
|
+
"build": "webpack",
|
|
18
|
+
"test": "jest --coverage"
|
|
19
|
+
},
|
|
20
|
+
"keywords": [
|
|
21
|
+
"login",
|
|
22
|
+
"authorization"
|
|
23
|
+
],
|
|
24
|
+
"author": "huangcheng",
|
|
25
|
+
"license": "ISC",
|
|
26
|
+
"dependencies": {
|
|
27
|
+
"@types/axios": "^0.14.4",
|
|
28
|
+
"@types/js-base64": "^3.0.0",
|
|
29
|
+
"@types/js-cookie": "^3.0.6",
|
|
30
|
+
"axios": "^0.24.0",
|
|
31
|
+
"js-base64": "^3.7.7",
|
|
32
|
+
"js-cookie": "^3.0.5",
|
|
33
|
+
"lodash": "^4.17.21",
|
|
34
|
+
"ts-loader": "^9.5.4"
|
|
35
|
+
},
|
|
36
|
+
"devDependencies": {
|
|
37
|
+
"@babel/core": "^7.16.5",
|
|
38
|
+
"@babel/plugin-transform-runtime": "^7.16.5",
|
|
39
|
+
"@babel/preset-env": "^7.16.5",
|
|
40
|
+
"@babel/preset-typescript": "^7.28.5",
|
|
41
|
+
"@jest/globals": "^30.2.0",
|
|
42
|
+
"@rollup/plugin-node-resolve": "^16.0.3",
|
|
43
|
+
"@rollup/plugin-typescript": "^12.3.0",
|
|
44
|
+
"@types/jest": "^30.0.0",
|
|
45
|
+
"babel-loader": "^8.2.3",
|
|
46
|
+
"jest": "^30.2.0",
|
|
47
|
+
"jest-environment-jsdom": "^30.2.0",
|
|
48
|
+
"rollup": "^4.53.3",
|
|
49
|
+
"ts-jest": "^29.4.6",
|
|
50
|
+
"tslib": "^2.8.1",
|
|
51
|
+
"typescript": "^5.9.3",
|
|
52
|
+
"webpack": "^5.65.0",
|
|
53
|
+
"webpack-cli": "^4.9.1"
|
|
54
|
+
}
|
|
55
|
+
}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 这个文件是写一些兼容的方法,避免各个项目做出大量调整
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
import { getAccessToken, setAccessToken, setRefreshToken } from './cookie'
|
|
6
|
+
import Cookie from 'js-cookie'
|
|
7
|
+
|
|
8
|
+
export const setIdToken = setAccessToken
|
|
9
|
+
export const getIdToken = getAccessToken
|
|
10
|
+
|
|
11
|
+
export const setCookie = (
|
|
12
|
+
name: string,
|
|
13
|
+
value: string | undefined | null,
|
|
14
|
+
domain: string,
|
|
15
|
+
path: string = '/',
|
|
16
|
+
time = 30 * 24 * 60 * 60 * 1000
|
|
17
|
+
) => {
|
|
18
|
+
if (value === null || value === undefined) {
|
|
19
|
+
return Cookie.remove(name)
|
|
20
|
+
}
|
|
21
|
+
Cookie.set(name, value, {
|
|
22
|
+
domain,
|
|
23
|
+
path,
|
|
24
|
+
expires: time / (24 * 60 * 60 * 1000)
|
|
25
|
+
})
|
|
26
|
+
}
|
|
27
|
+
export const clearLoginCookie = () => {
|
|
28
|
+
setAccessToken(null)
|
|
29
|
+
setRefreshToken(null)
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
export const getCookie = (c_name: string) => {
|
|
33
|
+
if (!c_name) return null
|
|
34
|
+
const reg = new RegExp('(?:^|; )' + encodeURIComponent(c_name) + '=([^;]*)')
|
|
35
|
+
const result = reg.exec(document.cookie)
|
|
36
|
+
return result ? decodeURIComponent(result[1] || '') : null
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
|
|
40
|
+
export const getUrlParam = (key: string, href?: string) => {
|
|
41
|
+
const search = '?' + ((href || window.location.href).split('?')[1] || '')
|
|
42
|
+
|
|
43
|
+
const searchParams = new URLSearchParams(search)
|
|
44
|
+
|
|
45
|
+
return searchParams.get(key)
|
|
46
|
+
}
|
package/src/constance.ts
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
export const NO_ACCESS_TOKEN = 'Access token not found'
|
|
2
|
+
export const INVALID_ACCESS_TOKEN = 'Invalid access token'
|
|
3
|
+
export const INVALID_REFRESH_TOKEN = 'Invalid refresh token'
|
|
4
|
+
export const NO_REFRESH_TOKEN = 'Refresh token not found'
|
|
5
|
+
export const NO_MODULE_BASE_URL = 'Module base URL is required'
|
|
6
|
+
export const INVALID_TENANT_ID = 'Invalid tenant ID'
|
|
7
|
+
export const INVALID_BRAND = 'Invalid brand'
|
package/src/cookie.ts
ADDED
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
import Cookie from 'js-cookie'
|
|
2
|
+
import type Cookies from 'js-cookie'
|
|
3
|
+
import { INVALID_ACCESS_TOKEN, INVALID_REFRESH_TOKEN } from './constance'
|
|
4
|
+
|
|
5
|
+
export type CookieKeys =
|
|
6
|
+
'access_token'
|
|
7
|
+
| 'refresh_token'
|
|
8
|
+
| 'idTokenFront'
|
|
9
|
+
| 'idTokenBack'
|
|
10
|
+
| 'refreshTokenFront'
|
|
11
|
+
| 'refreshTokenBack'
|
|
12
|
+
| 'currentSystemType'
|
|
13
|
+
|
|
14
|
+
const makeSetCookieFn = (key: CookieKeys, options?: Cookies.CookieAttributes) => {
|
|
15
|
+
const index = window.location.hostname.indexOf('.')
|
|
16
|
+
const domain =
|
|
17
|
+
index === -1
|
|
18
|
+
? window.location.hostname
|
|
19
|
+
: window.location.hostname.slice(index)
|
|
20
|
+
|
|
21
|
+
return (value: string | null) => {
|
|
22
|
+
if (value === null) {
|
|
23
|
+
return Cookie.remove(key, { domain, ...options } )
|
|
24
|
+
}
|
|
25
|
+
Cookie.set(key, value, {
|
|
26
|
+
domain,
|
|
27
|
+
expires: 30,
|
|
28
|
+
...options
|
|
29
|
+
})
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
const setIdTokenFront = makeSetCookieFn('idTokenFront')
|
|
34
|
+
const setIdTokenBack = makeSetCookieFn('idTokenBack')
|
|
35
|
+
const setRefreshTokenFront = makeSetCookieFn('refreshTokenFront')
|
|
36
|
+
const setRefreshTokenBack = makeSetCookieFn('refreshTokenBack')
|
|
37
|
+
export const setRefreshToken = (token: string | null) => {
|
|
38
|
+
if (!token) {
|
|
39
|
+
setIdTokenBack(null)
|
|
40
|
+
setIdTokenFront(null)
|
|
41
|
+
makeSetCookieFn('refresh_token')(null)
|
|
42
|
+
return
|
|
43
|
+
}
|
|
44
|
+
const splits = token.split('.')
|
|
45
|
+
if (splits.length < 5) throw new Error(INVALID_REFRESH_TOKEN)
|
|
46
|
+
const refreshTokenFront = splits[0] + '.' + splits[1]
|
|
47
|
+
const refreshTokenBack = splits[2] + '.' + splits[3] + '.' + splits[4]
|
|
48
|
+
|
|
49
|
+
setRefreshTokenFront(refreshTokenFront)
|
|
50
|
+
setRefreshTokenBack(refreshTokenBack)
|
|
51
|
+
makeSetCookieFn('refresh_token')(token)
|
|
52
|
+
}
|
|
53
|
+
export const setAccessToken = (token: string | null) => {
|
|
54
|
+
if (!token) {
|
|
55
|
+
setIdTokenBack(null)
|
|
56
|
+
setIdTokenFront(null)
|
|
57
|
+
makeSetCookieFn('access_token')(null)
|
|
58
|
+
return
|
|
59
|
+
}
|
|
60
|
+
const splits = token.split('.')
|
|
61
|
+
if (splits.length < 3) throw new Error(INVALID_ACCESS_TOKEN)
|
|
62
|
+
const idTokenFront = splits[0] + '.' + splits[1]
|
|
63
|
+
const idTokenBack = splits[2] || ''
|
|
64
|
+
|
|
65
|
+
setIdTokenFront(idTokenFront)
|
|
66
|
+
setIdTokenBack(idTokenBack)
|
|
67
|
+
|
|
68
|
+
makeSetCookieFn('access_token')(token)
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
export const getAccessToken = () => Cookie.get('access_token')
|
|
72
|
+
export const getRefreshToken = () => Cookie.get('refresh_token')
|
|
73
|
+
|
|
74
|
+
export const setSystemType = makeSetCookieFn('currentSystemType')
|
|
75
|
+
export const getSystemType = () => Cookie.get('currentSystemType')
|
package/src/dom.ts
ADDED
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
import { isMobile } from './utils'
|
|
2
|
+
import { loginPageUrl } from './shares'
|
|
3
|
+
|
|
4
|
+
const createPcDialog = () => {
|
|
5
|
+
return `<div id="confirm-container" style="box-sizing:border-box;position:fixed;width:615px;height:145px;box-shadow: 0 0 2px 2px #eeeeee;border-radius: 5px;z-index: 10000000;display: block;left: 35%;padding:20px 20px;top:10px;font-size: 16px;">
|
|
6
|
+
<div id="href" style="color: rgb(32,33,36);"></div>
|
|
7
|
+
<div style="margin: 10px 0 20px 0;color: rgb(32,33,36);font-size: 14px;">You do not have access to the system.</div>
|
|
8
|
+
<div style="display: flex;justify-content: flex-end;">
|
|
9
|
+
<button id="cancel" style="padding: 8px 15px;background: #ffffff;color:rgb(26,115,232);border:1px solid #ccc;border-radius:5px;cursor: pointer;font-size:14px;">Cancel</button>
|
|
10
|
+
<button id="confirm" style="padding: 8px 15px;background: rgb(26,115,232);color:#ffffff;border:none;border-radius:5px;margin-left: 10px;cursor: pointer;font-size:14px;">Sign in to another ZERO account</button>
|
|
11
|
+
</div>
|
|
12
|
+
</div>`
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
const createMobileDialog = () => {
|
|
16
|
+
return `<div id="confirm-container" style="box-sizing:border-box;position:fixed;width:97.6vw;height:145px;box-shadow: 0 0 2px 2px #eeeeee;border-radius: 5px;z-index: 10000000;display: block;left:0px;padding:20px 20px;top:4px;margin:0 4px;font-size: 16px;">
|
|
17
|
+
<div id="href" style="color: rgb(32,33,36);"></div>
|
|
18
|
+
<div style="margin: 10px 0 20px 0;color: rgb(32,33,36);font-size: 14px;">You do not have access to the system.</div>
|
|
19
|
+
<div style="display: flex;justify-content: flex-end;">
|
|
20
|
+
<div style="display: flex;justify-content: flex-end;">
|
|
21
|
+
<button id="cancel" style="padding: 8px 15px;background: #ffffff;color:rgb(26,115,232);border:1px solid #ccc;border-radius:5px;cursor: pointer;font-size:14px;">Cancel</button>
|
|
22
|
+
<button id="confirm" style="padding: 8px 15px;background: rgb(26,115,232);color:#ffffff;border:none;border-radius:5px;margin-left: 10px;cursor: pointer;font-size:14px;">Sign in to another ZERO account</button>
|
|
23
|
+
</div>
|
|
24
|
+
</div>
|
|
25
|
+
</div>`
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
const onConfirmHandler = (evt: Event) => {
|
|
29
|
+
closeDialog()
|
|
30
|
+
window.location.href = loginPageUrl
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
const onCancelHandler = () => {
|
|
34
|
+
closeDialog()
|
|
35
|
+
window.location.href = 'about:blank'
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
export const closeDialog = () => {
|
|
39
|
+
const container = document.getElementById('confirm-container')
|
|
40
|
+
|
|
41
|
+
if (!container || !container.parentNode) return
|
|
42
|
+
document.body.removeChild(container.parentNode)
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
export const openDialog = () => {
|
|
46
|
+
const container = document.createElement('div')
|
|
47
|
+
|
|
48
|
+
isMobile()
|
|
49
|
+
? container.innerHTML = createMobileDialog()
|
|
50
|
+
: container.innerHTML = createPcDialog()
|
|
51
|
+
|
|
52
|
+
const confirmButton = container.querySelector('#confirm')
|
|
53
|
+
const cancelButton = container.querySelector('#cancel')
|
|
54
|
+
|
|
55
|
+
confirmButton?.addEventListener('click', onConfirmHandler)
|
|
56
|
+
cancelButton?.addEventListener('click', onCancelHandler)
|
|
57
|
+
|
|
58
|
+
document.body.appendChild(container)
|
|
59
|
+
}
|
package/src/request.ts
ADDED
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
import axios from 'axios'
|
|
2
|
+
import { tenantId, brand, moduleBaseUrl } from './shares'
|
|
3
|
+
import type { ModuleName, UserInfo } from './types'
|
|
4
|
+
import { getAccessToken } from './cookie'
|
|
5
|
+
import type { AxiosInstance, AxiosPromise } from 'axios'
|
|
6
|
+
import { getUserInfo } from './utils'
|
|
7
|
+
|
|
8
|
+
let instance!: AxiosInstance
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* 没找到更好的方式,只能这样做了
|
|
12
|
+
*/
|
|
13
|
+
export const initInstance = async () => {
|
|
14
|
+
let userInfo: UserInfo | null = null
|
|
15
|
+
try {
|
|
16
|
+
userInfo = await getUserInfo()
|
|
17
|
+
} catch (error) {
|
|
18
|
+
console.warn('initInstance getUserInfo error:', error)
|
|
19
|
+
}
|
|
20
|
+
instance = axios.create({
|
|
21
|
+
baseURL: moduleBaseUrl,
|
|
22
|
+
timeout: 1.5e4,
|
|
23
|
+
headers: {
|
|
24
|
+
'X-tenant-id': userInfo ? userInfo['custom:tenant_id'].toString() : tenantId.toString(),
|
|
25
|
+
'X-brand': brand.toString(),
|
|
26
|
+
'Authorization': `Bearer ${getAccessToken()}`,
|
|
27
|
+
}
|
|
28
|
+
})
|
|
29
|
+
|
|
30
|
+
instance.interceptors.request.use(
|
|
31
|
+
(config) => {
|
|
32
|
+
return config
|
|
33
|
+
},
|
|
34
|
+
(error) => {
|
|
35
|
+
return Promise.reject(error)
|
|
36
|
+
}
|
|
37
|
+
)
|
|
38
|
+
|
|
39
|
+
instance.interceptors.response.use(
|
|
40
|
+
(response) => {
|
|
41
|
+
if (response.data.code !== 200) {
|
|
42
|
+
return Promise.reject(response.data.msg)
|
|
43
|
+
}
|
|
44
|
+
return response
|
|
45
|
+
},
|
|
46
|
+
(error) => {
|
|
47
|
+
return Promise.reject(error)
|
|
48
|
+
}
|
|
49
|
+
)
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
type RefreshTokenResponse = {
|
|
53
|
+
code: string
|
|
54
|
+
msg: string
|
|
55
|
+
content: {
|
|
56
|
+
accessToken: string
|
|
57
|
+
expiresIn: number
|
|
58
|
+
idToken: string
|
|
59
|
+
newDeviceMetadata: null
|
|
60
|
+
refreshToken: string
|
|
61
|
+
tokenType: 'Bearer'
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
export const fetchRefreshTokenHTTP = (refreshToken: string) => {
|
|
65
|
+
return instance({
|
|
66
|
+
method: 'post',
|
|
67
|
+
url: '/user-profile/refresh-token/refresh',
|
|
68
|
+
data: {
|
|
69
|
+
refreshToken
|
|
70
|
+
}
|
|
71
|
+
}) as AxiosPromise<RefreshTokenResponse>
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
export const fetchLogoutHTTP = () => {
|
|
75
|
+
return instance({
|
|
76
|
+
method: 'get',
|
|
77
|
+
url: '/user-profile/logout'
|
|
78
|
+
})
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
type Content = {
|
|
82
|
+
groupName: ModuleName
|
|
83
|
+
icon: string
|
|
84
|
+
id: number
|
|
85
|
+
label: string
|
|
86
|
+
staffEndpoint: boolean
|
|
87
|
+
url: string
|
|
88
|
+
}
|
|
89
|
+
type ServerListResponse = {
|
|
90
|
+
content: Array<Content>
|
|
91
|
+
code: number
|
|
92
|
+
totalElements: number
|
|
93
|
+
}
|
|
94
|
+
export const fetchServerListHTTP = () => {
|
|
95
|
+
return instance({
|
|
96
|
+
method: 'get',
|
|
97
|
+
url: '/session/current/servers'
|
|
98
|
+
}) as AxiosPromise<ServerListResponse>
|
|
99
|
+
}
|