diff --git a/lang/en.json b/lang/en.json index 89af339ffc8a53a93cfc7a91487d2a73ca617744..7c00c05f7782c59527aa7521a84e7416f24579f0 100755 --- a/lang/en.json +++ b/lang/en.json @@ -410,6 +410,7 @@ "errorUserSignType": "Signers without a certificate must be present before signers with a certificate.", "fortifyReadException": "Error when communicating with Fortify", "docaposteSignatureDisabled": "The docaposteSignature parameter is not activated", + "securedUrlNeeded": "If you want to sign with a certificate, you must have a secured application (https)", "certifiedDocumentMsg2": "Certified document! Annotations on the document will not be taken into account!", "history": "History", "manage_history": "Manage history", @@ -472,4 +473,4 @@ "refProcessInfo": "Refused on", "repoUrl": "https://labs.maarch.org/maarch/MaarchParapheur" } -} \ No newline at end of file +} diff --git a/lang/fr.json b/lang/fr.json index ef0bc048d94550fa961ee578cbbdea3297f08d98..55cf4200c8ba0f3f8f7244652d0a031adf93c003 100755 --- a/lang/fr.json +++ b/lang/fr.json @@ -350,6 +350,7 @@ "rgs_2stars": "Clé RGS**", "rgs_2stars_timestamped": "Clé RGS** + horodatage", "docaposteSignatureDisabled": "Le paramètre docaposteSignature n'est pas activé", + "securedUrlNeeded": "Pour pouvoir signer électroniquement, vous devez accéder à l'application de manière sécurisée (https)", "noAssociatedGroup": "L'utilisateur n'appartient à aucun groupe", "docToSign": "Document à signer", "attachDocToSign": "Annexe attaché au(x) document(s) à signer", diff --git a/src/app/document/controllers/DocumentController.php b/src/app/document/controllers/DocumentController.php index ce9f40eb1b090f2603eefc9a8a1f5147aeb1704d..48f3a37d5a6c1aa55d7c34dc9ec049036bc858d8 100755 --- a/src/app/document/controllers/DocumentController.php +++ b/src/app/document/controllers/DocumentController.php @@ -20,6 +20,7 @@ use Email\controllers\EmailController; use Group\controllers\PrivilegeController; use Respect\Validation\Validator; use setasign\Fpdi\Tcpdf\Fpdi; +use SrcCore\controllers\UrlController; use SrcCore\models\CoreConfigModel; use Attachment\models\AttachmentModel; use Docserver\controllers\DocserverController; @@ -117,7 +118,7 @@ class DocumentController $documents[$key]['mode'] = $workflowsShortcut[$document['id']]['mode']; $documents[$key]['owner'] = $workflowsShortcut[$document['id']]['user_id'] == $userId; } - + foreach ($countWorkflows as $mode) { $count[$mode['mode']] = $mode['count']; } @@ -274,7 +275,7 @@ class DocumentController $fileContent = file_get_contents($pathToDocument); $finfo = new \finfo(FILEINFO_MIME_TYPE); $mimeType = $finfo->buffer($fileContent); - + if (empty($queryParams['mode']) || $queryParams['mode'] == 'base64') { return $response->withJson(['encodedDocument' => base64_encode($fileContent)]); } else { @@ -291,9 +292,9 @@ class DocumentController if (!PrivilegeController::hasPrivilege(['userId' => $GLOBALS['id'], 'privilege' => 'indexation'])) { return $response->withStatus(403)->withJson(['errors' => 'Privilege forbidden']); } - + $body = $request->getParsedBody(); - + if (empty($body)) { return $response->withStatus(400)->withJson(['errors' => 'Body is not set or empty']); } elseif (!Validator::notEmpty()->validate($body['encodedDocument'])) { @@ -307,7 +308,7 @@ class DocumentController } elseif (!Validator::stringType()->length(0, 64)->validate($body['reference'])) { return $response->withStatus(400)->withJson(['errors' => 'Body reference is too loong or not a string']); } - + $body['attachments'] = empty($body['attachments']) ? [] : $body['attachments']; foreach ($body['attachments'] as $key => $attachment) { if (!Validator::notEmpty()->validate($attachment['encodedDocument'])) { @@ -317,7 +318,7 @@ class DocumentController } } - + $hasEidas = false; $hasElectronicSignature = false; foreach ($body['workflow'] as $key => $workflow) { @@ -365,7 +366,7 @@ class DocumentController $body['workflow'][$key]['userId'] = $processingUser['id']; } - + $libDir = CoreConfigModel::getLibrariesDirectory(); $loadedXml = CoreConfigModel::getConfig(); if ($loadedXml->docaposteSignature->enable == 'true' && $hasEidas && (empty($libDir) || !is_file($libDir . 'SetaPDF-Signer/library/SetaPDF/Autoload.php'))) { @@ -379,7 +380,7 @@ class DocumentController } else { $encodedDocument['encodedDocument'] = $body['encodedDocument']; } - + if (!empty($encodedDocument['errors'])) { return $response->withStatus(500)->withJson(['errors' => $encodedDocument['errors']]); } @@ -391,7 +392,7 @@ class DocumentController return $response->withStatus(400)->withJson(['errors' => 'Document is not a pdf']); } - + if (!empty($libDir) && is_file($libDir . 'SetaPDF-FormFiller-Full/library/SetaPDF/Autoload.php')) { require_once($libDir . 'SetaPDF-FormFiller-Full/library/SetaPDF/Autoload.php'); @@ -412,14 +413,14 @@ class DocumentController unlink($targetFile); } - + try { $storeInfos = DocserverController::storeResourceOnDocServer([ 'encodedFile' => $encodedDocument['encodedDocument'], 'format' => 'pdf', 'docserverType' => 'DOC' ]); - + if (!empty($storeInfos['errors'])) { return $response->withStatus(500)->withJson(['errors' => $storeInfos['errors']]); } @@ -434,7 +435,7 @@ class DocumentController } DatabaseModel::beginTransaction(); - + $id = DocumentModel::create([ 'title' => $body['title'], 'reference' => empty($body['reference']) ? null : $body['reference'], @@ -448,7 +449,7 @@ class DocumentController 'typist' => $GLOBALS['id'], 'mailing_id' => !empty($body['mailingId']) ? (string)$body['mailingId'] : null ]); - + AdrModel::createDocumentAdr([ 'documentId' => $id, @@ -457,14 +458,14 @@ class DocumentController 'filename' => $storeInfos['filename'], 'fingerprint' => $storeInfos['fingerprint'] ]); - + $storeInfos = DocserverController::storeResourceOnDocServer([ 'encodedFile' => $encodedDocument['encodedDocument'], 'format' => 'pdf', 'docserverType' => 'ORIGINAL' ]); - + if (!empty($storeInfos['errors'])) { return $response->withStatus(500)->withJson(['errors' => $storeInfos['errors']]); } @@ -475,7 +476,7 @@ class DocumentController 'filename' => $storeInfos['filename'], 'fingerprint' => $storeInfos['fingerprint'] ]); - + foreach ($body['workflow'] as $key => $workflow) { if (!SignatureController::isValidSignatureMode(['mode' => $workflow['signatureMode']])) { @@ -523,7 +524,7 @@ class DocumentController return $response->withStatus(500)->withJson(['errors' => $e->getMessage()]); } - + $workflow = WorkflowModel::get([ 'select' => ['id', 'user_id', 'signature_mode'], 'where' => ['mode = ?', 'main_document_id = ?'], @@ -537,13 +538,13 @@ class DocumentController return $response->withStatus(500)->withJson(['errors' => $result['errors']]); } } - + EmailController::sendNotification(['documentId' => $id, 'userId' => $GLOBALS['id']]); - + $configPath = CoreConfigModel::getConfigPath(); exec("php src/app/convert/scripts/ThumbnailScript.php '{$configPath}' {$id} 'document' '{$GLOBALS['id']}' > /dev/null &"); - + return $response->withJson(['id' => $id]); } @@ -566,6 +567,13 @@ class DocumentController return $response->withStatus(500)->withJson(['errors' => 'SetaPDF-Signer library is not installed', 'lang' => 'setAPdfSignerError']); } require_once($libDir . 'SetaPDF-Signer/library/SetaPDF/Autoload.php'); + + if ($workflow['signature_mode'] != 'eidas') { + $url = UrlController::getCoreUrl(); + if (strpos($url, 'https://') !== 0) { + return $response->withStatus(400)->withJson(['errors' => 'Url is not secured (https needed)', 'lang' => 'securedUrlNeeded']); + } + } } if (in_array($workflow['signature_mode'], ['eidas', 'inca_card_eidas']) && $loadedXml->docaposteSignature->enable != 'true') { return $response->withStatus(400)->withJson(['errors' => 'docaposteSignature is disabled', 'lang' => 'docaposteSignatureDisabled']); @@ -684,7 +692,7 @@ class DocumentController if (!empty($storeInfos['errors'])) { return $response->withStatus(500)->withJson(['errors' => $storeInfos['errors']]); } - + AdrModel::deleteDocumentAdr([ 'where' => ['main_document_id = ?', 'type = ?'], 'data' => [$args['id'], 'ESIGN'] diff --git a/src/core/controllers/AuthenticationController.php b/src/core/controllers/AuthenticationController.php index fd2c637f35ebed7892771115cccb900ef32cebb3..9fd6b51d398a5b4de152183c13bdd7ef48fae23e 100755 --- a/src/core/controllers/AuthenticationController.php +++ b/src/core/controllers/AuthenticationController.php @@ -21,8 +21,6 @@ use History\controllers\HistoryController; use Respect\Validation\Validator; use Slim\Http\Request; use Slim\Http\Response; -use SrcCore\controllers\LanguageController; -use SrcCore\controllers\UrlController; use SrcCore\models\AuthenticationModel; use SrcCore\models\CoreConfigModel; use SrcCore\models\PasswordModel; @@ -44,12 +42,14 @@ class AuthenticationController $connection = ConfigurationModel::getConnection(); $encryptKey = CoreConfigModel::getEncryptKey(); $path = CoreConfigModel::getConfigPath(); + $coreUrl = UrlController::getCoreUrl(); $hashedPath = md5($path); return $response->withJson([ - 'connection' => $connection, - 'changeKey' => $encryptKey == 'Security Key Maarch Parapheur #2008', - 'instanceId' => $hashedPath + 'connection' => $connection, + 'changeKey' => $encryptKey == 'Security Key Maarch Parapheur #2008', + 'instanceId' => $hashedPath, + 'coreUrl' => $coreUrl ]); } @@ -99,7 +99,7 @@ class AuthenticationController } $login = strtolower($body['login']); - + if ($connection == 'ldap') { $ldapConfigurations = ConfigurationModel::getByIdentifier(['identifier' => 'ldapServer', 'select' => ['value']]); if (empty($ldapConfigurations)) { diff --git a/src/frontend/app/service/auth.guard.ts b/src/frontend/app/service/auth.guard.ts index 8dda67cb75b6e7dd526391776c5d99192e7f55cd..50e552e87166f5b73e5e0f2d42c8da34c7529dec 100644 --- a/src/frontend/app/service/auth.guard.ts +++ b/src/frontend/app/service/auth.guard.ts @@ -38,6 +38,7 @@ export class AuthGuard implements CanActivate { map((data: any) => { this.authService.authMode = data.connection; this.authService.changeKey = data.changeKey; + this.authService.coreUrl = data.coreUrl; this.localStorage.setAppSession(data.instanceId); }) ). subscribe(); @@ -65,6 +66,7 @@ export class AuthGuard implements CanActivate { map((data: any) => { this.authService.authMode = data.connection; this.authService.changeKey = data.changeKey; + this.authService.coreUrl = data.coreUrl; this.localStorage.setAppSession(data.instanceId); tokenInfo = this.authService.getToken(); diff --git a/src/frontend/app/service/auth.service.ts b/src/frontend/app/service/auth.service.ts index 4714d092c03d1537619b0edf9a7c047e5df265bc..f0468c15e105bde3d6ba2159f0cadc74b343fe23 100755 --- a/src/frontend/app/service/auth.service.ts +++ b/src/frontend/app/service/auth.service.ts @@ -13,9 +13,10 @@ import { of } from 'rxjs'; }) export class AuthService { - authMode: string = 'default'; - changeKey: boolean = false; - user: any = {}; + authMode: string = 'default'; + changeKey: boolean = false; + coreUrl: string = ''; + user: any = {}; signatureRoles: any[] = []; constructor(public http: HttpClient, diff --git a/src/frontend/app/service/signature-method/signature-method.service.ts b/src/frontend/app/service/signature-method/signature-method.service.ts index 0fd5094a55dbaa692a02a3c435589d40cc4870b8..4f146066eea22ae08ccdae85a78e204bca7c7f3f 100644 --- a/src/frontend/app/service/signature-method/signature-method.service.ts +++ b/src/frontend/app/service/signature-method/signature-method.service.ts @@ -4,6 +4,8 @@ import { LoadingController, ModalController } from '@ionic/angular'; import { SignatureMethodModalComponent } from './signature-method-modal.component'; import { ActionsService } from '../actions.service'; import { TranslateService } from '@ngx-translate/core'; +import {AuthService} from "../auth.service"; +import {NotificationService} from "../notification.service"; @Injectable({ providedIn: 'root' @@ -16,10 +18,16 @@ export class SignatureMethodService { public actionsService: ActionsService, public loadingController: LoadingController, private translate: TranslateService, + public authService: AuthService, + public notificationService: NotificationService ) { } async checkAuthenticationAndLaunchAction(userWorkflow: any, note: any = null, idsToProcess: any[]) { if (['rgs_2stars', 'rgs_2stars_timestamped', 'inca_card', 'inca_card_eidas'].indexOf(userWorkflow.signatureMode) > -1) { + if (this.authService.coreUrl.indexOf('https://') !== 0) { + await this.notificationService.error('lang.securedUrlNeeded'); + return null; + } const res = await this.openRgsAuth(note, userWorkflow.signatureMode, idsToProcess); return res; } else {