openmates 0.12.0-alpha.24 → 0.12.0-alpha.25

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.
@@ -9605,6 +9605,24 @@ function writeChecksums(rootDir) {
9605
9605
  writeFileSync3(join3(rootDir, "checksums.sha256"), `${lines.sort().join("\n")}
9606
9606
  `);
9607
9607
  }
9608
+ function verifyChecksums(rootDir) {
9609
+ const checksumsPath = join3(rootDir, "checksums.sha256");
9610
+ if (!existsSync5(checksumsPath)) throw new Error("Backup archive is missing checksums.sha256.");
9611
+ for (const line of readFileSync5(checksumsPath, "utf-8").split("\n")) {
9612
+ const trimmed = line.trim();
9613
+ if (!trimmed) continue;
9614
+ const match = trimmed.match(/^([a-f0-9]{64}) {2}(.+)$/);
9615
+ if (!match) throw new Error(`Invalid checksum entry: ${trimmed}`);
9616
+ const relative2 = match[2];
9617
+ if (relative2.startsWith("/") || relative2.split(/[\\/]/).includes("..")) {
9618
+ throw new Error(`Unsafe checksum path in backup archive: ${relative2}`);
9619
+ }
9620
+ const filePath = join3(rootDir, relative2);
9621
+ if (!existsSync5(filePath)) throw new Error(`Backup archive is missing checksummed file: ${relative2}`);
9622
+ const actual = createHash5("sha256").update(readFileSync5(filePath)).digest("hex");
9623
+ if (actual !== match[1]) throw new Error(`Backup checksum mismatch for ${relative2}.`);
9624
+ }
9625
+ }
9608
9626
  function createServerBackup(installPath, role, options = {}) {
9609
9627
  const plan = planBackup({ role, includeObservability: options.includeObservability });
9610
9628
  const backupDir = roleBackupDir(installPath, role);
@@ -9629,7 +9647,10 @@ function createServerBackup(installPath, role, options = {}) {
9629
9647
  const databaseUser = env.DATABASE_USERNAME || "directus";
9630
9648
  const databaseName = env.DATABASE_NAME || "directus";
9631
9649
  try {
9632
- const dump = execSync(`docker exec cms-database pg_dump -U ${shellQuote(databaseUser)} ${shellQuote(databaseName)}`, { encoding: "utf-8" });
9650
+ const dump = execSync(
9651
+ `docker exec cms-database pg_dump --clean --if-exists --no-owner --no-privileges -U ${shellQuote(databaseUser)} ${shellQuote(databaseName)}`,
9652
+ { encoding: "utf-8" }
9653
+ );
9633
9654
  writeFileSync3(join3(tempDir, "postgres.sql"), dump);
9634
9655
  } catch (error) {
9635
9656
  throw new Error(`Postgres backup failed. Is cms-database running? ${error instanceof Error ? error.message : String(error)}`);
@@ -9658,6 +9679,7 @@ function restoreServerBackup(installPath, role, file) {
9658
9679
  const env = readEnvMap(installPath);
9659
9680
  try {
9660
9681
  execSync(`tar -xzf ${shellQuote(archivePath)} -C ${shellQuote(tempDir)}`, { stdio: "pipe" });
9682
+ verifyChecksums(tempDir);
9661
9683
  const manifestPath = join3(tempDir, "manifest.json");
9662
9684
  if (!existsSync5(manifestPath)) throw new Error("Backup archive is missing manifest.json.");
9663
9685
  const manifest = JSON.parse(readFileSync5(manifestPath, "utf-8"));
@@ -9668,7 +9690,7 @@ function restoreServerBackup(installPath, role, file) {
9668
9690
  if (role === "core" && existsSync5(postgresDump)) {
9669
9691
  const databaseUser = env.DATABASE_USERNAME || "directus";
9670
9692
  const databaseName = env.DATABASE_NAME || "directus";
9671
- execSync(`docker exec -i cms-database psql -U ${shellQuote(databaseUser)} ${shellQuote(databaseName)}`, {
9693
+ execSync(`docker exec -i cms-database psql -v ON_ERROR_STOP=1 -U ${shellQuote(databaseUser)} ${shellQuote(databaseName)}`, {
9672
9694
  input: readFileSync5(postgresDump),
9673
9695
  stdio: ["pipe", "pipe", "pipe"]
9674
9696
  });
@@ -9677,6 +9699,10 @@ function restoreServerBackup(installPath, role, file) {
9677
9699
  rmSync3(tempDir, { recursive: true, force: true });
9678
9700
  }
9679
9701
  }
9702
+ function restoreStopServices(role) {
9703
+ if (role !== "core") return [];
9704
+ return resolveServiceSelection("core", { exclude: "cms-database" });
9705
+ }
9680
9706
  async function promptText(question, defaultValue = "") {
9681
9707
  const rl = createPromptInterface({ input: process.stdin, output: process.stderr });
9682
9708
  try {
@@ -10631,7 +10657,8 @@ WARNING: This will restore ${role} data from ${file}.`);
10631
10657
  }
10632
10658
  const withOverrides = config?.composeProfile === "full";
10633
10659
  const installMode = getInstallMode(installPath, config);
10634
- let code = await runInteractive("docker", [...composeArgs(installPath, withOverrides, installMode, role), "stop"], installPath);
10660
+ const stopArgs = [...composeArgs(installPath, withOverrides, installMode, role), "stop", ...restoreStopServices(role)];
10661
+ let code = await runInteractive("docker", stopArgs, installPath);
10635
10662
  if (code !== 0) process.exit(code);
10636
10663
  restoreServerBackup(installPath, role, file);
10637
10664
  code = await runInteractive("docker", [...composeArgs(installPath, withOverrides, installMode, role), "up", "-d"], installPath);
@@ -27698,7 +27725,7 @@ Only output the final Markdown table. Do NOT include explanations, notes, or any
27698
27725
  text: "Private local personalization"
27699
27726
  },
27700
27727
  title: {
27701
- text: "Choose what you care about. Your picks stay in this browser session."
27728
+ text: "What are you interested in?"
27702
27729
  },
27703
27730
  continue: {
27704
27731
  text: "Continue"
package/dist/cli.js CHANGED
@@ -2,7 +2,7 @@
2
2
  import {
3
3
  getExtForLang,
4
4
  serializeToYaml
5
- } from "./chunk-YQL7OKLK.js";
5
+ } from "./chunk-V7DUGDYQ.js";
6
6
  import "./chunk-AXNRPVLE.js";
7
7
  export {
8
8
  getExtForLang,
package/dist/index.js CHANGED
@@ -11,7 +11,7 @@ import {
11
11
  getExtForLang,
12
12
  normalizeInterestTagIds,
13
13
  serializeToYaml
14
- } from "./chunk-YQL7OKLK.js";
14
+ } from "./chunk-V7DUGDYQ.js";
15
15
  import "./chunk-AXNRPVLE.js";
16
16
  export {
17
17
  ASSISTANT_FEEDBACK_REPORT_TITLE,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "openmates",
3
- "version": "0.12.0-alpha.24",
3
+ "version": "0.12.0-alpha.25",
4
4
  "description": "OpenMates CLI and SDK",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",