Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix backup restore process #4486

Merged
merged 3 commits into from
Nov 26, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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 @@ -2760,6 +2760,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 @@ -2778,12 +2780,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 @@ -2807,33 +2808,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