30 lines
2.2 KiB
TypeScript
30 lines
2.2 KiB
TypeScript
import type { CanonicalAssessmentModel } from '../domain/canonical-model';
|
|
import { createReferenceRecognizer, type ReferenceCatalogSnapshot, type ReferenceRecognitionRun } from '../domain/reference-recognition';
|
|
import { canonicalJson } from '../shared/canonical-json';
|
|
import { RepositoryValidationError } from './repository-errors';
|
|
|
|
export function validateReferenceRun(run: ReferenceRecognitionRun, catalogs: ReferenceCatalogSnapshot[], model: CanonicalAssessmentModel | null): void {
|
|
const hash = /^[a-f0-9]{64}$/;
|
|
if (!model || model.project.id !== run.projectId || model.assessment.id !== run.assessmentId
|
|
|| !model.scanRuns.some(scan => scan.id === run.scanRunId) || run.schemaVersion !== 1
|
|
|| !run.id || !run.recognizerVersion || !hash.test(run.inputSha256) || !Number.isFinite(Date.parse(run.createdAt))
|
|
|| catalogs.length !== 2 || new Set(catalogs.map(catalog => catalog.framework)).size !== 2
|
|
|| catalogs.some(catalog => !hash.test(catalog.sha256) || !catalog.entries.length || !catalog.license)
|
|
|| canonicalJson([...run.catalogHashes].sort()) !== canonicalJson(catalogs.map(catalog => catalog.sha256).sort())) {
|
|
throw new RepositoryValidationError('Ungültiger Referenzlauf oder fremder Scan-/Katalogkontext.');
|
|
}
|
|
const occurrences = model.findingOccurrences.filter(item => item.scanRunId === run.scanRunId);
|
|
const results = new Map(run.results.map(result => [result.occurrenceId, result]));
|
|
const recognize = createReferenceRecognizer(catalogs);
|
|
if (results.size !== occurrences.length || results.size !== run.results.length) throw new RepositoryValidationError('Unvollständiger Referenzlauf.');
|
|
for (const occurrence of occurrences) {
|
|
const result = results.get(occurrence.id);
|
|
const file = model.importFiles.find(item => item.id === occurrence.importFileId);
|
|
if (!result || result.importFileId !== occurrence.importFileId || result.sourceFileSha256 !== file?.sha256
|
|
|| canonicalJson(result.sourcePosition) !== canonicalJson(occurrence.sourcePosition)
|
|
|| canonicalJson(result.references) !== canonicalJson(recognize(occurrence.originalFields))) {
|
|
throw new RepositoryValidationError('Referenzherkunft stimmt nicht mit dem gespeicherten Original überein.');
|
|
}
|
|
}
|
|
}
|