roster-server 2.2.8 → 2.2.10
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 +2 -2
- package/package.json +1 -1
- package/tasks/lessons.md +1 -0
- package/test/roster-server.test.js +5 -6
- package/vendor/acme-dns-01-cli-wrapper.js +3 -67
package/index.js
CHANGED
|
@@ -247,12 +247,12 @@ class Roster {
|
|
|
247
247
|
this.disableWildcard = options.disableWildcard !== undefined
|
|
248
248
|
? parseBooleanFlag(options.disableWildcard, false)
|
|
249
249
|
: parseBooleanFlag(process.env.ROSTER_DISABLE_WILDCARD, false);
|
|
250
|
-
const combineDefault =
|
|
250
|
+
const combineDefault = false;
|
|
251
251
|
this.combineWildcardCerts = options.combineWildcardCerts !== undefined
|
|
252
252
|
? parseBooleanFlag(options.combineWildcardCerts, combineDefault)
|
|
253
253
|
: parseBooleanFlag(process.env.ROSTER_COMBINE_WILDCARD_CERTS, combineDefault);
|
|
254
254
|
if (isBunRuntime && this.combineWildcardCerts) {
|
|
255
|
-
log.info('Bun runtime detected: combined wildcard certificates enabled
|
|
255
|
+
log.info('Bun runtime detected: combined wildcard certificates enabled (SNI bypass)');
|
|
256
256
|
}
|
|
257
257
|
|
|
258
258
|
const port = options.port === undefined ? 443 : options.port;
|
package/package.json
CHANGED
package/tasks/lessons.md
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
1
|
# Lessons Learned
|
|
2
2
|
|
|
3
3
|
- When wildcard TLS must run under Bun, do not rely on manual DNS instructions; default to API-driven DNS-01 TXT creation/removal (Linode/Akamai) with propagation polling, then fall back to manual mode only when no provider token is configured.
|
|
4
|
+
- Do not keep speculative resolver/workaround attempts that are not the root cause; if a change does not resolve the issue with evidence, revert/simplify immediately so temporary experiments do not become permanent complexity.
|
|
@@ -8,7 +8,6 @@ const http = require('http');
|
|
|
8
8
|
const os = require('os');
|
|
9
9
|
const Roster = require('../index.js');
|
|
10
10
|
const {
|
|
11
|
-
isBunRuntime,
|
|
12
11
|
wildcardRoot,
|
|
13
12
|
hostMatchesWildcard,
|
|
14
13
|
wildcardSubjectForHost,
|
|
@@ -325,14 +324,14 @@ describe('Roster', () => {
|
|
|
325
324
|
else process.env.ROSTER_COMBINE_WILDCARD_CERTS = previous;
|
|
326
325
|
}
|
|
327
326
|
});
|
|
328
|
-
it('defaults combineWildcardCerts
|
|
327
|
+
it('defaults combineWildcardCerts to false', () => {
|
|
329
328
|
const roster = new Roster({ local: false });
|
|
330
|
-
assert.strictEqual(roster.combineWildcardCerts, isBunRuntime);
|
|
331
|
-
});
|
|
332
|
-
it('explicit combineWildcardCerts=false overrides Bun default', () => {
|
|
333
|
-
const roster = new Roster({ local: false, combineWildcardCerts: false });
|
|
334
329
|
assert.strictEqual(roster.combineWildcardCerts, false);
|
|
335
330
|
});
|
|
331
|
+
it('explicit combineWildcardCerts=true enables combined cert mode', () => {
|
|
332
|
+
const roster = new Roster({ local: false, combineWildcardCerts: true });
|
|
333
|
+
assert.strictEqual(roster.combineWildcardCerts, true);
|
|
334
|
+
});
|
|
336
335
|
});
|
|
337
336
|
|
|
338
337
|
describe('register (normal domain)', () => {
|
|
@@ -121,7 +121,6 @@ module.exports.create = function create(config = {}) {
|
|
|
121
121
|
resolver.setServers([server]);
|
|
122
122
|
return { server, resolver };
|
|
123
123
|
});
|
|
124
|
-
const authoritativeResolverClientsByHost = new Map();
|
|
125
124
|
const normalizeProvider = (value) => String(value || '').trim().toLowerCase();
|
|
126
125
|
const configuredProvider = normalizeProvider(
|
|
127
126
|
config.provider
|
|
@@ -151,73 +150,10 @@ module.exports.create = function create(config = {}) {
|
|
|
151
150
|
return candidate ? String(candidate).trim() : '';
|
|
152
151
|
}
|
|
153
152
|
|
|
154
|
-
function zoneCandidatesFromDnsHost(dnsHost) {
|
|
155
|
-
const normalized = String(dnsHost || '')
|
|
156
|
-
.replace(/^_acme-challenge\./, '')
|
|
157
|
-
.replace(/^_greenlock-[^.]+\./, '')
|
|
158
|
-
.replace(/\.$/, '')
|
|
159
|
-
.toLowerCase();
|
|
160
|
-
if (!normalized) return [];
|
|
161
|
-
|
|
162
|
-
const labels = normalized.split('.').filter(Boolean);
|
|
163
|
-
const candidates = [];
|
|
164
|
-
for (let i = 0; i <= labels.length - 2; i += 1) {
|
|
165
|
-
candidates.push(labels.slice(i).join('.'));
|
|
166
|
-
}
|
|
167
|
-
return candidates;
|
|
168
|
-
}
|
|
169
|
-
|
|
170
|
-
async function resolveAuthoritativeResolverClients(dnsHost) {
|
|
171
|
-
const cached = authoritativeResolverClientsByHost.get(dnsHost);
|
|
172
|
-
if (cached) return cached;
|
|
173
|
-
|
|
174
|
-
const candidates = zoneCandidatesFromDnsHost(dnsHost);
|
|
175
|
-
for (const zone of candidates) {
|
|
176
|
-
let nsRecords = [];
|
|
177
|
-
try {
|
|
178
|
-
nsRecords = await dns.resolveNs(zone);
|
|
179
|
-
} catch {
|
|
180
|
-
continue;
|
|
181
|
-
}
|
|
182
|
-
if (!Array.isArray(nsRecords) || nsRecords.length === 0) continue;
|
|
183
|
-
|
|
184
|
-
const clients = [];
|
|
185
|
-
for (const nsNameRaw of nsRecords) {
|
|
186
|
-
const nsName = String(nsNameRaw || '').replace(/\.$/, '');
|
|
187
|
-
if (!nsName) continue;
|
|
188
|
-
let ips = [];
|
|
189
|
-
try {
|
|
190
|
-
ips = await dns.resolve4(nsName);
|
|
191
|
-
} catch {}
|
|
192
|
-
if (ips.length === 0) {
|
|
193
|
-
try {
|
|
194
|
-
ips = await dns.resolve6(nsName);
|
|
195
|
-
} catch {}
|
|
196
|
-
}
|
|
197
|
-
for (const ip of ips) {
|
|
198
|
-
try {
|
|
199
|
-
const resolver = new dns.Resolver();
|
|
200
|
-
resolver.setServers([ip]);
|
|
201
|
-
clients.push({ server: `${nsName}/${ip}`, resolver });
|
|
202
|
-
} catch {}
|
|
203
|
-
}
|
|
204
|
-
}
|
|
205
|
-
|
|
206
|
-
if (clients.length > 0) {
|
|
207
|
-
authoritativeResolverClientsByHost.set(dnsHost, clients);
|
|
208
|
-
return clients;
|
|
209
|
-
}
|
|
210
|
-
}
|
|
211
|
-
|
|
212
|
-
authoritativeResolverClientsByHost.set(dnsHost, []);
|
|
213
|
-
return [];
|
|
214
|
-
}
|
|
215
|
-
|
|
216
153
|
async function resolveTxtRecords(dnsHost) {
|
|
217
154
|
const records = [];
|
|
218
155
|
const errors = [];
|
|
219
|
-
const
|
|
220
|
-
const resolverClients = [...staticResolverClients, ...authClients];
|
|
156
|
+
const resolverClients = staticResolverClients;
|
|
221
157
|
const seenServers = new Set();
|
|
222
158
|
|
|
223
159
|
for (const { server, resolver } of resolverClients) {
|
|
@@ -225,7 +161,7 @@ module.exports.create = function create(config = {}) {
|
|
|
225
161
|
seenServers.add(server);
|
|
226
162
|
|
|
227
163
|
// Primary path: query with dig directly (more reliable under Bun).
|
|
228
|
-
const serverTarget = String(server || '')
|
|
164
|
+
const serverTarget = String(server || '');
|
|
229
165
|
let digAttempted = false;
|
|
230
166
|
if (typeof execFileSync === 'function' && serverTarget) {
|
|
231
167
|
digAttempted = true;
|
|
@@ -254,7 +190,7 @@ module.exports.create = function create(config = {}) {
|
|
|
254
190
|
}
|
|
255
191
|
|
|
256
192
|
// Fallback path only if dig is unavailable/failed unexpectedly.
|
|
257
|
-
if (!digAttempted || records.length === 0) {
|
|
193
|
+
if ((!digAttempted || records.length === 0) && resolver) {
|
|
258
194
|
try {
|
|
259
195
|
const result = await resolver.resolveTxt(dnsHost);
|
|
260
196
|
if (Array.isArray(result)) {
|