mirror of
https://github.com/fawney19/Aether.git
synced 2026-09-02 09:20:22 +08:00
feat(auth): 添加 Turnstile 注册防护
This commit is contained in:
45
frontend/src/api/__tests__/auth-turnstile.spec.ts
Normal file
45
frontend/src/api/__tests__/auth-turnstile.spec.ts
Normal file
@@ -0,0 +1,45 @@
|
||||
import { beforeEach, describe, expect, it, vi } from 'vitest'
|
||||
|
||||
const { postMock } = vi.hoisted(() => ({
|
||||
postMock: vi.fn(),
|
||||
}))
|
||||
|
||||
vi.mock('@/api/client', () => ({
|
||||
default: {
|
||||
post: postMock,
|
||||
},
|
||||
}))
|
||||
|
||||
import { authApi } from '@/api/auth'
|
||||
|
||||
describe('authApi turnstile payloads', () => {
|
||||
beforeEach(() => {
|
||||
postMock.mockReset()
|
||||
postMock.mockResolvedValue({ data: {} })
|
||||
})
|
||||
|
||||
it('includes turnstile token when sending email verification code', async () => {
|
||||
await authApi.sendVerificationCode('alice@example.com', 'turnstile-token')
|
||||
|
||||
expect(postMock).toHaveBeenCalledWith('/api/auth/send-verification-code', {
|
||||
email: 'alice@example.com',
|
||||
turnstile_token: 'turnstile-token',
|
||||
})
|
||||
})
|
||||
|
||||
it('includes turnstile token when registering', async () => {
|
||||
await authApi.register({
|
||||
email: 'alice@example.com',
|
||||
username: 'alice',
|
||||
password: 'secret123',
|
||||
turnstile_token: 'turnstile-token',
|
||||
})
|
||||
|
||||
expect(postMock).toHaveBeenCalledWith('/api/auth/register', {
|
||||
email: 'alice@example.com',
|
||||
username: 'alice',
|
||||
password: 'secret123',
|
||||
turnstile_token: 'turnstile-token',
|
||||
})
|
||||
})
|
||||
})
|
||||
@@ -755,13 +755,13 @@ export const adminApi = {
|
||||
async getSystemConfig(
|
||||
key: string,
|
||||
options: { cacheTtlMs?: number } = {},
|
||||
): Promise<{ key: string; value: unknown }> {
|
||||
): Promise<{ key: string; value: unknown; is_set?: boolean }> {
|
||||
const cacheTtlMs = options.cacheTtlMs ?? 0
|
||||
const cacheKey = buildCacheKey('admin:system:config', { key })
|
||||
return cachedRequest(
|
||||
cacheKey,
|
||||
async () => {
|
||||
const response = await apiClient.get<{ key: string; value: unknown }>(
|
||||
const response = await apiClient.get<{ key: string; value: unknown; is_set?: boolean }>(
|
||||
`/api/admin/system/configs/${key}`
|
||||
)
|
||||
return response.data
|
||||
|
||||
@@ -33,6 +33,7 @@ export interface UserStats {
|
||||
|
||||
export interface SendVerificationCodeRequest {
|
||||
email: string
|
||||
turnstile_token?: string
|
||||
}
|
||||
|
||||
export interface SendVerificationCodeResponse {
|
||||
@@ -67,6 +68,7 @@ export interface RegisterRequest {
|
||||
email?: string
|
||||
username: string
|
||||
password: string
|
||||
turnstile_token?: string
|
||||
}
|
||||
|
||||
export interface RegisterResponse {
|
||||
@@ -81,6 +83,9 @@ export interface RegistrationSettingsResponse {
|
||||
require_email_verification: boolean
|
||||
email_configured: boolean
|
||||
password_policy_level: string
|
||||
turnstile_enabled?: boolean
|
||||
turnstile_site_key?: string | null
|
||||
turnstile_required_actions?: string[]
|
||||
}
|
||||
|
||||
export interface AuthSettingsResponse {
|
||||
@@ -153,10 +158,17 @@ export const authApi = {
|
||||
return response.data
|
||||
},
|
||||
|
||||
async sendVerificationCode(email: string): Promise<SendVerificationCodeResponse> {
|
||||
async sendVerificationCode(
|
||||
email: string,
|
||||
turnstileToken?: string
|
||||
): Promise<SendVerificationCodeResponse> {
|
||||
const payload: SendVerificationCodeRequest = { email }
|
||||
if (turnstileToken) {
|
||||
payload.turnstile_token = turnstileToken
|
||||
}
|
||||
const response = await apiClient.post<SendVerificationCodeResponse>(
|
||||
'/api/auth/send-verification-code',
|
||||
{ email }
|
||||
payload
|
||||
)
|
||||
return response.data
|
||||
},
|
||||
|
||||
Reference in New Issue
Block a user