@tsingroc/tsingroc-components 5.0.0-alpha.21 → 5.0.0-alpha.22
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/dist/components/Calendar.js +8 -4
- package/dist/components/ECharts.d.ts +1 -1
- package/dist/components/Header.d.ts +1 -1
- package/dist/components/Header.js +3 -1
- package/dist/components/LineChartEditor.js +3 -3
- package/dist/components/LineChartTable.js +319 -123
- package/dist/components/LinkedLineChart.js +3 -3
- package/dist/components/QuickDateRangePicker.d.ts +1 -1
- package/dist/components/QuickDateRangePicker.js +2 -3
- package/dist/components/Sidebar.d.ts +1 -1
- package/dist/components/Sidebar.js +4 -5
- package/dist/components/TsingrocDatePicker.d.ts +2 -2
- package/dist/components/TsingrocDatePicker.js +6 -7
- package/dist/components/UserButton.d.ts +1 -1
- package/dist/components/UserButton.js +24 -18
- package/dist/components/WeatherMap.js +1 -1
- package/dist/components/auth/AuthProvider.d.ts +29 -0
- package/dist/components/auth/AuthProvider.js +138 -0
- package/dist/components/auth/AuthService.d.ts +30 -0
- package/dist/components/auth/AuthService.js +1 -0
- package/dist/components/auth/CasdoorAuth.d.ts +135 -0
- package/dist/components/auth/CasdoorAuth.js +156 -0
- package/dist/components/auth/EmbeddedAuth.d.ts +16 -0
- package/dist/components/auth/EmbeddedAuth.js +53 -0
- package/dist/components/auth/Fetcher.d.ts +30 -0
- package/dist/components/auth/Fetcher.js +132 -0
- package/dist/components/auth/LocalAuth.d.ts +70 -0
- package/dist/components/auth/LocalAuth.js +84 -0
- package/dist/components/auth/LoginCheck.d.ts +13 -0
- package/dist/components/auth/LoginCheck.js +54 -0
- package/dist/components/auth/SessionStore.d.ts +68 -0
- package/dist/components/auth/SessionStore.js +193 -0
- package/dist/deckgl/TiandituLayer.d.ts +1 -1
- package/dist/deckgl/TiandituLayer.js +1 -1
- package/dist/deckgl/WeatherData.d.ts +1 -1
- package/dist/echarts/series/maxBarSeries.d.ts +1 -1
- package/dist/index.d.ts +8 -1
- package/dist/index.js +7 -1
- package/package.json +34 -50
- package/dist/components/Auth.d.ts +0 -314
- package/dist/components/Auth.js +0 -296
|
@@ -1,11 +1,10 @@
|
|
|
1
|
+
import { BarChartOutlined, LeftOutlined, RightOutlined, SwapOutlined, TeamOutlined } from "@ant-design/icons";
|
|
1
2
|
import { Button, Flex, Layout, Menu } from "antd";
|
|
2
3
|
import { createStyles } from "antd-style";
|
|
3
4
|
import { useState } from "react";
|
|
4
|
-
import { BarChartOutlined, LeftOutlined, RightOutlined, SwapOutlined, TeamOutlined } from "@ant-design/icons";
|
|
5
|
-
|
|
6
|
-
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
7
|
-
import { AuthCheck, AuthProvider } from "./Auth";
|
|
8
5
|
import UserButton from "./UserButton";
|
|
6
|
+
// eslint-disable-line @typescript-eslint/no-unused-vars
|
|
7
|
+
// eslint-disable-line @typescript-eslint/no-unused-vars
|
|
9
8
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
10
9
|
const menuItem = (label, key, icon, children) => ({
|
|
11
10
|
key,
|
|
@@ -19,7 +18,7 @@ const DEFAULT_MENU_ITEMS = [menuItem("数据看板", "data-board", /*#__PURE__*/
|
|
|
19
18
|
/**
|
|
20
19
|
* 出自 TMS 系统的侧边栏组件。该组件需要放置在 [Ant Design 的 `Layout` 组件][1]内部才能正常工作。
|
|
21
20
|
* 如果没有指定 {@linkcode SidebarProps.footer | footer} 属性,
|
|
22
|
-
* 那么还需要包裹在 {@linkcode AuthProvider} 内,并且经过 {@linkcode
|
|
21
|
+
* 那么还需要包裹在 {@linkcode AuthProvider} 内,并且经过 {@linkcode LoginCheck} 验证后
|
|
23
22
|
* 才能正常显示边栏底部的用户信息按钮。
|
|
24
23
|
*
|
|
25
24
|
* 一般来说,使用该组件时至少需要提供 `logo`、`items` 和 `onSelect` 三个属性,具体用法请参照范例。
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { type DatePickerProps as AntdDatePickerProps
|
|
1
|
+
import { type ButtonProps, type DatePickerProps as AntdDatePickerProps } from "antd";
|
|
2
2
|
import type { SpaceCompactProps } from "antd/es/space/Compact";
|
|
3
3
|
import type { Dayjs } from "dayjs";
|
|
4
4
|
export interface DatePickerProps extends Omit<SpaceCompactProps, "onChange"> {
|
|
@@ -25,7 +25,7 @@ export interface DatePickerProps extends Omit<SpaceCompactProps, "onChange"> {
|
|
|
25
25
|
*
|
|
26
26
|
* [1]: https://ant-design.antgroup.com/components/date-picker-cn#api
|
|
27
27
|
*/
|
|
28
|
-
pickerProps?: AntdDatePickerProps
|
|
28
|
+
pickerProps?: AntdDatePickerProps<Dayjs, false>;
|
|
29
29
|
}
|
|
30
30
|
/**
|
|
31
31
|
* 支持快速跳转的日/周/月/年选择器。
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
+
import { LeftOutlined, RightOutlined } from "@ant-design/icons";
|
|
1
2
|
import { Button, DatePicker, Space } from "antd";
|
|
2
3
|
import { useState } from "react";
|
|
3
|
-
import { LeftOutlined, RightOutlined } from "@ant-design/icons";
|
|
4
4
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
5
5
|
/**
|
|
6
6
|
* 支持快速跳转的日/周/月/年选择器。
|
|
@@ -19,9 +19,9 @@ function TsingrocDatePicker(props) {
|
|
|
19
19
|
pickerProps,
|
|
20
20
|
...rest
|
|
21
21
|
} = props;
|
|
22
|
-
const [dateValue, setDateValue] = value === undefined
|
|
22
|
+
const [dateValue, setDateValue] = value === undefined
|
|
23
23
|
// eslint-disable-next-line react-hooks/rules-of-hooks
|
|
24
|
-
useState(undefined) : [value, () => {}];
|
|
24
|
+
? useState(undefined) : [value, () => {}];
|
|
25
25
|
/**
|
|
26
26
|
* 快速增减一定时间,如果当前未选择日期则无效。
|
|
27
27
|
* @param delta 增减的时间量,按传入的时间单位 `dataType` 计算
|
|
@@ -33,6 +33,7 @@ function TsingrocDatePicker(props) {
|
|
|
33
33
|
propsOnChange?.(temp);
|
|
34
34
|
};
|
|
35
35
|
const onChange = value => {
|
|
36
|
+
if (!value) return;
|
|
36
37
|
setDateValue(value);
|
|
37
38
|
propsOnChange?.(value);
|
|
38
39
|
};
|
|
@@ -45,15 +46,13 @@ function TsingrocDatePicker(props) {
|
|
|
45
46
|
className: props.className,
|
|
46
47
|
...buttonProps
|
|
47
48
|
}), /*#__PURE__*/_jsx(DatePicker, {
|
|
48
|
-
picker: dataType
|
|
49
|
+
picker: dataType === "day" ? "date" : dataType,
|
|
49
50
|
value: dateValue,
|
|
50
51
|
onChange: onChange,
|
|
51
52
|
disabled: disabled,
|
|
52
53
|
className: props.className,
|
|
53
54
|
...pickerProps
|
|
54
|
-
}), /*#__PURE__*/_jsx(Button
|
|
55
|
-
// eslint-disable-next-line @typescript-eslint/no-unnecessary-type-conversion
|
|
56
|
-
, {
|
|
55
|
+
}), /*#__PURE__*/_jsx(Button, {
|
|
57
56
|
onClick: () => quickSwitch(+1),
|
|
58
57
|
icon: /*#__PURE__*/_jsx(RightOutlined, {}),
|
|
59
58
|
disabled: disabled,
|
|
@@ -31,7 +31,7 @@ export interface UserButtonProps extends ButtonProps {
|
|
|
31
31
|
}
|
|
32
32
|
/**
|
|
33
33
|
* 显示用户信息的按钮,点击弹出登出或跳转到账户页的菜单。
|
|
34
|
-
* 该组件必须包裹在 {@linkcode AuthProvider} 内,并且经过 {@linkcode
|
|
34
|
+
* 该组件必须包裹在 {@linkcode AuthProvider} 内,并且经过 {@linkcode LoginCheck} 验证后,
|
|
35
35
|
* 才能正常显示用户信息,否则只会显示占位数据。
|
|
36
36
|
*
|
|
37
37
|
* 除了文档中列出的属性以外,该组件会把额外的属性传递给内部的 [`Button`][1] 组件。
|
|
@@ -1,14 +1,13 @@
|
|
|
1
|
-
import { Avatar, Button, Dropdown, theme } from "antd";
|
|
2
1
|
import { DownOutlined, LogoutOutlined, UpOutlined, UserOutlined } from "@ant-design/icons";
|
|
3
|
-
import {
|
|
2
|
+
import { Avatar, Button, Dropdown, theme } from "antd";
|
|
3
|
+
import { useSyncExternalStore } from "react";
|
|
4
4
|
// eslint-disable-line @typescript-eslint/no-unused-vars
|
|
5
|
-
AuthProvider
|
|
5
|
+
import { useSessionStoreInternal } from "./auth/AuthProvider";
|
|
6
6
|
// eslint-disable-line @typescript-eslint/no-unused-vars
|
|
7
|
-
useAuth } from "./Auth";
|
|
8
7
|
import { Fragment as _Fragment, jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
9
8
|
/**
|
|
10
9
|
* 显示用户信息的按钮,点击弹出登出或跳转到账户页的菜单。
|
|
11
|
-
* 该组件必须包裹在 {@linkcode AuthProvider} 内,并且经过 {@linkcode
|
|
10
|
+
* 该组件必须包裹在 {@linkcode AuthProvider} 内,并且经过 {@linkcode LoginCheck} 验证后,
|
|
12
11
|
* 才能正常显示用户信息,否则只会显示占位数据。
|
|
13
12
|
*
|
|
14
13
|
* 除了文档中列出的属性以外,该组件会把额外的属性传递给内部的 [`Button`][1] 组件。
|
|
@@ -19,23 +18,30 @@ function UserButton(props) {
|
|
|
19
18
|
const {
|
|
20
19
|
token
|
|
21
20
|
} = theme.useToken();
|
|
22
|
-
const
|
|
21
|
+
const sessionStore = useSessionStoreInternal("UserButton");
|
|
22
|
+
const session = useSyncExternalStore(onChange => {
|
|
23
|
+
sessionStore.addEventListener(onChange);
|
|
24
|
+
return () => sessionStore.addEventListener(onChange);
|
|
25
|
+
}, () => sessionStore.session);
|
|
26
|
+
if (!session) {
|
|
27
|
+
throw new Error("UserButton 只有在用户登录后才能使用,请确保只在 LoginCheck 内部使用 UserButton。");
|
|
28
|
+
}
|
|
23
29
|
const {
|
|
24
30
|
compact,
|
|
25
31
|
layout = "sidebar",
|
|
26
|
-
onOpenProfile
|
|
27
|
-
const account = auth.accessToken === undefined ? undefined : {
|
|
28
|
-
accessToken: auth.accessToken
|
|
29
|
-
};
|
|
30
|
-
location.href = auth.sdk.getMyProfileUrl(account, location.href);
|
|
31
|
-
} : undefined,
|
|
32
|
+
onOpenProfile,
|
|
32
33
|
onLogout = () => {
|
|
33
|
-
|
|
34
|
+
sessionStore.clear();
|
|
34
35
|
location.href = "/";
|
|
35
36
|
},
|
|
36
37
|
dropdownProps,
|
|
38
|
+
style,
|
|
39
|
+
styles,
|
|
37
40
|
...rest
|
|
38
41
|
} = props;
|
|
42
|
+
const resolvedStyles = typeof styles === "function" ? styles({
|
|
43
|
+
props
|
|
44
|
+
}) : styles;
|
|
39
45
|
return /*#__PURE__*/_jsx(Dropdown, {
|
|
40
46
|
trigger: ["click"],
|
|
41
47
|
placement: layout === "sidebar" ? "topLeft" : "bottomRight",
|
|
@@ -70,15 +76,14 @@ function UserButton(props) {
|
|
|
70
76
|
type: "text",
|
|
71
77
|
icon: /*#__PURE__*/_jsx(Avatar, {
|
|
72
78
|
alt: "\u5934\u50CF",
|
|
73
|
-
src:
|
|
79
|
+
src: session.userInfo.picture,
|
|
74
80
|
icon: /*#__PURE__*/_jsx(UserOutlined, {})
|
|
75
81
|
}),
|
|
76
|
-
...rest,
|
|
77
82
|
styles: {
|
|
78
83
|
icon: {
|
|
79
84
|
display: "inline-flex",
|
|
80
85
|
alignItems: "center",
|
|
81
|
-
...
|
|
86
|
+
...resolvedStyles?.icon
|
|
82
87
|
}
|
|
83
88
|
},
|
|
84
89
|
style: {
|
|
@@ -89,14 +94,15 @@ function UserButton(props) {
|
|
|
89
94
|
} : {
|
|
90
95
|
paddingBlock: token.padding + token.paddingXS
|
|
91
96
|
}),
|
|
92
|
-
...
|
|
97
|
+
...style
|
|
93
98
|
},
|
|
99
|
+
...rest,
|
|
94
100
|
children: !compact && /*#__PURE__*/_jsxs(_Fragment, {
|
|
95
101
|
children: [/*#__PURE__*/_jsx("span", {
|
|
96
102
|
style: {
|
|
97
103
|
marginRight: token.marginXXS
|
|
98
104
|
},
|
|
99
|
-
children:
|
|
105
|
+
children: session.userInfo.name
|
|
100
106
|
}), layout === "sidebar" ? /*#__PURE__*/_jsx(UpOutlined, {}) : /*#__PURE__*/_jsx(DownOutlined, {})]
|
|
101
107
|
})
|
|
102
108
|
})
|
|
@@ -2,7 +2,7 @@ import { c as _c } from "react/compiler-runtime";
|
|
|
2
2
|
import { Button, Flex, Slider, Spin, theme } from "antd";
|
|
3
3
|
import { createStyles } from "antd-style";
|
|
4
4
|
import dayjs from "dayjs";
|
|
5
|
-
import DeckGL from "deck.gl";
|
|
5
|
+
import { DeckGL } from "deck.gl";
|
|
6
6
|
import { useMemo, useState } from "react";
|
|
7
7
|
import { MdDewPoint, MdThermostat } from "react-icons/md";
|
|
8
8
|
import { WiBarometer, WiCloudy, WiHumidity, WiRain, WiStrongWind } from "react-icons/wi";
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import { type ReactNode } from "react";
|
|
2
|
+
import type { AuthService } from "./AuthService";
|
|
3
|
+
import { SessionStore, type Session, type SessionStoreOptions } from "./SessionStore";
|
|
4
|
+
export type AuthProviderProps = TokenBasedAuthProviderProps | GenericAuthProviderProps;
|
|
5
|
+
export interface TokenBasedAuthProviderProps extends SessionStoreOptions {
|
|
6
|
+
service: AuthService<string, unknown>;
|
|
7
|
+
fetcherMiddleware?: boolean;
|
|
8
|
+
children: ReactNode;
|
|
9
|
+
}
|
|
10
|
+
export interface GenericAuthProviderProps extends SessionStoreOptions {
|
|
11
|
+
service: AuthService<unknown, unknown>;
|
|
12
|
+
fetcherMiddleware?: boolean;
|
|
13
|
+
persistent: false;
|
|
14
|
+
children: ReactNode;
|
|
15
|
+
}
|
|
16
|
+
export declare function AuthProvider(props: AuthProviderProps): import("react/jsx-runtime").JSX.Element;
|
|
17
|
+
export declare function useSessionStoreInternal(user: string): SessionStore;
|
|
18
|
+
export declare const useSessionStore: () => SessionStore;
|
|
19
|
+
export declare function useSessionInternal(user: string, allowNull?: false): Session;
|
|
20
|
+
export declare function useSessionInternal(user: string, allowNull: true): Session | null;
|
|
21
|
+
export interface UseSessionOptions {
|
|
22
|
+
/** 当未登录或已登出时是否抛出异常。 @default true */
|
|
23
|
+
allowNull?: boolean;
|
|
24
|
+
}
|
|
25
|
+
export interface UseSessionNonNullableOptions extends UseSessionOptions {
|
|
26
|
+
allowNull?: false;
|
|
27
|
+
}
|
|
28
|
+
export declare function useSession(options?: UseSessionNonNullableOptions): Session;
|
|
29
|
+
export declare function useSession(options?: UseSessionOptions): Session | null;
|
|
@@ -0,0 +1,138 @@
|
|
|
1
|
+
import { c as _c } from "react/compiler-runtime";
|
|
2
|
+
import { createContext, use, useState, useSyncExternalStore } from "react";
|
|
3
|
+
import { FetcherWithAuth } from "./Fetcher";
|
|
4
|
+
import { SessionStore } from "./SessionStore";
|
|
5
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
6
|
+
const AuthContext = /*#__PURE__*/createContext(null);
|
|
7
|
+
export function AuthProvider(props) {
|
|
8
|
+
const $ = _c(14);
|
|
9
|
+
let children;
|
|
10
|
+
let rest;
|
|
11
|
+
let service;
|
|
12
|
+
let t0;
|
|
13
|
+
if ($[0] !== props) {
|
|
14
|
+
({
|
|
15
|
+
service,
|
|
16
|
+
fetcherMiddleware: t0,
|
|
17
|
+
children,
|
|
18
|
+
...rest
|
|
19
|
+
} = props);
|
|
20
|
+
$[0] = props;
|
|
21
|
+
$[1] = children;
|
|
22
|
+
$[2] = rest;
|
|
23
|
+
$[3] = service;
|
|
24
|
+
$[4] = t0;
|
|
25
|
+
} else {
|
|
26
|
+
children = $[1];
|
|
27
|
+
rest = $[2];
|
|
28
|
+
service = $[3];
|
|
29
|
+
t0 = $[4];
|
|
30
|
+
}
|
|
31
|
+
const fetcherMiddleware = t0 === undefined ? true : t0;
|
|
32
|
+
let t1;
|
|
33
|
+
if ($[5] !== rest || $[6] !== service) {
|
|
34
|
+
t1 = () => new SessionStore(service, rest);
|
|
35
|
+
$[5] = rest;
|
|
36
|
+
$[6] = service;
|
|
37
|
+
$[7] = t1;
|
|
38
|
+
} else {
|
|
39
|
+
t1 = $[7];
|
|
40
|
+
}
|
|
41
|
+
const [sessionStore] = useState(t1);
|
|
42
|
+
let t2;
|
|
43
|
+
if ($[8] !== children || $[9] !== fetcherMiddleware) {
|
|
44
|
+
t2 = fetcherMiddleware ? /*#__PURE__*/_jsx(FetcherWithAuth, {
|
|
45
|
+
children: children
|
|
46
|
+
}) : children;
|
|
47
|
+
$[8] = children;
|
|
48
|
+
$[9] = fetcherMiddleware;
|
|
49
|
+
$[10] = t2;
|
|
50
|
+
} else {
|
|
51
|
+
t2 = $[10];
|
|
52
|
+
}
|
|
53
|
+
let t3;
|
|
54
|
+
if ($[11] !== sessionStore || $[12] !== t2) {
|
|
55
|
+
t3 = /*#__PURE__*/_jsx(AuthContext, {
|
|
56
|
+
value: sessionStore,
|
|
57
|
+
children: t2
|
|
58
|
+
});
|
|
59
|
+
$[11] = sessionStore;
|
|
60
|
+
$[12] = t2;
|
|
61
|
+
$[13] = t3;
|
|
62
|
+
} else {
|
|
63
|
+
t3 = $[13];
|
|
64
|
+
}
|
|
65
|
+
return t3;
|
|
66
|
+
}
|
|
67
|
+
export function useSessionStoreInternal(user) {
|
|
68
|
+
const sessionStore = use(AuthContext);
|
|
69
|
+
if (!sessionStore) {
|
|
70
|
+
throw new Error(user + " 只有在 AuthProvider 内部才能使用");
|
|
71
|
+
}
|
|
72
|
+
return sessionStore;
|
|
73
|
+
}
|
|
74
|
+
export const useSessionStore =
|
|
75
|
+
//
|
|
76
|
+
useSessionStoreInternal.bind(undefined, "useSessionStore");
|
|
77
|
+
export function useSessionInternal(user, t0) {
|
|
78
|
+
const $ = _c(4);
|
|
79
|
+
const allowNull = t0 === undefined ? false : t0;
|
|
80
|
+
const sessionStore = useSessionStoreInternal(user);
|
|
81
|
+
let t1;
|
|
82
|
+
if ($[0] !== sessionStore) {
|
|
83
|
+
t1 = onChange => {
|
|
84
|
+
sessionStore.addEventListener(onChange);
|
|
85
|
+
return () => sessionStore.addEventListener(onChange);
|
|
86
|
+
};
|
|
87
|
+
$[0] = sessionStore;
|
|
88
|
+
$[1] = t1;
|
|
89
|
+
} else {
|
|
90
|
+
t1 = $[1];
|
|
91
|
+
}
|
|
92
|
+
let t2;
|
|
93
|
+
if ($[2] !== sessionStore.session) {
|
|
94
|
+
t2 = () => sessionStore.session;
|
|
95
|
+
$[2] = sessionStore.session;
|
|
96
|
+
$[3] = t2;
|
|
97
|
+
} else {
|
|
98
|
+
t2 = $[3];
|
|
99
|
+
}
|
|
100
|
+
const session = useSyncExternalStore(t1, t2);
|
|
101
|
+
if (!(allowNull || session)) {
|
|
102
|
+
throw new Error(`当前用户未登录!请确保只在 LoginCheck 内部使用 ${user}。`);
|
|
103
|
+
}
|
|
104
|
+
return session;
|
|
105
|
+
}
|
|
106
|
+
export function useSession(t0) {
|
|
107
|
+
const $ = _c(4);
|
|
108
|
+
const options = t0 === undefined ? {} : t0;
|
|
109
|
+
const {
|
|
110
|
+
allowNull: t1
|
|
111
|
+
} = options;
|
|
112
|
+
const allowNull = t1 === undefined ? false : t1;
|
|
113
|
+
const sessionStore = useSessionStoreInternal("useSession");
|
|
114
|
+
let t2;
|
|
115
|
+
if ($[0] !== sessionStore) {
|
|
116
|
+
t2 = onChange => {
|
|
117
|
+
sessionStore.addEventListener(onChange);
|
|
118
|
+
return () => sessionStore.addEventListener(onChange);
|
|
119
|
+
};
|
|
120
|
+
$[0] = sessionStore;
|
|
121
|
+
$[1] = t2;
|
|
122
|
+
} else {
|
|
123
|
+
t2 = $[1];
|
|
124
|
+
}
|
|
125
|
+
let t3;
|
|
126
|
+
if ($[2] !== sessionStore.session) {
|
|
127
|
+
t3 = () => sessionStore.session;
|
|
128
|
+
$[2] = sessionStore.session;
|
|
129
|
+
$[3] = t3;
|
|
130
|
+
} else {
|
|
131
|
+
t3 = $[3];
|
|
132
|
+
}
|
|
133
|
+
const session = useSyncExternalStore(t2, t3);
|
|
134
|
+
if (!(allowNull || session)) {
|
|
135
|
+
throw new Error("\u5F53\u524D\u7528\u6237\u672A\u767B\u5F55\uFF0C\u65E0\u6CD5\u83B7\u53D6\u4F1A\u8BDD\u3002\u8BF7\u786E\u4FDD\u53EA\u5728 LoginCheck \u5185\u90E8\u4F7F\u7528 useSession\uFF0C\u6216\u8005\u5C06 allowNull \u8BBE\u4E3A true\u3002");
|
|
136
|
+
}
|
|
137
|
+
return session;
|
|
138
|
+
}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import type { Fetcher } from "./Fetcher";
|
|
2
|
+
/**
|
|
3
|
+
* 鉴权操作的抽象接口。
|
|
4
|
+
*
|
|
5
|
+
* 对于实现者来说,需要注意实现该接口的类自身不应该保存会话状态。
|
|
6
|
+
*/
|
|
7
|
+
export interface AuthService<State = unknown, RawUserInfo = unknown> {
|
|
8
|
+
/**
|
|
9
|
+
* 获取一个新会话,返回会话状态。
|
|
10
|
+
*
|
|
11
|
+
* 在不同实现中,这个函数不一定是登录,也有可能是向父页面获取 token 等其他操作。
|
|
12
|
+
* 某些实现返回的 Promise 可能永远都不会 resolve(例如跳转到了登录页面)。
|
|
13
|
+
*/
|
|
14
|
+
getSession(): Promise<State>;
|
|
15
|
+
/** 在线验证会话状态是否有效。有效时返回 `RawUserInfo`,无效时抛出异常。 */
|
|
16
|
+
validate(state: State): Promise<RawUserInfo>;
|
|
17
|
+
/** 使会话立即失效。很多实现不提供该操作。 */
|
|
18
|
+
endSession?(state: State): Promise<void>;
|
|
19
|
+
/** 创建使用会话状态鉴权的 fetcher 中间件,可搭配 {@linkcode FetcherMiddleware} 使用。 */
|
|
20
|
+
fetcherMiddleware(state: State): (fetcher: Fetcher) => Fetcher;
|
|
21
|
+
/** 从特定于实现的 `RawUserInfo` 中提取出格式统一的通用信息。 */
|
|
22
|
+
parseUserInfo(info: RawUserInfo): UserInfo;
|
|
23
|
+
}
|
|
24
|
+
/** 格式统一的通用个人信息。 */
|
|
25
|
+
export interface UserInfo {
|
|
26
|
+
/** 用户的显示名 */
|
|
27
|
+
name: string;
|
|
28
|
+
/** 用户的头像 URL */
|
|
29
|
+
picture?: string;
|
|
30
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,135 @@
|
|
|
1
|
+
import type { SdkConfig } from "casdoor-js-sdk/lib/esm/sdk";
|
|
2
|
+
import type { JwtPayload } from "jwt-decode";
|
|
3
|
+
import { type ReactNode } from "react";
|
|
4
|
+
import type { AuthService, UserInfo } from "./AuthService";
|
|
5
|
+
import { fetcherWithBearerToken } from "./Fetcher";
|
|
6
|
+
export interface CasdoorAuthServiceOptions {
|
|
7
|
+
config: SdkConfig;
|
|
8
|
+
signinOrigin?: string;
|
|
9
|
+
signinPath?: string | undefined;
|
|
10
|
+
}
|
|
11
|
+
export declare class CasdoorAuthService implements AuthService<string, CasdoorUserInfo> {
|
|
12
|
+
#private;
|
|
13
|
+
constructor(options: CasdoorAuthServiceOptions);
|
|
14
|
+
getSession(): Promise<string>;
|
|
15
|
+
validate(token: string): Promise<CasdoorUserInfo>;
|
|
16
|
+
/**
|
|
17
|
+
* CasdoorAuthService 的特有函数。
|
|
18
|
+
* 使用 CasdoorAuthService 时,需要在项目中设置一个回调页面。
|
|
19
|
+
* 当用户完成登录,跳转到回调页面时,可调用此函数获取 access token。
|
|
20
|
+
* 若用户不经过登录流程进入回调页面,或者后端发生错误,则会抛出异常。
|
|
21
|
+
*/
|
|
22
|
+
callback(): Promise<string>;
|
|
23
|
+
fetcherMiddleware: typeof fetcherWithBearerToken;
|
|
24
|
+
parseUserInfo(info: CasdoorUserInfo): UserInfo;
|
|
25
|
+
}
|
|
26
|
+
export interface CasdoorTokenPayload extends JwtPayload {
|
|
27
|
+
/**
|
|
28
|
+
* Token 的发布者。见 [JWT 标准][1]。
|
|
29
|
+
*
|
|
30
|
+
* [1]: https://datatracker.ietf.org/doc/html/rfc7519#section-4.1
|
|
31
|
+
*/
|
|
32
|
+
iss: string;
|
|
33
|
+
/**
|
|
34
|
+
* Token 的主题。见 [JWT 标准][1]。
|
|
35
|
+
*
|
|
36
|
+
* [1]: https://datatracker.ietf.org/doc/html/rfc7519#section-4.1
|
|
37
|
+
*/
|
|
38
|
+
sub: string;
|
|
39
|
+
/**
|
|
40
|
+
* Token 的目标应用 ID。见 [JWT 标准][1]。
|
|
41
|
+
*
|
|
42
|
+
* [1]: https://datatracker.ietf.org/doc/html/rfc7519#section-4.1
|
|
43
|
+
*/
|
|
44
|
+
aud: string[];
|
|
45
|
+
/**
|
|
46
|
+
* 使用 Token 的应用 ID。见 [JWT 标准][1]。
|
|
47
|
+
*
|
|
48
|
+
* [1]: https://datatracker.ietf.org/doc/html/rfc7519#section-4.1
|
|
49
|
+
*/
|
|
50
|
+
azp: string;
|
|
51
|
+
/**
|
|
52
|
+
* Token 的唯一标识符。见 [JWT 标准][1]。
|
|
53
|
+
*
|
|
54
|
+
* [1]: https://datatracker.ietf.org/doc/html/rfc7519#section-4.1
|
|
55
|
+
*/
|
|
56
|
+
jti: string;
|
|
57
|
+
/** Token 的过期时间(Unix 时间戳)。*/
|
|
58
|
+
exp: number;
|
|
59
|
+
/** Token 的生效时间(Unix 时间戳)。*/
|
|
60
|
+
nbf: number;
|
|
61
|
+
/** Token 的签发时间(Unix 时间戳)。*/
|
|
62
|
+
iat: number;
|
|
63
|
+
/** 用户的登录名。*/
|
|
64
|
+
name: string;
|
|
65
|
+
/** 用户的 UUID。*/
|
|
66
|
+
id: string;
|
|
67
|
+
/** 用户的显示名。*/
|
|
68
|
+
displayName: string;
|
|
69
|
+
/** 用户的头像 URL。*/
|
|
70
|
+
avatar: string;
|
|
71
|
+
/** 用户的邮件地址。*/
|
|
72
|
+
email: string;
|
|
73
|
+
/** 用户的手机号。*/
|
|
74
|
+
phone: string;
|
|
75
|
+
owner: "tsingroc";
|
|
76
|
+
tokenType: "access-token";
|
|
77
|
+
scope: "profile";
|
|
78
|
+
}
|
|
79
|
+
export interface CasdoorUserInfo {
|
|
80
|
+
/**
|
|
81
|
+
* Token 的发布者。见 [JWT 标准][1]。
|
|
82
|
+
*
|
|
83
|
+
* [1]: https://datatracker.ietf.org/doc/html/rfc7519#section-4.1
|
|
84
|
+
*/
|
|
85
|
+
iss: string;
|
|
86
|
+
/**
|
|
87
|
+
* Token 的主题。见 [JWT 标准][1]。
|
|
88
|
+
*
|
|
89
|
+
* [1]: https://datatracker.ietf.org/doc/html/rfc7519#section-4.1
|
|
90
|
+
*/
|
|
91
|
+
sub: string;
|
|
92
|
+
/**
|
|
93
|
+
* Token 的目标应用 ID。见 [JWT 标准][1]。
|
|
94
|
+
*
|
|
95
|
+
* [1]: https://datatracker.ietf.org/doc/html/rfc7519#section-4.1
|
|
96
|
+
*/
|
|
97
|
+
aud: string;
|
|
98
|
+
/** 用户的全名(显示名)。*/
|
|
99
|
+
name: string;
|
|
100
|
+
/** 短用户名(登录名)。*/
|
|
101
|
+
prefered_username?: string;
|
|
102
|
+
/** 用户的邮件地址。*/
|
|
103
|
+
email?: string;
|
|
104
|
+
/** 用户的邮件地址是否已确认。*/
|
|
105
|
+
email_verified?: boolean;
|
|
106
|
+
/** 用户的手机号。*/
|
|
107
|
+
phone?: string;
|
|
108
|
+
/** 用户的头像 URL。*/
|
|
109
|
+
picture: string;
|
|
110
|
+
/** 用户的地址。*/
|
|
111
|
+
address?: string;
|
|
112
|
+
/** 用户所属的用户组。*/
|
|
113
|
+
groups: string[];
|
|
114
|
+
/** 用户的角色。*/
|
|
115
|
+
roles: string[];
|
|
116
|
+
}
|
|
117
|
+
export interface CasdoorCallbackProps {
|
|
118
|
+
onSuccess?: () => void;
|
|
119
|
+
onError?: (err: unknown) => void;
|
|
120
|
+
success?: ReactNode;
|
|
121
|
+
error?: ReactNode;
|
|
122
|
+
/**
|
|
123
|
+
* 跳转前显示的内容。
|
|
124
|
+
* @default "正在跳转……"
|
|
125
|
+
*/
|
|
126
|
+
children?: ReactNode;
|
|
127
|
+
}
|
|
128
|
+
export declare function CasdoorCallback(props: CasdoorCallbackProps): string | number | bigint | boolean | import("react").ReactElement<unknown, string | import("react").JSXElementConstructor<any>> | Iterable<ReactNode> | Promise<string | number | bigint | boolean | import("react").ReactPortal | import("react").ReactElement<unknown, string | import("react").JSXElementConstructor<any>> | Iterable<ReactNode> | null | undefined> | null;
|
|
129
|
+
export interface CasdoorRoleCheckProps {
|
|
130
|
+
required: string[];
|
|
131
|
+
forbidden?: string[];
|
|
132
|
+
error?: ReactNode;
|
|
133
|
+
children: ReactNode;
|
|
134
|
+
}
|
|
135
|
+
export declare function CasdoorRoleCheck(props: CasdoorRoleCheckProps): ReactNode;
|