UNPKG

@cocalc/server

Version:

CoCalc server functionality: functions used by either the hub and the next.js server

115 lines 4.99 kB
"use strict"; /* * This file is part of CoCalc: Copyright © 2021 Sagemath, Inc. * License: AGPLv3 s.t. "Commons Clause" – see LICENSE.md for details */ var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.load_server_settings_from_env = exports.getServerSettings = exports.setPassportsCached = exports.getPassportsCached = exports.resetServerSettingsCache = void 0; const lru_cache_1 = __importDefault(require("lru-cache")); const site_settings_extras_1 = require("@cocalc/util/db-schema/site-settings-extras"); const schema_1 = require("@cocalc/util/schema"); const consts_1 = require("@cocalc/util/consts"); const pool_1 = __importDefault(require("@cocalc/database/pool")); const async_utils_1 = require("@cocalc/util/async-utils"); const logger_1 = __importDefault(require("@cocalc/backend/logger")); const L = (0, logger_1.default)("server:server-settings"); // We're just using this to cache this result for a **few seconds**. const CACHE_TIME_SECONDS = process.env.NODE_ENV == "development" ? 3 : 15; // TODO add something for the passports data type? const cache = new lru_cache_1.default({ max: 10, maxAge: 1000 * CACHE_TIME_SECONDS, }); const KEY = "server-settings"; function resetServerSettingsCache() { cache.reset(); } exports.resetServerSettingsCache = resetServerSettingsCache; function getPassportsCached() { return cache.get("passports"); } exports.getPassportsCached = getPassportsCached; function setPassportsCached(val) { return cache.set("passports", val); } exports.setPassportsCached = setPassportsCached; async function getServerSettings() { if (cache.has(KEY)) { return cache.get(KEY); // can't be null } const pool = (0, pool_1.default)(); const { rows } = await pool.query("SELECT name, value FROM server_settings"); const settings = { _timestamp: Date.now() }; const raw = {}; for (const row of rows) { raw[row.name] = row.value; } // process values, including any post-processing. for (const row of rows) { const { name, value } = row; const spec = schema_1.site_settings_conf[name] ?? site_settings_extras_1.EXTRAS[name]; // we only process values we know if (spec == null) continue; const toVal = spec.to_val; settings[name] = toVal != null ? toVal(value, raw) : value; } // set default values for missing keys for (const config of [site_settings_extras_1.EXTRAS, schema_1.site_settings_conf]) { for (const key in config) { if (settings[key] == null) { const spec = config[key]; settings[key] = spec?.to_val != null ? spec.to_val(spec.default, raw) : spec.default; } } } cache.set(KEY, settings); return settings; } exports.getServerSettings = getServerSettings; /* This stores environment variables for server settings in the DB to make the life of an admin easier. e.g. COCALC_SETTING_DNS, COCALC_SETTING_EMAIL_SMTP_SERVER, COCALC_SETTING_EMAIL_SMTP_PASSWORD, ... Loaded once at startup, right after configuring the db schema, see hub/hub.ts. */ async function load_server_settings_from_env(db) { const PREFIX = consts_1.SERVER_SETTINGS_ENV_PREFIX; // reset all readonly values await db.async_query({ query: "UPDATE server_settings", set: { readonly: false }, where: ["1=1"], // otherwise there is an exception about not restricting the query }); // now, check if there are any we know of for (const config of [site_settings_extras_1.EXTRAS, schema_1.site_settings_conf]) { for (const key in config) { const envvar = `${PREFIX}_${key.toUpperCase()}`; const envval = process.env[envvar]; if (envval == null) continue; // ATTN do not expose the value, could be a password L.debug(`picking up $${envvar} and saving it in the database`); // check validity const valid = (schema_1.site_settings_conf[key] ?? site_settings_extras_1.EXTRAS[key])?.valid; if (valid != null) { if (Array.isArray(valid) && !valid.includes(envval)) { throw new Error(`The value of $${envvar} is invalid. allowed are ${valid}.`); } else if (typeof valid == "function" && !valid(envval)) { throw new Error(`The validation function rejected the value of $${envvar}.`); } } await (0, async_utils_1.callback2)(db.set_server_setting, { name: key, value: envval, readonly: true, }); } } } exports.load_server_settings_from_env = load_server_settings_from_env; //# sourceMappingURL=server-settings.js.map