diff --git a/backend/src/services/certificate-parse.ts b/backend/src/services/certificate-parse.ts index fe0b950..3b3f65e 100644 --- a/backend/src/services/certificate-parse.ts +++ b/backend/src/services/certificate-parse.ts @@ -53,6 +53,11 @@ export function mapRosCertificateRow( const name = (row.name ?? "").trim() if (!name) return null + const rosId = (row[".id"] ?? "").trim() + const fingerprint = (row.fingerprint ?? "").trim() + const serialNumber = (row["serial-number"] ?? "").trim() + const stableId = rosId || fingerprint || serialNumber || name + const { revoked, expired: expiredFlag } = parseFlags(row.flags) const validFrom = parseRosDate(row["invalid-before"]) const validUntil = parseRosDate(row["invalid-after"]) @@ -68,7 +73,7 @@ export function mapRosCertificateRow( const keySize = Number.parseInt(String(row["key-size"] ?? "0"), 10) return { - id: `${serverId}:${name}`, + id: `${serverId}:${stableId}`, name, serverId: String(serverId), serverName, @@ -91,7 +96,17 @@ export function mapRosCertificates( serverName: string, rows: RosCertificateRow[], ): CertificateDto[] { + const seen = new Set() return rows .map((row) => mapRosCertificateRow(serverId, serverName, row)) .filter((row): row is CertificateDto => row != null) + .map((cert, index) => { + if (!seen.has(cert.id)) { + seen.add(cert.id) + return cert + } + const uniqueId = `${cert.id}#${index}` + seen.add(uniqueId) + return { ...cert, id: uniqueId } + }) }