roster-server 2.1.8 → 2.1.12
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/index.js +46 -23
- package/package.json +1 -1
package/index.js
CHANGED
|
@@ -5,6 +5,7 @@ const https = require('https');
|
|
|
5
5
|
const tls = require('tls');
|
|
6
6
|
const { EventEmitter } = require('events');
|
|
7
7
|
const Greenlock = require('./vendor/greenlock-express/greenlock-express.js');
|
|
8
|
+
const GreenlockShim = require('./vendor/greenlock-express/greenlock-shim.js');
|
|
8
9
|
const log = require('lemonlog')('roster');
|
|
9
10
|
|
|
10
11
|
// CRC32 implementation for deterministic port assignment
|
|
@@ -707,7 +708,7 @@ class Roster {
|
|
|
707
708
|
return this.startLocalMode();
|
|
708
709
|
}
|
|
709
710
|
|
|
710
|
-
const
|
|
711
|
+
const greenlockOptions = {
|
|
711
712
|
packageRoot: __dirname,
|
|
712
713
|
configDir: this.greenlockStorePath,
|
|
713
714
|
maintainerEmail: this.email,
|
|
@@ -724,9 +725,16 @@ class Roster {
|
|
|
724
725
|
else if (event === 'warning') log.warn(msg);
|
|
725
726
|
else log.info(msg);
|
|
726
727
|
}
|
|
728
|
+
};
|
|
729
|
+
// Keep a direct greenlock runtime handle so we can call get() explicitly under Bun
|
|
730
|
+
// before binding :443, avoiding invalid non-TLS responses on startup.
|
|
731
|
+
const greenlockRuntime = GreenlockShim.create(greenlockOptions);
|
|
732
|
+
const greenlock = Greenlock.init({
|
|
733
|
+
...greenlockOptions,
|
|
734
|
+
greenlock: greenlockRuntime
|
|
727
735
|
});
|
|
728
736
|
|
|
729
|
-
return greenlock.ready(glx => {
|
|
737
|
+
return greenlock.ready(async glx => {
|
|
730
738
|
const httpServer = glx.httpServer();
|
|
731
739
|
|
|
732
740
|
// Group sites by port
|
|
@@ -845,6 +853,26 @@ class Roster {
|
|
|
845
853
|
}
|
|
846
854
|
return null;
|
|
847
855
|
};
|
|
856
|
+
const ensureBunDefaultPems = async (primaryDomain) => {
|
|
857
|
+
let pems = resolvePemsForServername(primaryDomain);
|
|
858
|
+
if (pems) return pems;
|
|
859
|
+
|
|
860
|
+
const certSubject = primaryDomain.startsWith('*.') ? wildcardRoot(primaryDomain) : primaryDomain;
|
|
861
|
+
log.warn(`⚠️ Bun runtime detected and cert files missing for ${primaryDomain}; requesting certificate via Greenlock before HTTPS bind`);
|
|
862
|
+
try {
|
|
863
|
+
await greenlockRuntime.get({ servername: certSubject });
|
|
864
|
+
} catch (error) {
|
|
865
|
+
log.error(`❌ Failed to obtain certificate for ${certSubject} under Bun:`, error?.message || error);
|
|
866
|
+
}
|
|
867
|
+
|
|
868
|
+
pems = resolvePemsForServername(primaryDomain);
|
|
869
|
+
if (pems) return pems;
|
|
870
|
+
|
|
871
|
+
throw new Error(
|
|
872
|
+
`Bun runtime could not load TLS certificate files for ${primaryDomain}. ` +
|
|
873
|
+
`Refusing to start HTTPS on port ${portNum} to avoid serving invalid TLS.`
|
|
874
|
+
);
|
|
875
|
+
};
|
|
848
876
|
|
|
849
877
|
if (portNum === this.defaultPort) {
|
|
850
878
|
// Bun has known gaps around SNICallback compatibility.
|
|
@@ -855,28 +883,23 @@ class Roster {
|
|
|
855
883
|
|
|
856
884
|
if (isBunRuntime) {
|
|
857
885
|
const primaryDomain = Object.keys(portData.virtualServers)[0];
|
|
858
|
-
//
|
|
859
|
-
|
|
860
|
-
|
|
861
|
-
|
|
862
|
-
|
|
863
|
-
|
|
864
|
-
|
|
865
|
-
|
|
866
|
-
|
|
867
|
-
|
|
868
|
-
|
|
869
|
-
|
|
870
|
-
|
|
871
|
-
callback(error);
|
|
872
|
-
}
|
|
886
|
+
// Under Bun, avoid glx.httpsServer fallback (may serve invalid TLS on :443).
|
|
887
|
+
// Require concrete PEM files and create native https server directly.
|
|
888
|
+
const defaultPems = await ensureBunDefaultPems(primaryDomain);
|
|
889
|
+
httpsServer = https.createServer({
|
|
890
|
+
...tlsOpts,
|
|
891
|
+
key: defaultPems.key,
|
|
892
|
+
cert: defaultPems.cert,
|
|
893
|
+
SNICallback: (servername, callback) => {
|
|
894
|
+
try {
|
|
895
|
+
const pems = resolvePemsForServername(servername) || defaultPems;
|
|
896
|
+
callback(null, tls.createSecureContext({ key: pems.key, cert: pems.cert }));
|
|
897
|
+
} catch (error) {
|
|
898
|
+
callback(error);
|
|
873
899
|
}
|
|
874
|
-
}
|
|
875
|
-
|
|
876
|
-
}
|
|
877
|
-
log.warn(`⚠️ Bun runtime detected but cert files missing for ${primaryDomain}; falling back to Greenlock HTTPS server`);
|
|
878
|
-
httpsServer = glx.httpsServer(tlsOpts, dispatcher);
|
|
879
|
-
}
|
|
900
|
+
}
|
|
901
|
+
}, dispatcher);
|
|
902
|
+
log.warn(`⚠️ Bun runtime detected: using file-based TLS with SNI for ${primaryDomain} on port ${portNum}`);
|
|
880
903
|
} else {
|
|
881
904
|
httpsServer = glx.httpsServer(tlsOpts, dispatcher);
|
|
882
905
|
}
|