mirror of
https://github.com/snipe/snipe-it.git
synced 2024-11-09 23:24:06 -08:00
Expose the 'sanitize' system for backup restores to the web GUI
This commit is contained in:
parent
0f1e5181a6
commit
cc5ad456e6
|
@ -185,6 +185,7 @@ REQUIRE_SAML=false
|
|||
API_THROTTLE_PER_MINUTE=120
|
||||
CSV_ESCAPE_FORMULAS=true
|
||||
LIVEWIRE_URL_PREFIX=null
|
||||
SANITIZE_BY_DEFAULT=false
|
||||
|
||||
# --------------------------------------------
|
||||
# OPTIONAL: HASHING
|
||||
|
|
|
@ -1203,7 +1203,7 @@ class SettingsController extends Controller
|
|||
* @author [A. Gianotto] [<snipe@snipe.net>]
|
||||
* @since [v6.0]
|
||||
*/
|
||||
public function postRestore($filename = null) : RedirectResponse
|
||||
public function postRestore(Request $request, $filename = null): RedirectResponse
|
||||
{
|
||||
|
||||
if (! config('app.lock_passwords')) {
|
||||
|
@ -1223,13 +1223,29 @@ class SettingsController extends Controller
|
|||
|
||||
Log::debug('Attempting to restore from: '. storage_path($path).'/'.$filename);
|
||||
|
||||
// run the restore command
|
||||
Artisan::call('snipeit:restore',
|
||||
[
|
||||
$restore_params = [
|
||||
'--force' => true,
|
||||
'--no-progress' => true,
|
||||
'filename' => storage_path($path).'/'.$filename
|
||||
]);
|
||||
'filename' => storage_path($path) . '/' . $filename
|
||||
];
|
||||
|
||||
if ($request->input('clean')) {
|
||||
Log::debug("Attempting 'clean' - first, guessing prefix...");
|
||||
Artisan::call('snipeit:restore', [
|
||||
'--sanitize-guess-prefix' => true,
|
||||
'filename' => storage_path($path) . '/' . $filename
|
||||
]);
|
||||
$guess_prefix_output = Artisan::output();
|
||||
Log::debug("Sanitize output is: $guess_prefix_output");
|
||||
list($prefix, $_output) = explode("\n", $guess_prefix_output);
|
||||
Log::debug("prefix is: '$prefix'");
|
||||
$restore_params['--sanitize-with-prefix'] = $prefix;
|
||||
}
|
||||
|
||||
// run the restore command
|
||||
Artisan::call('snipeit:restore',
|
||||
$restore_params
|
||||
);
|
||||
|
||||
// If it's greater than 300, it probably worked
|
||||
$output = Artisan::output();
|
||||
|
|
|
@ -237,4 +237,6 @@ return [
|
|||
],
|
||||
],
|
||||
|
||||
'sanitize_by_default' => env('SANITIZE_BY_DEFAULT', false),
|
||||
|
||||
];
|
||||
|
|
|
@ -82,84 +82,45 @@ pieOptions = {
|
|||
|
||||
var baseUrl = $('meta[name="baseUrl"]').attr('content');
|
||||
|
||||
(function($, settings) {
|
||||
var Components = {};
|
||||
Components.modals = {};
|
||||
$(function () {
|
||||
|
||||
var $el = $('table');
|
||||
|
||||
// confirm restore modal
|
||||
Components.modals.confirmRestore = function() {
|
||||
var $el = $('table');
|
||||
|
||||
var events = {
|
||||
'click': function(evnt) {
|
||||
var $context = $(this);
|
||||
var $restoreConfirmModal = $('#restoreConfirmModal');
|
||||
var href = $context.attr('href');
|
||||
var message = $context.attr('data-content');
|
||||
var title = $context.attr('data-title');
|
||||
$el.on('click', '.restore-asset', function (evnt) {
|
||||
var $context = $(this);
|
||||
var $restoreConfirmModal = $('#restoreConfirmModal');
|
||||
var href = $context.attr('href');
|
||||
var message = $context.attr('data-content');
|
||||
var title = $context.attr('data-title');
|
||||
|
||||
$('#restoreConfirmModalLabel').text(title);
|
||||
$restoreConfirmModal.find('.modal-body').text(message);
|
||||
$('#restoreForm').attr('action', href);
|
||||
$restoreConfirmModal.modal({
|
||||
show: true
|
||||
});
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
var render = function() {
|
||||
$el.on('click', '.restore-asset', events['click']);
|
||||
};
|
||||
|
||||
return {
|
||||
render: render
|
||||
};
|
||||
};
|
||||
$('#confirmModalLabel').text(title);
|
||||
$restoreConfirmModal.find('.modal-body').text(message);
|
||||
$('#restoreForm').attr('action', href);
|
||||
$restoreConfirmModal.modal({
|
||||
show: true
|
||||
});
|
||||
return false;
|
||||
});
|
||||
|
||||
// confirm delete modal
|
||||
Components.modals.confirmDelete = function() {
|
||||
var $el = $('table');
|
||||
|
||||
var events = {
|
||||
'click': function(evnt) {
|
||||
var $context = $(this);
|
||||
var $dataConfirmModal = $('#dataConfirmModal');
|
||||
var href = $context.attr('href');
|
||||
var message = $context.attr('data-content');
|
||||
var title = $context.attr('data-title');
|
||||
$el.on('click', '.delete-asset', function (evnt) {
|
||||
var $context = $(this);
|
||||
var $dataConfirmModal = $('#dataConfirmModal');
|
||||
var href = $context.attr('href');
|
||||
var message = $context.attr('data-content');
|
||||
var title = $context.attr('data-title');
|
||||
|
||||
$('#myModalLabel').text(title);
|
||||
$dataConfirmModal.find('.modal-body').text(message);
|
||||
$('#deleteForm').attr('action', href);
|
||||
$dataConfirmModal.modal({
|
||||
show: true
|
||||
});
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
var render = function() {
|
||||
$el.on('click', '.delete-asset', events['click']);
|
||||
};
|
||||
|
||||
return {
|
||||
render: render
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Application start point
|
||||
* Component definition stays out of load event, execution only happens.
|
||||
*/
|
||||
$(function() {
|
||||
new Components.modals.confirmRestore().render();
|
||||
new Components.modals.confirmDelete().render();
|
||||
$('#myModalLabel').text(title);
|
||||
$dataConfirmModal.find('.modal-body').text(message);
|
||||
$('#deleteForm').attr('action', href);
|
||||
$dataConfirmModal.modal({
|
||||
show: true
|
||||
});
|
||||
return false;
|
||||
});
|
||||
}(jQuery, window.snipeit.settings));
|
||||
|
||||
$(document).ready(function () {
|
||||
|
||||
/*
|
||||
* Slideout help menu
|
||||
|
|
|
@ -31,6 +31,8 @@ return [
|
|||
'backups' => 'Backups',
|
||||
'backups_help' => 'Create, download, and restore backups ',
|
||||
'backups_restoring' => 'Restoring from Backup',
|
||||
'backups_clean' => 'Clean the backed-up database before restore',
|
||||
'backups_clean_helptext' => "This can be useful if you're changing between database versions",
|
||||
'backups_upload' => 'Upload Backup',
|
||||
'backups_path' => 'Backups on the server are stored in <code>:path</code>',
|
||||
'backups_restore_warning' => 'Use the restore button <small><span class="btn btn-xs btn-warning"><i class="text-white fas fa-retweet" aria-hidden="true"></i></span></small> to restore from a previous backup. (This does not currently work with S3 file storage or Docker.)<br><br>Your <strong>entire :app_name database and any uploaded files will be completely replaced</strong> by what\'s in the backup file. ',
|
||||
|
|
|
@ -7,7 +7,8 @@
|
|||
@stop
|
||||
|
||||
@section('header_right')
|
||||
<a href="{{ route('settings.index') }}" class="btn btn-default pull-right" style="margin-left: 5px;">
|
||||
<a href="{{ route('settings.index') }}" class="btn btn-default pull-right" style="margin-left: 5px;"
|
||||
xmlns="http://www.w3.org/1999/html">
|
||||
{{ trans('general.back') }}
|
||||
</a>
|
||||
|
||||
|
@ -21,8 +22,36 @@
|
|||
{{-- Page content --}}
|
||||
@section('content')
|
||||
|
||||
<div class="modal modal-warning fade" tabindex="-1" role="dialog" id="backupRestoreModal">
|
||||
<div class="modal-dialog" role="document">
|
||||
<div class="modal-content">
|
||||
<form method="post" role="form">
|
||||
<div class="modal-header">
|
||||
<h4 class="modal-title">Modal title</h4>
|
||||
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
|
||||
<span aria-hidden="true">×</span>
|
||||
</button>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
<p>{{ trans('admin/settings/message.backup.restore_warning') }}</p>
|
||||
<p><label><input type="checkbox"
|
||||
name="clean" {{ config('backup.sanitize_by_default') ? "checked='checked'" : "" }}>{{ trans('admin/settings/general.backups_clean') }}
|
||||
</label></p>
|
||||
<p>{{ trans('admin/settings/general.backups_clean_helptext') }}</p>
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
{{ csrf_field() }}
|
||||
{{ method_field('POST') }}
|
||||
<button type="button" class="btn btn-default pull-left"
|
||||
data-dismiss="modal">{{ trans('general.cancel') }}</button>
|
||||
<button type="submit" class="btn btn-outline">{{ trans('general.yes') }}</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row">
|
||||
<div class="row">
|
||||
|
||||
<div class="col-md-8">
|
||||
|
||||
|
@ -85,13 +114,13 @@
|
|||
</a>
|
||||
@endif
|
||||
|
||||
<a data-html="true"
|
||||
href="{{ route('settings.backups.restore', $file['filename']) }}"
|
||||
class="btn btn-warning btn-sm restore-asset {{ (config('app.lock_passwords')) ? ' disabled': '' }}"
|
||||
data-toggle="modal"
|
||||
data-content="{{ trans('admin/settings/message.backup.restore_warning') }}"
|
||||
data-title="{{ trans('admin/settings/message.backup.restore_confirm', array('filename' => e($file['filename']))) }}"
|
||||
onClick="return false;">
|
||||
<a data-html="true"
|
||||
href="{{ route('settings.backups.restore', $file['filename']) }}"
|
||||
class="btn btn-warning btn-sm restore-backup {{ (config('app.lock_passwords')) ? ' disabled': '' }}"
|
||||
{{-- data-toggle="modal"--}}
|
||||
data-target="#backupRestoreModal"
|
||||
data-title="{{ trans('admin/settings/message.backup.restore_confirm', array('filename' => e($file['filename']))) }}"
|
||||
onClick="return false;">
|
||||
<i class="fas fa-retweet" aria-hidden="true"></i>
|
||||
<span class="sr-only">{{ trans('general.restore') }}</span>
|
||||
</a>
|
||||
|
@ -226,11 +255,21 @@
|
|||
});
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
});
|
||||
});
|
||||
|
||||
// due to dynamic loading, we have to use the below 'weird' way of adding event handlers instead of just saying
|
||||
// $('.restore-backup').on( .....
|
||||
$('table').on('click', '.restore-backup', function (event) {
|
||||
event.preventDefault();
|
||||
var modal = $('#backupRestoreModal');
|
||||
modal.find('.modal-title').text($(this).data('title'));
|
||||
modal.find('form').attr('action', $(this).attr('href'));
|
||||
modal.modal({
|
||||
show: true
|
||||
});
|
||||
return false;
|
||||
})
|
||||
</script>
|
||||
@stop
|
||||
|
||||
|
|
Loading…
Reference in a new issue