feat(mcp): подготовить сервер и доступ к приёмке
This commit is contained in:
commit
bf3d50e1ff
3835 files changed
+537122
No files matched your search
@@ -0,0 +1,105 @@
|
||||
import assert from "node:assert/strict"
|
||||
import { test } from "node:test"
|
||||
import { exportIpsecCertByName, exportIpsecUserCert, type IpsecExistingCertExportOptions } from "./ipsec"
|
||||
|
||||
const base = "https://fixture.example.test"
|
||||
const options: IpsecExistingCertExportOptions = { privateKeyExport: true, caPrivateKeyExport: false, requestKey: "11111111-1111-4111-8111-111111111111" }
|
||||
const passphrase = " synthetic-passphrase "
|
||||
const bundle = { user: "Renamed label", filename: "fixture.p12", contentB64: "YQ==", passphrase }
|
||||
|
||||
test("existing exports reject missing/invalid explicit intent before fetch", async () => {
|
||||
const original = globalThis.fetch
|
||||
let calls = 0
|
||||
globalThis.fetch = async () => { calls++; throw Error("Unexpected fetch") }
|
||||
try {
|
||||
for (const invalid of [undefined, {}, { ...options, privateKeyExport: false }, { ...options, caPrivateKeyExport: undefined }, { ...options, requestKey: "invalid" }, { ...options, requestKey: undefined }, { ...options, extra: true }]) {
|
||||
const intent = invalid as IpsecExistingCertExportOptions
|
||||
await assert.rejects(() => exportIpsecUserCert(base, "1", "identity:*1", passphrase, intent))
|
||||
await assert.rejects(() => exportIpsecCertByName(base, "1", "cert", passphrase, intent))
|
||||
}
|
||||
await assert.rejects(() => exportIpsecUserCert(base, "1", "identity:*1", "short", options))
|
||||
assert.equal(calls, 0)
|
||||
} finally { globalThis.fetch = original }
|
||||
})
|
||||
|
||||
test("client export preserves native identity selector, raw passphrase, flags and caller UUID", async () => {
|
||||
const original = globalThis.fetch
|
||||
let calls = 0
|
||||
globalThis.fetch = async (url, init) => {
|
||||
calls++
|
||||
assert.equal(new URL(String(url)).pathname.endsWith("/identity%3A*1%2F2/cert"), true)
|
||||
assert.equal(init?.method, "POST")
|
||||
const headers = new Headers(init?.headers), body = JSON.parse(String(init?.body))
|
||||
assert.equal(headers.get("Idempotency-Key") === options.requestKey, true)
|
||||
assert.equal(headers.get("Content-Type"), "application/json")
|
||||
// Compare as booleans so assertion failures cannot print private material.
|
||||
assert.equal(body.passphrase === passphrase, true)
|
||||
assert.equal(body.privateKeyExport, true); assert.equal(body.caPrivateKeyExport, false)
|
||||
assert.equal(Object.hasOwn(body, "requestKey"), false); assert.equal(Object.hasOwn(body, "name"), false)
|
||||
return new Response(JSON.stringify(bundle))
|
||||
}
|
||||
try {
|
||||
const result = await exportIpsecUserCert(base, "1", "identity:*1/2", passphrase, options)
|
||||
assert.equal(result.passphrase === passphrase, true); assert.equal(calls, 1)
|
||||
} finally { globalThis.fetch = original }
|
||||
})
|
||||
|
||||
test("by-name export supports client/server/foreign/CA targets and explicit CA intent", async () => {
|
||||
const original = globalThis.fetch
|
||||
let expectedName = "", expectedCa = false, calls = 0
|
||||
globalThis.fetch = async (url, init) => {
|
||||
calls++
|
||||
assert.equal(new URL(String(url)).pathname, "/api/ipsec/certs/1/export")
|
||||
const body = JSON.parse(String(init?.body))
|
||||
assert.equal(body.name === expectedName, true); assert.equal(body.passphrase === passphrase, true)
|
||||
assert.equal(body.privateKeyExport, true); assert.equal(body.caPrivateKeyExport, expectedCa)
|
||||
assert.equal(new Headers(init?.headers).get("Idempotency-Key") === options.requestKey, true)
|
||||
return new Response(JSON.stringify(bundle))
|
||||
}
|
||||
try {
|
||||
for (const [name, ca] of [["client", false], ["server", false], ["foreign", false], ["ca", true]] as const) {
|
||||
expectedName = name; expectedCa = ca
|
||||
await exportIpsecCertByName(base, "1", name, passphrase, { ...options, caPrivateKeyExport: ca })
|
||||
}
|
||||
assert.equal(calls, 4)
|
||||
} finally { globalThis.fetch = original }
|
||||
})
|
||||
|
||||
test("failed, unknown and malformed responses never retry or allocate another request UUID", async () => {
|
||||
const original = globalThis.fetch
|
||||
try {
|
||||
for (const mode of ["network", "unknown", "malformed"] as const) {
|
||||
let calls = 0
|
||||
globalThis.fetch = async (_url, init) => {
|
||||
calls++
|
||||
assert.equal(new Headers(init?.headers).get("Idempotency-Key") === options.requestKey, true)
|
||||
if (mode === "network") throw Error("Synthetic transport failure")
|
||||
if (mode === "unknown") return new Response(JSON.stringify({ error: "Результат неизвестен", state: "unknown", needsReview: true }), { status: 502 })
|
||||
return new Response(JSON.stringify({ ...bundle, contentB64: "invalid!" }))
|
||||
}
|
||||
await assert.rejects(() => exportIpsecUserCert(base, "1", "identity:*1", passphrase, options))
|
||||
assert.equal(calls, 1)
|
||||
await assert.rejects(() => exportIpsecCertByName(base, "1", "client", passphrase, options))
|
||||
assert.equal(calls, 2)
|
||||
}
|
||||
} finally { globalThis.fetch = original }
|
||||
})
|
||||
|
||||
test("closing an export can abort its one fetch without changing explicit intent", async () => {
|
||||
const original = globalThis.fetch, controller = new AbortController()
|
||||
let calls = 0
|
||||
globalThis.fetch = async (_url, init) => {
|
||||
calls++
|
||||
assert.equal(init?.signal === controller.signal, true)
|
||||
assert.equal(new Headers(init?.headers).get("Idempotency-Key") === options.requestKey, true)
|
||||
return new Promise<Response>((_resolve, reject) => {
|
||||
init?.signal?.addEventListener("abort", () => reject(new DOMException("Aborted", "AbortError")), { once: true })
|
||||
})
|
||||
}
|
||||
try {
|
||||
const pending = exportIpsecUserCert(base, "1", "identity:*1", passphrase, options, { signal: controller.signal })
|
||||
controller.abort()
|
||||
await assert.rejects(pending, error => error instanceof DOMException && error.name === "AbortError")
|
||||
assert.equal(calls, 1)
|
||||
} finally { globalThis.fetch = original }
|
||||
})
|
||||
Reference in new issue
Block a user