From 46f940d91c8ae438833c2cb49529e70cb08d60f7 Mon Sep 17 00:00:00 2001
From: Alex ORLUC <alex.orluc@maarch.org>
Date: Thu, 10 Dec 2020 12:35:19 +0100
Subject: [PATCH] FEAT #14565 TIME 2:30 WIP front rgs sign

---
 .../controllers/DocumentController.php        |   6 +-
 .../app/document/document.component.ts        |   6 +
 src/frontend/app/service/actions.service.ts   | 103 +++++++++++++++
 .../signature-method-modal.component.ts       | 125 ++++++++++++++----
 4 files changed, 211 insertions(+), 29 deletions(-)
 create mode 100644 src/frontend/app/service/actions.service.ts

diff --git a/src/app/document/controllers/DocumentController.php b/src/app/document/controllers/DocumentController.php
index b18661bfbf..8644ba4c12 100755
--- a/src/app/document/controllers/DocumentController.php
+++ b/src/app/document/controllers/DocumentController.php
@@ -770,9 +770,9 @@ class DocumentController
         } elseif ($workflow['signature_mode'] == 'rgs_2stars' && !empty($body['hashSignature'])) {
             $return = CertificateSignatureController::signDocument([
                 'id'                     => $args['id'],
-                'certificate'            => $args['certificate'],
-                'signatureContentLength' => $args['signatureContentLength'],
-                'hashSignature'          => $args['hashSignature']
+                'certificate'            => $body['certificate'],
+                'signatureContentLength' => $body['signatureContentLength'],
+                'hashSignature'          => $body['hashSignature']
             ]);
             if (!empty($return['errors'])) {
                 return $response->withStatus(400)->withJson($return);
diff --git a/src/frontend/app/document/document.component.ts b/src/frontend/app/document/document.component.ts
index 7174e44c7a..a5e0ea5c5d 100755
--- a/src/frontend/app/document/document.component.ts
+++ b/src/frontend/app/document/document.component.ts
@@ -692,6 +692,12 @@ export class DocumentComponent implements OnInit {
                                 load.present();
                                 const res = await this.sendDocument({ 'note': data.paragraph, 'certInfo': certInfo });
                                 if (res) {
+                                    if (this.signaturesService.documentsList[this.signaturesService.indexDocumentsList] !== undefined) {
+                                        this.signaturesService.documentsList.splice(this.signaturesService.indexDocumentsList, 1);
+                                        if (this.signaturesService.documentsListCount.current > 0) {
+                                            this.signaturesService.documentsListCount.current--;
+                                        }
+                                    }
                                     const config: MatBottomSheetConfig = {
                                         disableClose: true,
                                         direction: 'ltr'
diff --git a/src/frontend/app/service/actions.service.ts b/src/frontend/app/service/actions.service.ts
new file mode 100644
index 0000000000..216579d063
--- /dev/null
+++ b/src/frontend/app/service/actions.service.ts
@@ -0,0 +1,103 @@
+import { HttpClient } from '@angular/common/http';
+import { Injectable } from '@angular/core';
+import { TranslateService } from '@ngx-translate/core';
+import { LatinisePipe } from 'ngx-pipes';
+import { tap, exhaustMap, catchError } from 'rxjs/operators';
+import { SignaturesContentService } from './signatures.service';
+import { NotificationService } from '../service/notification.service';
+import { of } from 'rxjs';
+
+@Injectable({
+    providedIn: 'root'
+})
+export class ActionsService {
+
+    constructor(
+        public http: HttpClient,
+        public translate: TranslateService,
+        private latinisePipe: LatinisePipe,
+        public notificationService: NotificationService,
+        public signaturesService: SignaturesContentService,
+    ) { }
+
+    sendDocument(eSignature: any = null) {
+        return new Promise(async (resolve) => {
+            const signatures: any[] = [];
+            if (this.signaturesService.currentAction > 0) {
+                for (let index = 1; index <= this.signaturesService.totalPage; index++) {
+                    if (this.signaturesService.datesContent[index]) {
+                        this.signaturesService.datesContent[index].forEach((date: any) => {
+                            signatures.push(
+                                {
+                                    'encodedImage': date.content.replace('data:image/svg+xml;base64,', ''),
+                                    'width': date.width,
+                                    'positionX': date.positionX,
+                                    'positionY': date.positionY,
+                                    'type': 'SVG',
+                                    'page': index,
+                                }
+                            );
+                        });
+                    }
+                    if (this.signaturesService.signaturesContent[index]) {
+                        this.signaturesService.signaturesContent[index].forEach((signature: any) => {
+                            signatures.push(
+                                {
+                                    'encodedImage': signature.encodedSignature,
+                                    'width': signature.width,
+                                    'positionX': signature.positionX,
+                                    'positionY': signature.positionY,
+                                    'type': 'PNG',
+                                    'page': index,
+                                }
+                            );
+                        });
+                    }
+                    if (this.signaturesService.notesContent[index]) {
+                        this.signaturesService.notesContent[index].forEach((note: any) => {
+                            signatures.push(
+                                {
+                                    'encodedImage': note.fullPath.replace('data:image/png;base64,', ''),
+                                    'width': note.width,
+                                    'positionX': note.positionX,
+                                    'positionY': note.positionY,
+                                    'type': 'PNG',
+                                    'page': index,
+                                }
+                            );
+                        });
+                    }
+                }
+                let data: any = {};
+                
+                data.signatures = signatures;
+
+                if (eSignature !== null) {
+                    data = {...data, ...eSignature }
+                }
+
+                this.http.put('../rest/documents/' + this.signaturesService.mainDocumentId + '/actions/' + this.signaturesService.currentAction, data)
+                    .pipe(
+                        tap((res: any) => {
+                            if (eSignature !== null) {
+                                const objSignData = {
+                                    hashDocument : res.dataToSign,
+                                    signatureContentLength : res.signatureContentLength
+                                }
+                                resolve(objSignData);
+                            } else {
+                                resolve(true);
+                            } 
+                        }),
+                        catchError((err: any) => {
+                            this.notificationService.handleErrors(err);
+                            resolve(false);
+                            return of(false);
+                        })
+                    ).subscribe();
+            } else {
+                resolve(false);
+            }
+        });
+    }
+}
diff --git a/src/frontend/app/service/signature-method/signature-method-modal.component.ts b/src/frontend/app/service/signature-method/signature-method-modal.component.ts
index 0ce6cac380..54014c2d50 100644
--- a/src/frontend/app/service/signature-method/signature-method-modal.component.ts
+++ b/src/frontend/app/service/signature-method/signature-method-modal.component.ts
@@ -1,9 +1,12 @@
 import { Component, Input, OnInit } from '@angular/core';
-import { ModalController } from '@ionic/angular';
-import {catchError, exhaustMap, tap} from 'rxjs/operators';
-import {of} from 'rxjs';
-import {HttpClient} from '@angular/common/http';
-import {NotificationService} from '../notification.service';
+import { LoadingController, ModalController } from '@ionic/angular';
+import { catchError, exhaustMap, 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';
 
 @Component({
     selector: 'signature-method-modal',
@@ -28,12 +31,21 @@ export class SignatureMethodModalComponent implements OnInit {
         onlyWithPrivateKey: true
     };
 
+    provider: any = null;
+    cert: any = null;
+    certPem: any = null;
+    privateKey: any = null;
+
     signature: string;
 
     constructor(
         public modalController: ModalController,
         public http: HttpClient,
+        public translate: TranslateService,
         public notificationService: NotificationService,
+        public loadingController: LoadingController,
+        public signaturesService: SignaturesContentService,
+        public actionsService: ActionsService,
     ) { }
 
     ngOnInit(): void {
@@ -67,22 +79,29 @@ export class SignatureMethodModalComponent implements OnInit {
     }
 
     async continueSignature(certData: any) {
-        console.log(certData);
-
-        const provider = await certData.detail.server.getCrypto(certData.detail.providerId);
+        this.loadingController.create({
+            message: this.translate.instant('lang.processing'),
+            spinner: 'dots'
+        }).then(async (load: HTMLIonLoadingElement) => {
+            load.present();
 
-        const cert = await provider.certStorage.getItem(certData.detail.certificateId);
-        const certPem = await provider.certStorage.exportCert('pem', cert);
-        const privateKey = await provider.keyStorage.getItem(certData.detail.privateKeyId);
+            this.provider = await certData.detail.server.getCrypto(certData.detail.providerId);
+            this.cert = await this.provider.certStorage.getItem(certData.detail.certificateId);
+            this.certPem = await this.provider.certStorage.exportCert('pem', this.cert);
+            this.privateKey = await this.provider.keyStorage.getItem(certData.detail.privateKeyId);
 
-        console.log('cert = ');
-        console.log(cert);
-        console.log('certPem = ');
-        console.log(certPem);
-        console.log('privateKey = ');
-        console.log(privateKey);
+            const certificate = {
+                certificate: this.certPem
+            }
 
-        await this.modalController.dismiss({certificate: certPem, certData: certData, privateKey: privateKey});
+            const res: any = await this.actionsService.sendDocument(certificate);
+            console.log('sendDocument', res);
+            
+            if (res !== false) {
+                await this.signDocument(res.hashDocument, res.signatureContentLength);
+            }
+            load.dismiss();
+        });
 
         // this.http.post('../rest/testFortify?action=start', {certificate: certPem}).pipe(
         //     tap(async (dataToSign: any) => {
@@ -105,17 +124,71 @@ export class SignatureMethodModalComponent implements OnInit {
         // ).subscribe();
     }
 
+    signDocument(hashDocument: any, eSignatureLength: any) {
+        console.log(hashDocument);
+        console.log(eSignatureLength);
+        
+        return new Promise(async (resolve) => {
+            const alg = {
+                name: this.privateKey.algorithm.name,
+                hash: 'SHA-256',
+            };
+            const hashDocumentHex = this.fromHex(hashDocument);
+
+            console.log('hashDocumentHex', hashDocumentHex);
+            
+
+            const hashSignature = await this.provider.subtle.sign(alg, this.privateKey, hashDocumentHex);
+
+            console.log('hashSignature', hashSignature);
+            
+
+            const objEsign = {
+                certificate: this.certPem,
+                hashSignature: this.toHex(hashSignature),
+                signatureContentLength: eSignatureLength
+            }
+            this.http.put('../rest/documents/' + this.signaturesService.mainDocumentId + '/actions/' + this.signaturesService.currentAction, objEsign)
+                .pipe(
+                    tap((res: any) => {
+                        resolve(true);
+                    }),
+                    catchError((err: any) => {
+                        this.notificationService.handleErrors(err);
+                        resolve(false);
+                        return of(false);
+                    })
+                ).subscribe();
+
+        });
+    }
+
     cancelSign(data: any) {
         console.log(data);
         this.modalController.dismiss(false);
     }
 
-    // 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;
-    // }
+    toHex(buffer: any) {
+        let buf = new Uint8Array(buffer),
+            splitter = "",
+            res = [],
+            len = buf.length;
+
+        for (let i = 0; i < len; i++) {
+            let char = buf[i].toString(16);
+            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;
+    }
+
 }
-- 
GitLab