fix(certificates): убрать stale SSL-хосты и вернуть Save в FormSheet
Группы с health-check без verify_tls исключаются из мониторинга сертификатов; list/summary чистят stale. FormSheet — sticky footer со скроллом тела. Co-authored-by: Cursor <[email protected]>
This commit is contained in:
@@ -248,4 +248,216 @@ describe("certificates", () => {
|
||||
|
||||
await testApp.close();
|
||||
});
|
||||
|
||||
it("skips SSL monitoring when group health is on without TLS verify", async () => {
|
||||
const testApp = await buildApp({
|
||||
config: { ...loadConfig(), staticDir: null },
|
||||
memory: true,
|
||||
});
|
||||
const headers = await authHeaders(testApp);
|
||||
|
||||
const domain = repos.createDomain(
|
||||
testApp.db,
|
||||
null,
|
||||
"rkns.example.com",
|
||||
"cf-zone-rkns",
|
||||
);
|
||||
const group = repos.createServiceGroup(
|
||||
testApp.db,
|
||||
"TG Proxy",
|
||||
"vpn",
|
||||
null,
|
||||
"gt.rkns.example.com",
|
||||
{
|
||||
health_check_enabled: true,
|
||||
health_check_type: "http",
|
||||
health_check_port: 443,
|
||||
health_check_verify_tls: false,
|
||||
},
|
||||
);
|
||||
const service = repos.createService(testApp.db, "Node", "node");
|
||||
repos.setServiceEnabled(testApp.db, service.id, true);
|
||||
repos.setServiceGroup(testApp.db, service.id, group.id);
|
||||
repos.insertBinding(testApp.db, domain.id, service.id, "rutg", null);
|
||||
|
||||
vi.spyOn(certificateService, "checkHostname").mockResolvedValue({
|
||||
expiresAt: new Date(Date.now() + 90 * 24 * 60 * 60 * 1000),
|
||||
error: null,
|
||||
});
|
||||
|
||||
await testApp.inject({
|
||||
method: "POST",
|
||||
url: "/api/v1/certificates/check",
|
||||
headers,
|
||||
});
|
||||
|
||||
const certs = repos.listCertificates(testApp.db);
|
||||
expect(certs.some((c) => c.hostname === "gt.rkns.example.com")).toBe(false);
|
||||
expect(certs.some((c) => c.hostname === "rutg.rkns.example.com")).toBe(
|
||||
false,
|
||||
);
|
||||
expect(certificateService.checkHostname).not.toHaveBeenCalled();
|
||||
|
||||
await testApp.close();
|
||||
});
|
||||
|
||||
it("monitors group hosts when health TLS verify is on", async () => {
|
||||
const testApp = await buildApp({
|
||||
config: { ...loadConfig(), staticDir: null },
|
||||
memory: true,
|
||||
});
|
||||
const headers = await authHeaders(testApp);
|
||||
|
||||
const domain = repos.createDomain(
|
||||
testApp.db,
|
||||
null,
|
||||
"ok.example.com",
|
||||
"cf-zone-ok",
|
||||
);
|
||||
const group = repos.createServiceGroup(
|
||||
testApp.db,
|
||||
"LB",
|
||||
"vpn",
|
||||
null,
|
||||
"lb.ok.example.com",
|
||||
{
|
||||
health_check_enabled: true,
|
||||
health_check_type: "http",
|
||||
health_check_port: 443,
|
||||
health_check_verify_tls: true,
|
||||
},
|
||||
);
|
||||
const service = repos.createService(testApp.db, "Edge", "edge");
|
||||
repos.setServiceEnabled(testApp.db, service.id, true);
|
||||
repos.setServiceGroup(testApp.db, service.id, group.id);
|
||||
repos.insertBinding(testApp.db, domain.id, service.id, "edge", null);
|
||||
|
||||
vi.spyOn(certificateService, "checkHostname").mockResolvedValue({
|
||||
expiresAt: new Date(Date.now() + 90 * 24 * 60 * 60 * 1000),
|
||||
error: null,
|
||||
});
|
||||
|
||||
await testApp.inject({
|
||||
method: "POST",
|
||||
url: "/api/v1/certificates/check",
|
||||
headers,
|
||||
});
|
||||
|
||||
const certs = repos.listCertificates(testApp.db);
|
||||
expect(certs.some((c) => c.hostname === "lb.ok.example.com")).toBe(true);
|
||||
expect(certs.some((c) => c.hostname === "edge.ok.example.com")).toBe(true);
|
||||
|
||||
await testApp.close();
|
||||
});
|
||||
|
||||
it("required mode still monitors when group skips TLS verify", async () => {
|
||||
const testApp = await buildApp({
|
||||
config: { ...loadConfig(), staticDir: null },
|
||||
memory: true,
|
||||
});
|
||||
const headers = await authHeaders(testApp);
|
||||
|
||||
const domain = repos.createDomain(
|
||||
testApp.db,
|
||||
null,
|
||||
"force.example.com",
|
||||
"cf-zone-force",
|
||||
);
|
||||
repos.updateDomain(testApp.db, domain.id, {
|
||||
group_id: null,
|
||||
status: "active",
|
||||
cert_monitoring: CERT_MONITOR_REQUIRED,
|
||||
});
|
||||
repos.createServiceGroup(
|
||||
testApp.db,
|
||||
"Proxy",
|
||||
"vpn",
|
||||
null,
|
||||
"force.example.com",
|
||||
{
|
||||
health_check_enabled: true,
|
||||
health_check_verify_tls: false,
|
||||
},
|
||||
);
|
||||
|
||||
vi.spyOn(certificateService, "checkHostname").mockResolvedValue({
|
||||
expiresAt: new Date(Date.now() + 90 * 24 * 60 * 60 * 1000),
|
||||
error: null,
|
||||
});
|
||||
|
||||
await testApp.inject({
|
||||
method: "POST",
|
||||
url: "/api/v1/certificates/check",
|
||||
headers,
|
||||
});
|
||||
|
||||
expect(
|
||||
repos.listCertificates(testApp.db).some(
|
||||
(c) => c.hostname === domain.zone_name,
|
||||
),
|
||||
).toBe(true);
|
||||
|
||||
await testApp.close();
|
||||
});
|
||||
|
||||
it("GET /certificates prunes stale rows without running check", async () => {
|
||||
const testApp = await buildApp({
|
||||
config: { ...loadConfig(), staticDir: null },
|
||||
memory: true,
|
||||
});
|
||||
const headers = await authHeaders(testApp);
|
||||
|
||||
const domain = repos.createDomain(
|
||||
testApp.db,
|
||||
null,
|
||||
"stale-list.example.com",
|
||||
"cf-zone-stale-list",
|
||||
);
|
||||
const group = repos.createServiceGroup(
|
||||
testApp.db,
|
||||
"Stale",
|
||||
"vpn",
|
||||
null,
|
||||
"gt.stale-list.example.com",
|
||||
{
|
||||
health_check_enabled: true,
|
||||
health_check_verify_tls: false,
|
||||
},
|
||||
);
|
||||
const service = repos.createService(testApp.db, "S", "s");
|
||||
repos.setServiceEnabled(testApp.db, service.id, true);
|
||||
repos.setServiceGroup(testApp.db, service.id, group.id);
|
||||
repos.insertBinding(testApp.db, domain.id, service.id, "rutg", null);
|
||||
|
||||
repos.upsertCertificateCheck(
|
||||
testApp.db,
|
||||
domain.id,
|
||||
null,
|
||||
"gt.stale-list.example.com",
|
||||
null,
|
||||
CERT_ERROR,
|
||||
"stale group domain",
|
||||
);
|
||||
repos.upsertCertificateCheck(
|
||||
testApp.db,
|
||||
domain.id,
|
||||
null,
|
||||
"rutg.stale-list.example.com",
|
||||
null,
|
||||
CERT_ERROR,
|
||||
"stale binding",
|
||||
);
|
||||
|
||||
expect(repos.listCertificates(testApp.db)).toHaveLength(2);
|
||||
|
||||
const listRes = await testApp.inject({
|
||||
method: "GET",
|
||||
url: "/api/v1/certificates",
|
||||
headers,
|
||||
});
|
||||
expect(listRes.statusCode).toBe(200);
|
||||
expect(listRes.json()).toEqual([]);
|
||||
|
||||
await testApp.close();
|
||||
});
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user