@morehao/ark-iam-react 0.0.0-stage → 1.0.0

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.

Potentially problematic release.


This version of @morehao/ark-iam-react might be problematic. Click here for more details.

Files changed (66) hide show
  1. package/README.md +83 -2
  2. package/dist/_types/api/index.d.ts +5 -0
  3. package/dist/_types/api/index.js +185 -0
  4. package/dist/_types/api/index.js.map +1 -0
  5. package/dist/_types/api/request.d.ts +34 -0
  6. package/dist/_types/api/resources/auth.d.ts +13 -0
  7. package/dist/_types/api/resources/platform.d.ts +80 -0
  8. package/dist/_types/api/sessionProbe.d.ts +13 -0
  9. package/dist/_types/auth/AuthProvider.d.ts +27 -0
  10. package/dist/_types/auth/config.d.ts +23 -0
  11. package/dist/_types/auth/guards.d.ts +1 -0
  12. package/dist/_types/auth/hooks.d.ts +11 -0
  13. package/dist/_types/auth/index.d.ts +8 -0
  14. package/dist/_types/auth/index.js +190 -0
  15. package/dist/_types/auth/index.js.map +1 -0
  16. package/dist/_types/auth/tenant.d.ts +3 -0
  17. package/dist/_types/types/auth.d.ts +62 -0
  18. package/dist/_types/types/department.d.ts +52 -0
  19. package/dist/_types/types/index.d.ts +5 -0
  20. package/dist/_types/types/index.js +14 -0
  21. package/dist/_types/types/index.js.map +1 -0
  22. package/dist/_types/types/platform.d.ts +347 -0
  23. package/dist/_types/types/response.d.ts +14 -0
  24. package/dist/_types/types/tenant.d.ts +243 -0
  25. package/dist/_types/ui/AppShell.d.ts +16 -0
  26. package/dist/_types/ui/EllipsisCell.d.ts +16 -0
  27. package/dist/_types/ui/IDCell.d.ts +14 -0
  28. package/dist/_types/ui/InitialPasswordModal.d.ts +18 -0
  29. package/dist/_types/ui/LoginPage.d.ts +6 -0
  30. package/dist/_types/ui/MainLayout.d.ts +14 -0
  31. package/dist/_types/ui/NameLink.d.ts +18 -0
  32. package/dist/_types/ui/PageContainer.d.ts +15 -0
  33. package/dist/_types/ui/ProfileCenter.d.ts +6 -0
  34. package/dist/_types/ui/RemoteSelect.d.ts +57 -0
  35. package/dist/_types/ui/RowActions.d.ts +36 -0
  36. package/dist/_types/ui/TenantSwitcher.d.ts +1 -0
  37. package/dist/_types/ui/TimeCell.d.ts +53 -0
  38. package/dist/_types/ui/columns.d.ts +116 -0
  39. package/dist/_types/ui/format.d.ts +20 -0
  40. package/dist/_types/ui/index.d.ts +25 -0
  41. package/dist/_types/ui/index.js +1233 -0
  42. package/dist/_types/ui/index.js.map +1 -0
  43. package/dist/_types/ui/status.d.ts +38 -0
  44. package/dist/_types/ui/theme.d.ts +49 -0
  45. package/dist/api.d.ts +1 -0
  46. package/dist/api.js +50 -0
  47. package/dist/api.js.map +1 -0
  48. package/dist/auth.d.ts +1 -0
  49. package/dist/auth.js +17 -0
  50. package/dist/auth.js.map +1 -0
  51. package/dist/index-BQuRl5A6.js +185 -0
  52. package/dist/index-BQuRl5A6.js.map +1 -0
  53. package/dist/index-D3uUqZ5c.js +190 -0
  54. package/dist/index-D3uUqZ5c.js.map +1 -0
  55. package/dist/index-DnhMUOxg.js +1233 -0
  56. package/dist/index-DnhMUOxg.js.map +1 -0
  57. package/dist/index.d.ts +4 -0
  58. package/dist/index.js +109 -0
  59. package/dist/index.js.map +1 -0
  60. package/dist/types.d.ts +1 -0
  61. package/dist/types.js +14 -0
  62. package/dist/types.js.map +1 -0
  63. package/dist/ui.d.ts +1 -0
  64. package/dist/ui.js +46 -0
  65. package/dist/ui.js.map +1 -0
  66. package/package.json +80 -3
@@ -0,0 +1,190 @@
1
+ var _a;
2
+ import { jsx, jsxs } from "react/jsx-runtime";
3
+ import { useState, useEffect, useCallback } from "react";
4
+ import { BrowserRouter } from "react-router-dom";
5
+ import { AuthProvider, useAuth } from "react-oidc-context";
6
+ import { WebStorageStateStore } from "oidc-client-ts";
7
+ import { message, Spin } from "antd";
8
+ import { useSSOSessionProbe, setUserProvider, setSessionExpiredHandler, logoutAllAPI, getMyTenants } from "@ark-iam/api";
9
+ const defaultIssuer = "/oidc";
10
+ const defaultRedirectPath = "/auth/callback";
11
+ const defaultPostLogoutRedirectPath = "/login";
12
+ const defaultScope = "openid profile email offline_access";
13
+ async function fetchRuntimeConfig(base) {
14
+ var _a2, _b;
15
+ const root = base ?? (((_b = (_a2 = import.meta) == null ? void 0 : _a2.env) == null ? void 0 : _b.BASE_URL) ?? "/");
16
+ try {
17
+ const res = await fetch(`${root}${root.endsWith("/") ? "" : "/"}config.json`, {
18
+ credentials: "same-origin",
19
+ headers: { Accept: "application/json" }
20
+ });
21
+ if (!res.ok) return null;
22
+ return await res.json();
23
+ } catch {
24
+ return null;
25
+ }
26
+ }
27
+ const oidcExtraQueryParams = {};
28
+ let currentTenantId = "";
29
+ function getCurrentTenantId() {
30
+ return currentTenantId;
31
+ }
32
+ function setCurrentTenantId(id) {
33
+ const next = id == null ? "" : String(id);
34
+ currentTenantId = next;
35
+ if (next) {
36
+ oidcExtraQueryParams.tenant = next;
37
+ } else {
38
+ delete oidcExtraQueryParams.tenant;
39
+ }
40
+ }
41
+ const ENV = ((_a = import.meta) == null ? void 0 : _a.env) ?? {};
42
+ function buildConfig(opts, runtime) {
43
+ const issuer = opts.issuer || (runtime == null ? void 0 : runtime.issuer) || ENV.VITE_OIDC_ISSUER || defaultIssuer;
44
+ const clientId = opts.clientID || (runtime == null ? void 0 : runtime.clientId) || ENV.VITE_OIDC_CLIENT_ID || "";
45
+ const redirectPath = opts.redirectPath || (runtime == null ? void 0 : runtime.callbackPath) || defaultRedirectPath;
46
+ const postLogoutRedirectPath = opts.postLogoutRedirectPath || defaultPostLogoutRedirectPath;
47
+ return { issuer, clientId, redirectPath, postLogoutRedirectPath };
48
+ }
49
+ function createAuthProvider(opts = {}) {
50
+ return function AuthProvider$1({ children }) {
51
+ const useRuntime = opts.useRuntimeConfig !== false;
52
+ const [runtime, setRuntime] = useState(
53
+ useRuntime ? void 0 : null
54
+ );
55
+ useEffect(() => {
56
+ if (!useRuntime) return;
57
+ let cancelled = false;
58
+ void fetchRuntimeConfig(opts.runtimeConfigBase).then((cfg) => {
59
+ if (!cancelled) setRuntime(cfg);
60
+ });
61
+ return () => {
62
+ cancelled = true;
63
+ };
64
+ }, []);
65
+ if (runtime === void 0) return null;
66
+ const { issuer, clientId, redirectPath, postLogoutRedirectPath } = buildConfig(opts, runtime);
67
+ const oidcConfig = {
68
+ authority: issuer,
69
+ client_id: clientId,
70
+ ...opts.clientSecret ? { client_secret: opts.clientSecret } : {},
71
+ redirect_uri: window.location.origin + redirectPath,
72
+ post_logout_redirect_uri: window.location.origin + postLogoutRedirectPath,
73
+ scope: defaultScope,
74
+ automaticSilentRenew: true,
75
+ // monitorSession 需要 OP 在 discovery 暴露 check_session_iframe(OIDC Session
76
+ // Management)。当前 OP(zitadel)未启用该端点,oidc-client-ts 会自动降级为不监控。
77
+ // "一处登出、处处登出"的即时性主要由后端请求粒度 SSO 活性校验保障
78
+ // (WithOIDCSSOValidation + HasActiveSession),此配置仅作跨标签页监控的尽力而为。
79
+ monitorSession: true,
80
+ loadUserInfo: true,
81
+ // 令牌存储:使用 sessionStorage(标签页级,关闭即清)而非 localStorage,
82
+ // 缩小 XSS 窃取令牌的持续暴露窗口。SSO 认证态本身在 OP 的 iam_sso_session
83
+ // cookie,不依赖前端存储;页面刷新/静默续期不受影响。
84
+ userStore: new WebStorageStateStore({ store: sessionStorage }),
85
+ extraQueryParams: {
86
+ ...oidcExtraQueryParams,
87
+ ...opts.getExtraQueryParams ? opts.getExtraQueryParams() : {}
88
+ }
89
+ };
90
+ return /* @__PURE__ */ jsx(BrowserRouter, { children: /* @__PURE__ */ jsx(AuthProvider, { ...oidcConfig, children }) });
91
+ };
92
+ }
93
+ function useTenantSwitching() {
94
+ const auth = useAuth();
95
+ const [tenants, setTenants] = useState([]);
96
+ const loadTenants = useCallback(async () => {
97
+ try {
98
+ const resp = await getMyTenants();
99
+ setTenants(resp.list || []);
100
+ } catch {
101
+ message.warning("获取可用租户失败");
102
+ }
103
+ }, []);
104
+ const handleSwitchTenant = useCallback(
105
+ async (tenantID) => {
106
+ if (String(tenantID) === getCurrentTenantId()) return;
107
+ setCurrentTenantId(tenantID);
108
+ try {
109
+ await auth.removeUser();
110
+ } catch {
111
+ }
112
+ await auth.signinRedirect({ extraQueryParams: { tenant: String(tenantID) }, redirectMethod: "replace" });
113
+ },
114
+ [auth]
115
+ );
116
+ return { tenants, loadTenants, handleSwitchTenant };
117
+ }
118
+ function useLogout() {
119
+ const auth = useAuth();
120
+ return useCallback(async () => {
121
+ var _a2;
122
+ try {
123
+ await logoutAllAPI(((_a2 = auth.user) == null ? void 0 : _a2.refresh_token) ?? "");
124
+ } catch {
125
+ }
126
+ try {
127
+ await auth.signoutRedirect();
128
+ } finally {
129
+ await auth.removeUser();
130
+ }
131
+ }, [auth]);
132
+ }
133
+ function useAuthGuard() {
134
+ const auth = useAuth();
135
+ useSSOSessionProbe(auth);
136
+ useEffect(() => {
137
+ setUserProvider(() => auth.user);
138
+ }, [auth.user]);
139
+ useEffect(() => {
140
+ setSessionExpiredHandler(() => {
141
+ void auth.removeUser();
142
+ });
143
+ }, [auth]);
144
+ useEffect(() => {
145
+ var _a2, _b;
146
+ const claim = (_b = (_a2 = auth.user) == null ? void 0 : _a2.profile) == null ? void 0 : _b.tenant_id;
147
+ if (claim != null && getCurrentTenantId() !== String(claim)) {
148
+ setCurrentTenantId(claim);
149
+ }
150
+ }, [auth.user]);
151
+ return auth;
152
+ }
153
+ const LOADING_BG = "#f6f7f9";
154
+ const LOADING_TEXT = "#94a3b8";
155
+ function FullPageSpinner() {
156
+ return /* @__PURE__ */ jsxs(
157
+ "div",
158
+ {
159
+ style: {
160
+ minHeight: "100vh",
161
+ display: "flex",
162
+ flexDirection: "column",
163
+ alignItems: "center",
164
+ justifyContent: "center",
165
+ gap: 16,
166
+ background: LOADING_BG
167
+ },
168
+ children: [
169
+ /* @__PURE__ */ jsx(Spin, { size: "large" }),
170
+ /* @__PURE__ */ jsx("span", { style: { color: LOADING_TEXT, fontSize: 13 }, children: "正在加载 IAM 平台…" })
171
+ ]
172
+ }
173
+ );
174
+ }
175
+ export {
176
+ FullPageSpinner,
177
+ createAuthProvider,
178
+ defaultIssuer,
179
+ defaultPostLogoutRedirectPath,
180
+ defaultRedirectPath,
181
+ defaultScope,
182
+ fetchRuntimeConfig,
183
+ getCurrentTenantId,
184
+ oidcExtraQueryParams,
185
+ setCurrentTenantId,
186
+ useAuthGuard,
187
+ useLogout,
188
+ useTenantSwitching
189
+ };
190
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sources":["../src/config.ts","../src/tenant.ts","../src/AuthProvider.tsx","../src/hooks.ts","../src/guards.tsx"],"sourcesContent":["// OIDC 客户端共享配置。\n//\n// 集中 OIDC 相关默认值,供 AuthProvider 与各业务 App(main.tsx)复用,\n// 避免 issuer / 默认路径等在多个文件间漂移。\n//\n// 配置优先级(越靠前越优先):\n// 1. createAuthProvider(opts) 显式传入的 props(issuer / clientId / redirectPath ...)\n// 2. /config.json 运行时配置(createAuthProvider 启动先 fetch,见 fetchRuntimeConfig)\n// 3. import.meta.env.VITE_* 构建期常量(仅仓内 / 自托管构建期的便捷覆盖)\n// 4. 下方相对默认值(开发环境经 Vite 代理到后端)\n//\n// 外部接入方通常无需设任何 VITE_*:只需提供 clientID,或让后端 /config.json 下发。\n\n// defaultIssuer 是开发环境的默认 issuer(相对路径,经 Vite 代理到后端)。\nexport const defaultIssuer = '/oidc'\n\n// defaultRedirectPath 是 OIDC 授权回调路径(拼接在 window.location.origin 后)。\nexport const defaultRedirectPath = '/auth/callback'\n\n// defaultPostLogoutRedirectPath 是登出后回跳路径。\nexport const defaultPostLogoutRedirectPath = '/login'\n\n// defaultScope 是申请的标准 OIDC scope;offline_access 用于签发 refresh token。\nexport const defaultScope = 'openid profile email offline_access'\n\n/**\n * RuntimeConfig 是后端 /config.json 下发的运行时配置(见 backend/iam/app_frontend.go)。\n * 字段全部可选:缺失时逐字段回退到 VITE_* / 相对默认值。\n */\nexport interface RuntimeConfig {\n issuer?: string\n apiBase?: string\n oidcBase?: string\n callbackPath?: string\n clientId?: string\n}\n\n/**\n * fetchRuntimeConfig 从 `{base}/config.json` 拉取运行时配置。\n *\n * - base 默认取 `import.meta.env.BASE_URL`(Vite 注入;自托管常为 '/'),保证子路径部署也能命中。\n * - 任一环节失败(网络、非 2xx、非 JSON)都 resolve 为 null,由调用方回退默认值,绝不 reject,\n * 避免因配置端点不可用而阻断整个应用启动。\n */\nexport async function fetchRuntimeConfig(base?: string): Promise<RuntimeConfig | null> {\n // import.meta.env.BASE_URL 在 Vite 下恒为 '/'(或显式 base),保证末尾带 '/'。\n const root: string = base ?? ((import.meta as any)?.env?.BASE_URL ?? '/')\n try {\n const res = await fetch(`${root}${root.endsWith('/') ? '' : '/'}config.json`, {\n credentials: 'same-origin',\n headers: { Accept: 'application/json' },\n })\n if (!res.ok) return null\n return (await res.json()) as RuntimeConfig\n } catch {\n return null\n }\n}\n","export const oidcExtraQueryParams: Record<string, string | number | boolean> = {}\n\nlet currentTenantId = ''\n\nexport function getCurrentTenantId(): string {\n return currentTenantId\n}\n\nexport function setCurrentTenantId(id: string | number | undefined) {\n const next = id == null ? '' : String(id)\n currentTenantId = next\n if (next) {\n oidcExtraQueryParams.tenant = next\n } else {\n delete oidcExtraQueryParams.tenant\n }\n}\n","import React, { useEffect, useState } from 'react'\nimport { BrowserRouter } from 'react-router-dom'\nimport { AuthProvider as OidcAuthProvider } from 'react-oidc-context'\nimport { WebStorageStateStore } from 'oidc-client-ts'\nimport {\n defaultIssuer,\n defaultRedirectPath,\n defaultPostLogoutRedirectPath,\n defaultScope,\n fetchRuntimeConfig,\n type RuntimeConfig,\n} from './config'\nimport { oidcExtraQueryParams } from './tenant'\n\nexport interface CreateAuthProviderOptions {\n /**\n * OIDC client_id(控制台应用的 application_client.code)。\n * 未传时优先用 /config.json 的 clientId,再退回 import.meta.env.VITE_OIDC_CLIENT_ID。\n */\n clientID?: string\n clientSecret?: string\n /**\n * OIDC issuer(OP 地址)。未传时优先级:/config.json.issuer > VITE_OIDC_ISSUER > '/oidc'。\n * 多源部署时可显式传 OP 的绝对地址(如 https://iam.example.com/oidc)。\n */\n issuer?: string\n redirectPath?: string\n postLogoutRedirectPath?: string\n getExtraQueryParams?: () => Record<string, string | number | boolean>\n /**\n * 是否在启动时拉取 `{base}/config.json` 作为运行时配置来源(默认 true)。\n * 置 false 则完全走 props / VITE_* / 默认值,适用于无 IAM 托管 / 无 config.json 的场景。\n */\n useRuntimeConfig?: boolean\n /** config.json 的拉取基址;默认 import.meta.env.BASE_URL。 */\n runtimeConfigBase?: string\n}\n\nconst ENV = (import.meta as any)?.env ?? {}\n\n// buildConfig 把「props > /config.json > VITE_* > 相对默认值」的优先级收敛为一层。\nfunction buildConfig(opts: CreateAuthProviderOptions, runtime: RuntimeConfig | null) {\n const issuer = opts.issuer || runtime?.issuer || ENV.VITE_OIDC_ISSUER || defaultIssuer\n const clientId =\n opts.clientID || runtime?.clientId || ENV.VITE_OIDC_CLIENT_ID || ''\n const redirectPath = opts.redirectPath || runtime?.callbackPath || defaultRedirectPath\n const postLogoutRedirectPath = opts.postLogoutRedirectPath || defaultPostLogoutRedirectPath\n return { issuer, clientId, redirectPath, postLogoutRedirectPath }\n}\n\nexport function createAuthProvider(opts: CreateAuthProviderOptions = {}) {\n return function AuthProvider({ children }: { children: React.ReactNode }) {\n const useRuntime = opts.useRuntimeConfig !== false\n // runtime 为 undefined 表示「尚未就绪」(加载中);null 表示「已尝试但不可用」,走回退。\n const [runtime, setRuntime] = useState<RuntimeConfig | null | undefined>(\n useRuntime ? undefined : null,\n )\n\n useEffect(() => {\n if (!useRuntime) return\n let cancelled = false\n void fetchRuntimeConfig(opts.runtimeConfigBase).then((cfg) => {\n if (!cancelled) setRuntime(cfg)\n })\n return () => {\n cancelled = true\n }\n // 仅挂载时拉取一次:运行时配置在应用生命周期内不变。\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [])\n\n // 加载中:先渲染 children 会拿到未就绪配置(issuer/clientId 可能为默认值),\n // 故等待 config.json 拉取完成(成功或失败都落定)再接 AuthProvider,避免一次错误的授权跳转。\n if (runtime === undefined) return null\n\n const { issuer, clientId, redirectPath, postLogoutRedirectPath } = buildConfig(opts, runtime)\n\n const oidcConfig = {\n authority: issuer,\n client_id: clientId,\n ...(opts.clientSecret ? { client_secret: opts.clientSecret } : {}),\n redirect_uri: window.location.origin + redirectPath,\n post_logout_redirect_uri: window.location.origin + postLogoutRedirectPath,\n scope: defaultScope,\n automaticSilentRenew: true,\n // monitorSession 需要 OP 在 discovery 暴露 check_session_iframe(OIDC Session\n // Management)。当前 OP(zitadel)未启用该端点,oidc-client-ts 会自动降级为不监控。\n // \"一处登出、处处登出\"的即时性主要由后端请求粒度 SSO 活性校验保障\n // (WithOIDCSSOValidation + HasActiveSession),此配置仅作跨标签页监控的尽力而为。\n monitorSession: true,\n loadUserInfo: true,\n // 令牌存储:使用 sessionStorage(标签页级,关闭即清)而非 localStorage,\n // 缩小 XSS 窃取令牌的持续暴露窗口。SSO 认证态本身在 OP 的 iam_sso_session\n // cookie,不依赖前端存储;页面刷新/静默续期不受影响。\n userStore: new WebStorageStateStore({ store: sessionStorage }),\n extraQueryParams: {\n ...oidcExtraQueryParams,\n ...(opts.getExtraQueryParams ? opts.getExtraQueryParams() : {}),\n },\n }\n\n return (\n <BrowserRouter>\n <OidcAuthProvider {...oidcConfig}>{children}</OidcAuthProvider>\n </BrowserRouter>\n )\n }\n}\n","import { useCallback, useEffect, useState } from 'react'\nimport { useAuth } from 'react-oidc-context'\nimport { message } from 'antd'\nimport {\n getMyTenants,\n logoutAllAPI,\n setUserProvider,\n setSessionExpiredHandler,\n useSSOSessionProbe,\n} from '@ark-iam/api'\nimport { getCurrentTenantId, setCurrentTenantId } from './tenant'\n\nexport interface TenantSwitchInfo {\n tenants: { tenantID: string; name: string }[]\n loadTenants: () => Promise<void>\n handleSwitchTenant: (tenantID: string) => Promise<void>\n}\n\nexport function useTenantSwitching(): TenantSwitchInfo {\n const auth = useAuth()\n const [tenants, setTenants] = useState<{ tenantID: string; name: string }[]>([])\n\n const loadTenants = useCallback(async () => {\n try {\n const resp = await getMyTenants()\n setTenants(resp.list || [])\n } catch {\n message.warning('获取可用租户失败')\n }\n }, [])\n\n const handleSwitchTenant = useCallback(\n async (tenantID: string) => {\n if (String(tenantID) === getCurrentTenantId()) return\n setCurrentTenantId(tenantID)\n try {\n await auth.removeUser()\n } catch {\n // 本地清理失败不阻断重授权\n }\n await auth.signinRedirect({ extraQueryParams: { tenant: String(tenantID) }, redirectMethod: 'replace' })\n },\n [auth],\n )\n\n return { tenants, loadTenants, handleSwitchTenant }\n}\n\nexport function useLogout() {\n const auth = useAuth()\n return useCallback(async () => {\n try {\n await logoutAllAPI(auth.user?.refresh_token ?? '')\n } catch {\n // ignore:撤销自有 refresh token 为尽力而为,失败不阻断登出\n }\n // 先 signoutRedirect 再 removeUser,保证 id_token_hint 仍存在以撤销后端 SSO session\n try {\n await auth.signoutRedirect()\n } finally {\n await auth.removeUser()\n }\n }, [auth])\n}\n\nexport function useAuthGuard() {\n const auth = useAuth()\n\n useSSOSessionProbe(auth)\n\n useEffect(() => {\n setUserProvider(() => auth.user)\n }, [auth.user])\n\n // 401(SSO 会话已被其它端点全局登出撤销)时,先移除本地 user 再跳转登录,\n // 避免 \"401 → 刷新 → sessionStorage 残留 user → 再 401\" 的死循环。\n useEffect(() => {\n setSessionExpiredHandler(() => {\n void auth.removeUser()\n })\n }, [auth])\n\n useEffect(() => {\n const claim = (auth.user?.profile as Record<string, unknown> | undefined)?.tenant_id\n if (claim != null && getCurrentTenantId() !== String(claim)) {\n setCurrentTenantId(claim as string | number)\n }\n }, [auth.user])\n\n return auth\n}\n","import { Spin } from 'antd'\n\n// 注:auth 包处于 ui 下层(ui → auth 依赖方向),无法引用 @ark-iam/ui tokens,\n// 这里的中性色与 DESIGN.md「冷白工程台」灰阶保持一致,改动需手动同步。\nconst LOADING_BG = '#f6f7f9'\nconst LOADING_TEXT = '#94a3b8'\n\nexport function FullPageSpinner() {\n return (\n <div\n style={{\n minHeight: '100vh',\n display: 'flex',\n flexDirection: 'column',\n alignItems: 'center',\n justifyContent: 'center',\n gap: 16,\n background: LOADING_BG,\n }}\n >\n <Spin size=\"large\" />\n <span style={{ color: LOADING_TEXT, fontSize: 13 }}>正在加载 IAM 平台…</span>\n </div>\n )\n}\n"],"names":["_a","AuthProvider","OidcAuthProvider"],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ export declare const oidcExtraQueryParams: Record<string, string | number | boolean>;
2
+ export declare function getCurrentTenantId(): string;
3
+ export declare function setCurrentTenantId(id: string | number | undefined): void;
@@ -0,0 +1,62 @@
1
+ import type { OwnerType } from './tenant';
2
+ /**
3
+ * 自然人可用性(后端具名类型 model.PersonStatus):active-正常 / suspended-已挂起
4
+ * (suspended 禁止登录与签发令牌,语义对齐 tenant.status 的挂起)。
5
+ */
6
+ export type PersonStatus = 'active' | 'suspended';
7
+ /** 自然人密码状态(后端具名类型 model.PasswordStatus):normal-正常 / must_change-必须改密。 */
8
+ export type PasswordStatus = 'normal' | 'must_change';
9
+ export interface PersonInfo {
10
+ personID: string;
11
+ name: string;
12
+ avatar: string;
13
+ }
14
+ export interface UserinfoResp {
15
+ personInfo: PersonInfo;
16
+ userInfo: {
17
+ userID: string;
18
+ tenantID: string;
19
+ name: string;
20
+ ownerType: OwnerType;
21
+ };
22
+ }
23
+ export interface MyTenantsResp {
24
+ list: {
25
+ tenantID: string;
26
+ name: string;
27
+ }[];
28
+ }
29
+ export interface PersonDetailResp {
30
+ personID: string;
31
+ username: string;
32
+ primaryEmail: string;
33
+ primaryPhone: string;
34
+ name: string;
35
+ avatar: string;
36
+ status: PersonStatus;
37
+ passwordStatus: PasswordStatus;
38
+ }
39
+ export interface PersonUpdatePasswordReq {
40
+ oldPassword: string;
41
+ newPassword: string;
42
+ }
43
+ export interface SessionResp {
44
+ id: string;
45
+ sessionID: string;
46
+ appID: string;
47
+ tenantID: string;
48
+ clientType: string;
49
+ clientIP: string;
50
+ userAgent: string;
51
+ expiresAt?: number | null;
52
+ createdAt: number;
53
+ isActive: boolean;
54
+ }
55
+ export interface SessionListResp {
56
+ list: SessionResp[];
57
+ total: number;
58
+ }
59
+ export interface SessionListReq {
60
+ page?: number;
61
+ pageSize?: number;
62
+ }
@@ -0,0 +1,52 @@
1
+ import type { UserStatus } from './tenant';
2
+ export type DeptNodeStatus = 'enable' | 'disable';
3
+ export interface DepartmentItem {
4
+ departmentID: string;
5
+ parentID: string;
6
+ deptPath: string;
7
+ deptDepth: number;
8
+ name: string;
9
+ sort: number;
10
+ status: DeptNodeStatus;
11
+ createdAt?: number;
12
+ children?: DepartmentItem[];
13
+ }
14
+ export interface DepartmentChildItem {
15
+ departmentID: string;
16
+ parentID: string;
17
+ deptDepth: number;
18
+ name: string;
19
+ sort: number;
20
+ status: DeptNodeStatus;
21
+ createdAt?: number;
22
+ updatedAt?: number;
23
+ hasChildren?: boolean;
24
+ }
25
+ export interface DepartmentUserItem {
26
+ departmentID: string;
27
+ userID: string;
28
+ userName: string;
29
+ username: string;
30
+ primaryEmail: string;
31
+ primaryPhone: string;
32
+ avatar: string;
33
+ status: UserStatus;
34
+ relationType: string;
35
+ joinedAt?: number;
36
+ }
37
+ export interface UserDepartmentItem {
38
+ departmentID: string;
39
+ departmentName: string;
40
+ relationType: string;
41
+ }
42
+ export interface DepartmentTreeResp {
43
+ list: DepartmentItem[];
44
+ }
45
+ export interface DepartmentChildrenResp {
46
+ list: DepartmentChildItem[];
47
+ total: number;
48
+ }
49
+ export interface PageListResp<T> {
50
+ list: T[];
51
+ total: number;
52
+ }
@@ -0,0 +1,5 @@
1
+ export * from './response';
2
+ export * from './auth';
3
+ export * from './department';
4
+ export * from './platform';
5
+ export * from './tenant';
@@ -0,0 +1,14 @@
1
+ var BizCode = /* @__PURE__ */ ((BizCode2) => {
2
+ BizCode2[BizCode2["Success"] = 0] = "Success";
3
+ BizCode2[BizCode2["Unauthorized"] = 11e4] = "Unauthorized";
4
+ BizCode2[BizCode2["Forbidden"] = 110001] = "Forbidden";
5
+ BizCode2[BizCode2["TokenInvalid"] = 110002] = "TokenInvalid";
6
+ BizCode2[BizCode2["TokenExpired"] = 110003] = "TokenExpired";
7
+ BizCode2[BizCode2["PermissionDenied"] = 110004] = "PermissionDenied";
8
+ BizCode2[BizCode2["ParamInvalid"] = 100104] = "ParamInvalid";
9
+ return BizCode2;
10
+ })(BizCode || {});
11
+ export {
12
+ BizCode
13
+ };
14
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sources":["../src/response.ts"],"sourcesContent":["export interface ApiResponse<T> {\n code: number\n msg: string\n data: T\n}\n\nexport enum BizCode {\n Success = 0,\n Unauthorized = 110000,\n Forbidden = 110001,\n TokenInvalid = 110002,\n TokenExpired = 110003,\n PermissionDenied = 110004,\n ParamInvalid = 100104,\n}\n"],"names":["BizCode"],"mappings":"AAMO,IAAK,4BAAAA,aAAL;AACLA,WAAAA,SAAA,aAAU,CAAA,IAAV;AACAA,WAAAA,SAAA,kBAAe,IAAA,IAAf;AACAA,WAAAA,SAAA,eAAY,MAAA,IAAZ;AACAA,WAAAA,SAAA,kBAAe,MAAA,IAAf;AACAA,WAAAA,SAAA,kBAAe,MAAA,IAAf;AACAA,WAAAA,SAAA,sBAAmB,MAAA,IAAnB;AACAA,WAAAA,SAAA,kBAAe,MAAA,IAAf;AAPU,SAAAA;AAAA,GAAA,WAAA,CAAA,CAAA;"}