/**
* CodeX Sanitizer
*
* Clears HTML from taint tags
*
* @version 2.0.0
*
* @example
*
* clean(yourTaintString, yourConfig);
*
* {@link SanitizerConfig}
*/
import * as _ from '../utils';
/**
* @typedef {object} SanitizerConfig
* @property {object} tags - define tags restrictions
*
* @example
*
* tags : {
* p: true,
* a: {
* href: true,
* rel: "nofollow",
* target: "_blank"
* }
* }
*/
import HTMLJanitor from 'html-janitor';
import { BlockToolData, SanitizerConfig } from '../../../types';
import { SavedData } from '../../../types/data-formats';
/**
* Sanitize Blocks
*
* Enumerate blocks and clean data
*
* @param blocksData - blocks' data to sanitize
* @param sanitizeConfig — sanitize config to use or function to get config for Tool
*/
export function sanitizeBlocks(
blocksData: Array>,
sanitizeConfig: SanitizerConfig | ((toolName: string) => SanitizerConfig)
): Array> {
return blocksData.map((block) => {
const toolConfig = _.isFunction(sanitizeConfig) ? sanitizeConfig(block.tool) : sanitizeConfig;
if (_.isEmpty(toolConfig)) {
return block;
}
block.data = deepSanitize(block.data, toolConfig) as BlockToolData;
return block;
});
}
/**
* Cleans string from unwanted tags
* Method allows to use default config
*
* @param {string} taintString - taint string
* @param {SanitizerConfig} customConfig - allowed tags
*
* @returns {string} clean HTML
*/
export function clean(taintString: string, customConfig: SanitizerConfig = {} as SanitizerConfig): string {
const sanitizerConfig = {
tags: customConfig,
};
/**
* API client can use custom config to manage sanitize process
*/
const sanitizerInstance = new HTMLJanitor(sanitizerConfig);
return sanitizerInstance.clean(taintString);
}
/**
* Method recursively reduces Block's data and cleans with passed rules
*
* @param {BlockToolData|object|*} dataToSanitize - taint string or object/array that contains taint string
* @param {SanitizerConfig} rules - object with sanitizer rules
*/
function deepSanitize(dataToSanitize: object | string, rules: SanitizerConfig): object | string {
/**
* BlockData It may contain 3 types:
* - Array
* - Object
* - Primitive
*/
if (Array.isArray(dataToSanitize)) {
/**
* Array: call sanitize for each item
*/
return cleanArray(dataToSanitize, rules);
} else if (_.isObject(dataToSanitize)) {
/**
* Objects: just clean object deeper.
*/
return cleanObject(dataToSanitize, rules);
} else {
/**
* Primitives (number|string|boolean): clean this item
*
* Clean only strings
*/
if (_.isString(dataToSanitize)) {
return cleanOneItem(dataToSanitize, rules);
}
return dataToSanitize;
}
}
/**
* Clean array
*
* @param {Array} array - [1, 2, {}, []]
* @param {SanitizerConfig} ruleForItem - sanitizer config for array
*/
function cleanArray(array: Array