diff --git a/extension/chrome/dev/ci_unit_test.htm b/extension/chrome/dev/ci_unit_test.htm
index cd284d04bdc..001fb57736f 100644
--- a/extension/chrome/dev/ci_unit_test.htm
+++ b/extension/chrome/dev/ci_unit_test.htm
@@ -10,6 +10,7 @@
loading..
running..
+
diff --git a/extension/chrome/dev/export.htm b/extension/chrome/dev/export.htm
index 540558439f4..64b9808d36d 100644
--- a/extension/chrome/dev/export.htm
+++ b/extension/chrome/dev/export.htm
@@ -12,6 +12,7 @@
+
diff --git a/extension/chrome/elements/add_pubkey.htm b/extension/chrome/elements/add_pubkey.htm
index 2cc80a3f4bd..9e4ad495345 100644
--- a/extension/chrome/elements/add_pubkey.htm
+++ b/extension/chrome/elements/add_pubkey.htm
@@ -48,6 +48,7 @@ Add a public key to email address
+
diff --git a/extension/chrome/elements/attachment.htm b/extension/chrome/elements/attachment.htm
index c4ec12d881e..4389a66a4f0 100644
--- a/extension/chrome/elements/attachment.htm
+++ b/extension/chrome/elements/attachment.htm
@@ -21,6 +21,7 @@
+
diff --git a/extension/chrome/elements/attachment_preview.htm b/extension/chrome/elements/attachment_preview.htm
index 10b3f06c0c4..906d1118abd 100644
--- a/extension/chrome/elements/attachment_preview.htm
+++ b/extension/chrome/elements/attachment_preview.htm
@@ -21,6 +21,7 @@
+
diff --git a/extension/chrome/elements/backup.htm b/extension/chrome/elements/backup.htm
index 3e3f1820c59..0851bc0fecb 100644
--- a/extension/chrome/elements/backup.htm
+++ b/extension/chrome/elements/backup.htm
@@ -25,6 +25,7 @@
+
diff --git a/extension/chrome/elements/compose.htm b/extension/chrome/elements/compose.htm
index 7e257479523..51a32a6710d 100644
--- a/extension/chrome/elements/compose.htm
+++ b/extension/chrome/elements/compose.htm
@@ -228,6 +228,7 @@
+
diff --git a/extension/chrome/elements/oauth2.htm b/extension/chrome/elements/oauth2.htm
index e0d3460c450..4f504a22f9e 100644
--- a/extension/chrome/elements/oauth2.htm
+++ b/extension/chrome/elements/oauth2.htm
@@ -1,4 +1,4 @@
-
+
OAuth 2.0 Finish Page
diff --git a/extension/chrome/elements/passphrase.htm b/extension/chrome/elements/passphrase.htm
index 9fe6aa71d97..95b31cdfa00 100644
--- a/extension/chrome/elements/passphrase.htm
+++ b/extension/chrome/elements/passphrase.htm
@@ -1,6 +1,6 @@
-
+
@@ -45,6 +45,7 @@
>
+
diff --git a/extension/chrome/elements/pgp_block.htm b/extension/chrome/elements/pgp_block.htm
index 9f3d9909ae8..f8f07a16198 100644
--- a/extension/chrome/elements/pgp_block.htm
+++ b/extension/chrome/elements/pgp_block.htm
@@ -34,6 +34,7 @@
Loading...
+
diff --git a/extension/chrome/elements/pgp_block_modules/pgp-block-print-module.ts b/extension/chrome/elements/pgp_block_modules/pgp-block-print-module.ts
index 231cdab8e18..96fa39340ac 100644
--- a/extension/chrome/elements/pgp_block_modules/pgp-block-print-module.ts
+++ b/extension/chrome/elements/pgp_block_modules/pgp-block-print-module.ts
@@ -15,7 +15,7 @@ export class PgpBlockViewPrintModule {
return;
}
const w = window.open();
- const html = `
+ let html = `
@@ -81,6 +81,12 @@ export class PgpBlockViewPrintModule {
`;
+ if (w?.trustedTypes && w?.trustedTypes.createPolicy) {
+ const policy = w?.trustedTypes.createPolicy('print-policy', {
+ createHTML: (string: string) => string,
+ });
+ html = policy.createHTML(html);
+ }
w?.document.write(html);
// Give some time for above dom to load in print dialog
// https://stackoverflow.com/questions/31725373/google-chrome-not-showing-image-in-print-preview
diff --git a/extension/chrome/elements/pgp_pubkey.htm b/extension/chrome/elements/pgp_pubkey.htm
index 8b2410daf93..738db380a28 100644
--- a/extension/chrome/elements/pgp_pubkey.htm
+++ b/extension/chrome/elements/pgp_pubkey.htm
@@ -35,6 +35,7 @@
+
diff --git a/extension/chrome/popups/default.htm b/extension/chrome/popups/default.htm
index 41afc5d76c0..3fbdfae4a21 100644
--- a/extension/chrome/popups/default.htm
+++ b/extension/chrome/popups/default.htm
@@ -25,6 +25,7 @@
+
diff --git a/extension/chrome/popups/select_account.htm b/extension/chrome/popups/select_account.htm
index 1ed46f8a0d3..29e1afd4b9a 100644
--- a/extension/chrome/popups/select_account.htm
+++ b/extension/chrome/popups/select_account.htm
@@ -19,6 +19,7 @@
Add Account
+
diff --git a/extension/chrome/settings/fatal.htm b/extension/chrome/settings/fatal.htm
index 7c1b528ec63..e109d252d08 100644
--- a/extension/chrome/settings/fatal.htm
+++ b/extension/chrome/settings/fatal.htm
@@ -23,6 +23,7 @@
loading details..
+
diff --git a/extension/chrome/settings/inbox/inbox.htm b/extension/chrome/settings/inbox/inbox.htm
index d94e9758708..a8c0b61a7d8 100644
--- a/extension/chrome/settings/inbox/inbox.htm
+++ b/extension/chrome/settings/inbox/inbox.htm
@@ -45,6 +45,7 @@
+
diff --git a/extension/chrome/settings/index.htm b/extension/chrome/settings/index.htm
index b27c2014a08..6c493435c02 100644
--- a/extension/chrome/settings/index.htm
+++ b/extension/chrome/settings/index.htm
@@ -240,6 +240,7 @@ FlowCrypt Settings
+
diff --git a/extension/chrome/settings/initial.htm b/extension/chrome/settings/initial.htm
index 1ce57c04b7f..e59cf22de70 100644
--- a/extension/chrome/settings/initial.htm
+++ b/extension/chrome/settings/initial.htm
@@ -46,6 +46,7 @@
+
diff --git a/extension/chrome/settings/initial.ts b/extension/chrome/settings/initial.ts
index 2bf8673c986..67e53d17512 100644
--- a/extension/chrome/settings/initial.ts
+++ b/extension/chrome/settings/initial.ts
@@ -8,10 +8,10 @@ import { View } from '../../js/common/view.js';
View.run(
class InitialView extends View {
public render = async () => {
- if (Catch.browser().name === 'chrome' && Number(Catch.browser().v) >= 76) {
- $('#chrome-steps').css('display', 'block');
- } else {
- $('#firefox-steps').css('display', 'block');
+ const browserName = Catch.browser().name === 'chrome' && Number(Catch.browser().v) >= 76 ? 'chrome' : 'firefox';
+ const stepsEl = document.getElementById(`${browserName}-steps`);
+ if (stepsEl) {
+ stepsEl.style.display = 'block';
}
};
diff --git a/extension/chrome/settings/modules/add_key.htm b/extension/chrome/settings/modules/add_key.htm
index 9d07dfc8295..2aca46c2d1d 100644
--- a/extension/chrome/settings/modules/add_key.htm
+++ b/extension/chrome/settings/modules/add_key.htm
@@ -68,6 +68,7 @@ Add Private Key
+
diff --git a/extension/chrome/settings/modules/backup.htm b/extension/chrome/settings/modules/backup.htm
index 5d76b81d2e9..ab4fbabec4b 100644
--- a/extension/chrome/settings/modules/backup.htm
+++ b/extension/chrome/settings/modules/backup.htm
@@ -16,6 +16,7 @@
+
diff --git a/extension/chrome/settings/modules/change_passphrase.htm b/extension/chrome/settings/modules/change_passphrase.htm
index b2df44c4ec9..6cc6ee253ff 100644
--- a/extension/chrome/settings/modules/change_passphrase.htm
+++ b/extension/chrome/settings/modules/change_passphrase.htm
@@ -55,6 +55,7 @@
+
diff --git a/extension/chrome/settings/modules/compatibility.htm b/extension/chrome/settings/modules/compatibility.htm
index 24917b5433f..a260e80fd27 100644
--- a/extension/chrome/settings/modules/compatibility.htm
+++ b/extension/chrome/settings/modules/compatibility.htm
@@ -54,6 +54,7 @@ OpenPGP key compatibility test
+
diff --git a/extension/chrome/settings/modules/contacts.htm b/extension/chrome/settings/modules/contacts.htm
index 616024b9ae2..bedf31553e5 100644
--- a/extension/chrome/settings/modules/contacts.htm
+++ b/extension/chrome/settings/modules/contacts.htm
@@ -87,6 +87,7 @@
+
diff --git a/extension/chrome/settings/modules/debug_api.htm b/extension/chrome/settings/modules/debug_api.htm
index 18749e8d48c..a8eeca4b029 100644
--- a/extension/chrome/settings/modules/debug_api.htm
+++ b/extension/chrome/settings/modules/debug_api.htm
@@ -14,6 +14,7 @@
This page is meant for debugging purposes. If you have questions, please email human@flowcrypt.com
+
diff --git a/extension/chrome/settings/modules/decrypt.htm b/extension/chrome/settings/modules/decrypt.htm
index 69cfa52a852..0941cca8e0e 100644
--- a/extension/chrome/settings/modules/decrypt.htm
+++ b/extension/chrome/settings/modules/decrypt.htm
@@ -36,6 +36,7 @@ Decrypt a file
+
diff --git a/extension/chrome/settings/modules/experimental.htm b/extension/chrome/settings/modules/experimental.htm
index 617c15697d2..cc174fb29f2 100644
--- a/extension/chrome/settings/modules/experimental.htm
+++ b/extension/chrome/settings/modules/experimental.htm
@@ -37,6 +37,7 @@ Experimental functionality
+
diff --git a/extension/chrome/settings/modules/help.htm b/extension/chrome/settings/modules/help.htm
index f3f92b912ad..b991c0bf645 100644
--- a/extension/chrome/settings/modules/help.htm
+++ b/extension/chrome/settings/modules/help.htm
@@ -29,6 +29,7 @@ Send message to FlowCrypt developers
+
diff --git a/extension/chrome/settings/modules/keyserver.htm b/extension/chrome/settings/modules/keyserver.htm
index fee334095fe..2c756b28fc3 100644
--- a/extension/chrome/settings/modules/keyserver.htm
+++ b/extension/chrome/settings/modules/keyserver.htm
@@ -23,6 +23,7 @@ Let others encrypt for you easier
+
diff --git a/extension/chrome/settings/modules/my_key.htm b/extension/chrome/settings/modules/my_key.htm
index bc78cb77128..78182e7e8a7 100644
--- a/extension/chrome/settings/modules/my_key.htm
+++ b/extension/chrome/settings/modules/my_key.htm
@@ -58,6 +58,7 @@
+
diff --git a/extension/chrome/settings/modules/my_key_update.htm b/extension/chrome/settings/modules/my_key_update.htm
index 3234497b494..ed326f4fd2c 100644
--- a/extension/chrome/settings/modules/my_key_update.htm
+++ b/extension/chrome/settings/modules/my_key_update.htm
@@ -51,6 +51,7 @@
+
diff --git a/extension/chrome/settings/modules/my_key_user_ids.htm b/extension/chrome/settings/modules/my_key_user_ids.htm
index 3df61549ccd..8607658a669 100644
--- a/extension/chrome/settings/modules/my_key_user_ids.htm
+++ b/extension/chrome/settings/modules/my_key_user_ids.htm
@@ -26,6 +26,7 @@
+
diff --git a/extension/chrome/settings/modules/security.htm b/extension/chrome/settings/modules/security.htm
index d9b638cf429..89cb78cb670 100644
--- a/extension/chrome/settings/modules/security.htm
+++ b/extension/chrome/settings/modules/security.htm
@@ -71,6 +71,7 @@ Password protected messages
-->
+
diff --git a/extension/chrome/settings/modules/test_passphrase.htm b/extension/chrome/settings/modules/test_passphrase.htm
index 9f04aefc4a0..5f1485f205b 100644
--- a/extension/chrome/settings/modules/test_passphrase.htm
+++ b/extension/chrome/settings/modules/test_passphrase.htm
@@ -28,6 +28,7 @@
+
diff --git a/extension/chrome/settings/setup.htm b/extension/chrome/settings/setup.htm
index c458144dde1..dee62ed69e1 100644
--- a/extension/chrome/settings/setup.htm
+++ b/extension/chrome/settings/setup.htm
@@ -369,6 +369,7 @@ Set Up FlowCrypt
+
diff --git a/extension/js/background_page/background_page.htm b/extension/js/background_page/background_page.htm
index 328fa7f81a7..56be3715160 100644
--- a/extension/js/background_page/background_page.htm
+++ b/extension/js/background_page/background_page.htm
@@ -4,6 +4,7 @@
+
diff --git a/extension/lib/blob.js b/extension/lib/blob.js
deleted file mode 100644
index 6c3a2558f20..00000000000
--- a/extension/lib/blob.js
+++ /dev/null
@@ -1,211 +0,0 @@
-/* Blob.js
- * A Blob implementation.
- * 2014-07-24
- *
- * By Eli Grey, http://eligrey.com
- * By Devin Samarin, https://github.com/dsamarin
- * License: MIT
- * See https://github.com/eligrey/Blob.js/blob/master/LICENSE.md
- */
-
-/*global self, unescape */
-/*jslint bitwise: true, regexp: true, confusion: true, es5: true, vars: true, white: true,
- plusplus: true */
-
-/*! @source http://purl.eligrey.com/github/Blob.js/blob/master/Blob.js */
-
-(function (view) {
- "use strict";
-
- view.URL = view.URL || view.webkitURL;
-
- if (view.Blob && view.URL) {
- try {
- new Blob;
- return;
- } catch (e) {}
- }
-
- // Internally we use a BlobBuilder implementation to base Blob off of
- // in order to support older browsers that only have BlobBuilder
- var BlobBuilder = view.BlobBuilder || view.WebKitBlobBuilder || view.MozBlobBuilder || (function(view) {
- var
- get_class = function(object) {
- return Object.prototype.toString.call(object).match(/^\[object\s(.*)\]$/)[1];
- }
- , FakeBlobBuilder = function BlobBuilder() {
- this.data = [];
- }
- , FakeBlob = function Blob(data, type, encoding) {
- this.data = data;
- this.size = data.length;
- this.type = type;
- this.encoding = encoding;
- }
- , FBB_proto = FakeBlobBuilder.prototype
- , FB_proto = FakeBlob.prototype
- , FileReaderSync = view.FileReaderSync
- , FileException = function(type) {
- this.code = this[this.name = type];
- }
- , file_ex_codes = (
- "NOT_FOUND_ERR SECURITY_ERR ABORT_ERR NOT_READABLE_ERR ENCODING_ERR "
- + "NO_MODIFICATION_ALLOWED_ERR INVALID_STATE_ERR SYNTAX_ERR"
- ).split(" ")
- , file_ex_code = file_ex_codes.length
- , real_URL = view.URL || view.webkitURL || view
- , real_create_object_URL = real_URL.createObjectURL
- , real_revoke_object_URL = real_URL.revokeObjectURL
- , URL = real_URL
- , btoa = view.btoa
- , atob = view.atob
-
- , ArrayBuffer = view.ArrayBuffer
- , Uint8Array = view.Uint8Array
-
- , origin = /^[\w-]+:\/*\[?[\w\.:-]+\]?(?::[0-9]+)?/
- ;
- FakeBlob.fake = FB_proto.fake = true;
- while (file_ex_code--) {
- FileException.prototype[file_ex_codes[file_ex_code]] = file_ex_code + 1;
- }
- // Polyfill URL
- if (!real_URL.createObjectURL) {
- URL = view.URL = function(uri) {
- var
- uri_info = document.createElementNS("http://www.w3.org/1999/xhtml", "a")
- , uri_origin
- ;
- uri_info.href = uri;
- if (!("origin" in uri_info)) {
- if (uri_info.protocol.toLowerCase() === "data:") {
- uri_info.origin = null;
- } else {
- uri_origin = uri.match(origin);
- uri_info.origin = uri_origin && uri_origin[1];
- }
- }
- return uri_info;
- };
- }
- URL.createObjectURL = function(blob) {
- var
- type = blob.type
- , data_URI_header
- ;
- if (type === null) {
- type = "application/octet-stream";
- }
- if (blob instanceof FakeBlob) {
- data_URI_header = "data:" + type;
- if (blob.encoding === "base64") {
- return data_URI_header + ";base64," + blob.data;
- } else if (blob.encoding === "URI") {
- return data_URI_header + "," + decodeURIComponent(blob.data);
- } if (btoa) {
- return data_URI_header + ";base64," + btoa(blob.data);
- } else {
- return data_URI_header + "," + encodeURIComponent(blob.data);
- }
- } else if (real_create_object_URL) {
- return real_create_object_URL.call(real_URL, blob);
- }
- };
- URL.revokeObjectURL = function(object_URL) {
- if (object_URL.substring(0, 5) !== "data:" && real_revoke_object_URL) {
- real_revoke_object_URL.call(real_URL, object_URL);
- }
- };
- FBB_proto.append = function(data/*, endings*/) {
- var bb = this.data;
- // decode data to a binary string
- if (Uint8Array && (data instanceof ArrayBuffer || data instanceof Uint8Array)) {
- var
- str = ""
- , buf = new Uint8Array(data)
- , i = 0
- , buf_len = buf.length
- ;
- for (; i < buf_len; i++) {
- str += String.fromCharCode(buf[i]);
- }
- bb.push(str);
- } else if (get_class(data) === "Blob" || get_class(data) === "File") {
- if (FileReaderSync) {
- var fr = new FileReaderSync;
- bb.push(fr.readAsBinaryString(data));
- } else {
- // async FileReader won't work as BlobBuilder is sync
- throw new FileException("NOT_READABLE_ERR");
- }
- } else if (data instanceof FakeBlob) {
- if (data.encoding === "base64" && atob) {
- bb.push(atob(data.data));
- } else if (data.encoding === "URI") {
- bb.push(decodeURIComponent(data.data));
- } else if (data.encoding === "raw") {
- bb.push(data.data);
- }
- } else {
- if (typeof data !== "string") {
- data += ""; // convert unsupported types to strings
- }
- // decode UTF-16 to binary string
- bb.push(unescape(encodeURIComponent(data)));
- }
- };
- FBB_proto.getBlob = function(type) {
- if (!arguments.length) {
- type = null;
- }
- return new FakeBlob(this.data.join(""), type, "raw");
- };
- FBB_proto.toString = function() {
- return "[object BlobBuilder]";
- };
- FB_proto.slice = function(start, end, type) {
- var args = arguments.length;
- if (args < 3) {
- type = null;
- }
- return new FakeBlob(
- this.data.slice(start, args > 1 ? end : this.data.length)
- , type
- , this.encoding
- );
- };
- FB_proto.toString = function() {
- return "[object Blob]";
- };
- FB_proto.close = function() {
- this.size = 0;
- delete this.data;
- };
- return FakeBlobBuilder;
- }(view));
-
- view.Blob = function(blobParts, options) {
- var type = options ? (options.type || "") : "";
- var builder = new BlobBuilder();
- if (blobParts) {
- for (var i = 0, len = blobParts.length; i < len; i++) {
- if (Uint8Array && blobParts[i] instanceof Uint8Array) {
- builder.append(blobParts[i].buffer);
- }
- else {
- builder.append(blobParts[i]);
- }
- }
- }
- var blob = builder.getBlob(type);
- if (!blob.slice && blob.webkitSlice) {
- blob.slice = blob.webkitSlice;
- }
- return blob;
- };
-
- var getPrototypeOf = Object.getPrototypeOf || function(object) {
- return object.__proto__;
- };
- view.Blob.prototype = getPrototypeOf(new view.Blob());
-}(typeof self !== "undefined" && self || typeof window !== "undefined" && window || this.content || this));
diff --git a/extension/lib/trusted-types.js b/extension/lib/trusted-types.js
new file mode 100644
index 00000000000..f9c7c044905
--- /dev/null
+++ b/extension/lib/trusted-types.js
@@ -0,0 +1,9 @@
+// temporary solution until jquery v4 with trusted types support will be released
+// https://github.com/jquery/jquery/issues/4409#issuecomment-931353583
+if (window.trustedTypes && window.trustedTypes.createPolicy) {
+ window.trustedTypes.createPolicy('default', {
+ createHTML: string => string,
+ createScriptURL: string => string,
+ createScript: string => string,
+ });
+}
\ No newline at end of file
diff --git a/extension/manifest.json b/extension/manifest.json
index 757607ad905..8e5f50927f1 100644
--- a/extension/manifest.json
+++ b/extension/manifest.json
@@ -50,6 +50,7 @@
"/lib/streams_web.js",
"/lib/emailjs/punycode.js",
"/lib/iso-8859-2.js",
+ "/lib/trusted-types.js",
"/lib/emailjs/emailjs-stringencoding.js",
"/lib/emailjs/emailjs-mime-codec.js",
"/lib/emailjs/emailjs-mime-types.js",
@@ -93,5 +94,5 @@
"/chrome/elements/oauth2.htm"
],
"minimum_chrome_version": "96",
- "content_security_policy": "upgrade-insecure-requests; script-src 'self'; frame-ancestors https://mail.google.com 'self'; img-src 'self' https://* data: blob:; frame-src 'self' blob:; worker-src 'self'; form-action 'none'; media-src 'none'; font-src 'none'; manifest-src 'none'; object-src 'none'; base-uri 'self'"
+ "content_security_policy": "upgrade-insecure-requests; script-src 'self'; frame-ancestors https://mail.google.com 'self'; img-src 'self' https://* data: blob:; frame-src 'self' blob:; worker-src 'self'; form-action 'none'; media-src 'none'; font-src 'none'; manifest-src 'none'; object-src 'none'; base-uri 'self'; require-trusted-types-for 'script';"
}
diff --git a/extension/types/purify.d.ts b/extension/types/purify.d.ts
index 0f1985b464f..f7328784c90 100644
--- a/extension/types/purify.d.ts
+++ b/extension/types/purify.d.ts
@@ -1,78 +1,138 @@
-// Type definitions for DOM Purify
-// Project: https://github.com/cure53/DOMPurify
-// Definitions by: Dave Taylor , Samira Bazuzi
-// Definitions: https://github.com/DefinitelyTyped/DefinitelyTyped
-
-/* tslint:disable:only-arrow-functions */
-/* tslint:disable:unified-signatures */
+///
export as namespace DOMPurify;
+export = DOMPurify;
-export declare let version: string;
-export declare let removed: any[];
-export declare let isSupported: boolean;
+declare const DOMPurify: createDOMPurifyI;
-export declare function sanitize(source: string | Node): string;
-export declare function sanitize(source: string | Node, config: Config & { RETURN_DOM_FRAGMENT?: false; RETURN_DOM?: false; }): string;
-export declare function sanitize(source: string | Node, config: Config & { RETURN_DOM_FRAGMENT: true; }): DocumentFragment;
-export declare function sanitize(source: string | Node, config: Config & { RETURN_DOM: true; }): HTMLElement;
-export declare function sanitize(source: string | Node, config: Config): string | HTMLElement | DocumentFragment;
-export declare function addHook(hook: 'uponSanitizeElement', cb: (currentNode: Element, data: SanitizeElementHookEvent, config: Config) => void): void;
-export declare function addHook(hook: 'uponSanitizeAttribute', cb: (currentNode: Element, data: SanitizeAttributeHookEvent, config: Config) => void): void;
-export declare function addHook(hook: HookName, cb: (currentNode: Element, data: HookEvent, config: Config) => void): void;
-export declare function setConfig(cfg: Config): void;
-export declare function clearConfig(): void;
-export declare function isValidAttribute(tag: string, attr: string, value: string): boolean;
-export declare function removeHook(entryPoint: HookName): void;
-export declare function removeHooks(entryPoint: HookName): void;
-export declare function removeAllHooks(): void;
+type WindowLike = Pick<
+ typeof globalThis,
+ | "NodeFilter"
+ | "Node"
+ | "Element"
+ | "HTMLTemplateElement"
+ | "DocumentFragment"
+ | "HTMLFormElement"
+ | "DOMParser"
+ | "NamedNodeMap"
+>;
-interface Config {
- ADD_ATTR?: string[];
- ADD_TAGS?: string[];
- ALLOW_DATA_ATTR?: boolean;
- ALLOWED_ATTR?: string[];
- ALLOWED_TAGS?: string[];
- FORBID_ATTR?: string[];
- FORBID_TAGS?: string[];
- FORCE_BODY?: boolean;
- KEEP_CONTENT?: boolean;
- RETURN_DOM?: boolean;
- RETURN_DOM_FRAGMENT?: boolean;
- RETURN_DOM_IMPORT?: boolean;
- SANITIZE_DOM?: boolean;
- WHOLE_DOCUMENT?: boolean;
- ALLOWED_URI_REGEXP?: RegExp;
- SAFE_FOR_TEMPLATES?: boolean;
- ALLOW_UNKNOWN_PROTOCOLS?: boolean;
- USE_PROFILES?: false | {mathMl?: boolean, svg?: boolean, svgFilters?: boolean, html?: boolean};
- IN_PLACE?: boolean;
+interface createDOMPurifyI extends DOMPurify.DOMPurifyI {
+ (window?: Window | WindowLike): DOMPurify.DOMPurifyI;
}
-type HookName
- = 'beforeSanitizeElements'
- | 'uponSanitizeElement'
- | 'afterSanitizeElements'
- | 'beforeSanitizeAttributes'
- | 'uponSanitizeAttribute'
- | 'afterSanitizeAttributes'
- | 'beforeSanitizeShadowDOM'
- | 'uponSanitizeShadowNode'
- | 'afterSanitizeShadowDOM';
+declare namespace DOMPurify {
+ interface DOMPurifyI {
+ sanitize(source: string | Node): string;
+ // sanitize(source: string | Node, config: Config & { RETURN_TRUSTED_TYPE: true }): TrustedHTML;
+ sanitize(
+ source: string | Node,
+ config: Config & { RETURN_DOM_FRAGMENT?: false | undefined; RETURN_DOM?: false | undefined },
+ ): string;
+ sanitize(source: string | Node, config: Config & { RETURN_DOM_FRAGMENT: true }): DocumentFragment;
+ sanitize(source: string | Node, config: Config & { RETURN_DOM: true }): HTMLElement;
+ sanitize(source: string | Node, config: Config): string | HTMLElement | DocumentFragment;
-type HookEvent
- = SanitizeElementHookEvent
- | SanitizeAttributeHookEvent
- | null;
+ addHook(
+ hook: "uponSanitizeElement",
+ cb: (currentNode: Element, data: SanitizeElementHookEvent, config: Config) => void,
+ ): void;
+ addHook(
+ hook: "uponSanitizeAttribute",
+ cb: (currentNode: Element, data: SanitizeAttributeHookEvent, config: Config) => void,
+ ): void;
+ addHook(hook: HookName, cb: (currentNode: Element, data: HookEvent, config: Config) => void): void;
-interface SanitizeElementHookEvent {
- tagName: string;
- allowedTags: string[];
-}
+ setConfig(cfg: Config): void;
+ clearConfig(): void;
+ isValidAttribute(tag: string, attr: string, value: string): boolean;
-interface SanitizeAttributeHookEvent {
- attrName: string;
- attrValue: string;
- keepAttr: boolean;
- allowedAttributes: string[];
-}
+ removeHook(entryPoint: HookName): void;
+ removeHooks(entryPoint: HookName): void;
+ removeAllHooks(): void;
+
+ version: string;
+ removed: any[];
+ isSupported: boolean;
+ }
+
+ interface Config {
+ ADD_ATTR?: string[] | undefined;
+ ADD_DATA_URI_TAGS?: string[] | undefined;
+ ADD_TAGS?: string[] | undefined;
+ ADD_URI_SAFE_ATTR?: string[] | undefined;
+ ALLOW_ARIA_ATTR?: boolean | undefined;
+ ALLOW_DATA_ATTR?: boolean | undefined;
+ ALLOW_UNKNOWN_PROTOCOLS?: boolean | undefined;
+ ALLOW_SELF_CLOSE_IN_ATTR?: boolean | undefined;
+ ALLOWED_ATTR?: string[] | undefined;
+ ALLOWED_TAGS?: string[] | undefined;
+ ALLOWED_NAMESPACES?: string[] | undefined;
+ ALLOWED_URI_REGEXP?: RegExp | undefined;
+ FORBID_ATTR?: string[] | undefined;
+ FORBID_CONTENTS?: string[] | undefined;
+ FORBID_TAGS?: string[] | undefined;
+ FORCE_BODY?: boolean | undefined;
+ IN_PLACE?: boolean | undefined;
+ KEEP_CONTENT?: boolean | undefined;
+ /**
+ * change the default namespace from HTML to something different
+ */
+ NAMESPACE?: string | undefined;
+ PARSER_MEDIA_TYPE?: string | undefined;
+ RETURN_DOM_FRAGMENT?: boolean | undefined;
+ /**
+ * This defaults to `true` starting DOMPurify 2.2.0. Note that setting it to `false`
+ * might cause XSS from attacks hidden in closed shadowroots in case the browser
+ * supports Declarative Shadow: DOM https://web.dev/declarative-shadow-dom/
+ */
+ RETURN_DOM_IMPORT?: boolean | undefined;
+ RETURN_DOM?: boolean | undefined;
+ RETURN_TRUSTED_TYPE?: boolean | undefined;
+ SAFE_FOR_TEMPLATES?: boolean | undefined;
+ SANITIZE_DOM?: boolean | undefined;
+ /** @default false */
+ SANITIZE_NAMED_PROPS?: boolean | undefined;
+ USE_PROFILES?:
+ | false
+ | {
+ mathMl?: boolean | undefined;
+ svg?: boolean | undefined;
+ svgFilters?: boolean | undefined;
+ html?: boolean | undefined;
+ }
+ | undefined;
+ WHOLE_DOCUMENT?: boolean | undefined;
+ CUSTOM_ELEMENT_HANDLING?: {
+ tagNameCheck?: RegExp | ((tagName: string) => boolean) | null | undefined;
+ attributeNameCheck?: RegExp | ((lcName: string) => boolean) | null | undefined;
+ allowCustomizedBuiltInElements?: boolean | undefined;
+ };
+ }
+
+ type HookName =
+ | "beforeSanitizeElements"
+ | "uponSanitizeElement"
+ | "afterSanitizeElements"
+ | "beforeSanitizeAttributes"
+ | "uponSanitizeAttribute"
+ | "afterSanitizeAttributes"
+ | "beforeSanitizeShadowDOM"
+ | "uponSanitizeShadowNode"
+ | "afterSanitizeShadowDOM";
+
+ type HookEvent = SanitizeElementHookEvent | SanitizeAttributeHookEvent | null;
+
+ interface SanitizeElementHookEvent {
+ tagName: string;
+ allowedTags: { [key: string]: boolean };
+ }
+
+ interface SanitizeAttributeHookEvent {
+ attrName: string;
+ attrValue: string;
+ keepAttr: boolean;
+ allowedAttributes: { [key: string]: boolean };
+ forceKeepAttr?: boolean | undefined;
+ }
+}
\ No newline at end of file
diff --git a/extension/types/trusted-types.d.ts b/extension/types/trusted-types.d.ts
new file mode 100644
index 00000000000..bfefff8c4f3
--- /dev/null
+++ b/extension/types/trusted-types.d.ts
@@ -0,0 +1,3 @@
+interface Window {
+ trustedTypes: any;
+}
\ No newline at end of file
diff --git a/package-lock.json b/package-lock.json
index 52a5b20303c..28cca2d5daf 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -796,103 +796,6 @@
"node": ">=12"
}
},
- "node_modules/@puppeteer/browsers": {
- "version": "1.4.6",
- "resolved": "https://registry.npmjs.org/@puppeteer/browsers/-/browsers-1.4.6.tgz",
- "integrity": "sha512-x4BEjr2SjOPowNeiguzjozQbsc6h437ovD/wu+JpaenxVLm3jkgzHY2xOslMTp50HoTvQreMjiexiGQw1sqZlQ==",
- "dev": true,
- "dependencies": {
- "debug": "4.3.4",
- "extract-zip": "2.0.1",
- "progress": "2.0.3",
- "proxy-agent": "6.3.0",
- "tar-fs": "3.0.4",
- "unbzip2-stream": "1.4.3",
- "yargs": "17.7.1"
- },
- "bin": {
- "browsers": "lib/cjs/main-cli.js"
- },
- "engines": {
- "node": ">=16.3.0"
- },
- "peerDependencies": {
- "typescript": ">= 4.7.4"
- },
- "peerDependenciesMeta": {
- "typescript": {
- "optional": true
- }
- }
- },
- "node_modules/@puppeteer/browsers/node_modules/ansi-regex": {
- "version": "5.0.1",
- "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz",
- "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==",
- "dev": true,
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/@puppeteer/browsers/node_modules/emoji-regex": {
- "version": "8.0.0",
- "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz",
- "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==",
- "dev": true
- },
- "node_modules/@puppeteer/browsers/node_modules/is-fullwidth-code-point": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz",
- "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==",
- "dev": true,
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/@puppeteer/browsers/node_modules/string-width": {
- "version": "4.2.3",
- "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz",
- "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==",
- "dev": true,
- "dependencies": {
- "emoji-regex": "^8.0.0",
- "is-fullwidth-code-point": "^3.0.0",
- "strip-ansi": "^6.0.1"
- },
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/@puppeteer/browsers/node_modules/strip-ansi": {
- "version": "6.0.1",
- "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz",
- "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==",
- "dev": true,
- "dependencies": {
- "ansi-regex": "^5.0.1"
- },
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/@puppeteer/browsers/node_modules/yargs": {
- "version": "17.7.1",
- "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.1.tgz",
- "integrity": "sha512-cwiTb08Xuv5fqF4AovYacTFNxk62th7LKJ6BL9IGUpTJrWoU7/7WdQGTP2SjKf1dUNBGzDd28p/Yfs/GI6JrLw==",
- "dev": true,
- "dependencies": {
- "cliui": "^8.0.1",
- "escalade": "^3.1.1",
- "get-caller-file": "^2.0.5",
- "require-directory": "^2.1.1",
- "string-width": "^4.2.3",
- "y18n": "^5.0.5",
- "yargs-parser": "^21.1.1"
- },
- "engines": {
- "node": ">=12"
- }
- },
"node_modules/@selderee/plugin-htmlparser2": {
"version": "0.11.0",
"resolved": "https://registry.npmjs.org/@selderee/plugin-htmlparser2/-/plugin-htmlparser2-0.11.0.tgz",
@@ -1131,6 +1034,18 @@
}
}
},
+ "node_modules/@typescript-eslint/eslint-plugin/node_modules/ts-api-utils": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-1.0.3.tgz",
+ "integrity": "sha512-wNMeqtMz5NtwpT/UZGY5alT+VoKdSsOOP/kqHFcUW1P/VRhH2wJ48+DN2WwUliNbQ976ETwDL0Ifd2VVvgonvg==",
+ "dev": true,
+ "engines": {
+ "node": ">=16.13.0"
+ },
+ "peerDependencies": {
+ "typescript": ">=4.2.0"
+ }
+ },
"node_modules/@typescript-eslint/parser": {
"version": "6.19.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-6.19.0.tgz",
@@ -1203,6 +1118,18 @@
}
}
},
+ "node_modules/@typescript-eslint/type-utils/node_modules/ts-api-utils": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-1.0.3.tgz",
+ "integrity": "sha512-wNMeqtMz5NtwpT/UZGY5alT+VoKdSsOOP/kqHFcUW1P/VRhH2wJ48+DN2WwUliNbQ976ETwDL0Ifd2VVvgonvg==",
+ "dev": true,
+ "engines": {
+ "node": ">=16.13.0"
+ },
+ "peerDependencies": {
+ "typescript": ">=4.2.0"
+ }
+ },
"node_modules/@typescript-eslint/types": {
"version": "6.19.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-6.19.0.tgz",
@@ -1244,6 +1171,18 @@
}
}
},
+ "node_modules/@typescript-eslint/typescript-estree/node_modules/ts-api-utils": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-1.0.3.tgz",
+ "integrity": "sha512-wNMeqtMz5NtwpT/UZGY5alT+VoKdSsOOP/kqHFcUW1P/VRhH2wJ48+DN2WwUliNbQ976ETwDL0Ifd2VVvgonvg==",
+ "dev": true,
+ "engines": {
+ "node": ">=16.13.0"
+ },
+ "peerDependencies": {
+ "typescript": ">=4.2.0"
+ }
+ },
"node_modules/@typescript-eslint/utils": {
"version": "6.19.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-6.19.0.tgz",
@@ -9579,7 +9518,60 @@
"node": ">=16.3.0"
}
},
- "node_modules/puppeteer-core": {
+ "node_modules/puppeteer/node_modules/@puppeteer/browsers": {
+ "version": "1.4.6",
+ "resolved": "https://registry.npmjs.org/@puppeteer/browsers/-/browsers-1.4.6.tgz",
+ "integrity": "sha512-x4BEjr2SjOPowNeiguzjozQbsc6h437ovD/wu+JpaenxVLm3jkgzHY2xOslMTp50HoTvQreMjiexiGQw1sqZlQ==",
+ "dev": true,
+ "dependencies": {
+ "debug": "4.3.4",
+ "extract-zip": "2.0.1",
+ "progress": "2.0.3",
+ "proxy-agent": "6.3.0",
+ "tar-fs": "3.0.4",
+ "unbzip2-stream": "1.4.3",
+ "yargs": "17.7.1"
+ },
+ "bin": {
+ "browsers": "lib/cjs/main-cli.js"
+ },
+ "engines": {
+ "node": ">=16.3.0"
+ },
+ "peerDependencies": {
+ "typescript": ">= 4.7.4"
+ },
+ "peerDependenciesMeta": {
+ "typescript": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/puppeteer/node_modules/ansi-regex": {
+ "version": "5.0.1",
+ "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz",
+ "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==",
+ "dev": true,
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/puppeteer/node_modules/emoji-regex": {
+ "version": "8.0.0",
+ "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz",
+ "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==",
+ "dev": true
+ },
+ "node_modules/puppeteer/node_modules/is-fullwidth-code-point": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz",
+ "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==",
+ "dev": true,
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/puppeteer/node_modules/puppeteer-core": {
"version": "20.9.0",
"resolved": "https://registry.npmjs.org/puppeteer-core/-/puppeteer-core-20.9.0.tgz",
"integrity": "sha512-H9fYZQzMTRrkboEfPmf7m3CLDN6JvbxXA3qTtS+dFt27tR+CsFHzPsT6pzp6lYL6bJbAPaR0HaPO6uSi+F94Pg==",
@@ -9604,6 +9596,50 @@
}
}
},
+ "node_modules/puppeteer/node_modules/string-width": {
+ "version": "4.2.3",
+ "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz",
+ "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==",
+ "dev": true,
+ "dependencies": {
+ "emoji-regex": "^8.0.0",
+ "is-fullwidth-code-point": "^3.0.0",
+ "strip-ansi": "^6.0.1"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/puppeteer/node_modules/strip-ansi": {
+ "version": "6.0.1",
+ "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz",
+ "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==",
+ "dev": true,
+ "dependencies": {
+ "ansi-regex": "^5.0.1"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/puppeteer/node_modules/yargs": {
+ "version": "17.7.1",
+ "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.1.tgz",
+ "integrity": "sha512-cwiTb08Xuv5fqF4AovYacTFNxk62th7LKJ6BL9IGUpTJrWoU7/7WdQGTP2SjKf1dUNBGzDd28p/Yfs/GI6JrLw==",
+ "dev": true,
+ "dependencies": {
+ "cliui": "^8.0.1",
+ "escalade": "^3.1.1",
+ "get-caller-file": "^2.0.5",
+ "require-directory": "^2.1.1",
+ "string-width": "^4.2.3",
+ "y18n": "^5.0.5",
+ "yargs-parser": "^21.1.1"
+ },
+ "engines": {
+ "node": ">=12"
+ }
+ },
"node_modules/qs": {
"version": "6.11.2",
"resolved": "https://registry.npmjs.org/qs/-/qs-6.11.2.tgz",
@@ -11843,18 +11879,6 @@
"integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==",
"dev": true
},
- "node_modules/ts-api-utils": {
- "version": "1.0.3",
- "resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-1.0.3.tgz",
- "integrity": "sha512-wNMeqtMz5NtwpT/UZGY5alT+VoKdSsOOP/kqHFcUW1P/VRhH2wJ48+DN2WwUliNbQ976ETwDL0Ifd2VVvgonvg==",
- "dev": true,
- "engines": {
- "node": ">=16.13.0"
- },
- "peerDependencies": {
- "typescript": ">=4.2.0"
- }
- },
"node_modules/tsconfig-paths": {
"version": "3.15.0",
"resolved": "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-3.15.0.tgz",