Merge pull request #16 from yumusb/feat/hide-login-form

feat: Add `passwordEnabled` configuration to conditionally display th…
This commit is contained in:
dushixiang authored and GitHub committed 2025-12-26 19:57:27 +08:00
commit 681c645be0
3 files changed
+64 -58

No files matched your search

+6 -4
View File
@@ -167,15 +167,17 @@ func (s *AccountService) ValidateToken(tokenString string) (*JWTClaims, error) {
// AuthConfig 认证配置 // AuthConfig 认证配置
type AuthConfig struct { type AuthConfig struct {
OIDCEnabled bool `json:"oidcEnabled"` OIDCEnabled bool `json:"oidcEnabled"`
GitHubEnabled bool `json:"githubEnabled"` GitHubEnabled bool `json:"githubEnabled"`
PasswordEnabled bool `json:"passwordEnabled"`
} }
// GetAuthConfig 获取认证配置 // GetAuthConfig 获取认证配置
func (s *AccountService) GetAuthConfig() *AuthConfig { func (s *AccountService) GetAuthConfig() *AuthConfig {
return &AuthConfig{ return &AuthConfig{
OIDCEnabled: s.oidcService.IsEnabled(), OIDCEnabled: s.oidcService.IsEnabled(),
GitHubEnabled: s.githubService.IsEnabled(), GitHubEnabled: s.githubService.IsEnabled(),
PasswordEnabled: s.userService.IsEnabled(),
} }
} }
+1
View File
@@ -5,6 +5,7 @@ import type { LoginRequest, LoginResponse } from '../types';
export interface AuthConfig { export interface AuthConfig {
oidcEnabled: boolean; oidcEnabled: boolean;
githubEnabled: boolean; githubEnabled: boolean;
passwordEnabled: boolean;
} }
// OIDC 认证 URL // OIDC 认证 URL
+57 -54
View File
@@ -1,18 +1,19 @@
import {useEffect, useState} from 'react'; import { useEffect, useState } from 'react';
import {useNavigate} from 'react-router-dom'; import { useNavigate } from 'react-router-dom';
import {App, Button, Form, Input} from 'antd'; import { App, Button, Form, Input } from 'antd';
import {GithubOutlined, GlobalOutlined, LockOutlined, UserOutlined} from '@ant-design/icons'; import { GithubOutlined, GlobalOutlined, LockOutlined, UserOutlined } from '@ant-design/icons';
import {getAuthConfig, getGitHubAuthURL, getOIDCAuthURL, login} from '@/api/auth.ts'; import { getAuthConfig, getGitHubAuthURL, getOIDCAuthURL, login } from '@/api/auth.ts';
import type {LoginRequest} from '@/types'; import type { LoginRequest } from '@/types';
const Login = () => { const Login = () => {
const [loading, setLoading] = useState(false); const [loading, setLoading] = useState(false);
const [oidcEnabled, setOidcEnabled] = useState(false); const [oidcEnabled, setOidcEnabled] = useState(false);
const [githubEnabled, setGithubEnabled] = useState(false); const [githubEnabled, setGithubEnabled] = useState(false);
const [passwordEnabled, setPasswordEnabled] = useState(true);
const [oidcLoading, setOidcLoading] = useState(false); const [oidcLoading, setOidcLoading] = useState(false);
const [githubLoading, setGithubLoading] = useState(false); const [githubLoading, setGithubLoading] = useState(false);
const navigate = useNavigate(); const navigate = useNavigate();
const {message: messageApi} = App.useApp(); const { message: messageApi } = App.useApp();
useEffect(() => { useEffect(() => {
fetchAuthConfig(); fetchAuthConfig();
@@ -23,6 +24,7 @@ const Login = () => {
const response = await getAuthConfig(); const response = await getAuthConfig();
setOidcEnabled(response.data.oidcEnabled); setOidcEnabled(response.data.oidcEnabled);
setGithubEnabled(response.data.githubEnabled); setGithubEnabled(response.data.githubEnabled);
setPasswordEnabled(response.data.passwordEnabled);
} catch (error) { } catch (error) {
console.error('获取认证配置失败:', error); console.error('获取认证配置失败:', error);
} }
@@ -32,7 +34,7 @@ const Login = () => {
setLoading(true); setLoading(true);
try { try {
const response = await login(values); const response = await login(values);
const {token, user} = response.data; const { token, user } = response.data;
localStorage.setItem('token', token); localStorage.setItem('token', token);
localStorage.setItem('userInfo', JSON.stringify(user)); localStorage.setItem('userInfo', JSON.stringify(user));
messageApi.success('欢迎回来'); messageApi.success('欢迎回来');
@@ -83,60 +85,61 @@ const Login = () => {
</p> </p>
</div> </div>
<Form {passwordEnabled && (
name="login" <Form
layout="vertical" name="login"
layout="vertical"
onFinish={onFinish} onFinish={onFinish}
autoComplete="off" autoComplete="off"
requiredMark={false} // 4. 隐藏必填星号,界面更干净 requiredMark={false} // 4. 隐藏必填星号,界面更干净
>
<Form.Item
name="username"
rules={[{required: true, message: '请输入用户名'}]}
className="mb-4"
> >
<Input <Form.Item
prefix={<UserOutlined className="text-slate-400 mr-1"/>} name="username"
placeholder="用户名" rules={[{ required: true, message: '请输入用户名' }]}
className="rounded-xl px-4 py-2.5 bg-slate-50 border-slate-200 hover:bg-white focus:bg-white transition-all" className="mb-4"
/>
</Form.Item>
<Form.Item
name="password"
rules={[{required: true, message: '请输入密码'}]}
className="mb-6"
>
<Input.Password
prefix={<LockOutlined className="text-slate-400 mr-1"/>}
placeholder="密码"
className="rounded-xl px-4 py-2.5 bg-slate-50 border-slate-200 hover:bg-white focus:bg-white transition-all"
/>
</Form.Item>
<Form.Item className="mb-0">
<Button
type="primary"
htmlType="submit"
loading={loading}
block
className="h-11 rounded-xl bg-slate-900 hover:bg-slate-800 font-medium shadow-sm transition-all"
> >
登 录 <Input
</Button> prefix={<UserOutlined className="text-slate-400 mr-1" />}
</Form.Item> placeholder="用户名"
</Form> className="rounded-xl px-4 py-2.5 bg-slate-50 border-slate-200 hover:bg-white focus:bg-white transition-all"
/>
</Form.Item>
<Form.Item
name="password"
rules={[{ required: true, message: '请输入密码' }]}
className="mb-6"
>
<Input.Password
prefix={<LockOutlined className="text-slate-400 mr-1" />}
placeholder="密码"
className="rounded-xl px-4 py-2.5 bg-slate-50 border-slate-200 hover:bg-white focus:bg-white transition-all"
/>
</Form.Item>
<Form.Item className="mb-0">
<Button
type="primary"
htmlType="submit"
loading={loading}
block
className="h-11 rounded-xl bg-slate-900 hover:bg-slate-800 font-medium shadow-sm transition-all"
>
登 录
</Button>
</Form.Item>
</Form>
)}
{/* 5. 第三方登录区域 */} {/* 5. 第三方登录区域 */}
{(oidcEnabled || githubEnabled) && ( {(oidcEnabled || githubEnabled) && (
<div className="mt-8"> <div className="mt-8">
<div className="relative"> <div className="relative">
<div className="absolute inset-0 flex items-center"> <div className="absolute inset-0 flex items-center">
<span className="w-full border-t border-slate-200"/> <span className="w-full border-t border-slate-200" />
</div> </div>
<div className="relative flex justify-center text-xs uppercase"> <div className="relative flex justify-center text-xs uppercase">
<span className="bg-white px-2 text-slate-400">或者</span> <span className="bg-white px-2 text-slate-400">{passwordEnabled ? '或者' : '使用第三方登录'}</span>
</div> </div>
</div> </div>
@@ -146,7 +149,7 @@ const Login = () => {
<Button <Button
block block
loading={githubLoading} loading={githubLoading}
icon={<GithubOutlined/>} icon={<GithubOutlined />}
onClick={handleGitHubLogin} onClick={handleGitHubLogin}
className={`h-10 rounded-xl border-slate-200 text-slate-700 font-medium hover:border-slate-300 hover:text-slate-900 ${!oidcEnabled ? 'col-span-2' : ''}`} className={`h-10 rounded-xl border-slate-200 text-slate-700 font-medium hover:border-slate-300 hover:text-slate-900 ${!oidcEnabled ? 'col-span-2' : ''}`}
> >
@@ -157,7 +160,7 @@ const Login = () => {
<Button <Button
block block
loading={oidcLoading} loading={oidcLoading}
icon={<GlobalOutlined/>} // 换了一个更通用的图标 icon={<GlobalOutlined />} // 换了一个更通用的图标
onClick={handleOIDCLogin} onClick={handleOIDCLogin}
className={`h-10 rounded-xl border-slate-200 text-slate-700 font-medium hover:border-slate-300 hover:text-slate-900 ${!githubEnabled ? 'col-span-2' : ''}`} className={`h-10 rounded-xl border-slate-200 text-slate-700 font-medium hover:border-slate-300 hover:text-slate-900 ${!githubEnabled ? 'col-span-2' : ''}`}
> >