mirror of
https://github.com/24eme/signaturepdf
synced 2024-06-10 09:52:16 +02:00
Compare commits
11 commits
58ec504810
...
da9a342eef
Author | SHA1 | Date | |
---|---|---|---|
da9a342eef | |||
9edcac9ea8 | |||
4b82dae4f9 | |||
47ef75562f | |||
12043408cc | |||
488f720284 | |||
87000db098 | |||
80a0104a7c | |||
817325eea4 | |||
579379318f | |||
aa951558fb |
28
app.php
28
app.php
|
@ -87,6 +87,7 @@ $f3->route('GET /signature',
|
|||
$f3->set('noSharingMode', true);
|
||||
}
|
||||
$f3->set('activeTab', 'sign');
|
||||
|
||||
echo View::instance()->render('signature.html.php');
|
||||
}
|
||||
);
|
||||
|
@ -186,7 +187,6 @@ $f3->route('POST /sign',
|
|||
|
||||
shell_exec(sprintf("rsvg-convert -f pdf -o %s %s", $tmpfile.'.svg.pdf', $svgFiles));
|
||||
shell_exec(sprintf("pdftk %s multistamp %s output %s", $tmpfile.".pdf", $tmpfile.'.svg.pdf', $tmpfile.'_signe.pdf'));
|
||||
|
||||
Web::instance()->send($tmpfile.'_signe.pdf', null, 0, TRUE, $filename);
|
||||
|
||||
if($f3->get('DEBUG')) {
|
||||
|
@ -196,9 +196,11 @@ $f3->route('POST /sign',
|
|||
}
|
||||
);
|
||||
|
||||
require_once 'lib/cryptography.class.php';
|
||||
|
||||
$f3->route('POST /share',
|
||||
function($f3) {
|
||||
$hash = substr(hash('sha512', uniqid().rand()), 0, 20);
|
||||
$hash = Web::instance()->slug($_POST['hash']);
|
||||
$sharingFolder = $f3->get('PDF_STORAGE_PATH').$hash;
|
||||
$f3->set('UPLOADS', $sharingFolder."/");
|
||||
if (!is_dir($f3->get('PDF_STORAGE_PATH'))) {
|
||||
|
@ -214,7 +216,6 @@ $f3->route('POST /share',
|
|||
$filename = "original.pdf";
|
||||
$tmpfile = tempnam($sharingFolder, date('YmdHis'));
|
||||
$svgFiles = "";
|
||||
|
||||
$files = Web::instance()->receive(function($file,$formFieldName){
|
||||
if($formFieldName == "pdf" && strpos(Web::instance()->mime($file['tmp_name'], true), 'application/pdf') !== 0) {
|
||||
$f3->error(403);
|
||||
|
@ -238,16 +239,19 @@ $f3->route('POST /share',
|
|||
if(!count($files)) {
|
||||
$f3->error(403);
|
||||
}
|
||||
|
||||
if($svgFiles) {
|
||||
shell_exec(sprintf("rsvg-convert -f pdf -o %s %s", $tmpfile.'.svg.pdf', $svgFiles));
|
||||
}
|
||||
|
||||
if(!$f3->get('DEBUG')) {
|
||||
array_map('unlink', glob($tmpfile."*.svg"));
|
||||
array_map('cryptographyClass::hardUnlink', glob($tmpfile."*.svg"));
|
||||
}
|
||||
|
||||
$f3->reroute($f3->get('REVERSE_PROXY_URL').'/signature/'.$hash."#informations");
|
||||
$symmetricKey = $_COOKIE[$hash];
|
||||
$encryptor = new CryptographyClass($_COOKIE[$hash], $f3->get('PDF_STORAGE_PATH').$hash);
|
||||
$encryptor->encrypt();
|
||||
|
||||
|
||||
$f3->reroute($f3->get('REVERSE_PROXY_URL').'/signature/'.$hash."#sk:".$symmetricKey);
|
||||
}
|
||||
|
||||
);
|
||||
|
@ -257,6 +261,12 @@ $f3->route('GET /signature/@hash/pdf',
|
|||
$f3->set('activeTab', 'sign');
|
||||
$hash = Web::instance()->slug($f3->get('PARAMS.hash'));
|
||||
$sharingFolder = $f3->get('PDF_STORAGE_PATH').$hash;
|
||||
|
||||
$cryptor = new CryptographyClass(CryptographyClass::protectSymmetricKey($_COOKIE[$hash]), $f3->get('PDF_STORAGE_PATH').$hash);
|
||||
if ($cryptor->decrypt() == false) {
|
||||
$f3->error(403);
|
||||
}
|
||||
|
||||
$files = scandir($sharingFolder);
|
||||
$originalFile = $sharingFolder.'/original.pdf';
|
||||
$finalFile = $sharingFolder.'/'.$f3->get('PARAMS.hash').uniqid().'.pdf';
|
||||
|
@ -282,6 +292,8 @@ $f3->route('GET /signature/@hash/pdf',
|
|||
}
|
||||
Web::instance()->send($finalFile, null, 0, TRUE, $filename);
|
||||
|
||||
$cryptor->encrypt($hash);
|
||||
|
||||
if($f3->get('DEBUG')) {
|
||||
return;
|
||||
}
|
||||
|
@ -399,7 +411,7 @@ $f3->route ('POST /compress',
|
|||
$compressionType = '/ebook';
|
||||
} elseif ($compressionType === 'low') {
|
||||
$compressionType = '/printer';
|
||||
} elseif ($compressionType === 'high') {
|
||||
} else {
|
||||
$compressionType = '/screen';
|
||||
}
|
||||
|
||||
|
|
77
lib/cryptography.class.php
Normal file
77
lib/cryptography.class.php
Normal file
|
@ -0,0 +1,77 @@
|
|||
<?php
|
||||
|
||||
class CryptographyClass
|
||||
{
|
||||
private $symmetricKey = null;
|
||||
private $pathHash = null;
|
||||
|
||||
function __construct($key, $pathHash) {
|
||||
$this->symmetricKey = $key;
|
||||
$this->pathHash = $pathHash;
|
||||
}
|
||||
|
||||
private function getFiles($isGpg) {
|
||||
$suffix = "";
|
||||
if ($isGpg) {
|
||||
$suffix = ".gpg";
|
||||
}
|
||||
$filesTab = glob($this->pathHash.'/*.pdf'.$suffix);
|
||||
$filesTab[] = $this->pathHash."/filename.txt".$suffix;
|
||||
|
||||
return $filesTab;
|
||||
}
|
||||
|
||||
public function encrypt() {
|
||||
|
||||
foreach ($this->getFiles(false) as $file) {
|
||||
$outputFile = $file.".gpg";
|
||||
$command = "gpg --batch --passphrase $this->symmetricKey --symmetric --cipher-algo AES256 -o $outputFile $file";
|
||||
$result = shell_exec($command);
|
||||
if ($result === false) {
|
||||
echo "Cypher failure";
|
||||
exit;
|
||||
}
|
||||
$this->hardUnlink($file);
|
||||
}
|
||||
}
|
||||
|
||||
public function decrypt() {
|
||||
foreach ($this->getFiles(true) as $file) {
|
||||
$outputFile = str_replace(".gpg", "", $file);
|
||||
$command = "gpg --batch --passphrase $this->symmetricKey --decrypt -o $outputFile $file";
|
||||
$result = shell_exec($command);
|
||||
if ($result === false) {
|
||||
echo "Decypher failure";
|
||||
return $result;
|
||||
}
|
||||
$this->hardUnlink($file);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public static function hardUnlink($element) {
|
||||
if (!$element) {
|
||||
return;
|
||||
}
|
||||
$eraser = str_repeat(0, strlen(file_get_contents($element)));
|
||||
file_put_contents($element, $eraser);
|
||||
unlink($element);
|
||||
}
|
||||
|
||||
public static function protectSymmetricKey($key) {
|
||||
return preg_replace('/[^0-9a-zA-Z]*/', '', $key);
|
||||
}
|
||||
|
||||
public static function createSymmetricKey() {
|
||||
$length = 15;
|
||||
$keySpace = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';
|
||||
$pieces = [];
|
||||
$max = mb_strlen($keySpace, '8bit') - 1;
|
||||
for ($i = 0; $i < $length; ++$i) {
|
||||
$pieces []= $keySpace[random_int(0, $max)];
|
||||
}
|
||||
|
||||
return implode('', $pieces);
|
||||
}
|
||||
}
|
||||
?>
|
|
@ -414,6 +414,7 @@ var displaysSVG = function() {
|
|||
});
|
||||
};
|
||||
|
||||
|
||||
function dataURLtoBlob(dataurl) {
|
||||
let arr = dataurl.split(','), mime = arr[0].match(/:(.*?);/)[1],
|
||||
bstr = atob(arr[1]), n = bstr.length, u8arr = new Uint8Array(n);
|
||||
|
@ -835,6 +836,10 @@ var createEventsListener = function() {
|
|||
}
|
||||
document.getElementById('input_svg_share').files = dataTransfer.files;
|
||||
hasModifications = false;
|
||||
|
||||
document.getElementById('input_pdf_hash').value = generatePdfHash();
|
||||
document.getElementById('input_symmetric_key').value = generateSymmetricKey();
|
||||
storeSymmetricKeyCookie(document.getElementById('input_pdf_hash').value, document.getElementById('input_symmetric_key').value);
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -962,7 +967,7 @@ var createEventsListener = function() {
|
|||
return true;
|
||||
});
|
||||
|
||||
if(hash) {
|
||||
if(pdfHash) {
|
||||
updateNbLayers();
|
||||
setInterval(function() {
|
||||
updateNbLayers();
|
||||
|
@ -1081,12 +1086,12 @@ var pageUpload = async function() {
|
|||
|
||||
var updateNbLayers = function() {
|
||||
const xhr = new XMLHttpRequest();
|
||||
xhr.open('GET', '/signature/'+hash+'/nblayers', true);
|
||||
xhr.open('GET', '/signature/'+pdfHash+'/nblayers', true);
|
||||
xhr.onload = function() {
|
||||
if (xhr.status == 200) {
|
||||
let newNblayers = xhr.response;
|
||||
if(nblayers !== null && nblayers != newNblayers) {
|
||||
reloadPDF('/signature/'+hash+'/pdf');
|
||||
reloadPDF('/signature/'+pdfHash+'/pdf');
|
||||
}
|
||||
nblayers = newNblayers;
|
||||
document.querySelectorAll('.nblayers').forEach(function(item) {
|
||||
|
@ -1127,7 +1132,7 @@ var pageSignature = async function(url) {
|
|||
let pdfBlob = null;
|
||||
let filename = url.replace('/pdf/', '');
|
||||
|
||||
if(hash) {
|
||||
if(pdfHash) {
|
||||
let response = await fetch(url);
|
||||
if(response.status != 200) {
|
||||
return;
|
||||
|
@ -1159,8 +1164,8 @@ var pageSignature = async function(url) {
|
|||
if(sharingMode) {
|
||||
setTimeout(function() { runCron() }, 2000);
|
||||
}
|
||||
if(hash) {
|
||||
pageSignature('/signature/'+hash+'/pdf');
|
||||
if(pdfHash) {
|
||||
pageSignature('/signature/'+pdfHash+'/pdf');
|
||||
window.addEventListener('hashchange', function() {
|
||||
window.location.reload();
|
||||
})
|
||||
|
@ -1179,4 +1184,38 @@ var pageSignature = async function(url) {
|
|||
window.addEventListener('hashchange', function() {
|
||||
window.location.reload();
|
||||
})
|
||||
})();
|
||||
})();
|
||||
|
||||
function storeSymmetricKeyCookie(hash, symmetricKey) {
|
||||
if (symmetricKey.length != 15) {
|
||||
console.error("Erreur taille cle symmetrique.");
|
||||
return;
|
||||
}
|
||||
document.cookie = hash + "=" + symmetricKey + "; SameSite=Strict";
|
||||
}
|
||||
|
||||
function generateSymmetricKey() {
|
||||
const length = 15;
|
||||
const keySpace = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';
|
||||
let key = '';
|
||||
|
||||
for (let i = 0; i < length; ++i) {
|
||||
const randomIndex = Math.floor(Math.random() * keySpace.length);
|
||||
key += keySpace.charAt(randomIndex);
|
||||
}
|
||||
|
||||
return key;
|
||||
}
|
||||
|
||||
function generatePdfHash() {
|
||||
const length = 20;
|
||||
const keySpace = '0123456789abcdefghijklmnopqrstuvwxyz';
|
||||
let key = '';
|
||||
|
||||
for (let i = 0; i < length; ++i) {
|
||||
const randomIndex = Math.floor(Math.random() * keySpace.length);
|
||||
key += keySpace.charAt(randomIndex);
|
||||
}
|
||||
|
||||
return key;
|
||||
}
|
||||
|
|
|
@ -116,6 +116,7 @@
|
|||
</div>
|
||||
<form id="form_pdf" action="<?php echo $REVERSE_PROXY_URL; ?>/signature/<?php echo $hash ?>/save" method="post" enctype="multipart/form-data" class="d-none d-sm-none d-md-block">
|
||||
<input id="input_svg" name="svg[]" type="file" class="d-none" />
|
||||
|
||||
<button class="btn btn-primary w-100 mt-2" disabled="disabled" type="submit" id="save"><i class="bi bi-cloud-upload"></i> <?php echo _("Transmit my signature"); ?></button>
|
||||
</form>
|
||||
<?php endif; ?>
|
||||
|
@ -201,6 +202,8 @@
|
|||
<form id="form_sharing" clas action="<?php echo $REVERSE_PROXY_URL; ?>/share" method="post" enctype="multipart/form-data">
|
||||
<input id="input_pdf_share" name="pdf" type="file" class="d-none" />
|
||||
<input id="input_svg_share" name="svg[]" type="file" class="d-none" />
|
||||
<input id="input_pdf_hash" name="hash" type="hidden" value="" />
|
||||
<input id="input_symmetric_key" name="key" type="hidden" value="" />
|
||||
<button class="btn col-9 col-md-6 btn-primary" type="submit" id="save_share"><?php echo sprintf(_("%s Start sharing"), '<i class="bi bi-cloud-upload"></i>'); ?></button>
|
||||
</form>
|
||||
</div>
|
||||
|
@ -264,10 +267,10 @@
|
|||
var maxSize = <?php echo $maxSize ?>;
|
||||
var maxPage = <?php echo $maxPage ?>;
|
||||
var sharingMode = <?php echo intval(!isset($noSharingMode)) ?>;
|
||||
var hash = null;
|
||||
var pdfHash = null;
|
||||
var direction = '<?php echo $DIRECTION_LANGUAGE ?>';
|
||||
<?php if(isset($hash)): ?>
|
||||
hash = "<?php echo $hash ?>";
|
||||
pdfHash = "<?php echo $hash ?>";
|
||||
<?php endif; ?>
|
||||
|
||||
var trad = <?php echo json_encode([
|
||||
|
|
Loading…
Reference in a new issue