access.ts 2.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293
  1. import { create } from "zustand";
  2. import { persist } from "zustand/middleware";
  3. import { StoreKey } from "../constant";
  4. import { getHeaders } from "../requests";
  5. import { BOT_HELLO } from "./chat";
  6. import { ALL_MODELS } from "./config";
  7. export interface AccessControlStore {
  8. accessCode: string;
  9. token: string;
  10. needCode: boolean;
  11. hideUserApiKey: boolean;
  12. openaiUrl: string;
  13. updateToken: (_: string) => void;
  14. updateCode: (_: string) => void;
  15. enabledAccessControl: () => boolean;
  16. isAuthorized: () => boolean;
  17. fetch: () => void;
  18. }
  19. let fetchState = 0; // 0 not fetch, 1 fetching, 2 done
  20. export const useAccessStore = create<AccessControlStore>()(
  21. persist(
  22. (set, get) => ({
  23. token: "",
  24. accessCode: "",
  25. needCode: true,
  26. hideUserApiKey: false,
  27. openaiUrl: "/api/openai/",
  28. enabledAccessControl() {
  29. get().fetch();
  30. return get().needCode;
  31. },
  32. updateCode(code: string) {
  33. set(() => ({ accessCode: code }));
  34. },
  35. updateToken(token: string) {
  36. set(() => ({ token }));
  37. },
  38. isAuthorized() {
  39. get().fetch();
  40. // has token or has code or disabled access control
  41. return (
  42. !!get().token || !!get().accessCode || !get().enabledAccessControl()
  43. );
  44. },
  45. fetch() {
  46. if (fetchState > 0) return;
  47. fetchState = 1;
  48. fetch("/api/config", {
  49. method: "post",
  50. body: null,
  51. headers: {
  52. ...getHeaders(),
  53. },
  54. })
  55. .then((res) => res.json())
  56. .then((res: DangerConfig) => {
  57. console.log("[Config] got config from server", res);
  58. set(() => ({ ...res }));
  59. if (!res.enableGPT4) {
  60. ALL_MODELS.forEach((model) => {
  61. if (model.name.startsWith("gpt-4")) {
  62. (model as any).available = false;
  63. }
  64. });
  65. }
  66. if ((res as any).botHello) {
  67. BOT_HELLO.content = (res as any).botHello;
  68. }
  69. })
  70. .catch(() => {
  71. console.error("[Config] failed to fetch config");
  72. })
  73. .finally(() => {
  74. fetchState = 2;
  75. });
  76. },
  77. }),
  78. {
  79. name: StoreKey.Access,
  80. version: 1,
  81. },
  82. ),
  83. );