Skip to content

Commit

Permalink
✨ feat: supports setting multiple access code (#647)
Browse files Browse the repository at this point in the history
* ✨ feat: `ACCESS_CODE` supports setting multiple

* 📝 docs: Update the `ACCESS_CODE` documentation

* ✅ test: Add `ACCESS_CODE` testing
  • Loading branch information
mushan0x0 committed Dec 16, 2023
1 parent 31d3994 commit 7db0430
Show file tree
Hide file tree
Showing 8 changed files with 75 additions and 24 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -395,7 +395,7 @@ This project provides some additional configuration items set with environment v
| `OPENAI_API_KEY` | Yes | This is the API key you apply on the OpenAI account page | `sk-xxxxxx...xxxxxx` |
| `OPENAI_PROXY_URL` | No | If you manually configure the OpenAI interface proxy, you can use this configuration item to override the default OpenAI API request base URL | `https://api.chatanywhere.cn/v1`<br/>The default value is<br/>`https://api.openai.com/v1` |
| `OPENAI_FUNCTION_REGIONS` | No | When you deploy Lobe-Chat using Vercel and need to specify the region for the Edge Function that handles requests to the OpenAI API, you can use this configuration. The value should be a comma-separated array of strings. | `iad1,sfo1` |
| `ACCESS_CODE` | No | Add a password to access this service; you can set a long password to avoid leaking | `awCTe)re_r74` or `rtrt_ewee3@09!` |
| `ACCESS_CODE` | No | Add a password to access this service; you can set a long password to avoid leaking. If this value contains a comma, it is a password array. | `awCTe)re_r74` or `rtrt_ewee3@09!` or `code1,code2,code3` |

> \[!NOTE]
>
Expand Down
2 changes: 1 addition & 1 deletion README.zh-CN.md
Original file line number Diff line number Diff line change
Expand Up @@ -367,7 +367,7 @@ $ docker run -d -p 3210:3210 \
| `OPENAI_API_KEY` | 必选 | 这是你在 OpenAI 账户页面申请的 API 密钥 | `sk-xxxxxx...xxxxxx` |
| `OPENAI_PROXY_URL` | 可选 | 如果你手动配置了 OpenAI 接口代理,可以使用此配置项来覆盖默认的 OpenAI API 请求基础 URL | `https://api.chatanywhere.cn/v1`<br/>默认值:<br/>`https://api.openai.com/v1` |
| `OPENAI_FUNCTION_REGIONS` | 可选 | 当你使用 Vercel 部署 Lobe-Chat,而且有需求指定响应调用 OpenAI 接口的请求的 Edge Function 的 Region 时,可以使用该配置进行配置,该值的类型为逗号分隔的字符串数组 | `iad1,sfo1` |
| `ACCESS_CODE` | 可选 | 添加访问此服务的密码,你可以设置一个长密码以防被爆破 | `awCTe)re_r74` or `rtrt_ewee3@09!` |
| `ACCESS_CODE` | 可选 | 添加访问此服务的密码,你可以设置一个长密码以防被爆破,该值用逗号分隔时为密码数组 | `awCTe)re_r74` or `rtrt_ewee3@09!` or `code1,code2,code3` |

> \[!NOTE]
>
Expand Down
14 changes: 7 additions & 7 deletions docs/Deployment/Deploy-with-Azure-OpenAI.md
Original file line number Diff line number Diff line change
Expand Up @@ -37,13 +37,13 @@ After completing the above field configuration, click on "Check". If the prompt

If you want the deployed version to be directly configured with Azure OpenAI for end users to use immediately, you need to configure the following environment variables at deployment:

| Environment Variable | Required | Description | Default Value | Example |
| -------------------- | -------- | --------------------------------------------------------------------------------- | ------------------ | -------------------------------------------------------------- |
| `USE_AZURE_OPENAI` | Yes | Set this value to `1` to enable Azure OpenAI configuration | - | `1` |
| `AZURE_API_KEY` | Yes | This is the API key you applied for on the Azure OpenAI account page | - | `c55168be3874490ef0565d9779ecd5a6` |
| `OPENAI_PROXY_URL` | Yes | Azure API address, can be found in the "Keys and Endpoints" section | - | `https://docs-test-001.openai.azure.com` |
| `AZURE_API_VERSION` | No | Azure's API version, follows the YYYY-MM-DD format | 2023-08-01-preview | `2023-05-15`, refer to [latest version][azure-api-version-url] |
| `ACCESS_CODE` | No | Add a password to access this service, the password should be 6 digits or letters | - | `awCT74` or `e3@09!` |
| Environment Variable | Required | Description | Default Value | Example |
| -------------------- | -------- | -------------------------------------------------------------------------------------------------------------------------------------------- | ------------------ | -------------------------------------------------------------- |
| `USE_AZURE_OPENAI` | Yes | Set this value to `1` to enable Azure OpenAI configuration | - | `1` |
| `AZURE_API_KEY` | Yes | This is the API key you applied for on the Azure OpenAI account page | - | `c55168be3874490ef0565d9779ecd5a6` |
| `OPENAI_PROXY_URL` | Yes | Azure API address, can be found in the "Keys and Endpoints" section | - | `https://docs-test-001.openai.azure.com` |
| `AZURE_API_VERSION` | No | Azure's API version, follows the YYYY-MM-DD format | 2023-08-01-preview | `2023-05-15`, refer to [latest version][azure-api-version-url] |
| `ACCESS_CODE` | No | Add a password to access this service; you can set a long password to avoid leaking. If this value contains a comma, it is a password array. | - | `awCT74` or `e3@09!` or `code1,code2,code3` |

> \[!NOTE]
>
Expand Down
14 changes: 7 additions & 7 deletions docs/Deployment/Deploy-with-Azure-OpenAI.zh-CN.md
Original file line number Diff line number Diff line change
Expand Up @@ -37,13 +37,13 @@ LobeChat 支持使用 [Azure OpenAI][azure-openai-url] 作为 OpenAI 的模型

如果你希望部署的版本直接配置好 Azure OpenAI,让终端用户直接使用,那么你需要在部署时配置以下环境变量:

| 环境变量 | 类型 | 描述 | 默认值 | 示例 |
| ------------------- | ---- | --------------------------------------------------------------------------- | ------------------ | -------------------------------------------------- |
| `USE_AZURE_OPENAI` | 必选 | 设置改值为 `1` 开启 Azure OpenAI 配置 | - | `1` |
| `AZURE_API_KEY` | 必选 | 这是你在 Azure OpenAI 账户页面申请的 API 密钥 | - | `c55168be3874490ef0565d9779ecd5a6` |
| `OPENAI_PROXY_URL` | 必选 | Azure API 地址,从 Azure 门户检查资源时,可在 “密钥和终结点” 部分中找到此值 | - | `https://docs-test-001.openai.azure.com` |
| `AZURE_API_VERSION` | 可选 | Azure 的 API 版本,遵循 YYYY-MM-DD 格式 | 2023-08-01-preview | `2023-05-15`,查阅[最新版本][azure-api-verion-url] |
| `ACCESS_CODE` | 可选 | 添加访问此服务的密码,密码应为 6 位数字或字母 | - | `awCT74``e3@09!` |
| 环境变量 | 类型 | 描述 | 默认值 | 示例 |
| ------------------- | ---- | -------------------------------------------------------------------------------- | ------------------ | -------------------------------------------------- |
| `USE_AZURE_OPENAI` | 必选 | 设置改值为 `1` 开启 Azure OpenAI 配置 | - | `1` |
| `AZURE_API_KEY` | 必选 | 这是你在 Azure OpenAI 账户页面申请的 API 密钥 | - | `c55168be3874490ef0565d9779ecd5a6` |
| `OPENAI_PROXY_URL` | 必选 | Azure API 地址,从 Azure 门户检查资源时,可在 “密钥和终结点” 部分中找到此值 | - | `https://docs-test-001.openai.azure.com` |
| `AZURE_API_VERSION` | 可选 | Azure 的 API 版本,遵循 YYYY-MM-DD 格式 | 2023-08-01-preview | `2023-05-15`,查阅[最新版本][azure-api-verion-url] |
| `ACCESS_CODE` | 可选 | 添加访问此服务的密码,你可以设置一个长密码以防被爆破,该值用逗号分隔时为密码数组 | - | `awCT74``e3@09!` or `code1,code2,code3` |

> \[!NOTE]
>
Expand Down
4 changes: 2 additions & 2 deletions docs/Deployment/Environment-Variable.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,9 +27,9 @@ LobeChat provides additional configuration options during deployment, which can
### `ACCESS_CODE`

- Type: Optional
- Description: Add a password to access the LobeChat service, ; you can set a long password to avoid leaking.
- Description: Add a password to access the LobeChat service, ; you can set a long password to avoid leaking. If this value contains a comma, it is a password array.
- Default: `-`
- Example: `awCTe)re_r74` or `rtrt_ewee3@09!`
- Example: `awCTe)re_r74` or `rtrt_ewee3@09!` or `code1,code2,code3`

### `NEXT_PUBLIC_CUSTOM_MODELS`

Expand Down
6 changes: 3 additions & 3 deletions src/app/api/auth.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,17 +7,17 @@ interface AuthConfig {
}

export const checkAuth = ({ apiKey, accessCode }: AuthConfig) => {
const { ACCESS_CODE } = getServerConfig();
const { ACCESS_CODES } = getServerConfig();

// if apiKey exist
if (apiKey) {
return { auth: true };
}

// if accessCode doesn't exist
if (!ACCESS_CODE) return { auth: true };
if (!ACCESS_CODES.length) return { auth: true };

if (accessCode !== ACCESS_CODE) {
if (!accessCode || !ACCESS_CODES.includes(accessCode)) {
return { auth: false, error: ChatErrorType.InvalidAccessCode };
}

Expand Down
51 changes: 51 additions & 0 deletions src/app/api/config.test.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { describe, expect, it, vi } from 'vitest';

import { checkAuth } from './auth';
import { getPreferredRegion } from './config';

// Stub the global process object to safely mock environment variables
Expand Down Expand Up @@ -40,3 +41,53 @@ describe('getPreferredRegion', () => {
expect(preferredRegion).toStrictEqual(['ida1', 'sfo1']);
});
});

describe('ACCESS_CODE', () => {
let auth = false;

beforeEach(() => {
auth = false;
process.env.ACCESS_CODE = undefined;
// Reset environment variables before each test case
vi.restoreAllMocks();
});

it('set multiple access codes', () => {
process.env.ACCESS_CODE = ',code1,code2,code3';
({ auth } = checkAuth({ accessCode: 'code1' }));
expect(auth).toBe(true);
({ auth } = checkAuth({ accessCode: 'code2' }));
expect(auth).toBe(true);
({ auth } = checkAuth({ accessCode: 'code1,code2' }));
expect(auth).toBe(false);
});

it('set individual access code', () => {
process.env.ACCESS_CODE = 'code1';
({ auth } = checkAuth({ accessCode: 'code1' }));
expect(auth).toBe(true);
({ auth } = checkAuth({ accessCode: 'code2' }));
expect(auth).toBe(false);
});

it('no access code', () => {
({ auth } = checkAuth({ accessCode: 'code1' }));
expect(auth).toBe(true);
({ auth } = checkAuth({}));
expect(auth).toBe(true);
});

it('empty access code', () => {
process.env.ACCESS_CODE = '';
({ auth } = checkAuth({ accessCode: 'code1' }));
expect(auth).toBe(true);
({ auth } = checkAuth({}));
expect(auth).toBe(true);

process.env.ACCESS_CODE = ',,';
({ auth } = checkAuth({ accessCode: 'code1' }));
expect(auth).toBe(true);
({ auth } = checkAuth({}));
expect(auth).toBe(true);
});
});
6 changes: 3 additions & 3 deletions src/config/server.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,12 +33,12 @@ export const getServerConfig = () => {
regions = process.env.OPENAI_FUNCTION_REGIONS.split(',');
}

const ACCESS_CODE = process.env.ACCESS_CODE;
const ACCESS_CODES = process.env.ACCESS_CODE?.split(',').filter(Boolean) || [];

return {
ACCESS_CODE,
ACCESS_CODES,

SHOW_ACCESS_CODE_CONFIG: !!ACCESS_CODE,
SHOW_ACCESS_CODE_CONFIG: !!ACCESS_CODES.length,

OPENAI_API_KEY: process.env.OPENAI_API_KEY,
OPENAI_PROXY_URL: process.env.OPENAI_PROXY_URL,
Expand Down

0 comments on commit 7db0430

Please sign in to comment.