mirror of
https://github.com/iflytek/skillhub.git
synced 2026-09-09 22:31:14 +00:00
fix(security): include csrf token in scan retry
Signed-off-by: XiaoSeS <87064762+XiaoSeS@users.noreply.github.com>
This commit is contained in:
parent
fd932cc160
commit
1b7e679d45
3 changed files with 29 additions and 3 deletions
|
|
@ -232,6 +232,7 @@ class ScanTaskConsumerLoggingTest {
|
|||
ScannerType scannerType,
|
||||
String reason) {
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private static final class TestProducer implements ScanTaskProducer {
|
||||
|
|
|
|||
|
|
@ -12,12 +12,22 @@ import { describe, expect, it, vi } from 'vitest'
|
|||
|
||||
// Capture the options passed to useQuery so we can assert on them.
|
||||
let capturedOptions: Record<string, unknown> | undefined
|
||||
let capturedMutationOptions: Record<string, unknown> | undefined
|
||||
const apiMocks = vi.hoisted(() => ({
|
||||
fetchJson: vi.fn(),
|
||||
getCsrfHeaders: vi.fn(() => ({ 'X-XSRF-TOKEN': 'csrf-token' })),
|
||||
}))
|
||||
|
||||
vi.mock('@tanstack/react-query', () => ({
|
||||
useQuery: (options: Record<string, unknown>) => {
|
||||
capturedOptions = options
|
||||
return { data: undefined, isLoading: false }
|
||||
},
|
||||
useMutation: (options: Record<string, unknown>) => {
|
||||
capturedMutationOptions = options
|
||||
return { mutate: vi.fn(), isPending: false }
|
||||
},
|
||||
useQueryClient: () => ({ invalidateQueries: vi.fn() }),
|
||||
}))
|
||||
|
||||
// Mock fetchJson to avoid actual network calls. The hook's queryFn
|
||||
|
|
@ -30,11 +40,12 @@ vi.mock('@/api/client', () => ({
|
|||
this.status = status
|
||||
}
|
||||
},
|
||||
fetchJson: vi.fn(),
|
||||
fetchJson: apiMocks.fetchJson,
|
||||
getCsrfHeaders: apiMocks.getCsrfHeaders,
|
||||
}))
|
||||
|
||||
// Dynamic import to ensure mocks are established first.
|
||||
const { useSecurityAudits } = await import('./use-security-audit')
|
||||
const { useRetrySecurityScan, useSecurityAudits } = await import('./use-security-audit')
|
||||
|
||||
describe('useSecurityAudits', () => {
|
||||
it('uses the correct query key structure', () => {
|
||||
|
|
@ -78,4 +89,17 @@ describe('useSecurityAudits', () => {
|
|||
|
||||
expect(capturedOptions?.retry).toBe(false)
|
||||
})
|
||||
|
||||
it('sends the CSRF header when retrying a security scan', async () => {
|
||||
apiMocks.fetchJson.mockResolvedValueOnce({ status: 'SCANNING' })
|
||||
useRetrySecurityScan(42, 100)
|
||||
|
||||
await (capturedMutationOptions?.mutationFn as () => Promise<unknown>)()
|
||||
|
||||
expect(apiMocks.getCsrfHeaders).toHaveBeenCalledOnce()
|
||||
expect(apiMocks.fetchJson).toHaveBeenCalledWith(
|
||||
'/api/v1/skills/42/versions/100/security-audit/retry',
|
||||
{ method: 'POST', headers: { 'X-XSRF-TOKEN': 'csrf-token' } },
|
||||
)
|
||||
})
|
||||
})
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
import { useMutation, useQuery, useQueryClient } from '@tanstack/react-query'
|
||||
import { ApiError, fetchJson } from '@/api/client'
|
||||
import { ApiError, fetchJson, getCsrfHeaders } from '@/api/client'
|
||||
import type { SecurityAuditRecord } from './types'
|
||||
|
||||
async function fetchSecurityAudits(
|
||||
|
|
@ -37,6 +37,7 @@ export function useRetrySecurityScan(skillId: number, versionId: number) {
|
|||
return useMutation({
|
||||
mutationFn: () => fetchJson(`/api/v1/skills/${skillId}/versions/${versionId}/security-audit/retry`, {
|
||||
method: 'POST',
|
||||
headers: getCsrfHeaders(),
|
||||
}),
|
||||
onSuccess: () => {
|
||||
void queryClient.invalidateQueries({ queryKey: ['security-audits', skillId, versionId] })
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue