fixes bug with CSRF on file upload, fixes turbolink issues with remote form submition [fixes SCI-2284]

This commit is contained in:
zmagod 2018-04-10 13:19:53 +02:00
parent d6156e2f4a
commit ea4bd8831f
9 changed files with 144 additions and 38 deletions

View file

@ -157,6 +157,9 @@
$form.clearFormErrors();
switch(resultTypeEnum) {
case ResultTypeEnum.FILE:
_handleResultFileSubmit($form, ev);
break;
case ResultTypeEnum.TABLE:
var $nameInput = $form.find('#result_name');
var nameValid = textValidator(ev, $nameInput, 0,
@ -178,6 +181,55 @@
}
}
// create custom ajax request in order to fix issuses with remote: true from
function _handleResultFileSubmit(form, ev) {
ev.preventDefault();
ev.stopPropagation();
animateSpinner();
var data = new FormData();
var file = document.getElementById('result_asset_attributes_file')
.files[0];
data.append('result[name]', form.find('#result_name').val());
data.append('result[asset_attributes][id]',
form.find('#result_asset_attributes_id').val());
if( file ) {
data.append('result[asset_attributes][file]', file);
}
$.ajax({
type: 'PUT',
url: form.attr('action'),
data: data,
success: function(data) {
animateSpinner(null, false);
$('.edit_result').parent().remove();
$(data.html).prependTo('#results').promise().done(function() {
$.each($('#results').find('.result'),
function() {
initFormSubmitLinks($(this));
ResutlAssets.applyEditResultAssetCallback();
applyCollapseLinkCallBack();
toggleResultEditButtons(true);
initPreviewModal();
Comments.initialize();
ResutlAssets.initNewResultAsset();
expandResult($(this));
});
});
$('#results-toolbar').show();
},
error: function(XHR) {
animateSpinner(null, false)
$('.edit_result').renderFormErrors('result',
XHR.responseJSON['errors']);
},
processData: false,
contentType: false,
});
}
// init cancel button
function initCancelFormButton(form, callback) {
$(form).find('.cancel-new').click(function(event) {

View file

@ -15,22 +15,44 @@
}
function _initParseRecordsModal() {
$('#form-records-file').on('ajax:success', function(ev, data) {
$('#modal-import-records').modal('hide');
$(data.html).appendTo('body').promise().done(function() {
$('#parse-records-modal')
.modal('show')
.on('hidden.bs.modal', function() {
animateSpinner();
location.reload();
});
repositoryRecordsImporter();
var form = $('#form-records-file');
var submitBtn = form.find('input[type="submit"]');
submitBtn.on('click', function(event) {
event.preventDefault();
event.stopPropagation();
var data = new FormData();
data.append('file', document.getElementById('file').files[0]);
data.append('team_id', document.getElementById('team_id').value);
$.ajax({
type: 'POST',
url: form.attr('action'),
data: data,
success: _handleSuccessfulSubmit,
error: _handleErrorSubmit,
processData: false,
contentType: false,
});
}).on('ajax:error', function(ev, data) {
$(this).find('.form-group').addClass('has-error');
$(this).find('.form-group').find('.help-block').remove();
$(this).find('.form-group').append("<span class='help-block'>" +
data.responseJSON.message + '</span>');
});
}
function _handleErrorSubmit(XHR) {
var formGroup = $('#form-records-file').find('.form-group');
formGroup.addClass('has-error');
formGroup.find('.help-block').remove();
formGroup.append('<span class="help-block">' +
XHR.responseJSON.message + '</span>');
}
function _handleSuccessfulSubmit(data) {
$('#modal-import-records').modal('hide');
$(data.html).appendTo('body').promise().done(function() {
$('#parse-records-modal')
.modal('show')
.on('hidden.bs.modal', function() {
animateSpinner();
location.reload();
});
repositoryRecordsImporter();
});
}

View file

@ -1,3 +1,44 @@
(function() {
'use strict';
// handles CSV upload for samples import
function postSamplesCSV() {
var form = $('form#form-samples-file');
var submitBtn = form.find('input[type="submit"]');
submitBtn.on('click', function(event) {
event.preventDefault();
event.stopPropagation();
var data = new FormData();
data.append('file', document.getElementById('file').files[0]);
$.ajax({
type: 'POST',
url: form.attr('action'),
data: data,
success: _handleSuccessfulSubmit,
error: _handleErrorSubmit,
processData: false,
contentType: false,
});
});
}
function _handleSuccessfulSubmit(data) {
$('#modal-parse-samples').html(data.html);
$('#modal-import-samples').modal('hide');
$('#modal-parse-samples').modal('show');
}
function _handleErrorSubmit(XHR) {
var formGroup = $('form#form-samples-file').find('.form-group');
formGroup.addClass('has-error');
formGroup.find('.help-block').remove();
formGroup.append('<span class="help-block">' +
XHR.responseJSON.message + '</span>');
}
$(document).ready(postSamplesCSV);
})()
// Create import samples ajax
$("#modal-import-samples").on("show.bs.modal", function(event) {
formGroup = $(this).find(".form-group");
@ -5,18 +46,6 @@ $("#modal-import-samples").on("show.bs.modal", function(event) {
formGroup.find(".help-block").remove();
});
$("form#form-samples-file")
.on("ajax:success", function(ev, data, status) {
$("#modal-parse-samples").html(data.html);
$("#modal-import-samples").modal("hide");
$("#modal-parse-samples").modal("show");
})
.on("ajax:error", function(ev, data, status) {
$(this).find(".form-group").addClass("has-error");
$(this).find(".form-group").find(".help-block").remove();
$(this).find(".form-group").append("<span class='help-block'>" + data.responseJSON.message + "</span>");
});
$('.sample-assign-group > .btn').click(function() {
$('.btn-group > .btn').removeClass('active btn-primary');
$('.btn-group > .btn').addClass('btn-default');

View file

@ -33,7 +33,12 @@ var renderFormError = function(ev, input, errMsgs, clearErr, errAttributes) {
// Add error message/s
var errorText = ($.makeArray(errMsgs).map(function(m) {
return m.strToErrorFormat();
if( m instanceof Array ) {
return m.join(', ').strToErrorFormat();
} else {
return m.strToErrorFormat();
}
})).join('<br />');
var $errSpan = "<span class='help-block'" +
errAttributes + '>' + errorText + '</span>';

View file

@ -16,4 +16,4 @@ class WopiMethodOverride
app.call(env)
end
end
end

View file

@ -6,10 +6,9 @@
<h4 class="modal-title"><%= t('repositories.modal_import.title') %></h4>
<%= t("repositories.modal_import.notice") %>
</div>
<%= bootstrap_form_tag url: parse_sheet_repository_path(repository, format: :json),
<%= bootstrap_form_tag url: parse_sheet_repository_path(repository),
html: {'data-type' => 'json',
id: 'form-records-file'},
remote: :true do |f| %>
id: 'form-records-file'} do |f| %>
<%= f.hidden_field :team_id, value: current_team.id %>
<div class="modal-body">
<%= f.file_field :file %>

View file

@ -1,5 +1,5 @@
<div class="well">
<%= bootstrap_form_for(@result, url: result_asset_path(format: :json), remote: true, multipart: true, data: { type: :json }) do |f| %>
<%= bootstrap_form_for(@result, url: result_asset_path(format: :json), multipart: true, data: { type: :json }) do |f| %>
<%= f.text_field :name, style: "margin-top: 10px;" %><br />
<%= f.fields_for :asset do |ff| %>
<span><strong><%=t "result_assets.edit.uploaded_asset" %></strong></span>

View file

@ -6,10 +6,9 @@
<h4 class="modal-title"><%= t('samples.modal_import.title') %></h4>
<%= t("samples.modal_import.notice") %>
</div>
<%= bootstrap_form_tag url: parse_sheet_team_path(@team, format: :json),
<%= bootstrap_form_tag url: parse_sheet_team_path(@team),
html: {'data-type' => 'json',
id: 'form-samples-file'},
remote: :true do |f| %>
id: 'form-samples-file'} do |f| %>
<div class="modal-body">
<%= f.file_field :file %>
</div>

View file

@ -177,7 +177,7 @@ Rails.application.routes.draw do
get 'destroy_html'
end
member do
post 'parse_sheet'
post 'parse_sheet', defaults: { format: 'json' }
post 'import_samples'
post 'export_samples'
post 'export_repository', to: 'repositories#export_repository'
@ -475,7 +475,7 @@ Rails.application.routes.draw do
resources :repository_rows, only: %i(create edit update)
member do
post 'parse_sheet'
post 'parse_sheet', defaults: { format: 'json' }
post 'import_records'
end
end