@tinkoff/ng-dompurify

Inclusive Angular API for DOMPurify

Usage no npm install needed!

<script type="module">
  import tinkoffNgDompurify from 'https://cdn.skypack.dev/@tinkoff/ng-dompurify';
</script>

README

NgDompurify

Build npm bundle size Coverage Status npm version code style: @tinkoff/linters

This library implements DOMPurify as Angular Sanitizer or Pipe. It delegates sanitizing to DOMPurify and supports the same configuration. See DOMPurify.

Install

npm install @tinkoff/ng-dompurify

If you do not have dompurify in your package, install also:

npm install dompurify
npm install --save-dev @types/dompurify

How to use

Either use pipe to sanitize your content when binding to [innerHTML] or use NgDompurifySanitizer service manually.

import {NgDompurifyModule} from '@tinkoff/ng-dompurify';

@NgModule({
    imports: [NgDompurifyModule],
})
export class MyModule {}

As a pipe:

<div [innerHtml]="value | dompurify"></div>

As a service:

import {SecurityContext} from '@angular/core';
import {NgDompurifySanitizer} from '@tinkoff/ng-dompurify';

@Component({})
export class MyComponent {
    constructor(private readonly dompurifySanitizer: NgDompurifySanitizer) {}

    purify(value: string): string {
        return this.dompurifySanitizer.sanitize(SecurityContext.HTML, value);
    }
}

You can also substitute Angular Sanitizer with DOMPurify so it is automatically used all the time:

import {NgModule, Sanitizer} from '@angular/core';
import {NgDompurifySanitizer} from '@tinkoff/ng-dompurify';
// ...

@NgModule({
    // ...
    providers: [
        {
            provide: Sanitizer,
            useClass: NgDompurifySanitizer,
        },
    ],
    // ...
})
export class AppModule {}

Configuring

Config for NgDompurifySanitizer or NgDompurifyDomSanitizer can be provided using token DOMPURIFY_CONFIG. NgDompurifyPipe supports passing DOMPurify config as an argument to override config from DI.

import {NgModule, Sanitizer} from '@angular/core';
import {NgDompurifySanitizer, DOMPURIFY_CONFIG} from '@tinkoff/ng-dompurify';
// ...

@NgModule({
    // ...
    providers: [
        {
            provide: Sanitizer,
            useClass: NgDompurifySanitizer,
        },
        {
            provide: DOMPURIFY_CONFIG,
            useValue: {FORBID_ATTR: ['id']},
        },
    ],
    // ...
})
export class AppModule {}

CSS sanitization

DOMPurify does not support sanitizing CSS. Angular starting version 10 dropped CSS sanitation as something that presents no threat in supported browsers. You can still provide a handler to sanitize CSS rules values upon binding if you want to:

import {NgModule, Sanitizer} from '@angular/core';
import {NgDompurifySanitizer, SANITIZE_STYLE} from '@tinkoff/ng-dompurify';

@NgModule({
    // ...
    providers: [
        {
            provide: Sanitizer,
            useClass: NgDompurifySanitizer,
        },
        {
            provide: SANITIZE_STYLE,
            useValue: yourImplementation, // <---
        },
    ],
    // ...
})
export class AppModule {}

Hooks

DOMPurify supports various hooks. You can provide them using DOMPURIFY_HOOKS token:

import {NgModule, Sanitizer} from '@angular/core';
import {
    NgDompurifySanitizer,
    DOMPURIFY_HOOKS,
    SANITIZE_STYLE,
} from '@tinkoff/ng-dompurify';

@NgModule({
    // ...
    providers: [
        {
            provide: Sanitizer,
            useClass: NgDompurifySanitizer,
        },
        {
            provide: SANITIZE_STYLE,
            useValue: yourImplementation,
        },
        {
            provide: DOMPURIFY_HOOKS,
            useValue: [
                {
                    name: 'beforeSanitizeAttributes',
                    hook: (node: Element) => {
                        node.removeAttribute('id');
                    },
                },
            ],
        },
    ],
    // ...
})
export class AppModule {}

Demo

You can see live demo here: https://stackblitz.com/github/TinkoffCreditSystems/ng-dompurify/tree/master/projects/demo