Skip to content
Snippets Groups Projects
signature-method-modal.component.ts 8.29 KiB
Newer Older
import { Component, Input, OnInit } from '@angular/core';
import { LoadingController, ModalController } from '@ionic/angular';
Damien's avatar
Damien committed
import { catchError, tap } from 'rxjs/operators';
import { of } from 'rxjs';
import { HttpClient } from '@angular/common/http';
import { NotificationService } from '../notification.service';
import { TranslateService } from '@ngx-translate/core';
import { ActionsService } from '../actions.service';
import { SignaturesContentService } from '../signatures.service';
import { AuthService } from '../auth.service';
import { FunctionsService } from '../functions.service';

@Component({
    selector: 'signature-method-modal',
    templateUrl: 'signature-method-modal.component.html',
    styleUrls: ['./signature-method-modal.component.scss']
})
export class SignatureMethodModalComponent implements OnInit {
    filters: any = {
        //   onlySmartcards: false,
        expired: false,
    provider: any = null;
    cert: any = null;
    certPem: any = null;
    privateKey: any = null;

    signatures: any[] = [];

    certificate: any;
    signatureLength: any = null;
    @Input() note: string;
    @Input() idsToProcess: any[];
        public modalController: ModalController,
        public http: HttpClient,
        public translate: TranslateService,
        public notificationService: NotificationService,
        public loadingController: LoadingController,
        public signaturesService: SignaturesContentService,
        public actionsService: ActionsService,
        private functionsService: FunctionsService,
        public authService: AuthService
    async ngOnInit(): Promise<void> {
        const signatureModeData = this.authService.signatureRoles.filter((mode: any) => mode.id === this.signatureMode)[0];
        if (!this.functionsService.empty(signatureModeData.issuer)) {
            this.filters.issuerDNMatch = new RegExp(signatureModeData.issuer, 'i');
        }
        if (!this.functionsService.empty(signatureModeData.subject)) {
            this.filters.subjectDNMatch = new RegExp(signatureModeData.subject, 'i');
        }
        if (!this.functionsService.empty(signatureModeData.keyUsage)) {
            this.filters.keyUsage.push(signatureModeData.keyUsage);
        }
        // this.loadingController.create({
        //     message: this.translate.instant('lang.processing'),
        //     spinner: 'dots'
        // }).then(async (load: HTMLIonLoadingElement) => {
        //     load.present();
                this.server = certData.detail.server;
                this.checkWebsocketSession();
                this.provider = await certData.detail.server.getCrypto(certData.detail.providerId);
                this.checkWebsocketSession();
                this.cert = await this.provider.certStorage.getItem(certData.detail.certificateId);
                this.checkWebsocketSession();
                this.certPem = await this.provider.certStorage.exportCert('pem', this.cert);
                this.checkWebsocketSession();
                this.privateKey = await this.provider.keyStorage.getItem(certData.detail.privateKeyId);
            } catch (e) {
                console.log('certificateChosen');
                this.notificationService.error(e);
                // load.dismiss();
                this.modalController.dismiss(false);
                return;
            }
                certificate: this.certPem
Damien's avatar
Damien committed
            };
            let result: any = false;
            for (let index = 0; index < this.idsToProcess.length; index++) {
                this.signatures = await this.actionsService.getElementsFromDoc();
                result = await this.sendAndSign(this.idsToProcess[index]);
            }
            this.modalController.dismiss(result);
        // });
    }

    async checkWebsocketSession() {
        // Why session closed?!
        while(this.server.client.state !== WebSocket.OPEN) {
            await this.server.connect();
            await new Promise(resolve => setTimeout(resolve, 150));
        }
    async sendAndSign(idToProcess: number) {
        let allSignaturesComplete: boolean = false;
        let res: any = {};
        while (!allSignaturesComplete) {
            let signDocComplete: any = false;
            while (signDocComplete === false) {
                res = await this.fusionStampAndGenerateSignature(idToProcess, res.tmpUniqueId);
                if (res === null) {
                    return false;
                } else if (res !== false) {
                    signDocComplete = await this.signDocument(idToProcess, res.hashDocument, res.signatureContentLength, res.signatureFieldName, res.tmpUniqueId);
                    console.log('signDocComplete', signDocComplete);
                    if (signDocComplete === true) {
                        this.signatures.shift();
                        allSignaturesComplete = this.signatures.length === 0;
                    } else {
                        return false;
                    }
                } else {
                    return false;
                }
            }
        }
        return allSignaturesComplete;
    }

    async fusionStampAndGenerateSignature(idToProcess: number, tmpUniqueId: string = null) {
        res = await this.actionsService.sendDocument(idToProcess, null, this.certificate, this.signatureLength, tmpUniqueId, this.signatures);
    signDocument(idToProcess: number, hashDocument: any, eSignatureLength: any, signatureFieldName: any, tmpUniqueId: string) {
        return new Promise(async (resolve) => {
            const alg = {
                name: this.privateKey.algorithm.name,
                hash: 'SHA-256',
            };
            const hashDocumentHex = this.fromHex(hashDocument);

            let hashSignature: any;

                this.checkWebsocketSession();
                hashSignature = await this.provider.subtle.sign(alg, this.privateKey, hashDocumentHex);
            } catch (e) {
                console.log('signDocument');
                this.notificationService.error(e);
            const objEsign = {
                signatures : this.signatures,
                certificate: this.certPem,
                hashSignature: this.toHex(hashSignature),
                signatureContentLength: eSignatureLength,
                signatureFieldName: signatureFieldName,
Damien's avatar
Damien committed
            };
            this.http.put('../rest/documents/' + idToProcess + '/actions/' + this.signaturesService.currentAction, objToSend)
                        resolve(true);
                    }),
                    catchError((err: any) => {
                        if (err.error.newSignatureLength !== undefined) {
                            this.signatureLength = err.error.newSignatureLength;
                            resolve(false);
                        } else {
                            this.notificationService.handleErrors(err);
                        return of(false);
                    })
                ).subscribe();

        });
    }

        this.modalController.dismiss(false);
    }

    toHex(buffer: any) {
Damien's avatar
Damien committed
        const buf = new Uint8Array(buffer),
            splitter = '',
            res = [],
            len = buf.length;

        for (let i = 0; i < len; i++) {
            const char = buf[i].toString(16);
Damien's avatar
Damien committed
            res.push(char.length === 1 ? '0' + char : char);
        }
        return res.join(splitter);
    }

    fromHex(hexString: any) {
        const res = new Uint8Array(hexString.length / 2);
        for (let i = 0; i < hexString.length; i = i + 2) {
            const c = hexString.slice(i, i + 2);
            res[i / 2] = parseInt(c, 16);
        }
        return res.buffer;
    }