diff --git a/backend/internal/config/config.go b/backend/internal/config/config.go index 31fbeed8..ffca51df 100644 --- a/backend/internal/config/config.go +++ b/backend/internal/config/config.go @@ -617,7 +617,7 @@ func setDefaults() { // Turnstile viper.SetDefault("turnstile.required", false) - // LinuxDo Connect OAuth 登录(终端用户 SSO) + // LinuxDo Connect OAuth 登录 viper.SetDefault("linuxdo_connect.enabled", false) viper.SetDefault("linuxdo_connect.client_id", "") viper.SetDefault("linuxdo_connect.client_secret", "") diff --git a/backend/internal/handler/admin/setting_handler.go b/backend/internal/handler/admin/setting_handler.go index ee75d072..2f9785ee 100644 --- a/backend/internal/handler/admin/setting_handler.go +++ b/backend/internal/handler/admin/setting_handler.go @@ -104,7 +104,7 @@ type UpdateSettingsRequest struct { TurnstileSiteKey string `json:"turnstile_site_key"` TurnstileSecretKey string `json:"turnstile_secret_key"` - // LinuxDo Connect OAuth 登录(终端用户 SSO) + // LinuxDo Connect OAuth 登录 LinuxDoConnectEnabled bool `json:"linuxdo_connect_enabled"` LinuxDoConnectClientID string `json:"linuxdo_connect_client_id"` LinuxDoConnectClientSecret string `json:"linuxdo_connect_client_secret"` diff --git a/backend/internal/service/auth_service.go b/backend/internal/service/auth_service.go index 61b15cd8..386b43fc 100644 --- a/backend/internal/service/auth_service.go +++ b/backend/internal/service/auth_service.go @@ -357,7 +357,7 @@ func (s *AuthService) Login(ctx context.Context, email, password string) (string // - 如果邮箱已存在:直接登录(不需要本地密码) // - 如果邮箱不存在:创建新用户并登录 // -// 注意:该函数用于“终端用户登录 Sub2API 本身”的场景(不同于上游账号的 OAuth,例如 OpenAI/Gemini)。 +// 注意:该函数用于 LinuxDo OAuth 登录场景(不同于上游账号的 OAuth,例如 Claude/OpenAI/Gemini)。 // 为了满足现有数据库约束(需要密码哈希),新用户会生成随机密码并进行哈希保存。 func (s *AuthService) LoginOrRegisterOAuth(ctx context.Context, email, username string) (string, *User, error) { email = strings.TrimSpace(email) @@ -376,8 +376,8 @@ func (s *AuthService) LoginOrRegisterOAuth(ctx context.Context, email, username user, err := s.userRepo.GetByEmail(ctx, email) if err != nil { if errors.Is(err, ErrUserNotFound) { - // OAuth 首次登录视为注册。 - if s.settingService != nil && !s.settingService.IsRegistrationEnabled(ctx) { + // OAuth 首次登录视为注册(fail-close:settingService 未配置时不允许注册) + if s.settingService == nil || !s.settingService.IsRegistrationEnabled(ctx) { return "", nil, ErrRegDisabled } diff --git a/backend/internal/service/setting_service.go b/backend/internal/service/setting_service.go index d85e1c83..863d8a57 100644 --- a/backend/internal/service/setting_service.go +++ b/backend/internal/service/setting_service.go @@ -176,7 +176,7 @@ func (s *SettingService) UpdateSettings(ctx context.Context, settings *SystemSet updates[SettingKeyTurnstileSecretKey] = settings.TurnstileSecretKey } - // LinuxDo Connect OAuth 登录(终端用户 SSO) + // LinuxDo Connect OAuth 登录 updates[SettingKeyLinuxDoConnectEnabled] = strconv.FormatBool(settings.LinuxDoConnectEnabled) updates[SettingKeyLinuxDoConnectClientID] = settings.LinuxDoConnectClientID updates[SettingKeyLinuxDoConnectRedirectURL] = settings.LinuxDoConnectRedirectURL @@ -227,8 +227,8 @@ func (s *SettingService) UpdateSettings(ctx context.Context, settings *SystemSet func (s *SettingService) IsRegistrationEnabled(ctx context.Context) bool { value, err := s.settingRepo.GetValue(ctx, SettingKeyRegistrationEnabled) if err != nil { - // 默认开放注册 - return true + // 安全默认:如果设置不存在或查询出错,默认关闭注册 + return false } return value == "true" } diff --git a/backend/internal/service/settings_view.go b/backend/internal/service/settings_view.go index f9fcb0b6..e20a230a 100644 --- a/backend/internal/service/settings_view.go +++ b/backend/internal/service/settings_view.go @@ -18,7 +18,7 @@ type SystemSettings struct { TurnstileSecretKey string TurnstileSecretKeyConfigured bool - // LinuxDo Connect OAuth 登录(终端用户 SSO) + // LinuxDo Connect OAuth 登录 LinuxDoConnectEnabled bool LinuxDoConnectClientID string LinuxDoConnectClientSecret string diff --git a/frontend/src/api/admin/settings.ts b/frontend/src/api/admin/settings.ts index 9a3d103f..913c9652 100644 --- a/frontend/src/api/admin/settings.ts +++ b/frontend/src/api/admin/settings.ts @@ -36,6 +36,12 @@ export interface SystemSettings { turnstile_site_key: string turnstile_secret_key_configured: boolean + // LinuxDo Connect OAuth settings + linuxdo_connect_enabled: boolean + linuxdo_connect_client_id: string + linuxdo_connect_client_secret_configured: boolean + linuxdo_connect_redirect_url: string + // Model fallback configuration enable_model_fallback: boolean fallback_model_anthropic: string @@ -76,6 +82,10 @@ export interface UpdateSettingsRequest { turnstile_enabled?: boolean turnstile_site_key?: string turnstile_secret_key?: string + linuxdo_connect_enabled?: boolean + linuxdo_connect_client_id?: string + linuxdo_connect_client_secret?: string + linuxdo_connect_redirect_url?: string enable_model_fallback?: boolean fallback_model_anthropic?: string fallback_model_openai?: string diff --git a/frontend/src/views/admin/SettingsView.vue b/frontend/src/views/admin/SettingsView.vue index 051f42b3..57b18d0d 100644 --- a/frontend/src/views/admin/SettingsView.vue +++ b/frontend/src/views/admin/SettingsView.vue @@ -261,6 +261,106 @@ + +
+
+

+ {{ t('admin.settings.linuxdo.title') }} +

+

+ {{ t('admin.settings.linuxdo.description') }} +

+
+
+
+
+ +

+ {{ t('admin.settings.linuxdo.enableHint') }} +

+
+ +
+ +
+
+
+ + +

+ {{ t('admin.settings.linuxdo.clientIdHint') }} +

+
+ +
+ + +

+ {{ + form.linuxdo_connect_client_secret_configured + ? t('admin.settings.linuxdo.clientSecretConfiguredHint') + : t('admin.settings.linuxdo.clientSecretHint') + }} +

+
+ +
+ + +
+ + + {{ linuxdoRedirectUrlSuggestion }} + +
+

+ {{ t('admin.settings.linuxdo.redirectUrlHint') }} +

+
+
+
+
+
+
@@ -712,19 +812,19 @@