@lobehub/lobehub 2.0.0-next.195 → 2.0.0-next.196

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (35) hide show
  1. package/CHANGELOG.md +25 -0
  2. package/changelog/v1.json +9 -0
  3. package/locales/ar/setting.json +0 -3
  4. package/locales/bg-BG/setting.json +0 -3
  5. package/locales/de-DE/setting.json +0 -3
  6. package/locales/en-US/setting.json +0 -3
  7. package/locales/es-ES/setting.json +0 -3
  8. package/locales/fa-IR/setting.json +0 -3
  9. package/locales/fr-FR/setting.json +0 -3
  10. package/locales/it-IT/setting.json +0 -3
  11. package/locales/ja-JP/setting.json +0 -3
  12. package/locales/ko-KR/setting.json +0 -3
  13. package/locales/nl-NL/setting.json +0 -3
  14. package/locales/pl-PL/setting.json +0 -3
  15. package/locales/pt-BR/setting.json +0 -3
  16. package/locales/ru-RU/setting.json +0 -3
  17. package/locales/tr-TR/setting.json +0 -3
  18. package/locales/vi-VN/setting.json +0 -3
  19. package/locales/zh-CN/setting.json +0 -3
  20. package/locales/zh-TW/setting.json +0 -3
  21. package/package.json +1 -1
  22. package/packages/const/src/fetch.ts +1 -4
  23. package/packages/types/src/auth.ts +0 -4
  24. package/packages/utils/src/server/xor.test.ts +1 -2
  25. package/src/app/(backend)/_deprecated/createBizOpenAI/auth.test.ts +7 -41
  26. package/src/app/(backend)/_deprecated/createBizOpenAI/auth.ts +1 -15
  27. package/src/app/(backend)/_deprecated/createBizOpenAI/index.ts +2 -9
  28. package/src/app/(backend)/middleware/auth/index.ts +0 -1
  29. package/src/app/(backend)/middleware/auth/utils.test.ts +2 -42
  30. package/src/app/(backend)/middleware/auth/utils.ts +3 -17
  31. package/src/app/(backend)/webapi/chat/[provider]/route.test.ts +0 -5
  32. package/src/app/(backend)/webapi/models/[provider]/route.test.ts +0 -6
  33. package/src/app/(backend)/webapi/plugin/gateway/route.ts +2 -32
  34. package/src/app/[variants]/(main)/settings/common/features/Common/Common.tsx +1 -16
  35. package/src/locales/default/setting.ts +0 -3
package/CHANGELOG.md CHANGED
@@ -2,6 +2,31 @@
2
2
 
3
3
  # Changelog
4
4
 
5
+ ## [Version 2.0.0-next.196](https://github.com/lobehub/lobe-chat/compare/v2.0.0-next.195...v2.0.0-next.196)
6
+
7
+ <sup>Released on **2026-01-03**</sup>
8
+
9
+ #### ♻ Code Refactoring
10
+
11
+ - **misc**: Refactor to remove access code.
12
+
13
+ <br/>
14
+
15
+ <details>
16
+ <summary><kbd>Improvements and Fixes</kbd></summary>
17
+
18
+ #### Code refactoring
19
+
20
+ - **misc**: Refactor to remove access code, closes [#11120](https://github.com/lobehub/lobe-chat/issues/11120) ([0e9f98c](https://github.com/lobehub/lobe-chat/commit/0e9f98c))
21
+
22
+ </details>
23
+
24
+ <div align="right">
25
+
26
+ [![](https://img.shields.io/badge/-BACK_TO_TOP-151515?style=flat-square)](#readme-top)
27
+
28
+ </div>
29
+
5
30
  ## [Version 2.0.0-next.195](https://github.com/lobehub/lobe-chat/compare/v2.0.0-next.194...v2.0.0-next.195)
6
31
 
7
32
  <sup>Released on **2026-01-03**</sup>
package/changelog/v1.json CHANGED
@@ -1,4 +1,13 @@
1
1
  [
2
+ {
3
+ "children": {
4
+ "improvements": [
5
+ "Refactor to remove access code."
6
+ ]
7
+ },
8
+ "date": "2026-01-03",
9
+ "version": "2.0.0-next.196"
10
+ },
2
11
  {
3
12
  "children": {
4
13
  "fixes": [
@@ -384,9 +384,6 @@
384
384
  "settingOpening.openingQuestions.title": "الأسئلة الافتتاحية",
385
385
  "settingOpening.title": "إعدادات البداية",
386
386
  "settingPlugin.title": "قائمة المهارات",
387
- "settingSystem.accessCode.desc": "تم تفعيل الوصول المشفر من قبل المسؤول",
388
- "settingSystem.accessCode.placeholder": "أدخل كلمة مرور الوصول",
389
- "settingSystem.accessCode.title": "كلمة مرور الوصول",
390
387
  "settingSystem.oauth.info.desc": "تم تسجيل الدخول",
391
388
  "settingSystem.oauth.info.title": "معلومات الحساب",
392
389
  "settingSystem.oauth.signin.action": "تسجيل الدخول",
@@ -384,9 +384,6 @@
384
384
  "settingOpening.openingQuestions.title": "Начални въпроси",
385
385
  "settingOpening.title": "Настройки за начало",
386
386
  "settingPlugin.title": "Списък с умения",
387
- "settingSystem.accessCode.desc": "Достъпът с шифроване е активиран от администратора",
388
- "settingSystem.accessCode.placeholder": "Въведете парола за достъп",
389
- "settingSystem.accessCode.title": "Парола за достъп",
390
387
  "settingSystem.oauth.info.desc": "Вход изпълнен",
391
388
  "settingSystem.oauth.info.title": "Информация за акаунта",
392
389
  "settingSystem.oauth.signin.action": "Вход",
@@ -384,9 +384,6 @@
384
384
  "settingOpening.openingQuestions.title": "Einstiegsfragen",
385
385
  "settingOpening.title": "Begrüßungseinstellungen",
386
386
  "settingPlugin.title": "Fähigkeitenliste",
387
- "settingSystem.accessCode.desc": "Zugriff mit Verschlüsselung ist vom Administrator aktiviert",
388
- "settingSystem.accessCode.placeholder": "Zugangspasswort eingeben",
389
- "settingSystem.accessCode.title": "Zugangspasswort",
390
387
  "settingSystem.oauth.info.desc": "Angemeldet",
391
388
  "settingSystem.oauth.info.title": "Kontoinformationen",
392
389
  "settingSystem.oauth.signin.action": "Anmelden",
@@ -384,9 +384,6 @@
384
384
  "settingOpening.openingQuestions.title": "Opening Questions",
385
385
  "settingOpening.title": "Opening Settings",
386
386
  "settingPlugin.title": "Skill List",
387
- "settingSystem.accessCode.desc": "Encryption access is enabled by the administrator",
388
- "settingSystem.accessCode.placeholder": "Enter access password",
389
- "settingSystem.accessCode.title": "Access Password",
390
387
  "settingSystem.oauth.info.desc": "Logged in",
391
388
  "settingSystem.oauth.info.title": "Account Information",
392
389
  "settingSystem.oauth.signin.action": "Sign In",
@@ -384,9 +384,6 @@
384
384
  "settingOpening.openingQuestions.title": "Preguntas de Apertura",
385
385
  "settingOpening.title": "Configuración de Apertura",
386
386
  "settingPlugin.title": "Lista de Habilidades",
387
- "settingSystem.accessCode.desc": "El administrador ha habilitado el acceso cifrado",
388
- "settingSystem.accessCode.placeholder": "Introduce la contraseña de acceso",
389
- "settingSystem.accessCode.title": "Contraseña de Acceso",
390
387
  "settingSystem.oauth.info.desc": "Sesión iniciada",
391
388
  "settingSystem.oauth.info.title": "Información de la Cuenta",
392
389
  "settingSystem.oauth.signin.action": "Iniciar Sesión",
@@ -384,9 +384,6 @@
384
384
  "settingOpening.openingQuestions.title": "سؤالات آغازین",
385
385
  "settingOpening.title": "تنظیمات آغازین",
386
386
  "settingPlugin.title": "فهرست مهارت‌ها",
387
- "settingSystem.accessCode.desc": "دسترسی رمزگذاری‌شده توسط مدیر فعال شده است",
388
- "settingSystem.accessCode.placeholder": "رمز عبور دسترسی را وارد کنید",
389
- "settingSystem.accessCode.title": "رمز عبور دسترسی",
390
387
  "settingSystem.oauth.info.desc": "وارد شده‌اید",
391
388
  "settingSystem.oauth.info.title": "اطلاعات حساب",
392
389
  "settingSystem.oauth.signin.action": "ورود",
@@ -384,9 +384,6 @@
384
384
  "settingOpening.openingQuestions.title": "Questions d’accueil",
385
385
  "settingOpening.title": "Paramètres d’accueil",
386
386
  "settingPlugin.title": "Liste des compétences",
387
- "settingSystem.accessCode.desc": "L’accès chiffré est activé par l’administrateur",
388
- "settingSystem.accessCode.placeholder": "Saisir le mot de passe d’accès",
389
- "settingSystem.accessCode.title": "Mot de passe d’accès",
390
387
  "settingSystem.oauth.info.desc": "Connecté",
391
388
  "settingSystem.oauth.info.title": "Informations du compte",
392
389
  "settingSystem.oauth.signin.action": "Se connecter",
@@ -384,9 +384,6 @@
384
384
  "settingOpening.openingQuestions.title": "Domande di Apertura",
385
385
  "settingOpening.title": "Impostazioni di Apertura",
386
386
  "settingPlugin.title": "Elenco Competenze",
387
- "settingSystem.accessCode.desc": "L'accesso crittografato è abilitato dall'amministratore",
388
- "settingSystem.accessCode.placeholder": "Inserisci la password di accesso",
389
- "settingSystem.accessCode.title": "Password di Accesso",
390
387
  "settingSystem.oauth.info.desc": "Accesso effettuato",
391
388
  "settingSystem.oauth.info.title": "Informazioni Account",
392
389
  "settingSystem.oauth.signin.action": "Accedi",
@@ -384,9 +384,6 @@
384
384
  "settingOpening.openingQuestions.title": "オープニング質問",
385
385
  "settingOpening.title": "オープニング設定",
386
386
  "settingPlugin.title": "スキルリスト",
387
- "settingSystem.accessCode.desc": "管理者が暗号化アクセスを有効にしています",
388
- "settingSystem.accessCode.placeholder": "アクセスコードを入力してください",
389
- "settingSystem.accessCode.title": "アクセスコード",
390
387
  "settingSystem.oauth.info.desc": "ログイン済み",
391
388
  "settingSystem.oauth.info.title": "アカウント情報",
392
389
  "settingSystem.oauth.signin.action": "ログイン",
@@ -384,9 +384,6 @@
384
384
  "settingOpening.openingQuestions.title": "오프닝 질문",
385
385
  "settingOpening.title": "오프닝 설정",
386
386
  "settingPlugin.title": "기능 목록",
387
- "settingSystem.accessCode.desc": "관리자가 암호화된 액세스를 활성화했습니다",
388
- "settingSystem.accessCode.placeholder": "액세스 암호를 입력하세요",
389
- "settingSystem.accessCode.title": "액세스 암호",
390
387
  "settingSystem.oauth.info.desc": "로그인됨",
391
388
  "settingSystem.oauth.info.title": "계정 정보",
392
389
  "settingSystem.oauth.signin.action": "로그인",
@@ -384,9 +384,6 @@
384
384
  "settingOpening.openingQuestions.title": "Openingsvragen",
385
385
  "settingOpening.title": "Openingsinstellingen",
386
386
  "settingPlugin.title": "Vaardighedenlijst",
387
- "settingSystem.accessCode.desc": "Versleutelde toegang is ingeschakeld door de beheerder",
388
- "settingSystem.accessCode.placeholder": "Voer toegangswachtwoord in",
389
- "settingSystem.accessCode.title": "Toegangswachtwoord",
390
387
  "settingSystem.oauth.info.desc": "Ingelogd",
391
388
  "settingSystem.oauth.info.title": "Accountinformatie",
392
389
  "settingSystem.oauth.signin.action": "Inloggen",
@@ -384,9 +384,6 @@
384
384
  "settingOpening.openingQuestions.title": "Pytania wprowadzające",
385
385
  "settingOpening.title": "Ustawienia powitania",
386
386
  "settingPlugin.title": "Lista umiejętności",
387
- "settingSystem.accessCode.desc": "Dostęp szyfrowany został włączony przez administratora",
388
- "settingSystem.accessCode.placeholder": "Wprowadź hasło dostępu",
389
- "settingSystem.accessCode.title": "Hasło dostępu",
390
387
  "settingSystem.oauth.info.desc": "Zalogowano",
391
388
  "settingSystem.oauth.info.title": "Informacje o koncie",
392
389
  "settingSystem.oauth.signin.action": "Zaloguj się",
@@ -384,9 +384,6 @@
384
384
  "settingOpening.openingQuestions.title": "Perguntas de Abertura",
385
385
  "settingOpening.title": "Configurações de Abertura",
386
386
  "settingPlugin.title": "Lista de Habilidades",
387
- "settingSystem.accessCode.desc": "O acesso criptografado foi ativado pelo administrador",
388
- "settingSystem.accessCode.placeholder": "Digite a senha de acesso",
389
- "settingSystem.accessCode.title": "Senha de Acesso",
390
387
  "settingSystem.oauth.info.desc": "Conectado",
391
388
  "settingSystem.oauth.info.title": "Informações da Conta",
392
389
  "settingSystem.oauth.signin.action": "Entrar",
@@ -384,9 +384,6 @@
384
384
  "settingOpening.openingQuestions.title": "Вводные вопросы",
385
385
  "settingOpening.title": "Настройки приветствия",
386
386
  "settingPlugin.title": "Список навыков",
387
- "settingSystem.accessCode.desc": "Доступ по паролю включён администратором",
388
- "settingSystem.accessCode.placeholder": "Введите пароль доступа",
389
- "settingSystem.accessCode.title": "Пароль доступа",
390
387
  "settingSystem.oauth.info.desc": "Вы вошли в систему",
391
388
  "settingSystem.oauth.info.title": "Информация об аккаунте",
392
389
  "settingSystem.oauth.signin.action": "Войти",
@@ -384,9 +384,6 @@
384
384
  "settingOpening.openingQuestions.title": "Açılış Soruları",
385
385
  "settingOpening.title": "Açılış Ayarları",
386
386
  "settingPlugin.title": "Yetenek Listesi",
387
- "settingSystem.accessCode.desc": "Şifreli erişim, yönetici tarafından etkinleştirilmiştir",
388
- "settingSystem.accessCode.placeholder": "Erişim şifresini girin",
389
- "settingSystem.accessCode.title": "Erişim Şifresi",
390
387
  "settingSystem.oauth.info.desc": "Giriş yapıldı",
391
388
  "settingSystem.oauth.info.title": "Hesap Bilgileri",
392
389
  "settingSystem.oauth.signin.action": "Giriş Yap",
@@ -384,9 +384,6 @@
384
384
  "settingOpening.openingQuestions.title": "Câu Hỏi Mở Đầu",
385
385
  "settingOpening.title": "Cài Đặt Mở Đầu",
386
386
  "settingPlugin.title": "Danh Sách Kỹ Năng",
387
- "settingSystem.accessCode.desc": "Mã truy cập được mã hóa do quản trị viên bật",
388
- "settingSystem.accessCode.placeholder": "Nhập mật khẩu truy cập",
389
- "settingSystem.accessCode.title": "Mật Khẩu Truy Cập",
390
387
  "settingSystem.oauth.info.desc": "Đã đăng nhập",
391
388
  "settingSystem.oauth.info.title": "Thông Tin Tài Khoản",
392
389
  "settingSystem.oauth.signin.action": "Đăng Nhập",
@@ -384,9 +384,6 @@
384
384
  "settingOpening.openingQuestions.title": "开场问题",
385
385
  "settingOpening.title": "开场设置",
386
386
  "settingPlugin.title": "技能列表",
387
- "settingSystem.accessCode.desc": "管理员已开启加密访问",
388
- "settingSystem.accessCode.placeholder": "请输入访问密码",
389
- "settingSystem.accessCode.title": "访问密码",
390
387
  "settingSystem.oauth.info.desc": "已登录",
391
388
  "settingSystem.oauth.info.title": "账户信息",
392
389
  "settingSystem.oauth.signin.action": "登录",
@@ -384,9 +384,6 @@
384
384
  "settingOpening.openingQuestions.title": "開場問題",
385
385
  "settingOpening.title": "開場設定",
386
386
  "settingPlugin.title": "插件列表",
387
- "settingSystem.accessCode.desc": "管理員已開啟加密訪問",
388
- "settingSystem.accessCode.placeholder": "請輸入訪問密碼",
389
- "settingSystem.accessCode.title": "訪問密碼",
390
387
  "settingSystem.oauth.info.desc": "已登錄",
391
388
  "settingSystem.oauth.info.title": "帳戶資訊",
392
389
  "settingSystem.oauth.signin.action": "登錄",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lobehub/lobehub",
3
- "version": "2.0.0-next.195",
3
+ "version": "2.0.0-next.196",
4
4
  "description": "LobeHub - an open-source,comprehensive AI Agent framework that supports speech synthesis, multimodal, and extensible Function Call plugin system. Supports one-click free deployment of your private ChatGPT/LLM web application.",
5
5
  "keywords": [
6
6
  "framework",
@@ -6,8 +6,6 @@ export const USE_AZURE_OPENAI = 'X-use-azure-openai';
6
6
 
7
7
  export const AZURE_OPENAI_API_VERSION = 'X-azure-openai-api-version';
8
8
 
9
- export const LOBE_CHAT_ACCESS_CODE = 'X-lobe-chat-access-code';
10
-
11
9
  export const OAUTH_AUTHORIZED = 'X-oauth-authorized';
12
10
 
13
11
  /**
@@ -16,7 +14,6 @@ export const OAUTH_AUTHORIZED = 'X-oauth-authorized';
16
14
  export const getOpenAIAuthFromRequest = (req: Request) => {
17
15
  const apiKey = req.headers.get(OPENAI_API_KEY_HEADER_KEY);
18
16
  const endpoint = req.headers.get(OPENAI_END_POINT);
19
- const accessCode = req.headers.get(LOBE_CHAT_ACCESS_CODE);
20
17
  const useAzureStr = req.headers.get(USE_AZURE_OPENAI);
21
18
  const apiVersion = req.headers.get(AZURE_OPENAI_API_VERSION);
22
19
  const oauthAuthorizedStr = req.headers.get(OAUTH_AUTHORIZED);
@@ -25,5 +22,5 @@ export const getOpenAIAuthFromRequest = (req: Request) => {
25
22
  const oauthAuthorized = !!oauthAuthorizedStr;
26
23
  const useAzure = !!useAzureStr;
27
24
 
28
- return { accessCode, apiKey, apiVersion, endpoint, oauthAuthorized, useAzure, userId };
25
+ return { apiKey, apiVersion, endpoint, oauthAuthorized, useAzure, userId };
29
26
  };
@@ -1,9 +1,5 @@
1
1
  /* eslint-disable typescript-sort-keys/interface */
2
2
  export interface ClientSecretPayload {
3
- /**
4
- * password
5
- */
6
- accessCode?: string;
7
3
  /**
8
4
  * Represents the user's API key
9
5
  *
@@ -7,7 +7,6 @@ describe('getXorPayload', () => {
7
7
  it('should correctly decode XOR obfuscated payload with user data', () => {
8
8
  const originalPayload = {
9
9
  userId: '001362c3-48c5-4635-bd3b-837bfff58fc0',
10
- accessCode: 'test-access-code',
11
10
  apiKey: 'test-api-key',
12
11
  baseURL: 'https://api.example.com',
13
12
  };
@@ -86,7 +85,7 @@ describe('getXorPayload', () => {
86
85
  it('should handle payload with undefined values', () => {
87
86
  const originalPayload = {
88
87
  userId: 'test-user',
89
- accessCode: undefined,
88
+ baseURL: undefined,
90
89
  apiKey: 'test-key',
91
90
  };
92
91
 
@@ -1,53 +1,19 @@
1
1
  // @vitest-environment node
2
2
  import { checkAuth } from './auth';
3
3
 
4
- describe('ACCESS_CODE', () => {
5
- let auth = false;
6
-
7
- beforeEach(() => {
8
- auth = false;
9
- process.env.ACCESS_CODE = undefined;
10
- // Reset environment variables before each test case
11
- vi.restoreAllMocks();
12
- });
13
-
14
- it('set multiple access codes', () => {
15
- process.env.ACCESS_CODE = ',code1,code2,code3';
16
- ({ auth } = checkAuth({ accessCode: 'code1' }));
17
- expect(auth).toBe(true);
18
- ({ auth } = checkAuth({ accessCode: 'code2' }));
19
- expect(auth).toBe(true);
20
- ({ auth } = checkAuth({ accessCode: 'code1,code2' }));
21
- expect(auth).toBe(false);
22
- });
23
-
24
- it('set individual access code', () => {
25
- process.env.ACCESS_CODE = 'code1';
26
- ({ auth } = checkAuth({ accessCode: 'code1' }));
4
+ describe('checkAuth', () => {
5
+ it('should pass with oauth authorized', () => {
6
+ const { auth } = checkAuth({ oauthAuthorized: true });
27
7
  expect(auth).toBe(true);
28
- ({ auth } = checkAuth({ accessCode: 'code2' }));
29
- expect(auth).toBe(false);
30
8
  });
31
9
 
32
- it('no access code', () => {
33
- delete process.env.ACCESS_CODE;
34
- ({ auth } = checkAuth({ accessCode: 'code1' }));
35
- expect(auth).toBe(true);
36
- ({ auth } = checkAuth({}));
10
+ it('should pass with api key', () => {
11
+ const { auth } = checkAuth({ apiKey: 'test-api-key' });
37
12
  expect(auth).toBe(true);
38
13
  });
39
14
 
40
- it('empty access code', () => {
41
- process.env.ACCESS_CODE = '';
42
- ({ auth } = checkAuth({ accessCode: 'code1' }));
43
- expect(auth).toBe(true);
44
- ({ auth } = checkAuth({}));
45
- expect(auth).toBe(true);
46
-
47
- process.env.ACCESS_CODE = ',,';
48
- ({ auth } = checkAuth({ accessCode: 'code1' }));
49
- expect(auth).toBe(true);
50
- ({ auth } = checkAuth({}));
15
+ it('should pass with no params', () => {
16
+ const { auth } = checkAuth({});
51
17
  expect(auth).toBe(true);
52
18
  });
53
19
  });
@@ -1,32 +1,18 @@
1
- import { ChatErrorType } from '@lobechat/types';
2
-
3
- import { getAppConfig } from '@/envs/app';
4
-
5
1
  interface AuthConfig {
6
- accessCode?: string | null;
7
2
  apiKey?: string | null;
8
3
  oauthAuthorized?: boolean;
9
4
  }
10
5
 
11
- export const checkAuth = ({ apiKey, accessCode, oauthAuthorized }: AuthConfig) => {
6
+ export const checkAuth = ({ apiKey, oauthAuthorized }: AuthConfig) => {
12
7
  // If authorized by oauth
13
8
  if (oauthAuthorized) {
14
9
  return { auth: true };
15
10
  }
16
11
 
17
- const { ACCESS_CODES } = getAppConfig();
18
-
19
12
  // if apiKey exist
20
13
  if (apiKey) {
21
14
  return { auth: true };
22
15
  }
23
16
 
24
- // if accessCode doesn't exist
25
- if (!ACCESS_CODES.length) return { auth: true };
26
-
27
- if (!accessCode || !ACCESS_CODES.includes(accessCode)) {
28
- return { auth: false, error: ChatErrorType.InvalidAccessCode };
29
- }
30
-
31
17
  return { auth: true };
32
18
  };
@@ -1,10 +1,9 @@
1
- import { ChatErrorType, type ErrorType } from '@lobechat/types';
1
+ import { ChatErrorType } from '@lobechat/types';
2
2
  import type OpenAI from 'openai';
3
3
 
4
4
  import { getOpenAIAuthFromRequest } from '@/const/fetch';
5
5
  import { createErrorResponse } from '@/utils/errorResponse';
6
6
 
7
- import { checkAuth } from './auth';
8
7
  import { createOpenai } from './createOpenai';
9
8
 
10
9
  /**
@@ -13,13 +12,7 @@ import { createOpenai } from './createOpenai';
13
12
  * if auth not pass ,just return error response
14
13
  */
15
14
  export const createBizOpenAI = (req: Request): Response | OpenAI => {
16
- const { apiKey, accessCode, endpoint, oauthAuthorized } = getOpenAIAuthFromRequest(req);
17
-
18
- const result = checkAuth({ accessCode, apiKey, oauthAuthorized });
19
-
20
- if (!result.auth) {
21
- return createErrorResponse(result.error as ErrorType);
22
- }
15
+ const { apiKey, endpoint } = getOpenAIAuthFromRequest(req);
23
16
 
24
17
  let openai: OpenAI;
25
18
 
@@ -92,7 +92,6 @@ export const checkAuth =
92
92
 
93
93
  if (!isUseOidcAuth)
94
94
  checkAuthMethod({
95
- accessCode: jwtPayload.accessCode,
96
95
  apiKey: jwtPayload.apiKey,
97
96
  betterAuthAuthorized,
98
97
  clerkAuth,
@@ -1,8 +1,6 @@
1
1
  import { type AuthObject } from '@clerk/backend';
2
2
  import { beforeEach, describe, expect, it, vi } from 'vitest';
3
3
 
4
- import { getAppConfig } from '@/envs/app';
5
-
6
4
  import { checkAuthMethod } from './utils';
7
5
 
8
6
  let enableClerkMock = false;
@@ -26,15 +24,9 @@ vi.mock('@/const/auth', async (importOriginal) => {
26
24
  };
27
25
  });
28
26
 
29
- vi.mock('@/envs/app', () => ({
30
- getAppConfig: vi.fn(),
31
- }));
32
-
33
27
  describe('checkAuthMethod', () => {
34
28
  beforeEach(() => {
35
- vi.mocked(getAppConfig).mockReturnValue({
36
- ACCESS_CODES: ['validAccessCode'],
37
- } as any);
29
+ vi.clearAllMocks();
38
30
  });
39
31
 
40
32
  it('should pass with valid Clerk auth', () => {
@@ -91,39 +83,7 @@ describe('checkAuthMethod', () => {
91
83
  ).not.toThrow();
92
84
  });
93
85
 
94
- it('should pass with no access code required', () => {
95
- vi.mocked(getAppConfig).mockReturnValueOnce({
96
- ACCESS_CODES: [],
97
- } as any);
98
-
86
+ it('should pass with no auth params', () => {
99
87
  expect(() => checkAuthMethod({})).not.toThrow();
100
88
  });
101
-
102
- it('should pass with valid access code', () => {
103
- expect(() =>
104
- checkAuthMethod({
105
- accessCode: 'validAccessCode',
106
- }),
107
- ).not.toThrow();
108
- });
109
-
110
- it('should throw error with invalid access code', () => {
111
- try {
112
- checkAuthMethod({
113
- accessCode: 'invalidAccessCode',
114
- });
115
- } catch (e) {
116
- expect(e).toEqual({
117
- errorType: 'InvalidAccessCode',
118
- });
119
- }
120
-
121
- try {
122
- checkAuthMethod({});
123
- } catch (e) {
124
- expect(e).toEqual({
125
- errorType: 'InvalidAccessCode',
126
- });
127
- }
128
- });
129
89
  });
@@ -3,28 +3,25 @@ import { AgentRuntimeError } from '@lobechat/model-runtime';
3
3
  import { ChatErrorType } from '@lobechat/types';
4
4
 
5
5
  import { enableBetterAuth, enableClerk, enableNextAuth } from '@/const/auth';
6
- import { getAppConfig } from '@/envs/app';
7
6
 
8
7
  interface CheckAuthParams {
9
- accessCode?: string;
10
8
  apiKey?: string;
11
9
  betterAuthAuthorized?: boolean;
12
10
  clerkAuth?: AuthObject;
13
11
  nextAuthAuthorized?: boolean;
14
12
  }
15
13
  /**
16
- * Check if the provided access code is valid, a user API key should be used or the OAuth 2 header is provided.
14
+ * Check if authentication is valid based on various auth methods.
17
15
  *
18
16
  * @param {CheckAuthParams} params - Authentication parameters extracted from headers.
19
- * @param {string} [params.accessCode] - The access code to check.
20
17
  * @param {string} [params.apiKey] - The user API key.
21
18
  * @param {boolean} [params.betterAuthAuthorized] - Whether the Better Auth session exists.
22
19
  * @param {AuthObject} [params.clerkAuth] - Clerk authentication payload from middleware.
23
20
  * @param {boolean} [params.nextAuthAuthorized] - Whether the OAuth 2 header is provided.
24
- * @throws {AgentRuntimeError} If the access code is invalid and no user API key is provided.
21
+ * @throws {AgentRuntimeError} If authentication fails.
25
22
  */
26
23
  export const checkAuthMethod = (params: CheckAuthParams) => {
27
- const { apiKey, betterAuthAuthorized, nextAuthAuthorized, accessCode, clerkAuth } = params;
24
+ const { apiKey, betterAuthAuthorized, nextAuthAuthorized, clerkAuth } = params;
28
25
  // clerk auth handler
29
26
  if (enableClerk) {
30
27
  // if there is no userId, means the use is not login, just throw error
@@ -42,15 +39,4 @@ export const checkAuthMethod = (params: CheckAuthParams) => {
42
39
 
43
40
  // if apiKey exist
44
41
  if (apiKey) return;
45
-
46
- const { ACCESS_CODES } = getAppConfig();
47
-
48
- // if accessCode doesn't exist
49
- if (!ACCESS_CODES.length) return;
50
-
51
- if (!accessCode || !ACCESS_CODES.includes(accessCode)) {
52
- // Avoid logging user-provided credentials (access code) for security reasons
53
- console.warn('Invalid access code provided');
54
- throw AgentRuntimeError.createError(ChatErrorType.InvalidAccessCode);
55
- }
56
42
  };
@@ -62,7 +62,6 @@ describe('POST handler', () => {
62
62
 
63
63
  // 设置 getJWTPayload 和 initModelRuntimeWithUserPayload 的模拟返回值
64
64
  vi.mocked(getXorPayload).mockReturnValueOnce({
65
- accessCode: 'test-access-code',
66
65
  apiKey: 'test-api-key',
67
66
  azureApiVersion: 'v1',
68
67
  });
@@ -105,7 +104,6 @@ describe('POST handler', () => {
105
104
  mockState.enableClerk = true;
106
105
 
107
106
  vi.mocked(getXorPayload).mockReturnValueOnce({
108
- accessCode: 'test-access-code',
109
107
  apiKey: 'test-api-key',
110
108
  azureApiVersion: 'v1',
111
109
  });
@@ -133,7 +131,6 @@ describe('POST handler', () => {
133
131
  await POST(request, { params: mockParams });
134
132
 
135
133
  expect(checkAuthMethod).toBeCalledWith({
136
- accessCode: 'test-access-code',
137
134
  apiKey: 'test-api-key',
138
135
  betterAuthAuthorized: false,
139
136
  clerkAuth: {},
@@ -163,7 +160,6 @@ describe('POST handler', () => {
163
160
  describe('chat', () => {
164
161
  it('should correctly handle chat completion with valid payload', async () => {
165
162
  vi.mocked(getXorPayload).mockReturnValueOnce({
166
- accessCode: 'test-access-code',
167
163
  apiKey: 'test-api-key',
168
164
  azureApiVersion: 'v1',
169
165
  userId: 'abc',
@@ -193,7 +189,6 @@ describe('POST handler', () => {
193
189
  it('should return an error response when chat completion fails', async () => {
194
190
  // 设置 getJWTPayload 和 initAgentRuntimeWithUserPayload 的模拟返回值
195
191
  vi.mocked(getXorPayload).mockReturnValueOnce({
196
- accessCode: 'test-access-code',
197
192
  apiKey: 'test-api-key',
198
193
  azureApiVersion: 'v1',
199
194
  });
@@ -41,7 +41,6 @@ describe('GET handler', () => {
41
41
  const mockParams = Promise.resolve({ provider: 'google' });
42
42
 
43
43
  vi.mocked(getXorPayload).mockReturnValueOnce({
44
- accessCode: 'test-access-code',
45
44
  apiKey: 'test-api-key',
46
45
  });
47
46
 
@@ -73,7 +72,6 @@ describe('GET handler', () => {
73
72
  const mockParams = Promise.resolve({ provider: 'google' });
74
73
 
75
74
  vi.mocked(getXorPayload).mockReturnValueOnce({
76
- accessCode: 'test-access-code',
77
75
  apiKey: 'test-api-key',
78
76
  });
79
77
 
@@ -103,7 +101,6 @@ describe('GET handler', () => {
103
101
  const mockParams = Promise.resolve({ provider: 'google' });
104
102
 
105
103
  vi.mocked(getXorPayload).mockReturnValueOnce({
106
- accessCode: 'test-access-code',
107
104
  apiKey: 'test-api-key',
108
105
  });
109
106
 
@@ -128,7 +125,6 @@ describe('GET handler', () => {
128
125
  const mockParams = Promise.resolve({ provider: 'google' });
129
126
 
130
127
  vi.mocked(getXorPayload).mockReturnValueOnce({
131
- accessCode: 'test-access-code',
132
128
  apiKey: 'test-api-key',
133
129
  });
134
130
 
@@ -145,7 +141,6 @@ describe('GET handler', () => {
145
141
  const mockParams = Promise.resolve({ provider: 'openai' });
146
142
 
147
143
  vi.mocked(getXorPayload).mockReturnValueOnce({
148
- accessCode: 'test-access-code',
149
144
  apiKey: 'test-api-key',
150
145
  });
151
146
 
@@ -165,7 +160,6 @@ describe('GET handler', () => {
165
160
  const mockParams = Promise.resolve({ provider: 'openai' });
166
161
 
167
162
  vi.mocked(getXorPayload).mockReturnValueOnce({
168
- accessCode: 'test-access-code',
169
163
  apiKey: 'test-api-key',
170
164
  });
171
165
 
@@ -1,36 +1,15 @@
1
1
  import { AgentRuntimeError } from '@lobechat/model-runtime';
2
- import { ChatErrorType, type ErrorType, TraceNameMap } from '@lobechat/types';
3
- import { getXorPayload } from '@lobechat/utils/server';
2
+ import { ChatErrorType, TraceNameMap } from '@lobechat/types';
4
3
  import type { PluginRequestPayload } from '@lobehub/chat-plugin-sdk';
5
4
  import { createGatewayOnEdgeRuntime } from '@lobehub/chat-plugins-gateway';
6
5
 
7
- import { LOBE_CHAT_AUTH_HEADER, OAUTH_AUTHORIZED, enableNextAuth } from '@/const/auth';
6
+ import { LOBE_CHAT_AUTH_HEADER } from '@/const/auth';
8
7
  import { LOBE_CHAT_TRACE_ID } from '@/const/trace';
9
8
  import { getAppConfig } from '@/envs/app';
10
9
  import { TraceClient } from '@/libs/traces';
11
10
  import { parserPluginSettings } from '@/server/services/pluginGateway/settings';
12
- import { createErrorResponse } from '@/utils/errorResponse';
13
11
  import { getTracePayload } from '@/utils/trace';
14
12
 
15
- const checkAuth = (accessCode: string | null, oauthAuthorized: boolean | null) => {
16
- const { ACCESS_CODES, PLUGIN_SETTINGS } = getAppConfig();
17
-
18
- // if there is no plugin settings, just skip the auth
19
- if (!PLUGIN_SETTINGS) return { auth: true };
20
-
21
- // If authorized by oauth
22
- if (oauthAuthorized && enableNextAuth) return { auth: true };
23
-
24
- // if accessCode doesn't exist
25
- if (!ACCESS_CODES.length) return { auth: true };
26
-
27
- if (!accessCode || !ACCESS_CODES.includes(accessCode)) {
28
- return { auth: false, error: ChatErrorType.InvalidAccessCode };
29
- }
30
-
31
- return { auth: true };
32
- };
33
-
34
13
  const { PLUGINS_INDEX_URL: pluginsIndexUrl, PLUGIN_SETTINGS } = getAppConfig();
35
14
 
36
15
  const defaultPluginSettings = parserPluginSettings(PLUGIN_SETTINGS);
@@ -42,15 +21,6 @@ export const POST = async (req: Request) => {
42
21
  const authorization = req.headers.get(LOBE_CHAT_AUTH_HEADER);
43
22
  if (!authorization) throw AgentRuntimeError.createError(ChatErrorType.Unauthorized);
44
23
 
45
- const oauthAuthorized = !!req.headers.get(OAUTH_AUTHORIZED);
46
- const payload = getXorPayload(authorization);
47
-
48
- const result = checkAuth(payload.accessCode!, oauthAuthorized);
49
-
50
- if (!result.auth) {
51
- return createErrorResponse(result.error as ErrorType);
52
- }
53
-
54
24
  // TODO: need to be replace by better telemetry system
55
25
  // add trace
56
26
  const tracePayload = getTracePayload(req);
@@ -1,6 +1,6 @@
1
1
  'use client';
2
2
 
3
- import { Form, type FormGroupItemType, Icon, ImageSelect, InputPassword } from '@lobehub/ui';
3
+ import { Form, type FormGroupItemType, Icon, ImageSelect } from '@lobehub/ui';
4
4
  import { Select, Skeleton } from '@lobehub/ui';
5
5
  import { Segmented, Switch } from 'antd';
6
6
  import isEqual from 'fast-deep-equal';
@@ -14,8 +14,6 @@ import { isDesktop } from '@/const/version';
14
14
  import { localeOptions } from '@/locales/resources';
15
15
  import { useGlobalStore } from '@/store/global';
16
16
  import { systemStatusSelectors } from '@/store/global/selectors';
17
- import { useServerConfigStore } from '@/store/serverConfig';
18
- import { serverConfigSelectors } from '@/store/serverConfig/selectors';
19
17
  import { useUserStore } from '@/store/user';
20
18
  import { settingsSelectors } from '@/store/user/selectors';
21
19
  import { type LocaleMode } from '@/types/locale';
@@ -23,7 +21,6 @@ import { type LocaleMode } from '@/types/locale';
23
21
  const Common = memo(() => {
24
22
  const { t } = useTranslation('setting');
25
23
 
26
- const showAccessCodeConfig = useServerConfigStore(serverConfigSelectors.enabledAccessCode);
27
24
  const general = useUserStore((s) => settingsSelectors.currentSettings(s).general, isEqual);
28
25
  const themeMode = useGlobalStore(systemStatusSelectors.themeMode);
29
26
  const language = useGlobalStore(systemStatusSelectors.language);
@@ -137,18 +134,6 @@ const Common = memo(() => {
137
134
  name: 'contextMenuMode',
138
135
  },
139
136
 
140
- {
141
- children: (
142
- <InputPassword
143
- autoComplete={'new-password'}
144
- placeholder={t('settingSystem.accessCode.placeholder')}
145
- />
146
- ),
147
- desc: t('settingSystem.accessCode.desc'),
148
- hidden: !showAccessCodeConfig,
149
- label: t('settingSystem.accessCode.title'),
150
- name: 'password',
151
- },
152
137
  {
153
138
  children: (
154
139
  <Select
@@ -442,9 +442,6 @@ export default {
442
442
  'settingOpening.openingQuestions.title': 'Opening Questions',
443
443
  'settingOpening.title': 'Opening Settings',
444
444
  'settingPlugin.title': 'Skill List',
445
- 'settingSystem.accessCode.desc': 'Encryption access is enabled by the administrator',
446
- 'settingSystem.accessCode.placeholder': 'Enter access password',
447
- 'settingSystem.accessCode.title': 'Access Password',
448
445
  'settingSystem.oauth.info.desc': 'Logged in',
449
446
  'settingSystem.oauth.info.title': 'Account Information',
450
447
  'settingSystem.oauth.signin.action': 'Sign In',