From 048fc96fa0fbdb2f74b74364c0cccfe4d9ec2b23 Mon Sep 17 00:00:00 2001
From: Guillaume Heurtier <guillaume.heurtier@maarch.org>
Date: Wed, 9 Dec 2020 18:30:26 +0100
Subject: [PATCH] FEAT #14565 TIME 0:00 WIP signature with fortify

---
 .../app/document/document.component.ts        | 41 +++++++++++++++---
 .../signature-method-modal.component.ts       | 43 ++++++++++---------
 2 files changed, 58 insertions(+), 26 deletions(-)

diff --git a/src/frontend/app/document/document.component.ts b/src/frontend/app/document/document.component.ts
index 3b9bce0ec7..3de80ec8a1 100755
--- a/src/frontend/app/document/document.component.ts
+++ b/src/frontend/app/document/document.component.ts
@@ -18,9 +18,10 @@ import { AuthService } from '../service/auth.service';
 import { LocalStorageService } from '../service/local-storage.service';
 import { ActionSheetController, AlertController, LoadingController, MenuController, ModalController, NavController } from '@ionic/angular';
 import { NgxExtendedPdfViewerService } from 'ngx-extended-pdf-viewer';
-import { catchError, tap } from 'rxjs/operators';
+import {catchError, exhaustMap, tap} from 'rxjs/operators';
 import { of } from 'rxjs';
 import { SignatureMethodService } from '../service/signature-method/signature-method.service';
+import {sign} from "crypto";
 
 @Component({
     selector: 'app-document',
@@ -681,15 +682,15 @@ export class DocumentComponent implements OnInit {
                     text: this.translate.instant('lang.validate'),
                     handler: async (data: any) => {
                         const currentUserWorkflow = this.mainDocument.workflow.filter((line: { current: boolean; }) => line.current === true)[0];
-                        const res = await this.signatureMethodService.checkAuthentication(currentUserWorkflow);
-                        console.log('result auth', res);
-                        if (res) {
+                        const certificate = await this.signatureMethodService.checkAuthentication(currentUserWorkflow);
+                        console.log('result auth', certificate);
+                        if (certificate !== false) {
                             this.loadingController.create({
                                 message: this.translate.instant('lang.processing') + ' ...',
                                 spinner: 'dots'
                             }).then(async (load: HTMLIonLoadingElement) => {
                                 load.present();
-                                const res = await this.sendDocument({ 'note': data.paragraph });
+                                const res = await this.sendDocument({ 'note': data.paragraph, 'certificate': certificate });
                                 if (res) {
                                     const config: MatBottomSheetConfig = {
                                         disableClose: true,
@@ -758,8 +759,27 @@ export class DocumentComponent implements OnInit {
                         });
                     }
                 }
-                this.http.put('../rest/documents/' + this.signaturesService.mainDocumentId + '/actions/' + this.signaturesService.currentAction, { 'signatures': signatures, 'note': data.note })
+                data.signatures = signatures;
+                const privateKey = data.privatekey;
+                data.privateKey = undefined;
+                const signDocumentWith2Steps = data.certificate !== undefined && data.certificate !== false && data.certificate !== true;
+                this.http.put('../rest/documents/' + this.signaturesService.mainDocumentId + '/actions/' + this.signaturesService.currentAction, data)
                     .pipe(
+                        tap((signatureData) => {
+                            if (signDocumentWith2Steps) {
+                                data.signatures = undefined;
+
+                                const message = this.fromHex(signatureData.dataToSign);
+                                const alg = {
+                                    name: privateKey.algorithm.name,
+                                    hash: 'SHA-256',
+                                };
+                                signature = await provider.subtle.sign(alg, privateKey, message);
+
+                                // TODO mettre les infos à envoyer en step 2 dans data !!!!
+                            }
+                        }),
+                        exhaustMap(() => signDocumentWith2Steps ? this.http.put('../rest/documents/' + this.signaturesService.mainDocumentId + '/actions/' + this.signaturesService.currentAction, data) : null),
                         tap(() => {
                             if (this.signaturesService.documentsList[this.signaturesService.indexDocumentsList] !== undefined) {
                                 this.signaturesService.documentsList.splice(this.signaturesService.indexDocumentsList, 1);
@@ -947,4 +967,13 @@ export class DocumentComponent implements OnInit {
             this.pagesList.open();
         }
     }
+
+    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;
+    }
 }
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 910cf94685..24d2058eab 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,6 +1,6 @@
 import { Component, Input, OnInit } from '@angular/core';
 import { ModalController } from '@ionic/angular';
-import {catchError, tap} from 'rxjs/operators';
+import {catchError, exhaustMap, tap} from 'rxjs/operators';
 import {of} from 'rxjs';
 import {HttpClient} from '@angular/common/http';
 import {NotificationService} from '../notification.service';
@@ -28,6 +28,8 @@ export class SignatureMethodModalComponent implements OnInit {
         onlyWithPrivateKey: true
     };
 
+    signature: string;
+
     constructor(
         public modalController: ModalController,
         public http: HttpClient,
@@ -80,26 +82,27 @@ export class SignatureMethodModalComponent implements OnInit {
         console.log('privateKey = ');
         console.log(privateKey);
 
-        this.http.post('../rest/testFortify?action=start', {certificate: certPem}).pipe(
-            tap(async (dataToSign: any) => {
-                const message = this.fromHex(dataToSign.dataToSign);
-                const alg = {
-                    name: privateKey.algorithm.name,
-                    hash: 'SHA-256',
-                };
-                const signature = await provider.subtle.sign(alg, privateKey, message);
+        await this.modalController.dismiss({certificate: certPem});
 
-                return this.http.post('../rest/testFortify?action=complete', {signature: signature});
-            }),
-            tap(() => {
-                console.log('signature ok');
-                this.modalController.dismiss(true);
-            }),
-            catchError(err => {
-                this.notificationService.handleErrors(err);
-                return of(false);
-            })
-        ).subscribe();
+        // this.http.post('../rest/testFortify?action=start', {certificate: certPem}).pipe(
+        //     tap(async (dataToSign: any) => {
+        //         const message = this.fromHex(dataToSign.dataToSign);
+        //         const alg = {
+        //             name: privateKey.algorithm.name,
+        //             hash: 'SHA-256',
+        //         };
+        //         this.signature = await provider.subtle.sign(alg, privateKey, message);
+        //     }),
+        //     exhaustMap(() => this.http.post('../rest/testFortify?action=complete', {signature: this.signature})),
+        //     tap(() => {
+        //         console.log('signature ok');
+        //         this.modalController.dismiss(true);
+        //     }),
+        //     catchError(err => {
+        //         this.notificationService.handleErrors(err);
+        //         return of(false);
+        //     })
+        // ).subscribe();
     }
 
     cancelSign(data: any) {
-- 
GitLab