Merge pull request #14050 from dashevchenko/noXssEnhancement2

NoXss validation enhancements
This commit is contained in:
Viacheslav Klimov 2025-09-24 11:50:05 +03:00 committed by GitHub
commit d16be8238d
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 12 additions and 2 deletions

View File

@ -30,6 +30,7 @@ import org.thingsboard.server.common.data.id.MobileAppId;
import org.thingsboard.server.common.data.id.TenantId; import org.thingsboard.server.common.data.id.TenantId;
import org.thingsboard.server.common.data.mobile.layout.MobileLayoutConfig; import org.thingsboard.server.common.data.mobile.layout.MobileLayoutConfig;
import org.thingsboard.server.common.data.validation.Length; import org.thingsboard.server.common.data.validation.Length;
import org.thingsboard.server.common.data.validation.NoXss;
@EqualsAndHashCode(callSuper = true) @EqualsAndHashCode(callSuper = true)
@Data @Data
@ -40,9 +41,11 @@ public class MobileAppBundle extends BaseData<MobileAppBundleId> implements HasT
private TenantId tenantId; private TenantId tenantId;
@Schema(description = "Application bundle title. Cannot be empty", requiredMode = Schema.RequiredMode.REQUIRED) @Schema(description = "Application bundle title. Cannot be empty", requiredMode = Schema.RequiredMode.REQUIRED)
@NotBlank @NotBlank
@NoXss
@Length(fieldName = "title") @Length(fieldName = "title")
private String title; private String title;
@Schema(description = "Application bundle description.") @Schema(description = "Application bundle description.")
@NoXss
@Length(fieldName = "description") @Length(fieldName = "description")
private String description; private String description;
@Schema(description = "Android application id") @Schema(description = "Android application id")

View File

@ -62,6 +62,7 @@ public class NotificationRule extends BaseData<NotificationRuleId> implements Ha
@Valid @Valid
private NotificationRuleRecipientsConfig recipientsConfig; private NotificationRuleRecipientsConfig recipientsConfig;
@Valid
private NotificationRuleConfig additionalConfig; private NotificationRuleConfig additionalConfig;
private NotificationRuleId externalId; private NotificationRuleId externalId;

View File

@ -16,12 +16,14 @@
package org.thingsboard.server.common.data.notification.rule; package org.thingsboard.server.common.data.notification.rule;
import lombok.Data; import lombok.Data;
import org.thingsboard.server.common.data.validation.NoXss;
import java.io.Serializable; import java.io.Serializable;
@Data @Data
public class NotificationRuleConfig implements Serializable { public class NotificationRuleConfig implements Serializable {
@NoXss
private String description; private String description;
} }

View File

@ -24,6 +24,7 @@ import {
NgZone, NgZone,
OnDestroy, OnDestroy,
OnInit, OnInit,
SecurityContext,
ViewChild ViewChild
} from '@angular/core'; } from '@angular/core';
import { ControlValueAccessor, NG_VALUE_ACCESSOR } from '@angular/forms'; import { ControlValueAccessor, NG_VALUE_ACCESSOR } from '@angular/forms';
@ -53,6 +54,7 @@ import {
import { deepClone } from '@core/utils'; import { deepClone } from '@core/utils';
import { hidePageSizePixelValue } from '@shared/models/constants'; import { hidePageSizePixelValue } from '@shared/models/constants';
import { CdkDragDrop, moveItemInArray } from '@angular/cdk/drag-drop'; import { CdkDragDrop, moveItemInArray } from '@angular/cdk/drag-drop';
import { DomSanitizer } from '@angular/platform-browser';
@Component({ @Component({
selector: 'tb-manage-widget-actions', selector: 'tb-manage-widget-actions',
@ -106,7 +108,8 @@ export class ManageWidgetActionsComponent extends PageComponent implements OnIni
private dialogs: DialogService, private dialogs: DialogService,
private cd: ChangeDetectorRef, private cd: ChangeDetectorRef,
private elementRef: ElementRef, private elementRef: ElementRef,
private zone: NgZone) { private zone: NgZone,
private sanitizer: DomSanitizer) {
super(); super();
const sortOrder: SortOrder = { property: 'actionSourceName', direction: Direction.ASC }; const sortOrder: SortOrder = { property: 'actionSourceName', direction: Direction.ASC };
this.pageLink = new PageLink(10, 0, null, sortOrder); this.pageLink = new PageLink(10, 0, null, sortOrder);
@ -289,7 +292,8 @@ export class ManageWidgetActionsComponent extends PageComponent implements OnIni
} }
const title = this.translate.instant('widget-config.delete-action-title'); const title = this.translate.instant('widget-config.delete-action-title');
const content = this.translate.instant('widget-config.delete-action-text', {actionName: action.name}); const content = this.translate.instant('widget-config.delete-action-text', {actionName: action.name});
this.dialogs.confirm(title, content, const safeContent = this.sanitizer.sanitize(SecurityContext.HTML, content);
this.dialogs.confirm(title, safeContent,
this.translate.instant('action.no'), this.translate.instant('action.no'),
this.translate.instant('action.yes'), true).subscribe( this.translate.instant('action.yes'), true).subscribe(
(res) => { (res) => {