Skip to content

Commit

Permalink
chore: add TrustedHTML to sanitizer output to fix build errors for CSP (
Browse files Browse the repository at this point in the history
#151)

* chore: add TrustedHTML to sanitizer output to fix build errors for CSP
  • Loading branch information
ghiscoding authored Nov 7, 2023
1 parent 82b5baf commit 7eeeab1
Show file tree
Hide file tree
Showing 14 changed files with 26 additions and 12 deletions.
3 changes: 3 additions & 0 deletions .github/workflows/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,9 @@ jobs:
- name: Install Playwright Browsers (chromium)
run: pnpm exec playwright install chromium

- name: Start HTTP Server
run: pnpm serve:demo &

- name: Find Playwright Summary Comment (when exist)
if: ${{ github.event.pull_request.number }}
uses: peter-evans/find-comment@v2
Expand Down
2 changes: 2 additions & 0 deletions demo/src/examples/example13.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import DOMPurify from 'dompurify';
import { multipleSelect, MultipleSelectInstance } from 'multiple-select-vanilla';

export default class Example {
Expand All @@ -17,6 +18,7 @@ export default class Example {
name: 'my-select',
single: false,
useSelectOptionLabelToHtml: true,
sanitizer: (html) => DOMPurify.sanitize(html, { RETURN_TRUSTED_TYPE: true }),
data: [
{
text: '<i class="fa fa-star"></i> January',
Expand Down
3 changes: 3 additions & 0 deletions demo/src/options/options27.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import DOMPurify from 'dompurify';
import { multipleSelect, MultipleSelectInstance, TextFilter } from 'multiple-select-vanilla';

export default class Example {
Expand All @@ -20,6 +21,7 @@ export default class Example {
divElm.innerHTML = text;
return divElm.textContent?.includes(search) ?? true;
},
sanitizer: (html) => DOMPurify.sanitize(html, { RETURN_TRUSTED_TYPE: true }),
}) as MultipleSelectInstance;

this.ms2 = multipleSelect('#from-data', {
Expand All @@ -31,6 +33,7 @@ export default class Example {
{ value: `44'`, text: `44'` },
{ value: `33`, text: `<span style="font-weight:bold">33</span>` },
],
sanitizer: (html) => DOMPurify.sanitize(html, { RETURN_TRUSTED_TYPE: true }) as unknown as string,
}) as MultipleSelectInstance;

this.btnEnableElm = document.querySelector('#enableRenderHtml') as HTMLButtonElement;
Expand Down
2 changes: 2 additions & 0 deletions demo/src/options/options28.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import DOMPurify from 'dompurify';
import { multipleSelect, MultipleSelectInstance } from 'multiple-select-vanilla';

export default class Example {
Expand All @@ -9,6 +10,7 @@ export default class Example {
labelTemplate: (el) => {
return `<i class="fa fa-star"></i>${el.getAttribute('label')}`;
},
sanitizer: (html) => DOMPurify.sanitize(html, { RETURN_TRUSTED_TYPE: true }),
}) as MultipleSelectInstance;
}

Expand Down
4 changes: 4 additions & 0 deletions demo/src/options/options30.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import DOMPurify from 'dompurify';
import { multipleSelect, MultipleSelectInstance } from 'multiple-select-vanilla';

export default class Example {
Expand All @@ -12,18 +13,21 @@ export default class Example {
autoAdjustDropHeight: true,
position: 'top',
showOkButton: true,
sanitizer: (html) => DOMPurify.sanitize(html, { RETURN_TRUSTED_TYPE: true }),
}) as MultipleSelectInstance;

this.ms2 = multipleSelect('#select2', {
autoAdjustDropHeight: true,
position: 'top',
showOkButton: true,
sanitizer: (html) => DOMPurify.sanitize(html, { RETURN_TRUSTED_TYPE: true }),
}) as MultipleSelectInstance;

this.ms3 = multipleSelect('#select3', {
autoAdjustDropHeight: true,
filter: true,
position: 'top',
sanitizer: (html) => DOMPurify.sanitize(html, { RETURN_TRUSTED_TYPE: true }) as unknown as string,
}) as MultipleSelectInstance;

this.ms4 = multipleSelect('#select4') as MultipleSelectInstance;
Expand Down
2 changes: 2 additions & 0 deletions demo/src/options/options31.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import DOMPurify from 'dompurify';
import { multipleSelect, MultipleSelectInstance } from 'multiple-select-vanilla';

export default class Example {
Expand All @@ -11,6 +12,7 @@ export default class Example {

this.ms2 = multipleSelect('#select2', {
useSelectOptionLabelToHtml: true,
sanitizer: (html) => DOMPurify.sanitize(html, { RETURN_TRUSTED_TYPE: true }),
data: [
{
text: '<i class="fa fa-star"></i> January',
Expand Down
2 changes: 1 addition & 1 deletion demo/src/options/options32.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ export default class Example {
: dirtyHtml,

// or even better, use dedicated libraries like DOM Purify: https://github.com/cure53/DOMPurify
// sanitizer: (dirtyHtml) => DOMPurify.sanitize(dirtyHtml || '')
// sanitizer: (html) => DOMPurify.sanitize(html, { RETURN_TRUSTED_TYPE: true }),
}) as MultipleSelectInstance;
}

Expand Down
1 change: 1 addition & 0 deletions lib/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,7 @@
"sass:copy": "cross-env copyfiles -u 2 src/styles/**/*.scss dist/styles/sass"
},
"devDependencies": {
"@types/trusted-types": "^2.0.5",
"autoprefixer": "^10.4.16",
"copyfiles": "^2.4.1",
"cross-env": "^7.0.3",
Expand Down
2 changes: 1 addition & 1 deletion lib/src/MultipleSelectInstance.ts
Original file line number Diff line number Diff line change
Expand Up @@ -972,7 +972,7 @@ export class MultipleSelectInstance {
*/
protected renderAsTextOrHtmlWhenEnabled(elm: HTMLElement, value: string) {
if (this.isRenderAsHtml) {
elm.innerHTML = this.options.sanitizer ? this.options.sanitizer(value) : value;
elm.innerHTML = (typeof this.options.sanitizer === 'function' ? this.options.sanitizer(value) : value) as unknown as string;
} else {
elm.textContent = value;
}
Expand Down
2 changes: 1 addition & 1 deletion lib/src/interfaces/interfaces.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ export interface VirtualScrollOption {
scrollEl: HTMLElement;
contentEl: HTMLElement;
callback: () => void;
sanitizer?: (dirtyHtml: string) => string;
sanitizer?: (html: string) => string | TrustedHTML;
}

export interface MultipleSelectLocale {
Expand Down
2 changes: 1 addition & 1 deletion lib/src/interfaces/multipleSelectOption.interface.ts
Original file line number Diff line number Diff line change
Expand Up @@ -255,5 +255,5 @@ export interface MultipleSelectOption extends MultipleSelectLocale {
* Sanitizes HTML code, for example `<script>`, to prevents XSS attacks.
* A library like DOM Purify could be used to sanitize html code, for example: `sanitizer: (dirtyHtml) => DOMPurify.sanitize(dirtyHtml || '')`
*/
sanitizer?: (dirtyHtml: string) => string;
sanitizer?: (html: string) => string | TrustedHTML;
}
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@
"new-publish": "lerna publish from-package",
"preroll-new-release": "echo Please update getting-started lib version before pushing release. ⚠️",
"roll-new-release": "pnpm build && pnpm new-version && pnpm new-publish",
"serve": "pnpm -r --stream --filter=\"{demo/**}\" dev",
"serve:demo": "pnpm -r --stream --filter=\"{demo/**}\" dev",
"test:e2e": "playwright test --config playwright/playwright.config.ts",
"test:e2e:debug": "playwright test --config playwright/playwright.config.ts --ui --debug",
"test:e2e:ui": "playwright test --config playwright/playwright.config.ts --ui",
Expand Down
8 changes: 1 addition & 7 deletions playwright/playwright.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ export default defineConfig({
timeout: 5000,
},
/* Fail the build on CI if you accidentally left test.only in the source code. */
forbidOnly: !!process.env.CI,
forbidOnly: Boolean(process.env.CI),
use: {
baseURL: 'http://localhost:3000/',
headless: true,
Expand All @@ -26,10 +26,4 @@ export default defineConfig({
// { name: 'firefox', use: { ...devices['Desktop Firefox'] } },
]
: [{ name: 'chromium', use: { ...devices['Desktop Chrome'] } }],
webServer: process.env.CI
? {
command: 'pnpm serve',
port: 3000,
}
: undefined,
});
3 changes: 3 additions & 0 deletions pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

0 comments on commit 7eeeab1

Please sign in to comment.