openship 0.6.5 → 0.6.7

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 (68) hide show
  1. package/dist/bare-7QD623QV.js +29 -0
  2. package/dist/chunk-2ANV5ZQ5.js +88 -0
  3. package/dist/{chunk-LEYSL46B.js → chunk-2VSW6Q6C.js} +3911 -898
  4. package/dist/{chunk-5OUWIPOB.js → chunk-5T4UVOM3.js} +16 -86
  5. package/dist/{chunk-EZPPTWJQ.js → chunk-BLEXTYRK.js} +1 -1
  6. package/dist/{chunk-3ZAGC5NT.js → chunk-CIJV43LH.js} +83 -33
  7. package/dist/{chunk-7S4USQYF.js → chunk-DDFUESPJ.js} +67 -124
  8. package/dist/{chunk-6FH4AXVY.js → chunk-E2X26PXR.js} +1 -1
  9. package/dist/{chunk-XVOBL7BC.js → chunk-FYPFEDPZ.js} +1 -1
  10. package/dist/{chunk-WFRXYWK2.js → chunk-FZ6QCF6B.js} +8 -6
  11. package/dist/{chunk-VHMOQL5Y.js → chunk-GGIAIGUL.js} +125 -80
  12. package/dist/{chunk-WE7BXW6L.js → chunk-GIPJNNI5.js} +38 -44
  13. package/dist/{chunk-ZFJXPCQP.js → chunk-H3WT3A6R.js} +4 -3
  14. package/dist/chunk-H4FS5BED.js +936 -0
  15. package/dist/{chunk-HPXP6LXZ.js → chunk-J2XM3QSP.js} +8 -5
  16. package/dist/{chunk-6JELW75A.js → chunk-J3K6XABC.js} +5 -5
  17. package/dist/{chunk-VDESJSG6.js → chunk-LHFXSC36.js} +558 -109
  18. package/dist/{chunk-MSZUCNPV.js → chunk-MEE6OZFP.js} +3 -3
  19. package/dist/chunk-N5YZMO33.js +111 -0
  20. package/dist/{chunk-VLQ3UIVO.js → chunk-NRTJRNAE.js} +105 -37
  21. package/dist/chunk-PPEBIY5F.js +2331 -0
  22. package/dist/{chunk-RFWJE7ZN.js → chunk-PVP4RGWT.js} +3 -3
  23. package/dist/{chunk-PZRRL5PC.js → chunk-QHMDCYZ3.js} +15 -4
  24. package/dist/chunk-R4VDPFLS.js +106 -0
  25. package/dist/chunk-RDXT4BQB.js +310 -0
  26. package/dist/{chunk-GRTXMUHA.js → chunk-S6B2Z3OO.js} +145 -60
  27. package/dist/chunk-UWEV6XTS.js +249 -0
  28. package/dist/{chunk-QLX7NBEA.js → chunk-VQM6JHJB.js} +1004 -2046
  29. package/dist/{chunk-A7EWM2KA.js → chunk-VSTFHUCV.js} +44 -50
  30. package/dist/chunk-WU54BXFE.js +70 -0
  31. package/dist/{chunk-LFCSC4IU.js → chunk-XWHWTHEL.js} +313 -469
  32. package/dist/{chunk-7334NSJL.js → chunk-ZPJ74LXE.js} +76 -38
  33. package/dist/cloud-KNNABE3O.js +40 -0
  34. package/dist/{detect-P4CIQBRH.js → detect-G4DR3U2N.js} +9 -6
  35. package/dist/{docker-3K2NEBD6.js → docker-YOVPCIB4.js} +11 -7
  36. package/dist/{docker-edge-executor-YZZ6P7IC.js → docker-edge-executor-QFXD3337.js} +8 -6
  37. package/dist/edge-import-CRFVSR6P.js +56 -0
  38. package/dist/{edge-preflight-ES6FH4JK.js → edge-preflight-MXERVAMG.js} +15 -12
  39. package/dist/{ensure-container-edge-YPITNH45.js → ensure-container-edge-F4JUNQIK.js} +13 -10
  40. package/dist/{executor-DZGX55K2.js → executor-CVPAYYHR.js} +10 -5
  41. package/dist/host-channel-preflight-QTDNGLCK.js +54 -0
  42. package/dist/index.js +139 -92
  43. package/dist/{local-executor-WOFZD72X.js → local-executor-ODC6RANU.js} +3 -2
  44. package/dist/{nginx-NSAHWGJV.js → nginx-KLFF43TC.js} +13 -8
  45. package/dist/{openresty-lua-DR4D3EZ6.js → openresty-lua-VKWUV4GB.js} +8 -5
  46. package/dist/{privilege-YTVI4SKF.js → privilege-7D3SSOL3.js} +6 -5
  47. package/dist/server/engine/samples/amavisd/amavisd.conf +25 -0
  48. package/dist/server/engine/samples/postfix/master.cf +14 -0
  49. package/dist/server/index.js +44526 -33476
  50. package/dist/server/migrations/0105_mail_inbound_rules.sql +80 -0
  51. package/dist/server/migrations/0106_mcp_call_tracking.sql +23 -0
  52. package/dist/server/migrations/0107_build_minute_metering_indexes.sql +20 -0
  53. package/dist/server/migrations/0108_credential.sql +68 -0
  54. package/dist/server/migrations/meta/_journal.json +28 -0
  55. package/dist/setup-I5AJC6NJ.js +25 -0
  56. package/dist/ssh-client-625VWGKP.js +29 -0
  57. package/dist/up-QXTOOVXC.js +61 -0
  58. package/package.json +1 -1
  59. package/dist/bare-XQIPDO4R.js +0 -24
  60. package/dist/chunk-6HOA5JT7.js +0 -124
  61. package/dist/chunk-TM2IQPYU.js +0 -434
  62. package/dist/chunk-XRNRT37W.js +0 -316
  63. package/dist/cloud-3DODOWTR.js +0 -36
  64. package/dist/edge-import-MCJNVTZ2.js +0 -51
  65. package/dist/host-channel-preflight-MUXE3KZU.js +0 -49
  66. package/dist/setup-WUUZURHS.js +0 -22
  67. package/dist/up-XEO3SR6Z.js +0 -58
  68. /package/dist/{dist-es-ZP5QDSJ3.js → dist-es-AXFRS7PS.js} +0 -0
package/dist/index.js CHANGED
@@ -7,18 +7,13 @@ import {
7
7
  RELEASES,
8
8
  RELEASES_DIR,
9
9
  assetUrl,
10
- bootstrapAdmin,
11
- detectPublicIp,
12
10
  downloadToFile,
13
11
  ensureDashboard,
14
- ensureInternalToken,
15
12
  expectedSha256,
16
13
  fetchSidecar,
17
14
  formatBytes,
18
15
  hashFile,
19
16
  headlessProvision,
20
- internalGet,
21
- internalPost,
22
17
  normalizeUrl,
23
18
  parseSha256,
24
19
  readCliInstall,
@@ -30,24 +25,8 @@ import {
30
25
  startService,
31
26
  stop,
32
27
  upCommand,
33
- waitDashboard,
34
- waitHealthy,
35
28
  writeCliInstall
36
- } from "./chunk-7S4USQYF.js";
37
- import {
38
- importMigratedSites
39
- } from "./chunk-6HOA5JT7.js";
40
- import {
41
- completeHostEdge,
42
- confirmEdgeAction,
43
- diagnoseEdge,
44
- planAndApplyHostEdge,
45
- remediateUnreachableStaticRoots,
46
- renderEdgeConflict,
47
- repairEdgeConflict,
48
- rollbackHostEdge
49
- } from "./chunk-HPXP6LXZ.js";
50
- import "./chunk-XRNRT37W.js";
29
+ } from "./chunk-DDFUESPJ.js";
51
30
  import {
52
31
  composeDown,
53
32
  composeInternalToken,
@@ -79,16 +58,40 @@ import {
79
58
  saveInstanceUrl,
80
59
  shortSha,
81
60
  sourceBuildDir,
82
- startUnitHint,
83
61
  storedApiPort,
84
62
  storedDashboardPort
85
- } from "./chunk-QLX7NBEA.js";
63
+ } from "./chunk-PPEBIY5F.js";
64
+ import {
65
+ bootstrapAdmin,
66
+ detectPublicIp,
67
+ importMigratedSites,
68
+ internalFetch,
69
+ internalGet,
70
+ internalPost,
71
+ internalTokenRejectedProblem,
72
+ waitDashboard,
73
+ waitHealthy
74
+ } from "./chunk-RDXT4BQB.js";
75
+ import {
76
+ startUnitHint
77
+ } from "./chunk-VQM6JHJB.js";
86
78
  import "./chunk-QWHBRY2K.js";
79
+ import {
80
+ completeHostEdge,
81
+ confirmEdgeAction,
82
+ diagnoseEdge,
83
+ planAndApplyHostEdge,
84
+ remediateUnreachableStaticRoots,
85
+ renderEdgeConflict,
86
+ repairEdgeConflict,
87
+ rollbackHostEdge
88
+ } from "./chunk-J2XM3QSP.js";
87
89
  import {
88
90
  DATA_DIR,
89
91
  LOG_DIR,
90
92
  OS_DIR
91
93
  } from "./chunk-ELGRMZOW.js";
94
+ import "./chunk-FYPFEDPZ.js";
92
95
  import "./chunk-ONKEYSMY.js";
93
96
  import "./chunk-XZYFZ6A5.js";
94
97
  import "./chunk-PDW4L3NV.js";
@@ -97,37 +100,42 @@ import "./chunk-42WQABXM.js";
97
100
  import "./chunk-DRK3MEDS.js";
98
101
  import "./chunk-3NQQXMDR.js";
99
102
  import "./chunk-ZWLDLTJP.js";
100
- import "./chunk-6JELW75A.js";
101
- import "./chunk-3ZAGC5NT.js";
102
- import "./chunk-WNWQBB7F.js";
103
- import "./chunk-2GWYYHOR.js";
104
- import "./chunk-RXQBD4ZY.js";
105
- import "./chunk-XVOBL7BC.js";
103
+ import "./chunk-J3K6XABC.js";
104
+ import "./chunk-CIJV43LH.js";
106
105
  import {
107
106
  detectInstalledProxy,
108
107
  scanImportableSites
109
- } from "./chunk-7334NSJL.js";
110
- import "./chunk-VLQ3UIVO.js";
108
+ } from "./chunk-ZPJ74LXE.js";
109
+ import "./chunk-NRTJRNAE.js";
110
+ import "./chunk-QHMDCYZ3.js";
111
111
  import "./chunk-I3DPMTSF.js";
112
- import "./chunk-VDESJSG6.js";
113
- import "./chunk-LFCSC4IU.js";
114
- import "./chunk-GRTXMUHA.js";
115
- import "./chunk-MSZUCNPV.js";
116
- import "./chunk-TM2IQPYU.js";
117
- import "./chunk-VHMOQL5Y.js";
118
- import "./chunk-5OUWIPOB.js";
112
+ import "./chunk-WNWQBB7F.js";
113
+ import "./chunk-2GWYYHOR.js";
114
+ import "./chunk-RXQBD4ZY.js";
115
+ import "./chunk-LHFXSC36.js";
116
+ import "./chunk-XWHWTHEL.js";
117
+ import "./chunk-S6B2Z3OO.js";
118
+ import "./chunk-MEE6OZFP.js";
119
+ import "./chunk-WU54BXFE.js";
120
+ import "./chunk-H4FS5BED.js";
121
+ import "./chunk-GGIAIGUL.js";
122
+ import "./chunk-R4VDPFLS.js";
123
+ import "./chunk-2ANV5ZQ5.js";
124
+ import "./chunk-5T4UVOM3.js";
119
125
  import {
120
126
  LocalExecutor
121
- } from "./chunk-6FH4AXVY.js";
122
- import "./chunk-RFWJE7ZN.js";
123
- import "./chunk-WE7BXW6L.js";
124
- import "./chunk-A7EWM2KA.js";
125
- import "./chunk-PZRRL5PC.js";
126
- import "./chunk-EZPPTWJQ.js";
127
- import "./chunk-WFRXYWK2.js";
128
- import "./chunk-ZFJXPCQP.js";
127
+ } from "./chunk-E2X26PXR.js";
128
+ import "./chunk-PVP4RGWT.js";
129
+ import "./chunk-BLEXTYRK.js";
130
+ import "./chunk-FZ6QCF6B.js";
131
+ import "./chunk-H3WT3A6R.js";
132
+ import "./chunk-GIPJNNI5.js";
133
+ import "./chunk-VSTFHUCV.js";
134
+ import "./chunk-UWEV6XTS.js";
135
+ import "./chunk-N5YZMO33.js";
129
136
  import {
130
137
  CLOUD_DASHBOARD_URL,
138
+ HOST_CHANNEL_AUTH_REJECTED_SHORT,
131
139
  HOST_CHANNEL_PROVISION_COMMAND,
132
140
  LOCAL_API_URL,
133
141
  LOCAL_DASHBOARD_URL,
@@ -142,7 +150,7 @@ import {
142
150
  parseOpenshipConfigJson,
143
151
  resolveCliUpdatePlan,
144
152
  summarizeHostChannelCause
145
- } from "./chunk-LEYSL46B.js";
153
+ } from "./chunk-2VSW6Q6C.js";
146
154
  import "./chunk-PXKCZB2I.js";
147
155
 
148
156
  // src/index.ts
@@ -301,7 +309,7 @@ function getDashboardUrl(name) {
301
309
  }
302
310
 
303
311
  // src/lib/api-client.ts
304
- var USER_AGENT = `openship-cli/${true ? "0.6.5" : "dev"}`;
312
+ var USER_AGENT = `openship-cli/${true ? "0.6.7" : "dev"}`;
305
313
  function getApiUrl2() {
306
314
  return `${getApiUrl()}/api`;
307
315
  }
@@ -1008,16 +1016,11 @@ function ensure(value) {
1008
1016
  return value;
1009
1017
  }
1010
1018
  async function internalGet2(path2, timeoutMs = 8e3) {
1011
- try {
1012
- const res = await fetch(`http://127.0.0.1:${storedApiPort()}${path2}`, {
1013
- headers: { "X-Internal-Token": ensureInternalToken() },
1014
- signal: AbortSignal.timeout(timeoutMs)
1015
- });
1016
- if (!res.ok) return null;
1017
- return await res.json();
1018
- } catch {
1019
- return null;
1020
- }
1019
+ const call = await internalFetch(String(storedApiPort()), path2, {
1020
+ signal: AbortSignal.timeout(timeoutMs)
1021
+ });
1022
+ if (call.kind !== "response" || !call.res.ok) return null;
1023
+ return await call.res.json().catch(() => null);
1021
1024
  }
1022
1025
  async function apiReachable() {
1023
1026
  try {
@@ -1102,7 +1105,7 @@ function dockerNameRunning(nameFilter) {
1102
1105
  return r.stdout.trim().length > 0;
1103
1106
  }
1104
1107
  async function hostControlCheck(api) {
1105
- const { checkHostChannel } = await import("./host-channel-preflight-MUXE3KZU.js");
1108
+ const { checkHostChannel } = await import("./host-channel-preflight-QTDNGLCK.js");
1106
1109
  return hostControlRow(await checkHostChannel().catch(() => null), api);
1107
1110
  }
1108
1111
  var NEVER_PROVISIONED_DETAIL = `never provisioned \u2014 run \`${HOST_CHANNEL_PROVISION_COMMAND}\``;
@@ -1127,6 +1130,11 @@ function hostControlRow(res, api) {
1127
1130
  case "key_unreadable":
1128
1131
  case "unreachable":
1129
1132
  return row2("fail", `${api.state.replace(/_/g, " ")} \u2014 see the api container's boot log`);
1133
+ // Its own case, NOT grouped above: this is the one fault here an operator can act
1134
+ // on without the withheld address, and #527 is what happens when the only thing
1135
+ // we tell them is to go read a log.
1136
+ case "auth_rejected":
1137
+ return row2("fail", HOST_CHANNEL_AUTH_REJECTED_SHORT);
1130
1138
  // `disabled` (a hardening choice) and `not_applicable` (a bare install) are the
1131
1139
  // same non-event the local path returns null for. Whitelisted rather than derived
1132
1140
  // from `ok === false`, which `disabled` also is.
@@ -1502,7 +1510,7 @@ async function interactiveDoctor() {
1502
1510
  continue;
1503
1511
  }
1504
1512
  if (action2 === "host-control") {
1505
- const { verifyHostChannel } = await import("./host-channel-preflight-MUXE3KZU.js");
1513
+ const { verifyHostChannel } = await import("./host-channel-preflight-QTDNGLCK.js");
1506
1514
  const report3 = await verifyHostChannel().catch(() => null);
1507
1515
  if (report3?.status === "fixed") log2.success("Host control is reachable now.");
1508
1516
  else if (report3?.status === "ok") log2.success("Host control was already reachable.");
@@ -1609,8 +1617,6 @@ async function deployFolder(opts) {
1609
1617
  tarball,
1610
1618
  "--exclude=./node_modules",
1611
1619
  "--exclude=./.git",
1612
- "--exclude=./dist",
1613
- "--exclude=./.next",
1614
1620
  "--exclude=./.DS_Store",
1615
1621
  "-C",
1616
1622
  cwd,
@@ -1678,7 +1684,11 @@ async function deployFolder(opts) {
1678
1684
  })
1679
1685
  });
1680
1686
  if (!dep.deployment_id) throw new Error(dep.error || "Failed to start deployment");
1681
- return { deploymentId: dep.deployment_id, projectId: dep.project_id };
1687
+ return {
1688
+ deploymentId: dep.deployment_id,
1689
+ projectId: dep.project_id,
1690
+ ...scan.configDiagnostics && { configDiagnostics: scan.configDiagnostics }
1691
+ };
1682
1692
  }
1683
1693
 
1684
1694
  // src/lib/sse.ts
@@ -1867,8 +1877,18 @@ var deployCommand = new Command11("deploy").description("Trigger a deployment fo
1867
1877
  }
1868
1878
  });
1869
1879
  deploymentId = result2.deploymentId;
1870
- payload = { success: true, deployment_id: result2.deploymentId, project_id: result2.projectId };
1880
+ payload = {
1881
+ success: true,
1882
+ deployment_id: result2.deploymentId,
1883
+ project_id: result2.projectId,
1884
+ ...result2.configDiagnostics && { configDiagnostics: result2.configDiagnostics }
1885
+ };
1871
1886
  spinner5?.succeed(deploymentId ? `Deployment queued: ${deploymentId}` : "Deployment queued");
1887
+ if (result2.configDiagnostics?.wholeFile) {
1888
+ err(" \u2717 openship.json was ignored entirely \u2014 deployed with detected settings:");
1889
+ }
1890
+ for (const e of result2.configDiagnostics?.errors ?? []) err(` \u2022 ${e}`);
1891
+ for (const w of result2.configDiagnostics?.warnings ?? []) info(` \u26A0 ${w}`);
1872
1892
  } catch (e) {
1873
1893
  spinner5?.fail("Folder deploy failed");
1874
1894
  err(e instanceof ApiError ? e.message : String(e));
@@ -2949,16 +2969,36 @@ ${mapErrors.join("\n")}`
2949
2969
  }
2950
2970
  });
2951
2971
  function containerActionCommand(action2) {
2952
- return stackCommand(action2).description(`${action2[0].toUpperCase()}${action2.slice(1)} a service's container`).argument("<service>", "Service name or id").action(async (service, opts) => {
2972
+ const cmd = stackCommand(action2).description(
2973
+ action2 === "restart" ? "Bounce a service's container (does NOT apply changed env \u2014 use `deploy --refresh` for that)" : `${action2[0].toUpperCase()}${action2.slice(1)} a service's container`
2974
+ ).argument("<service>", "Service name or id");
2975
+ if (action2 === "restart") {
2976
+ cmd.option("--force", "Bounce even with pending env changes (they will NOT be applied)");
2977
+ }
2978
+ return cmd.action(async (service, opts) => {
2953
2979
  requireAuth();
2980
+ let serviceId = "";
2954
2981
  try {
2955
2982
  const projectId = await resolveProject(opts.project);
2956
2983
  const svc = await resolveService(projectId, service);
2957
- await apiRequest(`/projects/${projectId}/services/${svc.id}/${action2}`, {
2984
+ serviceId = svc.id;
2985
+ const query2 = action2 === "restart" && opts.force ? "?force=true" : "";
2986
+ await apiRequest(`/projects/${projectId}/services/${svc.id}/${action2}${query2}`, {
2958
2987
  method: "POST"
2959
2988
  });
2960
2989
  ok(` ${action2}ed "${svc.name}".`);
2961
2990
  } catch (e) {
2991
+ const body = e instanceof ApiError ? e.body : null;
2992
+ if (body?.code === "SERVICE_CONFIG_STALE") {
2993
+ const keys = Array.isArray(body.staleEnvKeys) ? body.staleEnvKeys : [];
2994
+ err(` Restart refused: "${body.serviceName ?? service}" has pending environment changes.`);
2995
+ if (keys.length > 0) info(` Pending: ${keys.join(", ")}`);
2996
+ info(
2997
+ ` Apply them: openship deploy --refresh --service-ids ${serviceId} -p ${opts.project}`
2998
+ );
2999
+ info(` Bounce anyway (changes NOT applied): add --force`);
3000
+ process.exit(1);
3001
+ }
2962
3002
  fail(e);
2963
3003
  }
2964
3004
  });
@@ -3459,7 +3499,7 @@ async function runRepair2(mode) {
3459
3499
  requireLinux();
3460
3500
  const sp = spin2(mode === "migrate" ? "Migrating the existing proxy's sites into the edge\u2026" : "Taking over :80/:443\u2026");
3461
3501
  try {
3462
- const { repairEdgeConflict: repairEdgeConflict2 } = await import("./edge-preflight-ES6FH4JK.js");
3502
+ const { repairEdgeConflict: repairEdgeConflict2 } = await import("./edge-preflight-MXERVAMG.js");
3463
3503
  sp?.stop();
3464
3504
  const res = await repairEdgeConflict2(mode, apiPort(), onLog);
3465
3505
  reportRepair(res);
@@ -3608,7 +3648,7 @@ async function panelStatus() {
3608
3648
  async function panelRepair(mode) {
3609
3649
  const sp = spin2(mode === "migrate" ? "Migrating the existing proxy's sites\u2026" : "Taking over :80/:443\u2026");
3610
3650
  try {
3611
- const { repairEdgeConflict: repairEdgeConflict2 } = await import("./edge-preflight-ES6FH4JK.js");
3651
+ const { repairEdgeConflict: repairEdgeConflict2 } = await import("./edge-preflight-MXERVAMG.js");
3612
3652
  sp?.stop();
3613
3653
  const res = await repairEdgeConflict2(mode, apiPort(), onLog);
3614
3654
  renderRepair(res);
@@ -4450,7 +4490,7 @@ function printMonitoringNextSteps() {
4450
4490
  info(" openship edge analytics -p <project> per-domain analytics");
4451
4491
  }
4452
4492
  async function runMonitoringInstall(opts) {
4453
- const up = await import("./up-XEO3SR6Z.js");
4493
+ const up = await import("./up-QXTOOVXC.js");
4454
4494
  let adminName = opts.adminName;
4455
4495
  let adminEmail = opts.adminEmail;
4456
4496
  let adminPassword = opts.adminPassword;
@@ -6152,21 +6192,26 @@ var resetAdminCommand = new Command24("reset-admin-password").description("Reset
6152
6192
  pw = entered;
6153
6193
  }
6154
6194
  const port = String(opts.port || storedApiPort());
6155
- let res;
6156
- try {
6157
- res = await fetch(`http://127.0.0.1:${port}/api/system/reset-admin-password`, {
6158
- method: "POST",
6159
- headers: { "Content-Type": "application/json", "X-Internal-Token": ensureInternalToken() },
6160
- body: JSON.stringify({ password: pw, email: opts.email, name: opts.name })
6161
- });
6162
- } catch {
6195
+ const call = await internalFetch(port, "/api/system/reset-admin-password", {
6196
+ method: "POST",
6197
+ headers: { "Content-Type": "application/json" },
6198
+ body: JSON.stringify({ password: pw, email: opts.email, name: opts.name })
6199
+ });
6200
+ if (call.kind === "unreachable") {
6163
6201
  log4.error(`Couldn't reach the Openship API on port ${port}. Is it running? (openship status)`);
6164
6202
  log4.info("If it's listening on another port, pass --port <n>.");
6165
6203
  process.exit(1);
6166
6204
  }
6205
+ if (call.kind === "no-token") {
6206
+ log4.error(`Reset failed \u2014 ${call.detail}`);
6207
+ process.exit(1);
6208
+ }
6209
+ const res = call.res;
6167
6210
  const data = await res.json().catch(() => ({}));
6168
6211
  if (!res.ok || !data.ok) {
6169
- log4.error(`Reset failed: ${data.error || res.statusText}`);
6212
+ log4.error(
6213
+ `Reset failed: ${call.tokenRejected ? internalTokenRejectedProblem() : data.error || res.statusText}`
6214
+ );
6170
6215
  process.exit(1);
6171
6216
  }
6172
6217
  outro3(chalk18.green(`Password reset. Log in as ${data.email} with your new password.`));
@@ -6602,7 +6647,7 @@ function applyOnlyArgv(selfArgs, json) {
6602
6647
  // src/commands/update.ts
6603
6648
  async function verifyHostChannelAfterUpdate() {
6604
6649
  if (isJsonMode()) return;
6605
- const { verifyHostChannel } = await import("./host-channel-preflight-MUXE3KZU.js");
6650
+ const { verifyHostChannel } = await import("./host-channel-preflight-QTDNGLCK.js");
6606
6651
  await verifyHostChannel().catch(() => {
6607
6652
  });
6608
6653
  }
@@ -6679,7 +6724,7 @@ async function runSourceUpdate(source, opts) {
6679
6724
  }
6680
6725
  var REINSTALL_HINT = "curl -fsSL https://get.openship.io | sh";
6681
6726
  async function runTarballUpdate(install, opts) {
6682
- const current = "0.6.5";
6727
+ const current = "0.6.7";
6683
6728
  let latest;
6684
6729
  try {
6685
6730
  latest = (await resolveLatestTag()).replace(/^v/, "");
@@ -6763,7 +6808,7 @@ var updateCommand = new Command26("update").description("Update the Openship CLI
6763
6808
  if (source) return runSourceUpdate(source, opts);
6764
6809
  const cliInstall = readCliInstall();
6765
6810
  if (cliInstall?.method === "tarball") return runTarballUpdate(cliInstall, opts);
6766
- const current = "0.6.5";
6811
+ const current = "0.6.7";
6767
6812
  let latest;
6768
6813
  try {
6769
6814
  latest = (await resolveLatestTag()).replace(/^v/, "");
@@ -7023,10 +7068,11 @@ async function streamProvision(port, sessionId, s) {
7023
7068
  let ok3 = false;
7024
7069
  let detail;
7025
7070
  try {
7026
- const res = await fetch(`http://127.0.0.1:${port}/api/system/self-register/stream?id=${sessionId}`, {
7027
- headers: { "X-Internal-Token": ensureInternalToken() },
7071
+ const call = await internalFetch(port, `/api/system/self-register/stream?id=${sessionId}`, {
7028
7072
  signal: AbortSignal.timeout(3e5)
7029
7073
  });
7074
+ if (call.kind !== "response") return { ok: false, detail: call.detail };
7075
+ const res = call.res;
7030
7076
  if (!res.ok || !res.body) return { ok: false };
7031
7077
  const reader = res.body.getReader();
7032
7078
  const decoder = new TextDecoder();
@@ -7370,7 +7416,7 @@ async function runWizard() {
7370
7416
  }
7371
7417
  }
7372
7418
  }
7373
- const uiTag = `v${"0.6.5"}`;
7419
+ const uiTag = `v${"0.6.7"}`;
7374
7420
  if (method === "bare") {
7375
7421
  const dl = spinner4();
7376
7422
  dl.start("Pulling the Openship dist from GitHub");
@@ -7430,7 +7476,7 @@ async function runWizard() {
7430
7476
  const dashboardPort = String(ports.dashboard);
7431
7477
  const moved = portMoveNotice(ports, composeTrustedOriginUrls());
7432
7478
  if (moved.length) log5.info(moved.join("\n"));
7433
- if (!pinnedImagesReady({ version: "0.6.5" })) {
7479
+ if (!pinnedImagesReady({ version: "0.6.7" })) {
7434
7480
  cancel4("The pinned Openship image tag isn't in the registry yet \u2014 nothing on this box was changed.");
7435
7481
  process.exit(1);
7436
7482
  }
@@ -7454,7 +7500,7 @@ async function runWizard() {
7454
7500
  dashboardPort,
7455
7501
  publicUrl,
7456
7502
  trustProxy: behindProxy,
7457
- version: "0.6.5",
7503
+ version: "0.6.7",
7458
7504
  noHostControl: !allowHostControl
7459
7505
  });
7460
7506
  if (!fetched.ok) {
@@ -7483,7 +7529,7 @@ async function runWizard() {
7483
7529
  dashboardPort,
7484
7530
  publicUrl,
7485
7531
  trustProxy: behindProxy,
7486
- version: "0.6.5",
7532
+ version: "0.6.7",
7487
7533
  noHostControl: !allowHostControl
7488
7534
  });
7489
7535
  if (!up.ok) {
@@ -7538,9 +7584,10 @@ async function runWizard() {
7538
7584
  migratedCertPems,
7539
7585
  migratedStaticRootOverrides
7540
7586
  );
7541
- if (!imported.ok) {
7587
+ const missed = migratedSites.length - imported.registered.length;
7588
+ if (missed > 0) {
7542
7589
  log5.warn(
7543
- `Your ${migratedSites.length} existing site${migratedSites.length === 1 ? "" : "s"} aren't served yet \u2014 re-run \`openship up\` to retry the import.`
7590
+ `${missed} of your ${migratedSites.length} existing site${migratedSites.length === 1 ? "" : "s"} ${missed === 1 ? "isn't" : "aren't"} served yet \u2014 see the import output above.`
7544
7591
  );
7545
7592
  }
7546
7593
  }
@@ -7583,7 +7630,7 @@ async function runWizard() {
7583
7630
  if (result.liveUrl) liveUrl2 = result.liveUrl;
7584
7631
  else if (!result.domainRegistered) liveUrl2 = `http://localhost:${started.dashPort}`;
7585
7632
  for (const w of result.warnings) log5.warn(w);
7586
- const { verifyHostChannel } = await import("./host-channel-preflight-MUXE3KZU.js");
7633
+ const { verifyHostChannel } = await import("./host-channel-preflight-QTDNGLCK.js");
7587
7634
  await verifyHostChannel().catch(() => {
7588
7635
  });
7589
7636
  finishSetup({
@@ -7862,7 +7909,7 @@ function attachCompletion(program2) {
7862
7909
 
7863
7910
  // src/index.ts
7864
7911
  var program = new Command28();
7865
- program.name("openship").description("Openship CLI \u2014 install, run, and manage Openship from your terminal").version("0.6.5").option("--json", "Machine-readable JSON output (stdout data only)").hook("preAction", (thisCommand) => {
7912
+ program.name("openship").description("Openship CLI \u2014 install, run, and manage Openship from your terminal").version("0.6.7").option("--json", "Machine-readable JSON output (stdout data only)").hook("preAction", (thisCommand) => {
7866
7913
  if (thisCommand.opts().json) setJsonMode(true);
7867
7914
  }).action(async () => {
7868
7915
  const installed = serviceStatus().installed || readInstallMethod() === "compose";
@@ -4,8 +4,9 @@ import { createRequire as __ospCreateRequire } from "node:module";
4
4
  const require = __ospCreateRequire(import.meta.url);
5
5
  import {
6
6
  LocalExecutor
7
- } from "./chunk-6FH4AXVY.js";
8
- import "./chunk-ZFJXPCQP.js";
7
+ } from "./chunk-E2X26PXR.js";
8
+ import "./chunk-H3WT3A6R.js";
9
+ import "./chunk-2VSW6Q6C.js";
9
10
  import "./chunk-PXKCZB2I.js";
10
11
  export {
11
12
  LocalExecutor
@@ -8,20 +8,24 @@ import {
8
8
  VHOST_GENERATION,
9
9
  acmeKeyArgs,
10
10
  assertValidChallengeToken,
11
+ isAcmePortBindFailure,
11
12
  readVhostGeneration,
12
13
  renderGeoEntries,
13
14
  renderProxyOptions,
14
15
  renderProxyTlsOptions,
15
16
  summarizeCertbotFailure
16
- } from "./chunk-VLQ3UIVO.js";
17
+ } from "./chunk-NRTJRNAE.js";
18
+ import "./chunk-QHMDCYZ3.js";
17
19
  import "./chunk-I3DPMTSF.js";
18
- import "./chunk-WE7BXW6L.js";
19
- import "./chunk-A7EWM2KA.js";
20
- import "./chunk-PZRRL5PC.js";
21
- import "./chunk-EZPPTWJQ.js";
22
- import "./chunk-WFRXYWK2.js";
23
- import "./chunk-ZFJXPCQP.js";
24
- import "./chunk-LEYSL46B.js";
20
+ import "./chunk-R4VDPFLS.js";
21
+ import "./chunk-BLEXTYRK.js";
22
+ import "./chunk-FZ6QCF6B.js";
23
+ import "./chunk-H3WT3A6R.js";
24
+ import "./chunk-GIPJNNI5.js";
25
+ import "./chunk-VSTFHUCV.js";
26
+ import "./chunk-UWEV6XTS.js";
27
+ import "./chunk-N5YZMO33.js";
28
+ import "./chunk-2VSW6Q6C.js";
25
29
  import "./chunk-PXKCZB2I.js";
26
30
  export {
27
31
  MANAGED_STATIC_BASE,
@@ -29,6 +33,7 @@ export {
29
33
  VHOST_GENERATION,
30
34
  acmeKeyArgs,
31
35
  assertValidChallengeToken,
36
+ isAcmePortBindFailure,
32
37
  readVhostGeneration,
33
38
  renderGeoEntries,
34
39
  renderProxyOptions,
@@ -10,6 +10,7 @@ import {
10
10
  EDGE_CHALLENGE_LOCATION,
11
11
  EDGE_CHALLENGE_ROOT,
12
12
  EDGE_CHALLENGE_URL_PREFIX,
13
+ EDGE_CLIENT_MAX_BODY_SIZE,
13
14
  EDGE_CONTAINER_MOUNTS,
14
15
  EDGE_DEFAULT_CERT_CN,
15
16
  EDGE_DEFAULT_CERT_DIRNAME,
@@ -39,11 +40,12 @@ import {
39
40
  ensureOpenRestyConfig,
40
41
  luaSourceAvailable,
41
42
  parseNginxVersion
42
- } from "./chunk-PZRRL5PC.js";
43
- import "./chunk-EZPPTWJQ.js";
44
- import "./chunk-WFRXYWK2.js";
45
- import "./chunk-ZFJXPCQP.js";
46
- import "./chunk-LEYSL46B.js";
43
+ } from "./chunk-QHMDCYZ3.js";
44
+ import "./chunk-BLEXTYRK.js";
45
+ import "./chunk-FZ6QCF6B.js";
46
+ import "./chunk-H3WT3A6R.js";
47
+ import "./chunk-N5YZMO33.js";
48
+ import "./chunk-2VSW6Q6C.js";
47
49
  import "./chunk-PXKCZB2I.js";
48
50
  export {
49
51
  ACME_CHALLENGE_LOCATION,
@@ -53,6 +55,7 @@ export {
53
55
  EDGE_CHALLENGE_LOCATION,
54
56
  EDGE_CHALLENGE_ROOT,
55
57
  EDGE_CHALLENGE_URL_PREFIX,
58
+ EDGE_CLIENT_MAX_BODY_SIZE,
56
59
  EDGE_CONTAINER_MOUNTS,
57
60
  EDGE_DEFAULT_CERT_CN,
58
61
  EDGE_DEFAULT_CERT_DIRNAME,
@@ -6,11 +6,12 @@ import {
6
6
  privilegedExecutor,
7
7
  rootChecked,
8
8
  rootOrDegrade
9
- } from "./chunk-RFWJE7ZN.js";
10
- import "./chunk-EZPPTWJQ.js";
11
- import "./chunk-WFRXYWK2.js";
12
- import "./chunk-ZFJXPCQP.js";
13
- import "./chunk-LEYSL46B.js";
9
+ } from "./chunk-PVP4RGWT.js";
10
+ import "./chunk-BLEXTYRK.js";
11
+ import "./chunk-FZ6QCF6B.js";
12
+ import "./chunk-H3WT3A6R.js";
13
+ import "./chunk-N5YZMO33.js";
14
+ import "./chunk-2VSW6Q6C.js";
14
15
  import "./chunk-PXKCZB2I.js";
15
16
  export {
16
17
  privilegedExecutor,
@@ -477,6 +477,31 @@ $bad_header_quarantine_to = 'bad-header-quarantine';
477
477
  #$undecipherable_subject_tag = '***UNCHECKED*** '; # undef disables it
478
478
  $undecipherable_subject_tag = undef;
479
479
 
480
+ # ─── What happens when NO virus scanner can be reached (GH-565) ──────────────
481
+ #
482
+ # With the settings above and @av_scanners_backup = () earlier in this file, a
483
+ # message that no scanner could examine is DELIVERED, with no subject tag and no
484
+ # admin notification. That is amavis' default and it is a deliberate choice here:
485
+ # clamd's signature load is memory-hungry and its socket is the most fragile part
486
+ # of the stack, so failing OPEN keeps mail flowing on small VPSes.
487
+ #
488
+ # It is a real trade-off, so know which side you are on. Note that amavis still
489
+ # adds its `X-Virus-Scanned` header on this path — the header records that amavis
490
+ # processed the message, NOT that a scanner passed it, and it must not be read as
491
+ # proof of a clean scan. The Emails → Health tab is the honest signal: it reports
492
+ # ClamAV as Crashed/Failed and says mail is being delivered without scanning.
493
+ #
494
+ # To fail CLOSED instead — mail queues (4xx tempfail) until a scanner is back,
495
+ # rather than arriving unscanned — uncomment ONE of these:
496
+ #
497
+ # $virus_scanners_failure_is_fatal = 1; # scanner failure => tempfail
498
+ # $final_unchecked_destiny = D_TEMPFAIL; # same, via the destiny table
499
+ #
500
+ # Before you do: while clamd is down this defers EVERY inbound message, and a
501
+ # queue that outlives the sender's retry window loses mail. Pair it with the
502
+ # subject tag above if you would rather label than defer.
503
+ # ─────────────────────────────────────────────────────────────────────────────
504
+
480
505
  # Hope to fix 'nested MAIL command' issue on high load server.
481
506
  $smtp_connection_cache_enable = 0;
482
507
 
@@ -24,12 +24,26 @@ mlmmj unix - n n - - pipe
24
24
  flags=ORhu user=PH_SYS_USER_MLMMJ:PH_SYS_GROUP_MLMMJ argv=PH_CMD_MLMMJ_AMIME_RECEIVE -L PH_MLMMJ_SPOOL_DIR/${nexthop}
25
25
 
26
26
  # Amavisd integration.
27
+ #
28
+ # smtp_tls_security_level=none is REQUIRED, not an optimisation (GH-392). This
29
+ # is an smtp CLIENT service, so it inherits the global smtp_tls_security_level
30
+ # — and amavisd's :10024 listener does not offer STARTTLS. With the global set
31
+ # to `encrypt` every inbound message defers with "TLS is required, but was not
32
+ # offered": a complete INBOUND outage, from a setting that only looks like it
33
+ # concerns outbound delivery. Saving an outbound relay with scope "all" sets
34
+ # exactly that (apps/api/src/modules/mail/admin/outbound-relay.service.ts), and
35
+ # so does an operator hardening TLS by hand.
36
+ #
37
+ # TLS here would be meaningless anyway: the hop is loopback to a content filter
38
+ # on the same host. Pinning it at the transport keeps the guarantee local to the
39
+ # thing that needs it, instead of depending on every writer of the global.
27
40
  smtp-amavis unix - - n - PH_AMAVISD_MAX_SERVERS smtp
28
41
  -o syslog_name=postfix/amavis
29
42
  -o local_header_rewrite_clients=
30
43
  -o smtp_data_done_timeout=1200
31
44
  -o smtp_send_xforward_command=yes
32
45
  -o smtp_dns_support_level=disabled
46
+ -o smtp_tls_security_level=none
33
47
  -o max_use=20
34
48
 
35
49
  # smtp port used by Amavisd to re-inject scanned email back to Postfix