roster-server 2.0.2 → 2.0.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +14 -1
- package/index.js +39 -6
- package/package.json +2 -1
package/README.md
CHANGED
|
@@ -11,6 +11,7 @@ Welcome to **RosterServer**, the ultimate domain host router with automatic HTTP
|
|
|
11
11
|
- **Virtual Hosting**: Serve multiple domains from a single server.
|
|
12
12
|
- **Automatic Redirects**: Redirect `www` subdomains to the root domain.
|
|
13
13
|
- **Zero Configuration**: Well, almost zero. Just a tiny bit of setup.
|
|
14
|
+
- **Bun compatible**: Works with both Node.js and [Bun](https://bun.sh).
|
|
14
15
|
|
|
15
16
|
## 📦 Installation
|
|
16
17
|
|
|
@@ -18,6 +19,12 @@ Welcome to **RosterServer**, the ultimate domain host router with automatic HTTP
|
|
|
18
19
|
npm install roster-server
|
|
19
20
|
```
|
|
20
21
|
|
|
22
|
+
Or with [Bun](https://bun.sh):
|
|
23
|
+
|
|
24
|
+
```bash
|
|
25
|
+
bun add roster-server
|
|
26
|
+
```
|
|
27
|
+
|
|
21
28
|
## 🤖 AI Skill
|
|
22
29
|
|
|
23
30
|
You can also add RosterServer as a skill for AI agentic development:
|
|
@@ -145,10 +152,16 @@ roster.register('example.com:8080', (httpsServer) => {
|
|
|
145
152
|
### Running the Server
|
|
146
153
|
|
|
147
154
|
```bash
|
|
148
|
-
#
|
|
155
|
+
# With Node.js
|
|
149
156
|
node server.js
|
|
150
157
|
```
|
|
151
158
|
|
|
159
|
+
Or with Bun:
|
|
160
|
+
|
|
161
|
+
```bash
|
|
162
|
+
bun server.js
|
|
163
|
+
```
|
|
164
|
+
|
|
152
165
|
And that's it! Your server is now hosting multiple HTTPS-enabled sites. 🎉
|
|
153
166
|
|
|
154
167
|
## 🤯 But Wait, There's More!
|
package/index.js
CHANGED
|
@@ -166,6 +166,8 @@ class Roster {
|
|
|
166
166
|
this.filename = options.filename || 'index';
|
|
167
167
|
this.minLocalPort = options.minLocalPort || 4000;
|
|
168
168
|
this.maxLocalPort = options.maxLocalPort || 9999;
|
|
169
|
+
this.tlsMinVersion = options.tlsMinVersion ?? 'TLSv1.2';
|
|
170
|
+
this.tlsMaxVersion = options.tlsMaxVersion ?? 'TLSv1.3';
|
|
169
171
|
|
|
170
172
|
const port = options.port === undefined ? 443 : options.port;
|
|
171
173
|
if (port === 80 && !this.local) {
|
|
@@ -374,13 +376,13 @@ class Roster {
|
|
|
374
376
|
getUrl(domain) {
|
|
375
377
|
// Remove www prefix if present
|
|
376
378
|
const cleanDomain = domain.startsWith('www.') ? domain.slice(4) : domain;
|
|
377
|
-
|
|
379
|
+
|
|
378
380
|
// Check if domain is registered
|
|
379
381
|
const isRegistered = this.sites[cleanDomain] || this.sites[`www.${cleanDomain}`];
|
|
380
382
|
if (!isRegistered) {
|
|
381
383
|
return null;
|
|
382
384
|
}
|
|
383
|
-
|
|
385
|
+
|
|
384
386
|
// Return URL based on environment
|
|
385
387
|
if (this.local) {
|
|
386
388
|
// Local mode: return localhost URL with assigned port
|
|
@@ -437,7 +439,7 @@ class Roster {
|
|
|
437
439
|
startLocalMode() {
|
|
438
440
|
// Store mapping of domain to port for later retrieval
|
|
439
441
|
this.domainPorts = {};
|
|
440
|
-
|
|
442
|
+
|
|
441
443
|
// Create a simple HTTP server for each domain with CRC32-based ports
|
|
442
444
|
for (const [hostKey, siteApp] of Object.entries(this.sites)) {
|
|
443
445
|
const domain = hostKey.split(':')[0]; // Remove port if present
|
|
@@ -449,7 +451,7 @@ class Roster {
|
|
|
449
451
|
|
|
450
452
|
// Calculate deterministic port based on domain CRC32, with collision detection
|
|
451
453
|
const port = this.assignPortToDomain(domain);
|
|
452
|
-
|
|
454
|
+
|
|
453
455
|
// Store domain → port mapping
|
|
454
456
|
this.domainPorts[domain] = port;
|
|
455
457
|
|
|
@@ -608,8 +610,37 @@ class Roster {
|
|
|
608
610
|
const upgradeHandler = createUpgradeHandler(portData);
|
|
609
611
|
|
|
610
612
|
if (portNum === this.defaultPort) {
|
|
611
|
-
//
|
|
612
|
-
|
|
613
|
+
// Bun has known gaps around SNICallback compatibility.
|
|
614
|
+
// Fallback to static cert loading for the primary domain on default HTTPS port.
|
|
615
|
+
const isBunRuntime = typeof Bun !== 'undefined' || process.release?.name === 'bun';
|
|
616
|
+
const tlsOpts = { minVersion: this.tlsMinVersion, maxVersion: this.tlsMaxVersion };
|
|
617
|
+
let httpsServer;
|
|
618
|
+
|
|
619
|
+
if (isBunRuntime) {
|
|
620
|
+
const primaryDomain = Object.keys(portData.virtualServers)[0];
|
|
621
|
+
const certPath = path.join(this.greenlockStorePath, 'live', primaryDomain);
|
|
622
|
+
const keyPath = path.join(certPath, 'privkey.pem');
|
|
623
|
+
const certFilePath = path.join(certPath, 'cert.pem');
|
|
624
|
+
const chainPath = path.join(certPath, 'chain.pem');
|
|
625
|
+
|
|
626
|
+
if (fs.existsSync(keyPath) && fs.existsSync(certFilePath) && fs.existsSync(chainPath)) {
|
|
627
|
+
const key = fs.readFileSync(keyPath, 'utf8');
|
|
628
|
+
const cert = fs.readFileSync(certFilePath, 'utf8');
|
|
629
|
+
const chain = fs.readFileSync(chainPath, 'utf8');
|
|
630
|
+
httpsServer = https.createServer({
|
|
631
|
+
...tlsOpts,
|
|
632
|
+
key,
|
|
633
|
+
cert: cert + chain
|
|
634
|
+
}, dispatcher);
|
|
635
|
+
log.warn(`⚠️ Bun runtime detected: using static TLS cert for ${primaryDomain} on port ${portNum}`);
|
|
636
|
+
} else {
|
|
637
|
+
log.warn(`⚠️ Bun runtime detected but cert files missing for ${primaryDomain}; falling back to Greenlock HTTPS server`);
|
|
638
|
+
httpsServer = glx.httpsServer(tlsOpts, dispatcher);
|
|
639
|
+
}
|
|
640
|
+
} else {
|
|
641
|
+
httpsServer = glx.httpsServer(tlsOpts, dispatcher);
|
|
642
|
+
}
|
|
643
|
+
|
|
613
644
|
this.portServers[portNum] = httpsServer;
|
|
614
645
|
|
|
615
646
|
// Handle WebSocket upgrade events
|
|
@@ -621,6 +652,8 @@ class Roster {
|
|
|
621
652
|
} else {
|
|
622
653
|
// Create HTTPS server for custom ports using Greenlock certificates
|
|
623
654
|
const httpsOptions = {
|
|
655
|
+
minVersion: this.tlsMinVersion,
|
|
656
|
+
maxVersion: this.tlsMaxVersion,
|
|
624
657
|
// SNI callback to get certificates dynamically
|
|
625
658
|
SNICallback: (domain, callback) => {
|
|
626
659
|
try {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "roster-server",
|
|
3
|
-
"version": "2.0.
|
|
3
|
+
"version": "2.0.6",
|
|
4
4
|
"description": "👾 RosterServer - A domain host router to host multiple HTTPS.",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"scripts": {
|
|
@@ -26,6 +26,7 @@
|
|
|
26
26
|
"express",
|
|
27
27
|
"greenlock-express",
|
|
28
28
|
"shotx",
|
|
29
|
+
"bun",
|
|
29
30
|
"clasen"
|
|
30
31
|
],
|
|
31
32
|
"author": "Martin Clasen",
|