roster-server 2.1.30 → 2.1.32

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "roster-server",
3
- "version": "2.1.30",
3
+ "version": "2.1.32",
4
4
  "description": "👾 RosterServer - A domain host router to host multiple HTTPS.",
5
5
  "main": "index.js",
6
6
  "scripts": {
@@ -44,7 +44,7 @@ module.exports.create = function create(config = {}) {
44
44
  const challenger = legacyCli.create(config);
45
45
  const propagationDelay = Number.isFinite(config.propagationDelay)
46
46
  ? config.propagationDelay
47
- : 60000;
47
+ : 120000;
48
48
  const envAutoContinue = process.env.ROSTER_DNS_AUTO_CONTINUE;
49
49
  const parseAutoContinue = (value, fallback) => {
50
50
  if (value === undefined || value === null || value === '') return fallback;
@@ -76,16 +76,23 @@ module.exports.create = function create(config = {}) {
76
76
  : Number.isFinite(Number(process.env.ROSTER_DNS_POLL_INTERVAL_MS))
77
77
  ? Number(process.env.ROSTER_DNS_POLL_INTERVAL_MS)
78
78
  : 5000;
79
- const dnsPollTimeoutMs = Number.isFinite(config.dnsPollTimeoutMs)
80
- ? config.dnsPollTimeoutMs
81
- : Number.isFinite(Number(process.env.ROSTER_DNS_POLL_TIMEOUT_MS))
82
- ? Number(process.env.ROSTER_DNS_POLL_TIMEOUT_MS)
83
- : null;
84
- const dryRunPollTimeoutMs = Number.isFinite(config.dryRunPollTimeoutMs)
85
- ? config.dryRunPollTimeoutMs
86
- : Number.isFinite(Number(process.env.ROSTER_DNS_DRYRUN_POLL_TIMEOUT_MS))
87
- ? Number(process.env.ROSTER_DNS_DRYRUN_POLL_TIMEOUT_MS)
88
- : null;
79
+ const parseTimeoutMs = (value, fallback) => {
80
+ if (value === undefined || value === null || value === '') return fallback;
81
+ const normalized = String(value).trim().toLowerCase();
82
+ if (normalized === '-1' || normalized === 'inf' || normalized === 'infinite') return null;
83
+ const parsed = Number(normalized);
84
+ if (Number.isFinite(parsed) && parsed >= 0) return parsed;
85
+ return fallback;
86
+ };
87
+ const dnsPollTimeoutMs = config.dnsPollTimeoutMs !== undefined
88
+ ? parseTimeoutMs(config.dnsPollTimeoutMs, propagationDelay)
89
+ : parseTimeoutMs(process.env.ROSTER_DNS_POLL_TIMEOUT_MS, propagationDelay);
90
+ const dryRunPollTimeoutMs = config.dryRunPollTimeoutMs !== undefined
91
+ ? parseTimeoutMs(config.dryRunPollTimeoutMs, dryRunDelay)
92
+ : parseTimeoutMs(process.env.ROSTER_DNS_DRYRUN_POLL_TIMEOUT_MS, dryRunDelay);
93
+ const dnsPollDebug = config.dnsPollDebug !== undefined
94
+ ? parseBool(config.dnsPollDebug, true)
95
+ : parseBool(process.env.ROSTER_DNS_POLL_DEBUG, true);
89
96
  const parseResolvers = (value) => String(value || '')
90
97
  .split(',')
91
98
  .map((s) => s.trim())
@@ -93,7 +100,8 @@ module.exports.create = function create(config = {}) {
93
100
  const configuredResolvers = Array.isArray(config.dnsResolvers)
94
101
  ? config.dnsResolvers.map((s) => String(s).trim()).filter(Boolean)
95
102
  : parseResolvers(process.env.ROSTER_DNS_RESOLVERS);
96
- const resolverClients = configuredResolvers.map((server) => {
103
+ const effectiveResolvers = configuredResolvers.length > 0 ? configuredResolvers : ['1.1.1.1', '8.8.8.8'];
104
+ const resolverClients = effectiveResolvers.map((server) => {
97
105
  const resolver = new dns.Resolver();
98
106
  resolver.setServers([server]);
99
107
  return { server, resolver };
@@ -114,43 +122,46 @@ module.exports.create = function create(config = {}) {
114
122
 
115
123
  async function resolveTxtRecords(dnsHost) {
116
124
  const records = [];
117
- if (resolverClients.length === 0) {
118
- return await dns.resolveTxt(dnsHost);
119
- }
125
+ const errors = [];
120
126
 
121
- for (const { resolver } of resolverClients) {
127
+ for (const { server, resolver } of resolverClients) {
122
128
  try {
123
129
  const result = await resolver.resolveTxt(dnsHost);
124
130
  if (Array.isArray(result)) {
125
131
  records.push(...result);
126
132
  }
127
- } catch (_) {
128
- // Try next configured resolver
129
- }
130
- }
131
- return records;
132
- }
133
-
134
- async function hasDnsTxtToken(dnsHost, expectedToken) {
135
- if (!dnsHost || !expectedToken) return false;
136
- try {
137
- const records = await resolveTxtRecords(dnsHost);
138
- for (const recordParts of records || []) {
139
- const joined = (recordParts || []).map(normalizeTxtChunk).join('').trim();
140
- if (joined === expectedToken) return true;
133
+ } catch (error) {
134
+ errors.push(`${server}:${error?.code || error?.message || error}`);
141
135
  }
142
- return false;
143
- } catch (_) {
144
- return false;
145
136
  }
137
+ return { records, errors };
146
138
  }
147
139
 
148
140
  async function waitForDnsTxtPropagation(dnsHost, expectedToken, timeoutMs) {
149
141
  const started = Date.now();
150
142
  const hasFiniteTimeout = Number.isFinite(timeoutMs) && timeoutMs >= 0;
151
143
  const maxWait = hasFiniteTimeout ? timeoutMs : null;
144
+ let attempt = 0;
152
145
  while (maxWait === null || (Date.now() - started) <= maxWait) {
153
- if (await hasDnsTxtToken(dnsHost, expectedToken)) return true;
146
+ attempt += 1;
147
+ const { records, errors } = await resolveTxtRecords(dnsHost);
148
+ const seenTokens = [];
149
+ let found = false;
150
+ for (const recordParts of records || []) {
151
+ const joined = (recordParts || []).map(normalizeTxtChunk).join('').trim();
152
+ if (joined) seenTokens.push(joined);
153
+ if (joined === expectedToken) {
154
+ found = true;
155
+ }
156
+ }
157
+
158
+ if (dnsPollDebug) {
159
+ const errorMsg = errors.length > 0 ? ` errors=[${errors.join(', ')}]` : '';
160
+ const seenMsg = seenTokens.length > 0 ? ` seen=[${seenTokens.join(', ')}]` : ' seen=[]';
161
+ log.info(`DNS poll attempt ${attempt} ${dnsHost}${seenMsg}${errorMsg}`);
162
+ }
163
+
164
+ if (found) return true;
154
165
  await sleep(Math.max(1000, dnsPollIntervalMs));
155
166
  }
156
167
  return false;
@@ -189,8 +200,8 @@ module.exports.create = function create(config = {}) {
189
200
  'DNS verification enabled. Continuing automatically when TXT appears at ' +
190
201
  dnsHost +
191
202
  ' (timeout ' +
192
- (effectiveTimeoutMs === null ? 'infinite' : effectiveTimeoutMs) +
193
- 'ms, poll ' +
203
+ (effectiveTimeoutMs === null ? 'infinite' : (effectiveTimeoutMs + 'ms')) +
204
+ ', poll ' +
194
205
  dnsPollIntervalMs +
195
206
  'ms).'
196
207
  );
@@ -200,7 +211,7 @@ module.exports.create = function create(config = {}) {
200
211
  return null;
201
212
  }
202
213
  log.warn(
203
- `DNS TXT not detected for ${dnsHost} within ${effectiveTimeoutMs}; ` +
214
+ `DNS TXT not detected for ${dnsHost} within ${effectiveTimeoutMs === null ? 'infinite' : (effectiveTimeoutMs + 'ms')}; ` +
204
215
  'continuing anyway (ACME preflight may still fail).'
205
216
  );
206
217
  return null;