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