feat: 添加认证服务模块,包括注册、登录、OAuth、令牌管理及密码更新功能,并新增密码修改组件。
This commit is contained in:
@@ -1,6 +1,6 @@
|
|||||||
import { useState } from 'react';
|
import { useState, useEffect } from 'react';
|
||||||
import { Icon } from '@iconify/react';
|
import { Icon } from '@iconify/react';
|
||||||
import { updatePassword } from '../../../services/authService';
|
import { updatePassword, getCurrentUser, type User } from '../../../services/authService';
|
||||||
import './ChangePassword.css';
|
import './ChangePassword.css';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -8,12 +8,26 @@ import './ChangePassword.css';
|
|||||||
* Allows users to change their login password
|
* Allows users to change their login password
|
||||||
*/
|
*/
|
||||||
function ChangePassword() {
|
function ChangePassword() {
|
||||||
|
const [user, setUser] = useState<User | null>(null);
|
||||||
const [oldPassword, setOldPassword] = useState('');
|
const [oldPassword, setOldPassword] = useState('');
|
||||||
const [newPassword, setNewPassword] = useState('');
|
const [newPassword, setNewPassword] = useState('');
|
||||||
const [confirmPassword, setConfirmPassword] = useState('');
|
const [confirmPassword, setConfirmPassword] = useState('');
|
||||||
const [loading, setLoading] = useState(false);
|
const [loading, setLoading] = useState(false);
|
||||||
const [message, setMessage] = useState<{ type: 'success' | 'error'; text: string } | null>(null);
|
const [message, setMessage] = useState<{ type: 'success' | 'error'; text: string } | null>(null);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
loadUser();
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
const loadUser = async () => {
|
||||||
|
try {
|
||||||
|
const userData = await getCurrentUser();
|
||||||
|
setUser(userData);
|
||||||
|
} catch (error) {
|
||||||
|
console.error('Failed to load user info', error);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
const handleSubmit = async (e: React.FormEvent) => {
|
const handleSubmit = async (e: React.FormEvent) => {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
|
|
||||||
@@ -28,7 +42,7 @@ function ChangePassword() {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (oldPassword === newPassword) {
|
if (user?.has_password && oldPassword === newPassword) {
|
||||||
setMessage({ type: 'error', text: '新密码不能与旧密码相同' });
|
setMessage({ type: 'error', text: '新密码不能与旧密码相同' });
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -37,28 +51,35 @@ function ChangePassword() {
|
|||||||
setMessage(null);
|
setMessage(null);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
await updatePassword(oldPassword, newPassword);
|
// If user has no password, send empty string as old password
|
||||||
setMessage({ type: 'success', text: '登录密码修改成功' });
|
await updatePassword(user?.has_password ? oldPassword : '', newPassword);
|
||||||
|
setMessage({ type: 'success', text: user?.has_password ? '登录密码修改成功' : '登录密码设置成功' });
|
||||||
|
|
||||||
// Clear forms
|
// Clear forms
|
||||||
setOldPassword('');
|
setOldPassword('');
|
||||||
setNewPassword('');
|
setNewPassword('');
|
||||||
setConfirmPassword('');
|
setConfirmPassword('');
|
||||||
|
|
||||||
|
// Refresh user info to update has_password status
|
||||||
|
loadUser();
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
setMessage({
|
setMessage({
|
||||||
type: 'error',
|
type: 'error',
|
||||||
text: error instanceof Error ? error.message : '修改密码失败,请检查旧密码是否正确'
|
text: error instanceof Error ? error.message : '操作失败'
|
||||||
});
|
});
|
||||||
} finally {
|
} finally {
|
||||||
setLoading(false);
|
setLoading(false);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const hasPassword = user?.has_password ?? false;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="change-password-settings">
|
<div className="change-password-settings">
|
||||||
<section className="password-section">
|
<section className="password-section">
|
||||||
<h3>
|
<h3>
|
||||||
<Icon icon="solar:lock-password-bold-duotone" className="text-primary" />
|
<Icon icon="solar:lock-password-bold-duotone" className="text-primary" />
|
||||||
登录密码
|
{hasPassword ? '修改登录密码' : '设置登录密码'}
|
||||||
</h3>
|
</h3>
|
||||||
|
|
||||||
{message && (
|
{message && (
|
||||||
@@ -69,21 +90,23 @@ function ChangePassword() {
|
|||||||
)}
|
)}
|
||||||
|
|
||||||
<form onSubmit={handleSubmit} className="password-form">
|
<form onSubmit={handleSubmit} className="password-form">
|
||||||
<div className="form-group">
|
{hasPassword && (
|
||||||
<label htmlFor="login-old-password">当前密码</label>
|
<div className="form-group">
|
||||||
<input
|
<label htmlFor="login-old-password">当前密码</label>
|
||||||
type="password"
|
<input
|
||||||
id="login-old-password"
|
type="password"
|
||||||
value={oldPassword}
|
id="login-old-password"
|
||||||
onChange={(e) => setOldPassword(e.target.value)}
|
value={oldPassword}
|
||||||
placeholder="输入当前使用的登录密码"
|
onChange={(e) => setOldPassword(e.target.value)}
|
||||||
disabled={loading}
|
placeholder="输入当前使用的登录密码"
|
||||||
required
|
disabled={loading}
|
||||||
/>
|
required
|
||||||
</div>
|
/>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
|
||||||
<div className="form-group">
|
<div className="form-group">
|
||||||
<label htmlFor="login-new-password">新密码</label>
|
<label htmlFor="login-new-password">{hasPassword ? '新密码' : '设置密码'}</label>
|
||||||
<input
|
<input
|
||||||
type="password"
|
type="password"
|
||||||
id="login-new-password"
|
id="login-new-password"
|
||||||
@@ -113,11 +136,11 @@ function ChangePassword() {
|
|||||||
<button type="submit" disabled={loading} className="password-btn">
|
<button type="submit" disabled={loading} className="password-btn">
|
||||||
{loading ? (
|
{loading ? (
|
||||||
<>
|
<>
|
||||||
<Icon icon="line-md:loading-loop" /> 修改中...
|
<Icon icon="line-md:loading-loop" /> {hasPassword ? '修改中...' : '设置中...'}
|
||||||
</>
|
</>
|
||||||
) : (
|
) : (
|
||||||
<>
|
<>
|
||||||
<Icon icon="solar:check-read-bold" /> 修改密码
|
<Icon icon="solar:check-read-bold" /> {hasPassword ? '修改密码' : '设置密码'}
|
||||||
</>
|
</>
|
||||||
)}
|
)}
|
||||||
</button>
|
</button>
|
||||||
@@ -130,6 +153,7 @@ function ChangePassword() {
|
|||||||
<li>使用包含字母、数字和符号的强密码</li>
|
<li>使用包含字母、数字和符号的强密码</li>
|
||||||
<li>不要使用与其他网站相同的密码</li>
|
<li>不要使用与其他网站相同的密码</li>
|
||||||
<li>定期更换密码可以提高账户安全性</li>
|
<li>定期更换密码可以提高账户安全性</li>
|
||||||
|
{!hasPassword && <li>设置密码后,您可以使用邮箱和密码登录,也可以继续使用第三方账号登录</li>}
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -17,6 +17,7 @@ export interface User {
|
|||||||
username: string;
|
username: string;
|
||||||
avatar?: string;
|
avatar?: string;
|
||||||
is_active: boolean;
|
is_active: boolean;
|
||||||
|
has_password?: boolean;
|
||||||
created_at: string;
|
created_at: string;
|
||||||
updated_at: string;
|
updated_at: string;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user