From 9dcb7b9b5bc13c39b7531322259ee90ceb52050c Mon Sep 17 00:00:00 2001 From: Vladyslav Date: Thu, 29 Apr 2021 18:25:38 +0300 Subject: [PATCH] UI: Refactoring for the build rule node ui (#4460) * UI: Refactoring LWM2M; fixed build ui rule node * UI: Refactoring LWM2M security config --- .../device/device-credentials.component.html | 4 +- .../device/device-credentials.component.ts | 75 ++-- ...ecurity-config-lwm2m-server.component.html | 79 ++++ ...ecurity-config-lwm2m-server.component.scss | 20 + .../security-config-lwm2m-server.component.ts | 176 ++++++++ .../security-config-lwm2m.component.html | 143 +++++++ .../security-config-lwm2m.component.scss | 34 ++ .../device/security-config-lwm2m.component.ts | 257 ++++++++++++ .../home/components/home-components.module.ts | 6 + .../lwm2m-attributes-dialog.component.ts | 27 +- .../lwm2m-attributes-key-list.component.ts | 30 +- .../lwm2m/lwm2m-attributes.component.ts | 41 +- .../lwm2m-device-config-server.component.ts | 18 +- ...ofile-transport-configuration.component.ts | 31 +- ...m-object-add-instances-dialog.component.ts | 14 +- ...m2m-object-add-instances-list.component.ts | 11 +- .../lwm2m/lwm2m-object-list.component.ts | 47 +-- ...serve-attr-telemetry-resource.component.ts | 19 +- .../lwm2m-observe-attr-telemetry.component.ts | 24 +- .../lwm2m/lwm2m-profile-components.module.ts | 26 +- .../lwm2m/lwm2m-profile-config.models.ts | 4 +- .../home/pages/device/device.module.ts | 6 +- .../security-config-server.component.html | 101 ----- .../lwm2m/security-config-server.component.ts | 142 ------- .../lwm2m/security-config.component.html | 180 --------- .../device/lwm2m/security-config.component.ts | 382 ------------------ .../models/lwm2m-security-config.models.ts} | 66 ++- .../assets/locale/locale.constant-en_US.json | 15 +- 28 files changed, 925 insertions(+), 1053 deletions(-) create mode 100644 ui-ngx/src/app/modules/home/components/device/security-config-lwm2m-server.component.html create mode 100644 ui-ngx/src/app/modules/home/components/device/security-config-lwm2m-server.component.scss create mode 100644 ui-ngx/src/app/modules/home/components/device/security-config-lwm2m-server.component.ts create mode 100644 ui-ngx/src/app/modules/home/components/device/security-config-lwm2m.component.html create mode 100644 ui-ngx/src/app/modules/home/components/device/security-config-lwm2m.component.scss create mode 100644 ui-ngx/src/app/modules/home/components/device/security-config-lwm2m.component.ts delete mode 100644 ui-ngx/src/app/modules/home/pages/device/lwm2m/security-config-server.component.html delete mode 100644 ui-ngx/src/app/modules/home/pages/device/lwm2m/security-config-server.component.ts delete mode 100644 ui-ngx/src/app/modules/home/pages/device/lwm2m/security-config.component.html delete mode 100644 ui-ngx/src/app/modules/home/pages/device/lwm2m/security-config.component.ts rename ui-ngx/src/app/{modules/home/pages/device/lwm2m/security-config.models.ts => shared/models/lwm2m-security-config.models.ts} (60%) diff --git a/ui-ngx/src/app/modules/home/components/device/device-credentials.component.html b/ui-ngx/src/app/modules/home/components/device/device-credentials.component.html index faa2dbbce4..db28ff0453 100644 --- a/ui-ngx/src/app/modules/home/components/device/device-credentials.component.html +++ b/ui-ngx/src/app/modules/home/components/device/device-credentials.component.html @@ -20,7 +20,7 @@ device.credentials-type - {{ credentialTypeNamesMap.get(deviceCredentialsType[credentialsType]) }} + {{ credentialTypeNamesMap.get(credentialsType) }} @@ -85,7 +85,7 @@ device.lwm2m-value diff --git a/ui-ngx/src/app/modules/home/components/device/device-credentials.component.ts b/ui-ngx/src/app/modules/home/components/device/device-credentials.component.ts index edc331d338..17ad828b48 100644 --- a/ui-ngx/src/app/modules/home/components/device/device-credentials.component.ts +++ b/ui-ngx/src/app/modules/home/components/device/device-credentials.component.ts @@ -14,7 +14,7 @@ /// limitations under the License. /// -import {Component, forwardRef, Input, OnDestroy, OnInit} from '@angular/core'; +import { Component, forwardRef, Input, OnDestroy, OnInit } from '@angular/core'; import { ControlValueAccessor, FormBuilder, @@ -33,9 +33,9 @@ import { DeviceCredentials, DeviceCredentialsType } from '@shared/models/device.models'; -import {Subscription} from 'rxjs'; -import {distinctUntilChanged} from 'rxjs/operators'; -import {SecurityConfigComponent} from '@home/pages/device/lwm2m/security-config.component'; +import { Subject } from 'rxjs'; +import { distinctUntilChanged, takeUntil } from 'rxjs/operators'; +import { SecurityConfigLwm2mComponent } from '@home/components/device/security-config-lwm2m.component'; import { ClientSecurityConfig, DEFAULT_END_POINT, @@ -44,10 +44,10 @@ import { getDefaultSecurityConfig, JSON_ALL_CONFIG, validateSecurityConfig -} from '@home/pages/device/lwm2m/security-config.models'; -import {TranslateService} from '@ngx-translate/core'; -import {MatDialog} from '@angular/material/dialog'; -import {isDefinedAndNotNull} from '@core/utils'; +} from '@shared/models/lwm2m-security-config.models'; +import { TranslateService } from '@ngx-translate/core'; +import { MatDialog } from '@angular/material/dialog'; +import { isDefinedAndNotNull } from '@core/utils'; @Component({ selector: 'tb-device-credentials', @@ -67,20 +67,16 @@ import {isDefinedAndNotNull} from '@core/utils'; }) export class DeviceCredentialsComponent implements ControlValueAccessor, OnInit, Validator, OnDestroy { - deviceCredentialsFormGroup: FormGroup; - - subscriptions: Subscription[] = []; - @Input() disabled: boolean; - deviceCredentials: DeviceCredentials = null; + private destroy$ = new Subject(); - submitted = false; + deviceCredentialsFormGroup: FormGroup; deviceCredentialsType = DeviceCredentialsType; - credentialsTypes = Object.keys(DeviceCredentialsType); + credentialsTypes = Object.values(DeviceCredentialsType); credentialTypeNamesMap = credentialTypeNames; @@ -102,16 +98,17 @@ export class DeviceCredentialsComponent implements ControlValueAccessor, OnInit, }, {validators: this.atLeastOne(Validators.required, ['clientId', 'userName'])}) }); this.deviceCredentialsFormGroup.get('credentialsBasic').disable(); - this.subscriptions.push( - this.deviceCredentialsFormGroup.valueChanges.pipe(distinctUntilChanged()).subscribe(() => { - this.updateView(); - }) - ); - this.subscriptions.push( - this.deviceCredentialsFormGroup.get('credentialsType').valueChanges.subscribe(() => { - this.credentialsTypeChanged(); - }) - ); + this.deviceCredentialsFormGroup.valueChanges.pipe( + distinctUntilChanged(), + takeUntil(this.destroy$) + ).subscribe(() => { + this.updateView(); + }); + this.deviceCredentialsFormGroup.get('credentialsType').valueChanges.pipe( + takeUntil(this.destroy$) + ).subscribe((type) => { + this.credentialsTypeChanged(type); + }); } ngOnInit(): void { @@ -121,12 +118,12 @@ export class DeviceCredentialsComponent implements ControlValueAccessor, OnInit, } ngOnDestroy() { - this.subscriptions.forEach(s => s.unsubscribe()); + this.destroy$.next(); + this.destroy$.complete(); } writeValue(value: DeviceCredentials | null): void { if (isDefinedAndNotNull(value)) { - this.deviceCredentials = value; let credentialsBasic = {clientId: null, userName: null, password: null}; let credentialsValue = null; if (value.credentialsType === DeviceCredentialsType.MQTT_BASIC) { @@ -179,10 +176,11 @@ export class DeviceCredentialsComponent implements ControlValueAccessor, OnInit, }; } - credentialsTypeChanged(): void { + credentialsTypeChanged(credentialsType: DeviceCredentialsType): void { + const credentialsValue = credentialsType === DeviceCredentialsType.LWM2M_CREDENTIALS ? this.lwm2mDefaultConfig : null; this.deviceCredentialsFormGroup.patchValue({ credentialsId: null, - credentialsValue: JSON.stringify(getDefaultSecurityConfig(), null, 2), + credentialsValue, credentialsBasic: {clientId: '', userName: '', password: ''} }); this.updateValidators(); @@ -264,7 +262,7 @@ export class DeviceCredentialsComponent implements ControlValueAccessor, OnInit, } } const credentialsId = this.deviceCredentialsFormGroup.get('credentialsId').value || DEFAULT_END_POINT; - this.dialog.open(SecurityConfigComponent, { + this.dialog.open(SecurityConfigLwm2mComponent, { disableClose: true, panelClass: ['tb-dialog', 'tb-fullscreen-dialog'], data: { @@ -275,8 +273,8 @@ export class DeviceCredentialsComponent implements ControlValueAccessor, OnInit, (res) => { if (res) { this.deviceCredentialsFormGroup.patchValue({ - credentialsValue: this.isDefautLw2mResponse(res[JSON_ALL_CONFIG]) ? null : JSON.stringify(res[JSON_ALL_CONFIG]), - credentialsId: this.isDefautLw2mResponse(res[END_POINT]) ? null : JSON.stringify(res[END_POINT]).split('\"').join('') + credentialsValue: this.isDefaultLw2mResponse(res[JSON_ALL_CONFIG]) ? null : JSON.stringify(res[JSON_ALL_CONFIG]), + credentialsId: this.isDefaultLw2mResponse(res[END_POINT]) ? null : JSON.stringify(res[END_POINT]).split('\"').join('') }); this.deviceCredentialsFormGroup.get('credentialsValue').markAsDirty(); } @@ -284,16 +282,19 @@ export class DeviceCredentialsComponent implements ControlValueAccessor, OnInit, ); } - private isDefautLw2mResponse(response: object): boolean { + private isDefaultLw2mResponse(response: object): boolean { return Object.keys(response).length === 0 || JSON.stringify(response) === '[{}]'; } private lwm2mConfigJsonValidator(control: FormControl) { - return validateSecurityConfig(control.value) ? null: {jsonError: {parsedJson: "error"}}; + return validateSecurityConfig(control.value) ? null : {jsonError: {parsedJson: 'error'}}; + } + + private get lwm2mDefaultConfig(): string { + return JSON.stringify(getDefaultSecurityConfig(), null, 2); } - lwm2mCredentialsValueTip (flag: boolean): string { - let jsonConfigDef = JSON.stringify(getDefaultSecurityConfig(), null, 2); - return !flag ? "" : 'Example (mode=\"NoSec\"):\n\r ' + jsonConfigDef; + lwm2mCredentialsValueTooltip(flag: boolean): string { + return !flag ? '' : 'Example (mode=\"NoSec\"):\n\r ' + this.lwm2mDefaultConfig; } } diff --git a/ui-ngx/src/app/modules/home/components/device/security-config-lwm2m-server.component.html b/ui-ngx/src/app/modules/home/components/device/security-config-lwm2m-server.component.html new file mode 100644 index 0000000000..a40ce4cb69 --- /dev/null +++ b/ui-ngx/src/app/modules/home/components/device/security-config-lwm2m-server.component.html @@ -0,0 +1,79 @@ + +
+ + device.lwm2m-security-config.mode + + + {{ lwm2mSecurityTypeTranslationMap.get(securityType) }} + + + +
+ + {{ 'device.lwm2m-security-config.client-publicKey-or-id' | translate }} + + {{clientPublicKeyOrId.value?.length || 0}}/{{lenMaxClientPublicKeyOrId}} + + {{ 'device.lwm2m-security-config.client-publicKey-or-id-required' | translate }} + + + {{ 'device.lwm2m-security-config.client-publicKey-or-id-pattern' | translate }} + + + {{ 'device.lwm2m-security-config.client-publicKey-or-id-length' | translate: { + count: lenMaxClientPublicKeyOrId + } }} + + + + {{ 'device.lwm2m-security-config.client-secret-key' | translate }} + + {{clientSecretKey.value?.length || 0}}/{{lengthClientSecretKey}} + + {{ 'device.lwm2m-security-config.client-secret-key-required' | translate }} + + + {{ 'device.lwm2m-security-config.client-secret-key-pattern' | translate }} + + + {{ 'device.lwm2m-security-config.client-secret-key-length' | translate: { + count: lengthClientSecretKey + } }} + + +
+
diff --git a/ui-ngx/src/app/modules/home/components/device/security-config-lwm2m-server.component.scss b/ui-ngx/src/app/modules/home/components/device/security-config-lwm2m-server.component.scss new file mode 100644 index 0000000000..1c55a86d8b --- /dev/null +++ b/ui-ngx/src/app/modules/home/components/device/security-config-lwm2m-server.component.scss @@ -0,0 +1,20 @@ +/** + * Copyright © 2016-2021 The Thingsboard Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +:host ::ng-deep { + textarea.mat-input-element.cdk-textarea-autosize { + box-sizing: content-box; + } +} diff --git a/ui-ngx/src/app/modules/home/components/device/security-config-lwm2m-server.component.ts b/ui-ngx/src/app/modules/home/components/device/security-config-lwm2m-server.component.ts new file mode 100644 index 0000000000..b8e1b42ef4 --- /dev/null +++ b/ui-ngx/src/app/modules/home/components/device/security-config-lwm2m-server.component.ts @@ -0,0 +1,176 @@ +/// +/// Copyright © 2016-2021 The Thingsboard Authors +/// +/// Licensed under the Apache License, Version 2.0 (the "License"); +/// you may not use this file except in compliance with the License. +/// You may obtain a copy of the License at +/// +/// http://www.apache.org/licenses/LICENSE-2.0 +/// +/// Unless required by applicable law or agreed to in writing, software +/// distributed under the License is distributed on an "AS IS" BASIS, +/// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +/// See the License for the specific language governing permissions and +/// limitations under the License. +/// + +import { Component, forwardRef, OnDestroy } from '@angular/core'; +import { + ControlValueAccessor, + FormBuilder, + FormGroup, + NG_VALIDATORS, + NG_VALUE_ACCESSOR, + ValidationErrors, + Validator, + Validators +} from '@angular/forms'; +import { + KEY_REGEXP_HEX_DEC, + LEN_MAX_PRIVATE_KEY, + LEN_MAX_PSK, + LEN_MAX_PUBLIC_KEY_RPK, + LEN_MAX_PUBLIC_KEY_X509, + Lwm2mSecurityType, + Lwm2mSecurityTypeTranslationMap, + ServerSecurityConfig +} from '@shared/models/lwm2m-security-config.models'; +import { takeUntil } from 'rxjs/operators'; +import { Subject } from 'rxjs'; + +@Component({ + selector: 'tb-security-config-lwm2m-server', + templateUrl: './security-config-lwm2m-server.component.html', + styleUrls: ['./security-config-lwm2m-server.component.scss'], + providers: [ + { + provide: NG_VALUE_ACCESSOR, + useExisting: forwardRef(() => SecurityConfigLwm2mServerComponent), + multi: true + }, + { + provide: NG_VALIDATORS, + useExisting: forwardRef(() => SecurityConfigLwm2mServerComponent), + multi: true + } + ] +}) + +export class SecurityConfigLwm2mServerComponent implements OnDestroy, ControlValueAccessor, Validator { + + serverFormGroup: FormGroup; + securityConfigLwM2MType = Lwm2mSecurityType; + securityConfigLwM2MTypes = Object.values(Lwm2mSecurityType); + lwm2mSecurityTypeTranslationMap = Lwm2mSecurityTypeTranslationMap; + lenMinClientPublicKeyOrId = 0; + lenMaxClientPublicKeyOrId = LEN_MAX_PUBLIC_KEY_RPK; + lengthClientSecretKey = LEN_MAX_PRIVATE_KEY; + + private destroy$ = new Subject(); + private propagateChange = (v: any) => {}; + + constructor(private fb: FormBuilder) { + this.serverFormGroup = this.fb.group({ + securityMode: [Lwm2mSecurityType.NO_SEC], + clientPublicKeyOrId: [''], + clientSecretKey: [''] + }); + this.serverFormGroup.get('securityMode').valueChanges.pipe( + takeUntil(this.destroy$) + ).subscribe((securityMode) => { + this.updateValidate(securityMode); + }); + + this.serverFormGroup.valueChanges.pipe( + takeUntil(this.destroy$) + ).subscribe((value) => { + this.propagateChange(value); + }); + } + + writeValue(value: any): void { + if (value) { + this.updateValueFields(value); + } + } + + registerOnChange(fn: any): void { + this.propagateChange = fn; + } + + registerOnTouched(fn: any): void { + } + + setDisabledState(isDisabled: boolean): void { + if (isDisabled) { + this.serverFormGroup.disable({emitEvent: false}); + } else { + this.serverFormGroup.enable({emitEvent: false}); + } + } + + validate(control): ValidationErrors | null { + return this.serverFormGroup.valid ? null : { + securityConfig: {valid: false} + }; + } + + ngOnDestroy() { + this.destroy$.next(); + this.destroy$.complete(); + } + + private updateValueFields(serverData: ServerSecurityConfig): void { + this.serverFormGroup.patchValue(serverData, {emitEvent: false}); + this.updateValidate(serverData.securityMode, true); + } + + private updateValidate(securityMode: Lwm2mSecurityType, initValue = false): void { + switch (securityMode) { + case Lwm2mSecurityType.NO_SEC: + this.serverFormGroup.get('clientPublicKeyOrId').clearValidators(); + this.serverFormGroup.get('clientSecretKey').clearValidators(); + break; + case Lwm2mSecurityType.PSK: + this.lenMinClientPublicKeyOrId = 0; + this.lenMaxClientPublicKeyOrId = LEN_MAX_PUBLIC_KEY_RPK; + this.lengthClientSecretKey = LEN_MAX_PSK; + this.setValidatorsSecurity(securityMode); + break; + case Lwm2mSecurityType.RPK: + this.lenMinClientPublicKeyOrId = LEN_MAX_PUBLIC_KEY_RPK; + this.lenMaxClientPublicKeyOrId = LEN_MAX_PUBLIC_KEY_RPK; + this.lengthClientSecretKey = LEN_MAX_PRIVATE_KEY; + this.setValidatorsSecurity(securityMode); + break; + case Lwm2mSecurityType.X509: + this.lenMinClientPublicKeyOrId = 0; + this.lenMaxClientPublicKeyOrId = LEN_MAX_PUBLIC_KEY_X509; + this.lengthClientSecretKey = LEN_MAX_PRIVATE_KEY; + this.setValidatorsSecurity(securityMode); + break; + } + this.serverFormGroup.get('clientPublicKeyOrId').updateValueAndValidity({emitEvent: false}); + this.serverFormGroup.get('clientSecretKey').updateValueAndValidity({emitEvent: !initValue}); + } + + private setValidatorsSecurity = (securityMode: Lwm2mSecurityType): void => { + if (securityMode === Lwm2mSecurityType.PSK) { + this.serverFormGroup.get('clientPublicKeyOrId').setValidators([Validators.required]); + } else { + this.serverFormGroup.get('clientPublicKeyOrId').setValidators([ + Validators.required, + Validators.pattern(KEY_REGEXP_HEX_DEC), + Validators.minLength(this.lenMinClientPublicKeyOrId), + Validators.maxLength(this.lenMaxClientPublicKeyOrId) + ]); + } + + this.serverFormGroup.get('clientSecretKey').setValidators([ + Validators.required, + Validators.pattern(KEY_REGEXP_HEX_DEC), + Validators.minLength(this.lengthClientSecretKey), + Validators.maxLength(this.lengthClientSecretKey) + ]); + } +} diff --git a/ui-ngx/src/app/modules/home/components/device/security-config-lwm2m.component.html b/ui-ngx/src/app/modules/home/components/device/security-config-lwm2m.component.html new file mode 100644 index 0000000000..bd83cc817b --- /dev/null +++ b/ui-ngx/src/app/modules/home/components/device/security-config-lwm2m.component.html @@ -0,0 +1,143 @@ + +
+ +

{{ title }}

+ + +
+
+ + device.lwm2m-security-config.endpoint + + + {{ 'device.lwm2m-security-config.endpoint-required' | translate }} + + + + + + device.lwm2m-security-config.mode + + + {{ credentialTypeLwM2MNamesMap.get(securityConfigLwM2MType[securityConfigClientMode]) }} + + + +
+ + {{ 'device.lwm2m-security-config.identity' | translate }} + + + {{ 'device.lwm2m-security-config.identity-required' | translate }} + + +
+ + {{ 'device.lwm2m-security-config.client-key' | translate }} + + {{key.value?.length || 0}}/{{lenMaxKeyClient}} + + {{ 'device.lwm2m-security-config.client-key-required' | translate }} + + + {{ 'device.lwm2m-security-config.client-key-pattern' | translate }} + + + {{ 'device.lwm2m-security-config.client-key-length' | translate: { + count: lenMaxKeyClient + } }} + + + + {{ 'device.lwm2m-security-config.client-certificate' | translate }} + +
+ +
+ + + + + {{ 'device.lwm2m-security-config.bootstrap-server' | translate }} + + + + + + + + + + + {{ 'device.lwm2m-security-config.lwm2m-server' | translate }} + + + + + + + + +
+
+ + + + + + +
+
+
+ + +
+
diff --git a/ui-ngx/src/app/modules/home/components/device/security-config-lwm2m.component.scss b/ui-ngx/src/app/modules/home/components/device/security-config-lwm2m.component.scss new file mode 100644 index 0000000000..0188fcd559 --- /dev/null +++ b/ui-ngx/src/app/modules/home/components/device/security-config-lwm2m.component.scss @@ -0,0 +1,34 @@ +/** + * Copyright © 2016-2021 The Thingsboard Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +:host { + mat-tab-group { + min-height: 330px; + } +} + +:host ::ng-deep { + .mat-tab-body-wrapper { + min-height: 200px; + } + + .mat-tab-body { + padding: 16px 0; + } + + textarea.mat-input-element.cdk-textarea-autosize { + box-sizing: content-box; + } +} diff --git a/ui-ngx/src/app/modules/home/components/device/security-config-lwm2m.component.ts b/ui-ngx/src/app/modules/home/components/device/security-config-lwm2m.component.ts new file mode 100644 index 0000000000..419576753c --- /dev/null +++ b/ui-ngx/src/app/modules/home/components/device/security-config-lwm2m.component.ts @@ -0,0 +1,257 @@ +/// +/// Copyright © 2016-2021 The Thingsboard Authors +/// +/// Licensed under the Apache License, Version 2.0 (the "License"); +/// you may not use this file except in compliance with the License. +/// You may obtain a copy of the License at +/// +/// http://www.apache.org/licenses/LICENSE-2.0 +/// +/// Unless required by applicable law or agreed to in writing, software +/// distributed under the License is distributed on an "AS IS" BASIS, +/// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +/// See the License for the specific language governing permissions and +/// limitations under the License. +/// + + +import { Component, Inject, OnDestroy, OnInit } from '@angular/core'; +import { DialogComponent } from '@shared/components/dialog.component'; +import { Store } from '@ngrx/store'; +import { AppState } from '@core/core.state'; +import { Router } from '@angular/router'; +import { MAT_DIALOG_DATA, MatDialogRef } from '@angular/material/dialog'; +import { FormBuilder, FormGroup, Validators } from '@angular/forms'; +import { TranslateService } from '@ngx-translate/core'; +import { + DeviceCredentialsDialogLwm2mData, + getClientSecurityConfig, + JSON_ALL_CONFIG, + KEY_REGEXP_HEX_DEC, + LEN_MAX_PSK, + LEN_MAX_PUBLIC_KEY_RPK, + Lwm2mSecurityConfigModels, + Lwm2mSecurityType, + Lwm2mSecurityTypeTranslationMap +} from '@shared/models/lwm2m-security-config.models'; +import { MatTabChangeEvent } from '@angular/material/tabs'; +import { MatTab } from '@angular/material/tabs/tab'; +import { Subject } from 'rxjs'; +import { takeUntil } from 'rxjs/operators'; + +@Component({ + selector: 'tb-security-config-lwm2m', + templateUrl: './security-config-lwm2m.component.html', + styleUrls: ['./security-config-lwm2m.component.scss'] +}) + +export class SecurityConfigLwm2mComponent extends DialogComponent implements OnInit, OnDestroy { + + private destroy$ = new Subject(); + + lwm2mConfigFormGroup: FormGroup; + title: string; + securityConfigLwM2MType = Lwm2mSecurityType; + securityConfigLwM2MTypes = Object.keys(Lwm2mSecurityType); + credentialTypeLwM2MNamesMap = Lwm2mSecurityTypeTranslationMap; + formControlNameJsonAllConfig = JSON_ALL_CONFIG; + jsonAllConfig: Lwm2mSecurityConfigModels; + lenMaxKeyClient = LEN_MAX_PSK; + tabPrevious: MatTab; + tabIndexPrevious = 0; + + constructor(protected store: Store, + protected router: Router, + @Inject(MAT_DIALOG_DATA) public data: DeviceCredentialsDialogLwm2mData, + public dialogRef: MatDialogRef, + public fb: FormBuilder, + public translate: TranslateService) { + super(store, router, dialogRef); + } + + ngOnInit() { + this.jsonAllConfig = JSON.parse(JSON.stringify(this.data.jsonAllConfig)); + this.lwm2mConfigFormGroup = this.initLwm2mConfigFormGroup(); + this.title = this.translate.instant('device.lwm2m-security-info') + ': ' + this.data.endPoint; + this.lwm2mConfigFormGroup.get('x509').disable(); + this.initClientSecurityConfig(this.lwm2mConfigFormGroup.get('jsonAllConfig').value); + this.registerDisableOnLoadFormControl(this.lwm2mConfigFormGroup.get('securityConfigClientMode')); + } + + ngOnDestroy() { + this.destroy$.next(); + this.destroy$.complete(); + } + + private initClientSecurityConfig = (jsonAllConfig: Lwm2mSecurityConfigModels): void => { + if (jsonAllConfig.client.securityConfigClientMode !== Lwm2mSecurityType.NO_SEC) { + this.lwm2mConfigFormGroup.patchValue(jsonAllConfig.client, {emitEvent: false}); + } + this.securityConfigClientUpdateValidators(jsonAllConfig.client.securityConfigClientMode); + } + + private securityConfigClientModeChanged(type: Lwm2mSecurityType): void { + const config = getClientSecurityConfig(type, this.lwm2mConfigFormGroup.get('endPoint').value); + switch (type) { + case Lwm2mSecurityType.PSK: + config.identity = this.data.endPoint; + config.key = this.lwm2mConfigFormGroup.get('key').value; + break; + case Lwm2mSecurityType.RPK: + config.key = this.lwm2mConfigFormGroup.get('key').value; + break; + } + this.jsonAllConfig.client = config; + this.lwm2mConfigFormGroup.patchValue({ + ...config, + jsonAllConfig: this.jsonAllConfig + }, {emitEvent: false}); + this.securityConfigClientUpdateValidators(type); + } + + private securityConfigClientUpdateValidators = (mode: Lwm2mSecurityType): void => { + switch (mode) { + case Lwm2mSecurityType.NO_SEC: + case Lwm2mSecurityType.X509: + this.setValidatorsNoSecX509(); + break; + case Lwm2mSecurityType.PSK: + this.lenMaxKeyClient = LEN_MAX_PSK; + this.setValidatorsPskRpk(mode); + break; + case Lwm2mSecurityType.RPK: + this.lenMaxKeyClient = LEN_MAX_PUBLIC_KEY_RPK; + this.setValidatorsPskRpk(mode); + break; + } + this.lwm2mConfigFormGroup.get('identity').updateValueAndValidity({emitEvent: false}); + this.lwm2mConfigFormGroup.get('key').updateValueAndValidity({emitEvent: false}); + } + + private setValidatorsNoSecX509 = (): void => { + this.lwm2mConfigFormGroup.get('identity').setValidators([]); + this.lwm2mConfigFormGroup.get('key').setValidators([]); + } + + private setValidatorsPskRpk = (mode: Lwm2mSecurityType): void => { + if (mode === Lwm2mSecurityType.PSK) { + this.lwm2mConfigFormGroup.get('identity').setValidators([Validators.required]); + } else { + this.lwm2mConfigFormGroup.get('identity').setValidators([]); + } + this.lwm2mConfigFormGroup.get('key').setValidators([Validators.required, + Validators.pattern(KEY_REGEXP_HEX_DEC), + Validators.maxLength(this.lenMaxKeyClient), Validators.minLength(this.lenMaxKeyClient)]); + } + + tabChanged = (tabChangeEvent: MatTabChangeEvent): void => { + if (this.tabIndexPrevious !== tabChangeEvent.index) { + this.upDateValueToJson(); + } + this.tabIndexPrevious = tabChangeEvent.index; + } + + private upDateValueToJson(): void { + switch (this.tabIndexPrevious) { + case 0: + this.upDateValueToJsonTab0(); + break; + case 1: + this.upDateValueToJsonTab1(); + break; + } + } + + private upDateValueToJsonTab0 = (): void => { + if (this.lwm2mConfigFormGroup.get('identity').dirty && this.lwm2mConfigFormGroup.get('identity').valid || + this.lwm2mConfigFormGroup.get('key').dirty && this.lwm2mConfigFormGroup.get('key').valid) { + this.updateBootstrapSettings(); + this.upDateJsonAllConfig(); + } + } + + private upDateValueToJsonTab1 = (): void => { + const bootstrap = this.lwm2mConfigFormGroup.get('bootstrapServer').value; + if (bootstrap !== null + && this.lwm2mConfigFormGroup.get('bootstrapServer').dirty + && this.lwm2mConfigFormGroup.get('bootstrapServer').valid) { + this.jsonAllConfig.bootstrap.bootstrapServer = bootstrap; + this.upDateJsonAllConfig(); + } + const serverConfig = this.lwm2mConfigFormGroup.get('lwm2mServer').value; + if (serverConfig !== null + && this.lwm2mConfigFormGroup.get('lwm2mServer').dirty + && this.lwm2mConfigFormGroup.get('lwm2mServer').valid) { + this.jsonAllConfig.bootstrap.lwm2mServer = serverConfig; + this.upDateJsonAllConfig(); + } + } + + private updateBootstrapSettings() { + const securityMode = 'securityMode'; + this.jsonAllConfig.client.identity = this.lwm2mConfigFormGroup.get('identity').value; + this.jsonAllConfig.client.key = this.lwm2mConfigFormGroup.get('key').value; + if (this.lwm2mConfigFormGroup.get('bootstrapServer').value[securityMode] === Lwm2mSecurityType.PSK) { + this.jsonAllConfig.bootstrap.bootstrapServer.clientPublicKeyOrId = this.jsonAllConfig.client.identity; + this.jsonAllConfig.bootstrap.bootstrapServer.clientSecretKey = this.jsonAllConfig.client.key; + this.lwm2mConfigFormGroup.get('bootstrapServer').patchValue(this.jsonAllConfig.bootstrap.bootstrapServer, {emitEvent: false}); + } + if (this.lwm2mConfigFormGroup.get('lwm2mServer').value[securityMode] === Lwm2mSecurityType.PSK) { + this.jsonAllConfig.bootstrap.lwm2mServer.clientPublicKeyOrId = this.jsonAllConfig.client.identity; + this.jsonAllConfig.bootstrap.lwm2mServer.clientSecretKey = this.jsonAllConfig.client.key; + this.lwm2mConfigFormGroup.get('lwm2mServer').patchValue(this.jsonAllConfig.bootstrap.lwm2mServer, {emitEvent: false}); + } + } + + private upDateJsonAllConfig = (): void => { + this.lwm2mConfigFormGroup.patchValue({ + jsonAllConfig: this.jsonAllConfig + }, {emitEvent: false}); + } + + private initLwm2mConfigFormGroup = (): FormGroup => { + if (this.jsonAllConfig.client.securityConfigClientMode === Lwm2mSecurityType.PSK) { + this.data.endPoint = this.jsonAllConfig.client.endpoint; + } + const formGroup = this.fb.group({ + securityConfigClientMode: [this.jsonAllConfig.client.securityConfigClientMode], + identity: [''], + key: [''], + x509: [false], + bootstrapServer: [this.jsonAllConfig.bootstrap.bootstrapServer], + lwm2mServer: [this.jsonAllConfig.bootstrap.lwm2mServer], + endPoint: [this.data.endPoint], + jsonAllConfig: [this.jsonAllConfig] + }); + formGroup.get('securityConfigClientMode').valueChanges.pipe( + takeUntil(this.destroy$) + ).subscribe((type) => { + this.securityConfigClientModeChanged(type); + }); + formGroup.get('endPoint').valueChanges.pipe( + takeUntil(this.destroy$) + ).subscribe((endpoint) => { + if (formGroup.get('securityConfigClientMode').value === Lwm2mSecurityType.PSK) { + this.jsonAllConfig.client.endpoint = endpoint; + this.upDateJsonAllConfig(); + } + }); + return formGroup; + } + + save(): void { + this.upDateValueToJson(); + this.data.endPoint = this.lwm2mConfigFormGroup.get('endPoint').value.split('\'').join(''); + this.data.jsonAllConfig = this.jsonAllConfig; + if (this.lwm2mConfigFormGroup.get('securityConfigClientMode').value === Lwm2mSecurityType.PSK) { + this.data.endPoint = this.data.jsonAllConfig.client.identity; + } + this.dialogRef.close(this.data); + } + + cancel(): void { + this.dialogRef.close(undefined); + } +} + + diff --git a/ui-ngx/src/app/modules/home/components/home-components.module.ts b/ui-ngx/src/app/modules/home/components/home-components.module.ts index f2208757d4..a5a3ed460b 100644 --- a/ui-ngx/src/app/modules/home/components/home-components.module.ts +++ b/ui-ngx/src/app/modules/home/components/home-components.module.ts @@ -138,6 +138,8 @@ import { EMBED_DASHBOARD_DIALOG_TOKEN } from '@home/components/widget/dialog/emb import { EdgeDownlinkTableComponent } from '@home/components/edge/edge-downlink-table.component'; import { EdgeDownlinkTableHeaderComponent } from '@home/components/edge/edge-downlink-table-header.component'; import { DisplayWidgetTypesPanelComponent } from '@home/components/dashboard-page/widget-types-panel.component'; +import { SecurityConfigLwm2mComponent } from '@home/components/device/security-config-lwm2m.component'; +import { SecurityConfigLwm2mServerComponent } from '@home/components/device/security-config-lwm2m-server.component'; @NgModule({ declarations: @@ -239,6 +241,8 @@ import { DisplayWidgetTypesPanelComponent } from '@home/components/dashboard-pag DeviceWizardDialogComponent, DeviceCredentialsComponent, CopyDeviceCredentialsComponent, + SecurityConfigLwm2mComponent, + SecurityConfigLwm2mServerComponent, AlarmScheduleDialogComponent, EditAlarmDetailsDialogComponent, SmsProviderConfigurationComponent, @@ -342,6 +346,8 @@ import { DisplayWidgetTypesPanelComponent } from '@home/components/dashboard-pag DeviceWizardDialogComponent, DeviceCredentialsComponent, CopyDeviceCredentialsComponent, + SecurityConfigLwm2mComponent, + SecurityConfigLwm2mServerComponent, AlarmScheduleInfoComponent, AlarmScheduleComponent, AlarmScheduleDialogComponent, diff --git a/ui-ngx/src/app/modules/home/components/profile/device/lwm2m/lwm2m-attributes-dialog.component.ts b/ui-ngx/src/app/modules/home/components/profile/device/lwm2m/lwm2m-attributes-dialog.component.ts index 834be7535c..c1877e218e 100644 --- a/ui-ngx/src/app/modules/home/components/profile/device/lwm2m/lwm2m-attributes-dialog.component.ts +++ b/ui-ngx/src/app/modules/home/components/profile/device/lwm2m/lwm2m-attributes-dialog.component.ts @@ -14,21 +14,20 @@ /// limitations under the License. /// -import {Component, Inject, OnInit, SkipSelf} from "@angular/core"; -import {ErrorStateMatcher} from "@angular/material/core"; -import {DialogComponent} from "@shared/components/dialog.component"; -import {Store} from "@ngrx/store"; -import {AppState} from "@core/core.state"; -import {Router} from "@angular/router"; -import {MAT_DIALOG_DATA, MatDialogRef} from "@angular/material/dialog"; -import {FormBuilder, FormControl, FormGroup, FormGroupDirective, NgForm} from "@angular/forms"; -import {TranslateService} from "@ngx-translate/core"; -import {JsonObject} from "@angular/compiler-cli/ngcc/src/packages/entry_point"; +import { Component, Inject, OnInit, SkipSelf } from '@angular/core'; +import { ErrorStateMatcher } from '@angular/material/core'; +import { DialogComponent } from '@shared/components/dialog.component'; +import { Store } from '@ngrx/store'; +import { AppState } from '@core/core.state'; +import { Router } from '@angular/router'; +import { MAT_DIALOG_DATA, MatDialogRef } from '@angular/material/dialog'; +import { FormBuilder, FormControl, FormGroup, FormGroupDirective, NgForm } from '@angular/forms'; +import { JsonObject } from '@angular/compiler-cli/ngcc/src/packages/entry_point'; export interface Lwm2mAttributesDialogData { readonly: boolean; attributeLwm2m: JsonObject; - destName: string + destName: string; } @Component({ @@ -37,7 +36,8 @@ export interface Lwm2mAttributesDialogData { styleUrls: ['./lwm2m-attributes.component.scss'], providers: [{provide: ErrorStateMatcher, useExisting: Lwm2mAttributesDialogComponent}], }) -export class Lwm2mAttributesDialogComponent extends DialogComponent implements OnInit, ErrorStateMatcher { +export class Lwm2mAttributesDialogComponent extends DialogComponent + implements OnInit, ErrorStateMatcher { readonly = this.data.readonly; @@ -54,8 +54,7 @@ export class Lwm2mAttributesDialogComponent extends DialogComponent, - private fb: FormBuilder, - public translate: TranslateService) { + private fb: FormBuilder) { super(store, router, dialogRef); this.attributeLwm2mDialogFormGroup = this.fb.group({ diff --git a/ui-ngx/src/app/modules/home/components/profile/device/lwm2m/lwm2m-attributes-key-list.component.ts b/ui-ngx/src/app/modules/home/components/profile/device/lwm2m/lwm2m-attributes-key-list.component.ts index 7d7af196f0..686382e9bd 100644 --- a/ui-ngx/src/app/modules/home/components/profile/device/lwm2m/lwm2m-attributes-key-list.component.ts +++ b/ui-ngx/src/app/modules/home/components/profile/device/lwm2m/lwm2m-attributes-key-list.component.ts @@ -14,7 +14,7 @@ /// limitations under the License. /// -import {Component, forwardRef, Input, OnInit} from "@angular/core"; +import { Component, forwardRef, Input, OnInit } from '@angular/core'; import { AbstractControl, ControlValueAccessor, @@ -26,17 +26,17 @@ import { NG_VALUE_ACCESSOR, Validator, Validators -} from "@angular/forms"; -import {Subscription} from "rxjs"; -import {PageComponent} from "@shared/components/page.component"; -import {Store} from "@ngrx/store"; -import {AppState} from "@core/core.state"; +} from '@angular/forms'; +import { Subscription } from 'rxjs'; import { ATTRIBUTE_KEYS, ATTRIBUTE_LWM2M_ENUM, ATTRIBUTE_LWM2M_MAP -} from "@home/components/profile/device/lwm2m/lwm2m-profile-config.models"; -import {isDefinedAndNotNull, isEmpty, isEmptyStr, isUndefinedOrNull} from "@core/utils"; +} from './lwm2m-profile-config.models'; +import { isDefinedAndNotNull, isEmpty, isEmptyStr, isUndefinedOrNull } from '@core/utils'; +import { Store } from '@ngrx/store'; +import { AppState } from '@core/core.state'; +import { PageComponent } from '@shared/components/page.component'; @Component({ @@ -98,7 +98,7 @@ export class Lwm2mAttributesKeyListComponent extends PageComponent implements Co registerOnTouched(fn: any): void { } - setDisabledState?(isDisabled: boolean): void { + setDisabledState(isDisabled: boolean): void { this.disabled = isDisabled; if (this.disabled) { this.kvListFormGroup.disable({emitEvent: false}); @@ -166,10 +166,10 @@ export class Lwm2mAttributesKeyListComponent extends PageComponent implements Co }; } - private updateValidate (c?: FormControl) { + private updateValidate() { const kvList = this.kvListFormGroup.get('keyVals') as FormArray; kvList.controls.forEach(fg => { - if (fg.get('key').value==='ver') { + if (fg.get('key').value === 'ver') { fg.get('value').setValidators(null); fg.get('value').setErrors(null); } @@ -189,7 +189,7 @@ export class Lwm2mAttributesKeyListComponent extends PageComponent implements Co if (isUndefinedOrNull(entry.value) || entry.key === 'ver' || isEmptyStr(entry.value.toString())) { keyValMap[entry.key] = entry.value.toString(); } else { - keyValMap[entry.key] = Number(entry.value) + keyValMap[entry.key] = Number(entry.value); } }); this.propagateChange(keyValMap); @@ -215,13 +215,13 @@ export class Lwm2mAttributesKeyListComponent extends PageComponent implements Co private attributeLwm2mValueNumberValidator = (control: AbstractControl) => { if (isNaN(Number(control.value)) || Number(control.value) < 0) { return { - 'validAttributeValue': true + validAttributeValue: true }; } return null; } - private attributeLwm2mValueValidator = (property: string): Object [] => { - return property === 'ver'? [] : [this.attributeLwm2mValueNumberValidator]; + private attributeLwm2mValueValidator = (property: string): object[] => { + return property === 'ver' ? [] : [this.attributeLwm2mValueNumberValidator]; } } diff --git a/ui-ngx/src/app/modules/home/components/profile/device/lwm2m/lwm2m-attributes.component.ts b/ui-ngx/src/app/modules/home/components/profile/device/lwm2m/lwm2m-attributes.component.ts index ca4b66ae36..1e467bcd93 100644 --- a/ui-ngx/src/app/modules/home/components/profile/device/lwm2m/lwm2m-attributes.component.ts +++ b/ui-ngx/src/app/modules/home/components/profile/device/lwm2m/lwm2m-attributes.component.ts @@ -14,21 +14,14 @@ /// limitations under the License. /// -import {Component, EventEmitter, forwardRef, Inject, Input, Output} from "@angular/core"; -import {ControlValueAccessor, FormBuilder, FormGroup, NG_VALUE_ACCESSOR} from "@angular/forms"; -import {coerceBooleanProperty} from "@angular/cdk/coercion"; -import {Store} from "@ngrx/store"; -import {AppState} from "@core/core.state"; -import {DeviceProfileService} from "@core/http/device-profile.service"; -import {WINDOW} from "@core/services/window.service"; -import {deepClone, isDefinedAndNotNull, isEmpty} from "@core/utils"; -import { - Lwm2mAttributesDialogComponent, - Lwm2mAttributesDialogData -} from "@home/components/profile/device/lwm2m/lwm2m-attributes-dialog.component"; -import {MatDialog} from "@angular/material/dialog"; -import {TranslateService} from "@ngx-translate/core"; -import {ATTRIBUTE_LWM2M_LABEL} from "@home/components/profile/device/lwm2m/lwm2m-profile-config.models"; +import { Component, EventEmitter, forwardRef, Input, Output } from '@angular/core'; +import { ControlValueAccessor, FormBuilder, FormGroup, NG_VALUE_ACCESSOR } from '@angular/forms'; +import { coerceBooleanProperty } from '@angular/cdk/coercion'; +import { deepClone, isDefinedAndNotNull, isEmpty } from '@core/utils'; +import { Lwm2mAttributesDialogComponent, Lwm2mAttributesDialogData } from './lwm2m-attributes-dialog.component'; +import { MatDialog } from '@angular/material/dialog'; +import { TranslateService } from '@ngx-translate/core'; +import { ATTRIBUTE_LWM2M_LABEL } from './lwm2m-profile-config.models'; @Component({ @@ -46,7 +39,6 @@ export class Lwm2mAttributesComponent implements ControlValueAccessor { attributeLwm2mLabel = ATTRIBUTE_LWM2M_LABEL; private requiredValue: boolean; - private dirty = false; @Input() attributeLwm2m: {}; @@ -71,12 +63,9 @@ export class Lwm2mAttributesComponent implements ControlValueAccessor { private propagateChange = (v: any) => { } - constructor(private store: Store, - private dialog: MatDialog, + constructor(private dialog: MatDialog, private fb: FormBuilder, - private deviceProfileService: DeviceProfileService, - private translate: TranslateService, - @Inject(WINDOW) private window: Window) {} + private translate: TranslateService) {} registerOnChange(fn: any): void { this.propagateChange = fn; @@ -117,20 +106,20 @@ export class Lwm2mAttributesComponent implements ControlValueAccessor { return label; } - isDisableBtn (): boolean { + isDisableBtn(): boolean { return this.disabled || this.isAttributeTelemetry ? !(isDefinedAndNotNull(this.attributeLwm2m) && !isEmpty(this.attributeLwm2m) && this.disabled) : this.disabled; } - isIconView (): boolean { + isIconView(): boolean { return this.isAttributeTelemetry || this.disabled; } - isIconEditAdd (): boolean { + isIconEditAdd(): boolean { return isDefinedAndNotNull(this.attributeLwm2m) && !isEmpty(this.attributeLwm2m); } - isToolTipLabel (): string { + isToolTipLabel(): string { return this.disabled ? this.translate.instant('device-profile.lwm2m.attribute-lwm2m-tip') : this.isAttributeTelemetry ? this.translate.instant('device-profile.lwm2m.attribute-lwm2m-disable-tip') : this.translate.instant('device-profile.lwm2m.attribute-lwm2m-tip'); @@ -140,7 +129,7 @@ export class Lwm2mAttributesComponent implements ControlValueAccessor { if ($event) { $event.stopPropagation(); } - this.dialog.open(Lwm2mAttributesDialogComponent, { + this.dialog.open(Lwm2mAttributesDialogComponent, { disableClose: true, panelClass: ['tb-dialog', 'tb-fullscreen-dialog'], data: { diff --git a/ui-ngx/src/app/modules/home/components/profile/device/lwm2m/lwm2m-device-config-server.component.ts b/ui-ngx/src/app/modules/home/components/profile/device/lwm2m/lwm2m-device-config-server.component.ts index b82da4bc06..55f8db8f84 100644 --- a/ui-ngx/src/app/modules/home/components/profile/device/lwm2m/lwm2m-device-config-server.component.ts +++ b/ui-ngx/src/app/modules/home/components/profile/device/lwm2m/lwm2m-device-config-server.component.ts @@ -14,8 +14,8 @@ /// limitations under the License. /// -import {Component, forwardRef, Inject, Input} from '@angular/core'; -import {ControlValueAccessor, FormBuilder, FormGroup, NG_VALUE_ACCESSOR, Validators} from '@angular/forms'; +import { Component, forwardRef, Inject, Input } from '@angular/core'; +import { ControlValueAccessor, FormBuilder, FormGroup, NG_VALUE_ACCESSOR, Validators } from '@angular/forms'; import { DEFAULT_CLIENT_HOLD_OFF_TIME, DEFAULT_ID_SERVER, @@ -28,13 +28,12 @@ import { SECURITY_CONFIG_MODE_NAMES, ServerSecurityConfig } from './lwm2m-profile-config.models'; -import {Store} from '@ngrx/store'; -import {AppState} from '@core/core.state'; -import {coerceBooleanProperty} from '@angular/cdk/coercion'; -import {WINDOW} from '@core/services/window.service'; -import {pairwise, startWith} from 'rxjs/operators'; -import {DeviceProfileService} from '@core/http/device-profile.service'; +import { coerceBooleanProperty } from '@angular/cdk/coercion'; +import { WINDOW } from '@core/services/window.service'; +import { pairwise, startWith } from 'rxjs/operators'; +import { DeviceProfileService } from '@core/http/device-profile.service'; +// @dynamic @Component({ selector: 'tb-profile-lwm2m-device-config-server', templateUrl: './lwm2m-device-config-server.component.html', @@ -73,8 +72,7 @@ export class Lwm2mDeviceConfigServerComponent implements ControlValueAccessor { this.requiredValue = coerceBooleanProperty(value); } - constructor(protected store: Store, - public fb: FormBuilder, + constructor(public fb: FormBuilder, private deviceProfileService: DeviceProfileService, @Inject(WINDOW) private window: Window) { this.serverFormGroup = this.initServerGroup(); diff --git a/ui-ngx/src/app/modules/home/components/profile/device/lwm2m/lwm2m-device-profile-transport-configuration.component.ts b/ui-ngx/src/app/modules/home/components/profile/device/lwm2m/lwm2m-device-profile-transport-configuration.component.ts index d6f6823db6..60fb27a752 100644 --- a/ui-ngx/src/app/modules/home/components/profile/device/lwm2m/lwm2m-device-profile-transport-configuration.component.ts +++ b/ui-ngx/src/app/modules/home/components/profile/device/lwm2m/lwm2m-device-profile-transport-configuration.component.ts @@ -15,10 +15,8 @@ /// import { DeviceProfileTransportConfiguration } from '@shared/models/device.models'; -import { Component, forwardRef, Inject, Input } from '@angular/core'; +import { Component, forwardRef, Input } from '@angular/core'; import { ControlValueAccessor, FormBuilder, FormGroup, NG_VALUE_ACCESSOR, Validators } from '@angular/forms'; -import { Store } from '@ngrx/store'; -import { AppState } from '@app/core/core.state'; import { coerceBooleanProperty } from '@angular/cdk/coercion'; import { ATTRIBUTE, @@ -37,7 +35,6 @@ import { } from './lwm2m-profile-config.models'; import { DeviceProfileService } from '@core/http/device-profile.service'; import { deepClone, isDefinedAndNotNull, isEmpty, isUndefined } from '@core/utils'; -import { WINDOW } from '@core/services/window.service'; import { JsonArray, JsonObject } from '@angular/compiler-cli/ngcc/src/packages/entry_point'; import { Direction } from '@shared/models/page/sort-order'; @@ -78,10 +75,8 @@ export class Lwm2mDeviceProfileTransportConfigurationComponent implements Contro private propagateChange = (v: any) => { } - constructor(private store: Store, - private fb: FormBuilder, - private deviceProfileService: DeviceProfileService, - @Inject(WINDOW) private window: Window) { + constructor(private fb: FormBuilder, + private deviceProfileService: DeviceProfileService) { this.lwm2mDeviceProfileFormGroup = this.fb.group({ clientOnlyObserveAfterConnect: [1, []], objectIds: [null, Validators.required], @@ -155,7 +150,7 @@ export class Lwm2mDeviceProfileTransportConfigurationComponent implements Contro this.lwm2mDeviceProfileFormGroup.patchValue({ clientOnlyObserveAfterConnect: this.configurationValue.clientLwM2mSettings.clientOnlyObserveAfterConnect, objectIds: value, - observeAttrTelemetry: this.getObserveAttrTelemetryObjects(value['objectsList']), + observeAttrTelemetry: this.getObserveAttrTelemetryObjects(value.objectsList), shortId: this.configurationValue.bootstrap.servers.shortId, lifetime: this.configurationValue.bootstrap.servers.lifetime, defaultMinPeriod: this.configurationValue.bootstrap.servers.defaultMinPeriod, @@ -171,7 +166,6 @@ export class Lwm2mDeviceProfileTransportConfigurationComponent implements Contro let configuration: DeviceProfileTransportConfiguration = null; if (this.lwm2mDeviceConfigFormGroup.valid && this.lwm2mDeviceProfileFormGroup.valid) { configuration = this.lwm2mDeviceConfigFormGroup.value.configurationJson; - // configuration.type = DeviceTransportType.LWM2M; } this.propagateChange(configuration); } @@ -206,7 +200,7 @@ export class Lwm2mDeviceProfileTransportConfigurationComponent implements Contro if (this.configurationValue.observeAttr && objectLwM2MS.length > 0) { const attributeArray = this.configurationValue.observeAttr.attribute; const telemetryArray = this.configurationValue.observeAttr.telemetry; - let keyNameJson = this.configurationValue.observeAttr.keyName; + const keyNameJson = this.configurationValue.observeAttr.keyName; if (this.includesNotZeroInstance(attributeArray, telemetryArray)) { this.addInstances(attributeArray, telemetryArray, objectLwM2MS); } @@ -270,9 +264,9 @@ export class Lwm2mDeviceProfileTransportConfigurationComponent implements Contro private updateAttributeLwm2m = (objectLwM2MS: ObjectLwM2M[]): void => { Object.keys(this.configurationValue.observeAttr.attributeLwm2m).forEach(key => { const [objectKeyId, instanceId, resourceId] = Array.from(key.substring(1).split('/'), String); - let objectLwM2M = objectLwM2MS.find(objectLwm2m => objectLwm2m.keyId === objectKeyId); + const objectLwM2M = objectLwM2MS.find(objectLwm2m => objectLwm2m.keyId === objectKeyId); if (objectLwM2M && instanceId) { - let instance = objectLwM2M.instances.find(instance => instance.id === +instanceId) + const instance = objectLwM2M.instances.find(obj => obj.id === +instanceId); if (instance && resourceId) { instance.resources.find(resource => resource.id === +resourceId) .attributeLwm2m = this.configurationValue.observeAttr.attributeLwm2m[key]; @@ -288,7 +282,7 @@ export class Lwm2mDeviceProfileTransportConfigurationComponent implements Contro private updateKeyNameObjects = (objectLwM2MS: ObjectLwM2M[]): void => { Object.keys(this.configurationValue.observeAttr.keyName).forEach(key => { const [objectKeyId, instanceId, resourceId] = Array.from(key.substring(1).split('/'), String); - const objectLwM2M = objectLwM2MS.find(objectLwm2m => objectLwm2m.keyId === objectKeyId) + const objectLwM2M = objectLwM2MS.find(objectLwm2m => objectLwm2m.keyId === objectKeyId); if (objectLwM2M) { objectLwM2M.instances.find(instance => instance.id === +instanceId) .resources.find(resource => resource.id === +resourceId) @@ -299,7 +293,7 @@ export class Lwm2mDeviceProfileTransportConfigurationComponent implements Contro private validateKeyNameObjects = (nameJson: JsonObject, attributeArray: JsonArray, telemetryArray: JsonArray): {} => { const keyName = JSON.parse(JSON.stringify(nameJson)); - let keyNameValidate = {}; + const keyNameValidate = {}; const keyAttrTelemetry = attributeArray.concat(telemetryArray); Object.keys(keyName).forEach(key => { if (keyAttrTelemetry.includes(key)) { @@ -345,9 +339,9 @@ export class Lwm2mDeviceProfileTransportConfigurationComponent implements Contro attributeLwm2m[pathRes] = resource.attributeLwm2m; } } - }) + }); } - }) + }); } }); if (isUndefined(this.configurationValue.observeAttr)) { @@ -356,7 +350,7 @@ export class Lwm2mDeviceProfileTransportConfigurationComponent implements Contro attribute: attributeArray, telemetry: telemetryArray, keyName: this.sortObjectKeyPathJson(KEY_NAME, keyNameNew), - attributeLwm2m: attributeLwm2m + attributeLwm2m }; } else { this.configurationValue.observeAttr.observe = observeArray; @@ -457,7 +451,6 @@ export class Lwm2mDeviceProfileTransportConfigurationComponent implements Contro } private removeAttributeLwm2mFromJson = (keyId: string): void => { - debugger const keyNameJson = this.configurationValue.observeAttr.attributeLwm2m; Object.keys(keyNameJson).forEach(key => { if (key.startsWith(`/${keyId}`)) { diff --git a/ui-ngx/src/app/modules/home/components/profile/device/lwm2m/lwm2m-object-add-instances-dialog.component.ts b/ui-ngx/src/app/modules/home/components/profile/device/lwm2m/lwm2m-object-add-instances-dialog.component.ts index c480356e72..030b19b6d2 100644 --- a/ui-ngx/src/app/modules/home/components/profile/device/lwm2m/lwm2m-object-add-instances-dialog.component.ts +++ b/ui-ngx/src/app/modules/home/components/profile/device/lwm2m/lwm2m-object-add-instances-dialog.component.ts @@ -14,13 +14,13 @@ /// limitations under the License. /// -import {Component, Inject, OnInit} from '@angular/core'; -import {DialogComponent} from '@shared/components/dialog.component'; -import {FormBuilder, FormGroup} from '@angular/forms'; -import {Store} from '@ngrx/store'; -import {AppState} from '@core/core.state'; -import {Router} from '@angular/router'; -import {MAT_DIALOG_DATA, MatDialogRef} from '@angular/material/dialog'; +import { Component, Inject, OnInit } from '@angular/core'; +import { DialogComponent } from '@shared/components/dialog.component'; +import { FormBuilder, FormGroup } from '@angular/forms'; +import { Store } from '@ngrx/store'; +import { AppState } from '@core/core.state'; +import { Router } from '@angular/router'; +import { MAT_DIALOG_DATA, MatDialogRef } from '@angular/material/dialog'; export interface Lwm2mObjectAddInstancesData { instancesIds: Set; diff --git a/ui-ngx/src/app/modules/home/components/profile/device/lwm2m/lwm2m-object-add-instances-list.component.ts b/ui-ngx/src/app/modules/home/components/profile/device/lwm2m/lwm2m-object-add-instances-list.component.ts index cda075a142..29f5bb33cf 100644 --- a/ui-ngx/src/app/modules/home/components/profile/device/lwm2m/lwm2m-object-add-instances-list.component.ts +++ b/ui-ngx/src/app/modules/home/components/profile/device/lwm2m/lwm2m-object-add-instances-list.component.ts @@ -14,11 +14,9 @@ /// limitations under the License. /// -import {Component, forwardRef} from '@angular/core'; -import {ControlValueAccessor, FormBuilder, FormGroup, NG_VALUE_ACCESSOR, Validators} from '@angular/forms'; -import {Store} from '@ngrx/store'; -import {AppState} from '@core/core.state'; -import {INSTANCES_ID_VALUE_MAX, INSTANCES_ID_VALUE_MIN, KEY_REGEXP_NUMBER} from './lwm2m-profile-config.models'; +import { Component, forwardRef } from '@angular/core'; +import { ControlValueAccessor, FormBuilder, FormGroup, NG_VALUE_ACCESSOR, Validators } from '@angular/forms'; +import { INSTANCES_ID_VALUE_MAX, INSTANCES_ID_VALUE_MIN, KEY_REGEXP_NUMBER } from './lwm2m-profile-config.models'; @Component({ selector: 'tb-profile-lwm2m-object-add-instances-list', @@ -41,8 +39,7 @@ export class Lwm2mObjectAddInstancesListComponent implements ControlValueAccesso private propagateChange = (v: any) => { }; - constructor(private store: Store, - private fb: FormBuilder) { + constructor(private fb: FormBuilder) { this.instancesListFormGroup = this.fb.group({ instanceIdInput: [null, [ Validators.min(this.instanceIdValueMin), diff --git a/ui-ngx/src/app/modules/home/components/profile/device/lwm2m/lwm2m-object-list.component.ts b/ui-ngx/src/app/modules/home/components/profile/device/lwm2m/lwm2m-object-list.component.ts index ba54f63411..8f1f676769 100644 --- a/ui-ngx/src/app/modules/home/components/profile/device/lwm2m/lwm2m-object-list.component.ts +++ b/ui-ngx/src/app/modules/home/components/profile/device/lwm2m/lwm2m-object-list.component.ts @@ -14,18 +14,16 @@ /// limitations under the License. /// -import {Component, ElementRef, EventEmitter, forwardRef, Input, OnInit, Output, ViewChild} from '@angular/core'; -import {ControlValueAccessor, FormBuilder, FormGroup, NG_VALUE_ACCESSOR, Validators} from '@angular/forms'; -import {coerceBooleanProperty} from '@angular/cdk/coercion'; -import {Store} from '@ngrx/store'; -import {AppState} from '@core/core.state'; -import {Observable} from 'rxjs'; -import {filter, map, mergeMap, publishReplay, refCount, tap} from 'rxjs/operators'; -import {ModelValue, ObjectLwM2M, PAGE_SIZE_LIMIT} from './lwm2m-profile-config.models'; -import {DeviceProfileService} from '@core/http/device-profile.service'; -import {Direction} from '@shared/models/page/sort-order'; -import {isDefined, isDefinedAndNotNull, isString} from '@core/utils'; -import {PageLink} from "@shared/models/page/page-link"; +import { Component, ElementRef, EventEmitter, forwardRef, Input, OnInit, Output, ViewChild } from '@angular/core'; +import { ControlValueAccessor, FormBuilder, FormGroup, NG_VALUE_ACCESSOR, Validators } from '@angular/forms'; +import { coerceBooleanProperty } from '@angular/cdk/coercion'; +import { Observable } from 'rxjs'; +import { filter, map, mergeMap, publishReplay, refCount, tap } from 'rxjs/operators'; +import { ModelValue, ObjectLwM2M, PAGE_SIZE_LIMIT } from './lwm2m-profile-config.models'; +import { DeviceProfileService } from '@core/http/device-profile.service'; +import { Direction } from '@shared/models/page/sort-order'; +import { isDefined, isDefinedAndNotNull, isString } from '@core/utils'; +import { PageLink } from '@shared/models/page/page-link'; @Component({ selector: 'tb-profile-lwm2m-object-list', @@ -71,8 +69,7 @@ export class Lwm2mObjectListComponent implements ControlValueAccessor, OnInit, V private propagateChange = (v: any) => { } - constructor(private store: Store, - private deviceProfileService: DeviceProfileService, + constructor(private deviceProfileService: DeviceProfileService, private fb: FormBuilder) { this.lwm2mListFormGroup = this.fb.group({ objectsList: [this.objectsList], @@ -162,20 +159,20 @@ export class Lwm2mObjectListComponent implements ControlValueAccessor, OnInit, V private fetchListObjects = (searchText?: string): Observable> => { this.searchText = searchText; - return this.getLwM2mModelsPage().pipe( - map(objectLwM2Ms => objectLwM2Ms) - ); + return this.getLwM2mModelsPage().pipe( + map(objectLwM2Ms => objectLwM2Ms) + ); } private getLwM2mModelsPage(): Observable> { - const pageLink = new PageLink(PAGE_SIZE_LIMIT, 0, this.searchText, { - property: 'id', - direction: Direction.ASC - }); - this.lw2mModels = this.deviceProfileService.getLwm2mObjectsPage(pageLink).pipe( - publishReplay(1), - refCount() - ); + const pageLink = new PageLink(PAGE_SIZE_LIMIT, 0, this.searchText, { + property: 'id', + direction: Direction.ASC + }); + this.lw2mModels = this.deviceProfileService.getLwm2mObjectsPage(pageLink).pipe( + publishReplay(1), + refCount() + ); return this.lw2mModels; } diff --git a/ui-ngx/src/app/modules/home/components/profile/device/lwm2m/lwm2m-observe-attr-telemetry-resource.component.ts b/ui-ngx/src/app/modules/home/components/profile/device/lwm2m/lwm2m-observe-attr-telemetry-resource.component.ts index c824b000a8..c3003c7c3e 100644 --- a/ui-ngx/src/app/modules/home/components/profile/device/lwm2m/lwm2m-observe-attr-telemetry-resource.component.ts +++ b/ui-ngx/src/app/modules/home/components/profile/device/lwm2m/lwm2m-observe-attr-telemetry-resource.component.ts @@ -14,13 +14,11 @@ /// limitations under the License. /// -import {Component, forwardRef, Input} from '@angular/core'; -import {ControlValueAccessor, FormArray, FormBuilder, FormGroup, NG_VALUE_ACCESSOR, Validators} from '@angular/forms'; -import {ResourceLwM2M, RESOURCES} from '@home/components/profile/device/lwm2m/lwm2m-profile-config.models'; -import {Store} from '@ngrx/store'; -import {AppState} from '@core/core.state'; +import { Component, forwardRef, Input } from '@angular/core'; +import { ControlValueAccessor, FormArray, FormBuilder, FormGroup, NG_VALUE_ACCESSOR, Validators } from '@angular/forms'; +import { ResourceLwM2M, RESOURCES } from '@home/components/profile/device/lwm2m/lwm2m-profile-config.models'; import _ from 'lodash'; -import {coerceBooleanProperty} from '@angular/cdk/coercion'; +import { coerceBooleanProperty } from '@angular/cdk/coercion'; @Component({ selector: 'tb-profile-lwm2m-observe-attr-telemetry-resource', @@ -54,8 +52,7 @@ export class Lwm2mObserveAttrTelemetryResourceComponent implements ControlValueA } } - constructor(private store: Store, - private fb: FormBuilder) { + constructor(private fb: FormBuilder) { this.resourceFormGroup = this.fb.group({ resources: this.fb.array([]) }); @@ -95,7 +92,7 @@ export class Lwm2mObserveAttrTelemetryResourceComponent implements ControlValueA } getNameResourceLwm2m = (resourceLwM2M: ResourceLwM2M): string => { - return '<' + resourceLwM2M.id +'> ' + resourceLwM2M.name; + return `<${resourceLwM2M.id}> ${resourceLwM2M.name}`; } createResourceLwM2M(resourcesLwM2M: ResourceLwM2M[]): void { @@ -135,14 +132,14 @@ export class Lwm2mObserveAttrTelemetryResourceComponent implements ControlValueA return index; } - updateObserve = (index: number): void =>{ + updateObserve = (index: number): void => { if (this.resourceFormArray.at(index).value.attribute === false && this.resourceFormArray.at(index).value.telemetry === false) { this.resourceFormArray.at(index).patchValue({observe: false}); this.resourceFormArray.at(index).patchValue({attributeLwm2m: {}}); } } - disableObserve = (index: number): boolean =>{ + disableObserve = (index: number): boolean => { return !this.resourceFormArray.at(index).value.telemetry && !this.resourceFormArray.at(index).value.attribute; } } diff --git a/ui-ngx/src/app/modules/home/components/profile/device/lwm2m/lwm2m-observe-attr-telemetry.component.ts b/ui-ngx/src/app/modules/home/components/profile/device/lwm2m/lwm2m-observe-attr-telemetry.component.ts index c38c413e98..77a5956855 100644 --- a/ui-ngx/src/app/modules/home/components/profile/device/lwm2m/lwm2m-observe-attr-telemetry.component.ts +++ b/ui-ngx/src/app/modules/home/components/profile/device/lwm2m/lwm2m-observe-attr-telemetry.component.ts @@ -14,7 +14,7 @@ /// limitations under the License. /// -import {Component, forwardRef, Input} from '@angular/core'; +import { Component, forwardRef, Input } from '@angular/core'; import { AbstractControl, ControlValueAccessor, @@ -24,9 +24,7 @@ import { NG_VALUE_ACCESSOR, Validators } from '@angular/forms'; -import {Store} from '@ngrx/store'; -import {AppState} from '@core/core.state'; -import {coerceBooleanProperty} from '@angular/cdk/coercion'; +import { coerceBooleanProperty } from '@angular/cdk/coercion'; import { ATTRIBUTE, ATTRIBUTE_LWM2M, @@ -38,9 +36,8 @@ import { RESOURCES, TELEMETRY } from './lwm2m-profile-config.models'; -import {deepClone, isDefinedAndNotNull, isEqual, isUndefined} from '@core/utils'; -import {MatDialog} from '@angular/material/dialog'; -import {TranslateService} from '@ngx-translate/core'; +import { deepClone, isDefinedAndNotNull, isEqual, isUndefined } from '@core/utils'; +import { MatDialog } from '@angular/material/dialog'; import { Lwm2mObjectAddInstancesData, Lwm2mObjectAddInstancesDialogComponent @@ -83,10 +80,8 @@ export class Lwm2mObserveAttrTelemetryComponent implements ControlValueAccessor @Input() disabled: boolean; - constructor(private store: Store, - private fb: FormBuilder, - private dialog: MatDialog, - public translate: TranslateService) { + constructor(private fb: FormBuilder, + private dialog: MatDialog) { this.observeAttrTelemetryFormGroup = this.fb.group({ [CLIENT_LWM2M]: this.fb.array([]) }); @@ -98,7 +93,7 @@ export class Lwm2mObserveAttrTelemetryComponent implements ControlValueAccessor } private propagateChange = (v: any) => { - }; + } registerOnChange(fn: any): void { this.propagateChange = fn; @@ -189,7 +184,7 @@ export class Lwm2mObserveAttrTelemetryComponent implements ControlValueAccessor this.observeAttrTelemetryFormGroup.get(CLIENT_LWM2M).updateValueAndValidity(); } - trackByParams = (index: number, element: any): number => { + trackByParams = (index: number): number => { return index; } @@ -252,7 +247,6 @@ export class Lwm2mObserveAttrTelemetryComponent implements ControlValueAccessor } private updateInstancesIds = (data: Lwm2mObjectAddInstancesData): void => { - debugger const objectLwM2MFormGroup = (this.observeAttrTelemetryFormGroup.get(CLIENT_LWM2M) as FormArray).controls .find(e => e.value.keyId === data.objectKeyId) as FormGroup; const instancesArray = objectLwM2MFormGroup.value.instances as Instance []; @@ -318,7 +312,7 @@ export class Lwm2mObserveAttrTelemetryComponent implements ControlValueAccessor return objectName + ' <' + idVerObj + '>'; } getNameInstanceLwm2m = (instance: Instance, idVerObj: string): string => { - return ' instance <' + idVerObj + '/' + instance.id +'>'; + return ` instance <${idVerObj}/${instance.id}>`; } updateAttributeLwm2mObject = (event: Event, objectKeyId: number): void => { diff --git a/ui-ngx/src/app/modules/home/components/profile/device/lwm2m/lwm2m-profile-components.module.ts b/ui-ngx/src/app/modules/home/components/profile/device/lwm2m/lwm2m-profile-components.module.ts index 43c297df56..4575d2bfff 100644 --- a/ui-ngx/src/app/modules/home/components/profile/device/lwm2m/lwm2m-profile-components.module.ts +++ b/ui-ngx/src/app/modules/home/components/profile/device/lwm2m/lwm2m-profile-components.module.ts @@ -14,19 +14,19 @@ /// limitations under the License. /// -import {NgModule} from '@angular/core'; -import {Lwm2mDeviceProfileTransportConfigurationComponent} from './lwm2m-device-profile-transport-configuration.component'; -import {Lwm2mObjectListComponent} from './lwm2m-object-list.component'; -import {Lwm2mObserveAttrTelemetryComponent} from './lwm2m-observe-attr-telemetry.component'; -import {Lwm2mObserveAttrTelemetryResourceComponent} from './lwm2m-observe-attr-telemetry-resource.component'; -import {Lwm2mAttributesDialogComponent} from './lwm2m-attributes-dialog.component'; -import {Lwm2mAttributesComponent} from './lwm2m-attributes.component'; -import {Lwm2mAttributesKeyListComponent} from './lwm2m-attributes-key-list.component'; -import {Lwm2mDeviceConfigServerComponent} from './lwm2m-device-config-server.component'; -import {Lwm2mObjectAddInstancesDialogComponent} from './lwm2m-object-add-instances-dialog.component'; -import {Lwm2mObjectAddInstancesListComponent} from './lwm2m-object-add-instances-list.component'; -import {CommonModule} from '@angular/common'; -import {SharedModule} from '@app/shared/shared.module'; +import { NgModule } from '@angular/core'; +import { Lwm2mDeviceProfileTransportConfigurationComponent } from './lwm2m-device-profile-transport-configuration.component'; +import { Lwm2mObjectListComponent } from './lwm2m-object-list.component'; +import { Lwm2mObserveAttrTelemetryComponent } from './lwm2m-observe-attr-telemetry.component'; +import { Lwm2mObserveAttrTelemetryResourceComponent } from './lwm2m-observe-attr-telemetry-resource.component'; +import { Lwm2mAttributesDialogComponent } from './lwm2m-attributes-dialog.component'; +import { Lwm2mAttributesComponent } from './lwm2m-attributes.component'; +import { Lwm2mAttributesKeyListComponent } from './lwm2m-attributes-key-list.component'; +import { Lwm2mDeviceConfigServerComponent } from './lwm2m-device-config-server.component'; +import { Lwm2mObjectAddInstancesDialogComponent } from './lwm2m-object-add-instances-dialog.component'; +import { Lwm2mObjectAddInstancesListComponent } from './lwm2m-object-add-instances-list.component'; +import { CommonModule } from '@angular/common'; +import { SharedModule } from '@app/shared/shared.module'; @NgModule({ declarations: diff --git a/ui-ngx/src/app/modules/home/components/profile/device/lwm2m/lwm2m-profile-config.models.ts b/ui-ngx/src/app/modules/home/components/profile/device/lwm2m/lwm2m-profile-config.models.ts index ff927bc09f..f6e58df903 100644 --- a/ui-ngx/src/app/modules/home/components/profile/device/lwm2m/lwm2m-profile-config.models.ts +++ b/ui-ngx/src/app/modules/home/components/profile/device/lwm2m/lwm2m-profile-config.models.ts @@ -127,8 +127,8 @@ export const SECURITY_CONFIG_MODE_NAMES = new Map( ); export interface ModelValue { - objectIds: string[], - objectsList: ObjectLwM2M[] + objectIds: string[]; + objectsList: ObjectLwM2M[]; } export interface BootstrapServersSecurityConfig { diff --git a/ui-ngx/src/app/modules/home/pages/device/device.module.ts b/ui-ngx/src/app/modules/home/pages/device/device.module.ts index f9ece52b22..8aeda0e2c1 100644 --- a/ui-ngx/src/app/modules/home/pages/device/device.module.ts +++ b/ui-ngx/src/app/modules/home/pages/device/device.module.ts @@ -24,8 +24,6 @@ import { DeviceCredentialsDialogComponent } from '@modules/home/pages/device/dev import { HomeDialogsModule } from '../../dialogs/home-dialogs.module'; import { HomeComponentsModule } from '@modules/home/components/home-components.module'; import { DeviceTabsComponent } from '@home/pages/device/device-tabs.component'; -import { SecurityConfigComponent } from '@home/pages/device/lwm2m/security-config.component'; -import { SecurityConfigServerComponent } from '@home/pages/device/lwm2m/security-config-server.component'; import { DefaultDeviceConfigurationComponent } from './data/default-device-configuration.component'; import { DeviceConfigurationComponent } from './data/device-configuration.component'; import { DeviceDataComponent } from './data/device-data.component'; @@ -50,9 +48,7 @@ import { SnmpDeviceTransportConfigurationComponent } from './data/snmp-device-tr DeviceComponent, DeviceTabsComponent, DeviceTableHeaderComponent, - DeviceCredentialsDialogComponent, - SecurityConfigComponent, - SecurityConfigServerComponent + DeviceCredentialsDialogComponent ], imports: [ CommonModule, diff --git a/ui-ngx/src/app/modules/home/pages/device/lwm2m/security-config-server.component.html b/ui-ngx/src/app/modules/home/pages/device/lwm2m/security-config-server.component.html deleted file mode 100644 index bd02c9dee3..0000000000 --- a/ui-ngx/src/app/modules/home/pages/device/lwm2m/security-config-server.component.html +++ /dev/null @@ -1,101 +0,0 @@ - -
-
-
-
- - device.lwm2m-security-config.mode - - - {{ credentialTypeLwM2MNamesMap.get(securityConfigLwM2MType[securityMode]) }} - - - -
-
-
-
- - {{ 'device.lwm2m-security-config.client-publicKey-or-id' | translate }} - - {{clientPublicKeyOrId.value?.length || 0}}/{{lenMaxClientPublicKeyOrId}} - - {{ 'device.lwm2m-security-config.client-publicKey-or-id' | translate }} - {{ 'device.lwm2m-security-config.required' | translate }} - - - {{ 'device.lwm2m-security-config.client-key' | translate }} - {{ 'device.lwm2m-security-config.pattern_hex_dec' | translate: { - count: 0 - } }} - - - {{ 'device.lwm2m-security-config.client-key' | translate }} - {{ 'device.lwm2m-security-config.pattern_hex_dec' | translate: { - count: lenMaxClientPublicKeyOrId - } }} - - - - {{ 'device.lwm2m-security-config.client-secret-key' | translate }} - - {{clientSecretKey.value?.length || 0}}/{{lenMaxClientSecretKey}} - - {{ 'device.lwm2m-security-config.client-secret-key' | translate }} - {{ 'device.lwm2m-security-config.required' | translate }} - - - {{ 'device.lwm2m-security-config.client-key' | translate }} - {{ 'device.lwm2m-security-config.pattern_hex_dec' | translate: { - count: 0 - } }} - - - {{ 'device.lwm2m-security-config.client-key' | translate }} - {{ 'device.lwm2m-security-config.pattern_hex_dec' | translate: { - count: lenMaxClientSecretKey - } }} - - -
-
-
-
diff --git a/ui-ngx/src/app/modules/home/pages/device/lwm2m/security-config-server.component.ts b/ui-ngx/src/app/modules/home/pages/device/lwm2m/security-config-server.component.ts deleted file mode 100644 index a068bb589e..0000000000 --- a/ui-ngx/src/app/modules/home/pages/device/lwm2m/security-config-server.component.ts +++ /dev/null @@ -1,142 +0,0 @@ -/// -/// Copyright © 2016-2021 The Thingsboard Authors -/// -/// Licensed under the Apache License, Version 2.0 (the "License"); -/// you may not use this file except in compliance with the License. -/// You may obtain a copy of the License at -/// -/// http://www.apache.org/licenses/LICENSE-2.0 -/// -/// Unless required by applicable law or agreed to in writing, software -/// distributed under the License is distributed on an "AS IS" BASIS, -/// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -/// See the License for the specific language governing permissions and -/// limitations under the License. -/// - -import { Component, forwardRef, Inject, Input, OnInit } from '@angular/core'; -import { ControlValueAccessor, FormBuilder, FormGroup, NG_VALUE_ACCESSOR, Validators } from '@angular/forms'; -import { - DeviceCredentialsDialogLwm2mData, - KEY_REGEXP_HEX_DEC, - LEN_MAX_PRIVATE_KEY, - LEN_MAX_PSK, - LEN_MAX_PUBLIC_KEY_RPK, - LEN_MAX_PUBLIC_KEY_X509, - SECURITY_CONFIG_MODE, - SECURITY_CONFIG_MODE_NAMES, - ServerSecurityConfig -} from '@home/pages/device/lwm2m/security-config.models'; -import { Store } from '@ngrx/store'; -import { AppState } from '@core/core.state'; -import { MAT_DIALOG_DATA, MatDialogRef } from '@angular/material/dialog'; -import { PageComponent } from '@shared/components/page.component'; - -@Component({ - selector: 'tb-security-config-server-lwm2m', - templateUrl: './security-config-server.component.html', - styleUrls: [], - providers: [ - { - provide: NG_VALUE_ACCESSOR, - useExisting: forwardRef(() => SecurityConfigServerComponent), - multi: true - } - ] -}) - -export class SecurityConfigServerComponent extends PageComponent implements OnInit, ControlValueAccessor { - - securityConfigLwM2MType = SECURITY_CONFIG_MODE; - securityConfigLwM2MTypes = Object.keys(SECURITY_CONFIG_MODE); - credentialTypeLwM2MNamesMap = SECURITY_CONFIG_MODE_NAMES; - lenMinClientPublicKeyOrId = 0; - lenMaxClientPublicKeyOrId = LEN_MAX_PUBLIC_KEY_RPK; - lenMinClientSecretKey = LEN_MAX_PRIVATE_KEY; - lenMaxClientSecretKey = LEN_MAX_PRIVATE_KEY; - - @Input() serverFormGroup: FormGroup; - - constructor(protected store: Store, - @Inject(MAT_DIALOG_DATA) public data: DeviceCredentialsDialogLwm2mData, - public dialogRef: MatDialogRef, - public fb: FormBuilder) { - super(store); - } - - ngOnInit(): void { - this.registerDisableOnLoadFormControl(this.serverFormGroup.get('securityMode')); - } - - private updateValueFields(serverData: ServerSecurityConfig): void { - this.serverFormGroup.patchValue(serverData, {emitEvent: false}); - const securityMode = this.serverFormGroup.get('securityMode').value as SECURITY_CONFIG_MODE; - this.updateValidate(securityMode); - } - - private updateValidate(securityMode: SECURITY_CONFIG_MODE): void { - switch (securityMode) { - case SECURITY_CONFIG_MODE.NO_SEC: - this.serverFormGroup.get('clientPublicKeyOrId').setValidators([]); - this.serverFormGroup.get('clientSecretKey').setValidators([]); - break; - case SECURITY_CONFIG_MODE.PSK: - this.lenMinClientPublicKeyOrId = 0; - this.lenMaxClientPublicKeyOrId = LEN_MAX_PUBLIC_KEY_RPK; - this.lenMinClientSecretKey = LEN_MAX_PSK; - this.lenMaxClientSecretKey = LEN_MAX_PSK; - this.setValidatorsSecurity(securityMode); - break; - case SECURITY_CONFIG_MODE.RPK: - this.lenMinClientPublicKeyOrId = LEN_MAX_PUBLIC_KEY_RPK; - this.lenMaxClientPublicKeyOrId = LEN_MAX_PUBLIC_KEY_RPK; - this.lenMinClientSecretKey = LEN_MAX_PRIVATE_KEY; - this.lenMaxClientSecretKey = LEN_MAX_PRIVATE_KEY; - this.setValidatorsSecurity(securityMode); - break; - case SECURITY_CONFIG_MODE.X509: - this.lenMinClientPublicKeyOrId = 0; - this.lenMaxClientPublicKeyOrId = LEN_MAX_PUBLIC_KEY_X509; - this.lenMinClientSecretKey = LEN_MAX_PRIVATE_KEY; - this.lenMaxClientSecretKey = LEN_MAX_PRIVATE_KEY; - this.setValidatorsSecurity(securityMode); - break; - } - this.serverFormGroup.updateValueAndValidity(); - } - - private setValidatorsSecurity = (securityMode: SECURITY_CONFIG_MODE): void => { - if (securityMode === SECURITY_CONFIG_MODE.PSK) { - this.serverFormGroup.get('clientPublicKeyOrId').setValidators([Validators.required]); - } else { - this.serverFormGroup.get('clientPublicKeyOrId').setValidators([Validators.required, - Validators.pattern(KEY_REGEXP_HEX_DEC), - Validators.minLength(this.lenMinClientPublicKeyOrId), - Validators.maxLength(this.lenMaxClientPublicKeyOrId)]); - } - - this.serverFormGroup.get('clientSecretKey').setValidators([Validators.required, - Validators.pattern(KEY_REGEXP_HEX_DEC), - Validators.minLength(this.lenMinClientSecretKey), - Validators.maxLength(this.lenMaxClientSecretKey)]); - } - - securityModeChanged(securityMode: SECURITY_CONFIG_MODE): void { - this.updateValidate(securityMode); - } - - writeValue(value: any): void { - if (value) { - this.updateValueFields(value); - } - } - - registerOnChange(fn: (value: any) => any): void { - } - - registerOnTouched(fn: any): void { - } - - setDisabledState?(isDisabled: boolean): void { - } -} diff --git a/ui-ngx/src/app/modules/home/pages/device/lwm2m/security-config.component.html b/ui-ngx/src/app/modules/home/pages/device/lwm2m/security-config.component.html deleted file mode 100644 index db0946b371..0000000000 --- a/ui-ngx/src/app/modules/home/pages/device/lwm2m/security-config.component.html +++ /dev/null @@ -1,180 +0,0 @@ - -
- -

{{ title }}

- - -
-
-
- - device.lwm2m-security-config.endpoint - - - {{ 'device.lwm2m-security-config.endpoint' | translate }} - {{ 'device.lwm2m-security-config.required' | translate }} - - - - - -
- - device.lwm2m-security-config.mode - - - {{ credentialTypeLwM2MNamesMap.get(securityConfigLwM2MType[securityConfigClientMode]) }} - - - -
- - {{ 'device.lwm2m-security-config.identity' | translate }} - - - {{ 'device.lwm2m-security-config.identity' | translate }} - {{ 'device.lwm2m-security-config.required' | translate }} - - -
-
- - {{ 'device.lwm2m-security-config.client-key' | translate }} - - {{clientKey.value?.length || 0}}/{{lenMaxKeyClient}} - - {{ 'device.lwm2m-security-config.client-key' | translate }} - {{ 'device.lwm2m-security-config.required' | translate }} - - - {{ 'device.lwm2m-security-config.client-key' | translate }} - {{ 'device.lwm2m-security-config.pattern_hex_dec' | translate: { - count: 0 - } }} - - - {{ 'device.lwm2m-security-config.client-key' | translate }} - {{ 'device.lwm2m-security-config.pattern_hex_dec' | translate: { - count: lenMaxKeyClient - } }} - - -
-
- - {{ 'device.lwm2m-security-config.client-certificate' | translate }} - -
-
-
-
- - -
- - - - -
{{ 'device.lwm2m-security-config.bootstrap-server' | translate | uppercase }}
-
-
- -
- - -
-
-
-
- - - - -
{{ 'device.lwm2m-security-config.lwm2m-server' | translate | uppercase }}
-
-
- -
- - -
-
-
-
-
-
-
- - -
-
- - -
-
-
-
-
-
-
-
- - - -
-
diff --git a/ui-ngx/src/app/modules/home/pages/device/lwm2m/security-config.component.ts b/ui-ngx/src/app/modules/home/pages/device/lwm2m/security-config.component.ts deleted file mode 100644 index 028f28c72a..0000000000 --- a/ui-ngx/src/app/modules/home/pages/device/lwm2m/security-config.component.ts +++ /dev/null @@ -1,382 +0,0 @@ -/// -/// Copyright © 2016-2021 The Thingsboard Authors -/// -/// Licensed under the Apache License, Version 2.0 (the "License"); -/// you may not use this file except in compliance with the License. -/// You may obtain a copy of the License at -/// -/// http://www.apache.org/licenses/LICENSE-2.0 -/// -/// Unless required by applicable law or agreed to in writing, software -/// distributed under the License is distributed on an "AS IS" BASIS, -/// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -/// See the License for the specific language governing permissions and -/// limitations under the License. -/// - - -import {Component, Inject, OnInit} from '@angular/core'; -import {DialogComponent} from '@shared/components/dialog.component'; -import {Store} from '@ngrx/store'; -import {AppState} from '@core/core.state'; -import {Router} from '@angular/router'; -import {MAT_DIALOG_DATA, MatDialogRef} from '@angular/material/dialog'; -import {FormBuilder, FormGroup, Validators} from '@angular/forms'; -import {TranslateService} from '@ngx-translate/core'; -import { - BOOTSTRAP_SERVER, - BOOTSTRAP_SERVERS, - ClientSecurityConfig, - DeviceCredentialsDialogLwm2mData, - getClientSecurityConfig, - JSON_ALL_CONFIG, - KEY_REGEXP_HEX_DEC, - LEN_MAX_PSK, - LEN_MAX_PUBLIC_KEY_RPK, - LWM2M_SERVER, - SECURITY_CONFIG_MODE, - SECURITY_CONFIG_MODE_NAMES, - SecurityConfigModels -} from './security-config.models'; -import {WINDOW} from '@core/services/window.service'; -import {MatTabChangeEvent} from '@angular/material/tabs'; -import {MatTab} from '@angular/material/tabs/tab'; - -@Component({ - selector: 'tb-security-config-lwm2m', - templateUrl: './security-config.component.html', - styleUrls: [] -}) - -export class SecurityConfigComponent extends DialogComponent implements OnInit { - - lwm2mConfigFormGroup: FormGroup; - title: string; - submitted = false; - securityConfigLwM2MType = SECURITY_CONFIG_MODE; - securityConfigLwM2MTypes = Object.keys(SECURITY_CONFIG_MODE); - credentialTypeLwM2MNamesMap = SECURITY_CONFIG_MODE_NAMES; - formControlNameJsonAllConfig = JSON_ALL_CONFIG; - jsonAllConfig: SecurityConfigModels; - bootstrapServers: string; - bootstrapServer: string; - lwm2mServer: string; - jsonObserveData: {}; - lenMaxKeyClient = LEN_MAX_PSK; - tabPrevious: MatTab; - tabIndexPrevious = 0; - - constructor(protected store: Store, - protected router: Router, - @Inject(MAT_DIALOG_DATA) public data: DeviceCredentialsDialogLwm2mData, - public dialogRef: MatDialogRef, - public fb: FormBuilder, - public translate: TranslateService, - @Inject(WINDOW) private window: Window) { - super(store, router, dialogRef); - } - - ngOnInit(): void { - this.jsonAllConfig = JSON.parse(JSON.stringify(this.data.jsonAllConfig)) as SecurityConfigModels; - this.initConstants(); - this.lwm2mConfigFormGroup = this.initLwm2mConfigFormGroup(); - this.title = this.translate.instant('device.lwm2m-security-info') + ': ' + this.data.endPoint; - this.lwm2mConfigFormGroup.get('clientCertificate').disable(); - this.initClientSecurityConfig(this.lwm2mConfigFormGroup.get('jsonAllConfig').value); - this.registerDisableOnLoadFormControl(this.lwm2mConfigFormGroup.get('securityConfigClientMode')); - } - - private initConstants = (): void => { - this.bootstrapServers = BOOTSTRAP_SERVERS; - this.bootstrapServer = BOOTSTRAP_SERVER; - this.lwm2mServer = LWM2M_SERVER; - } - - /** - * initChildesFormGroup - */ - get bootstrapFormGroup(): FormGroup { - return this.lwm2mConfigFormGroup.get('bootstrapFormGroup') as FormGroup; - } - - get lwm2mServerFormGroup(): FormGroup { - return this.lwm2mConfigFormGroup.get('lwm2mServerFormGroup') as FormGroup; - } - - get observeAttrFormGroup(): FormGroup { - return this.lwm2mConfigFormGroup.get('observeFormGroup') as FormGroup; - } - - private initClientSecurityConfig = (jsonAllConfig: SecurityConfigModels): void => { - switch (jsonAllConfig.client.securityConfigClientMode) { - case SECURITY_CONFIG_MODE.NO_SEC: - break; - case SECURITY_CONFIG_MODE.PSK: - const clientSecurityConfigPSK = jsonAllConfig.client as ClientSecurityConfig; - this.lwm2mConfigFormGroup.patchValue({ - identityPSK: clientSecurityConfigPSK.identity, - clientKey: clientSecurityConfigPSK.key, - }, {emitEvent: false}); - break; - case SECURITY_CONFIG_MODE.RPK: - const clientSecurityConfigRPK = jsonAllConfig.client as ClientSecurityConfig; - this.lwm2mConfigFormGroup.patchValue({ - clientKey: clientSecurityConfigRPK.key, - }, {emitEvent: false}); - break; - case SECURITY_CONFIG_MODE.X509: - const clientSecurityConfigX509 = jsonAllConfig.client as ClientSecurityConfig; - this.lwm2mConfigFormGroup.patchValue({ - clientCertificate: clientSecurityConfigX509.x509 - }, {emitEvent: false}); - break; - } - this.securityConfigClientUpdateValidators(this.lwm2mConfigFormGroup.get('securityConfigClientMode').value); - } - - securityConfigClientModeChanged = (mode: SECURITY_CONFIG_MODE): void => { - switch (mode) { - case SECURITY_CONFIG_MODE.NO_SEC: - const clientSecurityConfigNoSEC = getClientSecurityConfig(mode) as ClientSecurityConfig; - this.jsonAllConfig.client = clientSecurityConfigNoSEC; - this.lwm2mConfigFormGroup.patchValue({ - jsonAllConfig: this.jsonAllConfig, - clientCertificate: false - }, {emitEvent: false}); - break; - case SECURITY_CONFIG_MODE.PSK: - const clientSecurityConfigPSK = getClientSecurityConfig(mode, this.lwm2mConfigFormGroup.get('endPoint') - .value) as ClientSecurityConfig; - clientSecurityConfigPSK.identity = this.data.endPoint; - clientSecurityConfigPSK.key = this.lwm2mConfigFormGroup.get('clientKey').value; - this.jsonAllConfig.client = clientSecurityConfigPSK; - this.lwm2mConfigFormGroup.patchValue({ - identityPSK: clientSecurityConfigPSK.identity, - clientCertificate: false - }, {emitEvent: false}); - break; - case SECURITY_CONFIG_MODE.RPK: - const clientSecurityConfigRPK = getClientSecurityConfig(mode) as ClientSecurityConfig; - clientSecurityConfigRPK.key = this.lwm2mConfigFormGroup.get('clientKey').value; - this.jsonAllConfig.client = clientSecurityConfigRPK; - this.lwm2mConfigFormGroup.patchValue({ - clientCertificate: false - }, {emitEvent: false}); - break; - case SECURITY_CONFIG_MODE.X509: - this.jsonAllConfig.client = getClientSecurityConfig(mode) as ClientSecurityConfig; - this.lwm2mConfigFormGroup.patchValue({ - clientCertificate: true - }, {emitEvent: false}); - break; - } - this.securityConfigClientUpdateValidators(mode); - } - - private securityConfigClientUpdateValidators = (mode: SECURITY_CONFIG_MODE): void => { - switch (mode) { - case SECURITY_CONFIG_MODE.NO_SEC: - this.setValidatorsNoSecX509(); - break; - case SECURITY_CONFIG_MODE.PSK: - this.lenMaxKeyClient = LEN_MAX_PSK; - this.setValidatorsPskRpk(mode); - break; - case SECURITY_CONFIG_MODE.RPK: - this.lenMaxKeyClient = LEN_MAX_PUBLIC_KEY_RPK; - this.setValidatorsPskRpk(mode); - break; - case SECURITY_CONFIG_MODE.X509: - this.lenMaxKeyClient = LEN_MAX_PUBLIC_KEY_RPK; - this.setValidatorsNoSecX509(); - break; - } - this.lwm2mConfigFormGroup.updateValueAndValidity(); - } - - private setValidatorsNoSecX509 = (): void => { - this.lwm2mConfigFormGroup.get('identityPSK').setValidators([]); - this.lwm2mConfigFormGroup.get('clientKey').setValidators([]); - } - - private setValidatorsPskRpk = (mode: SECURITY_CONFIG_MODE): void => { - if (mode === SECURITY_CONFIG_MODE.PSK) { - this.lwm2mConfigFormGroup.get('identityPSK').setValidators([Validators.required]); - } else { - this.lwm2mConfigFormGroup.get('identityPSK').setValidators([]); - } - this.lwm2mConfigFormGroup.get('clientKey').setValidators([Validators.required, - Validators.pattern(KEY_REGEXP_HEX_DEC), - Validators.maxLength(this.lenMaxKeyClient), Validators.minLength(this.lenMaxKeyClient)]); - } - - tabChanged = (tabChangeEvent: MatTabChangeEvent): void => { - if (this.tabIndexPrevious !== tabChangeEvent.index) { this.upDateValueToJson(); } - this.tabIndexPrevious = tabChangeEvent.index; - } - - private upDateValueToJson(): void { - switch (this.tabIndexPrevious) { - case 0: - this.upDateValueToJsonTab0(); - break; - case 1: - this.upDateValueToJsonTab1(); - break; - case 2: - this.upDateValueToJsonTab2(); - break; - } - } - - private upDateValueToJsonTab0 = (): void => { - if (this.lwm2mConfigFormGroup !== null) { - if (!this.lwm2mConfigFormGroup.get('endPoint').pristine && this.lwm2mConfigFormGroup.get('endPoint').valid) { - this.data.endPoint = this.lwm2mConfigFormGroup.get('endPoint').value; - /** Client mode == PSK */ - if (this.lwm2mConfigFormGroup.get('securityConfigClientMode').value === SECURITY_CONFIG_MODE.PSK) { - const endPoint = 'endpoint'; - this.jsonAllConfig.client[endPoint] = this.data.endPoint; - this.lwm2mConfigFormGroup.get('endPoint').markAsPristine({ - onlySelf: true - }); - this.upDateJsonAllConfig(); - } - } - /** only Client mode == PSK */ - if (!this.lwm2mConfigFormGroup.get('identityPSK').pristine && this.lwm2mConfigFormGroup.get('identityPSK').valid) { - this.lwm2mConfigFormGroup.get('identityPSK').markAsPristine({ - onlySelf: true - }); - this.updateIdentityPSK(); - } - /** only Client mode == PSK (len = 64) || RPK (len = 182) */ - if (!this.lwm2mConfigFormGroup.get('clientKey').pristine && this.lwm2mConfigFormGroup.get('clientKey').valid) { - this.lwm2mConfigFormGroup.get('clientKey').markAsPristine({ - onlySelf: true - }); - this.updateClientKey(); - } - } - } - - private upDateValueToJsonTab1 = (): void => { - if (this.lwm2mConfigFormGroup !== null) { - if (this.bootstrapFormGroup !== null && !this.bootstrapFormGroup.pristine && this.bootstrapFormGroup.valid) { - this.jsonAllConfig.bootstrap.bootstrapServer = this.bootstrapFormGroup.value; - this.bootstrapFormGroup.markAsPristine({ - onlySelf: true - }); - this.upDateJsonAllConfig(); - } - - if (this.lwm2mServerFormGroup !== null && !this.lwm2mServerFormGroup.pristine && this.lwm2mServerFormGroup.valid) { - this.jsonAllConfig.bootstrap.lwm2mServer = this.lwm2mServerFormGroup.value; - this.lwm2mServerFormGroup.markAsPristine({ - onlySelf: true - }); - this.upDateJsonAllConfig(); - } - } - } - - private upDateValueToJsonTab2 = (): void => { - if (!this.lwm2mConfigFormGroup.get(this.formControlNameJsonAllConfig).pristine && - this.lwm2mConfigFormGroup.get(this.formControlNameJsonAllConfig).valid) { - this.jsonAllConfig = this.lwm2mConfigFormGroup.get(this.formControlNameJsonAllConfig).value; - this.lwm2mConfigFormGroup.get(this.formControlNameJsonAllConfig).markAsPristine({ - onlySelf: true - }); - } - } - - private updateIdentityPSK = (): void => { - const securityMode = 'securityMode'; - if (this.lwm2mConfigFormGroup.get('bootstrapServer').value[securityMode] === SECURITY_CONFIG_MODE.PSK) { - this.lwm2mConfigFormGroup.get('bootstrapFormGroup').patchValue({ - clientPublicKeyOrId: this.lwm2mConfigFormGroup.get('identityPSK').value - }); - const identity = 'identity'; - this.jsonAllConfig.client[identity] = this.lwm2mConfigFormGroup.get('identityPSK').value; - this.upDateJsonAllConfig(); - } - if (this.lwm2mConfigFormGroup.get('lwm2mServer').value[securityMode] === SECURITY_CONFIG_MODE.PSK) { - this.lwm2mConfigFormGroup.get('lwm2mServerFormGroup').patchValue({ - clientPublicKeyOrId: this.lwm2mConfigFormGroup.get('identityPSK').value - }); - this.jsonAllConfig.bootstrap.lwm2mServer.clientPublicKeyOrId = this.lwm2mConfigFormGroup.get('identityPSK').value; - this.upDateJsonAllConfig(); - } - } - - private updateClientKey = (): void => { - const key = 'key'; - const securityMode = 'securityMode'; - this.jsonAllConfig.client[key] = this.lwm2mConfigFormGroup.get('clientKey').value; - if (this.lwm2mConfigFormGroup.get('bootstrapServer').value[securityMode] === SECURITY_CONFIG_MODE.PSK) { - this.lwm2mConfigFormGroup.get('bootstrapServer').patchValue({ - clientSecretKey: this.jsonAllConfig.client[key] - }, {emitEvent: false}); - this.jsonAllConfig.bootstrap.bootstrapServer.clientSecretKey = this.jsonAllConfig.client[key]; - } - if (this.lwm2mConfigFormGroup.get('lwm2mServer').value[securityMode] === SECURITY_CONFIG_MODE.PSK) { - this.lwm2mConfigFormGroup.get('lwm2mServer').patchValue({ - clientSecretKey: this.jsonAllConfig.client[key] - }, {emitEvent: false}); - this.jsonAllConfig.bootstrap.lwm2mServer.clientSecretKey = this.jsonAllConfig.client[key]; - } - this.upDateJsonAllConfig(); - } - - private upDateJsonAllConfig = (): void => { - this.data.jsonAllConfig = JSON.parse(JSON.stringify(this.jsonAllConfig)); - this.lwm2mConfigFormGroup.patchValue({ - jsonAllConfig: JSON.parse(JSON.stringify(this.jsonAllConfig)) - }, {emitEvent: false}); - this.lwm2mConfigFormGroup.markAsDirty(); - } - - private initLwm2mConfigFormGroup = (): FormGroup => { - if (SECURITY_CONFIG_MODE[this.jsonAllConfig.client.securityConfigClientMode.toString()] === SECURITY_CONFIG_MODE.PSK) { - const endpoint = 'endpoint'; - this.data.endPoint = this.jsonAllConfig.client[endpoint]; - } - return this.fb.group({ - securityConfigClientMode: [SECURITY_CONFIG_MODE[this.jsonAllConfig.client.securityConfigClientMode.toString()], []], - identityPSK: ['', []], - clientKey: ['', []], - clientCertificate: [false, []], - bootstrapServer: [this.jsonAllConfig.bootstrap[this.bootstrapServer], []], - lwm2mServer: [this.jsonAllConfig.bootstrap[this.lwm2mServer], []], - bootstrapFormGroup: this.getServerGroup(), - lwm2mServerFormGroup: this.getServerGroup(), - endPoint: [this.data.endPoint, []], - jsonAllConfig: [this.jsonAllConfig, []] - }); - } - - private getServerGroup = (): FormGroup => { - return this.fb.group({ - securityMode: [this.fb.control(SECURITY_CONFIG_MODE.NO_SEC), []], - clientPublicKeyOrId: ['', []], - clientSecretKey: ['', []] - }); - } - - save(): void { - this.upDateValueToJson(); - this.data.endPoint = this.lwm2mConfigFormGroup.get('endPoint').value.split('\'').join(''); - this.data.jsonAllConfig = this.jsonAllConfig; - if (this.lwm2mConfigFormGroup.get('securityConfigClientMode').value === SECURITY_CONFIG_MODE.PSK) { - const identity = 'identity'; - this.data.endPoint = this.data.jsonAllConfig.client[identity]; - } - this.dialogRef.close(this.data); - } - - cancel(): void { - this.dialogRef.close(undefined); - } -} - - diff --git a/ui-ngx/src/app/modules/home/pages/device/lwm2m/security-config.models.ts b/ui-ngx/src/app/shared/models/lwm2m-security-config.models.ts similarity index 60% rename from ui-ngx/src/app/modules/home/pages/device/lwm2m/security-config.models.ts rename to ui-ngx/src/app/shared/models/lwm2m-security-config.models.ts index 32b8026a4c..de0f2dc8a5 100644 --- a/ui-ngx/src/app/modules/home/pages/device/lwm2m/security-config.models.ts +++ b/ui-ngx/src/app/shared/models/lwm2m-security-config.models.ts @@ -17,9 +17,6 @@ export const JSON_ALL_CONFIG = 'jsonAllConfig'; export const END_POINT = 'endPoint'; export const DEFAULT_END_POINT = 'default_client_lwm2m_end_point_no_sec'; -export const BOOTSTRAP_SERVERS = 'servers'; -export const BOOTSTRAP_SERVER = 'bootstrapServer'; -export const LWM2M_SERVER = 'lwm2mServer'; export const LEN_MAX_PSK = 64; export const LEN_MAX_PRIVATE_KEY = 134; export const LEN_MAX_PUBLIC_KEY_RPK = 182; @@ -28,28 +25,28 @@ export const KEY_REGEXP_HEX_DEC = /^[-+]?[0-9A-Fa-f]+\.?[0-9A-Fa-f]*?$/; export interface DeviceCredentialsDialogLwm2mData { - jsonAllConfig?: SecurityConfigModels; + jsonAllConfig?: Lwm2mSecurityConfigModels; endPoint?: string; } -export enum SECURITY_CONFIG_MODE { +export enum Lwm2mSecurityType { PSK = 'PSK', RPK = 'RPK', X509 = 'X509', NO_SEC = 'NO_SEC' } -export const SECURITY_CONFIG_MODE_NAMES = new Map( +export const Lwm2mSecurityTypeTranslationMap = new Map( [ - [SECURITY_CONFIG_MODE.PSK, 'Pre-Shared Key'], - [SECURITY_CONFIG_MODE.RPK, 'Raw Public Key'], - [SECURITY_CONFIG_MODE.X509, 'X.509 Certificate'], - [SECURITY_CONFIG_MODE.NO_SEC, 'No Security'], + [Lwm2mSecurityType.PSK, 'Pre-Shared Key'], + [Lwm2mSecurityType.RPK, 'Raw Public Key'], + [Lwm2mSecurityType.X509, 'X.509 Certificate'], + [Lwm2mSecurityType.NO_SEC, 'No Security'], ] ); export interface ClientSecurityConfig { - securityConfigClientMode: string; + securityConfigClientMode: Lwm2mSecurityType; endpoint: string; identity: string; key: string; @@ -57,7 +54,7 @@ export interface ClientSecurityConfig { } export interface ServerSecurityConfig { - securityMode: string; + securityMode: Lwm2mSecurityType; clientPublicKeyOrId?: string; clientSecretKey?: string; } @@ -67,20 +64,19 @@ interface BootstrapSecurityConfig { lwm2mServer: ServerSecurityConfig; } -export interface SecurityConfigModels { +export interface Lwm2mSecurityConfigModels { client: ClientSecurityConfig; bootstrap: BootstrapSecurityConfig; } -export function getClientSecurityConfig(securityConfigMode: SECURITY_CONFIG_MODE, endPoint?: string): ClientSecurityConfig { - let security = getDefaultClientSecurityConfig(); - security.securityConfigClientMode = securityConfigMode.toString(); +export function getClientSecurityConfig(securityConfigMode: Lwm2mSecurityType, endPoint = ''): ClientSecurityConfig { + const security = getDefaultClientSecurityConfig(securityConfigMode); switch (securityConfigMode) { - case SECURITY_CONFIG_MODE.PSK: + case Lwm2mSecurityType.PSK: security.endpoint = endPoint; security.identity = endPoint; break; - case SECURITY_CONFIG_MODE.X509: + case Lwm2mSecurityType.X509: security.x509 = true; break; } @@ -88,9 +84,9 @@ export function getClientSecurityConfig(securityConfigMode: SECURITY_CONFIG_MODE return security; } -export function getDefaultClientSecurityConfig(): ClientSecurityConfig { +export function getDefaultClientSecurityConfig(securityConfigMode: Lwm2mSecurityType): ClientSecurityConfig { return { - securityConfigClientMode: SECURITY_CONFIG_MODE.NO_SEC.toString(), + securityConfigClientMode: securityConfigMode, endpoint: '', identity: '', key: '', @@ -100,7 +96,7 @@ export function getDefaultClientSecurityConfig(): ClientSecurityConfig { export function getDefaultServerSecurityConfig(): ServerSecurityConfig { return { - securityMode: SECURITY_CONFIG_MODE.NO_SEC.toString(), + securityMode: Lwm2mSecurityType.NO_SEC, clientPublicKeyOrId: '', clientSecretKey: '' }; @@ -113,46 +109,42 @@ function getDefaultBootstrapSecurityConfig(): BootstrapSecurityConfig { }; } -export function getDefaultSecurityConfig(): SecurityConfigModels { +export function getDefaultSecurityConfig(): Lwm2mSecurityConfigModels { const securityConfigModels = { - client: getClientSecurityConfig(SECURITY_CONFIG_MODE.NO_SEC), + client: getClientSecurityConfig(Lwm2mSecurityType.NO_SEC), bootstrap: getDefaultBootstrapSecurityConfig() }; return securityConfigModels; } -const isSecurityConfigModels = (p: any): p is SecurityConfigModels => +const isSecurityConfigModels = (p: any): boolean => p.hasOwnProperty('client') && - isClientSecurityConfigType(p['client']) && + isClientSecurityConfigType(p.client) && p.hasOwnProperty('bootstrap') && - isBootstrapSecurityConfig(p['bootstrap']); + isBootstrapSecurityConfig(p.bootstrap); -const isClientSecurityConfigType = (p: any): p is ClientSecurityConfig => +const isClientSecurityConfigType = (p: any): boolean => p.hasOwnProperty('securityConfigClientMode') && p.hasOwnProperty('endpoint') && p.hasOwnProperty('identity') && p.hasOwnProperty('key') && p.hasOwnProperty('x509'); -const isBootstrapSecurityConfig = (p: any): p is BootstrapSecurityConfig => +const isBootstrapSecurityConfig = (p: any): boolean => p.hasOwnProperty('bootstrapServer') && - isServerSecurityConfig(p['bootstrapServer']) && + isServerSecurityConfig(p.bootstrapServer) && p.hasOwnProperty('lwm2mServer') && - isServerSecurityConfig(p['lwm2mServer']); + isServerSecurityConfig(p.lwm2mServer); -const isServerSecurityConfig = (p: any): p is ServerSecurityConfig => +const isServerSecurityConfig = (p: any): boolean => p.hasOwnProperty('securityMode') && p.hasOwnProperty('clientPublicKeyOrId') && p.hasOwnProperty('clientSecretKey'); export function validateSecurityConfig(config: string): boolean { try { - const securityConfig= JSON.parse(config); - if (isSecurityConfigModels(securityConfig)) { - return true; - } else { - return false; - } + const securityConfig = JSON.parse(config); + return isSecurityConfigModels(securityConfig); } catch (e) { return false; } diff --git a/ui-ngx/src/assets/locale/locale.constant-en_US.json b/ui-ngx/src/assets/locale/locale.constant-en_US.json index 08335a0175..bd7ec5e2a2 100644 --- a/ui-ngx/src/assets/locale/locale.constant-en_US.json +++ b/ui-ngx/src/assets/locale/locale.constant-en_US.json @@ -928,9 +928,13 @@ "lwm2m-credentials-value-tip": "Edit security config json editor", "lwm2m-security-config": { "identity": "Client Identity", + "identity-required": "Client Identity is required.", "client-key": "Client Key", - "required": " value is required.", + "client-key-required": "Client Key is required.", + "client-key-pattern": "Client Key must be hexadecimal format.", + "client-key-length": "Client Key must be {{ count }} characters.", "endpoint": "Endpoint Client Name", + "endpoint-required": "Endpoint Client Name is required.", "mode": "Security config mode", "client-tab": "Client Security Config", "client-certificate": "Client certificate", @@ -938,9 +942,14 @@ "bootstrap-server": "Bootstrap Server", "lwm2m-server": "LwM2M Server", "client-publicKey-or-id": "Client Public Key or Id", + "client-publicKey-or-id-required": "Client Public Key or Id is required.", + "client-publicKey-or-id-pattern": "Client Public Key or Id must be hexadecimal format.", + "client-publicKey-or-id-length": "Client Public Key or Id must be {{ count }} characters.", "client-secret-key": "Client Secret Key", - "config-json-tab": "Json Client Security Config", - "pattern_hex_dec": "{ count, plural, 0 {must be hex decimal format} other {must be # characters} }" + "client-secret-key-required": "Client Secret Key is required.", + "client-secret-key-pattern": "Client Secret Key must be hexadecimal format.", + "client-secret-key-length": "Client Secret Key must be {{ count }} characters.", + "config-json-tab": "Json Client Security Config" }, "client-id": "Client ID", "client-id-pattern": "Contains invalid character.",