@tsingroc/tsingroc-components 5.0.0-alpha.18 → 5.0.0-alpha.20

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.
@@ -175,9 +175,13 @@ interface CommonAuth {
175
175
  logout(redirect?: string): void;
176
176
  /**
177
177
  * 以当前用户的 access token 作为 bearer token 发起请求。
178
- * 用法与正常的 {@linkcode fetch} 完全一致。未登录时,返回的 Promise 会立即失败。
178
+ * 用法与正常的 {@linkcode fetch} 完全一致。未登录时,返回的 Promise 会立即抛出异常。
179
+ * 如果请求返回的状态码是 401,则会自动跳转到登录页。可以使用 `options.redirectOn401`
180
+ * 选项关闭这个行为。
179
181
  */
180
- fetchWithAuth(resource: RequestInfo | URL, options?: RequestInit): Promise<Response>;
182
+ fetchWithAuth(resource: RequestInfo | URL, options?: RequestInit & {
183
+ redirectOn401?: boolean;
184
+ }): Promise<Response>;
181
185
  /** 用户的个人信息,未经过 {@linkcode AuthCheck} 验证时为空。*/
182
186
  userInfo?: UserInfo;
183
187
  /** Access Token,未登录时为空。*/
@@ -1,6 +1,7 @@
1
+ import { c as _c } from "react/compiler-runtime";
1
2
  import Sdk from "casdoor-js-sdk";
2
3
  import { jwtDecode } from "jwt-decode";
3
- import { createContext, useContext, useEffect, useMemo, useRef, useState } from "react";
4
+ import { createContext, useContext, useEffect, useEffectEvent, useMemo, useRef, useState } from "react";
4
5
  import { jsx as _jsx } from "react/jsx-runtime";
5
6
  const commonAuth = (user, setUser) => ({
6
7
  logout(redirect) {
@@ -19,10 +20,16 @@ const commonAuth = (user, setUser) => ({
19
20
  if (!headers.has("Authorization")) {
20
21
  headers.set("Authorization", `Bearer ${token}`);
21
22
  }
22
- return await fetch(resource, {
23
+ const resp = await fetch(resource, {
23
24
  ...options,
24
25
  headers
25
26
  });
27
+ if ((options?.redirectOn401 ?? true) && resp.status === 401) {
28
+ localStorage.removeItem("access_token");
29
+ setUser({});
30
+ throw new Error("登陆状态无效!");
31
+ }
32
+ return resp;
26
33
  }
27
34
  });
28
35
  function casdoorAuth(user, setUser, sdkConfig, signinOrigin, signinPath) {
@@ -209,29 +216,56 @@ export function AuthProvider(props) {
209
216
  * 该组件必须在 {@linkcode AuthProvider} 内部才能使用。
210
217
  */
211
218
  export function AuthCheck(props) {
219
+ const $ = _c(8);
212
220
  const auth = useAuth("AuthCheck");
213
221
  const userInfo = auth.userInfo;
214
- // 用于确保在 Strict Mode 下副作用也只执行一次
215
222
  const effectDone = useRef(false);
216
- useEffect(() => {
217
- if (effectDone.current) return;
218
- effectDone.current = true;
219
- if (!auth.userInfo) {
220
- auth.validate().catch(props.onFail ?? (() => {
221
- auth.login(location.href);
222
- }));
223
- }
224
- // 这个副作用只在首次渲染时执行
225
- // eslint-disable-next-line react-hooks/exhaustive-deps
226
- }, []);
223
+ let t0;
224
+ if ($[0] !== auth || $[1] !== props.onFail) {
225
+ t0 = () => {
226
+ auth.validate().catch(props.onFail ?? (() => auth.login(location.href)));
227
+ };
228
+ $[0] = auth;
229
+ $[1] = props.onFail;
230
+ $[2] = t0;
231
+ } else {
232
+ t0 = $[2];
233
+ }
234
+ const onUnloggedIn = useEffectEvent(t0);
235
+ let t1;
236
+ if ($[3] !== auth.userInfo || $[4] !== onUnloggedIn) {
237
+ t1 = () => {
238
+ if (effectDone.current) {
239
+ return;
240
+ }
241
+ effectDone.current = true;
242
+ if (!auth.userInfo) {
243
+ onUnloggedIn();
244
+ }
245
+ };
246
+ $[3] = auth.userInfo;
247
+ $[4] = onUnloggedIn;
248
+ $[5] = t1;
249
+ } else {
250
+ t1 = $[5];
251
+ }
252
+ let t2;
253
+ if ($[6] !== auth) {
254
+ t2 = [auth];
255
+ $[6] = auth;
256
+ $[7] = t2;
257
+ } else {
258
+ t2 = $[7];
259
+ }
260
+ useEffect(t1, t2);
227
261
  if (userInfo) {
228
262
  if (!("roles" in userInfo) || (props.roles ?? []).every(role => userInfo.roles.includes(role))) {
229
263
  return props.children;
230
264
  } else {
231
- return props.forbidden ?? "您无权访问此页面!";
265
+ return props.forbidden ?? "\u60A8\u65E0\u6743\u8BBF\u95EE\u6B64\u9875\u9762\uFF01";
232
266
  }
233
267
  } else {
234
- return props.loading ?? "正在登录……";
268
+ return props.loading ?? "\u6B63\u5728\u767B\u5F55\u2026\u2026";
235
269
  }
236
270
  }
237
271
  /**
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tsingroc/tsingroc-components",
3
- "version": "5.0.0-alpha.18",
3
+ "version": "5.0.0-alpha.20",
4
4
  "author": "",
5
5
  "license": "ISC",
6
6
  "description": "",