mirror of
https://github.com/fawney19/Aether.git
synced 2026-01-08 10:42:29 +08:00
- 重构: 将 verification 模块重命名为 email,目录结构更清晰 - 新增: 独立的邮件配置管理页面 (EmailSettings.vue) - 新增: 邮件模板管理功能(支持自定义 HTML 模板和预览) - 新增: 查询验证状态 API,支持页面刷新后恢复验证流程 - 新增: 注册邮箱后缀白名单/黑名单限制功能 - 修复: 统一密码最小长度为 6 位(前后端一致) - 修复: SMTP 连接添加 30 秒超时配置,防止 worker 挂起 - 修复: 邮件模板变量添加 HTML 转义,防止 XSS - 修复: 验证状态清除改为 db.commit 后执行,避免竞态条件 - 优化: RegisterDialog 重写验证码输入组件,提升用户体验 - 优化: Input 组件支持 disableAutofill 属性
178 lines
4.5 KiB
TypeScript
178 lines
4.5 KiB
TypeScript
import apiClient from './client'
|
|
import { log } from '@/utils/logger'
|
|
|
|
export interface LoginRequest {
|
|
email: string
|
|
password: string
|
|
}
|
|
|
|
export interface LoginResponse {
|
|
access_token: string
|
|
refresh_token?: string
|
|
token_type?: string
|
|
expires_in?: number
|
|
user_id?: string // UUID
|
|
email?: string
|
|
username?: string
|
|
role?: string
|
|
}
|
|
|
|
export interface UserPreferences {
|
|
theme?: 'light' | 'dark' | 'auto'
|
|
language?: string
|
|
notifications_enabled?: boolean
|
|
[key: string]: unknown // 允许扩展其他偏好设置
|
|
}
|
|
|
|
export interface UserStats {
|
|
total_requests?: number
|
|
total_cost?: number
|
|
last_request_at?: string
|
|
[key: string]: unknown // 允许扩展其他统计数据
|
|
}
|
|
|
|
export interface SendVerificationCodeRequest {
|
|
email: string
|
|
}
|
|
|
|
export interface SendVerificationCodeResponse {
|
|
message: string
|
|
success: boolean
|
|
expire_minutes?: number
|
|
}
|
|
|
|
export interface VerifyEmailRequest {
|
|
email: string
|
|
code: string
|
|
}
|
|
|
|
export interface VerifyEmailResponse {
|
|
message: string
|
|
success: boolean
|
|
}
|
|
|
|
export interface VerificationStatusRequest {
|
|
email: string
|
|
}
|
|
|
|
export interface VerificationStatusResponse {
|
|
email: string
|
|
has_pending_code: boolean
|
|
is_verified: boolean
|
|
cooldown_remaining: number | null
|
|
code_expires_in: number | null
|
|
}
|
|
|
|
export interface RegisterRequest {
|
|
email: string
|
|
username: string
|
|
password: string
|
|
}
|
|
|
|
export interface RegisterResponse {
|
|
user_id: string
|
|
email: string
|
|
username: string
|
|
message: string
|
|
}
|
|
|
|
export interface RegistrationSettingsResponse {
|
|
enable_registration: boolean
|
|
require_email_verification: boolean
|
|
}
|
|
|
|
export interface User {
|
|
id: string // UUID
|
|
username: string
|
|
email?: string
|
|
role: string // 'admin' or 'user'
|
|
is_active: boolean
|
|
quota_usd?: number | null
|
|
used_usd?: number
|
|
total_usd?: number
|
|
allowed_providers?: string[] | null // 允许使用的提供商 ID 列表
|
|
allowed_endpoints?: string[] | null // 允许使用的端点 ID 列表
|
|
allowed_models?: string[] | null // 允许使用的模型名称列表
|
|
created_at: string
|
|
last_login_at?: string
|
|
preferences?: UserPreferences
|
|
stats?: UserStats
|
|
}
|
|
|
|
export const authApi = {
|
|
async login(credentials: LoginRequest): Promise<LoginResponse> {
|
|
const response = await apiClient.post<LoginResponse>('/api/auth/login', credentials)
|
|
apiClient.setToken(response.data.access_token)
|
|
// 后端暂时没有返回 refresh_token
|
|
if (response.data.refresh_token) {
|
|
localStorage.setItem('refresh_token', response.data.refresh_token)
|
|
}
|
|
return response.data
|
|
},
|
|
|
|
async logout() {
|
|
try {
|
|
// 调用后端登出接口,将 Token 加入黑名单
|
|
await apiClient.post('/api/auth/logout', {})
|
|
} catch (error) {
|
|
// 即使后端登出失败,也要清除本地认证信息
|
|
log.warn('后端登出失败,仅清除本地认证信息:', error)
|
|
} finally {
|
|
// 清除本地认证信息
|
|
apiClient.clearAuth()
|
|
}
|
|
},
|
|
|
|
async getCurrentUser(): Promise<User> {
|
|
const response = await apiClient.get<User>('/api/users/me')
|
|
return response.data
|
|
},
|
|
|
|
async refreshToken(refreshToken: string): Promise<LoginResponse> {
|
|
const response = await apiClient.post<LoginResponse>('/api/auth/refresh', {
|
|
refresh_token: refreshToken
|
|
})
|
|
apiClient.setToken(response.data.access_token)
|
|
if (response.data.refresh_token) {
|
|
localStorage.setItem('refresh_token', response.data.refresh_token)
|
|
}
|
|
return response.data
|
|
},
|
|
|
|
async sendVerificationCode(email: string): Promise<SendVerificationCodeResponse> {
|
|
const response = await apiClient.post<SendVerificationCodeResponse>(
|
|
'/api/auth/send-verification-code',
|
|
{ email }
|
|
)
|
|
return response.data
|
|
},
|
|
|
|
async verifyEmail(email: string, code: string): Promise<VerifyEmailResponse> {
|
|
const response = await apiClient.post<VerifyEmailResponse>(
|
|
'/api/auth/verify-email',
|
|
{ email, code }
|
|
)
|
|
return response.data
|
|
},
|
|
|
|
async register(data: RegisterRequest): Promise<RegisterResponse> {
|
|
const response = await apiClient.post<RegisterResponse>('/api/auth/register', data)
|
|
return response.data
|
|
},
|
|
|
|
async getRegistrationSettings(): Promise<RegistrationSettingsResponse> {
|
|
const response = await apiClient.get<RegistrationSettingsResponse>(
|
|
'/api/auth/registration-settings'
|
|
)
|
|
return response.data
|
|
},
|
|
|
|
async getVerificationStatus(email: string): Promise<VerificationStatusResponse> {
|
|
const response = await apiClient.post<VerificationStatusResponse>(
|
|
'/api/auth/verification-status',
|
|
{ email }
|
|
)
|
|
return response.data
|
|
}
|
|
}
|