62 lines
2.2 KiB
JavaScript
62 lines
2.2 KiB
JavaScript
// Sync-policy constants: one source of truth for every enforcement point on both
|
|
// sides of a sync.
|
|
|
|
// The ONLY global _sc_config keys a deployer syncs. The capture side records /
|
|
// ships only these and the apply side refuses any other key, so a compromised
|
|
// peer cannot write security-relevant config it was never meant to touch
|
|
// (disable_csrf_routes, custom HTML headers, SMTP creds). Per-environment
|
|
// settings (base_url: links, OAuth callbacks, the idp issuer) are deliberately
|
|
// absent.
|
|
const SYNCABLE_CONFIG_KEYS = [
|
|
"menu_items",
|
|
"site_name",
|
|
"site_logo_id"
|
|
];
|
|
|
|
// User tables that must NEVER receive peer-synced rows and must never be
|
|
// flipped into managed/starter mode, no matter what a peer sends. `users` is the
|
|
// crown jewel: a synced row there is an injected account (role_id=1 => admin
|
|
// takeover). Enforced on the apply (and revert) side, not just the UI, since a
|
|
// hostile authenticated peer never goes through the UI.
|
|
const ROW_SYNC_LOCKED_TABLES = ["users"];
|
|
|
|
// Per-table row-propagation modes.
|
|
// user (default) -- rows belong to the target; sync never touches them.
|
|
// starter -- rows ship once (initial seed), then the target owns them.
|
|
// managed -- rows always converge from source; source is canonical.
|
|
const DATA_MODES = {
|
|
USER: "user",
|
|
STARTER: "starter",
|
|
MANAGED: "managed"
|
|
};
|
|
|
|
|
|
// Plugin/system infrastructure: a table OR field whose name
|
|
// begins with "_" is reserved by Saltcorn (_sc_*) and plugins (_dd_*, _ss_*,
|
|
// _idp_*, the per-row identity columns _dd_row_uuid / _ss_row_uuid). Infra is
|
|
// never journaled, synced, diffed, pruned, or offered a data mode. (Documented
|
|
// limitation: an application table or field named with a leading underscore is
|
|
// not synced.)
|
|
const isInfraName = (name) => {
|
|
return typeof name === "string" && name.startsWith("_");
|
|
};
|
|
|
|
|
|
const isLockedTable = (name) => {
|
|
return ROW_SYNC_LOCKED_TABLES.includes(name);
|
|
};
|
|
|
|
|
|
const isSyncedMode = (mode) => {
|
|
return mode === DATA_MODES.MANAGED || mode === DATA_MODES.STARTER;
|
|
};
|
|
|
|
|
|
module.exports = {
|
|
SYNCABLE_CONFIG_KEYS,
|
|
ROW_SYNC_LOCKED_TABLES,
|
|
DATA_MODES,
|
|
isInfraName,
|
|
isLockedTable,
|
|
isSyncedMode
|
|
};
|