Skip to content

Commit af45169

Browse files
committed
csrf protection for delete, fix up issue with modals
1 parent 32d3fa9 commit af45169

File tree

2 files changed

+62
-21
lines changed

2 files changed

+62
-21
lines changed

client/js/ManyField.src.js

Lines changed: 50 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -4,19 +4,23 @@
44
var wrapManyFields = function() {
55
$('.manyfield__holder').each(function(i, elem) {
66
var canSort = $(elem).hasClass('manyfield__holder--cansort')
7-
var canAdd = $(elem).find('.manyfield__add').length > 0
87
var canRemove = $(elem).hasClass('manyfield__holder--canremove')
9-
108
var field = $(elem).find('.manyfield__row')
119

1210
$(elem).find('.manyfield__row').each(function (r, row) {
1311
if (canRemove) {
1412
if (!$(row).find('.manyfield__remove').length) {
15-
var href = $(this).data('inline-save');
13+
var href = $(this).data('inline-delete');
1614

1715
if (href) {
1816
href.replace('saveRecord', 'deleteRecord');
19-
href = href + '?ID='+ $(row).find('[name=ID]').val();
17+
var id = $(row).find('input[type="hidden"][name*=ID]');
18+
19+
if (id.length < 1) {
20+
console.error('No ID hidden field in ManyField row');
21+
}
22+
23+
href = href + '?ID='+ id.val();
2024

2125
$(row).prepend('<a class="btn btn-sm btn-danger manyfield__remove" href="' + href + '"><i class="fa fa-times"></i></a>');
2226
}
@@ -56,28 +60,34 @@
5660
value = $(field).val();
5761
}
5862

63+
var cleanName = name.substr(name.indexOf('[') + 1, name.indexOf(']') - (name.indexOf('[') + 1));
64+
65+
66+
if (name.split('[').length > 3) {
67+
cleanName += name.substr(name.lastIndexOf('['), name.lastIndexOf(']') - (name.lastIndexOf('[') - 1));
68+
}
69+
5970
data.push({
60-
name: name.substr(name.indexOf('[') + 1, name.indexOf(']') - (name.indexOf('[') + 1)),
71+
name: cleanName,
6172
value: value
6273
})
6374
})
6475

76+
6577
data.push({
6678
name: 'SecurityID',
6779
value: csrf
6880
})
6981

7082
$.post(url, $.param(data), function() {
71-
//..
83+
$('body').trigger('manyFieldSaved');
7284
});
7385
})
7486

7587
$('body').on('click', '.manyfield__add a', function(e) {
7688
e.preventDefault();
7789

78-
var
79-
form = $(this).parents('form'),
80-
parents = $(this).parents('.manyfield__holder');
90+
var parents = $(this).parents('.manyfield__holder');
8191

8292
$.get($(this).attr('href'), { index: parents.find('.manyfield__row').length }, function(data) {
8393
var rows = parents.find('.manyfield__row').last()
@@ -91,7 +101,7 @@
91101

92102
// write the provided names as we don't need to namespace them in this
93103
// case - we can only edit one at a time
94-
var content = $(data)
104+
var content = $(data);
95105
content.find('input[name]').each(function(i, field) {
96106
if ($(field).attr('name').indexOf('[') !== false) {
97107
var name = $(field).attr('name').substring(
@@ -103,7 +113,15 @@
103113
}
104114
});
105115

106-
modal.find('.modal-body').html(content.html());
116+
// move the modal form outside of the main form
117+
if (modal.parents('form').length > 0) {
118+
modal.detach().prependTo('body');
119+
}
120+
121+
122+
var saveURL = modal.attr('data-save-url');
123+
content = $('<form action="'+ saveURL + '"></form>').html(data)
124+
modal.find('.modal-body').html(content);
107125
modal.modal('show');
108126
} else {
109127
if (rows && rows.length) {
@@ -133,8 +151,12 @@
133151

134152
parent.remove()
135153

154+
var data = {
155+
'SecurityID': $('input[name=SecurityID]').val()
156+
};
157+
136158
if ($(this).attr('href')) {
137-
$.post($(this).attr('href'));
159+
$.post($(this).attr('href'), data);
138160
}
139161

140162
$('body').trigger('manyFieldRemoved', {
@@ -154,16 +176,25 @@
154176
form
155177
});
156178

157-
if (form.get(0).checkValidity()) {
179+
if (form.length > 0 && form.get(0).checkValidity()) {
158180
var body = $(this).parents('.modal-content').find('.modal-body')
159181
.addClass('loading')
160182

161-
$.post(form.attr('action'), form.serialize(), function(reply) {
183+
var action = form.attr('action');
184+
185+
if (!action) {
186+
console.error('No action found on form');
187+
return;
188+
}
189+
190+
$.post(action, form.serialize(), function(reply) {
162191
// reply should be the updated content for
163-
form.parents('.manyfield__holder').html(reply);
164-
body.html('');
192+
if (reply) {
193+
form.parents('.manyfield__holder').html(reply);
194+
body.html('');
195+
}
165196

166-
form.parents('.modal').modal('hide');
197+
$('.modal').modal('hide');
167198
$('body').removeClass('modal-open');
168199
$('.modal-backdrop').remove();
169200

@@ -175,6 +206,8 @@
175206
// highlight issues
176207
e.preventDefault();
177208

209+
alert('You are missing one or more fields');
210+
178211
return false;
179212
}
180213
})

src/ManyField.php

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -474,7 +474,7 @@ public function deleteRecord()
474474
$request = Controller::curr()->getRequest();
475475

476476
if (!SecurityToken::inst()->checkRequest($request)) {
477-
return Controller::curr()->httpError(400);
477+
return Controller::curr()->httpError(400, 'Bad security token');
478478
}
479479

480480
if ($this->readonly) {
@@ -499,7 +499,7 @@ public function deleteRecord()
499499
$record = $class::get()->byId($index);
500500

501501
if (!$record || !$record->canDelete()) {
502-
return Controller::curr()->httpError(400);
502+
return Controller::curr()->httpError(404, 'No record found with that ID');
503503
}
504504

505505
$record->delete();
@@ -660,13 +660,21 @@ public function generateRow($index, $value = null, $prefixName = true)
660660
$field = $field->setReadonly($this->readonly);
661661
$field = $field->setDisabled($this->readonly);
662662

663-
$row->push($field);
663+
if ($value && $value->hasMethod('modifyManyRecordField')) {
664+
$field = $value->modifyManyRecordField($field);
665+
}
666+
667+
if ($field) {
668+
$row->push($field);
669+
}
664670
}
665671

672+
666673
if ($this->inlineSave) {
667674
$row
668675
->addExtraClass('inline-save')
669-
->setAttribute('data-inline-save', $this->Link('saveRecord'));
676+
->setAttribute('data-inline-save', $this->Link('saveRecord'))
677+
->setAttribute('data-inline-delete', $this->Link('deleteRecord'));;
670678
}
671679

672680
$this->extend('alterRow', $row);

0 commit comments

Comments
 (0)