UNPKG

keycloakify

Version:

Framework to create custom Keycloak UIs

149 lines 7.39 kB
import { HtmlPolicyBuilder } from "./HtmlPolicyBuilder"; //implementation of java Sanitizer policy ( KeycloakSanitizerPolicy ) // All regex directly copied from the keycloak source but some of them changed slightly to work with typescript(ONSITE_URL and OFFSITE_URL) // Also replaced ?i with "i" tag as second parameter of RegExp //https://github.com/keycloak/keycloak/blob/8ce8a4ba089eef25a0e01f58e09890399477b9ef/services/src/main/java/org/keycloak/theme/KeycloakSanitizerPolicy.java#L29 export class KcSanitizerPolicy { static COLOR_NAME_OR_COLOR_CODE(s) { return (KcSanitizerPolicy.COLOR_NAME.test(s) || KcSanitizerPolicy.COLOR_CODE.test(s)); } static ONSITE_OR_OFFSITE_URL(s) { return (KcSanitizerPolicy.ONSITE_URL.test(s) || KcSanitizerPolicy.OFFSITE_URL.test(s)); } static sanitize(html, dependencyInjections) { return new HtmlPolicyBuilder(dependencyInjections) .allowWithoutAttributes("span") .allowAttributes("id") .matching(this.HTML_ID) .globally() .allowAttributes("class") .matching(this.HTML_CLASS) .globally() .allowAttributes("lang") .matching(/[a-zA-Z]{2,20}/) .globally() .allowAttributes("title") .matching(this.HTML_TITLE) .globally() .allowStyling() .allowAttributes("align") .matching(this.ALIGN) .onElements("p") .allowAttributes("for") .matching(this.HTML_ID) .onElements("label") .allowAttributes("color") .matching(this.COLOR_NAME_OR_COLOR_CODE) .onElements("font") .allowAttributes("face") .matching(/[\w;, \-]+/) .onElements("font") .allowAttributes("size") .matching(this.NUMBER) .onElements("font") .allowAttributes("href") .matching(this.ONSITE_OR_OFFSITE_URL) .onElements("a") .allowStandardUrlProtocols() .allowAttributes("nohref") .onElements("a") .allowAttributes("name") .matching(this.NAME) .onElements("a") .allowAttributes("onfocus", "onblur", "onclick", "onmousedown", "onmouseup") .matching(this.HISTORY_BACK) .onElements("a") .requireRelNofollowOnLinks() .allowAttributes("src") .matching(this.ONSITE_OR_OFFSITE_URL) .onElements("img") .allowAttributes("name") .matching(this.NAME) .onElements("img") .allowAttributes("alt") .matching(this.PARAGRAPH) .onElements("img") .allowAttributes("border", "hspace", "vspace") .matching(this.NUMBER) .onElements("img") .allowAttributes("border", "cellpadding", "cellspacing") .matching(this.NUMBER) .onElements("table") .allowAttributes("bgcolor") .matching(this.COLOR_NAME_OR_COLOR_CODE) .onElements("table") .allowAttributes("background") .matching(this.ONSITE_URL) .onElements("table") .allowAttributes("align") .matching(this.ALIGN) .onElements("table") .allowAttributes("noresize") .matching(new RegExp("noresize", "i")) .onElements("table") .allowAttributes("background") .matching(this.ONSITE_URL) .onElements("td", "th", "tr") .allowAttributes("bgcolor") .matching(this.COLOR_NAME_OR_COLOR_CODE) .onElements("td", "th") .allowAttributes("abbr") .matching(this.PARAGRAPH) .onElements("td", "th") .allowAttributes("axis", "headers") .matching(this.NAME) .onElements("td", "th") .allowAttributes("scope") .matching(new RegExp("(?:row|col)(?:group)?", "i")) .onElements("td", "th") .allowAttributes("nowrap") .onElements("td", "th") .allowAttributes("height", "width") .matching(this.NUMBER_OR_PERCENT) .onElements("table", "td", "th", "tr", "img") .allowAttributes("align") .matching(this.ALIGN) .onElements("thead", "tbody", "tfoot", "img", "td", "th", "tr", "colgroup", "col") .allowAttributes("valign") .matching(this.VALIGN) .onElements("thead", "tbody", "tfoot", "td", "th", "tr", "colgroup", "col") .allowAttributes("charoff") .matching(this.NUMBER_OR_PERCENT) .onElements("td", "th", "tr", "colgroup", "col", "thead", "tbody", "tfoot") .allowAttributes("char") .matching(this.ONE_CHAR) .onElements("td", "th", "tr", "colgroup", "col", "thead", "tbody", "tfoot") .allowAttributes("colspan", "rowspan") .matching(this.NUMBER) .onElements("td", "th") .allowAttributes("span", "width") .matching(this.NUMBER_OR_PERCENT) .onElements("colgroup", "col") .allowElements("a", "label", "noscript", "h1", "h2", "h3", "h4", "h5", "h6", "p", "i", "b", "u", "strong", "em", "small", "big", "pre", "code", "cite", "samp", "sub", "sup", "strike", "center", "blockquote", "hr", "br", "col", "font", "map", "span", "div", "img", "ul", "ol", "li", "dd", "dt", "dl", "tbody", "thead", "tfoot", "table", "td", "th", "tr", "colgroup", "fieldset", "legend") .apply(html); } } KcSanitizerPolicy.COLOR_NAME = new RegExp("(?:aqua|black|blue|fuchsia|gray|grey|green|lime|maroon|navy|olive|purple|red|silver|teal|white|yellow)"); KcSanitizerPolicy.COLOR_CODE = new RegExp("(?:#(?:[0-9a-fA-F]{3}(?:[0-9a-fA-F]{3})?))"); KcSanitizerPolicy.NUMBER_OR_PERCENT = new RegExp("[0-9]+%?"); KcSanitizerPolicy.PARAGRAPH = new RegExp("(?:[\\p{L}\\p{N},'\\.\\s\\-_\\(\\)]|&[0-9]{2};)*", "u" // Unicode flag for \p{L} and \p{N} in the pattern ); KcSanitizerPolicy.HTML_ID = new RegExp("[a-zA-Z0-9\\:\\-_\\.]+"); KcSanitizerPolicy.HTML_TITLE = new RegExp("[\\p{L}\\p{N}\\s\\-_',:\\[\\]!\\./\\\\\\(\\)&]*", "u" // Unicode flag for \p{L} and \p{N} in the pattern ); KcSanitizerPolicy.HTML_CLASS = new RegExp("[a-zA-Z0-9\\s,\\-_]+"); KcSanitizerPolicy.ONSITE_URL = new RegExp("(?:[\\p{L}\\p{N}.#@\\$%+&;\\-_~,?=/!]+|#(\\w)+)", "u" // Unicode flag for \p{L} and \p{N} in the pattern ); KcSanitizerPolicy.OFFSITE_URL = new RegExp("\\s*(?:(?:ht|f)tps?://|mailto:)[\\p{L}\\p{N}]+" + "[\\p{L}\\p{N}\\p{Zs}.#@\\$%+&;:\\-_~,?=/!()]*\\s*", "u" // Unicode flag for \p{L} and \p{N} in the pattern ); KcSanitizerPolicy.NUMBER = new RegExp("[+-]?(?:(?:[0-9]+(?:\\.[0-9]*)?)|\\.[0-9]+)"); KcSanitizerPolicy.NAME = new RegExp("[a-zA-Z0-9\\-_\\$]+"); KcSanitizerPolicy.ALIGN = new RegExp("\\b(center|left|right|justify|char)\\b", "i" // Case-insensitive flag ); KcSanitizerPolicy.VALIGN = new RegExp("\\b(baseline|bottom|middle|top)\\b", "i" // Case-insensitive flag ); KcSanitizerPolicy.HISTORY_BACK = new RegExp("(?:javascript:)?\\Qhistory.go(-1)\\E"); KcSanitizerPolicy.ONE_CHAR = new RegExp(".?", "s" // Dotall flag for . to match newlines ); //# sourceMappingURL=KcSanitizerPolicy.js.map