fix(federation): use real PEM certs in enrollment + ca service tests (#507)
This commit was merged in pull request #507.
This commit is contained in:
@@ -20,9 +20,10 @@
|
||||
*/
|
||||
|
||||
import 'reflect-metadata';
|
||||
import { describe, it, expect, vi, beforeEach, type Mock } from 'vitest';
|
||||
import { describe, it, expect, vi, beforeEach, beforeAll, type Mock } from 'vitest';
|
||||
import { jwtVerify, exportJWK, generateKeyPair } from 'jose';
|
||||
import { Pkcs10CertificateRequestGenerator } from '@peculiar/x509';
|
||||
import { makeMosaicIssuedCert } from './__tests__/helpers/test-cert.js';
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// Mock node:https BEFORE importing CaService so the mock is in place when
|
||||
@@ -74,6 +75,11 @@ const FAKE_CA_PEM = FAKE_CERT_PEM;
|
||||
const GRANT_ID = 'a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11';
|
||||
const SUBJECT_USER_ID = 'b1ffcd00-0d1c-5f09-cc7e-7cc0ce491b22';
|
||||
|
||||
// Real self-signed cert containing both Mosaic OID extensions — populated in beforeAll.
|
||||
// Required because CaService.issueCert performs CRIT-1 OID presence/value checks on the
|
||||
// response cert (PR #501 — strict parsing, no silent fallback).
|
||||
let realIssuedCertPem: string;
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// Generate a real EC P-256 key pair and CSR for integration-style tests
|
||||
// ---------------------------------------------------------------------------
|
||||
@@ -194,6 +200,15 @@ function makeHttpsMock(statusCode: number, body: unknown, errorMsg?: string): vo
|
||||
describe('CaService', () => {
|
||||
let service: CaService;
|
||||
|
||||
beforeAll(async () => {
|
||||
// Generate a cert with the two Mosaic OIDs so that CaService.issueCert's
|
||||
// CRIT-1 OID checks pass when mock step-ca returns it as `crt`.
|
||||
realIssuedCertPem = await makeMosaicIssuedCert({
|
||||
grantId: GRANT_ID,
|
||||
subjectUserId: SUBJECT_USER_ID,
|
||||
});
|
||||
});
|
||||
|
||||
beforeEach(() => {
|
||||
vi.clearAllMocks();
|
||||
service = new CaService();
|
||||
@@ -226,9 +241,9 @@ describe('CaService', () => {
|
||||
|
||||
// Now test that the service's validateCsr accepts it.
|
||||
// We call it indirectly via issueCert with a successful mock.
|
||||
makeHttpsMock(200, { crt: FAKE_CERT_PEM, certChain: [FAKE_CERT_PEM, FAKE_CA_PEM] });
|
||||
makeHttpsMock(200, { crt: realIssuedCertPem, certChain: [realIssuedCertPem, FAKE_CA_PEM] });
|
||||
const result = await service.issueCert(makeReq({ csrPem: realCsrPem }));
|
||||
expect(result.certPem).toBe(FAKE_CERT_PEM);
|
||||
expect(result.certPem).toBe(realIssuedCertPem);
|
||||
});
|
||||
|
||||
it('throws INVALID_CSR for a malformed PEM-shaped CSR', async () => {
|
||||
@@ -251,14 +266,14 @@ describe('CaService', () => {
|
||||
it('returns IssuedCertDto on success (certChain present)', async () => {
|
||||
if (!realCsrPem) realCsrPem = await generateRealCsr();
|
||||
makeHttpsMock(200, {
|
||||
crt: FAKE_CERT_PEM,
|
||||
certChain: [FAKE_CERT_PEM, FAKE_CA_PEM],
|
||||
crt: realIssuedCertPem,
|
||||
certChain: [realIssuedCertPem, FAKE_CA_PEM],
|
||||
});
|
||||
|
||||
const result = await service.issueCert(makeReq());
|
||||
|
||||
expect(result.certPem).toBe(FAKE_CERT_PEM);
|
||||
expect(result.certChainPem).toContain(FAKE_CERT_PEM);
|
||||
expect(result.certPem).toBe(realIssuedCertPem);
|
||||
expect(result.certChainPem).toContain(realIssuedCertPem);
|
||||
expect(result.certChainPem).toContain(FAKE_CA_PEM);
|
||||
expect(typeof result.serialNumber).toBe('string');
|
||||
});
|
||||
@@ -270,14 +285,14 @@ describe('CaService', () => {
|
||||
it('builds certChainPem from crt+ca when certChain is absent', async () => {
|
||||
if (!realCsrPem) realCsrPem = await generateRealCsr();
|
||||
makeHttpsMock(200, {
|
||||
crt: FAKE_CERT_PEM,
|
||||
crt: realIssuedCertPem,
|
||||
ca: FAKE_CA_PEM,
|
||||
});
|
||||
|
||||
const result = await service.issueCert(makeReq());
|
||||
|
||||
expect(result.certPem).toBe(FAKE_CERT_PEM);
|
||||
expect(result.certChainPem).toContain(FAKE_CERT_PEM);
|
||||
expect(result.certPem).toBe(realIssuedCertPem);
|
||||
expect(result.certChainPem).toContain(realIssuedCertPem);
|
||||
expect(result.certChainPem).toContain(FAKE_CA_PEM);
|
||||
});
|
||||
|
||||
@@ -287,12 +302,12 @@ describe('CaService', () => {
|
||||
|
||||
it('falls back to certPem alone when certChain and ca are absent', async () => {
|
||||
if (!realCsrPem) realCsrPem = await generateRealCsr();
|
||||
makeHttpsMock(200, { crt: FAKE_CERT_PEM });
|
||||
makeHttpsMock(200, { crt: realIssuedCertPem });
|
||||
|
||||
const result = await service.issueCert(makeReq());
|
||||
|
||||
expect(result.certPem).toBe(FAKE_CERT_PEM);
|
||||
expect(result.certChainPem).toBe(FAKE_CERT_PEM);
|
||||
expect(result.certPem).toBe(realIssuedCertPem);
|
||||
expect(result.certChainPem).toBe(realIssuedCertPem);
|
||||
});
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
@@ -398,7 +413,7 @@ describe('CaService', () => {
|
||||
statusCode: 200,
|
||||
on: (event: string, cb: (chunk?: Buffer) => void) => {
|
||||
if (event === 'data') {
|
||||
cb(Buffer.from(JSON.stringify({ crt: FAKE_CERT_PEM })));
|
||||
cb(Buffer.from(JSON.stringify({ crt: realIssuedCertPem })));
|
||||
}
|
||||
if (event === 'end') {
|
||||
cb();
|
||||
@@ -555,7 +570,7 @@ describe('CaService', () => {
|
||||
statusCode: 200,
|
||||
on: (event: string, cb: (chunk?: Buffer) => void) => {
|
||||
if (event === 'data') {
|
||||
cb(Buffer.from(JSON.stringify({ crt: FAKE_CERT_PEM })));
|
||||
cb(Buffer.from(JSON.stringify({ crt: realIssuedCertPem })));
|
||||
}
|
||||
if (event === 'end') {
|
||||
cb();
|
||||
|
||||
Reference in New Issue
Block a user