fix(backend): улучшить обработку хранилищ доверия для сертификатов

This commit is contained in:
Denozordec
2026-05-12 20:40:56 +07:00
parent bc01da1708
commit b51d979a1c
2 changed files with 41 additions and 3 deletions
+7 -2
View File
@@ -294,6 +294,10 @@ export async function issueCertificateWithCloudflareDns(params: {
const serverIp = await resolveServerPublicIp(params.server, clientRos) const serverIp = await resolveServerPublicIp(params.server, clientRos)
await syncCertificateDomainRecords(token, domains, serverIp, settings.defaultZoneId) await syncCertificateDomainRecords(token, domains, serverIp, settings.defaultZoneId)
const trustStores = params.trustStore.filter(Boolean)
const effectiveTrustStores = trustStores.length > 0 ? trustStores : ["www", "api"]
const trustStoreCsv = effectiveTrustStores.join(",")
params.onStep?.("import") params.onStep?.("import")
const safeBase = params.certName.replace(/[^a-zA-Z0-9._-]+/g, "_") const safeBase = params.certName.replace(/[^a-zA-Z0-9._-]+/g, "_")
const certFile = `${safeBase}.crt` const certFile = `${safeBase}.crt`
@@ -304,14 +308,15 @@ export async function issueCertificateWithCloudflareDns(params: {
fileName: certRouterFile, fileName: certRouterFile,
name: params.certName, name: params.certName,
trusted: true, trusted: true,
trustStore: params.trustStore.join(","), trustStore: trustStoreCsv,
}) })
await clientRos.importCertificate({ await clientRos.importCertificate({
fileName: keyRouterFile, fileName: keyRouterFile,
name: params.certName, name: params.certName,
trusted: true, trusted: true,
trustStore: params.trustStore.join(","), trustStore: trustStoreCsv,
}) })
await clientRos.applyCertificateToServices(params.certName, effectiveTrustStores)
} finally { } finally {
params.onStep?.("cleanup") params.onStep?.("cleanup")
for (const item of txtCleanups) { for (const item of txtCleanups) {
+34 -1
View File
@@ -565,12 +565,45 @@ export class MikrotikClient {
"file-name": params.fileName, "file-name": params.fileName,
name: params.name, name: params.name,
trusted: params.trusted === false ? "no" : "yes", trusted: params.trusted === false ? "no" : "yes",
"trust-store": params.trustStore?.trim() || "www,api",
} }
if (params.trustStore?.trim()) body["trust-store"] = params.trustStore.trim()
if (params.passphrase?.trim()) body.passphrase = params.passphrase.trim() if (params.passphrase?.trim()) body.passphrase = params.passphrase.trim()
return this.post("/certificate/import", body, 60_000) return this.post("/certificate/import", body, 60_000)
} }
async applyCertificateToServices(
certName: string,
trustStores: string[] = ["www", "api"],
): Promise<void> {
const stores = trustStores.length > 0 ? trustStores : ["www", "api"]
const targets: string[] = []
if (stores.includes("www")) targets.push("www-ssl")
if (stores.includes("api")) targets.push("api-ssl")
if (targets.length === 0) targets.push("www-ssl")
const body = {
disabled: "no",
certificate: certName,
}
for (const serviceName of targets) {
await this.patchIpService(serviceName, body)
}
}
private async patchIpService(serviceName: string, body: Record<string, string>): Promise<void> {
const pathByName = `/ip/service/${encodeURIComponent(serviceName)}`
try {
await this.patch(pathByName, body, 30_000)
return
} catch {
const services = await this.get<Array<Record<string, string | undefined>>>("/ip/service")
const row = services.find((service) => String(service.name ?? "") === serviceName)
const id = row?.[".id"]
if (!id) throw new Error(`Сервис RouterOS ${serviceName} не найден`)
await this.patch(`/ip/service/${encodeURIComponent(id)}`, body, 30_000)
}
}
async exportConfigScript(): Promise<string> { async exportConfigScript(): Promise<string> {
const raw = await this.post<unknown>("/console/export", {}, 30_000) const raw = await this.post<unknown>("/console/export", {}, 30_000)