access.ts 2.6 KB

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