Skip to content

Commit

Permalink
fix: allow inline styling propagation from CMS (#17988)
Browse files Browse the repository at this point in the history
Introduce SafeHtmlPipe for bypassing styles from CMS

Closes: CXSPA-3708
  • Loading branch information
rmch91 authored Oct 19, 2023
1 parent 376f1b7 commit 40515ff
Showing 7 changed files with 100 additions and 11 deletions.
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
<div
*ngIf="component.data$ | async as data"
[innerHTML]="data.content ?? '' | cxSupplementHashAnchors"
[innerHTML]="data.content ?? '' | cxSupplementHashAnchors | cxSafeHtml"
></div>
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
import { DebugElement, Pipe, PipeTransform } from '@angular/core';
import { waitForAsync, ComponentFixture, TestBed } from '@angular/core/testing';
import { By } from '@angular/platform-browser';
import { ComponentFixture, TestBed, waitForAsync } from '@angular/core/testing';
import { By, SafeHtml } from '@angular/platform-browser';
import { Router } from '@angular/router';
import { RouterTestingModule } from '@angular/router/testing';
import { CmsComponent, CmsParagraphComponent } from '@spartacus/core';
import { CmsComponentData } from '@spartacus/storefront';
import { BehaviorSubject } from 'rxjs';
import { ParagraphComponent } from './paragraph.component';
import { CmsComponentData } from '@spartacus/storefront';
import { CmsParagraphComponent, CmsComponent } from '@spartacus/core';
import { RouterTestingModule } from '@angular/router/testing';
import { Router } from '@angular/router';

@Pipe({ name: 'cxSupplementHashAnchors' })
export class MockAnchorPipe implements PipeTransform {
@@ -15,6 +15,13 @@ export class MockAnchorPipe implements PipeTransform {
}
}

@Pipe({ name: 'cxSafeHtml' })
export class MockSafeHtmlPipe implements PipeTransform {
public transform(html: string): SafeHtml {
return html;
}
}

describe('CmsParagraphComponent in CmsLib', () => {
let paragraphComponent: ParagraphComponent;
let fixture: ComponentFixture<ParagraphComponent>;
@@ -41,7 +48,7 @@ describe('CmsParagraphComponent in CmsLib', () => {
waitForAsync(() => {
TestBed.configureTestingModule({
imports: [RouterTestingModule],
declarations: [MockAnchorPipe, ParagraphComponent],
declarations: [MockAnchorPipe, ParagraphComponent, MockSafeHtmlPipe],
providers: [
{
provide: CmsComponentData,
Original file line number Diff line number Diff line change
@@ -4,15 +4,21 @@
* SPDX-License-Identifier: Apache-2.0
*/

import { NgModule } from '@angular/core';
import { CommonModule } from '@angular/common';
import { NgModule } from '@angular/core';
import { RouterModule } from '@angular/router';
import { CmsConfig, provideDefaultConfig } from '@spartacus/core';
import { SafeHtmlModule } from '../../../shared/pipes/safe-html/safe-html.module';
import { SupplementHashAnchorsModule } from '../../../shared/pipes/suplement-hash-anchors/supplement-hash-anchors.module';
import { ParagraphComponent } from './paragraph.component';
import { RouterModule } from '@angular/router';

@NgModule({
imports: [CommonModule, RouterModule, SupplementHashAnchorsModule],
imports: [
CommonModule,
RouterModule,
SupplementHashAnchorsModule,
SafeHtmlModule,
],
providers: [
provideDefaultConfig(<CmsConfig>{
cmsComponents: {
2 changes: 2 additions & 0 deletions projects/storefrontlib/shared/pipes/index.ts
Original file line number Diff line number Diff line change
@@ -4,5 +4,7 @@
* SPDX-License-Identifier: Apache-2.0
*/

export * from './safe-html/safe-html.module';
export * from './safe-html/safe-html.pipe';
export * from './suplement-hash-anchors/supplement-hash-anchors.module';
export * from './suplement-hash-anchors/supplement-hash-anchors.pipe';
14 changes: 14 additions & 0 deletions projects/storefrontlib/shared/pipes/safe-html/safe-html.module.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
/*
* SPDX-FileCopyrightText: 2023 SAP Spartacus team <spartacus-team@sap.com>
*
* SPDX-License-Identifier: Apache-2.0
*/

import { NgModule } from '@angular/core';
import { SafeHtmlPipe } from './safe-html.pipe';

@NgModule({
declarations: [SafeHtmlPipe],
exports: [SafeHtmlPipe],
})
export class SafeHtmlModule {}
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
/*
* SPDX-FileCopyrightText: 2023 SAP Spartacus team <spartacus-team@sap.com>
*
* SPDX-License-Identifier: Apache-2.0
*/

import { TestBed } from '@angular/core/testing';
import { DomSanitizer } from '@angular/platform-browser';
import { SafeHtmlPipe } from './safe-html.pipe';

describe('SafeHtmlPipe', () => {
let safeHtmlPipe: SafeHtmlPipe;

beforeEach(() => {
TestBed.configureTestingModule({
providers: [
SafeHtmlPipe,
{
provide: DomSanitizer,
useValue: {
bypassSecurityTrustHtml: (value: string) => value,
},
},
],
});

safeHtmlPipe = TestBed.inject(SafeHtmlPipe);
});

it('should create an instance', () => {
expect(safeHtmlPipe).toBeTruthy();
});

it('should bypass security and return SafeHtml', () => {
const htmlString = '<div>Some HTML content</div>';
const sanitizedHtml = safeHtmlPipe.transform(htmlString);

expect(sanitizedHtml).toBeDefined();
});
});
20 changes: 20 additions & 0 deletions projects/storefrontlib/shared/pipes/safe-html/safe-html.pipe.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
/*
* SPDX-FileCopyrightText: 2023 SAP Spartacus team <spartacus-team@sap.com>
*
* SPDX-License-Identifier: Apache-2.0
*/

import { Pipe, PipeTransform } from '@angular/core';
import { DomSanitizer, SafeHtml } from '@angular/platform-browser';

/*
* Pipe for bypassing security trust html
*/
@Pipe({ name: 'cxSafeHtml' })
export class SafeHtmlPipe implements PipeTransform {
constructor(private sanitizer: DomSanitizer) {}

public transform(html: string = ''): SafeHtml {
return this.sanitizer.bypassSecurityTrustHtml(html);
}
}

0 comments on commit 40515ff

Please sign in to comment.