Real-time collaboration for Jupyter Notebooks, Linux Terminals, LaTeX, VS Code, R IDE, and more,
all in one place.
Real-time collaboration for Jupyter Notebooks, Linux Terminals, LaTeX, VS Code, R IDE, and more,
all in one place.
Path: blob/master/src/packages/hub/servers/server-settings.ts
Views: 687
/*1* This file is part of CoCalc: Copyright © 2020 Sagemath, Inc.2* License: MS-RSL – see LICENSE.md for details3*/45/*6Synchronized table that tracks server settings.7*/89import { isEmpty } from "lodash";1011import { once } from "@cocalc/util/async-utils";12import { EXTRAS as SERVER_SETTINGS_EXTRAS } from "@cocalc/util/db-schema/site-settings-extras";13import { AllSiteSettings } from "@cocalc/util/db-schema/types";14import { startswith } from "@cocalc/util/misc";15import { site_settings_conf as SITE_SETTINGS_CONF } from "@cocalc/util/schema";16import { database } from "./database";1718// Returns:19// - all: a mutable javascript object that is a map from each server setting to its current value.20// This includes VERY private info (e.g., stripe private key)21// - pub: similar, but only subset of public info that is needed for browser UI rendering.22// - version23// - table: the table, so you can watch for on change events...24// These get automatically updated when the database changes.2526export interface ServerSettingsDynamic {27all: AllSiteSettings;28pub: object;29version: object;30table: any;31}3233let serverSettings: ServerSettingsDynamic | undefined = undefined;3435export default async function getServerSettings(): Promise<ServerSettingsDynamic> {36if (serverSettings != null) {37return serverSettings;38}39const table = database.server_settings_synctable();40serverSettings = { all: {}, pub: {}, version: {}, table: table };41const { all, pub, version } = serverSettings;42const update = async function () {43const allRaw = {};44table.get().forEach((record, field) => {45allRaw[field] = record.get("value");46});4748table.get().forEach(function (record, field) {49const rawValue = record.get("value");5051// process all values from the database according to the optional "to_val" mapping function52const spec = SITE_SETTINGS_CONF[field] ?? SERVER_SETTINGS_EXTRAS[field];53if (typeof spec?.to_val == "function") {54all[field] = spec.to_val(rawValue, allRaw);55} else {56if (typeof rawValue == "string" || typeof rawValue == "boolean") {57all[field] = rawValue;58}59}6061// export certain fields to "pub[...]" and some old code regarding the version numbers62if (SITE_SETTINGS_CONF[field]) {63if (startswith(field, "version_")) {64const field_val: number = (all[field] = parseInt(all[field]));65if (isNaN(field_val) || field_val * 1000 >= new Date().getTime()) {66// Guard against horrible error in which version is in future (so impossible) or NaN (e.g., an invalid string pasted by admin).67// In this case, just use 0, which is always satisifed.68all[field] = 0;69}70version[field] = all[field];71}72pub[field] = all[field];73}74});7576// set all default values77for (const config of [SITE_SETTINGS_CONF, SERVER_SETTINGS_EXTRAS]) {78for (const field in config) {79if (all[field] == null) {80const spec = config[field];81const fallbackVal =82spec?.to_val != null83? spec.to_val(spec.default, allRaw)84: spec.default;85// we don't bother to set empty strings or empty arrays86if (87(typeof fallbackVal === "string" && fallbackVal === "") ||88(Array.isArray(fallbackVal) && isEmpty(fallbackVal))89)90continue;91all[field] = fallbackVal;92// site-settings end up in the "pub" object as well93// while "all" is the one we keep to us, contains secrets94if (SITE_SETTINGS_CONF === config) {95pub[field] = all[field];96}97}98}99}100101// Since we want to tell users about the estimated LLM interaction price, we have to send the markup as well.102pub["_llm_markup"] = all.pay_as_you_go_openai_markup_percentage;103104// PRECAUTION: never make the required version bigger than version_recommended_browser. Very important105// not to stupidly completely eliminate all cocalc users by a typo...106for (const x of ["project", "browser"]) {107const field = `version_min_${x}`;108const minver = all[field] || 0;109const recomm = all["version_recommended_browser"] || 0;110pub[field] = version[field] = all[field] = Math.min(minver, recomm);111}112};113table.on("change", update);114table.on("init", update);115await once(table, "init");116return serverSettings;117}118119120