generated from Dicken/dickendock
78 lines
2.4 KiB
TypeScript
78 lines
2.4 KiB
TypeScript
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);
|
|
}
|
|
|
|
export function getApisForService(serviceId: string): DetectedApiEntry[] {
|
|
return db.select().from(detectedApis).where(eq(detectedApis.serviceId, serviceId)).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.
|
|
*
|
|
* Liefert zusätzlich `added` zurück: die Einträge, die VORHER noch nicht
|
|
* gespeichert waren (nach Pfad+Typ verglichen) - damit der Scanner auf der
|
|
* Scanner-Seite nach dem ersten Mal nur noch NEUE/geänderte Funde anzeigen
|
|
* kann, statt bei jedem erneuten Scan die komplette (meist unveränderte)
|
|
* Liste erneut runterzurattern. Die vollständige Liste bleibt jederzeit
|
|
* unter Admin -> APIs einsehbar.
|
|
*/
|
|
export function replaceApisForService(
|
|
serviceId: string,
|
|
found: { path: string; type: string; status: number }[]
|
|
): { saved: DetectedApiEntry[]; added: DetectedApiEntry[] } {
|
|
const before = getApisForService(serviceId);
|
|
const beforeKeys = new Set(before.map((e) => `${e.path}::${e.type}`));
|
|
|
|
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();
|
|
}
|
|
|
|
const saved = rows.map(mapRow);
|
|
const added = saved.filter((e) => !beforeKeys.has(`${e.path}::${e.type}`));
|
|
|
|
return { saved, added };
|
|
}
|
|
|
|
export function deleteApisForService(serviceId: string): void {
|
|
db.delete(detectedApis).where(eq(detectedApis.serviceId, serviceId)).run();
|
|
}
|