Browse Source

UI: Fixed XSS in show web notification

pull/15204/head
Vladyslav_Prykhodko 7 months ago
parent
commit
2b07065538
  1. 14
      ui-ngx/src/app/modules/home/pages/notification/inbox/inbox-table-config.resolver.ts
  2. 4
      ui-ngx/src/app/shared/components/notification/notification.component.html
  3. 13
      ui-ngx/src/app/shared/components/notification/notification.component.ts

14
ui-ngx/src/app/modules/home/pages/notification/inbox/inbox-table-config.resolver.ts

@ -37,9 +37,10 @@ import {
InboxNotificationDialogComponent, InboxNotificationDialogComponent,
InboxNotificationDialogData InboxNotificationDialogData
} from '@home/pages/notification/inbox/inbox-notification-dialog.component'; } from '@home/pages/notification/inbox/inbox-notification-dialog.component';
import { Injectable } from '@angular/core'; import { Injectable, SecurityContext } from '@angular/core';
import { ActivatedRouteSnapshot } from '@angular/router'; import { ActivatedRouteSnapshot } from '@angular/router';
import { UtilsService } from '@core/services/utils.service'; import { UtilsService } from '@core/services/utils.service';
import { DomSanitizer } from '@angular/platform-browser';
@Injectable() @Injectable()
export class InboxTableConfigResolver { export class InboxTableConfigResolver {
@ -50,7 +51,8 @@ export class InboxTableConfigResolver {
private translate: TranslateService, private translate: TranslateService,
private dialog: MatDialog, private dialog: MatDialog,
private datePipe: DatePipe, private datePipe: DatePipe,
private utilsService: UtilsService) { private utilsService: UtilsService,
private sanitizer: DomSanitizer) {
this.config.entityType = EntityType.NOTIFICATION; this.config.entityType = EntityType.NOTIFICATION;
this.config.detailsPanelEnabled = false; this.config.detailsPanelEnabled = false;
@ -95,14 +97,14 @@ export class InboxTableConfigResolver {
new EntityTableColumn<Notification>('type', 'notification.type', '10%', (notification) => new EntityTableColumn<Notification>('type', 'notification.type', '10%', (notification) =>
this.translate.instant(NotificationTemplateTypeTranslateMap.get(notification.type).name)), this.translate.instant(NotificationTemplateTypeTranslateMap.get(notification.type).name)),
new EntityTableColumn<Notification>('subject', 'notification.subject', '30%', new EntityTableColumn<Notification>('subject', 'notification.subject', '30%',
(entity) => this.utilsService.customTranslation(entity.subject, entity.subject)), (entity) => this.sanitizer.sanitize(SecurityContext.HTML, this.utilsService.customTranslation(entity.subject, entity.subject))),
new EntityTableColumn<Notification>('text', 'notification.message', '60%', new EntityTableColumn<Notification>('text', 'notification.message', '60%',
(entity) => this.utilsService.customTranslation(entity.text, entity.text)) (entity) => this.sanitizer.sanitize(SecurityContext.HTML, this.utilsService.customTranslation(entity.text, entity.text)))
); );
} }
resolve(route: ActivatedRouteSnapshot): EntityTableConfig<Notification> { resolve(_route: ActivatedRouteSnapshot): EntityTableConfig<Notification> {
return this.config; return this.config;
} }
@ -128,7 +130,7 @@ export class InboxTableConfigResolver {
}); });
} }
private markAsRead($event, entity){ private markAsRead($event: Event, entity){
if ($event) { if ($event) {
$event.stopPropagation(); $event.stopPropagation();
} }

4
ui-ngx/src/app/shared/components/notification/notification.component.html

@ -28,8 +28,8 @@
</tb-icon> </tb-icon>
</ng-template> </ng-template>
<div class="content flex-1"> <div class="content flex-1">
<div class="title" [innerHTML]="(title | safe: 'html' )"></div> <div class="title" [innerHTML]="title"></div>
<div class="message" [innerHTML]="(message | safe: 'html' )"></div> <div class="message" [innerHTML]="message"></div>
<button *ngIf="showButton" mat-stroked-button class="button" color="primary" <button *ngIf="showButton" mat-stroked-button class="button" color="primary"
(click)="navigate($event)"> (click)="navigate($event)">
{{ buttonLabel }} {{ buttonLabel }}

13
ui-ngx/src/app/shared/components/notification/notification.component.ts

@ -14,7 +14,7 @@
/// limitations under the License. /// limitations under the License.
/// ///
import { Component, EventEmitter, Input, OnInit, Output } from '@angular/core'; import { Component, EventEmitter, Input, OnInit, Output, SecurityContext } from '@angular/core';
import { import {
ActionButtonLinkType, ActionButtonLinkType,
AlarmSeverityNotificationColors, AlarmSeverityNotificationColors,
@ -30,6 +30,7 @@ import tinycolor from 'tinycolor2';
import { StateObject } from '@core/api/widget-api.models'; import { StateObject } from '@core/api/widget-api.models';
import { objToBase64URI } from '@core/utils'; import { objToBase64URI } from '@core/utils';
import { coerceBoolean } from '@shared/decorators/coercion'; import { coerceBoolean } from '@shared/decorators/coercion';
import { DomSanitizer } from '@angular/platform-browser';
@Component({ @Component({
selector: 'tb-notification', selector: 'tb-notification',
@ -68,7 +69,8 @@ export class NotificationComponent implements OnInit {
constructor( constructor(
private utils: UtilsService, private utils: UtilsService,
private router: Router private router: Router,
private sanitizer: DomSanitizer
) { ) {
} }
@ -76,11 +78,10 @@ export class NotificationComponent implements OnInit {
this.showIcon = this.notification.additionalConfig?.icon?.enabled; this.showIcon = this.notification.additionalConfig?.icon?.enabled;
this.showButton = this.notification.additionalConfig?.actionButtonConfig?.enabled; this.showButton = this.notification.additionalConfig?.actionButtonConfig?.enabled;
this.hideMarkAsReadButton = this.notification.status === NotificationStatus.READ; this.hideMarkAsReadButton = this.notification.status === NotificationStatus.READ;
this.title = this.utils.customTranslation(this.notification.subject, this.notification.subject); this.title = this.sanitizer.sanitize(SecurityContext.HTML, this.utils.customTranslation(this.notification.subject));
this.message = this.utils.customTranslation(this.notification.text, this.notification.text); this.message = this.sanitizer.sanitize(SecurityContext.HTML, this.utils.customTranslation(this.notification.text));
if (this.showButton) { if (this.showButton) {
this.buttonLabel = this.utils.customTranslation(this.notification.additionalConfig.actionButtonConfig.text, this.buttonLabel = this.utils.customTranslation(this.notification.additionalConfig.actionButtonConfig.text);
this.notification.additionalConfig.actionButtonConfig.text);
} }
} }

Loading…
Cancel
Save