fix: restore security hardening compatibility and validation

Restore authorized rule reveal, explicit full HTTP capture and retention, video task business fields, and valid payment URLs. Add opt-in credential preservation for trusted recovery, fix frontend type contracts and async races, and eliminate PostgreSQL test fixture resource leaks. Document audit coverage and successful fmt and CI-scoped Clippy checks.
This commit is contained in:
elky
2026-09-07 21:14:27 +08:00
parent a5c3699ae9
commit a90d564931
191 changed files with 6785 additions and 1643 deletions
@@ -744,7 +744,7 @@ async function executeAction(actionOverride?: PoolBatchActionValue): Promise<voi
const result = await batchActionPoolKeys(props.providerId, {
key_ids: batch,
action: selectedAction.value as 'enable' | 'disable' | 'clear_proxy' | 'set_proxy' | 'update_settings',
...(payload ? { payload } : {}),
...(payload ? { payload: { ...payload } } : {}),
})
successCount += result.affected
} catch (err) {
@@ -708,7 +708,7 @@ async function handleSave() {
try {
const latestProvider = await getProvider(providerId)
if (!props.modelValue || props.providerId !== providerId || dialogRevision !== revision) return
const latestAdvanced = (latestProvider as Record<string, unknown>).pool_advanced
const latestAdvanced = latestProvider.pool_advanced
const existingPoolAdvanced = mergePoolAdvancedPatch(latestAdvanced, {})
const latestScoreRules = typeof existingPoolAdvanced.score_rules === 'object'
&& existingPoolAdvanced.score_rules !== null
@@ -192,7 +192,7 @@ const chartWidth = 640
const chartHeight = 220
const yTickRatios = [0, 0.25, 0.5, 0.75, 1]
const latest = computed(() => props.samples.at(-1) ?? null)
const latest = computed(() => props.samples[props.samples.length - 1] ?? null)
const maxChartValue = computed(() => {
const maxValue = props.samples.reduce((max, sample) => {
@@ -108,7 +108,7 @@ function metricForGroup(
const cycleMetricRows = computed(() => {
const smallGroup = props.cycleGroups.length > 1 ? props.cycleGroups[0] : undefined
const largeGroup = props.cycleGroups.at(-1)
const largeGroup = props.cycleGroups[props.cycleGroups.length - 1]
if (!largeGroup) return []
return CYCLE_METRIC_KEYS.map((key) => {
@@ -92,7 +92,7 @@
:title="action.title"
@pointerenter="action.key === 'viewProvider' && emit('prefetchProvider')"
@focus="action.key === 'viewProvider' && emit('prefetchProvider')"
@click="emit(action.event)"
@click="triggerAction(action.event)"
>
<component
:is="action.icon"
@@ -253,7 +253,7 @@
:title="action.title"
@pointerenter="action.key === 'viewProvider' && emit('prefetchProvider')"
@focus="action.key === 'viewProvider' && emit('prefetchProvider')"
@click="emit(action.event)"
@click="triggerAction(action.event)"
>
<component
:is="action.icon"
@@ -413,6 +413,17 @@ const emit = defineEmits<{
refresh: []
}>()
function triggerAction(event: HeaderActionEvent) {
const handlers = {
import: () => emit('import'),
scheduling: () => emit('scheduling'),
viewProvider: () => emit('viewProvider'),
demandMetrics: () => emit('demandMetrics'),
advanced: () => emit('advanced'),
}
handlers[event]()
}
const { legacyT } = useI18n()
const providerModel = computed({
@@ -880,7 +880,7 @@ async function handleSave() {
const latestProvider = await getProvider(providerId)
if (!props.modelValue || props.providerId !== providerId || dialogRevision !== revision) return
const latestAdvanced = (latestProvider as Record<string, unknown>).pool_advanced
const latestAdvanced = latestProvider.pool_advanced
const mergedAdvanced = mergePoolAdvancedPatch(latestAdvanced, {
scheduling_presets: schedulingPresets,
})
@@ -1,6 +1,7 @@
import { beforeEach, describe, expect, it } from 'vitest'
import {
POOL_MANAGEMENT_VIEW_STORAGE_KEY,
buildPoolManagementQueryPatch,
readPoolManagementViewState,
resolvePoolManagementPageAfterLoad,
@@ -71,8 +72,9 @@ describe('poolManagementState', () => {
})
it('falls back to storage when query is missing', () => {
writePoolManagementViewState(
{
storage.setItem(
POOL_MANAGEMENT_VIEW_STORAGE_KEY,
JSON.stringify({
providerId: 'provider-c',
search: 'stored only',
status: 'active',
@@ -81,8 +83,7 @@ describe('poolManagementState', () => {
sortBy: 'last_used_at',
sortOrder: 'asc',
statsMode: 'account_total',
},
storage,
}),
)
const state = readPoolManagementViewState({}, storage)
@@ -23,7 +23,8 @@ export function mergePoolKeyQuotaSnapshots(
...(quotaSnapshot ? {
quota_updated_at: quotaSnapshot.updated_at ?? quotaSnapshot.observed_at ?? key.quota_updated_at ?? null,
status_snapshot: {
...(key.status_snapshot ?? {}),
oauth: key.status_snapshot?.oauth ?? { code: 'none' },
account: key.status_snapshot?.account ?? { code: 'unknown', blocked: false },
quota: quotaSnapshot,
},
} : {}),