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 d795b255ae7..6f55a710ad8 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
@@ -2,6 +2,7 @@
'use strict';
+import { TrustedHTML, TrustedTypesWindow } from 'types/trusted-types.js';
import { Time } from '../../../js/common/browser/time.js';
import { Catch } from '../../../js/common/platform/catch.js';
import { Xss } from '../../../js/common/platform/xss.js';
@@ -15,7 +16,7 @@ export class PgpBlockViewPrintModule {
return;
}
const w = window.open();
- let html = `
+ const html = `
@@ -81,16 +82,19 @@ export class PgpBlockViewPrintModule {
`;
+ let trustedHtml: TrustedHTML | undefined;
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment, @typescript-eslint/no-unsafe-member-access
+ const trustedTypes = (w as unknown as TrustedTypesWindow).trustedTypes;
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
- if (w?.trustedTypes?.createPolicy) {
+ if (trustedTypes?.createPolicy) {
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment, @typescript-eslint/no-unsafe-call, @typescript-eslint/no-unsafe-member-access
- const policy = w?.trustedTypes.createPolicy('print-policy', {
+ const policy = trustedTypes.createPolicy('print-policy', {
createHTML: (string: string) => string,
});
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment, @typescript-eslint/no-unsafe-call, @typescript-eslint/no-unsafe-member-access
- html = policy.createHTML(html);
+ trustedHtml = policy.createHTML(html);
}
- w?.document.write(html);
+ w?.document.write(html || (trustedHtml as unknown as string));
// Give some time for above dom to load in print dialog
// https://stackoverflow.com/questions/31725373/google-chrome-not-showing-image-in-print-preview
await Time.sleep(250);
diff --git a/extension/js/common/platform/xss.ts b/extension/js/common/platform/xss.ts
index 89e285eeaf9..db3875f11e8 100644
--- a/extension/js/common/platform/xss.ts
+++ b/extension/js/common/platform/xss.ts
@@ -82,13 +82,15 @@ export class Xss {
public static htmlSanitize = (dirtyHtml: string, tagCheck = false): string => {
Xss.throwIfNotSupported();
/* eslint-disable @typescript-eslint/naming-convention */
- return DOMPurify.sanitize(dirtyHtml, {
+ const sanitized = DOMPurify.sanitize(dirtyHtml, {
ADD_ATTR: Xss.ADD_ATTR,
+ RETURN_TRUSTED_TYPE: true,
FORBID_ATTR: Xss.FORBID_ATTR,
...(tagCheck && { ALLOWED_TAGS: Xss.ALLOWED_HTML_TAGS }),
ALLOWED_URI_REGEXP: Xss.sanitizeHrefRegexp(),
});
/* eslint-enable @typescript-eslint/naming-convention */
+ return sanitized as unknown as string;
};
/**
diff --git a/extension/types/purify.d.ts b/extension/types/purify.d.ts
index f7328784c90..4489b9e02b2 100644
--- a/extension/types/purify.d.ts
+++ b/extension/types/purify.d.ts
@@ -1,4 +1,4 @@
-///
+import { TrustedHTML } from 'trusted-types';
export as namespace DOMPurify;
export = DOMPurify;
@@ -24,7 +24,7 @@ interface createDOMPurifyI extends DOMPurify.DOMPurifyI {
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_TRUSTED_TYPE: true }): TrustedHTML;
sanitize(
source: string | Node,
config: Config & { RETURN_DOM_FRAGMENT?: false | undefined; RETURN_DOM?: false | undefined },
diff --git a/extension/types/trusted-types.d.ts b/extension/types/trusted-types.d.ts
index bfefff8c4f3..2c7ccd4b806 100644
--- a/extension/types/trusted-types.d.ts
+++ b/extension/types/trusted-types.d.ts
@@ -1,3 +1,64 @@
-interface Window {
- trustedTypes: any;
-}
\ No newline at end of file
+// The main type definitions. Packages that do not want to pollute the global
+// scope with Trusted Types (e.g. libraries whose users may not be using Trusted
+// Types) can import the types directly from 'trusted-types/lib'.
+
+export type FnNames = keyof TrustedTypePolicyOptions;
+export type Args = Parameters>;
+
+export class TrustedHTML {
+ private constructor(); // To prevent instantiting with 'new'.
+ private brand: true; // To prevent structural typing.
+}
+
+export class TrustedScript {
+ private constructor(); // To prevent instantiting with 'new'.
+ private brand: true; // To prevent structural typing.
+}
+
+export class TrustedScriptURL {
+ private constructor(); // To prevent instantiting with 'new'.
+ private brand: true; // To prevent structural typing.
+}
+
+export abstract class TrustedTypePolicyFactory {
+ createPolicy(
+ policyName: string,
+ policyOptions?: Options,
+ ): Pick, "name" | Extract>;
+ isHTML(value: unknown): value is TrustedHTML;
+ isScript(value: unknown): value is TrustedScript;
+ isScriptURL(value: unknown): value is TrustedScriptURL;
+ readonly emptyHTML: TrustedHTML;
+ readonly emptyScript: TrustedScript;
+ getAttributeType(tagName: string, attribute: string, elementNs?: string, attrNs?: string): string | null;
+ getPropertyType(tagName: string, property: string, elementNs?: string): string | null;
+ readonly defaultPolicy: TrustedTypePolicy | null;
+}
+
+export abstract class TrustedTypePolicy {
+ readonly name: string;
+ createHTML(...args: Args): TrustedHTML;
+ createScript(...args: Args): TrustedScript;
+ createScriptURL(...args: Args): TrustedScriptURL;
+}
+
+export interface TrustedTypePolicyOptions {
+ createHTML?: ((input: string, ...arguments: any[]) => string) | undefined;
+ createScript?: ((input: string, ...arguments: any[]) => string) | undefined;
+ createScriptURL?: ((input: string, ...arguments: any[]) => string) | undefined;
+}
+
+// The Window object is augmented with the following properties in browsers that
+// support Trusted Types. Users of the 'trusted-types/lib' entrypoint can cast
+// window as TrustedTypesWindow to access these properties.
+export interface TrustedTypesWindow {
+ // `trustedTypes` is left intentionally optional to make sure that
+ // people handle the case when their code is running in a browser not
+ // supporting trustedTypes.
+ trustedTypes?: TrustedTypePolicyFactory | undefined;
+ TrustedHTML: typeof TrustedHTML;
+ TrustedScript: typeof TrustedScript;
+ TrustedScriptURL: typeof TrustedScriptURL;
+ TrustedTypePolicyFactory: typeof TrustedTypePolicyFactory;
+ TrustedTypePolicy: typeof TrustedTypePolicy;
+}