Files
breakpilot-compliance/breakpilot-compliance-sdk/packages/vue/src/composables/useSecurity.ts
Benjamin Boenisch 4435e7ea0a Initial commit: breakpilot-compliance - Compliance SDK Platform
Services: Admin-Compliance, Backend-Compliance,
AI-Compliance-SDK, Consent-SDK, Developer-Portal,
PCA-Platform, DSMS

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-11 23:47:28 +01:00

186 lines
4.8 KiB
TypeScript

/**
* Security composable for SBOM and security scanning
*/
import { computed, type ComputedRef, type Ref, ref } from 'vue'
import { useComplianceStore } from '../plugin'
import type {
SBOM,
SBOMComponent,
SecurityIssue,
Vulnerability,
SecurityScanResult,
} from '@breakpilot/compliance-sdk-types'
export interface UseSecurityReturn {
// SBOM
sbom: ComputedRef<SBOM | null>
components: ComputedRef<SBOMComponent[]>
componentsByCategory: ComputedRef<Record<string, SBOMComponent[]>>
vulnerableComponents: ComputedRef<SBOMComponent[]>
generateSBOM: (source?: string) => Promise<SBOM>
exportSBOM: (format: 'cyclonedx' | 'spdx') => Promise<Blob>
// Security Issues
securityIssues: ComputedRef<SecurityIssue[]>
criticalIssues: ComputedRef<SecurityIssue[]>
openIssues: ComputedRef<SecurityIssue[]>
issuesBySeverity: ComputedRef<Record<string, SecurityIssue[]>>
// Scanning
scan: (options?: ScanOptions) => Promise<SecurityScanResult>
lastScanResult: Ref<SecurityScanResult | null>
isScanning: Ref<boolean>
// Vulnerabilities
vulnerabilities: ComputedRef<Vulnerability[]>
getVulnerabilitiesForComponent: (componentId: string) => Vulnerability[]
// Loading state
isLoading: Ref<boolean>
error: Ref<Error | null>
}
export interface ScanOptions {
tools?: string[]
targetPath?: string
excludePaths?: string[]
}
export function useSecurity(): UseSecurityReturn {
const store = useComplianceStore()
const { state, security } = store
const isLoading = ref(false)
const isScanning = ref(false)
const error = ref<Error | null>(null)
const lastScanResult = ref<SecurityScanResult | null>(null)
// SBOM
const sbom = computed(() => state.sbom)
const components = computed(() => state.sbom?.components || [])
const componentsByCategory = computed(() => {
const comps = state.sbom?.components || []
return comps.reduce(
(acc, comp) => {
const cat = comp.category || 'other'
if (!acc[cat]) acc[cat] = []
acc[cat].push(comp)
return acc
},
{} as Record<string, SBOMComponent[]>
)
})
const vulnerableComponents = computed(() => {
return components.value.filter(c => c.vulnerabilities && c.vulnerabilities.length > 0)
})
const generateSBOM = async (source?: string): Promise<SBOM> => {
isLoading.value = true
error.value = null
try {
return await security.generateSBOM(source)
} catch (err) {
error.value = err instanceof Error ? err : new Error(String(err))
throw err
} finally {
isLoading.value = false
}
}
const exportSBOM = async (format: 'cyclonedx' | 'spdx'): Promise<Blob> => {
isLoading.value = true
error.value = null
try {
return await security.exportSBOM(format)
} catch (err) {
error.value = err instanceof Error ? err : new Error(String(err))
throw err
} finally {
isLoading.value = false
}
}
// Security Issues
const securityIssues = computed(() => state.securityIssues)
const criticalIssues = computed(() =>
state.securityIssues.filter(i => i.severity === 'CRITICAL' || i.severity === 'HIGH')
)
const openIssues = computed(() =>
state.securityIssues.filter(i => i.status === 'OPEN' || i.status === 'IN_PROGRESS')
)
const issuesBySeverity = computed(() => {
return state.securityIssues.reduce(
(acc, issue) => {
if (!acc[issue.severity]) acc[issue.severity] = []
acc[issue.severity].push(issue)
return acc
},
{} as Record<string, SecurityIssue[]>
)
})
// Scanning
const scan = async (options?: ScanOptions): Promise<SecurityScanResult> => {
isScanning.value = true
isLoading.value = true
error.value = null
try {
const result = await security.scan(options)
lastScanResult.value = result
return result
} catch (err) {
error.value = err instanceof Error ? err : new Error(String(err))
throw err
} finally {
isScanning.value = false
isLoading.value = false
}
}
// Vulnerabilities
const vulnerabilities = computed(() => {
const vulns: Vulnerability[] = []
components.value.forEach(comp => {
if (comp.vulnerabilities) {
vulns.push(...comp.vulnerabilities)
}
})
return vulns
})
const getVulnerabilitiesForComponent = (componentId: string): Vulnerability[] => {
const comp = components.value.find(c => c.name === componentId)
return comp?.vulnerabilities || []
}
return {
sbom,
components,
componentsByCategory,
vulnerableComponents,
generateSBOM,
exportSBOM,
securityIssues,
criticalIssues,
openIssues,
issuesBySeverity,
scan,
lastScanResult,
isScanning,
vulnerabilities,
getVulnerabilitiesForComponent,
isLoading,
error,
}
}