Feeds: load quickaddfeed and search dialogs via XHR w/ CSRF protection
This commit is contained in:
parent
8080c525fd
commit
cbcb10a272
|
@ -8,7 +8,7 @@ class Feeds extends Handler_Protected {
|
||||||
private $params;
|
private $params;
|
||||||
|
|
||||||
function csrf_ignore($method) {
|
function csrf_ignore($method) {
|
||||||
$csrf_ignored = array("index", "quickaddfeed", "search");
|
$csrf_ignored = array("index");
|
||||||
|
|
||||||
return array_search($method, $csrf_ignored) !== false;
|
return array_search($method, $csrf_ignored) !== false;
|
||||||
}
|
}
|
||||||
|
|
|
@ -75,116 +75,120 @@ const CommonDialogs = {
|
||||||
return false;
|
return false;
|
||||||
},
|
},
|
||||||
quickAddFeed: function() {
|
quickAddFeed: function() {
|
||||||
const query = "backend.php?op=feeds&method=quickAddFeed";
|
|
||||||
|
|
||||||
// overlapping widgets
|
// overlapping widgets
|
||||||
if (dijit.byId("batchSubDlg")) dijit.byId("batchSubDlg").destroyRecursive();
|
if (dijit.byId("batchSubDlg")) dijit.byId("batchSubDlg").destroyRecursive();
|
||||||
if (dijit.byId("feedAddDlg")) dijit.byId("feedAddDlg").destroyRecursive();
|
if (dijit.byId("feedAddDlg")) dijit.byId("feedAddDlg").destroyRecursive();
|
||||||
|
|
||||||
const dialog = new dijit.Dialog({
|
xhrPost("backend.php",
|
||||||
id: "feedAddDlg",
|
{op: "feeds", method: "quickAddFeed"},
|
||||||
title: __("Subscribe to Feed"),
|
(transport) => {
|
||||||
style: "width: 600px",
|
|
||||||
show_error: function (msg) {
|
|
||||||
const elem = $("fadd_error_message");
|
|
||||||
|
|
||||||
elem.innerHTML = msg;
|
const dialog = new dijit.Dialog({
|
||||||
|
id: "feedAddDlg",
|
||||||
|
title: __("Subscribe to Feed"),
|
||||||
|
style: "width: 600px",
|
||||||
|
content: transport.responseText,
|
||||||
|
show_error: function (msg) {
|
||||||
|
const elem = $("fadd_error_message");
|
||||||
|
|
||||||
if (!Element.visible(elem))
|
elem.innerHTML = msg;
|
||||||
new Effect.Appear(elem);
|
|
||||||
|
|
||||||
},
|
if (!Element.visible(elem))
|
||||||
execute: function () {
|
new Effect.Appear(elem);
|
||||||
if (this.validate()) {
|
|
||||||
console.log(dojo.objectToQuery(this.attr('value')));
|
|
||||||
|
|
||||||
const feed_url = this.attr('value').feed;
|
},
|
||||||
|
execute: function () {
|
||||||
|
if (this.validate()) {
|
||||||
|
console.log(dojo.objectToQuery(this.attr('value')));
|
||||||
|
|
||||||
Element.show("feed_add_spinner");
|
const feed_url = this.attr('value').feed;
|
||||||
Element.hide("fadd_error_message");
|
|
||||||
|
|
||||||
xhrPost("backend.php", this.attr('value'), (transport) => {
|
Element.show("feed_add_spinner");
|
||||||
try {
|
Element.hide("fadd_error_message");
|
||||||
|
|
||||||
let reply;
|
xhrPost("backend.php", this.attr('value'), (transport) => {
|
||||||
|
try {
|
||||||
|
|
||||||
try {
|
let reply;
|
||||||
reply = JSON.parse(transport.responseText);
|
|
||||||
} catch (e) {
|
|
||||||
Element.hide("feed_add_spinner");
|
|
||||||
alert(__("Failed to parse output. This can indicate server timeout and/or network issues. Backend output was logged to browser console."));
|
|
||||||
console.log('quickAddFeed, backend returned:' + transport.responseText);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
const rc = reply['result'];
|
try {
|
||||||
|
reply = JSON.parse(transport.responseText);
|
||||||
Notify.close();
|
} catch (e) {
|
||||||
Element.hide("feed_add_spinner");
|
Element.hide("feed_add_spinner");
|
||||||
|
alert(__("Failed to parse output. This can indicate server timeout and/or network issues. Backend output was logged to browser console."));
|
||||||
console.log(rc);
|
console.log('quickAddFeed, backend returned:' + transport.responseText);
|
||||||
|
return;
|
||||||
switch (parseInt(rc['code'])) {
|
|
||||||
case 1:
|
|
||||||
dialog.hide();
|
|
||||||
Notify.info(__("Subscribed to %s").replace("%s", feed_url));
|
|
||||||
|
|
||||||
if (App.isPrefs())
|
|
||||||
dijit.byId("feedTree").reload();
|
|
||||||
else
|
|
||||||
Feeds.reload();
|
|
||||||
|
|
||||||
break;
|
|
||||||
case 2:
|
|
||||||
dialog.show_error(__("Specified URL seems to be invalid."));
|
|
||||||
break;
|
|
||||||
case 3:
|
|
||||||
dialog.show_error(__("Specified URL doesn't seem to contain any feeds."));
|
|
||||||
break;
|
|
||||||
case 4:
|
|
||||||
{
|
|
||||||
const feeds = rc['feeds'];
|
|
||||||
|
|
||||||
Element.show("fadd_multiple_notify");
|
|
||||||
|
|
||||||
const select = dijit.byId("feedDlg_feedContainerSelect");
|
|
||||||
|
|
||||||
while (select.getOptions().length > 0)
|
|
||||||
select.removeOption(0);
|
|
||||||
|
|
||||||
select.addOption({value: '', label: __("Expand to select feed")});
|
|
||||||
|
|
||||||
for (const feedUrl in feeds) {
|
|
||||||
if (feeds.hasOwnProperty(feedUrl)) {
|
|
||||||
select.addOption({value: feedUrl, label: feeds[feedUrl]});
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Effect.Appear('feedDlg_feedsContainer', {duration: 0.5});
|
const rc = reply['result'];
|
||||||
|
|
||||||
|
Notify.close();
|
||||||
|
Element.hide("feed_add_spinner");
|
||||||
|
|
||||||
|
console.log(rc);
|
||||||
|
|
||||||
|
switch (parseInt(rc['code'])) {
|
||||||
|
case 1:
|
||||||
|
dialog.hide();
|
||||||
|
Notify.info(__("Subscribed to %s").replace("%s", feed_url));
|
||||||
|
|
||||||
|
if (App.isPrefs())
|
||||||
|
dijit.byId("feedTree").reload();
|
||||||
|
else
|
||||||
|
Feeds.reload();
|
||||||
|
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
dialog.show_error(__("Specified URL seems to be invalid."));
|
||||||
|
break;
|
||||||
|
case 3:
|
||||||
|
dialog.show_error(__("Specified URL doesn't seem to contain any feeds."));
|
||||||
|
break;
|
||||||
|
case 4:
|
||||||
|
{
|
||||||
|
const feeds = rc['feeds'];
|
||||||
|
|
||||||
|
Element.show("fadd_multiple_notify");
|
||||||
|
|
||||||
|
const select = dijit.byId("feedDlg_feedContainerSelect");
|
||||||
|
|
||||||
|
while (select.getOptions().length > 0)
|
||||||
|
select.removeOption(0);
|
||||||
|
|
||||||
|
select.addOption({value: '', label: __("Expand to select feed")});
|
||||||
|
|
||||||
|
for (const feedUrl in feeds) {
|
||||||
|
if (feeds.hasOwnProperty(feedUrl)) {
|
||||||
|
select.addOption({value: feedUrl, label: feeds[feedUrl]});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Effect.Appear('feedDlg_feedsContainer', {duration: 0.5});
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 5:
|
||||||
|
dialog.show_error(__("Couldn't download the specified URL: %s").replace("%s", rc['message']));
|
||||||
|
break;
|
||||||
|
case 6:
|
||||||
|
dialog.show_error(__("XML validation failed: %s").replace("%s", rc['message']));
|
||||||
|
break;
|
||||||
|
case 0:
|
||||||
|
dialog.show_error(__("You are already subscribed to this feed."));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
} catch (e) {
|
||||||
|
console.error(transport.responseText);
|
||||||
|
App.Error.report(e);
|
||||||
}
|
}
|
||||||
break;
|
});
|
||||||
case 5:
|
|
||||||
dialog.show_error(__("Couldn't download the specified URL: %s").replace("%s", rc['message']));
|
|
||||||
break;
|
|
||||||
case 6:
|
|
||||||
dialog.show_error(__("XML validation failed: %s").replace("%s", rc['message']));
|
|
||||||
break;
|
|
||||||
case 0:
|
|
||||||
dialog.show_error(__("You are already subscribed to this feed."));
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
},
|
||||||
} catch (e) {
|
|
||||||
console.error(transport.responseText);
|
|
||||||
App.Error.report(e);
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
}
|
|
||||||
},
|
|
||||||
href: query
|
|
||||||
});
|
|
||||||
|
|
||||||
dialog.show();
|
dialog.show();
|
||||||
|
});
|
||||||
},
|
},
|
||||||
showFeedsWithErrors: function() {
|
showFeedsWithErrors: function() {
|
||||||
const query = {op: "pref-feeds", method: "feedsWithErrors"};
|
const query = {op: "pref-feeds", method: "feedsWithErrors"};
|
||||||
|
|
65
js/Feeds.js
65
js/Feeds.js
|
@ -552,47 +552,50 @@ const Feeds = {
|
||||||
return tree.model.store.getValue(nuf, 'bare_id');
|
return tree.model.store.getValue(nuf, 'bare_id');
|
||||||
},
|
},
|
||||||
search: function() {
|
search: function() {
|
||||||
const query = "backend.php?op=feeds&method=search¶m=" +
|
|
||||||
encodeURIComponent(Feeds.getActive() + ":" + Feeds.activeIsCat());
|
|
||||||
|
|
||||||
if (dijit.byId("searchDlg"))
|
if (dijit.byId("searchDlg"))
|
||||||
dijit.byId("searchDlg").destroyRecursive();
|
dijit.byId("searchDlg").destroyRecursive();
|
||||||
|
|
||||||
const dialog = new dijit.Dialog({
|
xhrPost("backend.php",
|
||||||
id: "searchDlg",
|
{op: "feeds", method: "search",
|
||||||
title: __("Search"),
|
param: Feeds.getActive() + ":" + Feeds.activeIsCat()},
|
||||||
style: "width: 600px",
|
(transport) => {
|
||||||
execute: function () {
|
const dialog = new dijit.Dialog({
|
||||||
if (this.validate()) {
|
id: "searchDlg",
|
||||||
Feeds._search_query = this.attr('value');
|
content: transport.responseText,
|
||||||
|
title: __("Search"),
|
||||||
|
style: "width: 600px",
|
||||||
|
execute: function () {
|
||||||
|
if (this.validate()) {
|
||||||
|
Feeds._search_query = this.attr('value');
|
||||||
|
|
||||||
// disallow empty queries
|
// disallow empty queries
|
||||||
if (!Feeds._search_query.query)
|
if (!Feeds._search_query.query)
|
||||||
Feeds._search_query = false;
|
Feeds._search_query = false;
|
||||||
|
|
||||||
this.hide();
|
this.hide();
|
||||||
Feeds.reloadCurrent();
|
Feeds.reloadCurrent();
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
href: query
|
});
|
||||||
});
|
|
||||||
|
|
||||||
const tmph = dojo.connect(dialog, 'onLoad', function () {
|
const tmph = dojo.connect(dialog, 'onLoad', function () {
|
||||||
dojo.disconnect(tmph);
|
dojo.disconnect(tmph);
|
||||||
|
|
||||||
if (Feeds._search_query) {
|
if (Feeds._search_query) {
|
||||||
if (Feeds._search_query.query)
|
if (Feeds._search_query.query)
|
||||||
dijit.byId('search_query')
|
dijit.byId('search_query')
|
||||||
.attr('value', Feeds._search_query.query);
|
.attr('value', Feeds._search_query.query);
|
||||||
|
|
||||||
if (Feeds._search_query.search_language)
|
if (Feeds._search_query.search_language)
|
||||||
dijit.byId('search_language')
|
dijit.byId('search_language')
|
||||||
.attr('value', Feeds._search_query.search_language);
|
.attr('value', Feeds._search_query.search_language);
|
||||||
}
|
}
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
|
dialog.show();
|
||||||
|
});
|
||||||
|
|
||||||
dialog.show();
|
|
||||||
},
|
},
|
||||||
updateRandom: function() {
|
updateRandom: function() {
|
||||||
console.log("in update_random_feed");
|
console.log("in update_random_feed");
|
||||||
|
|
Loading…
Reference in New Issue