fix(ipsec): убрать неподдерживаемый параметр при добавлении сертификата

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
DenozordecandCursor committed 2026-09-12 22:06:27 +07:00
1 parent 3eb75ea0b8
commit 11ae7593f4
3 files changed
+27 -1

No files matched your search

+20 -1
View File
@@ -415,6 +415,13 @@ export function encodeRosId(rosId: string): string {
// ── MikrotikClient ─────────────────────────────────────────────────────────────
/** Имя параметра из ошибки RouterOS `unknown parameter <name>` (400) — для деградации запроса. */
function unknownParameterName(error: MikrotikError): string | undefined {
if (error.statusCode !== 400) return undefined
const match = error.body.match(/unknown parameter\s+"?([A-Za-z0-9_-]+)"?/i)
return match?.[1]
}
export class MikrotikClient {
constructor(private readonly params: MikrotikConnectParams) {}
@@ -691,7 +698,19 @@ export class MikrotikClient {
/** Создание ключевой пары + заявки: /certificate add (поля common-name, key-size, key-usage…). */
async addCertificate(body: Record<string, string>, timeoutMs = 30_000): Promise<unknown> {
return this.post("/certificate/add", body, timeoutMs)
// Набор параметров `/certificate/add` зависит от версии RouterOS (напр. `comment`).
// Деградируем: при 400 «unknown parameter X» убираем X из тела и повторяем.
const payload: Record<string, string> = { ...body }
for (let attempt = 0; attempt < 4; attempt += 1) {
try {
return await this.post("/certificate/add", payload, timeoutMs)
} catch (error) {
const param = error instanceof MikrotikError ? unknownParameterName(error) : undefined
if (!param || !(param in payload)) throw error
delete payload[param]
}
}
throw new Error(`RouterOS: не удалось добавить сертификат (несовместимые параметры): ${Object.keys(body).join(", ")}`)
}
/** Подпись сертификата локальным CA; sign небыстрый — увеличенный таймаут. */