From 9008f56414ceaaa01c521f9c5847887fb7b3f696 Mon Sep 17 00:00:00 2001 From: Valentin Mihai Date: Sun, 22 May 2022 23:35:42 +0300 Subject: [PATCH] RED-3982 - updates to add 'pkcs signature' and 'kms signature' forms also on main screen component to be edited --- .../src/app/modules/admin/admin.module.ts | 4 +- ...onfigure-certificate-dialog.component.html | 3 +- ...onfigure-certificate-dialog.component.scss | 5 - .../configure-certificate-dialog.component.ts | 54 +++++-- .../base-signature-configuration-component.ts | 42 ++++++ ...kms-signature-configuration.component.html | 3 +- ...kms-signature-configuration.component.scss | 6 + .../kms-signature-configuration.component.ts | 43 ++++++ ...kcs-signature-configuration.component.html | 3 +- ...kcs-signature-configuration.component.scss | 9 ++ .../pkcs-signature-configuration.component.ts | 43 ++++++ .../kms-signature-configuration.component.ts | 26 ---- ...kcs-signature-configuration.component.scss | 3 - .../pkcs-signature-configuration.component.ts | 24 ---- .../digital-signature-screen.component.html | 114 +++++---------- .../digital-signature-screen.component.ts | 132 +++++++----------- .../services/digital-signature.service.ts | 40 +++++- apps/red-ui/src/assets/i18n/de.json | 34 ++--- apps/red-ui/src/assets/i18n/en.json | 35 ++--- libs/common-ui | 2 +- ...equest.ts => digital-signature-request.ts} | 3 - .../src/lib/signature/digital-signature.ts | 6 - libs/red-domain/src/lib/signature/index.ts | 7 +- .../kms-digital-signature.request.ts | 8 ++ .../lib/signature/kms-digital-signature.ts | 6 + .../pkcs-digital-signature.request.ts | 7 + .../lib/signature/pkcs-digital-signature.ts | 6 + 27 files changed, 357 insertions(+), 311 deletions(-) create mode 100644 apps/red-ui/src/app/modules/admin/dialogs/configure-digital-signature-dialog/form/base-signature-configuration-component.ts rename apps/red-ui/src/app/modules/admin/dialogs/configure-digital-signature-dialog/{ => form}/kms-signature-configuration/kms-signature-configuration.component.html (91%) rename apps/red-ui/src/app/modules/admin/dialogs/configure-digital-signature-dialog/{ => form}/kms-signature-configuration/kms-signature-configuration.component.scss (52%) create mode 100644 apps/red-ui/src/app/modules/admin/dialogs/configure-digital-signature-dialog/form/kms-signature-configuration/kms-signature-configuration.component.ts rename apps/red-ui/src/app/modules/admin/dialogs/configure-digital-signature-dialog/{ => form}/pkcs-signature-configuration/pkcs-signature-configuration.component.html (85%) create mode 100644 apps/red-ui/src/app/modules/admin/dialogs/configure-digital-signature-dialog/form/pkcs-signature-configuration/pkcs-signature-configuration.component.scss create mode 100644 apps/red-ui/src/app/modules/admin/dialogs/configure-digital-signature-dialog/form/pkcs-signature-configuration/pkcs-signature-configuration.component.ts delete mode 100644 apps/red-ui/src/app/modules/admin/dialogs/configure-digital-signature-dialog/kms-signature-configuration/kms-signature-configuration.component.ts delete mode 100644 apps/red-ui/src/app/modules/admin/dialogs/configure-digital-signature-dialog/pkcs-signature-configuration/pkcs-signature-configuration.component.scss delete mode 100644 apps/red-ui/src/app/modules/admin/dialogs/configure-digital-signature-dialog/pkcs-signature-configuration/pkcs-signature-configuration.component.ts rename libs/red-domain/src/lib/signature/{digital-signature.request.ts => digital-signature-request.ts} (52%) delete mode 100644 libs/red-domain/src/lib/signature/digital-signature.ts create mode 100644 libs/red-domain/src/lib/signature/kms-digital-signature.request.ts create mode 100644 libs/red-domain/src/lib/signature/kms-digital-signature.ts create mode 100644 libs/red-domain/src/lib/signature/pkcs-digital-signature.request.ts create mode 100644 libs/red-domain/src/lib/signature/pkcs-digital-signature.ts diff --git a/apps/red-ui/src/app/modules/admin/admin.module.ts b/apps/red-ui/src/app/modules/admin/admin.module.ts index b5570876a..c754937ae 100644 --- a/apps/red-ui/src/app/modules/admin/admin.module.ts +++ b/apps/red-ui/src/app/modules/admin/admin.module.ts @@ -44,8 +44,8 @@ import { BaseEntityScreenComponent } from './base-entity-screen/base-entity-scre import { CloneDossierTemplateDialogComponent } from './dialogs/clone-dossier-template-dialog/clone-dossier-template-dialog.component'; import { AdminSideNavComponent } from './admin-side-nav/admin-side-nav.component'; import { ConfigureCertificateDialogComponent } from './dialogs/configure-digital-signature-dialog/configure-certificate-dialog.component'; -import { PkcsSignatureConfigurationComponent } from './dialogs/configure-digital-signature-dialog/pkcs-signature-configuration/pkcs-signature-configuration.component'; -import { KmsSignatureConfigurationComponent } from './dialogs/configure-digital-signature-dialog/kms-signature-configuration/kms-signature-configuration.component'; +import { PkcsSignatureConfigurationComponent } from './dialogs/configure-digital-signature-dialog/form/pkcs-signature-configuration/pkcs-signature-configuration.component'; +import { KmsSignatureConfigurationComponent } from './dialogs/configure-digital-signature-dialog/form/kms-signature-configuration/kms-signature-configuration.component'; const dialogs = [ AddEditDossierTemplateDialogComponent, diff --git a/apps/red-ui/src/app/modules/admin/dialogs/configure-digital-signature-dialog/configure-certificate-dialog.component.html b/apps/red-ui/src/app/modules/admin/dialogs/configure-digital-signature-dialog/configure-certificate-dialog.component.html index 203eb8b54..51d0ea681 100644 --- a/apps/red-ui/src/app/modules/admin/dialogs/configure-digital-signature-dialog/configure-certificate-dialog.component.html +++ b/apps/red-ui/src/app/modules/admin/dialogs/configure-digital-signature-dialog/configure-certificate-dialog.component.html @@ -23,7 +23,6 @@ {{ 'digital-signature-dialog.upload-warning-message' | translate }} - -
diff --git a/apps/red-ui/src/app/modules/admin/dialogs/configure-digital-signature-dialog/configure-certificate-dialog.component.scss b/apps/red-ui/src/app/modules/admin/dialogs/configure-digital-signature-dialog/configure-certificate-dialog.component.scss index ad58f439f..9348c9978 100644 --- a/apps/red-ui/src/app/modules/admin/dialogs/configure-digital-signature-dialog/configure-certificate-dialog.component.scss +++ b/apps/red-ui/src/app/modules/admin/dialogs/configure-digital-signature-dialog/configure-certificate-dialog.component.scss @@ -33,10 +33,5 @@ .selected { background: rgba(variables.$red-1, 0.1); } - - iqser-upload-file { - padding-top: 24px; - padding-bottom: 24px; - } } } diff --git a/apps/red-ui/src/app/modules/admin/dialogs/configure-digital-signature-dialog/configure-certificate-dialog.component.ts b/apps/red-ui/src/app/modules/admin/dialogs/configure-digital-signature-dialog/configure-certificate-dialog.component.ts index f8f625078..bbb6c2ba8 100644 --- a/apps/red-ui/src/app/modules/admin/dialogs/configure-digital-signature-dialog/configure-certificate-dialog.component.ts +++ b/apps/red-ui/src/app/modules/admin/dialogs/configure-digital-signature-dialog/configure-certificate-dialog.component.ts @@ -1,14 +1,15 @@ -import { Component, Injector, ViewChild } from '@angular/core'; +import { ChangeDetectorRef, Component, Injector, ViewChild } from '@angular/core'; import { digitalSignatureDialogTranslations } from '../../translations/digital-signature-dialog-translations'; -import { BaseDialogComponent } from '../../../../../../../../libs/common-ui/src'; +import { BaseDialogComponent, LoadingService, Toaster } from '../../../../../../../../libs/common-ui/src'; import { MatDialogRef } from '@angular/material/dialog'; -import { PkcsSignatureConfigurationComponent } from './pkcs-signature-configuration/pkcs-signature-configuration.component'; -import { KmsSignatureConfigurationComponent } from './kms-signature-configuration/kms-signature-configuration.component'; +import { PkcsSignatureConfigurationComponent } from './form/pkcs-signature-configuration/pkcs-signature-configuration.component'; +import { KmsSignatureConfigurationComponent } from './form/kms-signature-configuration/kms-signature-configuration.component'; +import { marker as _ } from '@biesbjerg/ngx-translate-extract-marker'; +import { HttpStatusCode } from '@angular/common/http'; +import { CertificateType } from '../../screens/digital-signature/digital-signature-screen.component'; -enum CertificateType { - PKCS = 'pkcs', - KMS = 'kms', -} +const DEFAULT_DIALOG_WIDTH = '662px'; +const KMS_SIGNATURE_DIALOG_WIDTH = '810px'; @Component({ templateUrl: './configure-certificate-dialog.component.html', @@ -25,18 +26,47 @@ export class ConfigureCertificateDialogComponent extends BaseDialogComponent { selectedOption = this.certificateOptions[0]; isInConfiguration = false; - constructor(protected readonly _injector: Injector, protected readonly _dialogRef: MatDialogRef) { + constructor( + protected readonly _injector: Injector, + protected readonly _dialogRef: MatDialogRef, + private readonly _loadingService: LoadingService, + private readonly _toaster: Toaster, + private readonly _changeDetectorRef: ChangeDetectorRef, + ) { super(_injector, _dialogRef); } toggleIsInConfiguration() { this.isInConfiguration = !this.isInConfiguration; if (this.isInConfiguration && this.selectedOption === CertificateType.KMS) { - this._dialogRef.updateSize('810px'); + this._dialogRef.updateSize(KMS_SIGNATURE_DIALOG_WIDTH); } else { - this._dialogRef.updateSize('662px'); + this._dialogRef.updateSize(DEFAULT_DIALOG_WIDTH); } + this._changeDetectorRef.detectChanges(); } - save() {} + get disabled(): boolean { + return this.activeComponent?.disabled; + } + + get activeComponent() { + return this.selectedOption === CertificateType.PKCS + ? this.pkcsSignatureConfigurationComponent + : this.kmsSignatureConfigurationComponent; + } + + async save(): Promise { + try { + await this.activeComponent.save(); + this._toaster.success(_('digital-signature-dialog.actions.save-success')); + this._dialogRef.close(true); + } catch (error) { + if (error.status === HttpStatusCode.BadRequest) { + this._toaster.error(_('digital-signature-dialog.actions.certificate-not-valid-error')); + } else { + this._toaster.error(_('digital-signature-dialog.actions.save-error')); + } + } + } } diff --git a/apps/red-ui/src/app/modules/admin/dialogs/configure-digital-signature-dialog/form/base-signature-configuration-component.ts b/apps/red-ui/src/app/modules/admin/dialogs/configure-digital-signature-dialog/form/base-signature-configuration-component.ts new file mode 100644 index 000000000..19d5099c7 --- /dev/null +++ b/apps/red-ui/src/app/modules/admin/dialogs/configure-digital-signature-dialog/form/base-signature-configuration-component.ts @@ -0,0 +1,42 @@ +import { BaseFormComponent } from '@iqser/common-ui'; +import { lastIndexOfEnd } from '../../../../../utils'; + +export abstract class BaseSignatureConfigurationComponent extends BaseFormComponent { + constructor(private readonly _certificateFormKey: string) { + super(); + } + + setCertificateName(file: File | null): void { + if (file) { + let name = file.name.split('.')[0]; + name = name.replace(/-/g, ' '); + this.form.controls['certificateName'].setValue(name); + } else { + this.form.controls['certificateName'].setValue(''); + } + } + + addRemoveCertificate(file: File | null): void { + this.setCertificateName(file); + if (file) { + const fileReader = new FileReader(); + fileReader.onload = () => { + const dataUrl = fileReader.result; + const actualBase64Value = dataUrl.substring(lastIndexOfEnd(dataUrl, ';base64,')); + this.form.get(this._certificateFormKey).setValue(actualBase64Value); + }; + fileReader.readAsDataURL(file as Blob); + } else { + this.form.controls[this._certificateFormKey].setValue(''); + } + } + + generateFile(certificateName: string, extension: '.p12' | '.pem'): File | null { + if (certificateName) { + return { + name: certificateName.split(' ').join('-') + extension, + } as File; + } + return null; + } +} diff --git a/apps/red-ui/src/app/modules/admin/dialogs/configure-digital-signature-dialog/kms-signature-configuration/kms-signature-configuration.component.html b/apps/red-ui/src/app/modules/admin/dialogs/configure-digital-signature-dialog/form/kms-signature-configuration/kms-signature-configuration.component.html similarity index 91% rename from apps/red-ui/src/app/modules/admin/dialogs/configure-digital-signature-dialog/kms-signature-configuration/kms-signature-configuration.component.html rename to apps/red-ui/src/app/modules/admin/dialogs/configure-digital-signature-dialog/form/kms-signature-configuration/kms-signature-configuration.component.html index 79c64fa12..32c5ee3ab 100644 --- a/apps/red-ui/src/app/modules/admin/dialogs/configure-digital-signature-dialog/kms-signature-configuration/kms-signature-configuration.component.html +++ b/apps/red-ui/src/app/modules/admin/dialogs/configure-digital-signature-dialog/form/kms-signature-configuration/kms-signature-configuration.component.html @@ -1,3 +1,4 @@ +
@@ -28,7 +29,7 @@
-
+
diff --git a/apps/red-ui/src/app/modules/admin/dialogs/configure-digital-signature-dialog/kms-signature-configuration/kms-signature-configuration.component.scss b/apps/red-ui/src/app/modules/admin/dialogs/configure-digital-signature-dialog/form/kms-signature-configuration/kms-signature-configuration.component.scss similarity index 52% rename from apps/red-ui/src/app/modules/admin/dialogs/configure-digital-signature-dialog/kms-signature-configuration/kms-signature-configuration.component.scss rename to apps/red-ui/src/app/modules/admin/dialogs/configure-digital-signature-dialog/form/kms-signature-configuration/kms-signature-configuration.component.scss index b566c7e18..9b54c29df 100644 --- a/apps/red-ui/src/app/modules/admin/dialogs/configure-digital-signature-dialog/kms-signature-configuration/kms-signature-configuration.component.scss +++ b/apps/red-ui/src/app/modules/admin/dialogs/configure-digital-signature-dialog/form/kms-signature-configuration/kms-signature-configuration.component.scss @@ -6,3 +6,9 @@ height: 100%; } } + +iqser-upload-file { + display: block; + margin-top: 24px; + margin-bottom: 24px; +} diff --git a/apps/red-ui/src/app/modules/admin/dialogs/configure-digital-signature-dialog/form/kms-signature-configuration/kms-signature-configuration.component.ts b/apps/red-ui/src/app/modules/admin/dialogs/configure-digital-signature-dialog/form/kms-signature-configuration/kms-signature-configuration.component.ts new file mode 100644 index 000000000..1c6a29161 --- /dev/null +++ b/apps/red-ui/src/app/modules/admin/dialogs/configure-digital-signature-dialog/form/kms-signature-configuration/kms-signature-configuration.component.ts @@ -0,0 +1,43 @@ +import { ChangeDetectionStrategy, Component, Input, OnInit } from '@angular/core'; +import { FormBuilder, Validators } from '@angular/forms'; +import { BaseSignatureConfigurationComponent } from '../base-signature-configuration-component'; +import { IKmsDigitalSignature, IPkcsDigitalSignature } from '../../../../../../../../../../libs/red-domain/src'; +import { lastIndexOfEnd } from '../../../../../../utils'; +import { firstValueFrom } from 'rxjs'; +import { DigitalSignatureService } from '../../../../services/digital-signature.service'; + +@Component({ + selector: 'redaction-kms-signature-configuration', + templateUrl: './kms-signature-configuration.component.html', + styleUrls: ['./kms-signature-configuration.component.scss'], + changeDetection: ChangeDetectionStrategy.OnPush, +}) +export class KmsSignatureConfigurationComponent extends BaseSignatureConfigurationComponent implements OnInit { + @Input() digitalSignature!: IKmsDigitalSignature; + file: File | null; + + constructor(private readonly _formBuilder: FormBuilder, private readonly _digitalSignatureService: DigitalSignatureService) { + super('certificate'); + } + + ngOnInit() { + this.form = this._formBuilder.group({ + certificateName: [this.digitalSignature?.certificateName, Validators.required], + kmsServiceEndpoint: [this.digitalSignature?.kmsServiceEndpoint, Validators.required], + kmsRegion: [this.digitalSignature?.kmsRegion, Validators.required], + kmsKeyId: [this.digitalSignature?.kmsKeyId, Validators.required], + kmsAccessKey: [this.digitalSignature?.kmsAccessKey, Validators.required], + kmsSecretKey: [this.digitalSignature?.kmsSecretKey, this.digitalSignature ? Validators.required : null], + certificate: [this.digitalSignature?.certificate, this.digitalSignature ? Validators.required : null], + }); + this.initialFormValue = this.form.getRawValue(); + this.file = this.generateFile(this.digitalSignature?.certificateName, '.pem'); + } + + async save() { + const formValue = this.form.getRawValue(); + const digitalSignature: IKmsDigitalSignature = { ...formValue }; + + return await firstValueFrom(this._digitalSignatureService.saveKmsSignature(digitalSignature)); + } +} diff --git a/apps/red-ui/src/app/modules/admin/dialogs/configure-digital-signature-dialog/pkcs-signature-configuration/pkcs-signature-configuration.component.html b/apps/red-ui/src/app/modules/admin/dialogs/configure-digital-signature-dialog/form/pkcs-signature-configuration/pkcs-signature-configuration.component.html similarity index 85% rename from apps/red-ui/src/app/modules/admin/dialogs/configure-digital-signature-dialog/pkcs-signature-configuration/pkcs-signature-configuration.component.html rename to apps/red-ui/src/app/modules/admin/dialogs/configure-digital-signature-dialog/form/pkcs-signature-configuration/pkcs-signature-configuration.component.html index adc6b7c97..246e00946 100644 --- a/apps/red-ui/src/app/modules/admin/dialogs/configure-digital-signature-dialog/pkcs-signature-configuration/pkcs-signature-configuration.component.html +++ b/apps/red-ui/src/app/modules/admin/dialogs/configure-digital-signature-dialog/form/pkcs-signature-configuration/pkcs-signature-configuration.component.html @@ -1,3 +1,4 @@ +
@@ -5,7 +6,7 @@
-
+
diff --git a/apps/red-ui/src/app/modules/admin/dialogs/configure-digital-signature-dialog/form/pkcs-signature-configuration/pkcs-signature-configuration.component.scss b/apps/red-ui/src/app/modules/admin/dialogs/configure-digital-signature-dialog/form/pkcs-signature-configuration/pkcs-signature-configuration.component.scss new file mode 100644 index 000000000..e821f1e30 --- /dev/null +++ b/apps/red-ui/src/app/modules/admin/dialogs/configure-digital-signature-dialog/form/pkcs-signature-configuration/pkcs-signature-configuration.component.scss @@ -0,0 +1,9 @@ +textarea { + resize: none; +} + +iqser-upload-file { + display: block; + margin-top: 24px; + margin-bottom: 24px; +} diff --git a/apps/red-ui/src/app/modules/admin/dialogs/configure-digital-signature-dialog/form/pkcs-signature-configuration/pkcs-signature-configuration.component.ts b/apps/red-ui/src/app/modules/admin/dialogs/configure-digital-signature-dialog/form/pkcs-signature-configuration/pkcs-signature-configuration.component.ts new file mode 100644 index 000000000..3559ddf26 --- /dev/null +++ b/apps/red-ui/src/app/modules/admin/dialogs/configure-digital-signature-dialog/form/pkcs-signature-configuration/pkcs-signature-configuration.component.ts @@ -0,0 +1,43 @@ +import { ChangeDetectionStrategy, Component, Input, OnInit } from '@angular/core'; +import { FormBuilder, FormGroup, Validators } from '@angular/forms'; +import { BaseSignatureConfigurationComponent } from '../base-signature-configuration-component'; +import { lastIndexOfEnd } from '../../../../../../utils'; +import { IPkcsDigitalSignature } from '../../../../../../../../../../libs/red-domain/src'; +import { firstValueFrom } from 'rxjs'; +import { LoadingService } from '../../../../../../../../../../libs/common-ui/src'; +import { DigitalSignatureService } from '../../../../services/digital-signature.service'; + +@Component({ + selector: 'redaction-pkcs-signature-configuration', + templateUrl: './pkcs-signature-configuration.component.html', + styleUrls: ['./pkcs-signature-configuration.component.scss'], + changeDetection: ChangeDetectionStrategy.OnPush, +}) +export class PkcsSignatureConfigurationComponent extends BaseSignatureConfigurationComponent implements OnInit { + @Input() digitalSignature!: IPkcsDigitalSignature; + file: File | null; + + constructor(private readonly _formBuilder: FormBuilder, private readonly _digitalSignatureService: DigitalSignatureService) { + super('base64EncodedPrivateKey'); + } + + ngOnInit() { + this.form = this._formBuilder.group({ + certificateName: [this.digitalSignature?.certificateName, Validators.required], + password: [this.digitalSignature?.password, !this.digitalSignature ? Validators.required : null], + contactInfo: [this.digitalSignature?.contactInfo], + location: [this.digitalSignature?.location], + reason: [this.digitalSignature?.reason], + base64EncodedPrivateKey: [this.digitalSignature?.base64EncodedPrivateKey, !this.digitalSignature ? Validators.required : null], + }); + this.initialFormValue = this.form.getRawValue(); + this.file = this.generateFile(this.digitalSignature?.certificateName, '.p12'); + } + + async save() { + const formValue = this.form.getRawValue(); + const digitalSignature: IPkcsDigitalSignature = { ...formValue }; + + return await firstValueFrom(this._digitalSignatureService.saveSignature(digitalSignature)); + } +} diff --git a/apps/red-ui/src/app/modules/admin/dialogs/configure-digital-signature-dialog/kms-signature-configuration/kms-signature-configuration.component.ts b/apps/red-ui/src/app/modules/admin/dialogs/configure-digital-signature-dialog/kms-signature-configuration/kms-signature-configuration.component.ts deleted file mode 100644 index ef66f801e..000000000 --- a/apps/red-ui/src/app/modules/admin/dialogs/configure-digital-signature-dialog/kms-signature-configuration/kms-signature-configuration.component.ts +++ /dev/null @@ -1,26 +0,0 @@ -import { ChangeDetectionStrategy, Component, OnInit } from '@angular/core'; -import { FormBuilder, FormGroup, Validators } from '@angular/forms'; - -@Component({ - selector: 'redaction-kms-signature-configuration', - templateUrl: './kms-signature-configuration.component.html', - styleUrls: ['./kms-signature-configuration.component.scss'], - changeDetection: ChangeDetectionStrategy.OnPush, -}) -export class KmsSignatureConfigurationComponent implements OnInit { - form: FormGroup; - - constructor(private readonly _formBuilder: FormBuilder) {} - - ngOnInit() { - this.form = this._formBuilder.group({ - certificateName: ['', Validators.required], - kmsServiceEndpoint: ['', Validators.required], - kmsRegion: ['', Validators.required], - kmsKeyId: ['', Validators.required], - kmsAccessKey: ['', Validators.required], - kmsSecretKey: ['', Validators.required], - certificate: ['', Validators.required], - }); - } -} diff --git a/apps/red-ui/src/app/modules/admin/dialogs/configure-digital-signature-dialog/pkcs-signature-configuration/pkcs-signature-configuration.component.scss b/apps/red-ui/src/app/modules/admin/dialogs/configure-digital-signature-dialog/pkcs-signature-configuration/pkcs-signature-configuration.component.scss deleted file mode 100644 index 2e0c215b3..000000000 --- a/apps/red-ui/src/app/modules/admin/dialogs/configure-digital-signature-dialog/pkcs-signature-configuration/pkcs-signature-configuration.component.scss +++ /dev/null @@ -1,3 +0,0 @@ -textarea { - resize: none; -} diff --git a/apps/red-ui/src/app/modules/admin/dialogs/configure-digital-signature-dialog/pkcs-signature-configuration/pkcs-signature-configuration.component.ts b/apps/red-ui/src/app/modules/admin/dialogs/configure-digital-signature-dialog/pkcs-signature-configuration/pkcs-signature-configuration.component.ts deleted file mode 100644 index 4bddc2b8f..000000000 --- a/apps/red-ui/src/app/modules/admin/dialogs/configure-digital-signature-dialog/pkcs-signature-configuration/pkcs-signature-configuration.component.ts +++ /dev/null @@ -1,24 +0,0 @@ -import { ChangeDetectionStrategy, Component, OnInit } from '@angular/core'; -import { FormBuilder, FormGroup, Validators } from '@angular/forms'; - -@Component({ - selector: 'redaction-pkcs-signature-configuration', - templateUrl: './pkcs-signature-configuration.component.html', - styleUrls: ['./pkcs-signature-configuration.component.scss'], - changeDetection: ChangeDetectionStrategy.OnPush, -}) -export class PkcsSignatureConfigurationComponent implements OnInit { - form: FormGroup; - - constructor(private readonly _formBuilder: FormBuilder) {} - - ngOnInit() { - this.form = this._formBuilder.group({ - certificateName: ['', Validators.required], - password: ['', Validators.required], - contactInfo: [''], - location: [''], - reason: [''], - }); - } -} diff --git a/apps/red-ui/src/app/modules/admin/screens/digital-signature/digital-signature-screen.component.html b/apps/red-ui/src/app/modules/admin/screens/digital-signature/digital-signature-screen.component.html index fc7f7e306..c54eeefa0 100644 --- a/apps/red-ui/src/app/modules/admin/screens/digital-signature/digital-signature-screen.component.html +++ b/apps/red-ui/src/app/modules/admin/screens/digital-signature/digital-signature-screen.component.html @@ -13,92 +13,42 @@
- - + - + + + + -
- - -
+
+
- - -
- -
- - -
- -
- - -
- -
- - -
- -
- - - - -
-
- + (click)="removeDigitalSignature()" + *ngIf="digitalSignature" + class="all-caps-label cancel" + translate="digital-signature-screen.action.remove" + >
+
diff --git a/apps/red-ui/src/app/modules/admin/screens/digital-signature/digital-signature-screen.component.ts b/apps/red-ui/src/app/modules/admin/screens/digital-signature/digital-signature-screen.component.ts index 3d29517a2..710669630 100644 --- a/apps/red-ui/src/app/modules/admin/screens/digital-signature/digital-signature-screen.component.ts +++ b/apps/red-ui/src/app/modules/admin/screens/digital-signature/digital-signature-screen.component.ts @@ -1,15 +1,20 @@ -import { Component, OnInit } from '@angular/core'; -import { FormBuilder, FormGroup, Validators } from '@angular/forms'; -import { lastIndexOfEnd } from '@utils/functions'; +import { ChangeDetectorRef, Component, OnInit, ViewChild } from '@angular/core'; import { IconButtonTypes, LoadingService, Toaster } from '@iqser/common-ui'; import { marker as _ } from '@biesbjerg/ngx-translate-extract-marker'; import { UserService } from '@services/user.service'; import { RouterHistoryService } from '@services/router-history.service'; import { DigitalSignatureService } from '../../services/digital-signature.service'; -import { IDigitalSignature } from '@red/domain'; import { firstValueFrom } from 'rxjs'; -import { HttpStatusCode } from '@angular/common/http'; import { AdminDialogService } from '../../services/admin-dialog.service'; +import { PkcsSignatureConfigurationComponent } from '../../dialogs/configure-digital-signature-dialog/form/pkcs-signature-configuration/pkcs-signature-configuration.component'; +import { KmsSignatureConfigurationComponent } from '../../dialogs/configure-digital-signature-dialog/form/kms-signature-configuration/kms-signature-configuration.component'; +import { IKmsDigitalSignatureRequest, IPkcsDigitalSignatureRequest } from '../../../../../../../../libs/red-domain/src'; +import { HttpStatusCode } from '@angular/common/http'; + +export enum CertificateType { + PKCS = 'pkcs', + KMS = 'kms', +} @Component({ selector: 'redaction-digital-signature-screen', @@ -17,66 +22,34 @@ import { AdminDialogService } from '../../services/admin-dialog.service'; styleUrls: ['./digital-signature-screen.component.scss'], }) export class DigitalSignatureScreenComponent implements OnInit { + @ViewChild(PkcsSignatureConfigurationComponent) pkcsSignatureConfigurationComponent: PkcsSignatureConfigurationComponent; + @ViewChild(KmsSignatureConfigurationComponent) kmsSignatureConfigurationComponent: KmsSignatureConfigurationComponent; + + readonly certificateType = CertificateType; readonly iconButtonTypes = IconButtonTypes; readonly currentUser = this._userService.currentUser; - digitalSignature: IDigitalSignature; - form: FormGroup; - - digitalSignatureExists = false; + digitalSignature: IPkcsDigitalSignatureRequest | IKmsDigitalSignatureRequest; constructor( private readonly _toaster: Toaster, - private readonly _formBuilder: FormBuilder, private readonly _userService: UserService, private readonly _loadingService: LoadingService, private readonly _digitalSignatureService: DigitalSignatureService, private readonly _dialogService: AdminDialogService, + private readonly _changeDetectorRef: ChangeDetectorRef, readonly routerHistoryService: RouterHistoryService, ) {} - get hasDigitalSignatureSet() { - return this.digitalSignatureExists || !!this.form.get('base64EncodedPrivateKey').value; - } - async ngOnInit(): Promise { - await this.loadDigitalSignatureAndInitializeForm(); - } - - async saveDigitalSignature(): Promise { - this._loadingService.start(); - const formValue = this.form.getRawValue(); - const digitalSignature: IDigitalSignature = { - ...formValue, - }; - //adjusted for chrome auto-complete / password manager - digitalSignature.password = formValue.keySecret; - - const observable = this.digitalSignatureExists - ? this._digitalSignatureService.update(digitalSignature) - : this._digitalSignatureService.save(digitalSignature); - - try { - await firstValueFrom(observable); - await this.loadDigitalSignatureAndInitializeForm(); - this._toaster.success(_('digital-signature-screen.action.save-success')); - } catch (error) { - console.error(error); - if (error.status === HttpStatusCode.BadRequest) { - this._toaster.error(_('digital-signature-screen.action.certificate-not-valid-error')); - } else { - this._toaster.error(_('digital-signature-screen.action.save-error')); - } - } - - this._loadingService.stop(); + await this.loadDigitalSignature(); } async removeDigitalSignature(): Promise { this._loadingService.start(); try { - await firstValueFrom(this._digitalSignatureService.delete()); - await this.loadDigitalSignatureAndInitializeForm(); + await firstValueFrom(this._digitalSignatureService.deleteSignature()); + await this.loadDigitalSignature(); this._toaster.success(_('digital-signature-screen.action.delete-success')); } catch (error) { console.error(error); @@ -84,48 +57,45 @@ export class DigitalSignatureScreenComponent implements OnInit { } } - // fileChanged(event, input: HTMLInputElement) { - // const file = event.target.files[0]; - // const fileReader = new FileReader(); - // fileReader.onload = () => { - // const dataUrl = fileReader.result; - // const actualBase64Value = dataUrl.substring(lastIndexOfEnd(dataUrl, ';base64,')); - // this.form.get('base64EncodedPrivateKey').setValue(actualBase64Value); - // this.form.get('certificateName').setValue(file.name); - // input.value = null; - // }; - // fileReader.readAsDataURL(file as Blob); - // } - - openConfigureCertificate() { - this._dialogService.openDialog('configureCertificate', null, null); + get disabled(): boolean { + return this.activeComponent?.disabled; } - async loadDigitalSignatureAndInitializeForm(): Promise { - this._loadingService.start(); + async saveDigitalSignature(): Promise { try { - const digitalSignature = await firstValueFrom(this._digitalSignatureService.getSignature()); - this.digitalSignatureExists = true; - this.digitalSignature = digitalSignature; + await this.activeComponent.save(); + this._toaster.success(_('digital-signature-screen.action.save-success')); } catch (error) { - this.digitalSignatureExists = false; - this.digitalSignature = {}; + this._toaster.error(_('digital-signature-screen.action.save-error')); } - - this.form = this._getForm(); - this._loadingService.stop(); } - private _getForm(): FormGroup { - return this._formBuilder.group({ - certificateName: [this.digitalSignature.certificateName, Validators.required], - contactInfo: this.digitalSignature.contactInfo, - location: this.digitalSignature.location, - keySecret: this.digitalSignatureExists ? null : [this.digitalSignature.password, Validators.required], - reason: this.digitalSignature.reason, - base64EncodedPrivateKey: this.digitalSignatureExists - ? null - : [this.digitalSignature.base64EncodedPrivateKey, Validators.required], + get currentCertificateType() { + if (!this.digitalSignature) { + return; + } + return 'contactInfo' in this.digitalSignature ? CertificateType.PKCS : CertificateType.KMS; + } + + get activeComponent() { + return this.currentCertificateType === CertificateType.PKCS + ? this.pkcsSignatureConfigurationComponent + : this.kmsSignatureConfigurationComponent; + } + + openConfigureCertificate(): void { + const dialogRef = this._dialogService.openDialog('configureCertificate', null, null); + firstValueFrom(dialogRef.afterClosed()).then(async res => { + if (res) { + await this.loadDigitalSignature(); + } }); } + + async loadDigitalSignature(): Promise { + this._loadingService.start(); + this.digitalSignature = await firstValueFrom(this._digitalSignatureService.getSignature()); + this._loadingService.stop(); + this._changeDetectorRef.detectChanges(); + } } diff --git a/apps/red-ui/src/app/modules/admin/services/digital-signature.service.ts b/apps/red-ui/src/app/modules/admin/services/digital-signature.service.ts index 005bb8b08..9e956e0ed 100644 --- a/apps/red-ui/src/app/modules/admin/services/digital-signature.service.ts +++ b/apps/red-ui/src/app/modules/admin/services/digital-signature.service.ts @@ -1,7 +1,14 @@ import { Injectable, Injector } from '@angular/core'; -import { GenericService, RequiredParam, Validate } from '@iqser/common-ui'; -import { Observable } from 'rxjs'; -import { IDigitalSignature, IDigitalSignatureRequest } from '@red/domain'; +import { filterEach, GenericService, RequiredParam, Validate } from '@iqser/common-ui'; +import { filter, forkJoin, Observable, of } from 'rxjs'; +import { + IDigitalSignatureRequest, + IKmsDigitalSignature, + IKmsDigitalSignatureRequest, + IPkcsDigitalSignature, + IPkcsDigitalSignatureRequest, +} from '@red/domain'; +import { catchError, map, tap } from 'rxjs/operators'; @Injectable() export class DigitalSignatureService extends GenericService { @@ -10,20 +17,39 @@ export class DigitalSignatureService extends GenericService { + updateSignature(@RequiredParam() body: IDigitalSignatureRequest): Observable { return this._put(body); } @Validate() - save(@RequiredParam() body: IDigitalSignature): Observable { + updateKmsSignature(@RequiredParam() body: IKmsDigitalSignatureRequest): Observable { + return this._put(body, `${this._defaultModelPath}/kms`); + } + + @Validate() + saveSignature(@RequiredParam() body: IPkcsDigitalSignature): Observable { return this._post(body); } - delete(): Observable { + @Validate() + saveKmsSignature(@RequiredParam() body: IKmsDigitalSignature): Observable { + return this._post(body, `${this._defaultModelPath}/kms`); + } + + deleteSignature(): Observable { return super.delete({}); } + deleteKmsSignature(): Observable { + return super.delete({}, `${this._defaultModelPath}/kms`); + } + getSignature(): Observable { - return super.getAll(); + const digitalSignature$ = super.getAll().pipe(catchError(() => of(null))); + const kmsDigitalSignature$ = super.getAll(`${this._defaultModelPath}/kms`).pipe(catchError(() => of(null))); + return forkJoin([digitalSignature$, kmsDigitalSignature$]).pipe( + filterEach(signature => !!signature), + map(signatures => signatures[0] as IDigitalSignatureRequest), + ); } } diff --git a/apps/red-ui/src/assets/i18n/de.json b/apps/red-ui/src/assets/i18n/de.json index bb00a1640..0b3680bea 100644 --- a/apps/red-ui/src/assets/i18n/de.json +++ b/apps/red-ui/src/assets/i18n/de.json @@ -659,8 +659,11 @@ "actions": { "back": "", "cancel": "", + "certificate-not-valid-error": "", "continue": "", - "save": "" + "save": "", + "save-error": "", + "save-success": "" }, "forms": { "kms": { @@ -699,38 +702,17 @@ }, "digital-signature-screen": { "action": { - "certificate-not-valid-error": "Das hochgeladene Zertifikat eignet sich nicht zum Signieren von PDF-Dokumenten. Sie benötigen das Format PCKS#12.", - "delete": "Digitale Signatur löschen", + "certificate-not-valid-error": "", "delete-error": "Die digitale Signatur konnte nicht entfernt werden, bitte versuchen Sie es erneut.", "delete-success": "Die digitale Signatur wurde gelöscht. Geschwärzte Dateien werden nicht länger mit einer Signatur versehen!", - "reset": "Zurücksetzen", + "remove": "", "save": "Digitale Signatur speichern", - "save-error": "Fehler beim Speichern der digitalen Signatur", - "save-success": "Digitale Signatur erfolgreich gespeichert" - }, - "certificate-name": { - "label": "Name des Zertifikats", - "placeholder": "Name des Zertifikats" - }, - "contact-info": { - "label": "Kontaktdaten", - "placeholder": "Kontaktdaten" - }, - "location": { - "label": "Ort", - "placeholder": "Ort" + "save-error": "", + "save-success": "" }, "no-data": { "action": "Zertifikat hochladen", "title": "Es ist kein Zertifikat für die digitale Signatur konfiguriert. Laden Sie ein PCKS#12-Zertifikat hoch, um Ihre geschwärzten Dokumente zu signieren." - }, - "password": { - "label": "Zertifikatspasswort/-schlüssel", - "placeholder": "Passwort" - }, - "reason": { - "label": "Begründung", - "placeholder": "Begründung" } }, "document-info": { diff --git a/apps/red-ui/src/assets/i18n/en.json b/apps/red-ui/src/assets/i18n/en.json index b9f0199ce..a42746dcb 100644 --- a/apps/red-ui/src/assets/i18n/en.json +++ b/apps/red-ui/src/assets/i18n/en.json @@ -659,8 +659,11 @@ "actions": { "back": "Back", "cancel": "Cancel", + "certificate-not-valid-error": "Uploaded Certificate is not valid!", "continue": "Continue", - "save": "Save Configurations" + "save": "Save Configurations", + "save-error": "Failed to save digital signature!", + "save-success": "Digital Signature Certificate successfully saved!" }, "forms": { "kms": { @@ -699,38 +702,16 @@ }, "digital-signature-screen": { "action": { - "certificate-not-valid-error": "Uploaded Certificate is not valid for signing PDFs. PCKS.12 format is required.", - "delete": "Delete Digital Signature", "delete-error": "Failed to remove digital signature, please try again.", "delete-success": "Digital signature removed. Redacted files will no longer be signed!", - "reset": "Reset", - "save": "Save Digital Signature", - "save-error": "Failed to save digital signature", - "save-success": "Digital signature saved successfully" - }, - "certificate-name": { - "label": "Certificate Name", - "placeholder": "Certificate Name" - }, - "contact-info": { - "label": "Contact Information", - "placeholder": "Contact Information" - }, - "location": { - "label": "Location", - "placeholder": "Location" + "remove": "Remove", + "save": "Save Changes", + "save-error": "Failed to save digital signature!", + "save-success": "Digital Signature Certificate successfully saved!" }, "no-data": { "action": "Configure Certificate", "title": "No Digital Signature Certificate.
For signing redacted documents please configure a certificate." - }, - "password": { - "label": "Certificate Password/Key", - "placeholder": "Password" - }, - "reason": { - "label": "Reason", - "placeholder": "Reason" } }, "document-info": { diff --git a/libs/common-ui b/libs/common-ui index e7be61eff..1b146037f 160000 --- a/libs/common-ui +++ b/libs/common-ui @@ -1 +1 @@ -Subproject commit e7be61efff0b9baa3d6b53002cbecd8b53d7b934 +Subproject commit 1b146037facaa4d3e5a662fea64f67c0dd8b0110 diff --git a/libs/red-domain/src/lib/signature/digital-signature.request.ts b/libs/red-domain/src/lib/signature/digital-signature-request.ts similarity index 52% rename from libs/red-domain/src/lib/signature/digital-signature.request.ts rename to libs/red-domain/src/lib/signature/digital-signature-request.ts index d7d9fa618..3eb55d4ac 100644 --- a/libs/red-domain/src/lib/signature/digital-signature.request.ts +++ b/libs/red-domain/src/lib/signature/digital-signature-request.ts @@ -1,6 +1,3 @@ export interface IDigitalSignatureRequest { certificateName?: string; - contactInfo?: string; - location?: string; - reason?: string; } diff --git a/libs/red-domain/src/lib/signature/digital-signature.ts b/libs/red-domain/src/lib/signature/digital-signature.ts deleted file mode 100644 index 0b971ca70..000000000 --- a/libs/red-domain/src/lib/signature/digital-signature.ts +++ /dev/null @@ -1,6 +0,0 @@ -import { IDigitalSignatureRequest } from './digital-signature.request'; - -export interface IDigitalSignature extends IDigitalSignatureRequest { - base64EncodedPrivateKey?: string; - password?: string; -} diff --git a/libs/red-domain/src/lib/signature/index.ts b/libs/red-domain/src/lib/signature/index.ts index f5a313484..a6c32906c 100644 --- a/libs/red-domain/src/lib/signature/index.ts +++ b/libs/red-domain/src/lib/signature/index.ts @@ -1,2 +1,5 @@ -export * from './digital-signature.request'; -export * from './digital-signature'; +export * from './pkcs-digital-signature.request'; +export * from './kms-digital-signature.request'; +export * from './pkcs-digital-signature'; +export * from './kms-digital-signature'; +export * from './digital-signature-request'; diff --git a/libs/red-domain/src/lib/signature/kms-digital-signature.request.ts b/libs/red-domain/src/lib/signature/kms-digital-signature.request.ts new file mode 100644 index 000000000..f8261ba11 --- /dev/null +++ b/libs/red-domain/src/lib/signature/kms-digital-signature.request.ts @@ -0,0 +1,8 @@ +import { IDigitalSignatureRequest } from './digital-signature-request'; + +export interface IKmsDigitalSignatureRequest extends IDigitalSignatureRequest { + kmsAccessKey?: string; + kmsKeyId?: string; + kmsRegion?: string; + kmsServiceEndpoint?: string; +} diff --git a/libs/red-domain/src/lib/signature/kms-digital-signature.ts b/libs/red-domain/src/lib/signature/kms-digital-signature.ts new file mode 100644 index 000000000..db37bea71 --- /dev/null +++ b/libs/red-domain/src/lib/signature/kms-digital-signature.ts @@ -0,0 +1,6 @@ +import { IKmsDigitalSignatureRequest } from './kms-digital-signature.request'; + +export interface IKmsDigitalSignature extends IKmsDigitalSignatureRequest { + certificate?: string; + kmsSecretKey?: string; +} diff --git a/libs/red-domain/src/lib/signature/pkcs-digital-signature.request.ts b/libs/red-domain/src/lib/signature/pkcs-digital-signature.request.ts new file mode 100644 index 000000000..06eb9bf84 --- /dev/null +++ b/libs/red-domain/src/lib/signature/pkcs-digital-signature.request.ts @@ -0,0 +1,7 @@ +import { IDigitalSignatureRequest } from './digital-signature-request'; + +export interface IPkcsDigitalSignatureRequest extends IDigitalSignatureRequest { + contactInfo?: string; + location?: string; + reason?: string; +} diff --git a/libs/red-domain/src/lib/signature/pkcs-digital-signature.ts b/libs/red-domain/src/lib/signature/pkcs-digital-signature.ts new file mode 100644 index 000000000..16a6ebfad --- /dev/null +++ b/libs/red-domain/src/lib/signature/pkcs-digital-signature.ts @@ -0,0 +1,6 @@ +import { IPkcsDigitalSignatureRequest } from './pkcs-digital-signature.request'; + +export interface IPkcsDigitalSignature extends IPkcsDigitalSignatureRequest { + base64EncodedPrivateKey?: string; + password?: string; +}