Package Exports
- secure-ssl-server
- secure-ssl-server/src/index.js
This package does not declare an exports field, so the exports above have been automatically detected and optimized by JSPM instead. If any package subpath is missing, it is recommended to post an issue to the original package (secure-ssl-server) to support the "exports" field. If that is not possible, create a JSPM override to customize the exports field for this package.
Readme
secure-ssl-server
π Effortless HTTPS server creation for Node.js with multi-framework support, automatic certificate reloading, and Let's Encrypt integration
A comprehensive SSL/TLS helper that simplifies HTTPS server setup across multiple Node.js frameworks. Perfect for development and production environments with built-in certificate management, monitoring, and Let's Encrypt integration.
β¨ Features
- π Quick Setup - Create HTTPS servers with a single function call
- π Multi-Framework - Support for Express, Fastify, Koa, and Hapi
- π Auto-Reload - Watch SSL certificates and automatically reload when they change
- π Let's Encrypt - Built-in ACME client with automatic certificate renewal
- π Monitoring - Certificate expiration monitoring with customizable alerts
- π‘οΈ Secure by Default - Built-in certificate validation and error handling
- π¦ Lightweight - Minimal dependencies, optimized footprint
- β‘ Production Ready - Battle-tested in production environments
- π TypeScript - Full TypeScript definitions included
π Requirements
- Node.js 14.0.0 or higher
- SSL certificate and private key files (or use Let's Encrypt integration)
- One of the supported frameworks: Express, Fastify, Koa, or Hapi (optional)
π¦ Installation
npm install secure-ssl-serverπ Quick Start
Express
import express from 'express';
import { createHttpsExpressServer } from 'secure-ssl-server';
const app = express();
app.get('/', (req, res) => {
res.send('Hello HTTPS! π');
});
const server = createHttpsExpressServer({
certPath: './certs/cert.pem',
keyPath: './certs/key.pem',
port: 8443
}, app);Fastify
import Fastify from 'fastify';
import { createHttpsFastifyServer } from 'secure-ssl-server';
const app = Fastify();
app.get('/', async (request, reply) => {
return { hello: 'HTTPS! π' };
});
const server = createHttpsFastifyServer({
certPath: './certs/cert.pem',
keyPath: './certs/key.pem',
port: 8443
}, app);Koa
import Koa from 'koa';
import { createHttpsKoaServer } from 'secure-ssl-server';
const app = new Koa();
app.use(async ctx => {
ctx.body = 'Hello HTTPS! π';
});
const server = createHttpsKoaServer({
certPath: './certs/cert.pem',
keyPath: './certs/key.pem',
port: 8443
}, app);Let's Encrypt (Express)
import express from 'express';
import { createHttpsServerWithLetsEncrypt } from 'secure-ssl-server';
const app = express();
app.get('/', (req, res) => {
res.send('Hello HTTPS with Let\'s Encrypt! π');
});
const server = await createHttpsServerWithLetsEncrypt(
{
email: 'your-email@example.com',
domains: ['example.com', 'www.example.com'],
staging: false, // Use production Let's Encrypt
autoRenew: true
},
{
port: 443,
watch: true
},
app,
'express'
);π Usage
Basic HTTPS Server (Express)
import express from 'express';
import { createHttpsExpressServer } from 'secure-ssl-server';
const app = express();
const server = createHttpsExpressServer({
certPath: './certs/cert.pem',
keyPath: './certs/key.pem',
port: 443
}, app);Multi-Framework Support
Fastify
import Fastify from 'fastify';
import { createHttpsFastifyServer } from 'secure-ssl-server';
const app = Fastify();
const server = createHttpsFastifyServer({
certPath: './certs/cert.pem',
keyPath: './certs/key.pem',
port: 8443
}, app);Koa
import Koa from 'koa';
import { createHttpsKoaServer } from 'secure-ssl-server';
const app = new Koa();
const server = createHttpsKoaServer({
certPath: './certs/cert.pem',
keyPath: './certs/key.pem',
port: 8443
}, app);Hapi
import Hapi from '@hapi/hapi';
import { createHttpsHapiServer } from 'secure-ssl-server';
const server = Hapi.server();
await createHttpsHapiServer({
certPath: './certs/cert.pem',
keyPath: './certs/key.pem',
port: 8443
}, server);With Certificate Watching
Enable automatic certificate reloading when files change:
const server = createHttpsExpressServer({
certPath: './certs/cert.pem',
keyPath: './certs/key.pem',
watch: true, // Enable file watching
port: 8443,
onReload: () => {
console.log('Certificates have been reloaded! π');
}
}, app);With CA Bundle
For certificates that require intermediate certificates:
const server = createHttpsExpressServer({
certPath: './certs/cert.pem',
keyPath: './certs/key.pem',
caPath: './certs/ca-bundle.pem', // Optional CA bundle
port: 8443
}, app);Manual Certificate Loading
For more control, you can load certificates separately:
import { loadSSL } from 'secure-ssl-server';
import https from 'https';
import express from 'express';
const app = express();
const ssl = loadSSL({
certPath: './certs/cert.pem',
keyPath: './certs/key.pem'
});
const server = https.createServer(ssl, app);
server.listen(8443);Certificate Monitoring
Monitor certificate expiration and receive alerts:
import { monitorCertificate } from 'secure-ssl-server';
const monitor = monitorCertificate('./certs/cert.pem', {
warningThreshold: 30, // Warning 30 days before expiration
criticalThreshold: 7, // Critical alert 7 days before
onWarning: (daysLeft) => {
console.log(`β οΈ Certificate expires in ${daysLeft} days`);
// Send notification, email, etc.
},
onCritical: (daysLeft) => {
console.error(`π¨ CRITICAL: Certificate expires in ${daysLeft} days!`);
// Send urgent alert
}
});
// Get certificate information
const info = monitor.getInfo();
console.log(`Certificate valid until: ${info.validTo}`);
console.log(`Days until expiration: ${info.daysUntilExpiration}`);
// Stop monitoring
// monitor.stop();Let's Encrypt Integration
Automatic Certificate Management
import express from 'express';
import { createHttpsServerWithLetsEncrypt } from 'secure-ssl-server';
const app = express();
// Create server with Let's Encrypt
const server = await createHttpsServerWithLetsEncrypt(
{
email: 'admin@example.com',
domains: ['example.com', 'www.example.com'],
certDir: './letsencrypt-certs',
staging: false, // Use production environment
autoRenew: true, // Automatic renewal
renewalThreshold: 30, // Renew 30 days before expiration
challengeType: 'http-01', // or 'dns-01'
onObtained: (certPaths) => {
console.log('β
Certificates obtained!', certPaths);
},
onRenewed: (certPaths) => {
console.log('π Certificates renewed!', certPaths);
},
onError: (error) => {
console.error('β ACME Error:', error);
}
},
{
port: 443,
watch: true
},
app,
'express' // or 'fastify', 'koa', 'hapi'
);
// Access ACME client for manual control
const acmeClient = server.acmeClient;
// Manually renew certificates
await acmeClient.renewCertificates();
// Stop automatic renewal
acmeClient.stopAutoRenewal();Manual Certificate Obtainment
import { obtainLetsEncryptCertificates } from 'secure-ssl-server';
const certPaths = await obtainLetsEncryptCertificates({
email: 'admin@example.com',
domains: ['example.com'],
certDir: './certs',
staging: true // Use staging for testing
});
console.log('Certificate:', certPaths.cert);
console.log('Private Key:', certPaths.key);
console.log('CA Bundle:', certPaths.ca);ACME Client Control
import { createAcmeClient } from 'secure-ssl-server';
const acmeClient = createAcmeClient({
email: 'admin@example.com',
domains: ['example.com'],
certDir: './certs'
});
// Obtain certificates
await acmeClient.obtainCertificates();
// Start automatic renewal checks
acmeClient.startAutoRenewal();
// Get certificate info
const info = await acmeClient.getCertificateInfo();
console.log(`Expires in ${info.daysUntilExpiration} days`);
// Stop auto-renewal
acmeClient.stopAutoRenewal();π§ API Reference
Server Creation
createHttpsExpressServer(options, app)
Creates and starts an HTTPS server with Express.
Parameters:
options- Configuration objectcertPath(string) - Path to SSL certificate filekeyPath(string) - Path to private key filecaPath(string, optional) - Path to CA bundle fileport(number, default: 443) - Port to listen onwatch(boolean, default: false) - Enable certificate file watchingonReload(function, optional) - Callback fired when certificates are reloaded
app- Express application instance
Returns: https.Server
createHttpsFastifyServer(options, app)
Creates and starts an HTTPS server with Fastify.
Parameters: Same as createHttpsExpressServer
Returns: https.Server
createHttpsKoaServer(options, app)
Creates and starts an HTTPS server with Koa.
Parameters: Same as createHttpsExpressServer
Returns: https.Server
createHttpsHapiServer(options, server)
Creates and starts an HTTPS server with Hapi.
Parameters: Same as createHttpsExpressServer
Returns: Promise<HapiServer>
Certificate Management
loadSSL(options)
Loads SSL certificates from the filesystem with validation.
Parameters:
options- Configuration objectcertPath(string) - Path to SSL certificate filekeyPath(string) - Path to private key filecaPath(string, optional) - Path to CA bundle file
Returns: { cert: string, key: string, ca: string|null }
validateCert(cert)
Validates if a string contains a proper SSL certificate.
Parameters:
cert(string) - Certificate content
Throws: Error if invalid
validateKey(key)
Validates if a string contains a proper SSL private key.
Parameters:
key(string) - Private key content
Throws: Error if invalid
Certificate Monitoring
monitorCertificate(certPath, options)
Monitor certificate expiration and trigger alerts.
Parameters:
certPath(string) - Path to certificate fileoptions(object, optional) - Monitoring optionswarningThreshold(number, default: 30) - Warning threshold in dayscriticalThreshold(number, default: 7) - Critical threshold in daysonWarning(function) - Callback for warningsonCritical(function) - Callback for critical alerts
Returns: { stop: function, check: function, getInfo: function }
getCertificateInfo(certPath)
Get certificate information including expiration details.
Parameters:
certPath(string) - Path to certificate file
Returns: Object with certificate details:
{
subject: string,
issuer: string,
validFrom: Date,
validTo: Date,
daysUntilExpiration: number,
isExpired: boolean,
serialNumber: string
}isCertificateExpiringSoon(certPath, thresholdDays)
Check if certificate is expiring soon.
Parameters:
certPath(string) - Path to certificate filethresholdDays(number, default: 30) - Threshold in days
Returns: boolean
Let's Encrypt / ACME
createHttpsServerWithLetsEncrypt(acmeOptions, serverOptions, app, framework)
Create an HTTPS server with Let's Encrypt certificates.
Parameters:
acmeOptions- ACME configurationemail(string) - Email address for Let's Encrypt accountdomains(string[]) - Domain names to obtain certificates forcertDir(string, default: './certs') - Directory to store certificatesstaging(boolean, default: false) - Use staging environmentautoRenew(boolean, default: true) - Enable automatic renewalrenewalCheckInterval(number, default: 86400000) - Check interval in msrenewalThreshold(number, default: 30) - Renew N days before expirationchallengeType(string, default: 'http-01') - Challenge type: 'http-01' or 'dns-01'onObtained(function) - Callback when certificates obtainedonRenewed(function) - Callback when certificates renewedonError(function) - Callback on errors
serverOptions- Server options (without certPath/keyPath)port(number)watch(boolean)onReload(function)
app- Framework app instanceframework(string, default: 'express') - Framework: 'express', 'fastify', 'koa', 'hapi'
Returns: Promise<https.Server>
createAcmeClient(options)
Create an ACME client for Let's Encrypt certificate management.
Parameters: Same as acmeOptions above
Returns: AcmeClient instance with methods:
obtainCertificates()- Obtain new certificatesrenewCertificates()- Renew existing certificatesstartAutoRenewal()- Start automatic renewal checksstopAutoRenewal()- Stop automatic renewal checksgetCertificateInfo()- Get certificate information
obtainLetsEncryptCertificates(options)
One-time certificate obtainment from Let's Encrypt.
Parameters: Same as acmeOptions above
Returns: Promise<{ cert: string, key: string, ca: string }>
π Generating Self-Signed Certificates
For development purposes, you can generate self-signed certificates:
# Generate private key
openssl genrsa -out key.pem 2048
# Generate certificate
openssl req -new -x509 -key key.pem -out cert.pem -days 365π οΈ Development
# Install dependencies
npm install
# Run tests
npm test
# Run linter
npm run lint
# Run tests with coverage
npm run test:coverageπΊοΈ Version History
v2.0.0 (Current)
- β Multi-framework support (Express, Fastify, Koa, Hapi)
- β Let's Encrypt integration with automatic certificate renewal
- β Certificate expiration monitoring and alerts
- β Enhanced configuration options
- β Full TypeScript definitions
- β ACME client with HTTP-01 and DNS-01 challenge support
v1.0.0
- Basic Express HTTPS server creation
- Certificate file watching
- CA bundle support
π Migration Guide (v1 β v2)
Version 2.0 is fully backward compatible with v1.x. All existing code will continue to work.
New Features Available
// v1.x - Still works!
import { createHttpsExpressServer } from 'secure-ssl-server';
// v2.0 - New multi-framework support
import {
createHttpsFastifyServer,
createHttpsKoaServer,
createHttpsHapiServer
} from 'secure-ssl-server';
// v2.0 - New monitoring features
import { monitorCertificate, getCertificateInfo } from 'secure-ssl-server';
// v2.0 - New Let's Encrypt integration
import { createHttpsServerWithLetsEncrypt } from 'secure-ssl-server';β FAQ
Q: Does this work in production?
A: Yes! The package is production-ready and battle-tested, especially useful for applications that need dynamic certificate management.
Q: Can I use this with Let's Encrypt?
A: Yes! v2.0 includes full Let's Encrypt integration with automatic certificate renewal. See the Let's Encrypt Integration section for details.
Q: What frameworks are supported?
A: Express, Fastify, Koa, and Hapi are officially supported with dedicated adapters.
Q: What happens if certificate files are invalid?
A: The package validates certificates on load and throws descriptive errors if formats are invalid.
Q: Does watching certificates impact performance?
A: No, the file watcher is efficient and only triggers on actual file changes.
Q: How does automatic certificate renewal work?
A: The ACME client checks certificate expiration periodically (default: every 24 hours) and automatically renews certificates when they're within the renewal threshold (default: 30 days before expiration).
Q: Can I use DNS-01 challenges with Let's Encrypt?
A: Yes, set challengeType: 'dns-01' in the ACME options. You'll need to manually configure DNS TXT records as instructed in the console output.
Q: Is TypeScript supported?
A: Yes! Full TypeScript definitions are included in v2.0.
π€ Contributing
Contributions are welcome! Please feel free to submit a Pull Request. For major changes, please open an issue first to discuss what you would like to change.
π License
MIT Β© 2025 Omar Gamal
π Acknowledgments
Built with β€οΈ for the Node.js community.
Special thanks to:
- The ACME protocol and Let's Encrypt for making SSL certificates accessible
- All contributors and users of this package
Need help? Open an issue
Want to contribute? View contributing guidelines