access.ts 1.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869
  1. import { create } from "zustand";
  2. import { persist } from "zustand/middleware";
  3. export interface AccessControlStore {
  4. accessCode: string;
  5. token: string;
  6. needCode: boolean;
  7. updateToken: (_: string) => void;
  8. updateCode: (_: string) => void;
  9. enabledAccessControl: () => boolean;
  10. isAuthorized: () => boolean;
  11. fetch: () => void;
  12. }
  13. export const ACCESS_KEY = "access-control";
  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: ACCESS_KEY,
  59. version: 1,
  60. },
  61. ),
  62. );