mermaid/src/config.js

223 lines
8.0 KiB
JavaScript
Raw Normal View History

import { assignWithDepth } from './utils';
2021-02-06 11:26:05 +01:00
import { log } from './logger';
import theme from './themes';
import config from './defaultConfig';
export const defaultConfig = Object.freeze(config);
let siteConfig = assignWithDepth({}, defaultConfig);
let configFromInitialize;
let directives = [];
let currentConfig = assignWithDepth({}, defaultConfig);
export const updateCurrentConfig = (siteCfg, _directives) => {
2020-08-16 21:49:36 +02:00
// start with config beeing the siteConfig
let cfg = assignWithDepth({}, siteCfg);
2020-08-16 21:49:36 +02:00
// let sCfg = assignWithDepth(defaultConfig, siteConfigDelta);
2020-08-16 21:49:36 +02:00
// Join directives
let sumOfDirectives = {};
2020-07-29 22:19:23 +02:00
for (let i = 0; i < _directives.length; i++) {
const d = _directives[i];
sanitize(d);
2020-08-16 21:49:36 +02:00
// Apply the data from the directive where the the overrides the themeVaraibles
sumOfDirectives = assignWithDepth(sumOfDirectives, d);
2020-07-29 22:19:23 +02:00
}
2020-08-16 21:49:36 +02:00
cfg = assignWithDepth(cfg, sumOfDirectives);
if (sumOfDirectives.theme && theme[sumOfDirectives.theme]) {
const tmpConfigFromInitialize = assignWithDepth({}, configFromInitialize);
2020-08-16 21:49:36 +02:00
const themeVariables = assignWithDepth(
tmpConfigFromInitialize.themeVariables || {},
2020-08-16 21:49:36 +02:00
sumOfDirectives.themeVariables
);
cfg.themeVariables = theme[cfg.theme].getThemeVariables(themeVariables);
}
currentConfig = cfg;
return cfg;
};
2021-11-07 03:36:06 +01:00
/**
2021-11-10 08:41:52 +01:00
* ## setSiteConfig
*
* | Function | Description | Type | Values |
* | ------------- | ------------------------------------- | ----------- | --------------------------------------- |
* | setSiteConfig | Sets the siteConfig to desired values | Put Request | Any Values, except ones in secure array |
*
* **Notes:** Sets the siteConfig. The siteConfig is a protected configuration for repeat use. Calls
* to reset() will reset the currentConfig to siteConfig. Calls to reset(configApi.defaultConfig)
* will reset siteConfig and currentConfig to the defaultConfig Note: currentConfig is set in this
* function _Default value: At default, will mirror Global Config_
2021-11-10 08:41:52 +01:00
*
* @param conf - The base currentConfig to use as siteConfig
* @returns {object} - The siteConfig
*/
2021-07-15 11:35:12 +02:00
export const setSiteConfig = (conf) => {
siteConfig = assignWithDepth({}, defaultConfig);
siteConfig = assignWithDepth(siteConfig, conf);
if (conf.theme && theme[conf.theme]) {
siteConfig.themeVariables = theme[conf.theme].getThemeVariables(conf.themeVariables);
}
currentConfig = updateCurrentConfig(siteConfig, directives);
return siteConfig;
};
2020-08-16 21:49:36 +02:00
2021-07-15 11:35:12 +02:00
export const saveConfigFromInitilize = (conf) => {
configFromInitialize = assignWithDepth({}, conf);
2020-08-16 21:49:36 +02:00
};
2021-07-15 11:35:12 +02:00
export const updateSiteConfig = (conf) => {
siteConfig = assignWithDepth(siteConfig, conf);
updateCurrentConfig(siteConfig, directives);
return siteConfig;
};
/**
2021-11-10 08:41:52 +01:00
* ## getSiteConfig
*
* | Function | Description | Type | Values |
* | ------------- | ------------------------------------------------- | ----------- | -------------------------------- |
* | setSiteConfig | Returns the current siteConfig base configuration | Get Request | Returns Any Values in siteConfig |
2021-11-10 08:41:52 +01:00
*
* **Notes**: Returns **any** values in siteConfig.
*
* @returns {object} - The siteConfig
*/
export const getSiteConfig = () => {
return assignWithDepth({}, siteConfig);
};
/**
2021-11-10 08:41:52 +01:00
* ## setConfig
*
* | Function | Description | Type | Values |
* | ------------- | ------------------------------------- | ----------- | --------------------------------------- |
* | setSiteConfig | Sets the siteConfig to desired values | Put Request | Any Values, except ones in secure array |
*
* **Notes**: Sets the currentConfig. The parameter conf is sanitized based on the siteConfig.secure
* keys. Any values found in conf with key found in siteConfig.secure will be replaced with the
* corresponding siteConfig value.
*
* @param {any} conf - The potential currentConfig
* @returns {any} - The currentConfig merged with the sanitized conf
*/
2021-07-15 11:35:12 +02:00
export const setConfig = (conf) => {
// sanitize(conf);
// Object.keys(conf).forEach(key => {
// const manipulator = manipulators[key];
// conf[key] = manipulator ? manipulator(conf[key]) : conf[key];
// });
assignWithDepth(currentConfig, conf);
return getConfig();
};
/**
2021-11-10 08:41:52 +01:00
* ## getConfig
*
* | Function | Description | Type | Return Values |
* | --------- | ------------------------- | ----------- | ------------------------------ |
* | getConfig | Obtains the currentConfig | Get Request | Any Values from current Config |
*
* **Notes**: Returns **any** the currentConfig
*
* @returns {any} - The currentConfig
*/
export const getConfig = () => {
return assignWithDepth({}, currentConfig);
};
/**
2021-11-10 08:41:52 +01:00
* ## sanitize
*
* | Function | Description | Type | Values |
* | -------- | -------------------------------------- | ----------- | ------ |
* | sanitize | Sets the siteConfig to desired values. | Put Request | None |
*
* Ensures options parameter does not attempt to override siteConfig secure keys **Notes**: modifies
* options in-place
*
* @param {any} options - The potential setConfig parameter
*/
2021-07-15 11:35:12 +02:00
export const sanitize = (options) => {
2021-03-11 20:57:45 +01:00
// Checking that options are not in the list of excluded options
2021-07-15 11:35:12 +02:00
Object.keys(siteConfig.secure).forEach((key) => {
if (typeof options[siteConfig.secure[key]] !== 'undefined') {
// DO NOT attempt to print options[siteConfig.secure[key]] within `${}` as a malicious script
// can exploit the logger's attempt to stringify the value and execute arbitrary code
2021-02-06 11:26:05 +01:00
log.debug(
`Denied attempt to modify a secure key ${siteConfig.secure[key]}`,
options[siteConfig.secure[key]]
);
delete options[siteConfig.secure[key]];
}
});
2021-03-11 20:57:45 +01:00
// Check that there no attempts of prototype pollution
2021-07-15 11:35:12 +02:00
Object.keys(options).forEach((key) => {
2021-03-11 20:57:45 +01:00
if (key.indexOf('__') === 0) {
delete options[key];
}
});
// Check that there no attempts of xss, there should be no tags at all in the directive
// blocking data urls as base64 urls can contain svgs with inline script tags
2021-07-15 11:35:12 +02:00
Object.keys(options).forEach((key) => {
2021-03-11 20:57:45 +01:00
if (typeof options[key] === 'string') {
if (
options[key].indexOf('<') > -1 ||
options[key].indexOf('>') > -1 ||
options[key].indexOf('url(data:') > -1
) {
delete options[key];
}
}
if (typeof options[key] === 'object') {
sanitize(options[key]);
}
});
};
2021-11-07 03:36:06 +01:00
/**
* Pushes in a directive to the configuration
*
* @param {object} directive The directive to push in
2021-11-07 03:36:06 +01:00
*/
2021-07-15 11:35:12 +02:00
export const addDirective = (directive) => {
2020-08-14 07:34:42 +02:00
if (directive.fontFamily) {
if (!directive.themeVariables) {
directive.themeVariables = { fontFamily: directive.fontFamily };
} else {
if (!directive.themeVariables.fontFamily) {
directive.themeVariables = { fontFamily: directive.fontFamily };
}
}
}
directives.push(directive);
updateCurrentConfig(siteConfig, directives);
};
/**
2021-11-10 08:41:52 +01:00
* ## reset
*
* | Function | Description | Type | Required | Values |
* | -------- | ---------------------------- | ----------- | -------- | ------ |
* | reset | Resets currentConfig to conf | Put Request | Required | None |
2020-07-15 03:11:36 +02:00
*
2021-11-15 09:07:08 +01:00
* ## conf
2020-07-15 03:11:36 +02:00
*
2021-11-15 09:07:08 +01:00
* | Parameter | Description | Type | Required | Values |
* | --------- | ------------------------------------------------------------- | ---------- | -------- | -------------------------------------------- |
* | conf | base set of values, which currentConfig coul be **reset** to. | Dictionary | Required | Any Values, with respect to the secure Array |
*
2021-11-10 08:41:52 +01:00
* **Notes**: (default: current siteConfig ) (optional, default `getSiteConfig()`)
*/
export const reset = () => {
// Replace current config with siteConfig
directives = [];
updateCurrentConfig(siteConfig, directives);
};