Skip to content

Commit

Permalink
Merge pull request #4486 from nilsteampassnet/fix_backup
Browse files Browse the repository at this point in the history
Fix backup restore process
  • Loading branch information
nilsteampassnet authored Nov 26, 2024
2 parents f4bd2db + 792b10b commit ad4e195
Show file tree
Hide file tree
Showing 11 changed files with 169 additions and 104 deletions.
2 changes: 1 addition & 1 deletion includes/config/include.php
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@

define('TP_VERSION', '3.1.2');
define("UPGRADE_MIN_DATE", "1732264740");
define('TP_VERSION_MINOR', '167');
define('TP_VERSION_MINOR', '170');
define('TP_TOOL_NAME', 'Teampass');
define('TP_ONE_DAY_SECONDS', 86400);
define('TP_ONE_WEEK_SECONDS', 604800);
Expand Down
12 changes: 7 additions & 5 deletions pages/backups.js.php
Original file line number Diff line number Diff line change
Expand Up @@ -294,8 +294,6 @@ function(response) {
function updateProgressBar(offset, totalSize) {
// Show progress to user
var percentage = Math.round((offset / totalSize) * 100);
//var message = '<i class="mr-2 fa-solid fa-rocket fa-beat"></i><?php echo $lang->get('restore_in_progress');?> <b>' + percentage + '%</b>';
//console.log(message)
$('#onthefly-restore-progress-text').text(percentage);
}

Expand All @@ -314,13 +312,14 @@ function updateProgressBar(offset, totalSize) {
: $SETTINGS['upload_maxfilesize'];
?>

let toastrElement;
var restoreOperationId = '',
uploader_restoreDB = new plupload.Uploader({
runtimes: "gears,html5,flash,silverlight,browserplus",
browse_button: "onthefly-restore-file-select",
container: "onthefly-restore-file",
max_file_size: "<?php echo $maxFileSize; ?>",
chunk_size: "5mb",
chunk_size: "2mb", // adapted to standard PHP configuration
unique_names: true,
dragdrop: true,
multiple_queues: false,
Expand Down Expand Up @@ -364,8 +363,7 @@ function(teampassUser) {
BeforeUpload: function(up, file) {
// Show cog
toastr.remove();
toastr.info('<?php echo $lang->get('loading_item'); ?> ... <i class="fas fa-circle-notch fa-spin fa-2x"></i>');
console.log("Upload token: "+store.get('teampassUser').uploadToken);
toastrElement = toastr.info('<?php echo $lang->get('loading_item'); ?> ... <span id="plupload-progress" class="mr-2 ml-2 strong">0%</span><i class="fas fa-circle-notch fa-spin fa-2x"></i>');

up.setOption('multipart_params', {
PHPSESSID: '<?php echo $session->get('user-id'); ?>',
Expand All @@ -374,6 +372,10 @@ function(teampassUser) {
user_token: store.get('teampassUser').uploadToken
});
},
UploadProgress: function(up, file) {
// Update only the percentage inside the Toastr message
$('#plupload-progress').text(file.percent + '%');
},
UploadComplete: function(up, files) {
store.update(
'teampassUser',
Expand Down
13 changes: 0 additions & 13 deletions pages/import.js.php
Original file line number Diff line number Diff line change
Expand Up @@ -142,21 +142,8 @@ function(teampassApplication) {
PHPSESSID: '<?php echo $session->get('key'); ?>',
type_upload: "import_items_from_csv",
user_token: data[0].token
/*itemId: store.get('teampassItem').id,
type_upload: 'item_attachments',
isNewItem: store.get('teampassItem').isNewItem,
isPersonal: store.get('teampassItem').folderIsPersonal,
edit_item: false,
user_upload_token: store.get('teampassApplication').attachmentToken,
randomId: store.get('teampassApplication').uploadedFileId,
files_number: $('#form-item-hidden-pickFilesNumber').val(),
file_size: file.size*/
});

/*up.settings.multipart_params.PHPSESSID = "<?php echo session_id(); ?>";
up.settings.multipart_params.type_upload = "import_items_from_csv";
up.settings.multipart_params.user_token = data[0].token;*/

up.start();
},
"json"
Expand Down
69 changes: 50 additions & 19 deletions pages/items.js.php
Original file line number Diff line number Diff line change
Expand Up @@ -2742,6 +2742,8 @@ function(ret) {
var mime_types = <?php echo json_encode($mime_types); ?>;
var prevent_empty = <?php echo json_encode($prevent_empty); ?>;
var resize = <?php echo json_encode($resize); ?>;
let toastrElement;
let fileId;

var uploader_attachments = new plupload.Uploader({
runtimes: 'html5,flash,silverlight,html4',
Expand All @@ -2760,12 +2762,11 @@ function(ret) {
resize: resize,
init: {
BeforeUpload: function(up, file) {
toastr.info(
'<i class="fa-solid fa-cloud-arrow-up fa-bounce mr-2"></i><?php echo $lang->get('uploading'); ?>',
'', {
timeOut: 0
}
);
fileId = file.id;
toastr.remove();
toastrElement = toastr.info('<?php echo $lang->get('loading_item'); ?> ... <span id="plupload-progress" class="mr-2 ml-2 strong">0%</span><i class="fas fa-cloud-arrow-up fa-bounce fa-2x"></i>');
// Show file name
$('#upload-file_' + file.id).html('<i class="fa-solid fa-file fa-sm mr-2"></i>' + htmlEncode(file.name) + '<span id="fileStatus_'+file.id+'"><i class="fa-solid fa-circle-notch fa-spin ml-2"></i></span>');

// Get random number
if (store.get('teampassApplication').uploadedFileId === '') {
Expand All @@ -2789,33 +2790,63 @@ function(teampassApplication) {
files_number: $('#form-item-hidden-pickFilesNumber').val(),
file_size: file.size
});
},
UploadProgress: function(up, file) {
// Update only the percentage inside the Toastr message
$('#plupload-progress').text(file.percent + '%');
},
UploadComplete: function(up, files) {
// Inform user
toastr.remove();
},
Error: function(up, args) {
console.log("ERROR arguments:");
console.log(args);
}
}
});

// Uploader options
uploader_attachments.bind('UploadProgress', function(up, file) {
//console.log('uploader_attachments.bind')
$('#upload-file_' + file.id).html('<i class="fa-solid fa-file fa-sm mr-2"></i>' + htmlEncode(file.name) + '<span id="fileStatus_'+file.id+'"><i class="fa-solid fa-circle-notch fa-spin ml-2"></i></span>');
});
uploader_attachments.bind('FileUploaded', function(up, file) {
//console.log('File '+file.name+' uploaded');
$('#fileStatus_'+file.id).html('<i class="fa-solid fa-circle-check text-success ml-2 fa-1x"></i>');
userUploadedFile = true;
userDidAChange = true;
toastr.remove();
});
uploader_attachments.bind('Error', function(up, err) {
toastr.remove();
toastr.error(
err.message + (err.file ? ', File: ' + err.file.name : ''),
'', {
timeOut: 5000,
progressBar: true
// Extraire le message d'erreur
let errorMessage = 'An unknown error occurred.';
if (err.response) {
try {
const response = JSON.parse(err.response);
if (response.error && response.error.message) {
errorMessage = response.error.message;
}
} catch (e) {
errorMessage = err.response; // Si la réponse n'est pas JSON
}
);
}

up.refresh(); // Reposition Flash/Silverlight
// Vérifie si l'erreur est due à un dépassement de taille ou une autre erreur critique
if (err.code === -200 || err.status === 413) {
// Arrêter l'upload des chunks
up.stop();
errorMessage += ' - Upload stopped.';

// Affiche l'erreur dans l'interface utilisateur
toastr.error(
errorMessage + (err.file ? ', File: ' + err.file.name : ''),
'', {
timeOut: 10000,
progressBar: true
}
);

$('#fileStatus_'+fileId).html('<i class="fa-solid fa-circle-xmark text-danger ml-2 fa-1x"></i>');
return false;
} else {
up.refresh(); // Reposition Flash/Silverlight
}
});

$("#form-item-upload-pickfiles").click(function(e) {
Expand Down
10 changes: 2 additions & 8 deletions sources/admin.queries.php
Original file line number Diff line number Diff line change
Expand Up @@ -206,7 +206,6 @@
'encrypt',
$SETTINGS['path_to_files_folder'] . '/' . $filename,
$SETTINGS['path_to_files_folder'] . '/defuse_temp_' . $filename,
$SETTINGS,
$post_option
);

Expand Down Expand Up @@ -283,7 +282,6 @@
'decrypt',
$SETTINGS['path_to_files_folder'] . '/' . $file,
$SETTINGS['path_to_files_folder'] . '/defuse_temp_' . $file,
$SETTINGS,
$key
);

Expand Down Expand Up @@ -890,8 +888,7 @@
prepareFileWithDefuse(
'decrypt',
$SETTINGS['path_to_upload_folder'] . '/' . $record['file'],
$SETTINGS['path_to_upload_folder'] . '/' . $record['file'] . '_encrypted',
$SETTINGS
$SETTINGS['path_to_upload_folder'] . '/' . $record['file'] . '_encrypted'
);

// Do cleanup of files
Expand All @@ -901,8 +898,7 @@
prepareFileWithDefuse(
'encryp',
$SETTINGS['path_to_upload_folder'] . '/' . $record['file'] . '_encrypted',
$SETTINGS['path_to_upload_folder'] . '/' . $record['file'],
$SETTINGS
$SETTINGS['path_to_upload_folder'] . '/' . $record['file']
);

// Do cleanup of files
Expand Down Expand Up @@ -1476,15 +1472,13 @@
'decrypt',
$SETTINGS['path_to_upload_folder'] . '/' . $file_info['file'],
$SETTINGS['path_to_upload_folder'] . '/defuse_temp_' . $file_info['file'],
$SETTINGS
);
// Case where we want to encrypt
} elseif ($post_option === 'encrypt') {
prepareFileWithDefuse(
'encrypt',
$SETTINGS['path_to_upload_folder'] . '/' . $file_info['file'],
$SETTINGS['path_to_upload_folder'] . '/defuse_temp_' . $file_info['file'],
$SETTINGS
);
}
// Do file cleanup
Expand Down
60 changes: 40 additions & 20 deletions sources/backups.queries.php
Original file line number Diff line number Diff line change
Expand Up @@ -173,7 +173,7 @@
while ($row = $result->fetch_row()) {
$return .= 'INSERT INTO ' . $table . ' VALUES(';
for ($j = 0; $j < $numFields; ++$j) {
// Gestion des valeurs NULL
// Manage NULL values
$value = $row[$j] === null ? 'NULL' : '"' . addslashes(preg_replace("/\n/", '\\n', $row[$j])) . '"';
$return .= $value;
if ($j < ($numFields - 1)) {
Expand All @@ -199,15 +199,14 @@
fwrite($handle, $return);
fclose($handle);
}

// Encrypt the file
if (empty($post_key) === false) {
// Encrypt the file
prepareFileWithDefuse(
'encrypt',
$SETTINGS['path_to_files_folder'] . '/' . $filename,
$SETTINGS['path_to_files_folder'] . '/defuse_temp_' . $filename,
$SETTINGS,
$post_key
);

Expand Down Expand Up @@ -287,10 +286,22 @@
$post_backupFile = filter_var($dataReceived['backupFile'], FILTER_SANITIZE_FULL_SPECIAL_CHARS);
$post_clearFilename = filter_var($dataReceived['clearFilename'], FILTER_SANITIZE_FULL_SPECIAL_CHARS);
$post_offset = (int) filter_var($dataReceived['offset'], FILTER_SANITIZE_NUMBER_INT);
$post_totalSize = (int) filter_var($dataReceived['post_totalSize'], FILTER_SANITIZE_NUMBER_INT);
$post_totalSize = (int) filter_var($dataReceived['totalSize'], FILTER_SANITIZE_NUMBER_INT);
$batchSize = 500;

if (WIP === true) error_log('DEBUG: Offset -> '.$post_offset.' | File -> '.$post_clearFilename.' | key -> '.$post_key);
// Check if the offset is greater than the total size
if (empty($post_offset) === false && $post_offset >= $post_totalSize) {
echo prepareExchangedData(
array(
'error' => false,
'message' => 'operation_finished',
),
'encode'
);
break;
}

if (WIP === true) error_log('DEBUG: Offset -> '.$post_offset.'/'.$post_totalSize.' | File -> '.$post_clearFilename.' | key -> '.$post_key);

include_once $SETTINGS['cpassman_dir'] . '/sources/main.functions.php';

Expand All @@ -311,19 +322,19 @@
);

$post_backupFile = $data['valeur'];

// Uncrypt the file
// Decrypt the file
if (empty($post_key) === false) {
// Decrypt the file

$ret = prepareFileWithDefuse(
'decrypt',
$SETTINGS['path_to_files_folder'] . '/' . $post_backupFile,
$SETTINGS['path_to_files_folder'] . '/defuse_temp_' . $post_backupFile,
$SETTINGS,
$post_key
);

if (empty($ret) === false) {
if (empty($ret) === false && $ret !== true) {
echo prepareExchangedData(
array(
'error' => true,
Expand All @@ -338,11 +349,19 @@
fileDelete($SETTINGS['path_to_files_folder'] . '/' . $post_backupFile, $SETTINGS);
$post_backupFile = $SETTINGS['path_to_files_folder'] . '/defuse_temp_' . $post_backupFile;
} else {
$post_backupFile = $SETTINGS['path_to_files_folder'] . '/' . $post_backupFile;
echo prepareExchangedData(
array(
'error' => true,
'message' => 'An error occurred. No encryption key provided.',
),
'encode'
);
break;
}
} else {
$post_backupFile = $post_clearFilename;
}


//read sql file
$handle = fopen($post_backupFile, 'r');
Expand All @@ -353,20 +372,19 @@
}

if ($handle !== false) {
// Déplacer le pointeur de fichier à l'offset actuel
// Move the file pointer to the current offset
fseek($handle, $post_offset);

$query = '';
$executedQueries = 0;
while (!feof($handle) && $executedQueries < $batchSize) {
$line = fgets($handle);
// Check if not false
if ($line !== false) {
// Vérifier si la ligne est une partie d'une instruction SQL
// Check if the line is part of an SQL statement
if (substr(trim($line), -1) != ';') {
$query .= $line;
} else {
// Exécuter l'instruction SQL complète
// Execute the complete SQL statement
$query .= $line;
DB::queryRaw($query);
$query = '';
Expand All @@ -375,14 +393,14 @@
}
}

// Calculer le nouvel offset
// Calculate the new offset
$newOffset = ftell($handle);

// Vérifier si la fin du fichier a été atteinte
// Check if the end of the file has been reached
$isEndOfFile = feof($handle);
fclose($handle);

// Répondre avec le nouvel offset
// Respond with the new offset
echo prepareExchangedData(
array(
'error' => false,
Expand All @@ -393,12 +411,13 @@
'encode'
);

// Vérifier si la fin du fichier a été atteinte pour supprimer le fichier
// Check if the end of the file has been reached to delete the file
if ($isEndOfFile) {
error_log('DEBUG: End of file reached. Deleting file '.$post_backupFile);
unlink($post_backupFile);
}
} else {
// Gérer l'erreur d'ouverture du fichier
// Handle file opening error
echo prepareExchangedData(
array(
'error' => true,
Expand All @@ -410,3 +429,4 @@
break;
}
}

Loading

0 comments on commit ad4e195

Please sign in to comment.