diff --git a/projects/common/element-components/text.component.ts b/projects/common/element-components/text.component.ts index b87a96880596f0388ff5fe9b8ba4dc59ef2cd698..0ac4eebc3edafe694e1c6235f1e93fb193057f5e 100644 --- a/projects/common/element-components/text.component.ts +++ b/projects/common/element-components/text.component.ts @@ -1,4 +1,5 @@ import { Component, ElementRef, ViewChild } from '@angular/core'; +import { DomSanitizer } from '@angular/platform-browser'; import { TextElement } from '../unit'; import { ElementComponent } from '../element-component.directive'; @@ -22,7 +23,7 @@ import { ElementComponent } from '../element-component.directive'; [style.font-style]="elementModel.italic ? 'italic' : ''" [style.text-decoration]="elementModel.underline ? 'underline' : ''" [style.white-space]="'pre-wrap'" - [innerHTML]="elementModel.text" + [innerHTML]="sanitizer.bypassSecurityTrustHtml(elementModel.text)" #container> </div> </div> @@ -34,6 +35,10 @@ export class TextComponent extends ElementComponent { highlightedNodes: Node[] = []; + constructor(public sanitizer: DomSanitizer) { + super(); + } + // TODO double click selection does not work and adds more and more nested spans highlightSelection(color: string): void { const selection = window.getSelection(); diff --git a/projects/editor/src/app/components/unit-view/page-view/properties/element-properties.component.html b/projects/editor/src/app/components/unit-view/page-view/properties/element-properties.component.html index 3ef3d29628ee61d69b802f698b54e3ff8d7eb401..d57872262c236ea9527d643a1e36a58f68ec1e8d 100644 --- a/projects/editor/src/app/components/unit-view/page-view/properties/element-properties.component.html +++ b/projects/editor/src/app/components/unit-view/page-view/properties/element-properties.component.html @@ -19,8 +19,8 @@ </mat-form-field> Text - <div class="text-text" [innerHTML]="combinedProperties.text" - (click)="unitService.showDefaultEditDialog(selectedElements[0])" > + <div class="text-text" [innerHTML]="sanitizer.bypassSecurityTrustHtml($any(combinedProperties.text))" + (click)="unitService.showDefaultEditDialog(selectedElements[0])"> </div> <mat-checkbox *ngIf="combinedProperties.hasOwnProperty('highlightable')" diff --git a/projects/editor/src/app/components/unit-view/page-view/properties/element-properties.component.ts b/projects/editor/src/app/components/unit-view/page-view/properties/element-properties.component.ts index 58b454ac593df3928f6426d4b21e7b3ed8c96e22..f344af2d506846fe73beafa3e3d54c0ce7da2eaa 100644 --- a/projects/editor/src/app/components/unit-view/page-view/properties/element-properties.component.ts +++ b/projects/editor/src/app/components/unit-view/page-view/properties/element-properties.component.ts @@ -9,6 +9,7 @@ import { UnitUIElement } from '../../../../../../../common/unit'; import { UnitService } from '../../../../unit.service'; import { SelectionService } from '../../../../selection.service'; import { MessageService } from '../../../../../../../common/message.service'; +import { DomSanitizer } from '@angular/platform-browser'; @Component({ selector: 'app-element-properties', @@ -34,7 +35,8 @@ export class ElementPropertiesComponent implements OnInit, OnDestroy { private ngUnsubscribe = new Subject<void>(); constructor(private selectionService: SelectionService, public unitService: UnitService, - private messageService: MessageService) { } + private messageService: MessageService, + public sanitizer: DomSanitizer) { } ngOnInit(): void { this.unitService.elementPropertyUpdated diff --git a/projects/editor/src/app/unit.service.ts b/projects/editor/src/app/unit.service.ts index 3507e80547971a5499d0528594e49a43b2ab9926..6fdaa54ce8a10d18b4037c7ac76073991d1108d9 100644 --- a/projects/editor/src/app/unit.service.ts +++ b/projects/editor/src/app/unit.service.ts @@ -1,4 +1,5 @@ import { Injectable } from '@angular/core'; +import { DomSanitizer, SafeHtml } from '@angular/platform-browser'; import { BehaviorSubject, Observable, Subject } from 'rxjs'; import { Unit, UnitPage, UnitPageSection, UnitUIElement @@ -23,7 +24,8 @@ export class UnitService { constructor(private veronaApiService: VeronaAPIService, private messageService: MessageService, private idService: IdService, - private dialogService: DialogService) { + private dialogService: DialogService, + private sanitizer: DomSanitizer) { const initialUnit = UnitFactory.createUnit(); const initialPage = UnitFactory.createUnitPage(0); const initialSection = UnitFactory.createUnitPageSection(); @@ -306,7 +308,12 @@ export class UnitService { case 'text': this.dialogService.showRichTextEditDialog(element.text as string).subscribe((result: string) => { if (result) { - this.updateElementProperty([element], 'text', result); + // TODO add proper sanitization + this.updateElementProperty( + [element], + 'text', + (this.sanitizer.bypassSecurityTrustHtml(result) as any).changingThisBreaksApplicationSecurity as string + ); } }); break;