diff --git a/api/apps/system_app.py b/api/apps/system_app.py index c1ae5ec3b..c4a70bcac 100644 --- a/api/apps/system_app.py +++ b/api/apps/system_app.py @@ -37,7 +37,6 @@ from timeit import default_timer as timer from rag.utils.redis_conn import REDIS_CONN - @manager.route("/version", methods=["GET"]) # noqa: F821 @login_required def version(): @@ -298,3 +297,25 @@ def rm(token): [APIToken.tenant_id == current_user.id, APIToken.token == token] ) return get_json_result(data=True) + + +@manager.route('/config', methods=['GET']) # noqa: F821 +def get_config(): + """ + Get system configuration. + --- + tags: + - System + responses: + 200: + description: Return system configuration + schema: + type: object + properties: + registerEnable: + type: integer 0 means disabled, 1 means enabled + description: Whether user registration is enabled + """ + return get_json_result(data={ + "registerEnabled": settings.REGISTER_ENABLED + }) diff --git a/api/apps/user_app.py b/api/apps/user_app.py index 1cf85986c..89e771448 100644 --- a/api/apps/user_app.py +++ b/api/apps/user_app.py @@ -562,6 +562,14 @@ def user_add(): schema: type: object """ + + if not settings.REGISTER_ENABLED: + return get_json_result( + data=False, + message="User registration is disabled!", + code=settings.RetCode.OPERATING_ERROR, + ) + req = request.json email_address = req["email"] diff --git a/api/settings.py b/api/settings.py index d4b829cf9..87b4858b9 100644 --- a/api/settings.py +++ b/api/settings.py @@ -62,9 +62,12 @@ docStoreConn = None retrievaler = None kg_retrievaler = None +# user registration switch +REGISTER_ENABLED = 1 + def init_settings(): - global LLM, LLM_FACTORY, LLM_BASE_URL, LIGHTEN, DATABASE_TYPE, DATABASE, FACTORY_LLM_INFOS + global LLM, LLM_FACTORY, LLM_BASE_URL, LIGHTEN, DATABASE_TYPE, DATABASE, FACTORY_LLM_INFOS, REGISTER_ENABLED LIGHTEN = int(os.environ.get('LIGHTEN', "0")) DATABASE_TYPE = os.getenv("DB_TYPE", 'mysql') DATABASE = decrypt_database_config(name=DATABASE_TYPE) @@ -72,6 +75,10 @@ def init_settings(): LLM_DEFAULT_MODELS = LLM.get("default_models", {}) LLM_FACTORY = LLM.get("factory", "Tongyi-Qianwen") LLM_BASE_URL = LLM.get("base_url") + try: + REGISTER_ENABLED = int(os.environ.get("REGISTER_ENABLED", "1")) + except Exception: + pass try: with open(os.path.join(get_project_base_directory(), "conf", "llm_factories.json"), "r") as f: diff --git a/docker/.env b/docker/.env index 2b0b5b8be..40a8a3c5e 100644 --- a/docker/.env +++ b/docker/.env @@ -146,3 +146,6 @@ TIMEZONE='Asia/Shanghai' # ENDPOINT=http://oss-cn-hangzhou.aliyuncs.com # REGION=cn-hangzhou # BUCKET=ragflow65536 + +# user registration switch +REGISTER_ENABLED=1 diff --git a/web/src/hooks/login-hooks.ts b/web/src/hooks/login-hooks.ts index 8f8c292c3..ddecc3ce7 100644 --- a/web/src/hooks/login-hooks.ts +++ b/web/src/hooks/login-hooks.ts @@ -67,6 +67,8 @@ export const useRegister = () => { const { data = {} } = await userService.register(params); if (data.code === 0) { message.success(t('message.registered')); + } else if (data.message && data.message.includes('registration is disabled')) { + message.error(t('message.registerDisabled') || 'User registration is disabled'); } return data.code; }, diff --git a/web/src/hooks/system-hooks.ts b/web/src/hooks/system-hooks.ts new file mode 100644 index 000000000..b5ce92969 --- /dev/null +++ b/web/src/hooks/system-hooks.ts @@ -0,0 +1,18 @@ +import userService from '@/services/user-service'; +import { useQuery } from '@tanstack/react-query'; + +/** + * Hook to fetch system configuration including register enable status + * @returns System configuration with loading status + */ +export const useSystemConfig = () => { + const { data, isLoading } = useQuery({ + queryKey: ['systemConfig'], + queryFn: async () => { + const { data = {} } = await userService.getSystemConfig(); + return data.data || { registerEnabled: 1 }; // Default to enabling registration + }, + }); + + return { config: data, loading: isLoading }; +}; diff --git a/web/src/locales/en.ts b/web/src/locales/en.ts index c686e03a3..181bbcf34 100644 --- a/web/src/locales/en.ts +++ b/web/src/locales/en.ts @@ -705,6 +705,7 @@ This auto-tag feature enhances retrieval by adding another layer of domain-speci logout: 'logout', logged: 'logged!', pleaseSelectChunk: 'Please select chunk!', + registerDisabled: 'User registration is disabled', modified: 'Modified', created: 'Created', deleted: 'Deleted', diff --git a/web/src/pages/login/index.tsx b/web/src/pages/login/index.tsx index 0bc24cf04..dab0b264c 100644 --- a/web/src/pages/login/index.tsx +++ b/web/src/pages/login/index.tsx @@ -1,4 +1,5 @@ import { useLogin, useRegister } from '@/hooks/login-hooks'; +import { useSystemConfig } from '@/hooks/system-hooks'; import { rsaPsw } from '@/utils'; import { Button, Checkbox, Form, Input } from 'antd'; import { useEffect, useState } from 'react'; @@ -16,8 +17,13 @@ const Login = () => { const { register, loading: registerLoading } = useRegister(); const { t } = useTranslation('translation', { keyPrefix: 'login' }); const loading = signLoading || registerLoading; + const { config } = useSystemConfig(); + const registerEnabled = config?.registerEnabled !== 0; const changeTitle = () => { + if (title === 'login' && !registerEnabled) { + return; + } setTitle((title) => (title === 'login' ? 'register' : 'login')); }; const [form] = Form.useForm(); @@ -119,7 +125,7 @@ const Login = () => { )}
- {title === 'login' && ( + {title === 'login' && registerEnabled && (
{t('signInTip')}