smartproxy/examples/certificate-management-v19.ts

119 lines
3.6 KiB
TypeScript

/**
* Certificate Management Example (v19+)
*
* This example demonstrates the new global ACME configuration introduced in v19+
* along with route-level overrides for specific domains.
*/
import {
SmartProxy,
createHttpRoute,
createHttpsTerminateRoute,
createCompleteHttpsServer
} from '../dist_ts/index.js';
async function main() {
// Create a SmartProxy instance with global ACME configuration
const proxy = new SmartProxy({
// Global ACME configuration (v19+)
// These settings apply to all routes with certificate: 'auto'
acme: {
email: 'ssl@bleu.de', // Global contact email
useProduction: false, // Use staging by default
port: 8080, // Use non-privileged port
renewThresholdDays: 30, // Renew 30 days before expiry
autoRenew: true, // Enable automatic renewal
renewCheckIntervalHours: 12 // Check twice daily
},
routes: [
// Route that uses global ACME settings
createHttpsTerminateRoute('app.example.com',
{ host: 'localhost', port: 3000 },
{ certificate: 'auto' } // Uses global ACME configuration
),
// Route with route-level ACME override
{
name: 'production-api',
match: { ports: 443, domains: 'api.example.com' },
action: {
type: 'forward',
target: { host: 'localhost', port: 3001 },
tls: {
mode: 'terminate',
certificate: 'auto',
acme: {
email: 'api-certs@example.com', // Override email
useProduction: true, // Use production for API
renewThresholdDays: 60 // Earlier renewal for critical API
}
}
}
},
// Complete HTTPS server with automatic redirects
...createCompleteHttpsServer('website.example.com',
{ host: 'localhost', port: 8080 },
{ certificate: 'auto' }
),
// Static certificate (not using ACME)
{
name: 'internal-service',
match: { ports: 8443, domains: 'internal.local' },
action: {
type: 'forward',
target: { host: 'localhost', port: 3002 },
tls: {
mode: 'terminate',
certificate: {
cert: '-----BEGIN CERTIFICATE-----\n...\n-----END CERTIFICATE-----',
key: '-----BEGIN PRIVATE KEY-----\n...\n-----END PRIVATE KEY-----'
}
}
}
}
]
});
// Monitor certificate events
proxy.on('certificate:issued', (event) => {
console.log(`Certificate issued for ${event.domain}`);
console.log(`Expires: ${event.expiryDate}`);
});
proxy.on('certificate:renewed', (event) => {
console.log(`Certificate renewed for ${event.domain}`);
});
proxy.on('certificate:error', (event) => {
console.error(`Certificate error for ${event.domain}: ${event.error}`);
});
// Start the proxy
await proxy.start();
console.log('SmartProxy started with global ACME configuration');
// Check certificate status programmatically
setTimeout(async () => {
// Get status for a specific route
const status = proxy.getCertificateStatus('app-route');
console.log('Certificate status:', status);
// Manually trigger renewal if needed
if (status && status.status === 'expiring') {
await proxy.renewCertificate('app-route');
}
}, 10000);
// Handle shutdown gracefully
process.on('SIGINT', async () => {
console.log('Shutting down proxy...');
await proxy.stop();
process.exit(0);
});
}
// Run the example
main().catch(console.error);