Browse Source

Lwm2m: front: refactoring

pull/3980/head
nickAS21 6 years ago
parent
commit
cfa9a5778a
  1. 27
      ui-ngx/src/app/modules/home/components/profile/device/lwm2m/lwm2m-device-config-server.component.html
  2. 76
      ui-ngx/src/app/modules/home/components/profile/device/lwm2m/lwm2m-device-config-server.component.ts
  3. 218
      ui-ngx/src/app/modules/home/components/profile/device/lwm2m/lwm2m-device-profile-transport-configuration.component.html
  4. 132
      ui-ngx/src/app/modules/home/components/profile/device/lwm2m/lwm2m-device-profile-transport-configuration.component.ts
  5. 68
      ui-ngx/src/app/modules/home/components/profile/device/lwm2m/lwm2m-object-add-instances-list.component.ts
  6. 2
      ui-ngx/src/app/modules/home/components/profile/device/lwm2m/lwm2m-object-add-instances.component.html
  7. 6
      ui-ngx/src/app/modules/home/components/profile/device/lwm2m/lwm2m-object-add-instances.component.ts
  8. 82
      ui-ngx/src/app/modules/home/components/profile/device/lwm2m/lwm2m-object-list.component.ts
  9. 41
      ui-ngx/src/app/modules/home/components/profile/device/lwm2m/lwm2m-observe-attr-telemetry-resource.component.ts
  10. 153
      ui-ngx/src/app/modules/home/components/profile/device/lwm2m/lwm2m-observe-attr-telemetry.component.ts
  11. 108
      ui-ngx/src/app/modules/home/components/profile/device/lwm2m/profile-config.models.ts
  12. 3
      ui-ngx/src/app/modules/home/pages/device/device.module.ts
  13. 57
      ui-ngx/src/app/modules/home/pages/device/lwm2m/security-config-server.component.html
  14. 62
      ui-ngx/src/app/modules/home/pages/device/lwm2m/security-config-server.component.ts
  15. 206
      ui-ngx/src/app/modules/home/pages/device/lwm2m/security-config.component.html
  16. 185
      ui-ngx/src/app/modules/home/pages/device/lwm2m/security-config.component.ts
  17. 54
      ui-ngx/src/app/modules/home/pages/device/lwm2m/security-config.models.ts
  18. 6
      ui-ngx/src/app/shared/components/json-object-edit.component.ts
  19. 10
      ui-ngx/src/assets/locale/locale.constant-en_US.json

27
ui-ngx/src/app/modules/home/components/profile/device/lwm2m/lwm2m-device-config-server.component.html

@ -90,9 +90,14 @@
serverFormGroup.get('securityMode').value === securityConfigLwM2MType.X509">
<mat-form-field class="mat-block">
<mat-label>{{ 'device-profile.lwm2m.server-public-key' | translate }}</mat-label>
<textarea matInput type="text" rows="3" cols="1" required
formControlName="serverPublicKey" #serverPublicKey
<textarea matInput
#serverPublicKey
maxlength="{{lenMaxServerPublicKey}}"
cdkTextareaAutosize
cdkAutosizeMinRows="1"
cols="1" required
style="overflow:hidden"
formControlName="serverPublicKey"
matTooltip="{{'device-profile.lwm2m.server-public-key-tip' | translate}}"
></textarea>
<mat-hint align="end">{{serverPublicKey.value?.length || 0}}/{{lenMaxServerPublicKey}}</mat-hint>
@ -101,14 +106,18 @@
<strong>{{ 'device-profile.lwm2m.required' | translate }}</strong>
</mat-error>
<mat-error *ngIf="serverFormGroup.get('serverPublicKey').hasError('pattern') &&
serverFormGroup.get('securityMode').value === securityConfigLwM2MType.RPK">
{{ 'device-profile.lwm2m.client-key' | translate }}
<strong>{{ 'device-profile.lwm2m.pattern_hex_dec_182' | translate }}</strong>
(serverFormGroup.get('securityMode').value === securityConfigLwM2MType.RPK ||
serverFormGroup.get('securityMode').value === securityConfigLwM2MType.X509)">
{{ 'device-profile.lwm2m.server-public-key' | translate }}
<strong>{{ translate.get('device-profile.lwm2m.pattern_hex_dec', {
count: 0}) | async }}</strong>
</mat-error>
<mat-error *ngIf="serverFormGroup.get('serverPublicKey').hasError('pattern') &&
serverFormGroup.get('securityMode').value === securityConfigLwM2MType.X509">
{{ 'device-profile.lwm2m.client-key' | translate }}
<strong>{{ 'device-profile.lwm2m.pattern_hex_dec' | translate }}</strong>
<mat-error *ngIf="(serverFormGroup.get('serverPublicKey').hasError('maxlength') ||
serverFormGroup.get('serverPublicKey').hasError('minlength')) &&
serverFormGroup.get('securityMode').value === securityConfigLwM2MType.RPK">
{{ 'device-profile.lwm2m.server-public-key' | translate }}
<strong>{{ translate.get('device-profile.lwm2m.pattern_hex_dec', {
count: lenMaxServerPublicKey }) | async }}</strong>
</mat-error>
</mat-form-field>
</div>

76
ui-ngx/src/app/modules/home/components/profile/device/lwm2m/lwm2m-device-config-server.component.ts

@ -14,31 +14,28 @@
/// limitations under the License.
///
import { Component, forwardRef, Inject, Input, OnInit } from "@angular/core";
import { Component, forwardRef, Inject, Input, OnInit } from '@angular/core';
import {
ControlValueAccessor,
FormBuilder, FormGroup, NG_VALUE_ACCESSOR, NgModel, Validators
} from "@angular/forms";
FormBuilder, FormGroup, NG_VALUE_ACCESSOR, Validators
} from '@angular/forms';
import {
SECURITY_CONFIG_MODE,
SECURITY_CONFIG_MODE_NAMES,
KEY_PUBLIC_REGEXP_PSK,
ServerSecurityConfig,
LEN_MAX_PUBLIC_KEY_PSK,
LEN_MAX_PUBLIC_KEY_RPK_X509,
KEY_PUBLIC_REGEXP_X509,
DEFAULT_PORT_BOOTSTRAP_NO_SEC,
DEFAULT_PORT_SERVER_NO_SEC,
DEFAULT_CLIENT_HOLD_OFF_TIME,
DEFAULT_ID_SERVER
} from "./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";
DEFAULT_ID_SERVER, LEN_MAX_PUBLIC_KEY_RPK, LEN_MAX_PUBLIC_KEY_X509, KEY_REGEXP_HEX_DEC
} from './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 { TranslateService } from '@ngx-translate/core';
@Component({
selector: 'tb-profile-lwm2m-device-config-server',
@ -55,12 +52,14 @@ import { DeviceProfileService } from '@core/http/device-profile.service';
export class Lwm2mDeviceConfigServerComponent implements OnInit, ControlValueAccessor, Validators {
private requiredValue: boolean;
valuePrev = null;
serverFormGroup: FormGroup;
securityConfigLwM2MType = SECURITY_CONFIG_MODE;
securityConfigLwM2MTypes = Object.keys(SECURITY_CONFIG_MODE);
credentialTypeLwM2MNamesMap = SECURITY_CONFIG_MODE_NAMES;
lenMaxServerPublicKey = LEN_MAX_PUBLIC_KEY_PSK;
lenMinServerPublicKey = 0;
lenMaxServerPublicKey = LEN_MAX_PUBLIC_KEY_RPK;
currentSecurityMode = null;
@ -80,6 +79,7 @@ export class Lwm2mDeviceConfigServerComponent implements OnInit, ControlValueAcc
}
constructor(protected store: Store<AppState>,
public translate: TranslateService,
public fb: FormBuilder,
private deviceProfileService: DeviceProfileService,
@Inject(WINDOW) private window: Window) {
@ -105,7 +105,7 @@ export class Lwm2mDeviceConfigServerComponent implements OnInit, ControlValueAcc
ngOnInit(): void {
}
updateValueFields(serverData: ServerSecurityConfig): void {
private updateValueFields = (serverData: ServerSecurityConfig): void => {
serverData.bootstrapServerIs = this.bootstrapServerIs;
this.serverFormGroup.patchValue(serverData, {emitEvent: false});
this.serverFormGroup.get('bootstrapServerIs').disable();
@ -113,40 +113,38 @@ export class Lwm2mDeviceConfigServerComponent implements OnInit, ControlValueAcc
this.updateValidate(securityMode);
}
updateValidate(securityMode: SECURITY_CONFIG_MODE): void {
private updateValidate = (securityMode: SECURITY_CONFIG_MODE): void => {
switch (securityMode) {
case SECURITY_CONFIG_MODE.NO_SEC:
this.serverFormGroup.get('serverPublicKey').setValidators([]);
this.setValidatorsNoSecPsk();
break;
case SECURITY_CONFIG_MODE.PSK:
this.lenMaxServerPublicKey = LEN_MAX_PUBLIC_KEY_PSK;
this.serverFormGroup.get('serverPublicKey').setValidators([]);
this.setValidatorsNoSecPsk();
break;
case SECURITY_CONFIG_MODE.RPK:
this.lenMaxServerPublicKey = LEN_MAX_PUBLIC_KEY_RPK_X509;
this.serverFormGroup.get('serverPublicKey').setValidators([Validators.required, Validators.pattern(KEY_PUBLIC_REGEXP_PSK)]);
this.lenMinServerPublicKey = LEN_MAX_PUBLIC_KEY_RPK;
this.lenMaxServerPublicKey = LEN_MAX_PUBLIC_KEY_RPK;
this.setValidatorsRpkX509();
break;
case SECURITY_CONFIG_MODE.X509:
this.lenMaxServerPublicKey = LEN_MAX_PUBLIC_KEY_RPK_X509;
this.serverFormGroup.get('serverPublicKey').setValidators([Validators.required, Validators.pattern(KEY_PUBLIC_REGEXP_X509)]);
this.lenMinServerPublicKey = 0;
this.lenMaxServerPublicKey = LEN_MAX_PUBLIC_KEY_X509;
this.setValidatorsRpkX509();
break;
}
this.serverFormGroup.updateValueAndValidity();
// this.checkValueWithNewValidate();
}
// checkValueWithNewValidate(): void {
// this.serverFormGroup.patchValue({
// host: this.serverFormGroup.get('host').value,
// port: this.serverFormGroup.get('port').value,
// bootstrapServerIs: this.serverFormGroup.get('bootstrapServerIs').value,
// serverPublicKey: this.serverFormGroup.get('serverPublicKey').value,
// clientHoldOffTime: this.serverFormGroup.get('clientHoldOffTime').value,
// serverId: this.serverFormGroup.get('serverId').value,
// bootstrapServerAccountTimeout: this.serverFormGroup.get('bootstrapServerAccountTimeout').value,
// },
// {emitEvent: true});
// }
private setValidatorsNoSecPsk = (): void => {
this.serverFormGroup.get('serverPublicKey').setValidators([]);
}
private setValidatorsRpkX509 = (): void => {
this.serverFormGroup.get('serverPublicKey').setValidators([Validators.required,
Validators.pattern(KEY_REGEXP_HEX_DEC),
Validators.minLength(this.lenMinServerPublicKey),
Validators.maxLength(this.lenMaxServerPublicKey)]);
}
writeValue(value: any): void {
if (value) {
@ -160,7 +158,7 @@ export class Lwm2mDeviceConfigServerComponent implements OnInit, ControlValueAcc
this.propagateChange = fn;
}
private propagateChangeState(value: any): void {
private propagateChangeState = (value: any): void => {
if (value !== undefined) {
if (this.valuePrev === null) {
this.valuePrev = 'init';
@ -190,7 +188,7 @@ export class Lwm2mDeviceConfigServerComponent implements OnInit, ControlValueAcc
registerOnTouched(fn: any): void {
}
getServerGroup(): FormGroup {
private getServerGroup = (): FormGroup => {
const port = this.bootstrapServerIs ? DEFAULT_PORT_BOOTSTRAP_NO_SEC : DEFAULT_PORT_SERVER_NO_SEC;
return this.fb.group({
host: [this.window.location.hostname, this.required ? [Validators.required] : []],
@ -204,7 +202,7 @@ export class Lwm2mDeviceConfigServerComponent implements OnInit, ControlValueAcc
});
}
getLwm2mBootstrapSecurityInfo(mode: string) {
private getLwm2mBootstrapSecurityInfo = (mode: string): void => {
this.deviceProfileService.getLwm2mBootstrapSecurityInfo(mode, this.serverFormGroup.get('bootstrapServerIs').value).subscribe(
(serverSecurityConfig) => {
this.serverFormGroup.patchValue({

218
ui-ngx/src/app/modules/home/components/profile/device/lwm2m/lwm2m-device-profile-transport-configuration.component.html

@ -19,118 +19,126 @@
<div mat-dialog-content>
<mat-tab-group dynamicHeight>
<mat-tab label="{{ 'device-profile.lwm2m.model-tab' | translate }}">
<div class="mat-padding">
<tb-profile-lwm2m-object-list
(addList)="addObjectsList($event)"
(removeList)="removeObjectsList($event)"
[required]="required"
formControlName="objectIds">
</tb-profile-lwm2m-object-list>
</div>
<div class="mat-padding">
<tb-profile-lwm2m-observe-attr-telemetry
[required]="required"
formControlName="observeAttrTelemetry">
</tb-profile-lwm2m-observe-attr-telemetry>
</div>
<ng-template matTabContent>
<div class="mat-padding">
<tb-profile-lwm2m-object-list
(addList)="addObjectsList($event)"
(removeList)="removeObjectsList($event)"
[required]="required"
formControlName="objectIds">
</tb-profile-lwm2m-object-list>
</div>
<div class="mat-padding">
<tb-profile-lwm2m-observe-attr-telemetry
[required]="required"
formControlName="observeAttrTelemetry">
</tb-profile-lwm2m-observe-attr-telemetry>
</div>
</ng-template>
</mat-tab>
<mat-tab label="{{ 'device-profile.lwm2m.bootstrap-tab' | translate }}">
<div class="mat-padding">
<mat-accordion multi="true" class="mat-body-1">
<mat-expansion-panel>
<mat-expansion-panel-header>
<mat-panel-title>
<div class="tb-panel-title">{{ 'device-profile.lwm2m.servers' | translate | uppercase }}</div>
</mat-panel-title>
</mat-expansion-panel-header>
<div fxLayout="column">
<div fxLayout="row" fxLayoutGap="8px">
<mat-form-field fxFlex>
<mat-label>{{ 'device-profile.lwm2m.short-id' | translate }}</mat-label>
<input matInput type="number" formControlName="shortId" required>
<mat-error *ngIf="lwm2mDeviceProfileTransportConfFormGroup.get('shortId').hasError('required')">
{{ 'device-profile.lwm2m.short-id' | translate }}
<strong>{{ 'device-profile.lwm2m.required' | translate }}</strong>
</mat-error>
</mat-form-field>
<mat-form-field fxFlex>
<mat-label>{{ 'device-profile.lwm2m.lifetime' | translate }}</mat-label>
<input matInput type="number" formControlName="lifetime" required>
<mat-error *ngIf="lwm2mDeviceProfileTransportConfFormGroup.get('lifetime').hasError('required')">
{{ 'device-profile.lwm2m.lifetime' | translate }}
<strong>{{ 'device-profile.lwm2m.required' | translate }}</strong>
</mat-error>
</mat-form-field>
<ng-template matTabContent>
<div class="mat-padding">
<mat-accordion multi="true" class="mat-body-1">
<mat-expansion-panel>
<mat-expansion-panel-header>
<mat-panel-title>
<div class="tb-panel-title">{{ 'device-profile.lwm2m.servers' | translate | uppercase }}</div>
</mat-panel-title>
</mat-expansion-panel-header>
<div fxLayout="column">
<div fxLayout="row" fxLayoutGap="8px">
<mat-form-field fxFlex>
<mat-label>{{ 'device-profile.lwm2m.short-id' | translate }}</mat-label>
<input matInput type="number" formControlName="shortId" required>
<mat-error *ngIf="lwm2mDeviceProfileTransportConfFormGroup.get('shortId').hasError('required')">
{{ 'device-profile.lwm2m.short-id' | translate }}
<strong>{{ 'device-profile.lwm2m.required' | translate }}</strong>
</mat-error>
</mat-form-field>
<mat-form-field fxFlex>
<mat-label>{{ 'device-profile.lwm2m.lifetime' | translate }}</mat-label>
<input matInput type="number" formControlName="lifetime" required>
<mat-error *ngIf="lwm2mDeviceProfileTransportConfFormGroup.get('lifetime').hasError('required')">
{{ 'device-profile.lwm2m.lifetime' | translate }}
<strong>{{ 'device-profile.lwm2m.required' | translate }}</strong>
</mat-error>
</mat-form-field>
</div>
<div fxLayout="row" fxLayoutGap="8px">
<mat-form-field fxFlex>
<mat-label>{{ 'device-profile.lwm2m.default-min-period' | translate }}</mat-label>
<input matInput type="number" formControlName="defaultMinPeriod" required>
<mat-error
*ngIf="lwm2mDeviceProfileTransportConfFormGroup.get('defaultMinPeriod').hasError('required')">
{{ 'device-profile.lwm2m.default-min-period' | translate }}
<strong>{{ 'device-profile.lwm2m.required' | translate }}</strong>
</mat-error>
</mat-form-field>
<mat-form-field fxFlex>
<mat-label>{{ 'device-profile.lwm2m.binding' | translate }}</mat-label>
<input matInput type="text" formControlName="binding" required>
<mat-error *ngIf="lwm2mDeviceProfileTransportConfFormGroup.get('binding').hasError('required')">
{{ 'device-profile.lwm2m.binding' | translate }}
<strong>{{ 'device-profile.lwm2m.required' | translate }}</strong>
</mat-error>
</mat-form-field>
</div>
<div>
<mat-checkbox formControlName="notifIfDisabled" color="primary">
{{ 'device-profile.lwm2m.notif-if-disabled' | translate }}
</mat-checkbox>
</div>
</div>
<div fxLayout="row" fxLayoutGap="8px">
<mat-form-field fxFlex>
<mat-label>{{ 'device-profile.lwm2m.default-min-period' | translate }}</mat-label>
<input matInput type="number" formControlName="defaultMinPeriod" required>
<mat-error *ngIf="lwm2mDeviceProfileTransportConfFormGroup.get('defaultMinPeriod').hasError('required')">
{{ 'device-profile.lwm2m.default-min-period' | translate }}
<strong>{{ 'device-profile.lwm2m.required' | translate }}</strong>
</mat-error>
</mat-form-field>
<mat-form-field fxFlex>
<mat-label>{{ 'device-profile.lwm2m.binding' | translate }}</mat-label>
<input matInput type="text" formControlName="binding" required>
<mat-error *ngIf="lwm2mDeviceProfileTransportConfFormGroup.get('binding').hasError('required')">
{{ 'device-profile.lwm2m.binding' | translate }}
<strong>{{ 'device-profile.lwm2m.required' | translate }}</strong>
</mat-error>
</mat-form-field>
</mat-expansion-panel>
</mat-accordion>
<mat-accordion multi="true" class="mat-body-1">
<mat-expansion-panel>
<mat-expansion-panel-header>
<mat-panel-title>
<div
class="tb-panel-title">{{ 'device-profile.lwm2m.bootstrap-server' | translate | uppercase }}</div>
</mat-panel-title>
</mat-expansion-panel-header>
<div class="mat-padding">
<tb-profile-lwm2m-device-config-server
[required]="required"
formControlName="bootstrapServer"
[bootstrapServerIs]=true>
</tb-profile-lwm2m-device-config-server>
</div>
<div>
<mat-checkbox formControlName="notifIfDisabled" color="primary">
{{ 'device-profile.lwm2m.notif-if-disabled' | translate }}
</mat-checkbox>
</mat-expansion-panel>
</mat-accordion>
<mat-accordion multi="true" class="mat-body-1">
<mat-expansion-panel>
<mat-expansion-panel-header>
<mat-panel-title>
<div class="tb-panel-title">{{ 'device-profile.lwm2m.lwm2m-server' | translate | uppercase }}</div>
</mat-panel-title>
</mat-expansion-panel-header>
<div class="mat-padding">
<tb-profile-lwm2m-device-config-server
[required]="required"
formControlName="lwm2mServer"
[bootstrapServerIs]=false>
</tb-profile-lwm2m-device-config-server>
</div>
</div>
</mat-expansion-panel>
</mat-accordion>
<mat-accordion multi="true" class="mat-body-1">
<mat-expansion-panel>
<mat-expansion-panel-header>
<mat-panel-title>
<div class="tb-panel-title">{{ 'device-profile.lwm2m.bootstrap-server' | translate | uppercase }}</div>
</mat-panel-title>
</mat-expansion-panel-header>
<div class="mat-padding">
<tb-profile-lwm2m-device-config-server
[required]="required"
formControlName = "bootstrapServer"
[bootstrapServerIs]=true>
</tb-profile-lwm2m-device-config-server>
</div>
</mat-expansion-panel>
</mat-accordion>
<mat-accordion multi="true" class="mat-body-1">
<mat-expansion-panel>
<mat-expansion-panel-header>
<mat-panel-title>
<div class="tb-panel-title">{{ 'device-profile.lwm2m.lwm2m-server' | translate | uppercase }}</div>
</mat-panel-title>
</mat-expansion-panel-header>
<div class="mat-padding">
<tb-profile-lwm2m-device-config-server
[required]="required"
formControlName="lwm2mServer"
[bootstrapServerIs]=false>
</tb-profile-lwm2m-device-config-server>
</div>
</mat-expansion-panel>
</mat-accordion>
</div>
</mat-expansion-panel>
</mat-accordion>
</div>
</ng-template>
</mat-tab>
<mat-tab label="{{ 'device-profile.lwm2m.config-json-tab' | translate }}">
<div class="mat-padding">
<tb-json-object-edit
[required]="required"
[sort] = "sortFunction"
label="{{ 'device-profile.transport-type-lwm2m' | translate }}"
formControlName="configurationJson">
</tb-json-object-edit>
</div>
<ng-template matTabContent>
<div class="mat-padding">
<tb-json-object-edit
[required]="required"
[sort]="sortFunction"
label="{{ 'device-profile.transport-type-lwm2m' | translate }}"
formControlName="configurationJson">
</tb-json-object-edit>
</div>
</ng-template>
</mat-tab>
</mat-tab-group>
</div>

132
ui-ngx/src/app/modules/home/components/profile/device/lwm2m/lwm2m-device-profile-transport-configuration.component.ts

@ -34,10 +34,10 @@ import {
OBSERVE_ATTR,
TELEMETRY,
ObjectLwM2M, getDefaultProfileConfig, KEY_NAME, Instance, ProfileConfigModels, ResourceLwM2M
} from "./profile-config.models";
import { DeviceProfileService } from "@core/http/device-profile.service";
import { deepClone, isUndefined } from "@core/utils";
import { WINDOW } from "@core/services/window.service";
} from './profile-config.models';
import { DeviceProfileService } from '@core/http/device-profile.service';
import { deepClone, isUndefined } from '@core/utils';
import { WINDOW } from '@core/services/window.service';
import { JsonObject } from '@angular/compiler-cli/ngcc/src/packages/entry_point';
import { isNotNullOrUndefined } from 'codelyzer/util/isNotNullOrUndefined';
@ -65,7 +65,7 @@ export class Lwm2mDeviceProfileTransportConfigurationComponent implements Contro
bootstrapServers: string;
bootstrapServer: string;
lwm2mServer: string;
sortFunction = this.sortObjectKeyPathJson;
sortFunction: {};
get required(): boolean {
return this.requiredValue;
@ -76,7 +76,7 @@ export class Lwm2mDeviceProfileTransportConfigurationComponent implements Contro
this.requiredValue = coerceBooleanProperty(value);
}
private propagateChange = (v: any) => { };
private propagateChange = (v: any) => { };
constructor(private store: Store<AppState>,
private fb: FormBuilder,
@ -109,6 +109,7 @@ export class Lwm2mDeviceProfileTransportConfigurationComponent implements Contro
}
ngOnInit() {
this.sortFunction = this.sortObjectKeyPathJson;
}
setDisabledState(isDisabled: boolean): void {
@ -130,22 +131,22 @@ export class Lwm2mDeviceProfileTransportConfigurationComponent implements Contro
this.initWriteValue();
}
private initWriteValue(): void {
private initWriteValue = (): void => {
const modelValue = {objectIds: null, objectsList: []};
modelValue.objectIds = this.getObjectsFromJsonAllConfig();
if (modelValue.objectIds !== null) {
this.deviceProfileService.getLwm2mObjects(modelValue.objectIds).subscribe(
(objectsList) => {
modelValue.objectsList = objectsList;
this.updateWriteValue(modelValue);
}
(objectsList) => {
modelValue.objectsList = objectsList;
this.updateWriteValue(modelValue);
}
);
} else {
this.updateWriteValue(modelValue);
}
}
private updateWriteValue(value: any): void {
private updateWriteValue = (value: any): void => {
const objectsList = deepClone(value.objectsList);
this.lwm2mDeviceProfileTransportConfFormGroup.patchValue({
objectIds: value,
@ -161,7 +162,7 @@ export class Lwm2mDeviceProfileTransportConfigurationComponent implements Contro
{emitEvent: false});
}
private updateModel() {
private updateModel = (): void => {
let configuration: DeviceProfileTransportConfiguration = null;
if (this.lwm2mDeviceProfileTransportConfFormGroup.valid) {
this.upDateValueToJson();
@ -171,25 +172,25 @@ export class Lwm2mDeviceProfileTransportConfigurationComponent implements Contro
this.propagateChange(configuration);
}
private updateObserveAttrTelemetryObjectFormGroup(objectsList: ObjectLwM2M[]) {
private updateObserveAttrTelemetryObjectFormGroup = (objectsList: ObjectLwM2M[]): void => {
this.lwm2mDeviceProfileTransportConfFormGroup.patchValue({
observeAttrTelemetry: {clientLwM2M: this.getObserveAttrTelemetryObjects(objectsList)}
},
{emitEvent: false});
observeAttrTelemetry: {clientLwM2M: this.getObserveAttrTelemetryObjects(objectsList)}
},
{emitEvent: false});
this.lwm2mDeviceProfileTransportConfFormGroup.get('observeAttrTelemetry').markAsPristine({
onlySelf: true
});
}
upDateValueToJson(): void {
this.upDateValueToJsonTab_0();
this.upDateValueToJsonTab_1();
private upDateValueToJson = (): void => {
this.upDateValueToJsonTab0();
this.upDateValueToJsonTab1();
}
upDateValueToJsonTab_0(): void {
private upDateValueToJsonTab0 = (): void => {
if (!this.lwm2mDeviceProfileTransportConfFormGroup.get('observeAttrTelemetry').pristine) {
this.upDateObserveAttrTelemetryFromGroupToJson(
this.lwm2mDeviceProfileTransportConfFormGroup.get('observeAttrTelemetry').value.clientLwM2M
this.lwm2mDeviceProfileTransportConfFormGroup.get('observeAttrTelemetry').value.clientLwM2M
);
this.lwm2mDeviceProfileTransportConfFormGroup.get('observeAttrTelemetry').markAsPristine({
onlySelf: true
@ -198,7 +199,7 @@ export class Lwm2mDeviceProfileTransportConfigurationComponent implements Contro
}
}
upDateValueToJsonTab_1(): void {
private upDateValueToJsonTab1 = (): void => {
this.upDateValueServersToJson();
if (!this.lwm2mDeviceProfileTransportConfFormGroup.get('bootstrapServer').pristine) {
this.configurationValue.bootstrap.bootstrapServer = this.lwm2mDeviceProfileTransportConfFormGroup.get('bootstrapServer').value;
@ -216,7 +217,7 @@ export class Lwm2mDeviceProfileTransportConfigurationComponent implements Contro
}
}
upDateValueServersToJson(): void {
private upDateValueServersToJson = (): void => {
const bootstrapServers = this.configurationValue.bootstrap.servers;
if (!this.lwm2mDeviceProfileTransportConfFormGroup.get('shortId').pristine) {
bootstrapServers.shortId = this.lwm2mDeviceProfileTransportConfFormGroup.get('shortId').value;
@ -255,7 +256,7 @@ export class Lwm2mDeviceProfileTransportConfigurationComponent implements Contro
}
}
getObserveAttrTelemetryObjects(listObject: ObjectLwM2M[]): ObjectLwM2M [] {
private getObserveAttrTelemetryObjects = (listObject: ObjectLwM2M[]): ObjectLwM2M [] => {
const clientObserveAttr = deepClone(listObject);
if (this.configurationValue[this.observeAttr]) {
const observeArray = this.configurationValue[this.observeAttr][this.observe] as Array<string>;
@ -284,12 +285,13 @@ export class Lwm2mDeviceProfileTransportConfigurationComponent implements Contro
return clientObserveAttr;
}
includesInstancesNo(attributeArray: Array<string>, telemetryArray: Array<string>): boolean {
private includesInstancesNo = (attributeArray: Array<string>, telemetryArray: Array<string>): boolean => {
const isIdIndex = (element) => !element.includes('/0/');
return attributeArray.findIndex(isIdIndex) >= 0 || telemetryArray.findIndex(isIdIndex) >= 0;
}
addInstances(attributeArray: Array<string>, telemetryArray: Array<string>, clientObserveAttr: ObjectLwM2M[]): void {
private addInstances = (attributeArray: Array<string>, telemetryArray: Array<string>,
clientObserveAttr: ObjectLwM2M[]): void => {
const attr = [] as Array<string>;
[...attributeArray].filter(x => (!x.includes('/0/'))).forEach(x => {
attr.push(this.convertPathToInstance(x));
@ -310,42 +312,43 @@ export class Lwm2mDeviceProfileTransportConfigurationComponent implements Contro
});
}
convertPathToInstance(path: string): string {
private convertPathToInstance = (path: string): string => {
const newX = Array.from(path.substring(1).split('/'), Number);
return [newX[0], newX[1]].join('/');
}
updateObserveAttrTelemetryObjects(isParameter: Array<string>, clientObserveAttr: ObjectLwM2M[], nameParameter: string): void {
private updateObserveAttrTelemetryObjects = (isParameter: Array<string>, clientObserveAttr: ObjectLwM2M[],
nameParameter: string): void => {
isParameter.forEach(attr => {
const idKeys = Array.from(attr.substring(1).split('/'), Number);
clientObserveAttr
.forEach(e => {
if (e.id === idKeys[0]) {
const instance = e.instances.find(itrInstance => itrInstance.id === idKeys[1]);
if (isNotNullOrUndefined(instance)) {
instance.resources.find(resource => resource.id === idKeys[2])[nameParameter] = true;
}
.forEach(e => {
if (e.id === idKeys[0]) {
const instance = e.instances.find(itrInstance => itrInstance.id === idKeys[1]);
if (isNotNullOrUndefined(instance)) {
instance.resources.find(resource => resource.id === idKeys[2])[nameParameter] = true;
}
});
}
});
});
}
updateKeyNameObjects(nameJson: JsonObject, clientObserveAttr: ObjectLwM2M[]): void {
private updateKeyNameObjects = (nameJson: JsonObject, clientObserveAttr: ObjectLwM2M[]): void => {
const keyName = JSON.parse(JSON.stringify(nameJson));
Object.keys(keyName).forEach(key => {
const idKeys = Array.from(key.substring(1).split('/'), Number);
clientObserveAttr
.forEach(e => {
if (e.id === idKeys[0]) {
e.instances
.find(instance => instance.id === idKeys[1]).resources
.find(resource => resource.id === idKeys[2]).keyName = keyName[key];
}
});
.forEach(e => {
if (e.id === idKeys[0]) {
e.instances
.find(instance => instance.id === idKeys[1]).resources
.find(resource => resource.id === idKeys[2]).keyName = keyName[key];
}
});
});
}
upDateObserveAttrTelemetryFromGroupToJson(val: ObjectLwM2M[]): void {
private upDateObserveAttrTelemetryFromGroupToJson = (val: ObjectLwM2M[]): void => {
const observeArray: Array<string> = [];
const attributeArray: Array<string> = [];
const telemetryArray: Array<string> = [];
@ -405,19 +408,22 @@ export class Lwm2mDeviceProfileTransportConfigurationComponent implements Contro
this.updateKeyName();
}
sortObjectKeyPathJson(key, value) {
sortObjectKeyPathJson = (key: string, value: object): object => {
if (key === 'keyName') {
return Object.keys(value).sort((a, b) => {
const aLC = Array.from(a.substring(1).split('/'), Number);
const bLC = Array.from(b.substring(1).split('/'), Number);
return aLC[0] === bLC[0] ? aLC[1] - bLC[1] : aLC[0] - bLC[0];
}).reduce((r, k) => r[k] = value[k], {});
}).reduce((obj, keySort) => {
obj[keySort] = value[keySort];
return obj;
}, {});
} else {
return value;
}
}
updateKeyName(): void {
private updateKeyName = (): void => {
const paths = new Set<string>();
if (this.configurationValue[this.observeAttr][this.attribute]) {
this.configurationValue[this.observeAttr][this.attribute].forEach(path => {
@ -431,20 +437,20 @@ export class Lwm2mDeviceProfileTransportConfigurationComponent implements Contro
}
const keyNameNew = {};
paths.forEach(path => {
const pathParameter = this.findIndexsForIds(path);
const pathParameter = this.findIndexesForIds(path);
if (pathParameter.length === 3) {
keyNameNew[path] = this.lwm2mDeviceProfileTransportConfFormGroup.get('observeAttrTelemetry').value
.clientLwM2M[pathParameter[0]].instances[pathParameter[1]].resources[pathParameter[2]][this.keyName];
.clientLwM2M[pathParameter[0]].instances[pathParameter[1]].resources[pathParameter[2]][this.keyName];
}
});
this.configurationValue[this.observeAttr][this.keyName] = this.sortObjectKeyPathJson('keyName', keyNameNew);
}
findIndexsForIds(path: string): number[] {
private findIndexesForIds = (path: string): number[] => {
const pathParameter = Array.from(path.substring(1).split('/'), Number);
const pathParameterIndexes: number[] = [];
const objectsOld = deepClone(
this.lwm2mDeviceProfileTransportConfFormGroup.get('observeAttrTelemetry').value.clientLwM2M) as ObjectLwM2M[];
this.lwm2mDeviceProfileTransportConfFormGroup.get('observeAttrTelemetry').value.clientLwM2M) as ObjectLwM2M[];
let isIdIndex = (element) => element.id === pathParameter[0];
const objIndex = objectsOld.findIndex(isIdIndex);
if (objIndex >= 0) {
@ -463,7 +469,7 @@ export class Lwm2mDeviceProfileTransportConfigurationComponent implements Contro
return pathParameterIndexes;
}
getObjectsFromJsonAllConfig(): number [] {
private getObjectsFromJsonAllConfig = (): number [] => {
const objectsIds = new Set<number>();
if (this.configurationValue[this.observeAttr]) {
if (this.configurationValue[this.observeAttr][this.observe]) {
@ -485,7 +491,7 @@ export class Lwm2mDeviceProfileTransportConfigurationComponent implements Contro
return (objectsIds.size > 0) ? Array.from(objectsIds) : null;
}
upDateJsonAllConfig(): void {
private upDateJsonAllConfig = (): void => {
this.lwm2mDeviceProfileTransportConfFormGroup.patchValue({
configurationJson: this.configurationValue
}, {emitEvent: false});
@ -494,11 +500,11 @@ export class Lwm2mDeviceProfileTransportConfigurationComponent implements Contro
});
}
addObjectsList(value: ObjectLwM2M[]): void {
addObjectsList = (value: ObjectLwM2M[]): void => {
this.updateObserveAttrTelemetryObjectFormGroup(deepClone(value));
}
removeObjectsList(value: ObjectLwM2M): void {
removeObjectsList = (value: ObjectLwM2M): void => {
const objectsOld = deepClone(this.lwm2mDeviceProfileTransportConfFormGroup.get('observeAttrTelemetry').value.clientLwM2M);
const isIdIndex = (element) => element.id === value.id;
const index = objectsOld.findIndex(isIdIndex);
@ -514,7 +520,7 @@ export class Lwm2mDeviceProfileTransportConfigurationComponent implements Contro
this.upDateJsonAllConfig();
}
removeObserveAttrTelemetryFromJson(observeAttrTel: string, id: number): void {
private removeObserveAttrTelemetryFromJson = (observeAttrTel: string, id: number): void => {
const isIdIndex = (element) => Array.from(element.substring(1).split('/'), Number)[0] === id;
let index = this.configurationValue[this.observeAttr][observeAttrTel].findIndex(isIdIndex);
while (index >= 0) {
@ -523,12 +529,12 @@ export class Lwm2mDeviceProfileTransportConfigurationComponent implements Contro
}
}
removeKeyNameFromJson(id: number): void {
const keyNmaeJson = this.configurationValue[this.observeAttr][this.keyName];
Object.keys(keyNmaeJson).forEach(key => {
private removeKeyNameFromJson = (id: number): void => {
const keyNameJson = this.configurationValue[this.observeAttr][this.keyName];
Object.keys(keyNameJson).forEach(key => {
const idKey = Array.from(key.substring(1).split('/'), Number)[0];
if (idKey === id) {
delete keyNmaeJson[key];
delete keyNameJson[key];
}
});
}
@ -538,10 +544,10 @@ export class Lwm2mDeviceProfileTransportConfigurationComponent implements Contro
if (!isPath) {
isPath = this.findPathInJson(path, this.telemetry);
}
return (isPath) ? true : false;
return !!isPath;
}
findPathInJson(path: string, side: string): string {
private findPathInJson = (path: string, side: string): string => {
if (this.configurationValue[this.observeAttr]) {
if (this.configurationValue[this.observeAttr][side]) {
return this.configurationValue[this.observeAttr][side].find(

68
ui-ngx/src/app/modules/home/components/profile/device/lwm2m/lwm2m-object-add-instances-list.component.ts

@ -21,44 +21,45 @@ import {
OnInit,
ViewChild,
ElementRef,
} from "@angular/core";
} 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";
} from '@angular/forms';
import { coerceBooleanProperty } from '@angular/cdk/coercion';
import { Store } from '@ngrx/store';
import { AppState } from '@core/core.state';
import { MatChipList } from '@angular/material/chips';
import {
INSTANCES_ID_VALUE_MAX,
INSTANCES_ID_VALUE_MIN
} from "./profile-config.models";
import { TranslateService } from "@ngx-translate/core";
import { DeviceProfileService } from "@core/http/device-profile.service";
} from './profile-config.models';
import { TranslateService } from '@ngx-translate/core';
import { DeviceProfileService } from '@core/http/device-profile.service';
@Component({
selector: 'tb-profile-lwm2m-object-add-instances-list',
templateUrl: './lwm2m-object-add-instances-list.component.html',
styleUrls: ['./lwm2m-object-add-instances-list.component.scss'],
providers: [{
provide: NG_VALUE_ACCESSOR,
useExisting: forwardRef(() => Lwm2mObjectAddInstancesListComponent),
multi: true
}]
provide: NG_VALUE_ACCESSOR,
useExisting: forwardRef(() => Lwm2mObjectAddInstancesListComponent),
multi: true
}]
})
export class Lwm2mObjectAddInstancesListComponent implements ControlValueAccessor, OnInit, Validators {
lwm2mObjectListFormGroup: FormGroup;
private requiredValue: boolean;
private instancesIdsList: Set<number> | null;
filteredObjectsList: Array<number>;
private disabled = false as boolean;
private dirty = false as boolean;
instanceIdValueMin = INSTANCES_ID_VALUE_MIN as number
instanceIdValueMax = INSTANCES_ID_VALUE_MAX as number
lwm2mObjectListFormGroup: FormGroup;
instancesIdsList: Set<number> | null;
filteredObjectsList: Array<number>;
instanceIdValueMin = INSTANCES_ID_VALUE_MIN as number;
instanceIdValueMax = INSTANCES_ID_VALUE_MAX as number;
get required(): boolean {
return this.requiredValue;
@ -76,8 +77,7 @@ export class Lwm2mObjectAddInstancesListComponent implements ControlValueAccesso
@ViewChild('instanceIdInput') instanceIdInput: ElementRef<HTMLInputElement>;
@ViewChild('chipList', {static: true}) chipList: MatChipList;
private propagateChange = (v: any) => {
};
private propagateChange = (v: any) => { };
constructor(private store: Store<AppState>,
public translate: TranslateService,
@ -89,7 +89,7 @@ export class Lwm2mObjectAddInstancesListComponent implements ControlValueAccesso
});
}
updateValidators() {
private updateValidators = (): void => {
this.lwm2mObjectListFormGroup.get('instanceIdInput').setValidators([
Validators.min(this.instanceIdValueMin),
Validators.max(this.instanceIdValueMax)]);
@ -128,41 +128,41 @@ export class Lwm2mObjectAddInstancesListComponent implements ControlValueAccesso
this.dirty = false;
}
add(value: number): void {
add = (value: number): void => {
if (!isNaN(value) && this.lwm2mObjectListFormGroup.get('instanceIdInput').valid) {
this.instancesIdsList.add(value);
this.lwm2mObjectListFormGroup.get('instancesIdsList').setValue(this.instancesIdsList);
this.propagateChange(this.instancesIdsList);
this.dirty = true
this.dirty = true;
}
this.clear();
}
remove(object: number) {
remove = (object: number): void => {
this.instancesIdsList.delete(object);
this.lwm2mObjectListFormGroup.get('instancesIdsList').setValue(this.instancesIdsList);
this.propagateChange(this.instancesIdsList);
this.dirty = true
this.dirty = true;
this.clear();
}
//
// displayFn(object?: number): number | undefined {
// return object ? object : undefined;
// }
displayFn(object?: number): number | undefined {
return object ? object : undefined;
}
clear() {
private clear = (): void => {
this.lwm2mObjectListFormGroup.get('instanceIdInput').patchValue(null, {emitEvent: true});
this.instanceIdInput.nativeElement.value = "";
this.instanceIdInput.nativeElement.value = '';
setTimeout(() => {
this.instanceIdInput.nativeElement.blur();
this.instanceIdInput.nativeElement.focus();
}, 0);
}
onkeydown(e: KeyboardEvent) {
if (e.keyCode == 189 || e.keyCode == 187 || e.keyCode == 109 || e.keyCode == 107) {
onkeydown = (e: KeyboardEvent): boolean => {
if (e.keyCode === 189 || e.keyCode === 187 || e.keyCode === 109 || e.keyCode === 107) {
return false;
} else if (e.keyCode == 8) {
} else if (e.keyCode === 8) {
if (this.lwm2mObjectListFormGroup.get('instanceIdInput').value == null) {
this.clear();
}
@ -170,7 +170,7 @@ export class Lwm2mObjectAddInstancesListComponent implements ControlValueAccesso
}
}
onFocus() {
onFocus = (): void => {
if (this.dirty) {
this.lwm2mObjectListFormGroup.get('instanceIdInput').updateValueAndValidity({onlySelf: true, emitEvent: true});
this.dirty = false;

2
ui-ngx/src/app/modules/home/components/profile/device/lwm2m/lwm2m-object-add-instances.component.html

@ -42,7 +42,7 @@
<button mat-button color="primary"
type="button"
[disabled]="(isLoading$ | async)"
(click)="cancel()" cdkFocusInitial>
(click)="cancel()">
{{ 'action.cancel' | translate }}
</button>
<button mat-button mat-raised-button color="primary"

6
ui-ngx/src/app/modules/home/components/profile/device/lwm2m/lwm2m-object-add-instances.component.ts

@ -36,8 +36,6 @@ export interface Lwm2mObjectAddInstancesData {
export class Lwm2mObjectAddInstancesComponent extends DialogComponent<Lwm2mObjectAddInstancesComponent, object> implements OnInit {
jsonFormGroup: FormGroup;
// title: string;
submitted = false;
constructor(protected store: Store<AppState>,
@ -52,7 +50,7 @@ export class Lwm2mObjectAddInstancesComponent extends DialogComponent<Lwm2mObjec
ngOnInit(): void {
this.jsonFormGroup = this.fb.group({
instancesIds: this.data.instancesIds
})
});
}
cancel(): void {
@ -60,7 +58,7 @@ export class Lwm2mObjectAddInstancesComponent extends DialogComponent<Lwm2mObjec
}
add(): void {
this.data.instancesIds = this.jsonFormGroup.get('instancesIds').value
this.data.instancesIds = this.jsonFormGroup.get('instancesIds').value;
this.dialogRef.close(this.data);
}
}

82
ui-ngx/src/app/modules/home/components/profile/device/lwm2m/lwm2m-object-list.component.ts

@ -23,25 +23,25 @@ import {
ElementRef,
Output,
EventEmitter
} from "@angular/core";
} 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";
} from '@angular/forms';
import {coerceBooleanProperty} from '@angular/cdk/coercion';
import {Store} from '@ngrx/store';
import {AppState} from '@core/core.state';
import {MatChipList} from '@angular/material/chips';
import {MatAutocomplete} from "@angular/material/autocomplete";
import {Observable} from "rxjs";
import {MatAutocomplete} from '@angular/material/autocomplete';
import {Observable} from 'rxjs';
import {filter, map, mergeMap, share, tap} from 'rxjs/operators';
import {ObjectLwM2M} from "./profile-config.models";
import {TranslateService} from "@ngx-translate/core";
import {DeviceProfileService} from "@core/http/device-profile.service";
import {PageLink} from "@shared/models/page/page-link";
import {Direction} from "@shared/models/page/sort-order";
import {ObjectLwM2M} from './profile-config.models';
import {TranslateService} from '@ngx-translate/core';
import {DeviceProfileService} from '@core/http/device-profile.service';
import {PageLink} from '@shared/models/page/page-link';
import {Direction} from '@shared/models/page/sort-order';
@Component({
selector: 'tb-profile-lwm2m-object-list',
@ -56,14 +56,15 @@ import {Direction} from "@shared/models/page/sort-order";
})
export class Lwm2mObjectListComponent implements ControlValueAccessor, OnInit, Validators {
lwm2mObjectListFormGroup: FormGroup;
private requiredValue: boolean;
private dirty = false as boolean;
lwm2mObjectListFormGroup: FormGroup;
modelValue: Array<number> | null;
objectsList: Array<ObjectLwM2M> = [];
filteredObjectsList: Observable<Array<ObjectLwM2M>>;
private disabled = false as boolean;
disabled = false as boolean;
searchText = '' as string;
private dirty = false as boolean;
get required(): boolean {
return this.requiredValue;
@ -88,8 +89,7 @@ export class Lwm2mObjectListComponent implements ControlValueAccessor, OnInit, V
@ViewChild('objectAutocomplete') matAutocomplete: MatAutocomplete;
@ViewChild('chipList', {static: true}) chipList: MatChipList;
private propagateChange = (v: any) => {
};
private propagateChange = (v: any) => { };
constructor(private store: Store<AppState>,
public translate: TranslateService,
@ -101,7 +101,7 @@ export class Lwm2mObjectListComponent implements ControlValueAccessor, OnInit, V
});
}
updateValidators() {
private updateValidators = (): void => {
this.lwm2mObjectListFormGroup.get('objectLwm2m').setValidators(this.required ? [Validators.required] : []);
this.lwm2mObjectListFormGroup.get('objectLwm2m').updateValueAndValidity();
}
@ -130,7 +130,7 @@ export class Lwm2mObjectListComponent implements ControlValueAccessor, OnInit, V
);
}
ngAfterViewInit(): void {
ngAfterViewInit = (): void => {
}
setDisabledState(isDisabled: boolean): void {
@ -144,9 +144,10 @@ export class Lwm2mObjectListComponent implements ControlValueAccessor, OnInit, V
writeValue(value: any): void {
this.searchText = '';
if (value.hasOwnProperty("objectIds") && value["objectIds"] != null && value["objectIds"].length > 0) {
this.modelValue = [...value["objectIds"]];
this.objectsList = value["objectsList"];
const objectIds = 'objectIds';
if (value.hasOwnProperty(objectIds) && value[objectIds] != null && value[objectIds].length > 0) {
this.modelValue = [...value[objectIds]];
this.objectsList = value.objectsList;
this.lwm2mObjectListFormGroup.get('objectsList').setValue(this.objectsList);
} else {
this.objectsList = [];
@ -156,19 +157,19 @@ export class Lwm2mObjectListComponent implements ControlValueAccessor, OnInit, V
this.dirty = true;
}
reset() {
this.objectsList = [];
this.lwm2mObjectListFormGroup.get('objectsList').setValue(this.objectsList);
this.modelValue = null;
if (this.objectInput) {
this.objectInput.nativeElement.value = '';
}
this.lwm2mObjectListFormGroup.get('objectLwm2m').patchValue('', {emitEvent: false});
this.propagateChange(this.modelValue);
this.dirty = true;
}
// reset() {
// this.objectsList = [];
// this.lwm2mObjectListFormGroup.get('objectsList').setValue(this.objectsList);
// this.modelValue = null;
// if (this.objectInput) {
// this.objectInput.nativeElement.value = '';
// }
// this.lwm2mObjectListFormGroup.get('objectLwm2m').patchValue('', {emitEvent: false});
// this.propagateChange(this.modelValue);
// this.dirty = true;
// }
add(object: ObjectLwM2M): void {
private add = (object: ObjectLwM2M): void => {
if (!this.modelValue || this.modelValue.indexOf(object.id) === -1) {
if (!this.modelValue) {
this.modelValue = [];
@ -182,7 +183,7 @@ export class Lwm2mObjectListComponent implements ControlValueAccessor, OnInit, V
this.clear();
}
remove(object: ObjectLwM2M) {
remove = (object: ObjectLwM2M): void => {
let index = this.objectsList.indexOf(object);
if (index >= 0) {
this.objectsList.splice(index, 1);
@ -198,11 +199,11 @@ export class Lwm2mObjectListComponent implements ControlValueAccessor, OnInit, V
}
}
displayObjectLwm2mFn(object?: ObjectLwM2M): string | undefined {
displayObjectLwm2mFn = (object?: ObjectLwM2M): string | undefined => {
return object ? object.name : undefined;
}
fetchListObjects(searchText?: string): Observable<Array<ObjectLwM2M>> {
private fetchListObjects = (searchText?: string): Observable<Array<ObjectLwM2M>> => {
this.searchText = searchText;
const pageLink = new PageLink(10, 0, searchText, {
property: 'name',
@ -210,20 +211,19 @@ export class Lwm2mObjectListComponent implements ControlValueAccessor, OnInit, V
});
return this.deviceProfileService.getLwm2mObjectsPage(pageLink, {ignoreLoading: true}).pipe(
map(pageData => {
let data = pageData.data;
return data;
return pageData.data;
})
);
}
onFocus() {
onFocus = (): void => {
if (this.dirty) {
this.lwm2mObjectListFormGroup.get('objectLwm2m').updateValueAndValidity({onlySelf: true, emitEvent: true});
this.dirty = false;
}
}
clear(value: string = '') {
private clear = (value: string = ''): void => {
this.objectInput.nativeElement.value = value;
this.lwm2mObjectListFormGroup.get('objectLwm2m').patchValue(value, {emitEvent: true});
setTimeout(() => {

41
ui-ngx/src/app/modules/home/components/profile/device/lwm2m/lwm2m-observe-attr-telemetry-resource.component.ts

@ -14,13 +14,13 @@
/// limitations under the License.
///
import { Component, forwardRef, Input, OnInit } from "@angular/core";
import { Component, forwardRef, Input, OnInit } from '@angular/core';
import {
ControlValueAccessor,
FormArray, FormBuilder,
FormGroup,
NG_VALUE_ACCESSOR, Validators
} from "@angular/forms";
} from '@angular/forms';
import {
CAMEL_CASE_REGEXP,
ResourceLwM2M
@ -45,10 +45,10 @@ import { coerceBooleanProperty } from '@angular/cdk/coercion';
export class Lwm2mObserveAttrTelemetryResourceComponent implements ControlValueAccessor, OnInit, Validators {
resourceFormGroup : FormGroup;
private requiredValue: boolean;
resourceFormGroup: FormGroup;
disabled = false as boolean;
private requiredValue: boolean;
get required(): boolean {
return this.requiredValue;
@ -63,7 +63,7 @@ export class Lwm2mObserveAttrTelemetryResourceComponent implements ControlValueA
}
constructor(private store: Store<AppState>,
private fb: FormBuilder) {
this.resourceFormGroup = this.fb.group({'resources': this.fb.array([])});
this.resourceFormGroup = this.fb.group({resources: this.fb.array([])});
this.resourceFormGroup.valueChanges.subscribe(value => {
if (!this.disabled) {
this.propagateChangeState(value.resources);
@ -85,7 +85,7 @@ export class Lwm2mObserveAttrTelemetryResourceComponent implements ControlValueA
return this.resourceFormGroup.get('resources') as FormArray;
}
resourceLwm2mFormArray(instance: FormGroup): FormArray {
resourceLwm2mFormArray = (instance: FormGroup): FormArray => {
return instance.get('resources') as FormArray;
}
@ -98,28 +98,28 @@ export class Lwm2mObserveAttrTelemetryResourceComponent implements ControlValueA
}
}
getDisabledState(): boolean {
getDisabledState = (): boolean => {
return this.disabled;
}
updateValueKeyName (event: any, z: number): void {
updateValueKeyName = (event: any, z: number): void => {
this.resourceFormArray.at(z).patchValue( {keyName: this.keysToCamel(deepClone(event.target.value))} );
}
keysToCamel(o: any): string {
let val = o.split(" ");
let playStore = [];
val.forEach(function (item, k){
private keysToCamel = (o: any): string => {
const val = o.split(' ');
const playStore = [];
val.forEach((item, k) => {
item = item.replace(CAMEL_CASE_REGEXP, '');
item = (k===0)? item.charAt(0).toLowerCase() + item.substr(1) : item.charAt(0).toUpperCase() + item.substr(1)
item = (k === 0) ? item.charAt(0).toLowerCase() + item.substr(1) : item.charAt(0).toUpperCase() + item.substr(1);
playStore.push(item);
});
return playStore.join('');
}
createResourceLwM2M(resourcesLwM2MJson: ResourceLwM2M []): void {
if(resourcesLwM2MJson.length === this.resourceFormArray.length) {
this.resourceFormArray.patchValue(resourcesLwM2MJson, {emitEvent: false})
private createResourceLwM2M = (resourcesLwM2MJson: ResourceLwM2M []): void => {
if (resourcesLwM2MJson.length === this.resourceFormArray.length) {
this.resourceFormArray.patchValue(resourcesLwM2MJson, {emitEvent: false});
} else {
this.resourceFormArray.clear();
resourcesLwM2MJson.forEach(resourceLwM2M => {
@ -131,18 +131,17 @@ export class Lwm2mObserveAttrTelemetryResourceComponent implements ControlValueA
telemetry: resourceLwM2M.telemetry,
keyName: [resourceLwM2M.keyName, Validators.required]
}));
})
});
}
}
private propagateChange = (v: any) => {
};
private propagateChange = (v: any) => { };
registerOnChange(fn: any): void {
this.propagateChange = fn;
}
private propagateChangeState(value: any): void {
private propagateChangeState = (value: any): void => {
if (value && this.resourceFormGroup.valid) {
this.propagateChange(value);
} else {
@ -150,7 +149,7 @@ export class Lwm2mObserveAttrTelemetryResourceComponent implements ControlValueA
}
}
trackByParams(index: number): number {
trackByParams = (index: number): number => {
return index;
}
}

153
ui-ngx/src/app/modules/home/components/profile/device/lwm2m/lwm2m-observe-attr-telemetry.component.ts

@ -15,7 +15,7 @@
///
import { Component, forwardRef, Input, OnInit, Output } from "@angular/core";
import { Component, forwardRef, Input, OnInit } from '@angular/core';
import {
AbstractControl,
ControlValueAccessor,
@ -24,10 +24,10 @@ import {
FormGroup,
NG_VALUE_ACCESSOR,
Validators
} from "@angular/forms";
import { Store } from "@ngrx/store";
import { AppState } from "@core/core.state";
import { coerceBooleanProperty } from "@angular/cdk/coercion";
} from '@angular/forms';
import { Store } from '@ngrx/store';
import { AppState } from '@core/core.state';
import { coerceBooleanProperty } from '@angular/cdk/coercion';
import {
ATTR,
Instance,
@ -35,7 +35,7 @@ import {
OBSERVE,
ResourceLwM2M,
TELEMETRY
} from "./profile-config.models";
} from './profile-config.models';
import { isNotNullOrUndefined } from 'codelyzer/util/isNotNullOrUndefined';
import { deepClone, isUndefined } from '@core/utils';
import { MatDialog } from '@angular/material/dialog';
@ -60,12 +60,13 @@ import {
export class Lwm2mObserveAttrTelemetryComponent implements ControlValueAccessor, OnInit, Validators {
private requiredValue: boolean;
valuePrev = null as any;
observeAttrTelemetryFormGroup: FormGroup;
observe = OBSERVE as string;
attribute = ATTR as string;
telemetry = TELEMETRY as string;
private requiredValue: boolean;
get required(): boolean {
return this.requiredValue;
@ -74,6 +75,7 @@ export class Lwm2mObserveAttrTelemetryComponent implements ControlValueAccessor,
@Input()
disabled: boolean;
// tslint:disable-next-line:adjacent-overload-signatures
@Input()
set required(value: boolean) {
const newVal = coerceBooleanProperty(value);
@ -86,7 +88,7 @@ export class Lwm2mObserveAttrTelemetryComponent implements ControlValueAccessor,
constructor(private store: Store<AppState>,
private fb: FormBuilder,
private dialog: MatDialog,
private translate: TranslateService) {
public translate: TranslateService) {
this.observeAttrTelemetryFormGroup = this.fb.group({
clientLwM2M: this.fb.array([])
});
@ -100,19 +102,18 @@ export class Lwm2mObserveAttrTelemetryComponent implements ControlValueAccessor,
ngOnInit(): void {
}
private propagateChange = (v: any) => {
};
private propagateChange = (v: any) => { };
registerOnChange(fn: any): void {
this.propagateChange = fn;
}
private propagateChangeState(value: any): void {
private propagateChangeState = (value: any): void => {
if (value) {
if (this.valuePrev === null) {
this.valuePrev = "init";
} else if (this.valuePrev === "init") {
this.valuePrev = 'init';
} else if (this.valuePrev === 'init') {
this.valuePrev = value;
} else if (JSON.stringify(value) !== JSON.stringify(this.valuePrev)) {
this.valuePrev = value;
@ -138,7 +139,7 @@ export class Lwm2mObserveAttrTelemetryComponent implements ControlValueAccessor,
}
}
getDisabledState(): boolean {
getDisabledState = (): boolean => {
return this.disabled;
}
@ -146,13 +147,13 @@ export class Lwm2mObserveAttrTelemetryComponent implements ControlValueAccessor,
this.buildClientObjectsLwM2M(value.clientLwM2M);
}
private buildClientObjectsLwM2M(objectsLwM2M: ObjectLwM2M []): void {
private buildClientObjectsLwM2M = (objectsLwM2M: ObjectLwM2M []): void => {
this.observeAttrTelemetryFormGroup.setControl('clientLwM2M',
this.createObjectsLwM2M(objectsLwM2M)
);
}
createObjectsLwM2M(objectsLwM2MJson: ObjectLwM2M []): FormArray {
private createObjectsLwM2M = (objectsLwM2MJson: ObjectLwM2M []): FormArray => {
return this.fb.array(objectsLwM2MJson.map((objectLwM2M) => {
return this.fb.group({
id: objectLwM2M.id,
@ -160,62 +161,62 @@ export class Lwm2mObserveAttrTelemetryComponent implements ControlValueAccessor,
multiple: objectLwM2M.multiple,
mandatory: objectLwM2M.mandatory,
instances: this.createInstanceLwM2M(objectLwM2M.instances)
})
}))
});
}));
}
createInstanceLwM2M(instanceLwM2MJson: Instance []): FormArray {
return this.fb.array(instanceLwM2MJson.map((instanceLwM2M, index) => {
private createInstanceLwM2M = (instanceLwM2MJson: Instance []): FormArray => {
return this.fb.array(instanceLwM2MJson.map((instanceLwM2M) => {
return this.fb.group({
id: instanceLwM2M.id,
[this.observe]: {value: false, disabled: this.disabled},
[this.attribute]: {value: false, disabled: this.disabled},
[this.telemetry]: {value: false, disabled: this.disabled},
resources: {value: instanceLwM2M.resources, disabled: this.disabled}
})
}))
});
}));
}
clientLwM2MFormArray(formGroup: FormGroup): FormArray {
clientLwM2MFormArray = (formGroup: FormGroup): FormArray => {
return formGroup.get('clientLwM2M') as FormArray;
}
instancesLwm2mFormArray(objectLwM2M: AbstractControl): FormArray {
instancesLwm2mFormArray = (objectLwM2M: AbstractControl): FormArray => {
return objectLwM2M.get('instances') as FormArray;
}
changeInstanceResourcesCheckBox(value: boolean, instance: AbstractControl, type: string): void {
let resources = instance.get('resources').value as ResourceLwM2M []
changeInstanceResourcesCheckBox = (value: boolean, instance: AbstractControl, type: string): void => {
const resources = instance.get('resources').value as ResourceLwM2M [];
resources.forEach(resource => resource[type] = value);
instance.get('resources').patchValue(resources);
this.propagateChange(this.observeAttrTelemetryFormGroup.value);
}
updateValidators() {
private updateValidators = (): void => {
this.observeAttrTelemetryFormGroup.get('clientLwM2M').setValidators(this.required ? [Validators.required] : []);
this.observeAttrTelemetryFormGroup.get('clientLwM2M').updateValueAndValidity();
}
trackByParams(index: number): number {
trackByParams = (index: number): number => {
return index;
}
getIndeterminate(instance: AbstractControl, type: string) {
getIndeterminate = (instance: AbstractControl, type: string): boolean => {
const resources = instance.get('resources').value as ResourceLwM2M [];
if (isNotNullOrUndefined(resources)) {
const isType = (element) => element[type] === true;
let checkedResource = resources.filter(isType);
if (checkedResource.length === 0) return false;
const checkedResource = resources.filter(isType);
if (checkedResource.length === 0) { return false; }
else if (checkedResource.length === resources.length) {
instance.patchValue({[type]: true});
return false;
} else return true;
} else { return true; }
}
return false;
}
getChecked(instance: AbstractControl, type: string) {
getChecked = (instance: AbstractControl, type: string): boolean => {
const resources = instance.get('resources').value as ResourceLwM2M [];
if (isNotNullOrUndefined(resources)) {
return resources.some(resource => resource[type]);
@ -223,7 +224,7 @@ export class Lwm2mObserveAttrTelemetryComponent implements ControlValueAccessor,
return false;
}
getExpended(objectLwM2M: AbstractControl) {
getExpended = (objectLwM2M: AbstractControl): boolean => {
return this.instancesLwm2mFormArray(objectLwM2M).length === 1;
}
@ -233,22 +234,24 @@ export class Lwm2mObserveAttrTelemetryComponent implements ControlValueAccessor,
* 2) Field in object: <Mandatory> == Mandatory/Optional
* If this field is “Multiple” then the number of Object Instance can be from 0 to many (Object Instance ID MAX_ID=65535).
* If this field is “Single” then the number of Object Instance can be from 0 to 1. (max count == 1)
* If the Object field “Mandatory” is “Mandatory” and the Object field “Instances” is “Single” then, the number of Object Instance MUST be 1.
* 1. <MultipleInstances> == Multiple (true), <Mandatory> == Optional (false) => Object Instance ID MIN_ID=0 MAX_ID=65535 (может ни одного не быть)
* 2. <MultipleInstances> == Multiple (true), <Mandatory> == Mandatory (true) => Object Instance ID MIN_ID=0 MAX_ID=65535 (min один обязательный)
* 3. <MultipleInstances> == Single (false), <Mandatory> == Optional (false) => Object Instance ID cnt_max = 1 cnt_min = 0 (может ни одного не быть)
* 4. <MultipleInstances> == Single (false), <Mandatory> == Mandatory (true) => Object Instance ID cnt_max = cnt_min = 1 (всегда есть один)
* @param $event
* @param objectId
* @param objectName
* If the Object field “Mandatory” is “Mandatory” and the Object field “Instances” is “Single” then -
* the number of Object Instance MUST be 1.
* 1. <MultipleInstances> == Multiple (true), <Mandatory> == Optional (false) -
* Object Instance ID MIN_ID=0 MAX_ID=65535 (может ни одного не быть)
* 2. <MultipleInstances> == Multiple (true), <Mandatory> == Mandatory (true) -
* Object Instance ID MIN_ID=0 MAX_ID=65535 (min один обязательный)
* 3. <MultipleInstances> == Single (false), <Mandatory> == Optional (false) -
* Object Instance ID cnt_max = 1 cnt_min = 0 (может ни одного не быть)
* 4. <MultipleInstances> == Single (false), <Mandatory> == Mandatory (true) -
* Object Instance ID cnt_max = cnt_min = 1 (всегда есть один)
*/
addInstances($event: Event, object: ObjectLwM2M): void {
addInstances = ($event: Event, object: ObjectLwM2M): void => {
if ($event) {
$event.stopPropagation();
$event.preventDefault();
}
let instancesIds = new Set<number>();
const instancesIds = new Set<number>();
object.instances.forEach(inst => {
instancesIds.add(inst.id);
});
@ -269,21 +272,22 @@ export class Lwm2mObserveAttrTelemetryComponent implements ControlValueAccessor,
);
}
updateInstancesIds(data: Lwm2mObjectAddInstancesData) {
let valueNew = new Set<number>();
let valueOld = new Set<number>();
private updateInstancesIds = (data: Lwm2mObjectAddInstancesData): void => {
const valueNew = new Set<number>();
const valueOld = new Set<number>();
data.instancesIds.forEach(value => {
valueNew.add(value);
})
let oldInstances = (this.observeAttrTelemetryFormGroup.get('clientLwM2M').value as ObjectLwM2M []).find(e => e.id == data.objectId).instances;
});
const oldInstances = (this.observeAttrTelemetryFormGroup.get('clientLwM2M').value as ObjectLwM2M []).
find(e => e.id === data.objectId).instances;
oldInstances.forEach(inst => {
valueOld.add(inst.id);
});
if (JSON.stringify(Array.from(valueOld)) != JSON.stringify(Array.from(valueNew))) {
let idsDel = this.diffBetweenSet(valueNew, this.deepCloneSet(valueOld));
let idsAdd = this.diffBetweenSet(valueOld, this.deepCloneSet(valueNew));
if (JSON.stringify(Array.from(valueOld)) !== JSON.stringify(Array.from(valueNew))) {
const idsDel = this.diffBetweenSet(valueNew, this.deepCloneSet(valueOld));
const idsAdd = this.diffBetweenSet(valueOld, this.deepCloneSet(valueNew));
if (idsAdd.size) {
this.addInstancesNew(data.objectId, idsAdd)
this.addInstancesNew(data.objectId, idsAdd);
}
if (idsDel.size) {
this.delInstances(data.objectId, idsDel);
@ -291,22 +295,25 @@ export class Lwm2mObserveAttrTelemetryComponent implements ControlValueAccessor,
}
}
delInstances(objectId: number, idsDel: Set<number>): void {
let isIdIndex = (element) => element.id == objectId;
let objectIndex = (this.observeAttrTelemetryFormGroup.get('clientLwM2M').value as ObjectLwM2M []).findIndex(isIdIndex);
private delInstances = (objectId: number, idsDel: Set<number>): void => {
let isIdIndex = (element) => element.id === objectId;
const objectIndex = (this.observeAttrTelemetryFormGroup.get('clientLwM2M').value as ObjectLwM2M []).findIndex(isIdIndex);
idsDel.forEach(x => {
isIdIndex = (element) => element.value.id == x;
let instancesFormArray = ((this.observeAttrTelemetryFormGroup.get('clientLwM2M') as FormArray).controls[objectIndex].get("instances") as FormArray);
let instanceIndex = instancesFormArray.controls.findIndex(isIdIndex);
isIdIndex = (element) => element.value.id === x;
const instancesFormArray = ((this.observeAttrTelemetryFormGroup.get('clientLwM2M') as FormArray)
.controls[objectIndex].get('instances') as FormArray);
const instanceIndex = instancesFormArray.controls.findIndex(isIdIndex);
instancesFormArray.removeAt(instanceIndex);
})
});
}
addInstancesNew(objectId: number, idsAdd: Set<number>): void {
let instancesValue = (this.observeAttrTelemetryFormGroup.get('clientLwM2M').value as ObjectLwM2M []).find(e => e.id == objectId).instances;
let instancesFormArray = ((this.observeAttrTelemetryFormGroup.get('clientLwM2M') as FormArray).controls.find(e => e.value.id == objectId).get("instances") as FormArray) as FormArray;
private addInstancesNew = (objectId: number, idsAdd: Set<number>): void => {
const instancesValue = (this.observeAttrTelemetryFormGroup.get('clientLwM2M').value as ObjectLwM2M [])
.find(e => e.id === objectId).instances;
const instancesFormArray = ((this.observeAttrTelemetryFormGroup.get('clientLwM2M') as FormArray).controls
.find(e => e.value.id === objectId).get('instances') as FormArray) as FormArray;
idsAdd.forEach(x => {
let instanceNew = deepClone(instancesValue[0]) as Instance;
const instanceNew = deepClone(instancesValue[0]) as Instance;
instanceNew.id = x;
instanceNew.resources.forEach(r => {
r.attribute = false;
@ -321,26 +328,26 @@ export class Lwm2mObserveAttrTelemetryComponent implements ControlValueAccessor,
resources: {value: instanceNew.resources, disabled: this.disabled}
}));
});
(instancesFormArray.controls as FormGroup[]).sort((a,b) => a.value.id - b.value.id);
(instancesFormArray.controls as FormGroup[]).sort((a, b) => a.value.id - b.value.id);
}
deepCloneSet(oldSet: Set<any>): Set<any> {
let newSet = new Set<number>();
private deepCloneSet = (oldSet: Set<any>): Set<any> => {
const newSet = new Set<number>();
oldSet.forEach(p => {
newSet.add(p);
})
});
return newSet;
}
diffBetweenSet(firstSet: Set<any>, secondSet: Set<any>): Set<any> {
private diffBetweenSet = (firstSet: Set<any>, secondSet: Set<any>): Set<any> => {
firstSet.forEach(p => {
secondSet.delete(p);
})
return secondSet
});
return secondSet;
}
setInstancesIds(instances: Instance []): Set<number> {
let instancesIds = new Set<number>();
private setInstancesIds = (instances: Instance []): Set<number> => {
const instancesIds = new Set<number>();
if (instances && instances.length) {
instances.forEach(inst => {
instancesIds.add(inst.id);

108
ui-ngx/src/app/modules/home/components/profile/device/lwm2m/profile-config.models.ts

@ -14,8 +14,6 @@
/// limitations under the License.
///
import { AbstractControl, ValidationErrors } from '@angular/forms';
export const OBSERVE_ATTR = 'observeAttr';
export const OBSERVE = 'observe';
export const ATTR = 'attribute';
@ -23,33 +21,29 @@ export const TELEMETRY = 'telemetry';
export const KEY_NAME = 'keyName';
export const DEFAULT_ID_SERVER = 123;
export const DEFAULT_ID_BOOTSTRAP = 111;
export const DEFAULT_HOST_NAME = "localhost";
export const DEFAULT_HOST_NAME = 'localhost';
export const DEFAULT_PORT_SERVER_NO_SEC = 5685;
export const DEFAULT_PORT_BOOTSTRAP_NO_SEC = 5691;
export const DEFAULT_CLIENT_HOLD_OFF_TIME = 1;
export const DEFAULT_LIFE_TIME = 300;
export const DEFAULT_DEFAULT_MIN_PERIOD = 1;
export const DEFAULT_MIN_PERIOD = 1;
export const DEFAULT_NOTIF_IF_DESIBLED = true;
export const DEFAULT_BINDING = "U";
export const DEFAULT_BINDING = 'U';
export const DEFAULT_BOOTSTRAP_SERVER_ACCOUNT_TIME_OUT = 0;
export const LEN_MAX_PUBLIC_KEY_PSK = 182;
export const LEN_MAX_PUBLIC_KEY_RPK_X509 = 3000;
export const KEY_IDENT_REGEXP_PSK = /^[0-9a-fA-F]{64,64}$/;
export const KEY_PRIVATE_REGEXP = /^[0-9a-fA-F]{134,134}$/;
export const KEY_PUBLIC_REGEXP_PSK = /^[0-9a-fA-F]{182,182}$/;
export const KEY_PUBLIC_REGEXP_X509 = /^[0-9a-fA-F]{0,3000}$/;
export const LEN_MAX_PUBLIC_KEY_RPK = 182;
export const LEN_MAX_PUBLIC_KEY_X509 = 3000;
export const KEY_REGEXP_HEX_DEC = /^[-+]?[0-9A-Fa-f]+\.?[0-9A-Fa-f]*?$/;
export const CAMEL_CASE_REGEXP = /[-_&@.,*+!?^${}()|[\]\\]/g;
export const INSTANCES_ID_VALUE_MIN = 0;
export const INSTANCES_ID_VALUE_MAX = 65535;
//ok
export enum SECURITY_CONFIG_MODE {
PSK = 'PSK',
RPK = 'RPK',
X509 = 'X509',
NO_SEC = 'NO_SEC'
}
//ok
export const SECURITY_CONFIG_MODE_NAMES = new Map<SECURITY_CONFIG_MODE, string>(
[
[SECURITY_CONFIG_MODE.PSK, 'Pre-Shared Key'],
@ -58,59 +52,54 @@ export const SECURITY_CONFIG_MODE_NAMES = new Map<SECURITY_CONFIG_MODE, string>(
[SECURITY_CONFIG_MODE.NO_SEC, 'No Security'],
]
);
//ok
export interface BootstrapServersSecurityConfig {
shortId: number,
lifetime: number,
defaultMinPeriod: number,
notifIfDisabled: boolean,
binding: string
shortId: number;
lifetime: number;
defaultMinPeriod: number;
notifIfDisabled: boolean;
binding: string;
}
//ok
export interface ServerSecurityConfig {
host?: string,
port?: number,
bootstrapServerIs?: boolean,
securityMode: string,
clientPublicKeyOrId?: string,
clientSecretKey?: string,
host?: string;
port?: number;
bootstrapServerIs?: boolean;
securityMode: string;
clientPublicKeyOrId?: string;
clientSecretKey?: string;
serverPublicKey?: string;
clientHoldOffTime?: number,
serverId?: number,
bootstrapServerAccountTimeout: number
clientHoldOffTime?: number;
serverId?: number;
bootstrapServerAccountTimeout: number;
}
//ok
interface BootstrapSecurityConfig {
servers: BootstrapServersSecurityConfig,
bootstrapServer: ServerSecurityConfig,
lwm2mServer: ServerSecurityConfig
servers: BootstrapServersSecurityConfig;
bootstrapServer: ServerSecurityConfig;
lwm2mServer: ServerSecurityConfig;
}
//ok
export interface ProfileConfigModels {
bootstrap: BootstrapSecurityConfig,
bootstrap: BootstrapSecurityConfig;
observeAttr: {
observe: string [],
attribute: string [],
telemetry: string [],
keyName: []
}
};
}
//ok
export function getDefaultBootstrapServersSecurityConfig(): BootstrapServersSecurityConfig {
return {
shortId: DEFAULT_ID_SERVER,
lifetime: DEFAULT_LIFE_TIME,
defaultMinPeriod: DEFAULT_DEFAULT_MIN_PERIOD,
defaultMinPeriod: DEFAULT_MIN_PERIOD,
notifIfDisabled: DEFAULT_NOTIF_IF_DESIBLED,
binding: DEFAULT_BINDING
}
};
}
//ok
export function getDefaultBootstrapServerSecurityConfig(hostname: any): ServerSecurityConfig {
return {
host: hostname,
@ -121,9 +110,9 @@ export function getDefaultBootstrapServerSecurityConfig(hostname: any): ServerSe
clientHoldOffTime: DEFAULT_CLIENT_HOLD_OFF_TIME,
serverId: DEFAULT_ID_BOOTSTRAP,
bootstrapServerAccountTimeout: DEFAULT_BOOTSTRAP_SERVER_ACCOUNT_TIME_OUT
}
};
}
//ok
export function getDefaultLwM2MServerSecurityConfig(hostname): ServerSecurityConfig {
const DefaultLwM2MServerSecurityConfig = getDefaultBootstrapServerSecurityConfig(hostname);
DefaultLwM2MServerSecurityConfig.bootstrapServerIs = false;
@ -132,19 +121,17 @@ export function getDefaultLwM2MServerSecurityConfig(hostname): ServerSecurityCon
return DefaultLwM2MServerSecurityConfig;
}
//ok
function getDefaultProfileBootstrapSecurityConfig(hostname: any): BootstrapSecurityConfig {
return {
servers: getDefaultBootstrapServersSecurityConfig(),
bootstrapServer: getDefaultBootstrapServerSecurityConfig(hostname),
lwm2mServer: getDefaultLwM2MServerSecurityConfig(hostname)
}
};
}
//ok
export function getDefaultProfileConfig(hostname?: any): ProfileConfigModels {
return {
bootstrap: getDefaultProfileBootstrapSecurityConfig((hostname)? hostname : DEFAULT_HOST_NAME),
bootstrap: getDefaultProfileBootstrapSecurityConfig((hostname) ? hostname : DEFAULT_HOST_NAME),
observeAttr: {
observe: [],
attribute: [],
@ -154,19 +141,18 @@ export function getDefaultProfileConfig(hostname?: any): ProfileConfigModels {
};
}
//ok
export interface ResourceLwM2M {
id: number,
name: string,
observe: boolean,
attribute: boolean,
telemetry: boolean,
keyName: string
id: number;
name: string;
observe: boolean;
attribute: boolean;
telemetry: boolean;
keyName: string;
}
//ok
export interface Instance {
id: number,
resources: ResourceLwM2M[]
id: number;
resources: ResourceLwM2M[];
}
/**
@ -176,10 +162,10 @@ export interface Instance {
* mandatory == false => Optional
*/
export interface ObjectLwM2M {
id: number,
name: string,
multiple?: boolean,
mandatory?: boolean,
instances?: Instance []
id: number;
name: string;
multiple?: boolean;
mandatory?: boolean;
instances?: Instance [];
}

3
ui-ngx/src/app/modules/home/pages/device/device.module.ts

@ -25,8 +25,7 @@ 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';
// TODO: @nickAS21 move to device profile
import {SecurityConfigServerComponent} from "@home/pages/device/lwm2m/security-config-server.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';

57
ui-ngx/src/app/modules/home/pages/device/lwm2m/security-config-server.component.html

@ -24,7 +24,7 @@
<mat-select formControlName="securityMode"
(ngModelChange)="securityModeChanged($event)">
<mat-option *ngFor="let securityMode of securityConfigLwM2MTypes"
[value]="securityMode" >
[value]="securityMode">
{{ credentialTypeLwM2MNamesMap.get(securityConfigLwM2MType[securityMode]) }}
</mat-option>
</mat-select>
@ -35,43 +35,64 @@
<div [fxShow]="serverFormGroup.get('securityMode').value !== securityConfigLwM2MType.NO_SEC">
<mat-form-field class="mat-block">
<mat-label>{{ 'device.lwm2m-security-config.client-publicKey-or-id' | translate }}</mat-label>
<textarea matInput type="text" rows="3" cols="1" formControlName="clientPublicKeyOrId" #clientPublicKeyOrId maxlength={{lenMaxClientPublicKeyOrId}}
[required]="serverFormGroup.get('securityMode').value !== securityConfigLwM2MType.NO_SEC"></textarea>
<textarea matInput
#clientPublicKeyOrId
maxlength={{lenMaxClientPublicKeyOrId}}
cdkTextareaAutosize
cdkAutosizeMinRows="1"
style="overflow:hidden"
cols="1"
formControlName="clientPublicKeyOrId"
[required]="serverFormGroup.get('securityMode').value !== securityConfigLwM2MType.NO_SEC">
</textarea>
<mat-hint align="end">{{clientPublicKeyOrId.value?.length || 0}}/{{lenMaxClientPublicKeyOrId}}</mat-hint>
<mat-error *ngIf="serverFormGroup.get('clientPublicKeyOrId').hasError('required')">
{{ 'device.lwm2m-security-config.client-publicKey-or-id' | translate }}
<strong>{{ 'device.lwm2m-security-config.required' | translate }}</strong>
</mat-error>
<mat-error *ngIf="serverFormGroup.get('clientPublicKeyOrId').hasError('pattern') &&
serverFormGroup.get('securityMode').value === securityConfigLwM2MType.RPK">
<mat-error *ngIf="serverFormGroup.get('clientPublicKeyOrId').hasError('pattern')">
{{ 'device.lwm2m-security-config.client-key' | translate }}
<strong>{{ 'device.lwm2m-security-config.pattern_hex_dec_182' | translate }}</strong>
<strong>{{ translate.get('device.lwm2m-security-config.pattern_hex_dec', {
count: 0
}) | async }}</strong>
</mat-error>
<mat-error *ngIf="serverFormGroup.get('clientPublicKeyOrId').hasError('pattern') &&
serverFormGroup.get('securityMode').value === securityConfigLwM2MType.X509">
<mat-error *ngIf="(serverFormGroup.get('clientPublicKeyOrId').hasError('maxlength') ||
serverFormGroup.get('clientPublicKeyOrId').hasError('minlength'))">
{{ 'device.lwm2m-security-config.client-key' | translate }}
<strong>{{ 'device.lwm2m-security-config.pattern_hex_dec' | translate }}</strong>
<strong>{{ translate.get('device.lwm2m-security-config.pattern_hex_dec', {
count: lenMaxClientPublicKeyOrId
}) | async }}</strong>
</mat-error>
</mat-form-field>
<mat-form-field class="mat-block">
<mat-label>{{ 'device.lwm2m-security-config.client-secret-key' | translate }}</mat-label>
<textarea matInput type="text" rows="2" cols="1" formControlName="clientSecretKey" #clientSecretKey maxlength={{lenMaxClientSecretKey}}
[required]="serverFormGroup.get('securityMode').value !== securityConfigLwM2MType.NO_SEC"></textarea>
<textarea matInput
#clientSecretKey
maxlength={{lenMaxClientSecretKey}}
cdkTextareaAutosize
cdkAutosizeMinRows="1"
style="overflow:hidden"
cols="1"
formControlName="clientSecretKey"
[required]="serverFormGroup.get('securityMode').value !== securityConfigLwM2MType.NO_SEC">
</textarea>
<mat-hint align="end">{{clientSecretKey.value?.length || 0}}/{{lenMaxClientSecretKey}}</mat-hint>
<mat-error *ngIf="serverFormGroup.get('clientSecretKey').hasError('required')">
{{ 'device.lwm2m-security-config.client-secret-key' | translate }}
<strong>{{ 'device.lwm2m-security-config.required' | translate }}</strong>
</mat-error>
<mat-error *ngIf="serverFormGroup.get('clientSecretKey').hasError('pattern') &&
(serverFormGroup.get('securityMode').value === securityConfigLwM2MType.RPK ||
serverFormGroup.get('securityMode').value === securityConfigLwM2MType.X509)">
<mat-error *ngIf="serverFormGroup.get('clientSecretKey').hasError('pattern')">
{{ 'device.lwm2m-security-config.client-key' | translate }}
<strong>{{ 'device.lwm2m-security-config.pattern_hex_dec_134' | translate }}</strong>
<strong>{{ translate.get('device.lwm2m-security-config.pattern_hex_dec', {
count: 0
}) | async }}</strong>
</mat-error>
<mat-error *ngIf="serverFormGroup.get('clientSecretKey').hasError('pattern') &&
(serverFormGroup.get('securityMode').value === securityConfigLwM2MType.PSK)">
<mat-error *ngIf="(serverFormGroup.get('clientSecretKey').hasError('maxlength') ||
serverFormGroup.get('clientSecretKey').hasError('minlength'))">
{{ 'device.lwm2m-security-config.client-key' | translate }}
<strong>{{ 'device-profile.lwm2m.pattern_hex_dec_64' | translate }}</strong>
<strong>{{ translate.get('device.lwm2m-security-config.pattern_hex_dec', {
count: lenMaxClientSecretKey
}) | async }}</strong>
</mat-error>
</mat-form-field>
</div>

62
ui-ngx/src/app/modules/home/pages/device/lwm2m/security-config-server.component.ts

@ -14,26 +14,25 @@
/// limitations under the License.
///
import {Component, forwardRef, Inject, Input, OnInit, ViewChild} from "@angular/core";
import { Component, forwardRef, Inject, Input, OnInit } from '@angular/core';
import {
ControlValueAccessor,
FormBuilder, FormGroup, NG_VALUE_ACCESSOR, Validators
} from "@angular/forms";
} from '@angular/forms';
import {
SECURITY_CONFIG_MODE,
SECURITY_CONFIG_MODE_NAMES,
KEY_IDENT_REGEXP_PSK,
KEY_REGEXP_HEX_DEC,
ServerSecurityConfig,
DeviceCredentialsDialogLwm2mData,
LEN_MAX_PSK,
LEN_MAX_PRIVATE_KEY, LEN_MAX_PUBLIC_KEY_RPK, KEY_PRIVATE_REGEXP, LEN_MAX_PUBLIC_KEY_X509, KEY_PUBLIC_REGEXP_X509
} 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";
import {MatPaginator} from "@angular/material/paginator";
LEN_MAX_PRIVATE_KEY, LEN_MAX_PUBLIC_KEY_RPK, LEN_MAX_PUBLIC_KEY_X509
} 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';
import { TranslateService } from '@ngx-translate/core';
@Component({
@ -54,13 +53,13 @@ export class SecurityConfigServerComponent extends PageComponent implements OnIn
securityConfigLwM2MType = SECURITY_CONFIG_MODE;
securityConfigLwM2MTypes = Object.keys(SECURITY_CONFIG_MODE);
credentialTypeLwM2MNamesMap = SECURITY_CONFIG_MODE_NAMES;
lenMaxClientPublicKeyOrId = LEN_MAX_PSK;
lenMinClientPublicKeyOrId = 0;
lenMaxClientPublicKeyOrId = LEN_MAX_PUBLIC_KEY_RPK;
lenMinClientSecretKey = LEN_MAX_PRIVATE_KEY;
lenMaxClientSecretKey = LEN_MAX_PRIVATE_KEY;
@Input() serverFormGroup: FormGroup;
@ViewChild(MatPaginator) paginator: MatPaginator;
constructor(protected store: Store<AppState>,
@Inject(MAT_DIALOG_DATA) public data: DeviceCredentialsDialogLwm2mData,
public dialogRef: MatDialogRef<SecurityConfigServerComponent, object>,
@ -73,40 +72,59 @@ export class SecurityConfigServerComponent extends PageComponent implements OnIn
this.registerDisableOnLoadFormControl(this.serverFormGroup.get('securityMode'));
}
updateValueFields(serverData: ServerSecurityConfig): void {
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);
}
updateValidate(securityMode: SECURITY_CONFIG_MODE): void {
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.serverFormGroup.get('clientPublicKeyOrId').setValidators([Validators.required]);
this.serverFormGroup.get('clientSecretKey').setValidators([Validators.required, Validators.pattern(KEY_IDENT_REGEXP_PSK)]);
this.setValidatorsSecurity(securityMode);
break;
case SECURITY_CONFIG_MODE.RPK:
this.lenMaxClientPublicKeyOrId = LEN_MAX_PUBLIC_KEY_X509;
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.serverFormGroup.get('clientPublicKeyOrId').setValidators([Validators.required, Validators.pattern(KEY_PUBLIC_REGEXP_X509)]);
this.serverFormGroup.get('clientSecretKey').setValidators([Validators.required, Validators.pattern(KEY_PRIVATE_REGEXP)]);
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.serverFormGroup.get('clientPublicKeyOrId').setValidators([Validators.required, Validators.pattern(KEY_PUBLIC_REGEXP_X509)]);
this.serverFormGroup.get('clientSecretKey').setValidators([Validators.required, Validators.pattern(KEY_PRIVATE_REGEXP)]);
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);
}

206
ui-ngx/src/app/modules/home/pages/device/lwm2m/security-config.component.html

@ -35,110 +35,124 @@
<strong>{{ 'device.lwm2m-security-config.required' | translate }}</strong>
</mat-error>
</mat-form-field>
<mat-tab-group dynamicHeight #tabGroup (selectedTabChange)="tabChanged($event)">
<mat-tab-group dynamicHeight (selectedTabChange)="tabChanged($event)">
<mat-tab label="{{ 'device.lwm2m-security-config.client-tab' | translate }}">
<div class="mat-padding">
<mat-form-field class="mat-block">
<mat-label translate>device.lwm2m-security-config.mode</mat-label>
<mat-select formControlName="securityConfigClientMode"
(ngModelChange)="securityConfigClientModeChanged($event)">
<mat-option *ngFor="let securityConfigClientMode of securityConfigLwM2MTypes"
[value]="securityConfigClientMode">
{{ credentialTypeLwM2MNamesMap.get(securityConfigLwM2MType[securityConfigClientMode]) }}
</mat-option>
</mat-select>
</mat-form-field>
<div [fxShow]="lwm2mConfigFormGroup.get('securityConfigClientMode').value === securityConfigLwM2MType.PSK">
<ng-template matTabContent>
<div class="mat-padding">
<mat-form-field class="mat-block">
<mat-label>{{ 'device.lwm2m-security-config.identity' | translate }}</mat-label>
<input matInput type="text" formControlName="identityPSK"
[required]="lwm2mConfigFormGroup.get('securityConfigClientMode').value === securityConfigLwM2MType.PSK">
<mat-error *ngIf="lwm2mConfigFormGroup.get('identityPSK').hasError('required')">
{{ 'device.lwm2m-security-config.identity' | translate }}
<strong>{{ 'device.lwm2m-security-config.required' | translate }}</strong>
</mat-error>
<mat-label translate>device.lwm2m-security-config.mode</mat-label>
<mat-select formControlName="securityConfigClientMode"
(ngModelChange)="securityConfigClientModeChanged($event)">
<mat-option *ngFor="let securityConfigClientMode of securityConfigLwM2MTypes"
[value]="securityConfigClientMode">
{{ credentialTypeLwM2MNamesMap.get(securityConfigLwM2MType[securityConfigClientMode]) }}
</mat-option>
</mat-select>
</mat-form-field>
</div>
<div [fxShow]="lwm2mConfigFormGroup.get('securityConfigClientMode').value === securityConfigLwM2MType.RPK ||
<div *ngIf="lwm2mConfigFormGroup.get('securityConfigClientMode').value === securityConfigLwM2MType.PSK">
<mat-form-field class="mat-block">
<mat-label>{{ 'device.lwm2m-security-config.identity' | translate }}</mat-label>
<input matInput type="text" formControlName="identityPSK"
[required]="lwm2mConfigFormGroup.get('securityConfigClientMode').value === securityConfigLwM2MType.PSK">
<mat-error *ngIf="lwm2mConfigFormGroup.get('identityPSK').hasError('required')">
{{ 'device.lwm2m-security-config.identity' | translate }}
<strong>{{ 'device.lwm2m-security-config.required' | translate }}</strong>
</mat-error>
</mat-form-field>
</div>
<div *ngIf="lwm2mConfigFormGroup.get('securityConfigClientMode').value === securityConfigLwM2MType.RPK ||
lwm2mConfigFormGroup.get('securityConfigClientMode').value === securityConfigLwM2MType.PSK">
<mat-form-field class="mat-block">
<mat-label>{{ 'device.lwm2m-security-config.client-key' | translate }}</mat-label>
<textarea matInput #clientKey maxlength={{lenMinMaxClient}} type="text" rows="3" cols="1"
formControlName="clientKey"
[required]="lwm2mConfigFormGroup.get('securityConfigClientMode').value === securityConfigLwM2MType.RPK ||
lwm2mConfigFormGroup.get('securityConfigClientMode').value === securityConfigLwM2MType.PSK"></textarea>
<mat-hint align="end">{{clientKey.value?.length || 0}}/{{lenMaxKeyClient}}</mat-hint>
<mat-error *ngIf="lwm2mConfigFormGroup.get('clientKey').hasError('required')">
{{ 'device.lwm2m-security-config.client-key' | translate }}
<strong>{{ 'device.lwm2m-security-config.required' | translate }}</strong>
</mat-error>
<mat-error *ngIf="lwm2mConfigFormGroup.get('clientKey').hasError('pattern') &&
lwm2mConfigFormGroup.get('securityConfigClientMode').value === securityConfigLwM2MType.PSK">
{{ 'device.lwm2m-security-config.client-key' | translate }}
<strong>{{ 'device-profile.lwm2m-security-config.pattern_hex_dec_64' | translate }}</strong>
</mat-error>
<mat-error *ngIf="lwm2mConfigFormGroup.get('clientKey').hasError('pattern') &&
lwm2mConfigFormGroup.get('securityConfigClientMode').value === securityConfigLwM2MType.RPK">
{{ 'device.lwm2m-security-config.client-key' | translate }}
<strong>{{ 'device.lwm2m-security-config.pattern_hex_dec_182' | translate }}</strong>
</mat-error>
</mat-form-field>
</div>
<div [fxShow]="lwm2mConfigFormGroup.get('securityConfigClientMode').value === securityConfigLwM2MType.X509">
<mat-checkbox formControlName="clientCertificate" color="primary">
{{ 'device.lwm2m-security-config.client-certificate' | translate }}
</mat-checkbox>
<mat-form-field class="mat-block">
<mat-label>{{ 'device.lwm2m-security-config.client-key' | translate }}</mat-label>
<textarea matInput
#clientKey
maxlength="{{lenMaxKeyClient}}"
cdkTextareaAutosize
cdkAutosizeMinRows="1"
cols="1"
formControlName="clientKey"
style="overflow:hidden"
[required]="lwm2mConfigFormGroup.get('securityConfigClientMode').value === securityConfigLwM2MType.RPK ||
lwm2mConfigFormGroup.get('securityConfigClientMode').value === securityConfigLwM2MType.PSK">
</textarea>
<mat-hint align="end">{{clientKey.value?.length || 0}}/{{lenMaxKeyClient}}</mat-hint>
<mat-error *ngIf="lwm2mConfigFormGroup.get('clientKey').hasError('required')">
{{ 'device.lwm2m-security-config.client-key' | translate }}
<strong>{{ 'device.lwm2m-security-config.required' | translate }}</strong>
</mat-error>
<mat-error *ngIf="lwm2mConfigFormGroup.get('clientKey').hasError('pattern')">
{{ 'device.lwm2m-security-config.client-key' | translate }}
<strong>{{ translate.get('device.lwm2m-security-config.pattern_hex_dec', {
count: 0 }) | async }}</strong>
</mat-error>
<mat-error *ngIf="(lwm2mConfigFormGroup.get('clientKey').hasError('maxlength') ||
lwm2mConfigFormGroup.get('clientKey').hasError('minlength'))">
{{ 'device.lwm2m-security-config.client-key' | translate }}
<strong>{{ translate.get('device.lwm2m-security-config.pattern_hex_dec', {
count: lenMaxKeyClient }) | async }}</strong>
</mat-error>
</mat-form-field>
</div>
<div *ngIf="lwm2mConfigFormGroup.get('securityConfigClientMode').value === securityConfigLwM2MType.X509">
<mat-checkbox formControlName="clientCertificate" color="primary">
{{ 'device.lwm2m-security-config.client-certificate' | translate }}
</mat-checkbox>
</div>
</div>
</div>
</ng-template>
</mat-tab>
<mat-tab label="{{ 'device.lwm2m-security-config.bootstrap-tab' | translate }}">
<div class="mat-padding">
<mat-accordion multi="true" class="mat-body-1">
<mat-expansion-panel>
<mat-expansion-panel-header>
<mat-panel-title>
<div
class="tb-panel-title">{{ 'device.lwm2m-security-config.bootstrap-server' | translate | uppercase }}</div>
</mat-panel-title>
</mat-expansion-panel-header>
<div class="mat-padding">
<tb-security-config-server-lwm2m
[formControlName]="bootstrapServer"
[serverFormGroup]="bootstrapFormGroup">
</tb-security-config-server-lwm2m>
</div>
</mat-expansion-panel>
</mat-accordion>
<mat-accordion multi="true" class="mat-body-1">
<mat-expansion-panel>
<mat-expansion-panel-header>
<mat-panel-title>
<div
class="tb-panel-title">{{ 'device.lwm2m-security-config.lwm2m-server' | translate | uppercase }}</div>
</mat-panel-title>
</mat-expansion-panel-header>
<div class="mat-padding">
<tb-security-config-server-lwm2m
[formControlName]="lwm2mServer"
[serverFormGroup]="lwm2mServerFormGroup">
</tb-security-config-server-lwm2m>
</div>
</mat-expansion-panel>
</mat-accordion>
</div>
<ng-template matTabContent>
<div class="mat-padding">
<mat-accordion multi="true" class="mat-body-1">
<mat-expansion-panel>
<mat-expansion-panel-header>
<mat-panel-title>
<div
class="tb-panel-title">{{ 'device.lwm2m-security-config.bootstrap-server' | translate | uppercase }}</div>
</mat-panel-title>
</mat-expansion-panel-header>
<div class="mat-padding">
<tb-security-config-server-lwm2m
[formControlName]="bootstrapServer"
[serverFormGroup]="bootstrapFormGroup">
</tb-security-config-server-lwm2m>
</div>
</mat-expansion-panel>
</mat-accordion>
<mat-accordion multi="true" class="mat-body-1">
<mat-expansion-panel>
<mat-expansion-panel-header>
<mat-panel-title>
<div
class="tb-panel-title">{{ 'device.lwm2m-security-config.lwm2m-server' | translate | uppercase }}</div>
</mat-panel-title>
</mat-expansion-panel-header>
<div class="mat-padding">
<tb-security-config-server-lwm2m
[formControlName]="lwm2mServer"
[serverFormGroup]="lwm2mServerFormGroup">
</tb-security-config-server-lwm2m>
</div>
</mat-expansion-panel>
</mat-accordion>
</div>
</ng-template>
</mat-tab>
<mat-tab label="{{ 'device.lwm2m-security-config.config-json-tab' | translate }}">
<div class="mat-padding">
<fieldset [disabled]="isLoading$ | async">
<tb-json-object-edit
[formControlName]="formControlNameJsonAllConfig"
label="{{ 'device.lwm2m-value' | translate }}"
validateContent="true"
[required]="true"
[fillHeight]="false">
</tb-json-object-edit>
</fieldset>
</div>
<ng-template matTabContent>
<div class="mat-padding">
<fieldset [disabled]="isLoading$ | async">
<tb-json-object-edit
[formControlName]="formControlNameJsonAllConfig"
label="{{ 'device.lwm2m-value' | translate }}"
validateContent="true"
[required]="true"
[fillHeight]="false">
</tb-json-object-edit>
</fieldset>
</div>
</ng-template>
</mat-tab>
</mat-tab-group>
</fieldset>
@ -148,7 +162,7 @@
<button mat-button color="primary"
type="button"
[disabled]="(isLoading$ | async)"
(click)="cancel()" cdkFocusInitial>
(click)="cancel()">
{{ 'action.cancel' | translate }}
</button>
<button mat-button mat-raised-button color="primary"

185
ui-ngx/src/app/modules/home/pages/device/lwm2m/security-config.component.ts

@ -15,14 +15,14 @@
///
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 {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 {
SECURITY_CONFIG_MODE_NAMES,
SECURITY_CONFIG_MODE,
@ -30,22 +30,20 @@ import {
ClientSecurityConfigPSK,
ClientSecurityConfigRPK,
JSON_ALL_CONFIG,
KEY_IDENT_REGEXP_PSK,
KEY_PUBLIC_REGEXP_PSK,
KEY_REGEXP_HEX_DEC,
DeviceCredentialsDialogLwm2mData,
BOOTSTRAP_SERVER,
BOOTSTRAP_SERVERS,
LWM2M_SERVER,
ClientSecurityConfigX509,
ClientSecurityConfigNO_SEC,
ClientSecurityConfigNoSEC,
getDefaultClientSecurityConfigType,
LEN_MAX_PSK,
LEN_MAX_PUBLIC_KEY_RPK
} from "./security-config.models";
import {WINDOW} from "@core/services/window.service";
import {MatTabChangeEvent, MatTabGroup} from "@angular/material/tabs";
import {MatTab} from "@angular/material/tabs/tab";
} 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',
@ -67,8 +65,8 @@ export class SecurityConfigComponent extends DialogComponent<SecurityConfigCompo
bootstrapServer: string;
lwm2mServer: string;
jsonObserveData: {};
lenMaxKeyClient = LEN_MAX_PSK;
tabPrevious: MatTab
lenMaxKeyClient = LEN_MAX_PSK as number;
tabPrevious: MatTab;
tabIndexPrevious = 0 as number;
constructor(protected store: Store<AppState>,
@ -76,7 +74,7 @@ export class SecurityConfigComponent extends DialogComponent<SecurityConfigCompo
@Inject(MAT_DIALOG_DATA) public data: DeviceCredentialsDialogLwm2mData,
public dialogRef: MatDialogRef<SecurityConfigComponent, object>,
public fb: FormBuilder,
private translate: TranslateService,
public translate: TranslateService,
@Inject(WINDOW) private window: Window) {
super(store, router, dialogRef);
}
@ -85,13 +83,13 @@ export class SecurityConfigComponent extends DialogComponent<SecurityConfigCompo
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.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'));
}
initConstants(): void {
private initConstants = (): void => {
this.bootstrapServers = BOOTSTRAP_SERVERS;
this.bootstrapServer = BOOTSTRAP_SERVER;
this.lwm2mServer = LWM2M_SERVER;
@ -112,7 +110,7 @@ export class SecurityConfigComponent extends DialogComponent<SecurityConfigCompo
return this.lwm2mConfigFormGroup.get('observeFormGroup') as FormGroup;
}
initClientSecurityConfig(jsonAllConfig: SecurityConfigModels): void {
private initClientSecurityConfig = (jsonAllConfig: SecurityConfigModels): void => {
switch (jsonAllConfig.client.securityConfigClientMode.toString()) {
case SECURITY_CONFIG_MODE.NO_SEC.toString():
break;
@ -139,106 +137,110 @@ export class SecurityConfigComponent extends DialogComponent<SecurityConfigCompo
this.securityConfigClientUpdateValidators(this.lwm2mConfigFormGroup.get('securityConfigClientMode').value);
}
securityConfigClientModeChanged(mode: SECURITY_CONFIG_MODE): void {
securityConfigClientModeChanged = (mode: SECURITY_CONFIG_MODE): void => {
switch (mode) {
case SECURITY_CONFIG_MODE.NO_SEC:
let clientSecurityConfigNO_SEC = getDefaultClientSecurityConfigType(mode) as ClientSecurityConfigNO_SEC;
this.jsonAllConfig.client = clientSecurityConfigNO_SEC;
const clientSecurityConfigNoSEC = getDefaultClientSecurityConfigType(mode) as ClientSecurityConfigNoSEC;
this.jsonAllConfig.client = clientSecurityConfigNoSEC;
this.lwm2mConfigFormGroup.patchValue({
jsonAllConfig: this.jsonAllConfig,
clientCertificate: false
}, {emitEvent: true});
}, {emitEvent: false});
break;
case SECURITY_CONFIG_MODE.PSK:
let clientSecurityConfigPSK = getDefaultClientSecurityConfigType(mode, this.lwm2mConfigFormGroup.get('endPoint').value) as ClientSecurityConfigPSK;
const clientSecurityConfigPSK = getDefaultClientSecurityConfigType(mode, this.lwm2mConfigFormGroup.get('endPoint')
.value) as ClientSecurityConfigPSK;
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: true});
}, {emitEvent: false});
break;
case SECURITY_CONFIG_MODE.RPK:
let clientSecurityConfigRPK = getDefaultClientSecurityConfigType(mode) as ClientSecurityConfigRPK;
const clientSecurityConfigRPK = getDefaultClientSecurityConfigType(mode) as ClientSecurityConfigRPK;
clientSecurityConfigRPK.key = this.lwm2mConfigFormGroup.get('clientKey').value;
this.jsonAllConfig.client = clientSecurityConfigRPK;
this.lwm2mConfigFormGroup.patchValue({
jsonAllConfig: this.jsonAllConfig,
clientCertificate: false
}, {emitEvent: true})
}, {emitEvent: false});
break;
case SECURITY_CONFIG_MODE.X509:
let clientSecurityConfigX509 = getDefaultClientSecurityConfigType(mode) as ClientSecurityConfigX509;
this.jsonAllConfig.client = clientSecurityConfigX509;
this.jsonAllConfig.client = getDefaultClientSecurityConfigType(mode) as ClientSecurityConfigX509;
this.lwm2mConfigFormGroup.patchValue({
jsonAllConfig: this.jsonAllConfig,
clientCertificate: true
}, {emitEvent: true})
}, {emitEvent: false});
break;
}
this.securityConfigClientUpdateValidators(mode);
}
securityConfigClientUpdateValidators(mode: SECURITY_CONFIG_MODE): void {
private securityConfigClientUpdateValidators = (mode: SECURITY_CONFIG_MODE): void => {
switch (mode) {
case SECURITY_CONFIG_MODE.NO_SEC:
this.lwm2mConfigFormGroup.get('identityPSK').setValidators([]);
this.lwm2mConfigFormGroup.get('identityPSK').updateValueAndValidity();
this.lwm2mConfigFormGroup.get('clientKey').setValidators([]);
this.lwm2mConfigFormGroup.get('clientKey').updateValueAndValidity();
this.setValidatorsNoSecX509();
break;
case SECURITY_CONFIG_MODE.PSK:
this.lenMaxKeyClient = LEN_MAX_PSK;
this.lwm2mConfigFormGroup.get('identityPSK').setValidators([]);
this.lwm2mConfigFormGroup.get('identityPSK').updateValueAndValidity();
this.lwm2mConfigFormGroup.get('clientKey').setValidators([Validators.required, Validators.pattern(KEY_IDENT_REGEXP_PSK)]);
this.lwm2mConfigFormGroup.get('clientKey').updateValueAndValidity();
this.setValidatorsPskRpk(mode);
break;
case SECURITY_CONFIG_MODE.RPK:
this.lenMaxKeyClient = LEN_MAX_PUBLIC_KEY_RPK;
this.lwm2mConfigFormGroup.get('identityPSK').setValidators([]);
this.lwm2mConfigFormGroup.get('identityPSK').updateValueAndValidity();
this.lwm2mConfigFormGroup.get('clientKey').setValidators([Validators.required, Validators.pattern(KEY_PUBLIC_REGEXP_PSK)]);
this.lwm2mConfigFormGroup.get('clientKey').updateValueAndValidity();
this.setValidatorsPskRpk(mode);
break;
case SECURITY_CONFIG_MODE.X509:
this.lenMaxKeyClient = LEN_MAX_PUBLIC_KEY_RPK;
this.lwm2mConfigFormGroup.get('identityPSK').setValidators([]);
this.lwm2mConfigFormGroup.get('identityPSK').updateValueAndValidity();
this.lwm2mConfigFormGroup.get('clientKey').setValidators([]);
this.lwm2mConfigFormGroup.get('clientKey').updateValueAndValidity();
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();
if (this.tabIndexPrevious !== tabChangeEvent.index) { this.upDateValueToJson(); }
this.tabIndexPrevious = tabChangeEvent.index;
}
upDateValueToJson(): void {
private upDateValueToJson(): void {
switch (this.tabIndexPrevious) {
case 0:
this.upDateValueToJsonTab_0();
this.upDateValueToJsonTab0();
break;
case 1:
this.upDateValueToJsonTab_1();
this.upDateValueToJsonTab1();
break;
case 2:
this.upDateValueToJsonTab_2();
this.upDateValueToJsonTab2();
break;
}
}
upDateValueToJsonTab_0(): void {
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) {
this.jsonAllConfig.client["endpoint"] = this.data.endPoint;
this.jsonAllConfig.client["endpoint"].markAsPristine({
const endPoint = 'endpoint';
this.jsonAllConfig.client[endPoint] = this.data.endPoint;
this.jsonAllConfig.client[endPoint].markAsPristine({
onlySelf: true
});
this.upDateJsonAllConfig();
@ -261,7 +263,7 @@ export class SecurityConfigComponent extends DialogComponent<SecurityConfigCompo
}
}
upDateValueToJsonTab_1(): void {
private upDateValueToJsonTab1 = (): void => {
if (this.lwm2mConfigFormGroup !== null) {
if (this.bootstrapFormGroup !== null && !this.bootstrapFormGroup.pristine && this.bootstrapFormGroup.valid) {
this.jsonAllConfig.bootstrap.bootstrapServer = this.bootstrapFormGroup.value;
@ -281,8 +283,9 @@ export class SecurityConfigComponent extends DialogComponent<SecurityConfigCompo
}
}
upDateValueToJsonTab_2(): void {
if (!this.lwm2mConfigFormGroup.get(this.formControlNameJsonAllConfig).pristine && this.lwm2mConfigFormGroup.get(this.formControlNameJsonAllConfig).valid) {
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
@ -290,15 +293,17 @@ export class SecurityConfigComponent extends DialogComponent<SecurityConfigCompo
}
}
updateIdentityPSK(): void {
if (this.lwm2mConfigFormGroup.get('bootstrapServer').value['securityMode'] === SECURITY_CONFIG_MODE.PSK.toString()) {
private updateIdentityPSK = (): void => {
const securityMode = 'securityMode';
if (this.lwm2mConfigFormGroup.get('bootstrapServer').value[securityMode] === SECURITY_CONFIG_MODE.PSK.toString()) {
this.lwm2mConfigFormGroup.get('bootstrapFormGroup').patchValue({
clientPublicKeyOrId: this.lwm2mConfigFormGroup.get('identityPSK').value
});
this.jsonAllConfig.client['identity'] = 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.toString()) {
if (this.lwm2mConfigFormGroup.get('lwm2mServer').value[securityMode] === SECURITY_CONFIG_MODE.PSK.toString()) {
this.lwm2mConfigFormGroup.get('lwm2mServerFormGroup').patchValue({
clientPublicKeyOrId: this.lwm2mConfigFormGroup.get('identityPSK').value
});
@ -307,32 +312,26 @@ export class SecurityConfigComponent extends DialogComponent<SecurityConfigCompo
}
}
updateClientKey(): void {
this.jsonAllConfig.client["key"] = this.lwm2mConfigFormGroup.get('clientKey').value;
if (this.lwm2mConfigFormGroup.get('bootstrapServer').value['securityMode'] === SECURITY_CONFIG_MODE.PSK.toString()) {
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.toString()) {
this.lwm2mConfigFormGroup.get('bootstrapServer').patchValue({
clientSecretKey: this.jsonAllConfig.client["key"]
clientSecretKey: this.jsonAllConfig.client[key]
}, {emitEvent: false});
this.jsonAllConfig.bootstrap.bootstrapServer.clientSecretKey = this.jsonAllConfig.client["key"];
this.jsonAllConfig.bootstrap.bootstrapServer.clientSecretKey = this.jsonAllConfig.client[key];
}
if (this.lwm2mConfigFormGroup.get('lwm2mServer').value['securityMode'] === SECURITY_CONFIG_MODE.PSK.toString()) {
if (this.lwm2mConfigFormGroup.get('lwm2mServer').value[securityMode] === SECURITY_CONFIG_MODE.PSK.toString()) {
this.lwm2mConfigFormGroup.get('lwm2mServer').patchValue({
clientSecretKey: this.jsonAllConfig.client["key"]
clientSecretKey: this.jsonAllConfig.client[key]
}, {emitEvent: false});
this.jsonAllConfig.bootstrap.lwm2mServer.clientSecretKey = this.jsonAllConfig.client["key"];
this.jsonAllConfig.bootstrap.lwm2mServer.clientSecretKey = this.jsonAllConfig.client[key];
}
this.upDateJsonAllConfig();
}
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();
}
upDateBootstrapFormGroup(): void {
private upDateJsonAllConfig = (): void => {
this.data.jsonAllConfig = JSON.parse(JSON.stringify(this.jsonAllConfig));
this.lwm2mConfigFormGroup.patchValue({
jsonAllConfig: JSON.parse(JSON.stringify(this.jsonAllConfig))
@ -340,9 +339,10 @@ export class SecurityConfigComponent extends DialogComponent<SecurityConfigCompo
this.lwm2mConfigFormGroup.markAsDirty();
}
initLwm2mConfigFormGroup(): FormGroup {
private initLwm2mConfigFormGroup = (): FormGroup => {
if (SECURITY_CONFIG_MODE[this.jsonAllConfig.client.securityConfigClientMode.toString()] === SECURITY_CONFIG_MODE.PSK) {
this.data.endPoint = this.jsonAllConfig.client['endpoint'];
const endpoint = 'endpoint';
this.data.endPoint = this.jsonAllConfig.client[endpoint];
}
return this.fb.group({
securityConfigClientMode: [SECURITY_CONFIG_MODE[this.jsonAllConfig.client.securityConfigClientMode.toString()], []],
@ -351,27 +351,28 @@ export class SecurityConfigComponent extends DialogComponent<SecurityConfigCompo
clientCertificate: [false, []],
bootstrapServer: [this.jsonAllConfig.bootstrap[this.bootstrapServer], []],
lwm2mServer: [this.jsonAllConfig.bootstrap[this.lwm2mServer], []],
bootstrapFormGroup: this.getServerGroup(true),
lwm2mServerFormGroup: this.getServerGroup(false),
bootstrapFormGroup: this.getServerGroup(),
lwm2mServerFormGroup: this.getServerGroup(),
endPoint: [this.data.endPoint, []],
jsonAllConfig: [this.jsonAllConfig, []]
});
}
getServerGroup(bootstrapServerIs: boolean): FormGroup {
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.endPoint = this.lwm2mConfigFormGroup.get('endPoint').value.split('\'').join('');
this.data.jsonAllConfig = this.jsonAllConfig;
if (this.lwm2mConfigFormGroup.get('securityConfigClientMode').value === SECURITY_CONFIG_MODE.PSK) {
this.data.endPoint = this.data.jsonAllConfig.client["identity"];
const identity = 'identity';
this.data.endPoint = this.data.jsonAllConfig.client[identity];
}
this.dialogRef.close(this.data);
}

54
ui-ngx/src/app/modules/home/pages/device/lwm2m/security-config.models.ts

@ -25,10 +25,8 @@ export const LEN_MAX_PSK = 64;
export const LEN_MAX_PRIVATE_KEY = 134;
export const LEN_MAX_PUBLIC_KEY_RPK = 182;
export const LEN_MAX_PUBLIC_KEY_X509 = 3000;
export const KEY_IDENT_REGEXP_PSK = /^[0-9a-fA-F]{64,64}$/;
export const KEY_PRIVATE_REGEXP = /^[0-9a-fA-F]{134,134}$/;
export const KEY_PUBLIC_REGEXP_PSK = /^[0-9a-fA-F]{182,182}$/;
export const KEY_PUBLIC_REGEXP_X509 = /^[0-9a-fA-F]{0,3000}$/;
export const KEY_REGEXP_HEX_DEC = /^[-+]?[0-9A-Fa-f]+\.?[0-9A-Fa-f]*?$/;
export interface DeviceCredentialsDialogLwm2mData {
jsonAllConfig?: SecurityConfigModels;
@ -55,43 +53,43 @@ export type ClientSecurityConfigType =
ClientSecurityConfigPSK
| ClientSecurityConfigRPK
| ClientSecurityConfigX509
| ClientSecurityConfigNO_SEC;
| ClientSecurityConfigNoSEC;
export interface ClientSecurityConfigPSK {
securityConfigClientMode: string,
endpoint: string,
identity: string,
key: string
securityConfigClientMode: string;
endpoint: string;
identity: string;
key: string;
}
export interface ClientSecurityConfigRPK {
securityConfigClientMode: string,
key: string
securityConfigClientMode: string;
key: string;
}
export interface ClientSecurityConfigX509 {
securityConfigClientMode: string,
x509: boolean
securityConfigClientMode: string;
x509: boolean;
}
export interface ClientSecurityConfigNO_SEC {
securityConfigClientMode: string
export interface ClientSecurityConfigNoSEC {
securityConfigClientMode: string;
}
export interface ServerSecurityConfig {
securityMode: string,
clientPublicKeyOrId?: string,
clientSecretKey?: string
securityMode: string;
clientPublicKeyOrId?: string;
clientSecretKey?: string;
}
interface BootstrapSecurityConfig {
bootstrapServer: ServerSecurityConfig,
lwm2mServer: ServerSecurityConfig
bootstrapServer: ServerSecurityConfig;
lwm2mServer: ServerSecurityConfig;
}
export interface SecurityConfigModels {
client: ClientSecurityConfigType,
bootstrap: BootstrapSecurityConfig
client: ClientSecurityConfigType;
bootstrap: BootstrapSecurityConfig;
}
export function getDefaultClientSecurityConfigType(securityConfigMode: SECURITY_CONFIG_MODE, endPoint?: string): ClientSecurityConfigType {
@ -103,24 +101,24 @@ export function getDefaultClientSecurityConfigType(securityConfigMode: SECURITY_
endpoint: endPoint,
identity: endPoint,
key: ''
}
};
break;
case SECURITY_CONFIG_MODE.RPK:
security = {
securityConfigClientMode: '',
key: ''
}
};
break;
case SECURITY_CONFIG_MODE.X509:
security = {
securityConfigClientMode: '',
x509: true
}
};
break;
case SECURITY_CONFIG_MODE.NO_SEC:
security = {
securityConfigClientMode: ''
}
};
break;
}
security.securityConfigClientMode = securityConfigMode.toString();
@ -132,14 +130,14 @@ export function getDefaultServerSecurityConfig(): ServerSecurityConfig {
securityMode: SECURITY_CONFIG_MODE.NO_SEC.toString(),
clientPublicKeyOrId: '',
clientSecretKey: ''
}
};
}
function getDefaultBootstrapSecurityConfig(): BootstrapSecurityConfig {
return {
bootstrapServer: getDefaultServerSecurityConfig(),
lwm2mServer: getDefaultServerSecurityConfig()
}
};
}
export function getDefaultSecurityConfig(): SecurityConfigModels {

6
ui-ngx/src/app/shared/components/json-object-edit.component.ts

@ -61,6 +61,7 @@ export class JsonObjectEditComponent implements OnInit, ControlValueAccessor, Va
@Input() editorStyle: { [klass: string]: any };
// tslint:disable-next-line:ban-types
@Input() sort: Function;
private requiredValue: boolean;
@ -226,9 +227,10 @@ export class JsonObjectEditComponent implements OnInit, ControlValueAccessor, Va
try {
if (this.modelValue) {
this.contentValue = JSON.stringify(this.modelValue, isUndefined(this.sort) ? undefined :
this.contentValue = JSON.stringify(this.modelValue, isUndefined(this.sort) ? null :
// tslint:disable-next-line:no-shadowed-variable
(key, value) => {
return this.sort(key, value)
return this.sort(key, value);
}, 2);
this.objectValid = true;
} else {

10
ui-ngx/src/assets/locale/locale.constant-en_US.json

@ -893,9 +893,8 @@
"lwm2m-server": "LwM2M Server",
"client-publicKey-or-id": "Client Public Key or Id",
"client-secret-key": "Client Secret Key",
"config-json-tab": "Json Client Security Config",
"pattern_hex_dec_64": "must be hex decimal format and 64 characters",
"pattern_hex_dec_182": "must be hex decimal format and 182 characters"
"config-json-tab": "Json Client Security Config",
"pattern_hex_dec": "{ count, plural, 0 {must be hex decimal format} other {must be # characters} }"
},
"client-id": "Client ID",
"client-id-pattern": "Contains invalid character.",
@ -1121,10 +1120,7 @@
"key-name_label": "Key Name in Camel format",
"required": " value is required.",
"mode": "Security config mode",
"pattern_hex_dec_64": "must be hex decimal format and 64 characters",
"pattern_hex_dec_134": "must be hex decimal format and 134 characters",
"pattern_hex_dec_182": "must be hex decimal format and 182 characters",
"pattern_hex_dec": "must be hex decimal format",
"pattern_hex_dec": "{ count, plural, 0 {must be hex decimal format} other {must be # characters} }",
"bootstrap-tab": "Bootstrap",
"servers": "Servers",
"short-id": "Short ID",

Loading…
Cancel
Save