quorlasocial/connector/test/server-settings.test.mjs
metatroncubeswdev 7c596ec6d5 Settings on the site instead of .env; Odoo in Connections
- Server settings (Settings page): SMTP, AI, publishing, Meta, platform keys and,
  on the control centre only, Stripe/billing. Stored sealed in data/settings.json and
  applied over .env in every process; hosted agency workspaces don't see our email,
  platform keys or billing.
- Odoo connection per workspace in Connections (login checked before saving).
- provision-tenants.sh marks agency containers with QUORLA_HOSTED_TENANT=true.
- docs/wildcard-subdomains.html: one-time setup for automatic agency subdomains.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-25 19:49:15 -04:00

52 lines
2.9 KiB
JavaScript

// Server settings on the site: override .env live, fall back when cleared, secrets hidden, scopes per workspace type.
import { test } from "node:test";
import assert from "node:assert/strict";
import fs from "node:fs";
import os from "node:os";
import path from "node:path";
const TMP = fs.mkdtempSync(path.join(os.tmpdir(), "quorla-settings-"));
const FILE = path.join(TMP, "settings.json");
Object.assign(process.env, {
QUORLA_SETTINGS_FILE: FILE, QUORLA_DASHBOARD_DATA: path.join(TMP, "dash"), QUORLA_CONTROL_DIR: path.join(TMP, "control"),
DASHBOARD_SECRET: "s".repeat(32), SMTP_HOST: "env.mail.test", QUORLA_CONTROL: "", QUORLA_HOSTED_TENANT: "",
});
delete process.env.SMTP_PASS;
const settings = await import("../../dashboard/server/settings.js");
const field = (r, key) => r.groups.flatMap((g) => g.fields).find((f) => f.key === key);
test("saved values override .env, secrets stay hidden, clearing falls back", () => {
assert.equal(field(settings.list(), "SMTP_HOST").source, "env");
let r = settings.save({ values: { SMTP_HOST: "site.mail.test", SMTP_PASS: "hunter2", ALLOW_PUBLISH: "true" } });
assert.deepEqual(r.changed.sort(), ["ALLOW_PUBLISH", "SMTP_HOST", "SMTP_PASS"]);
assert.equal(process.env.SMTP_HOST, "site.mail.test", "applied live");
assert.equal(process.env.SMTP_PASS, "hunter2");
assert.deepEqual([field(r, "SMTP_PASS").value, field(r, "SMTP_PASS").set, field(r, "SMTP_PASS").source], ["", true, "site"]);
assert.equal(JSON.stringify(r).includes("hunter2"), false);
assert.equal(fs.readFileSync(FILE, "utf8").includes("hunter2"), false, "encrypted at rest");
r = settings.save({ values: { SMTP_PASS: "" } });
assert.equal(process.env.SMTP_PASS, "hunter2", "empty secret keeps the stored one");
r = settings.save({ clear: ["SMTP_HOST", "SMTP_PASS"] });
assert.equal(process.env.SMTP_HOST, "env.mail.test", "back to .env");
assert.equal(process.env.SMTP_PASS, undefined);
assert.equal(field(r, "SMTP_HOST").source, "env");
assert.throws(() => settings.save({ values: { SMTP_PORT: "abc" } }), /whole number/);
assert.throws(() => settings.save({ values: { DASHBOARD_SECRET: "x" } }), /can't be changed here/);
assert.deepEqual(settings.save({ values: { META_API_VERSION: "v24.0" } }).restart, ["META_API_VERSION"]);
});
test("billing only on the control centre; our email and platform keys hidden in hosted agency workspaces", () => {
const groups = () => settings.list().groups.map((g) => g.name);
assert.ok(!groups().includes("Billing & sign-ups"));
process.env.QUORLA_CONTROL = "true";
assert.ok(groups().includes("Billing & sign-ups"));
process.env.QUORLA_CONTROL = "";
process.env.QUORLA_HOSTED_TENANT = "true";
assert.ok(!groups().includes("Email (SMTP)") && !groups().includes("Platforms") && groups().includes("AI runs"));
assert.equal(field(settings.list(), "PUBLIC_URL"), undefined);
assert.throws(() => settings.save({ values: { SMTP_HOST: "x" } }), /can't be changed here/);
process.env.QUORLA_HOSTED_TENANT = "";
});