roster-server 2.1.10 → 2.1.14
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 +49 -9
- 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,6 +725,13 @@ 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
737
|
return greenlock.ready(async glx => {
|
|
@@ -845,14 +853,46 @@ class Roster {
|
|
|
845
853
|
}
|
|
846
854
|
return null;
|
|
847
855
|
};
|
|
856
|
+
const issueAndReloadPemsForServername = async (servername) => {
|
|
857
|
+
const host = normalizeHostInput(servername).trim().toLowerCase();
|
|
858
|
+
if (!host) return null;
|
|
859
|
+
|
|
860
|
+
let pems = resolvePemsForServername(host);
|
|
861
|
+
if (pems) return pems;
|
|
862
|
+
|
|
863
|
+
try {
|
|
864
|
+
await greenlockRuntime.get({ servername: host });
|
|
865
|
+
} catch (error) {
|
|
866
|
+
log.warn(`⚠️ Greenlock issuance failed for ${host}: ${error?.message || error}`);
|
|
867
|
+
}
|
|
868
|
+
|
|
869
|
+
pems = resolvePemsForServername(host);
|
|
870
|
+
if (pems) return pems;
|
|
871
|
+
|
|
872
|
+
// For wildcard zones, try a valid subdomain bootstrap host so Greenlock can
|
|
873
|
+
// resolve the wildcard site without relying on invalid "*.domain" servername input.
|
|
874
|
+
const wildcardSubject = wildcardSubjectForHost(host);
|
|
875
|
+
const zone = wildcardSubject ? wildcardRoot(wildcardSubject) : null;
|
|
876
|
+
if (zone) {
|
|
877
|
+
const bootstrapHost = `bun-bootstrap.${zone}`;
|
|
878
|
+
try {
|
|
879
|
+
await greenlockRuntime.get({ servername: bootstrapHost });
|
|
880
|
+
} catch (error) {
|
|
881
|
+
log.warn(`⚠️ Greenlock wildcard bootstrap failed for ${bootstrapHost}: ${error?.message || error}`);
|
|
882
|
+
}
|
|
883
|
+
pems = resolvePemsForServername(host);
|
|
884
|
+
}
|
|
885
|
+
|
|
886
|
+
return pems;
|
|
887
|
+
};
|
|
848
888
|
const ensureBunDefaultPems = async (primaryDomain) => {
|
|
849
|
-
let pems =
|
|
889
|
+
let pems = await issueAndReloadPemsForServername(primaryDomain);
|
|
850
890
|
if (pems) return pems;
|
|
851
891
|
|
|
852
892
|
const certSubject = primaryDomain.startsWith('*.') ? wildcardRoot(primaryDomain) : primaryDomain;
|
|
853
893
|
log.warn(`⚠️ Bun runtime detected and cert files missing for ${primaryDomain}; requesting certificate via Greenlock before HTTPS bind`);
|
|
854
894
|
try {
|
|
855
|
-
await
|
|
895
|
+
await greenlockRuntime.get({ servername: certSubject });
|
|
856
896
|
} catch (error) {
|
|
857
897
|
log.error(`❌ Failed to obtain certificate for ${certSubject} under Bun:`, error?.message || error);
|
|
858
898
|
}
|
|
@@ -883,12 +923,12 @@ class Roster {
|
|
|
883
923
|
key: defaultPems.key,
|
|
884
924
|
cert: defaultPems.cert,
|
|
885
925
|
SNICallback: (servername, callback) => {
|
|
886
|
-
|
|
887
|
-
|
|
888
|
-
|
|
889
|
-
|
|
890
|
-
|
|
891
|
-
|
|
926
|
+
issueAndReloadPemsForServername(servername)
|
|
927
|
+
.then((pems) => {
|
|
928
|
+
const selected = pems || defaultPems;
|
|
929
|
+
callback(null, tls.createSecureContext({ key: selected.key, cert: selected.cert }));
|
|
930
|
+
})
|
|
931
|
+
.catch(callback);
|
|
892
932
|
}
|
|
893
933
|
}, dispatcher);
|
|
894
934
|
log.warn(`⚠️ Bun runtime detected: using file-based TLS with SNI for ${primaryDomain} on port ${portNum}`);
|