mirror of
https://github.com/fawney19/Aether.git
synced 2026-10-07 09:57:47 +08:00
feat(providers): expand OAuth account management
Add Claude Code manual and cookie authorization, including redacted batch tasks. Harden OAuth imports, duplicate replacement, provider dialogs, and related account-management tests.
This commit is contained in:
@@ -0,0 +1,68 @@
|
||||
import { beforeEach, describe, expect, it, vi } from 'vitest'
|
||||
|
||||
vi.mock('@/config/demo', () => ({
|
||||
isDemoMode: () => true,
|
||||
DEMO_ACCOUNTS: {
|
||||
admin: { email: '[email protected]', password: 'demo123' },
|
||||
user: { email: '[email protected]', password: 'demo123' },
|
||||
},
|
||||
}))
|
||||
|
||||
import { handleMockRequest, setMockUserToken } from '../handler'
|
||||
|
||||
describe('Claude Cookie authorization demo contracts', () => {
|
||||
beforeEach(() => {
|
||||
setMockUserToken('demo-access-token-admin')
|
||||
})
|
||||
|
||||
it('keeps the single Cookie authorization response compatible', async () => {
|
||||
const response = await handleMockRequest({
|
||||
method: 'POST',
|
||||
url: '/api/admin/provider-oauth/providers/provider-claude/cookie-authorize',
|
||||
data: JSON.stringify({ cookie: 'sessionKey=single-secret' }),
|
||||
})
|
||||
|
||||
expect(response?.data).toMatchObject({
|
||||
provider_type: 'claude_code',
|
||||
has_refresh_token: true,
|
||||
})
|
||||
expect(JSON.stringify(response?.data)).not.toContain('single-secret')
|
||||
})
|
||||
|
||||
it('starts and reads a Cookie batch task without returning Cookie values', async () => {
|
||||
const startResponse = await handleMockRequest({
|
||||
method: 'POST',
|
||||
url: '/api/admin/provider-oauth/providers/provider-claude/cookie-authorize/tasks',
|
||||
data: JSON.stringify({
|
||||
cookies: ['sessionKey=success-secret', 'sessionKey=mock-fail-secret'],
|
||||
}),
|
||||
})
|
||||
const start = startResponse?.data as { task_id: string }
|
||||
|
||||
expect(startResponse?.data).toMatchObject({
|
||||
import_kind: 'cookie_authorize',
|
||||
status: 'submitted',
|
||||
total: 2,
|
||||
processed: 0,
|
||||
})
|
||||
|
||||
const statusResponse = await handleMockRequest({
|
||||
method: 'GET',
|
||||
url: `/api/admin/provider-oauth/providers/provider-claude/cookie-authorize/tasks/${start.task_id}`,
|
||||
})
|
||||
|
||||
expect(statusResponse?.data).toMatchObject({
|
||||
task_id: start.task_id,
|
||||
provider_id: 'provider-claude',
|
||||
provider_type: 'claude_code',
|
||||
import_kind: 'cookie_authorize',
|
||||
status: 'completed',
|
||||
total: 2,
|
||||
success: 1,
|
||||
failed: 1,
|
||||
error_samples: [{ index: 1, status: 'error' }],
|
||||
})
|
||||
expect(JSON.stringify(statusResponse?.data)).not.toContain('success-secret')
|
||||
expect(JSON.stringify(statusResponse?.data)).not.toContain('mock-fail-secret')
|
||||
})
|
||||
})
|
||||
@@ -3100,6 +3100,85 @@ registerDynamicRoute('POST', '/api/admin/provider-oauth/providers/:providerId/co
|
||||
})
|
||||
})
|
||||
|
||||
const mockClaudeCookieAuthorizeTasks = new Map<string, Record<string, unknown>>()
|
||||
let mockClaudeCookieAuthorizeTaskSequence = 0
|
||||
|
||||
registerDynamicRoute('POST', '/api/admin/provider-oauth/providers/:providerId/cookie-authorize/tasks', async (config, params) => {
|
||||
await delay()
|
||||
requireAdmin()
|
||||
const body = JSON.parse(config.data || '{}')
|
||||
const cookies = Array.isArray(body.cookies)
|
||||
? body.cookies.filter((cookie: unknown): cookie is string => typeof cookie === 'string' && cookie.trim().length > 0)
|
||||
: []
|
||||
const errorSamples = cookies.flatMap((cookie: string, index: number) => (
|
||||
cookie.includes('mock-fail')
|
||||
? [{ index, status: 'error', error: '演示模式:Cookie 授权失败', replaced: false }]
|
||||
: []
|
||||
))
|
||||
const failed = errorSamples.length
|
||||
const success = cookies.length - failed
|
||||
const now = Math.floor(Date.now() / 1000)
|
||||
const taskId = `claude-cookie-${Date.now()}-${++mockClaudeCookieAuthorizeTaskSequence}`
|
||||
mockClaudeCookieAuthorizeTasks.set(taskId, {
|
||||
task_id: taskId,
|
||||
provider_id: params.providerId,
|
||||
provider_type: 'claude_code',
|
||||
import_kind: 'cookie_authorize',
|
||||
status: 'completed',
|
||||
total: cookies.length,
|
||||
processed: cookies.length,
|
||||
success,
|
||||
failed,
|
||||
created_count: success,
|
||||
replaced_count: 0,
|
||||
progress_percent: 100,
|
||||
message: null,
|
||||
error: null,
|
||||
error_samples: errorSamples,
|
||||
created_at: now,
|
||||
started_at: now,
|
||||
finished_at: now,
|
||||
updated_at: now,
|
||||
})
|
||||
|
||||
return createMockResponse({
|
||||
task_id: taskId,
|
||||
import_kind: 'cookie_authorize',
|
||||
status: 'submitted',
|
||||
total: cookies.length,
|
||||
processed: 0,
|
||||
success: 0,
|
||||
failed: 0,
|
||||
created_count: 0,
|
||||
replaced_count: 0,
|
||||
progress_percent: 0,
|
||||
message: '任务已提交',
|
||||
})
|
||||
})
|
||||
|
||||
registerDynamicRoute('GET', '/api/admin/provider-oauth/providers/:providerId/cookie-authorize/tasks/:taskId', async (_config, params) => {
|
||||
await delay()
|
||||
requireAdmin()
|
||||
const task = mockClaudeCookieAuthorizeTasks.get(params.taskId)
|
||||
if (!task || task.provider_id !== params.providerId) {
|
||||
throw { response: createMockResponse({ detail: 'Cookie 授权任务不存在' }, 404) }
|
||||
}
|
||||
return createMockResponse(task)
|
||||
})
|
||||
|
||||
registerDynamicRoute('POST', '/api/admin/provider-oauth/providers/:providerId/cookie-authorize', async (config, _params) => {
|
||||
await delay()
|
||||
requireAdmin()
|
||||
const body = JSON.parse(config.data || '{}')
|
||||
return createMockResponse({
|
||||
key_id: `key-claude-cookie-${Date.now()}`,
|
||||
provider_type: 'claude_code',
|
||||
expires_at: Math.floor(Date.now() / 1000) + 24 * 3600,
|
||||
has_refresh_token: true,
|
||||
email: body.name ? `${body.name}@demo.dev` : '[email protected]'
|
||||
})
|
||||
})
|
||||
|
||||
registerDynamicRoute('POST', '/api/admin/provider-oauth/providers/:providerId/import-refresh-token', async (config, _params) => {
|
||||
await delay()
|
||||
requireAdmin()
|
||||
|
||||
Reference in New Issue
Block a user