diff --git a/web/src/pages/SystemSettingsPage/SystemSettingsPage.tsx b/web/src/pages/SystemSettingsPage/SystemSettingsPage.tsx
index 533e10c..9add5ab 100644
--- a/web/src/pages/SystemSettingsPage/SystemSettingsPage.tsx
+++ b/web/src/pages/SystemSettingsPage/SystemSettingsPage.tsx
@@ -2,21 +2,20 @@ import { Alert, message, Tabs, Space } from 'antd';
import { useEffect, useState } from 'react';
import PageCard from '../../components/PageCard';
import { getAllConfig, setConfig } from '../../api/config';
-import { AppstoreOutlined, RobotOutlined, DatabaseOutlined, SkinOutlined, MailOutlined, CloudSyncOutlined, UserOutlined } from '@ant-design/icons';
+import { AppstoreOutlined, RobotOutlined, DatabaseOutlined, SkinOutlined, MailOutlined, CloudSyncOutlined } from '@ant-design/icons';
import { useTheme } from '../../contexts/ThemeContext';
import '../../styles/settings-tabs.css';
import { useI18n } from '../../i18n';
import AppearanceSettingsTab from './components/AppearanceSettingsTab';
import AppSettingsTab from './components/AppSettingsTab';
-import AuthSettingsTab from './components/AuthSettingsTab';
import AiSettingsTab from './components/AiSettingsTab';
import VectorDbSettingsTab from './components/VectorDbSettingsTab';
import EmailSettingsTab from './components/EmailSettingsTab';
import ProtocolMappingsTab from './components/ProtocolMappingsTab';
-type TabKey = 'appearance' | 'app' | 'auth' | 'email' | 'ai' | 'vector-db' | 'mappings';
+type TabKey = 'appearance' | 'app' | 'email' | 'ai' | 'vector-db' | 'mappings';
-const TAB_KEYS: TabKey[] = ['appearance', 'app', 'auth', 'email', 'ai', 'vector-db', 'mappings'];
+const TAB_KEYS: TabKey[] = ['appearance', 'app', 'email', 'ai', 'vector-db', 'mappings'];
const DEFAULT_TAB: TabKey = 'appearance';
const isValidTab = (key?: string): key is TabKey => !!key && (TAB_KEYS as string[]).includes(key);
@@ -169,22 +168,6 @@ export default function SystemSettingsPage({ tabKey, onTabNavigate }: SystemSett
/>
),
},
- {
- key: 'auth',
- label: (
-
-
- {t('Registration Settings')}
-
- ),
- children: (
-
- ),
- },
{
key: 'email',
label: (
diff --git a/web/src/pages/SystemSettingsPage/components/AppSettingsTab.tsx b/web/src/pages/SystemSettingsPage/components/AppSettingsTab.tsx
index a0609ff..221ac14 100644
--- a/web/src/pages/SystemSettingsPage/components/AppSettingsTab.tsx
+++ b/web/src/pages/SystemSettingsPage/components/AppSettingsTab.tsx
@@ -1,4 +1,6 @@
-import { Form, Input, Button } from 'antd';
+import { Alert, Button, Divider, Form, Input, Select, Switch, message } from 'antd';
+import { useEffect, useMemo, useState } from 'react';
+import { rolesApi, type RoleInfo } from '../../../api/roles';
import { useI18n } from '../../../i18n';
interface AppConfigKey {
@@ -21,14 +23,56 @@ export default function AppSettingsTab({
configKeys,
}: AppSettingsTabProps) {
const { t } = useI18n();
+ const [rolesLoading, setRolesLoading] = useState(false);
+ const [roles, setRoles] = useState([]);
+
+ useEffect(() => {
+ let mounted = true;
+ async function loadRoles() {
+ setRolesLoading(true);
+ try {
+ const list = await rolesApi.list();
+ if (!mounted) return;
+ setRoles(list);
+ } catch (e: any) {
+ message.error(e.message || t('Load failed'));
+ } finally {
+ if (mounted) setRolesLoading(false);
+ }
+ }
+ loadRoles();
+ return () => {
+ mounted = false;
+ };
+ }, [t]);
+
+ const initialValues = useMemo(() => {
+ const allowRegister = (config.AUTH_ALLOW_REGISTER || '').trim().toLowerCase() === 'true';
+ const roleIdRaw = (config.AUTH_DEFAULT_REGISTER_ROLE_ID || '').trim();
+ const roleId = roleIdRaw ? Number(roleIdRaw) : undefined;
+ return {
+ ...Object.fromEntries(configKeys.map(({ key, default: def }) => [key, config[key] ?? def ?? ''])),
+ AUTH_ALLOW_REGISTER: allowRegister,
+ AUTH_DEFAULT_REGISTER_ROLE_ID: Number.isFinite(roleId) ? roleId : undefined,
+ };
+ }, [config, configKeys]);
return (