Commit 615e56b522cf15de41127eb22b0d8895664452a6

Authored by Igor Kulikov
Committed by GitHub
2 parents 851bed37 25d8f4d3

Merge pull request #5503 from vvlladd28/improvement/fields-validation/max-length

Added fields length validation
... ... @@ -21,6 +21,7 @@ import org.thingsboard.server.common.data.id.AdminSettingsId;
21 21
22 22 import com.fasterxml.jackson.databind.JsonNode;
23 23 import org.thingsboard.server.common.data.id.DeviceId;
  24 +import org.thingsboard.server.common.data.validation.Length;
24 25 import org.thingsboard.server.common.data.validation.NoXss;
25 26
26 27 @ApiModel
... ... @@ -29,6 +30,7 @@ public class AdminSettings extends BaseData<AdminSettingsId> {
29 30 private static final long serialVersionUID = -7670322981725511892L;
30 31
31 32 @NoXss
  33 + @Length(fieldName = "key")
32 34 private String key;
33 35 private transient JsonNode jsonValue;
34 36
... ...
... ... @@ -68,10 +68,13 @@ public class OtaPackageInfo extends SearchTextBasedWithAdditionalInfo<OtaPackage
68 68 @NoXss
69 69 @ApiModelProperty(position = 11, value = "OTA Package file name.", example = "fw_1.0", readOnly = true)
70 70 private String fileName;
  71 + @NoXss
  72 + @Length(fieldName = "contentType")
71 73 @ApiModelProperty(position = 12, value = "OTA Package content type.", example = "APPLICATION_OCTET_STREAM", readOnly = true)
72 74 private String contentType;
73 75 @ApiModelProperty(position = 13, value = "OTA Package checksum algorithm.", example = "CRC32", readOnly = true)
74 76 private ChecksumAlgorithm checksumAlgorithm;
  77 + @Length(fieldName = "checksum", max = 1020)
75 78 @ApiModelProperty(position = 14, value = "OTA Package checksum.", example = "0xd87f7e0c", readOnly = true)
76 79 private String checksum;
77 80 @ApiModelProperty(position = 15, value = "OTA Package data size.", example = "8", readOnly = true)
... ...
... ... @@ -42,6 +42,8 @@ public class TbResourceInfo extends SearchTextBased<TbResourceId> implements Has
42 42 private String title;
43 43 @ApiModelProperty(position = 5, value = "Resource type.", example = "LWM2M_MODEL", readOnly = true)
44 44 private ResourceType resourceType;
  45 + @NoXss
  46 + @Length(fieldName = "resourceKey")
45 47 @ApiModelProperty(position = 6, value = "Resource key.", example = "19_1.0", readOnly = true)
46 48 private String resourceKey;
47 49 @ApiModelProperty(position = 7, value = "Resource search text.", example = "19_1.0:binaryappdatacontainer", readOnly = true)
... ...
... ... @@ -37,6 +37,7 @@ public class Tenant extends ContactBased<TenantId> implements HasTenantId {
37 37 @ApiModelProperty(position = 3, value = "Title of the tenant", example = "Company A")
38 38 private String title;
39 39 @NoXss
  40 + @Length(fieldName = "region")
40 41 @ApiModelProperty(position = 5, value = "Geo region of the tenant", example = "North America")
41 42 private String region;
42 43
... ...
... ... @@ -29,6 +29,7 @@ import org.thingsboard.server.common.data.id.EdgeId;
29 29 import org.thingsboard.server.common.data.id.RuleChainId;
30 30 import org.thingsboard.server.common.data.id.TenantId;
31 31 import org.thingsboard.server.common.data.validation.Length;
  32 +import org.thingsboard.server.common.data.validation.NoXss;
32 33
33 34 @ApiModel
34 35 @EqualsAndHashCode(callSuper = true)
... ... @@ -41,15 +42,26 @@ public class Edge extends SearchTextBasedWithAdditionalInfo<EdgeId> implements H
41 42 private TenantId tenantId;
42 43 private CustomerId customerId;
43 44 private RuleChainId rootRuleChainId;
  45 + @NoXss
44 46 @Length(fieldName = "name")
45 47 private String name;
  48 + @NoXss
46 49 @Length(fieldName = "type")
47 50 private String type;
  51 + @NoXss
48 52 @Length(fieldName = "label")
49 53 private String label;
  54 + @NoXss
  55 + @Length(fieldName = "routingKey")
50 56 private String routingKey;
  57 + @NoXss
  58 + @Length(fieldName = "secret")
51 59 private String secret;
  60 + @NoXss
  61 + @Length(fieldName = "edgeLicenseKey", max = 30)
52 62 private String edgeLicenseKey;
  63 + @NoXss
  64 + @Length(fieldName = "cloudEndpoint")
53 65 private String cloudEndpoint;
54 66
55 67 public Edge() {
... ...
... ... @@ -21,6 +21,7 @@ import lombok.Builder;
21 21 import lombok.Data;
22 22 import lombok.EqualsAndHashCode;
23 23 import lombok.ToString;
  24 +import org.thingsboard.server.common.data.validation.Length;
24 25
25 26 @Builder(toBuilder = true)
26 27 @EqualsAndHashCode
... ... @@ -28,21 +29,27 @@ import lombok.ToString;
28 29 @ToString
29 30 @ApiModel
30 31 public class OAuth2BasicMapperConfig {
  32 + @Length(fieldName = "emailAttributeKey", max = 31)
31 33 @ApiModelProperty(value = "Email attribute key of OAuth2 principal attributes. " +
32 34 "Must be specified for BASIC mapper type and cannot be specified for GITHUB type")
33 35 private final String emailAttributeKey;
  36 + @Length(fieldName = "firstNameAttributeKey", max = 31)
34 37 @ApiModelProperty(value = "First name attribute key")
35 38 private final String firstNameAttributeKey;
  39 + @Length(fieldName = "lastNameAttributeKey", max = 31)
36 40 @ApiModelProperty(value = "Last name attribute key")
37 41 private final String lastNameAttributeKey;
38 42 @ApiModelProperty(value = "Tenant naming strategy. For DOMAIN type, domain for tenant name will be taken from the email (substring before '@')", required = true)
39 43 private final TenantNameStrategyType tenantNameStrategy;
  44 + @Length(fieldName = "tenantNamePattern")
40 45 @ApiModelProperty(value = "Tenant name pattern for CUSTOM naming strategy. " +
41 46 "OAuth2 attributes in the pattern can be used by enclosing attribute key in '%{' and '}'", example = "%{email}")
42 47 private final String tenantNamePattern;
  48 + @Length(fieldName = "customerNamePattern")
43 49 @ApiModelProperty(value = "Customer name pattern. When creating a user on the first OAuth2 log in, if specified, " +
44 50 "customer name will be used to create or find existing customer in the platform and assign customerId to the user")
45 51 private final String customerNamePattern;
  52 + @Length(fieldName = "defaultDashboardName")
46 53 @ApiModelProperty(value = "Name of the tenant's dashboard to set as default dashboard for newly created user")
47 54 private final String defaultDashboardName;
48 55 @ApiModelProperty(value = "Whether default dashboard should be open in full screen")
... ...
... ... @@ -24,7 +24,9 @@ import lombok.ToString;
24 24 import org.thingsboard.server.common.data.HasName;
25 25 import org.thingsboard.server.common.data.SearchTextBasedWithAdditionalInfo;
26 26 import org.thingsboard.server.common.data.id.OAuth2ClientRegistrationTemplateId;
  27 +import org.thingsboard.server.common.data.validation.Length;
27 28
  29 +import javax.validation.Valid;
28 30 import java.util.List;
29 31
30 32 @EqualsAndHashCode(callSuper = true)
... ... @@ -34,30 +36,42 @@ import java.util.List;
34 36 @ApiModel
35 37 public class OAuth2ClientRegistrationTemplate extends SearchTextBasedWithAdditionalInfo<OAuth2ClientRegistrationTemplateId> implements HasName {
36 38
  39 + @Length(fieldName = "providerId")
37 40 @ApiModelProperty(value = "OAuth2 provider identifier (e.g. its name)", required = true)
38 41 private String providerId;
  42 + @Valid
39 43 @ApiModelProperty(value = "Default config for mapping OAuth2 log in response to platform entities")
40 44 private OAuth2MapperConfig mapperConfig;
  45 + @Length(fieldName = "authorizationUri")
41 46 @ApiModelProperty(value = "Default authorization URI of the OAuth2 provider")
42 47 private String authorizationUri;
  48 + @Length(fieldName = "accessTokenUri")
43 49 @ApiModelProperty(value = "Default access token URI of the OAuth2 provider")
44 50 private String accessTokenUri;
45 51 @ApiModelProperty(value = "Default OAuth scopes that will be requested from OAuth2 platform")
46 52 private List<String> scope;
  53 + @Length(fieldName = "userInfoUri")
47 54 @ApiModelProperty(value = "Default user info URI of the OAuth2 provider")
48 55 private String userInfoUri;
  56 + @Length(fieldName = "userNameAttributeName")
49 57 @ApiModelProperty(value = "Default name of the username attribute in OAuth2 provider log in response")
50 58 private String userNameAttributeName;
  59 + @Length(fieldName = "jwkSetUri")
51 60 @ApiModelProperty(value = "Default JSON Web Key URI of the OAuth2 provider")
52 61 private String jwkSetUri;
  62 + @Length(fieldName = "clientAuthenticationMethod")
53 63 @ApiModelProperty(value = "Default client authentication method to use: 'BASIC' or 'POST'")
54 64 private String clientAuthenticationMethod;
  65 + @Length(fieldName = "comment")
55 66 @ApiModelProperty(value = "Comment for OAuth2 provider")
56 67 private String comment;
  68 + @Length(fieldName = "loginButtonIcon")
57 69 @ApiModelProperty(value = "Default log in button icon for OAuth2 provider")
58 70 private String loginButtonIcon;
  71 + @Length(fieldName = "loginButtonLabel")
59 72 @ApiModelProperty(value = "Default OAuth2 provider label")
60 73 private String loginButtonLabel;
  74 + @Length(fieldName = "helpLink")
61 75 @ApiModelProperty(value = "Help link for OAuth2 provider")
62 76 private String helpLink;
63 77
... ...
... ... @@ -15,15 +15,22 @@
15 15 */
16 16 package org.thingsboard.server.common.data.oauth2;
17 17
18   -import lombok.*;
  18 +import lombok.Builder;
  19 +import lombok.Data;
  20 +import lombok.EqualsAndHashCode;
  21 +import lombok.ToString;
  22 +import org.thingsboard.server.common.data.validation.Length;
19 23
20 24 @Builder(toBuilder = true)
21 25 @EqualsAndHashCode
22 26 @Data
23 27 @ToString(exclude = {"password"})
24 28 public class OAuth2CustomMapperConfig {
  29 + @Length(fieldName = "url")
25 30 private final String url;
  31 + @Length(fieldName = "username")
26 32 private final String username;
  33 + @Length(fieldName = "password")
27 34 private final String password;
28 35 private final boolean sendToken;
29 36 }
... ...
... ... @@ -21,6 +21,8 @@ import lombok.Data;
21 21 import lombok.EqualsAndHashCode;
22 22 import lombok.ToString;
23 23
  24 +import javax.validation.Valid;
  25 +
24 26 @Builder(toBuilder = true)
25 27 @EqualsAndHashCode
26 28 @Data
... ... @@ -32,8 +34,10 @@ public class OAuth2MapperConfig {
32 34 private boolean activateUser;
33 35 @ApiModelProperty(value = "Type of OAuth2 mapper. Depending on this param, different mapper config fields must be specified", required = true)
34 36 private MapperType type;
  37 + @Valid
35 38 @ApiModelProperty(value = "Mapper config for BASIC and GITHUB mapper types")
36 39 private OAuth2BasicMapperConfig basic;
  40 + @Valid
37 41 @ApiModelProperty(value = "Mapper config for CUSTOM mapper type")
38 42 private OAuth2CustomMapperConfig custom;
39 43 }
... ...
... ... @@ -21,6 +21,7 @@ import io.swagger.annotations.ApiModelProperty;
21 21 import lombok.*;
22 22 import org.thingsboard.server.common.data.SearchTextBased;
23 23 import org.thingsboard.server.common.data.id.ComponentDescriptorId;
  24 +import org.thingsboard.server.common.data.validation.Length;
24 25
25 26 /**
26 27 * @author Andrew Shvayka
... ... @@ -35,12 +36,14 @@ public class ComponentDescriptor extends SearchTextBased<ComponentDescriptorId>
35 36 @Getter @Setter private ComponentType type;
36 37 @ApiModelProperty(position = 4, value = "Scope of the Rule Node. Always set to 'TENANT', since no rule chains on the 'SYSTEM' level yet.", readOnly = true, allowableValues = "TENANT", example = "TENANT")
37 38 @Getter @Setter private ComponentScope scope;
  39 + @Length(fieldName = "name")
38 40 @ApiModelProperty(position = 5, value = "Name of the Rule Node. Taken from the @RuleNode annotation.", readOnly = true, example = "Custom Rule Node")
39 41 @Getter @Setter private String name;
40 42 @ApiModelProperty(position = 6, value = "Full name of the Java class that implements the Rule Engine Node interface.", readOnly = true, example = "com.mycompany.CustomRuleNode")
41 43 @Getter @Setter private String clazz;
42 44 @ApiModelProperty(position = 7, value = "Complex JSON object that represents the Rule Node configuration.", readOnly = true)
43 45 @Getter @Setter private transient JsonNode configurationDescriptor;
  46 + @Length(fieldName = "actions")
44 47 @ApiModelProperty(position = 8, value = "Rule Node Actions. Deprecated. Always null.", readOnly = true)
45 48 @Getter @Setter private String actions;
46 49
... ...
... ... @@ -21,6 +21,7 @@ import org.thingsboard.server.common.data.BaseData;
21 21 import org.thingsboard.server.common.data.HasTenantId;
22 22 import org.thingsboard.server.common.data.id.TenantId;
23 23 import org.thingsboard.server.common.data.id.WidgetTypeId;
  24 +import org.thingsboard.server.common.data.validation.Length;
24 25 import org.thingsboard.server.common.data.validation.NoXss;
25 26
26 27 @Data
... ... @@ -31,12 +32,15 @@ public class BaseWidgetType extends BaseData<WidgetTypeId> implements HasTenantI
31 32 @ApiModelProperty(position = 3, value = "JSON object with Tenant Id.", readOnly = true)
32 33 private TenantId tenantId;
33 34 @NoXss
  35 + @Length(fieldName = "bundleAlias")
34 36 @ApiModelProperty(position = 4, value = "Reference to widget bundle", readOnly = true)
35 37 private String bundleAlias;
36 38 @NoXss
  39 + @Length(fieldName = "alias")
37 40 @ApiModelProperty(position = 5, value = "Unique alias that is used in dashboards as a reference widget type", readOnly = true)
38 41 private String alias;
39 42 @NoXss
  43 + @Length(fieldName = "name")
40 44 @ApiModelProperty(position = 6, value = "Widget name used in search and UI", readOnly = true)
41 45 private String name;
42 46
... ...
... ... @@ -19,15 +19,18 @@ import com.fasterxml.jackson.annotation.JsonPropertyOrder;
19 19 import io.swagger.annotations.ApiModelProperty;
20 20 import lombok.Data;
21 21 import org.thingsboard.server.common.data.id.WidgetTypeId;
  22 +import org.thingsboard.server.common.data.validation.Length;
22 23 import org.thingsboard.server.common.data.validation.NoXss;
23 24
24 25 @Data
25 26 @JsonPropertyOrder({ "alias", "name", "image", "description", "descriptor" })
26 27 public class WidgetTypeDetails extends WidgetType {
27 28
  29 + @NoXss
28 30 @ApiModelProperty(position = 8, value = "Base64 encoded thumbnail", readOnly = true)
29 31 private String image;
30 32 @NoXss
  33 + @Length(fieldName = "description")
31 34 @ApiModelProperty(position = 9, value = "Description of the widget", readOnly = true)
32 35 private String description;
33 36
... ...
... ... @@ -79,6 +79,9 @@
79 79 <mat-error *ngIf="domainInfo.get('name').hasError('pattern')">
80 80 {{ 'admin.error-verification-url' | translate }}
81 81 </mat-error>
  82 + <mat-error *ngIf="domainInfo.get('name').hasError('maxlength')">
  83 + {{ 'admin.domain-name-max-length' | translate }}
  84 + </mat-error>
82 85 </mat-form-field>
83 86 </div>
84 87 <mat-error *ngIf="domainInfo.hasError('unique')">
... ... @@ -246,6 +249,9 @@
246 249 <mat-error *ngIf="registration.get('clientId').hasError('required')">
247 250 {{ 'admin.oauth2.client-id-required' | translate }}
248 251 </mat-error>
  252 + <mat-error *ngIf="registration.get('clientId').hasError('maxlength')">
  253 + {{ 'admin.oauth2.client-id-max-length' | translate }}
  254 + </mat-error>
249 255 </mat-form-field>
250 256
251 257 <mat-form-field fxFlex class="mat-block">
... ... @@ -254,6 +260,9 @@
254 260 <mat-error *ngIf="registration.get('clientSecret').hasError('required')">
255 261 {{ 'admin.oauth2.client-secret-required' | translate }}
256 262 </mat-error>
  263 + <mat-error *ngIf="registration.get('clientSecret').hasError('maxlength')">
  264 + {{ 'admin.oauth2.client-secret-max-length' | translate }}
  265 + </mat-error>
257 266 </mat-form-field>
258 267 </div>
259 268
... ... @@ -426,17 +435,29 @@
426 435 *ngIf="registration.get('mapperConfig.basic.emailAttributeKey').hasError('required')">
427 436 {{ 'admin.oauth2.email-attribute-key-required' | translate }}
428 437 </mat-error>
  438 + <mat-error
  439 + *ngIf="registration.get('mapperConfig.basic.emailAttributeKey').hasError('maxlength')">
  440 + {{ 'admin.oauth2.email-attribute-key-max-length' | translate }}
  441 + </mat-error>
429 442 </mat-form-field>
430 443
431 444 <div fxLayout="row" fxLayout.xs="column" fxLayoutGap.gt-xs="8px">
432 445 <mat-form-field fxFlex class="mat-block">
433 446 <mat-label translate>admin.oauth2.first-name-attribute-key</mat-label>
434 447 <input matInput formControlName="firstNameAttributeKey">
  448 + <mat-error
  449 + *ngIf="registration.get('mapperConfig.basic.firstNameAttributeKey').hasError('maxlength')">
  450 + {{ 'admin.oauth2.first-name-attribute-key-max-length' | translate }}
  451 + </mat-error>
435 452 </mat-form-field>
436 453
437 454 <mat-form-field fxFlex class="mat-block">
438 455 <mat-label translate>admin.oauth2.last-name-attribute-key</mat-label>
439 456 <input matInput formControlName="lastNameAttributeKey">
  457 + <mat-error
  458 + *ngIf="registration.get('mapperConfig.basic.lastNameAttributeKey').hasError('maxlength')">
  459 + {{ 'admin.oauth2.last-name-attribute-key-max-length' | translate }}
  460 + </mat-error>
440 461 </mat-form-field>
441 462 </div>
442 463
... ... @@ -460,18 +481,30 @@
460 481 *ngIf="registration.get('mapperConfig.basic.tenantNamePattern').hasError('required')">
461 482 {{ 'admin.oauth2.tenant-name-pattern-required' | translate }}
462 483 </mat-error>
  484 + <mat-error
  485 + *ngIf="registration.get('mapperConfig.basic.tenantNamePattern').hasError('maxlength')">
  486 + {{ 'admin.oauth2.tenant-name-pattern-max-length' | translate }}
  487 + </mat-error>
463 488 </mat-form-field>
464 489 </div>
465 490
466 491 <mat-form-field fxFlex class="mat-block">
467 492 <mat-label translate>admin.oauth2.customer-name-pattern</mat-label>
468 493 <input matInput formControlName="customerNamePattern">
  494 + <mat-error
  495 + *ngIf="registration.get('mapperConfig.basic.customerNamePattern').hasError('maxlength')">
  496 + {{ 'admin.oauth2.customer-name-pattern-max-length' | translate }}
  497 + </mat-error>
469 498 </mat-form-field>
470 499
471 500 <div fxLayout="row" fxLayout.xs="column" fxLayoutGap.gt-xs="8px">
472 501 <mat-form-field fxFlex class="mat-block">
473 502 <mat-label translate>admin.oauth2.default-dashboard-name</mat-label>
474 503 <input matInput formControlName="defaultDashboardName">
  504 + <mat-error
  505 + *ngIf="registration.get('mapperConfig.basic.defaultDashboardName').hasError('maxlength')">
  506 + {{ 'admin.oauth2.default-dashboard-name-max-length' | translate }}
  507 + </mat-error>
475 508 </mat-form-field>
476 509
477 510 <mat-checkbox fxFlex formControlName="alwaysFullScreen" class="checkbox-row">
... ... @@ -493,18 +526,28 @@
493 526 *ngIf="registration.get('mapperConfig.custom.url').hasError('pattern')">
494 527 {{ 'admin.oauth2.url-pattern' | translate }}
495 528 </mat-error>
  529 + <mat-error
  530 + *ngIf="registration.get('mapperConfig.custom.url').hasError('maxlength')">
  531 + {{ 'admin.oauth2.url-max-length' | translate }}
  532 + </mat-error>
496 533 </mat-form-field>
497 534
498 535 <div fxLayout="row" fxLayout.xs="column" fxLayoutGap.gt-xs="8px">
499 536 <mat-form-field fxFlex class="mat-block">
500 537 <mat-label translate>common.username</mat-label>
501 538 <input matInput formControlName="username" autocomplete="new-username">
  539 + <mat-error *ngIf="registration.get('mapperConfig.custom.username').hasError('maxlength')">
  540 + {{ 'admin.oauth2.username-max-length' | translate }}
  541 + </mat-error>
502 542 </mat-form-field>
503 543
504 544 <mat-form-field fxFlex class="mat-block">
505 545 <mat-label translate>common.password</mat-label>
506 546 <input matInput type="password" formControlName="password" autocomplete="new-password">
507 547 <tb-toggle-password matSuffix></tb-toggle-password>
  548 + <mat-error *ngIf="registration.get('mapperConfig.custom.password').hasError('maxlength')">
  549 + {{ 'admin.oauth2.password-max-length' | translate }}
  550 + </mat-error>
508 551 </mat-form-field>
509 552 </div>
510 553 </section>
... ...
... ... @@ -155,13 +155,18 @@ export class OAuth2SettingsComponent extends PageComponent implements OnInit, Ha
155 155 tenantNamePattern = {value: null, disabled: true};
156 156 }
157 157 const basicGroup = this.fb.group({
158   - emailAttributeKey: [mapperConfigBasic?.emailAttributeKey ? mapperConfigBasic.emailAttributeKey : 'email', Validators.required],
159   - firstNameAttributeKey: [mapperConfigBasic?.firstNameAttributeKey ? mapperConfigBasic.firstNameAttributeKey : ''],
160   - lastNameAttributeKey: [mapperConfigBasic?.lastNameAttributeKey ? mapperConfigBasic.lastNameAttributeKey : ''],
  158 + emailAttributeKey: [mapperConfigBasic?.emailAttributeKey ? mapperConfigBasic.emailAttributeKey : 'email',
  159 + [Validators.required, Validators.maxLength(31)]],
  160 + firstNameAttributeKey: [mapperConfigBasic?.firstNameAttributeKey ? mapperConfigBasic.firstNameAttributeKey : '',
  161 + Validators.maxLength(31)],
  162 + lastNameAttributeKey: [mapperConfigBasic?.lastNameAttributeKey ? mapperConfigBasic.lastNameAttributeKey : '',
  163 + Validators.maxLength(31)],
161 164 tenantNameStrategy: [mapperConfigBasic?.tenantNameStrategy ? mapperConfigBasic.tenantNameStrategy : TenantNameStrategy.DOMAIN],
162   - tenantNamePattern: [tenantNamePattern, Validators.required],
163   - customerNamePattern: [mapperConfigBasic?.customerNamePattern ? mapperConfigBasic.customerNamePattern : null],
164   - defaultDashboardName: [mapperConfigBasic?.defaultDashboardName ? mapperConfigBasic.defaultDashboardName : null],
  165 + tenantNamePattern: [tenantNamePattern, [Validators.required, Validators.maxLength(255)]],
  166 + customerNamePattern: [mapperConfigBasic?.customerNamePattern ? mapperConfigBasic.customerNamePattern : null,
  167 + Validators.maxLength(255)],
  168 + defaultDashboardName: [mapperConfigBasic?.defaultDashboardName ? mapperConfigBasic.defaultDashboardName : null,
  169 + Validators.maxLength(255)],
165 170 alwaysFullScreen: [isDefinedAndNotNull(mapperConfigBasic?.alwaysFullScreen) ? mapperConfigBasic.alwaysFullScreen : false]
166 171 });
167 172
... ... @@ -178,9 +183,10 @@ export class OAuth2SettingsComponent extends PageComponent implements OnInit, Ha
178 183
179 184 private formCustomGroup(mapperConfigCustom?: MapperConfigCustom): FormGroup {
180 185 return this.fb.group({
181   - url: [mapperConfigCustom?.url ? mapperConfigCustom.url : null, [Validators.required, Validators.pattern(this.URL_REGEXP)]],
182   - username: [mapperConfigCustom?.username ? mapperConfigCustom.username : null],
183   - password: [mapperConfigCustom?.password ? mapperConfigCustom.password : null]
  186 + url: [mapperConfigCustom?.url ? mapperConfigCustom.url : null,
  187 + [Validators.required, Validators.pattern(this.URL_REGEXP), Validators.maxLength(255)]],
  188 + username: [mapperConfigCustom?.username ? mapperConfigCustom.username : null, Validators.maxLength(255)],
  189 + password: [mapperConfigCustom?.password ? mapperConfigCustom.password : null, Validators.maxLength(255)]
184 190 });
185 191 }
186 192
... ... @@ -266,7 +272,7 @@ export class OAuth2SettingsComponent extends PageComponent implements OnInit, Ha
266 272 private buildDomainInfoForm(domainInfo?: OAuth2DomainInfo): FormGroup {
267 273 return this.fb.group({
268 274 name: [domainInfo ? domainInfo.name : this.window.location.hostname, [
269   - Validators.required,
  275 + Validators.required, Validators.maxLength(255),
270 276 Validators.pattern(this.DOMAIN_AND_PORT_REGEXP)]],
271 277 scheme: [domainInfo?.scheme ? domainInfo.scheme : DomainSchema.HTTPS, Validators.required]
272 278 }, {validators: this.uniqueDomainValidator});
... ... @@ -300,8 +306,8 @@ export class OAuth2SettingsComponent extends PageComponent implements OnInit, Ha
300 306 platforms: [registration?.platforms ? registration.platforms : []],
301 307 loginButtonLabel: [registration?.loginButtonLabel ? registration.loginButtonLabel : null, Validators.required],
302 308 loginButtonIcon: [registration?.loginButtonIcon ? registration.loginButtonIcon : null],
303   - clientId: [registration?.clientId ? registration.clientId : '', Validators.required],
304   - clientSecret: [registration?.clientSecret ? registration.clientSecret : '', Validators.required],
  309 + clientId: [registration?.clientId ? registration.clientId : '', [Validators.required, Validators.maxLength(255)]],
  310 + clientSecret: [registration?.clientSecret ? registration.clientSecret : '', [Validators.required, Validators.maxLength(2048)]],
305 311 accessTokenUri: [registration?.accessTokenUri ? registration.accessTokenUri : '',
306 312 [Validators.required,
307 313 Validators.pattern(this.URL_REGEXP)]],
... ...
... ... @@ -143,8 +143,8 @@
143 143 <mat-error *ngIf="entityForm.get('edgeLicenseKey').hasError('required')">
144 144 {{ 'edge.edge-license-key-required' | translate }}
145 145 </mat-error>
146   - <mat-error *ngIf="entityForm.get('type').hasError('maxlength')">
147   - {{ 'edge.type-max-length' | translate }}
  146 + <mat-error *ngIf="entityForm.get('edgeLicenseKey').hasError('maxlength')">
  147 + {{ 'edge.edge-license-key-max-length' | translate }}
148 148 </mat-error>
149 149 </mat-form-field>
150 150 </div>
... ... @@ -156,6 +156,9 @@
156 156 <mat-error *ngIf="entityForm.get('cloudEndpoint').hasError('required')">
157 157 {{ 'edge.cloud-endpoint-required' | translate }}
158 158 </mat-error>
  159 + <mat-error *ngIf="entityForm.get('cloudEndpoint').hasError('maxlength')">
  160 + {{ 'edge.cloud-endpoint-max-length' | translate }}
  161 + </mat-error>
159 162 </mat-form-field>
160 163 </div>
161 164 </fieldset>
... ...
... ... @@ -73,8 +73,8 @@ export class EdgeComponent extends EntityComponent<EdgeInfo> {
73 73 name: [entity ? entity.name : '', [Validators.required, Validators.maxLength(255)]],
74 74 type: [entity?.type ? entity.type : 'default', [Validators.required, Validators.maxLength(255)]],
75 75 label: [entity ? entity.label : '', Validators.maxLength(255)],
76   - cloudEndpoint: [null, [Validators.required]],
77   - edgeLicenseKey: ['', [Validators.required]],
  76 + cloudEndpoint: [null, [Validators.required, Validators.maxLength(255)]],
  77 + edgeLicenseKey: ['', [Validators.required, Validators.maxLength(30)]],
78 78 routingKey: this.fb.control({value: entity ? entity.routingKey : null, disabled: true}),
79 79 secret: this.fb.control({value: entity ? entity.secret : null, disabled: true}),
80 80 additionalInfo: this.fb.group(
... ...
... ... @@ -21,7 +21,7 @@
21 21 <mat-toolbar class="mat-elevation-z1 tb-edit-toolbar mat-hue-3" fxLayoutGap="16px" fxLayoutGap.lt-xl="8px">
22 22 <mat-form-field floatLabel="always" hideRequiredMarker class="tb-widget-title">
23 23 <mat-label></mat-label>
24   - <input [disabled]="isReadOnly" matInput required
  24 + <input [disabled]="isReadOnly" matInput required maxlength="255"
25 25 [(ngModel)]="widget.widgetName" (ngModelChange)="isDirty = true"
26 26 placeholder="{{ 'widget.title' | translate }}"/>
27 27 </mat-form-field>
... ...
... ... @@ -158,6 +158,7 @@
158 158 "user-lockout-notification-email": "In case user account lockout, send notification to email",
159 159 "domain-name": "Domain name",
160 160 "domain-name-unique": "Domain name and protocol need to unique.",
  161 + "domain-name-max-length": "Domain name should be less than 256",
161 162 "error-verification-url": "A domain name shouldn't contain symbols '/' and ':'. Example: thingsboard.io",
162 163 "oauth2": {
163 164 "access-token-uri": "Access token URI",
... ... @@ -174,21 +175,28 @@
174 175 "client-authentication-method": "Client authentication method",
175 176 "client-id": "Client ID",
176 177 "client-id-required": "Client ID is required.",
  178 + "client-id-max-length": "Client ID should be less than 256",
177 179 "client-secret": "Client secret",
178 180 "client-secret-required": "Client secret is required.",
  181 + "client-secret-max-length": "Client secret should be less than 2049",
179 182 "custom-setting": "Custom settings",
180 183 "customer-name-pattern": "Customer name pattern",
  184 + "customer-name-pattern-max-length": "Customer name pattern should be less than 256",
181 185 "default-dashboard-name": "Default dashboard name",
  186 + "default-dashboard-name-max-length": "Default dashboard name should be less than 256",
182 187 "delete-domain-text": "Be careful, after the confirmation a domain and all provider data will be unavailable.",
183 188 "delete-domain-title": "Are you sure you want to delete settings the domain '{{domainName}}'?",
184 189 "delete-registration-text": "Be careful, after the confirmation a provider data will be unavailable.",
185 190 "delete-registration-title": "Are you sure you want to delete the provider '{{name}}'?",
186 191 "email-attribute-key": "Email attribute key",
187 192 "email-attribute-key-required": "Email attribute key is required.",
  193 + "email-attribute-key-max-length": "Email attribute key should be less than 32",
188 194 "first-name-attribute-key": "First name attribute key",
  195 + "first-name-attribute-key-max-length": "First name attribute key should be less than 32",
189 196 "general": "General",
190 197 "jwk-set-uri": "JSON Web Key URI",
191 198 "last-name-attribute-key": "Last name attribute key",
  199 + "last-name-attribute-key-max-length": "Last name attribute key should be less than 32",
192 200 "login-button-icon": "Login button icon",
193 201 "login-button-label": "Provider label",
194 202 "login-button-label-placeholder": "Login with $(Provider label)",
... ... @@ -197,6 +205,7 @@
197 205 "mapper": "Mapper",
198 206 "new-domain": "New domain",
199 207 "oauth2": "OAuth2",
  208 + "password-max-length": "Password should be less than 256",
200 209 "redirect-uri-template": "Redirect URI template",
201 210 "copy-redirect-uri": "Copy redirect URI",
202 211 "registration-id": "Registration ID",
... ... @@ -206,14 +215,17 @@
206 215 "scope-required": "Scope is required.",
207 216 "tenant-name-pattern": "Tenant name pattern",
208 217 "tenant-name-pattern-required": "Tenant name pattern is required.",
  218 + "tenant-name-pattern-max-length": "Tenant name pattern ishould be less than 256",
209 219 "tenant-name-strategy": "Tenant name strategy",
210 220 "type": "Mapper type",
211 221 "uri-pattern-error": "Invalid URI format.",
212 222 "url": "URL",
213 223 "url-pattern": "Invalid URL format.",
214 224 "url-required": "URL is required.",
  225 + "url-max-length": "URL should be less than 256",
215 226 "user-info-uri": "User info URI",
216 227 "user-info-uri-required": "User info URI is required.",
  228 + "username-max-length": "User name should be less than 256",
217 229 "user-name-attribute-name": "User name attribute key",
218 230 "user-name-attribute-name-required": "User name attribute key is required",
219 231 "protocol": "Protocol",
... ... @@ -1448,9 +1460,11 @@
1448 1460 "name-required": "Name is required.",
1449 1461 "edge-license-key": "Edge License Key",
1450 1462 "edge-license-key-required": "Edge License Key is required.",
  1463 + "edge-license-key-max-length": "Edge License Key should be less than 31",
1451 1464 "edge-license-key-hint": "To obtain your license please navigate to the <a href='https://thingsboard.io/pricing/?active=thingsboard-edge' target='_blank'>pricing page</a> and select the best license option for your case.",
1452 1465 "cloud-endpoint": "Cloud Endpoint",
1453 1466 "cloud-endpoint-required": "Cloud Endpoint is required.",
  1467 + "cloud-endpoint-max-length": "Cloud Endpoint should be less than 256",
1454 1468 "cloud-endpoint-hint": "Edge requires HTTP(s) access to Cloud (ThingsBoard CE/PE) to verify the license key. Please specify Cloud URL that Edge is able to connect to.",
1455 1469 "description": "Description",
1456 1470 "details": "Details",
... ...