access.ts 1.6 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768
  1. import { create } from "zustand";
  2. import { persist } from "zustand/middleware";
  3. import { StoreKey } from "../constant";
  4. export interface AccessControlStore {
  5. accessCode: string;
  6. token: string;
  7. needCode: boolean;
  8. updateToken: (_: string) => void;
  9. updateCode: (_: string) => void;
  10. enabledAccessControl: () => boolean;
  11. isAuthorized: () => boolean;
  12. fetch: () => void;
  13. }
  14. let fetchState = 0; // 0 not fetch, 1 fetching, 2 done
  15. export const useAccessStore = create<AccessControlStore>()(
  16. persist(
  17. (set, get) => ({
  18. token: "",
  19. accessCode: "",
  20. needCode: true,
  21. enabledAccessControl() {
  22. get().fetch();
  23. return get().needCode;
  24. },
  25. updateCode(code: string) {
  26. set((state) => ({ accessCode: code }));
  27. },
  28. updateToken(token: string) {
  29. set((state) => ({ token }));
  30. },
  31. isAuthorized() {
  32. // has token or has code or disabled access control
  33. return (
  34. !!get().token || !!get().accessCode || !get().enabledAccessControl()
  35. );
  36. },
  37. fetch() {
  38. if (fetchState > 0) return;
  39. fetchState = 1;
  40. fetch("/api/config", {
  41. method: "post",
  42. body: null,
  43. })
  44. .then((res) => res.json())
  45. .then((res: DangerConfig) => {
  46. console.log("[Config] got config from server", res);
  47. set(() => ({ ...res }));
  48. })
  49. .catch(() => {
  50. console.error("[Config] failed to fetch config");
  51. })
  52. .finally(() => {
  53. fetchState = 2;
  54. });
  55. },
  56. }),
  57. {
  58. name: StoreKey.Access,
  59. version: 1,
  60. },
  61. ),
  62. );