access.ts 2.7 KB

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