@peerbit/server 6.0.41 → 7.0.0

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.
Files changed (84) hide show
  1. package/dist/src/cli.d.ts.map +1 -1
  2. package/dist/src/cli.js +161 -352
  3. package/dist/src/cli.js.map +1 -1
  4. package/dist/src/client.d.ts +1 -1
  5. package/dist/src/client.d.ts.map +1 -1
  6. package/dist/src/client.js +2 -5
  7. package/dist/src/client.js.map +1 -1
  8. package/dist/src/docker.d.ts +70 -1
  9. package/dist/src/docker.d.ts.map +1 -1
  10. package/dist/src/docker.js +559 -14
  11. package/dist/src/docker.js.map +1 -1
  12. package/dist/src/domain-lease.d.ts +126 -0
  13. package/dist/src/domain-lease.d.ts.map +1 -0
  14. package/dist/src/domain-lease.js +800 -0
  15. package/dist/src/domain-lease.js.map +1 -0
  16. package/dist/src/domain.d.ts +50 -2
  17. package/dist/src/domain.d.ts.map +1 -1
  18. package/dist/src/domain.js +484 -67
  19. package/dist/src/domain.js.map +1 -1
  20. package/dist/src/hetzner.d.ts +4 -21
  21. package/dist/src/hetzner.d.ts.map +1 -1
  22. package/dist/src/hetzner.js +4 -116
  23. package/dist/src/hetzner.js.map +1 -1
  24. package/dist/src/nginx-template.conf +19 -1
  25. package/dist/src/remotes.browser.d.ts +4 -1
  26. package/dist/src/remotes.browser.d.ts.map +1 -1
  27. package/dist/src/remotes.browser.js +1 -2
  28. package/dist/src/remotes.browser.js.map +1 -1
  29. package/dist/src/remotes.d.ts +2 -1
  30. package/dist/src/remotes.d.ts.map +1 -1
  31. package/dist/src/remotes.js +1 -0
  32. package/dist/src/remotes.js.map +1 -1
  33. package/dist/src/server.d.ts.map +1 -1
  34. package/dist/src/server.js +3 -5
  35. package/dist/src/server.js.map +1 -1
  36. package/dist/test/api.spec.js +2 -1
  37. package/dist/test/api.spec.js.map +1 -1
  38. package/dist/test/cli.spec.js +48 -1
  39. package/dist/test/cli.spec.js.map +1 -1
  40. package/dist/test/docker.spec.d.ts +2 -0
  41. package/dist/test/docker.spec.d.ts.map +1 -0
  42. package/dist/test/docker.spec.js +822 -0
  43. package/dist/test/docker.spec.js.map +1 -0
  44. package/dist/test/domain-lease.spec.d.ts +2 -0
  45. package/dist/test/domain-lease.spec.d.ts.map +1 -0
  46. package/dist/test/domain-lease.spec.js +530 -0
  47. package/dist/test/domain-lease.spec.js.map +1 -0
  48. package/dist/test/domain.integration.spec.js +358 -75
  49. package/dist/test/domain.integration.spec.js.map +1 -1
  50. package/dist/test/remotes.spec.d.ts +2 -0
  51. package/dist/test/remotes.spec.d.ts.map +1 -0
  52. package/dist/test/remotes.spec.js +15 -0
  53. package/dist/test/remotes.spec.js.map +1 -0
  54. package/dist/tsconfig.tsbuildinfo +1 -1
  55. package/dist/ui/assets/index-CjZwCewh.js +10 -0
  56. package/dist/ui/assets/index-e3g42MbC.js +9 -0
  57. package/dist/ui/index.html +1 -1
  58. package/package.json +14 -19
  59. package/src/cli.ts +204 -408
  60. package/src/client.ts +2 -6
  61. package/src/docker.ts +841 -20
  62. package/src/domain-lease.ts +1118 -0
  63. package/src/domain.ts +650 -90
  64. package/src/hetzner.ts +4 -184
  65. package/src/nginx-template.conf +19 -1
  66. package/src/remotes.browser.ts +7 -1
  67. package/src/remotes.ts +6 -1
  68. package/src/server.ts +3 -5
  69. package/dist/src/aws.browser.d.ts +0 -2
  70. package/dist/src/aws.browser.d.ts.map +0 -1
  71. package/dist/src/aws.browser.js +0 -3
  72. package/dist/src/aws.browser.js.map +0 -1
  73. package/dist/src/aws.d.ts +0 -30
  74. package/dist/src/aws.d.ts.map +0 -1
  75. package/dist/src/aws.js +0 -240
  76. package/dist/src/aws.js.map +0 -1
  77. package/dist/test/launch.spec.d.ts +0 -2
  78. package/dist/test/launch.spec.d.ts.map +0 -1
  79. package/dist/test/launch.spec.js +0 -23
  80. package/dist/test/launch.spec.js.map +0 -1
  81. package/dist/ui/assets/index-BBTKOM0z.js +0 -6
  82. package/dist/ui/assets/index-DVtj_GOf.js +0 -13
  83. package/src/aws.browser.ts +0 -1
  84. package/src/aws.ts +0 -327
@@ -1,6 +1,17 @@
1
1
  /* eslint-disable no-console */
2
- import { waitFor } from "@peerbit/time";
2
+ import { delay } from "@peerbit/time";
3
3
  const isNode = typeof process !== "undefined" && process.versions?.node != null;
4
+ export const CERTBOT_IMAGE = "jonasal/nginx-certbot:6.2.0-nginx1.31.2@sha256:59c217749aa27effc5109249902e1f5cdbfdfa26721d7dbd4e7162380a07c2cc";
5
+ export const CERTBOT_MANAGED_LABEL = "org.peerbit.managed";
6
+ export const CERTBOT_MANAGED_LABEL_VALUE = "nginx-certbot";
7
+ const CERTBOT_MOUNT_DESTINATIONS = [
8
+ "/etc/letsencrypt",
9
+ "/etc/nginx/user_conf.d",
10
+ "/usr/share/nginx/html",
11
+ ];
12
+ const DOMAIN_STATE_FOLDER = ".peerbit-domain";
13
+ const DOMAIN_GENERATIONS_FOLDER = "generations";
14
+ const ACTIVE_DOMAIN_GENERATION_FILE = "active";
4
15
  const getConfigFileTemplate = async () => {
5
16
  const url = await import("url");
6
17
  const filename = url.fileURLToPath(import.meta.url);
@@ -9,18 +20,9 @@ const getConfigFileTemplate = async () => {
9
20
  const file = fs.readFileSync(path.join(filename, "../nginx-template.conf"), "utf-8");
10
21
  return file;
11
22
  };
12
- const getNginxFolderPath = async () => {
13
- const { exec } = await import("child_process");
14
- const pwd = await new Promise((resolve, reject) => {
15
- exec("pwd", (error, stdout, stderr) => {
16
- if (error || stderr) {
17
- reject("Failed to get current directory");
18
- }
19
- resolve(stdout.trimEnd());
20
- });
21
- });
23
+ const getLegacyNginxFolderPath = async () => {
22
24
  const path = await import("path");
23
- const nginxConfigPath = path.join(pwd, "nginx");
25
+ const nginxConfigPath = path.join(process.cwd(), "nginx");
24
26
  return nginxConfigPath;
25
27
  };
26
28
  const getNginxConfigPath = async (folder) => {
@@ -34,22 +36,27 @@ const createConfig = async (outputPath, domain) => {
34
36
  let file = await getConfigFileTemplate();
35
37
  file = file.replaceAll("%DOMAIN%", domain);
36
38
  const fs = await import("fs");
37
- fs.mkdir(outputPath, { recursive: true }, (err) => {
38
- if (err)
39
- throw err;
40
- });
41
- await waitFor(() => fs.existsSync(outputPath));
39
+ fs.mkdirSync(outputPath, { recursive: true });
42
40
  fs.writeFileSync(await getNginxConfigPath(outputPath), file);
43
41
  return { domain };
44
42
  };
45
43
  export const loadConfig = async () => {
46
- const configFilePath = await getNginxConfigPath(await getNginxFolderPath());
47
44
  const fs = await import("fs");
48
- if (!fs.existsSync(configFilePath)) {
49
- return undefined;
45
+ const path = await import("path");
46
+ const stateRoot = path.join(process.cwd(), DOMAIN_STATE_FOLDER);
47
+ const activeGenerationPath = path.join(stateRoot, ACTIVE_DOMAIN_GENERATION_FILE);
48
+ if (fs.existsSync(activeGenerationPath)) {
49
+ const generation = normalizeDomainGenerationName(fs.readFileSync(activeGenerationPath, "utf8").trim());
50
+ const activeConfigPath = await getNginxConfigPath(path.join(stateRoot, DOMAIN_GENERATIONS_FOLDER, generation, "nginx"));
51
+ if (!fs.existsSync(activeConfigPath)) {
52
+ throw new Error(`Active domain configuration ${generation} is missing ${activeConfigPath}; repair or remove ${activeGenerationPath}`);
53
+ }
54
+ return fs.readFileSync(activeConfigPath, "utf-8");
50
55
  }
51
- const file = fs.readFileSync(configFilePath, "utf-8");
52
- return file;
56
+ const legacyConfigPath = await getNginxConfigPath(await getLegacyNginxFolderPath());
57
+ return fs.existsSync(legacyConfigPath)
58
+ ? fs.readFileSync(legacyConfigPath, "utf-8")
59
+ : undefined;
53
60
  };
54
61
  export const getDomainFromConfig = async (config) => {
55
62
  const pattern = "/etc/letsencrypt/live/(.*)/fullchain.pem";
@@ -57,6 +64,102 @@ export const getDomainFromConfig = async (config) => {
57
64
  const domain = match?.[1];
58
65
  return domain === "%DOMAIN%" ? undefined : domain;
59
66
  };
67
+ export const normalizeDomain = (domain) => {
68
+ const normalized = domain.trim().toLowerCase().replace(/\.$/, "");
69
+ const labels = normalized.split(".");
70
+ const isValidLabel = (label) => label.length > 0 &&
71
+ label.length <= 63 &&
72
+ /^[a-z0-9](?:[a-z0-9-]*[a-z0-9])?$/.test(label);
73
+ if (normalized.length > 253 ||
74
+ labels.length < 2 ||
75
+ !labels.every(isValidLabel)) {
76
+ throw new Error(`Invalid domain: ${domain}`);
77
+ }
78
+ return normalized;
79
+ };
80
+ export const isPeerbitDomainReadyResponse = (response) => response.status === 200 &&
81
+ typeof response.data === "string" &&
82
+ response.data.includes("<title>Peerbit</title>") &&
83
+ response.data.includes('content="Peerbit node"');
84
+ export const isPeerbitDomainChallengeResponse = (response, challengeToken) => response.status === 200 && response.data === challengeToken;
85
+ export const waitForPeerbitDomain = async (domain, options = {}) => {
86
+ domain = normalizeDomain(domain);
87
+ const challengeToken = options.challengeToken;
88
+ if (challengeToken && !/^[a-f0-9]{64}$/.test(challengeToken)) {
89
+ throw new Error("Domain readiness challenge token is invalid");
90
+ }
91
+ const timeoutMs = options.timeoutMs ?? 5 * 60 * 1000;
92
+ const delayIntervalMs = options.delayIntervalMs ?? 5000;
93
+ const requestTimeoutMs = options.requestTimeoutMs ?? 5000;
94
+ if (!Number.isFinite(timeoutMs) || timeoutMs <= 0) {
95
+ throw new Error("Domain readiness timeout must be positive");
96
+ }
97
+ if (!Number.isFinite(requestTimeoutMs) || requestTimeoutMs <= 0) {
98
+ throw new Error("Domain readiness request timeout must be positive");
99
+ }
100
+ if (!Number.isFinite(delayIntervalMs) || delayIntervalMs < 0) {
101
+ throw new Error("Domain readiness delay must not be negative");
102
+ }
103
+ let request = options.request;
104
+ if (!request) {
105
+ const { default: axios } = await import("axios");
106
+ request = (url, requestOptions) => axios.get(url, {
107
+ headers: {
108
+ "Cache-Control": "no-cache, no-store",
109
+ Pragma: "no-cache",
110
+ },
111
+ maxRedirects: 0,
112
+ responseType: "text",
113
+ signal: requestOptions.signal,
114
+ timeout: requestOptions.timeoutMs,
115
+ validateStatus: () => true,
116
+ });
117
+ }
118
+ const deadline = Date.now() + timeoutMs;
119
+ let attempt = 0;
120
+ while (Date.now() < deadline) {
121
+ const remainingMs = deadline - Date.now();
122
+ const attemptTimeoutMs = Math.min(requestTimeoutMs, remainingMs);
123
+ const controller = new AbortController();
124
+ let timer;
125
+ try {
126
+ attempt += 1;
127
+ const requestUrl = challengeToken
128
+ ? `https://${domain}/.well-known/peerbit-generation/${challengeToken}?attempt=${attempt}`
129
+ : `https://${domain}`;
130
+ const response = await Promise.race([
131
+ request(requestUrl, {
132
+ signal: controller.signal,
133
+ timeoutMs: attemptTimeoutMs,
134
+ }),
135
+ new Promise((_resolve, reject) => {
136
+ timer = setTimeout(() => {
137
+ controller.abort();
138
+ reject(new Error("Domain readiness request timed out"));
139
+ }, attemptTimeoutMs);
140
+ }),
141
+ ]);
142
+ if (challengeToken
143
+ ? isPeerbitDomainChallengeResponse(response, challengeToken)
144
+ : isPeerbitDomainReadyResponse(response)) {
145
+ return;
146
+ }
147
+ }
148
+ catch {
149
+ // DNS, TLS, HTTP, and per-request timeout failures are retried until the
150
+ // overall deadline. The old container remains available for rollback.
151
+ }
152
+ finally {
153
+ if (timer)
154
+ clearTimeout(timer);
155
+ controller.abort();
156
+ }
157
+ const sleepMs = Math.min(delayIntervalMs, deadline - Date.now());
158
+ if (sleepMs > 0)
159
+ await delay(sleepMs);
160
+ }
161
+ throw new Error(`Timed out waiting for Peerbit at https://${domain}`);
162
+ };
60
163
  const getUIPath = async () => {
61
164
  const url = await import("url");
62
165
  const path = await import("path");
@@ -74,65 +177,379 @@ const getUIPath = async () => {
74
177
  throw new Error("Failed to find UI path");
75
178
  }
76
179
  };
77
- export const getMyIp = async () => {
78
- const { exec } = await import("child_process");
79
- const ipv4 = await new Promise((resolve, reject) => {
80
- exec("dig @resolver4.opendns.com myip.opendns.com +short", (error, stdout, stderr) => {
81
- if (error || stderr) {
82
- reject("DNS lookup failed");
83
- }
84
- resolve(stdout.trimEnd());
85
- });
86
- });
87
- return ipv4;
88
- };
89
- export const createTestDomain = async () => {
90
- const { default: axios } = await import("axios");
91
- const domain = (await axios.post("https://bfbbnhwpfj2ptcmurz6lit4xlu0vjajw.lambda-url.us-east-1.on.aws", await getMyIp(), { headers: { "Content-Type": "application/json" } })).data.domain;
92
- return domain;
93
- };
94
180
  const validateEmail = (email) => {
95
181
  return String(email)
96
182
  .toLowerCase()
97
183
  .match(/^(([^<>()[\]\\.,;:\s@"]+(\.[^<>()[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/);
98
184
  };
185
+ export const normalizeDockerContainerName = (name) => {
186
+ const normalized = name.trim();
187
+ if (!/^[a-zA-Z0-9][a-zA-Z0-9_.-]{0,127}$/.test(normalized)) {
188
+ throw new Error(`Invalid Docker container name: ${name}`);
189
+ }
190
+ return normalized;
191
+ };
192
+ export const normalizeDomainGenerationName = (name) => {
193
+ if (!/^[a-zA-Z0-9][a-zA-Z0-9-]{0,127}$/.test(name)) {
194
+ throw new Error(`Invalid domain configuration generation: ${name}`);
195
+ }
196
+ return name;
197
+ };
198
+ export const activateDomainGeneration = async (stateRoot, generation) => {
199
+ generation = normalizeDomainGenerationName(generation);
200
+ const fs = await import("fs");
201
+ const path = await import("path");
202
+ fs.mkdirSync(stateRoot, { recursive: true });
203
+ const activePath = path.join(stateRoot, ACTIVE_DOMAIN_GENERATION_FILE);
204
+ const stagingPath = `${activePath}.peerbit-${process.pid}-${Date.now()}`;
205
+ try {
206
+ fs.writeFileSync(stagingPath, generation, "utf8");
207
+ fs.renameSync(stagingPath, activePath);
208
+ }
209
+ finally {
210
+ fs.rmSync(stagingPath, { force: true });
211
+ }
212
+ };
213
+ export const pruneDomainGenerations = async (stateRoot, activeGeneration, keepPrevious = 2) => {
214
+ activeGeneration = normalizeDomainGenerationName(activeGeneration);
215
+ if (!Number.isInteger(keepPrevious) || keepPrevious < 0) {
216
+ throw new Error("Domain generation retention must be a non-negative integer");
217
+ }
218
+ const fs = await import("fs");
219
+ const path = await import("path");
220
+ const generationsRoot = path.join(stateRoot, DOMAIN_GENERATIONS_FOLDER);
221
+ if (!fs.existsSync(generationsRoot))
222
+ return;
223
+ const generations = fs
224
+ .readdirSync(generationsRoot, { withFileTypes: true })
225
+ .filter((entry) => entry.isDirectory())
226
+ .map((entry) => entry.name)
227
+ .filter((name) => {
228
+ try {
229
+ normalizeDomainGenerationName(name);
230
+ return true;
231
+ }
232
+ catch {
233
+ return false;
234
+ }
235
+ })
236
+ .sort()
237
+ .reverse();
238
+ const retained = new Set([
239
+ activeGeneration,
240
+ ...generations
241
+ .filter((generation) => generation !== activeGeneration)
242
+ .slice(0, keepPrevious),
243
+ ]);
244
+ for (const generation of generations) {
245
+ if (!retained.has(generation)) {
246
+ fs.rmSync(path.join(generationsRoot, generation), {
247
+ recursive: true,
248
+ force: true,
249
+ });
250
+ }
251
+ }
252
+ };
253
+ export const buildCertbotContainerArguments = (properties) => [
254
+ "run",
255
+ "--name",
256
+ normalizeDockerContainerName(properties.containerName),
257
+ "-d",
258
+ "--net=host",
259
+ "--restart",
260
+ "unless-stopped",
261
+ "--label",
262
+ `${CERTBOT_MANAGED_LABEL}=${CERTBOT_MANAGED_LABEL_VALUE}`,
263
+ "--env",
264
+ `CERTBOT_EMAIL=${properties.email}`,
265
+ ...(properties.staging ? ["--env", "STAGING=1"] : []),
266
+ "-v",
267
+ `${properties.secretsPath}:/etc/letsencrypt`,
268
+ "-v",
269
+ `${properties.nginxConfigPath}:/etc/nginx/user_conf.d:ro`,
270
+ "-v",
271
+ `${properties.uiPath}:/usr/share/nginx/html:ro`,
272
+ CERTBOT_IMAGE,
273
+ ];
274
+ export const isPeerbitCertbotContainer = (inspection) => {
275
+ const destinations = new Set(inspection.Mounts?.map((mount) => mount.Destination).filter(Boolean));
276
+ const hasExpectedMounts = CERTBOT_MOUNT_DESTINATIONS.every((destination) => destinations.has(destination));
277
+ if (!hasExpectedMounts)
278
+ return false;
279
+ if (inspection.Config?.Labels?.[CERTBOT_MANAGED_LABEL] ===
280
+ CERTBOT_MANAGED_LABEL_VALUE) {
281
+ return true;
282
+ }
283
+ return (/^jonasal\/nginx-certbot(?::[A-Za-z0-9_][A-Za-z0-9_.-]{0,127})?(?:@sha256:[a-f0-9]{64})?$/.test(inspection.Config?.Image || "") &&
284
+ inspection.Config?.Env?.some((value) => value.startsWith("CERTBOT_EMAIL=")) === true);
285
+ };
286
+ const getUniqueMountSources = (inspection) => {
287
+ const sources = new Map();
288
+ for (const destination of CERTBOT_MOUNT_DESTINATIONS) {
289
+ const matching = inspection.Mounts?.filter((mount) => mount.Destination === destination && mount.Source) || [];
290
+ if (matching.length !== 1 || !matching[0].Source)
291
+ return undefined;
292
+ sources.set(destination, matching[0].Source);
293
+ }
294
+ return sources;
295
+ };
296
+ /**
297
+ * Discard a staged domain generation only after Docker rollback has produced a
298
+ * complete inventory proving that no remaining transaction container mounts
299
+ * the generation. The active-generation marker is an additional durable guard.
300
+ */
301
+ export const discardDomainGenerationAfterRollback = async (generationRoot, remainingContainers) => {
302
+ const fs = await import("fs");
303
+ const path = await import("path");
304
+ if (!fs.existsSync(generationRoot))
305
+ return true;
306
+ const resolvedGenerationRoot = fs.realpathSync(generationRoot);
307
+ const generation = path.basename(resolvedGenerationRoot);
308
+ const stateRoot = path.dirname(path.dirname(resolvedGenerationRoot));
309
+ const activePath = path.join(stateRoot, ACTIVE_DOMAIN_GENERATION_FILE);
310
+ if (fs.existsSync(activePath)) {
311
+ let activeGeneration;
312
+ try {
313
+ activeGeneration = normalizeDomainGenerationName(fs.readFileSync(activePath, "utf8").trim());
314
+ }
315
+ catch {
316
+ return false;
317
+ }
318
+ if (activeGeneration === generation)
319
+ return false;
320
+ }
321
+ const contains = (parent, candidate) => {
322
+ const relative = path.relative(parent, candidate);
323
+ return (relative === "" ||
324
+ (!relative.startsWith(`..${path.sep}`) &&
325
+ relative !== ".." &&
326
+ !path.isAbsolute(relative)));
327
+ };
328
+ for (const container of remainingContainers) {
329
+ for (const mount of container.Mounts || []) {
330
+ if (!mount.Source)
331
+ continue;
332
+ let resolvedSource;
333
+ try {
334
+ resolvedSource = fs.realpathSync(mount.Source);
335
+ }
336
+ catch {
337
+ resolvedSource = path.resolve(mount.Source);
338
+ }
339
+ if (contains(resolvedGenerationRoot, resolvedSource) ||
340
+ contains(resolvedSource, resolvedGenerationRoot)) {
341
+ return false;
342
+ }
343
+ }
344
+ }
345
+ fs.rmSync(resolvedGenerationRoot, { recursive: true, force: true });
346
+ return true;
347
+ };
348
+ const getMountedDomainGeneration = async (inspection) => {
349
+ const path = await import("path");
350
+ const sources = getUniqueMountSources(inspection);
351
+ const source = sources?.get("/etc/nginx/user_conf.d");
352
+ if (!source)
353
+ return undefined;
354
+ const nginxPath = path.resolve(source);
355
+ if (path.basename(nginxPath) !== "nginx")
356
+ return undefined;
357
+ const generationRoot = path.dirname(nginxPath);
358
+ const generation = path.basename(generationRoot);
359
+ const generationsRoot = path.dirname(generationRoot);
360
+ const stateRoot = path.dirname(generationsRoot);
361
+ if (path.basename(generationsRoot) !== DOMAIN_GENERATIONS_FOLDER ||
362
+ path.basename(stateRoot) !== DOMAIN_STATE_FOLDER) {
363
+ return undefined;
364
+ }
365
+ try {
366
+ normalizeDomainGenerationName(generation);
367
+ }
368
+ catch {
369
+ return undefined;
370
+ }
371
+ return {
372
+ configPath: path.join(nginxPath, "default.conf"),
373
+ generation,
374
+ nginxPath,
375
+ stateRoot,
376
+ };
377
+ };
378
+ const readActiveDomainGeneration = async (stateRoot) => {
379
+ const fs = await import("fs");
380
+ const path = await import("path");
381
+ const activePath = path.join(stateRoot, ACTIVE_DOMAIN_GENERATION_FILE);
382
+ if (!fs.existsSync(activePath))
383
+ return { kind: "missing" };
384
+ try {
385
+ return {
386
+ generation: normalizeDomainGenerationName(fs.readFileSync(activePath, "utf8").trim()),
387
+ kind: "value",
388
+ };
389
+ }
390
+ catch {
391
+ return { kind: "invalid" };
392
+ }
393
+ };
394
+ /**
395
+ * Reconcile a crash that left both the replacement and its backup. The active
396
+ * generation file is the commit marker; malformed or cross-root state is left
397
+ * untouched for an operator rather than guessed at.
398
+ */
399
+ export const resolvePeerbitCertbotInterruptedPair = async (current, backup) => {
400
+ if (!isPeerbitCertbotContainer(current) ||
401
+ !isPeerbitCertbotContainer(backup)) {
402
+ return undefined;
403
+ }
404
+ const currentSources = getUniqueMountSources(current);
405
+ const backupSources = getUniqueMountSources(backup);
406
+ if (!currentSources || !backupSources)
407
+ return undefined;
408
+ const path = await import("path");
409
+ if (path.resolve(currentSources.get("/etc/letsencrypt")) !==
410
+ path.resolve(backupSources.get("/etc/letsencrypt"))) {
411
+ return undefined;
412
+ }
413
+ const currentGeneration = await getMountedDomainGeneration(current);
414
+ if (!currentGeneration)
415
+ return undefined;
416
+ const backupGeneration = await getMountedDomainGeneration(backup);
417
+ const legacyNginxPath = path.resolve(path.dirname(currentGeneration.stateRoot), "nginx");
418
+ if (backupGeneration
419
+ ? backupGeneration.stateRoot !== currentGeneration.stateRoot
420
+ : path.resolve(backupSources.get("/etc/nginx/user_conf.d")) !==
421
+ legacyNginxPath) {
422
+ return undefined;
423
+ }
424
+ const active = await readActiveDomainGeneration(currentGeneration.stateRoot);
425
+ const fs = await import("fs");
426
+ if (active.kind === "value" &&
427
+ active.generation === currentGeneration.generation) {
428
+ const currentIsStable = current.State?.Running === true &&
429
+ current.State.Restarting !== true &&
430
+ (current.RestartCount ?? 0) === 0 &&
431
+ current.State.Health?.Status !== "unhealthy";
432
+ return currentIsStable && fs.existsSync(currentGeneration.configPath)
433
+ ? "keep-current"
434
+ : undefined;
435
+ }
436
+ if (active.kind !== "value" && active.kind !== "missing")
437
+ return undefined;
438
+ if (backupGeneration &&
439
+ backupGeneration.stateRoot === currentGeneration.stateRoot &&
440
+ active.kind === "value" &&
441
+ active.generation === backupGeneration.generation &&
442
+ fs.existsSync(backupGeneration.configPath)) {
443
+ return "restore-backup";
444
+ }
445
+ if (active.kind !== "missing" || backupGeneration)
446
+ return undefined;
447
+ return "restore-backup";
448
+ };
449
+ export const getCertbotSecretsPath = (inspection, fallback) => {
450
+ if (!inspection)
451
+ return fallback;
452
+ const source = inspection.Mounts?.find((mount) => mount.Destination === "/etc/letsencrypt")?.Source;
453
+ if (!source) {
454
+ throw new Error("Existing Peerbit certificate container has no host certificate mount");
455
+ }
456
+ return source;
457
+ };
458
+ export const replaceUiFolder = async (source, destination) => {
459
+ const fs = await import("fs");
460
+ const path = await import("path");
461
+ fs.mkdirSync(path.dirname(destination), { recursive: true });
462
+ const staging = `${destination}.peerbit-${process.pid}-${Date.now()}`;
463
+ fs.rmSync(staging, { recursive: true, force: true });
464
+ try {
465
+ fs.cpSync(source, staging, { recursive: true });
466
+ fs.rmSync(destination, { recursive: true, force: true });
467
+ fs.renameSync(staging, destination);
468
+ }
469
+ finally {
470
+ fs.rmSync(staging, { recursive: true, force: true });
471
+ }
472
+ };
99
473
  export const startCertbot = async (domain, email, waitForUp = false, dockerProcessName = "nginx-certbot") => {
474
+ domain = normalizeDomain(domain);
475
+ dockerProcessName = normalizeDockerContainerName(dockerProcessName);
100
476
  if (!validateEmail(email)) {
101
- throw new Error("Email for SSL renenewal is invalid");
477
+ throw new Error("Email for SSL renewal is invalid");
102
478
  }
103
- const { installDocker, startContainer } = await import("./docker.js");
104
- const nginxConfigPath = await getNginxFolderPath();
105
- await createConfig(nginxConfigPath, domain);
479
+ const { installDocker, pullDockerImage, replaceDockerContainer } = await import("./docker.js");
106
480
  await installDocker();
107
- // run
481
+ await pullDockerImage(CERTBOT_IMAGE);
108
482
  const isTest = process.env.JEST_WORKER_ID !== undefined;
109
- const uiPath = await getUIPath();
110
- // copy ui from node_modules to home for permission reasons (volume will not work otherwise)
111
- const certbotDockerCommand = `cp -r ${uiPath} $(pwd)/ui && docker pull jonasal/nginx-certbot:latest && docker run -d --net=host \
112
- --restart unless-stopped \
113
- --env CERTBOT_EMAIL=${email} ${isTest ? "--env STAGING=1" : ""}\
114
- -v $(pwd)/nginx_secrets:/etc/letsencrypt \
115
- -v ${nginxConfigPath}:/etc/nginx/user_conf.d:ro \
116
- -v $(pwd)/ui:/usr/share/nginx/html:ro \
117
- --name ${dockerProcessName} jonasal/nginx-certbot:latest`;
118
- console.log("Starting Certbot");
119
- // try two times with some delay, because sometimes the docker daemon is not available immidatel
120
- await startContainer(certbotDockerCommand, "Failed to start certbot container");
483
+ const fs = await import("fs");
484
+ const path = await import("path");
485
+ const { randomBytes, randomUUID } = await import("crypto");
486
+ const stateRoot = path.join(process.cwd(), DOMAIN_STATE_FOLDER);
487
+ const generation = normalizeDomainGenerationName(`${Date.now()}-${randomUUID()}`);
488
+ const generationRoot = path.join(stateRoot, DOMAIN_GENERATIONS_FOLDER, generation);
489
+ const nginxConfigPath = path.join(generationRoot, "nginx");
490
+ const uiPath = path.join(generationRoot, "ui");
491
+ const readinessChallenge = randomBytes(32).toString("hex");
492
+ let activated = false;
493
+ let replacementPrepared = false;
494
+ let rollbackDispositionHandled = false;
495
+ try {
496
+ await replaceUiFolder(await getUIPath(), uiPath);
497
+ const readinessChallengeDirectory = path.join(uiPath, ".well-known", "peerbit-generation");
498
+ fs.mkdirSync(readinessChallengeDirectory, { recursive: true });
499
+ fs.writeFileSync(path.join(readinessChallengeDirectory, readinessChallenge), readinessChallenge, "utf8");
500
+ await createConfig(nginxConfigPath, domain);
501
+ // Reconfiguration keeps the old container and generation as a stopped
502
+ // backup until the new container and active-generation pointer both succeed.
503
+ console.log("Starting Certbot");
504
+ await replaceDockerContainer(dockerProcessName, (existingContainer) => {
505
+ replacementPrepared = true;
506
+ return buildCertbotContainerArguments({
507
+ containerName: dockerProcessName,
508
+ email,
509
+ nginxConfigPath,
510
+ secretsPath: getCertbotSecretsPath(existingContainer, path.join(stateRoot, "nginx_secrets")),
511
+ uiPath,
512
+ staging: isTest,
513
+ });
514
+ }, {
515
+ onCommitted: async () => {
516
+ try {
517
+ await pruneDomainGenerations(stateRoot, generation);
518
+ }
519
+ catch (error) {
520
+ console.warn(`Domain configuration succeeded, but stale generations could not be pruned: ${error?.message || error}`);
521
+ }
522
+ },
523
+ onCommit: async () => {
524
+ await activateDomainGeneration(stateRoot, generation);
525
+ activated = true;
526
+ },
527
+ onRollbackInspected: async (remainingContainers) => {
528
+ rollbackDispositionHandled = true;
529
+ await discardDomainGenerationAfterRollback(generationRoot, remainingContainers);
530
+ },
531
+ onStarted: async () => {
532
+ if (waitForUp) {
533
+ console.log("Waiting for domain to be ready ...");
534
+ await waitForPeerbitDomain(domain, {
535
+ challengeToken: readinessChallenge,
536
+ });
537
+ }
538
+ },
539
+ resolveInterruptedPair: resolvePeerbitCertbotInterruptedPair,
540
+ validateExisting: isPeerbitCertbotContainer,
541
+ });
542
+ }
543
+ catch (error) {
544
+ if (!activated && !replacementPrepared && !rollbackDispositionHandled) {
545
+ fs.rmSync(generationRoot, { recursive: true, force: true });
546
+ }
547
+ throw error;
548
+ }
121
549
  console.log("Certbot started succesfully!");
122
550
  console.log("You domain is: ");
123
551
  console.log(domain);
124
552
  if (waitForUp) {
125
- const { default: axios } = await import("axios");
126
- console.log("Waiting for domain to be ready ...");
127
- await waitFor(async () => {
128
- try {
129
- const status = (await axios.get("https://" + domain)).status;
130
- return status >= 200 && status < 400;
131
- }
132
- catch (error) {
133
- return false;
134
- }
135
- }, { timeout: 5 * 60 * 10000, delayInterval: 5000 });
136
553
  console.log("Domain is ready");
137
554
  }
138
555
  else {
@@ -1 +1 @@
1
- {"version":3,"file":"domain.js","sourceRoot":"","sources":["../../src/domain.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"domain.js","sourceRoot":"","sources":["../../src/domain.ts"],"names":[],"mappings":"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"}