Assessor_2.0/outputs/dummy-work-export-audit.mjs

50 lines
3.4 KiB
JavaScript

// Opt-in, read-only check of the explicitly authorized Dummy workspace.
// No source content is persisted; all HTTP calls are GET and project-scoped.
import { createServer } from 'vite';
const projectId = 'project-7cbcb7ad';
const base = 'http://127.0.0.1:4173/api/v1';
const get = async path => {
const response = await fetch(base + path);
if (!response.ok) throw new Error(`HTTP ${response.status}`);
return response.json();
};
if ((await get(`/projects/${projectId}`)).name !== 'Dummy') throw new Error('Not Dummy');
const assessments = await get(`/projects/${projectId}/assessments`);
const allowed = new Set(assessments.map(item => item.id));
const reader = {
listProjectAssessments: async id => { if (id !== projectId) throw new Error('Wrong scope'); return assessments; },
loadAssessmentModel: async id => {
if (!allowed.has(id)) throw new Error('Wrong assessment');
const model = await get(`/assessments/${encodeURIComponent(id)}/model`);
if (model.project.id !== projectId) throw new Error('Wrong model');
return model;
},
queryUnifiedResults: async query => {
if (query.projectId !== projectId) throw new Error('Wrong result scope');
const params = new URLSearchParams();
for (const [key, value] of Object.entries(query)) if (value !== undefined) params.set(key, Array.isArray(value) ? value.join(',') : String(value));
return get(`/results?${params}`);
},
listPolicyEvaluations: () => get(`/projects/${projectId}/policy-evaluations`),
getPolicyAnalysisOverview: () => get(`/projects/${projectId}/policy-analysis-overview`),
// Public reference data, only IDs actually referenced by Dummy's evaluations.
listMicrosoftSecurityBaselineAnalyses: id => get(`/reference-data/microsoft-security-baselines/${encodeURIComponent(id)}/analysis`)
};
const vite = await createServer({ configFile: false, appType: 'custom', server: { middlewareMode: true, hmr: false, watch: null } });
try {
const { loadCanonicalProjectWorkspace } = await vite.ssrLoadModule('/src/features/project-import/load-canonical-project-workspace.ts');
const { toolIdForRecord } = await vite.ssrLoadModule('/src/importers/status-normalization.ts');
const { dataset } = await loadCanonicalProjectWorkspace(reader, projectId);
const sheet = dataset.sheets.find(item => item.isProjectSheet) ?? dataset.sheets[0];
const groups = Map.groupBy(sheet.analysis.records, record => toolIdForRecord(record, sheet.toolId ?? dataset.profileId));
console.log(JSON.stringify({ assessments: assessments.length, sheets: dataset.sheets.length,
groups: [...groups].map(([tool, records]) => ({ tool, count: records.length,
fields: process.argv.includes('--inspect') ? [...new Set(records.flatMap(record => record.fields.filter(field => field.value).map(field => field.label)))] : undefined,
sample: process.argv.includes('--inspect') && tool !== 'group-policy' ? records.find(record => record.fields.some(field => /^(Status|Result)$/.test(field.label) && /fail/i.test(field.value)))?.fields.filter(field => /^(Description|Remediation|Advised solution|Result|Result message|Details|Results|Notes)$/.test(field.label) && field.value).map(field => ({ label: field.label, value: field.value.slice(0, 1300) })) : undefined
})) }, null, 2));
if (process.argv.includes('--verify')) {
const { verify } = await import('./dummy-work-export-verification.mjs');
await verify(vite, dataset, sheet);
}
} finally { await vite.close(); }