import { tap, expect } from '@push.rocks/tapbundle'; import * as plugins from '../ts/plugins.js'; import { CertProvisioner } from '../ts/smartproxy/classes.pp.certprovisioner.js'; import type { IDomainConfig, ISmartProxyCertProvisionObject } from '../ts/smartproxy/classes.pp.interfaces.js'; import type { ICertificateData } from '../ts/port80handler/classes.port80handler.js'; // Fake Port80Handler stub class FakePort80Handler extends plugins.EventEmitter { public domainsAdded: string[] = []; public renewCalled: string[] = []; addDomain(opts: { domainName: string; sslRedirect: boolean; acmeMaintenance: boolean }) { this.domainsAdded.push(opts.domainName); } async renewCertificate(domain: string): Promise { this.renewCalled.push(domain); } } // Fake NetworkProxyBridge stub class FakeNetworkProxyBridge { public appliedCerts: ICertificateData[] = []; applyExternalCertificate(cert: ICertificateData) { this.appliedCerts.push(cert); } } tap.test('CertProvisioner handles static provisioning', async () => { const domain = 'static.com'; const domainConfigs: IDomainConfig[] = [{ domains: [domain], allowedIPs: [] }]; const fakePort80 = new FakePort80Handler(); const fakeBridge = new FakeNetworkProxyBridge(); // certProvider returns static certificate const certProvider = async (d: string): Promise => { expect(d).toEqual(domain); return { domainName: domain, publicKey: 'CERT', privateKey: 'KEY', validUntil: Date.now() + 3600 * 1000 }; }; const prov = new CertProvisioner( domainConfigs, fakePort80 as any, fakeBridge as any, certProvider, 1, // low renew threshold 1, // short interval false // disable auto renew for unit test ); const events: any[] = []; prov.on('certificate', (data) => events.push(data)); await prov.start(); // Static flow: no addDomain, certificate applied via bridge expect(fakePort80.domainsAdded.length).toEqual(0); expect(fakeBridge.appliedCerts.length).toEqual(1); expect(events.length).toEqual(1); const evt = events[0]; expect(evt.domain).toEqual(domain); expect(evt.certificate).toEqual('CERT'); expect(evt.privateKey).toEqual('KEY'); expect(evt.isRenewal).toEqual(false); expect(evt.source).toEqual('static'); }); tap.test('CertProvisioner handles http01 provisioning', async () => { const domain = 'http01.com'; const domainConfigs: IDomainConfig[] = [{ domains: [domain], allowedIPs: [] }]; const fakePort80 = new FakePort80Handler(); const fakeBridge = new FakeNetworkProxyBridge(); // certProvider returns http01 directive const certProvider = async (): Promise => 'http01'; const prov = new CertProvisioner( domainConfigs, fakePort80 as any, fakeBridge as any, certProvider, 1, 1, false ); const events: any[] = []; prov.on('certificate', (data) => events.push(data)); await prov.start(); // HTTP-01 flow: addDomain called, no static cert applied expect(fakePort80.domainsAdded).toEqual([domain]); expect(fakeBridge.appliedCerts.length).toEqual(0); expect(events.length).toEqual(0); }); tap.test('CertProvisioner on-demand http01 renewal', async () => { const domain = 'renew.com'; const domainConfigs: IDomainConfig[] = [{ domains: [domain], allowedIPs: [] }]; const fakePort80 = new FakePort80Handler(); const fakeBridge = new FakeNetworkProxyBridge(); const certProvider = async (): Promise => 'http01'; const prov = new CertProvisioner( domainConfigs, fakePort80 as any, fakeBridge as any, certProvider, 1, 1, false ); // requestCertificate should call renewCertificate await prov.requestCertificate(domain); expect(fakePort80.renewCalled).toEqual([domain]); }); tap.test('CertProvisioner on-demand static provisioning', async () => { const domain = 'ondemand.com'; const domainConfigs: IDomainConfig[] = [{ domains: [domain], allowedIPs: [] }]; const fakePort80 = new FakePort80Handler(); const fakeBridge = new FakeNetworkProxyBridge(); const certProvider = async (): Promise => ({ domainName: domain, publicKey: 'PKEY', privateKey: 'PRIV', validUntil: Date.now() + 1000 }); const prov = new CertProvisioner( domainConfigs, fakePort80 as any, fakeBridge as any, certProvider, 1, 1, false ); const events: any[] = []; prov.on('certificate', (data) => events.push(data)); await prov.requestCertificate(domain); expect(fakeBridge.appliedCerts.length).toEqual(1); expect(events.length).toEqual(1); expect(events[0].domain).toEqual(domain); expect(events[0].source).toEqual('static'); }); export default tap.start();