round26: Ping vor Portscan, Liste neuer Dienste, Suchmaschinen-Integration (OpenSearch), API-Scanner

This commit is contained in:
2026-07-24 02:21:58 +02:00
parent 458f58af6f
commit 0fc063b2a2
17 changed files with 507 additions and 4 deletions

View File

@@ -0,0 +1,60 @@
import { randomUUID } from "node:crypto";
import { eq } from "drizzle-orm";
import { db } from "../client.js";
import { detectedApis } from "../schema.js";
export interface DetectedApiEntry {
id: string;
serviceId: string;
path: string;
type: string;
status: number;
detectedAt: string;
}
function mapRow(row: typeof detectedApis.$inferSelect): DetectedApiEntry {
return {
id: row.id,
serviceId: row.serviceId,
path: row.path,
type: row.type,
status: row.status,
detectedAt: row.detectedAt,
};
}
export function listDetectedApis(): DetectedApiEntry[] {
return db.select().from(detectedApis).all().map(mapRow);
}
/**
* Ersetzt die gespeicherten API-Funde eines Dienstes komplett durch die
* neuen Ergebnisse eines Scan-Laufs - kein Anhäufen von veralteten
* Einträgen, wenn sich z. B. der API-Pfad einer Software mal ändert.
*/
export function replaceApisForService(
serviceId: string,
found: { path: string; type: string; status: number }[]
): DetectedApiEntry[] {
db.delete(detectedApis).where(eq(detectedApis.serviceId, serviceId)).run();
const timestamp = new Date().toISOString();
const rows = found.map((f) => ({
id: randomUUID(),
serviceId,
path: f.path,
type: f.type,
status: f.status,
detectedAt: timestamp,
}));
if (rows.length > 0) {
db.insert(detectedApis).values(rows).run();
}
return rows.map(mapRow);
}
export function deleteApisForService(serviceId: string): void {
db.delete(detectedApis).where(eq(detectedApis.serviceId, serviceId)).run();
}