prefs: remove some more stuff from global context (user management, etc)

This commit is contained in:
Andrew Dolgov 2018-12-02 16:17:36 +03:00
parent 58e54282d3
commit b9869dbc01
5 changed files with 163 additions and 225 deletions

View File

@ -166,7 +166,9 @@ class Dlg extends Handler_Protected {
$url_path = htmlspecialchars($this->params[2]) . "&key=" . $key;
print "<h2>".__("You can view this feed as RSS using the following URL:")."</h2>";
$feed_title = Feeds::getFeedTitle($feed_id, $is_cat);
print "<div>".T_sprintf("%s can be accessed via the following secret URL:", $feed_title)."</div>";
print "<div class=\"tagCloudContainer\">";
print "<a id='gen_feed_url' href='$url_path' target='_blank'>$url_path</a>";

View File

@ -1174,7 +1174,7 @@ class Pref_Feeds extends Handler_Protected {
print "<div style='float : right; padding-right : 4px;'>
<input dojoType=\"dijit.form.TextBox\" id=\"feed_search\" size=\"20\" type=\"search\"
value=\"$feed_search\">
<button dojoType=\"dijit.form.Button\" onclick=\"Feeds.reload()\">".
<button dojoType=\"dijit.form.Button\" onclick=\"dijit.byId('feedTree').reload()\">".
__('Search')."</button>
</div>";
@ -1326,7 +1326,7 @@ class Pref_Feeds extends Handler_Protected {
print "<button dojoType=\"dijit.form.Button\" onclick=\"return Utils.displayDlg('".__("Show as feed")."','generatedFeed', '$rss_url')\">".
__('Display URL')."</button> ";
print "<button class=\"warning\" dojoType=\"dijit.form.Button\" onclick=\"return clearFeedAccessKeys()\">".
print "<button class=\"btn-danger\" dojoType=\"dijit.form.Button\" onclick=\"return Prefs.clearFeedAccessKeys()\">".
__('Clear all generated URLs')."</button> ";
print "</p>";

View File

@ -218,12 +218,13 @@ class Pref_Users extends Handler_Protected {
}
function add() {
$login = trim(clean($_REQUEST["login"]));
$tmp_user_pwd = make_password(8);
$salt = substr(bin2hex(get_random_bytes(125)), 0, 250);
$pwd_hash = encrypt_password($tmp_user_pwd, $salt, true);
if (!$login) return; // no blank usernames
$sth = $this->pdo->prepare("SELECT id FROM ttrss_users WHERE
login = ?");
$sth->execute([$login]);
@ -243,18 +244,18 @@ class Pref_Users extends Handler_Protected {
$new_uid = $row['id'];
print format_notice(T_sprintf("Added user <b>%s</b> with password <b>%s</b>",
$login, $tmp_user_pwd));
print T_sprintf("Added user %s with password %s",
$login, $tmp_user_pwd);
initialize_user($new_uid);
} else {
print format_warning(T_sprintf("Could not create user <b>%s</b>", $login));
print T_sprintf("Could not create user %s", $login);
}
} else {
print format_warning(T_sprintf("User <b>%s</b> already exists.", $login));
print T_sprintf("User %s already exists.", $login);
}
}
@ -282,9 +283,9 @@ class Pref_Users extends Handler_Protected {
$sth->execute([$pwd_hash, $new_salt, $uid]);
if ($show_password) {
print T_sprintf("Changed password of user <b>%s</b> to <b>%s</b>", $login, $tmp_user_pwd);
print T_sprintf("Changed password of user %s to %s", $login, $tmp_user_pwd);
} else {
print_notice(T_sprintf("Sending new password of user <b>%s</b> to <b>%s</b>", $login, $email));
print_notice(T_sprintf("Sending new password of user %s to %s", $login, $email));
}
if ($email) {
@ -341,7 +342,7 @@ class Pref_Users extends Handler_Protected {
print "<div style='float : right; padding-right : 4px;'>
<input dojoType=\"dijit.form.TextBox\" id=\"user_search\" size=\"20\" type=\"search\"
value=\"$user_search\">
<button dojoType=\"dijit.form.Button\" onclick=\"updateUsersList()\">".
<button dojoType=\"dijit.form.Button\" oncl1ick=\"Users.reload()\">".
__('Search')."</button>
</div>";
@ -360,14 +361,14 @@ class Pref_Users extends Handler_Protected {
dojoType=\"dijit.MenuItem\">".__('None')."</div>";
print "</div></div>";
print "<button dojoType=\"dijit.form.Button\" onclick=\"addUser()\">".__('Create user')."</button>";
print "<button dojoType=\"dijit.form.Button\" onclick=\"Users.add()\">".__('Create user')."</button>";
print "
<button dojoType=\"dijit.form.Button\" onclick=\"editSelectedUser()\">".
<button dojoType=\"dijit.form.Button\" onclick=\"Users.editSelected()\">".
__('Edit')."</button dojoType=\"dijit.form.Button\">
<button dojoType=\"dijit.form.Button\" onclick=\"removeSelectedUsers()\">".
<button dojoType=\"dijit.form.Button\" onclick=\"Users.removeSelected()\">".
__('Remove')."</button dojoType=\"dijit.form.Button\">
<button dojoType=\"dijit.form.Button\" onclick=\"resetSelectedUserPass()\">".
<button dojoType=\"dijit.form.Button\" onclick=\"Users.resetSelected()\">".
__('Reset password')."</button dojoType=\"dijit.form.Button\">";
PluginHost::getInstance()->run_hooks(PluginHost::HOOK_PREFS_TAB_SECTION,
@ -400,11 +401,11 @@ class Pref_Users extends Handler_Protected {
print "<tr class=\"title\">
<td align='center' width=\"5%\">&nbsp;</td>
<td width='20%'><a href=\"#\" onclick=\"updateUsersList('login')\">".__('Login')."</a></td>
<td width='20%'><a href=\"#\" onclick=\"updateUsersList('access_level')\">".__('Access Level')."</a></td>
<td width='10%'><a href=\"#\" onclick=\"updateUsersList('num_feeds')\">".__('Subscribed feeds')."</a></td>
<td width='20%'><a href=\"#\" onclick=\"updateUsersList('created')\">".__('Registered')."</a></td>
<td width='20%'><a href=\"#\" onclick=\"updateUsersList('last_login')\">".__('Last login')."</a></td></tr>";
<td width='20%'><a href=\"#\" onclick=\"Users.reload('login')\">".__('Login')."</a></td>
<td width='20%'><a href=\"#\" onclick=\"Users.reload('access_level')\">".__('Access Level')."</a></td>
<td width='10%'><a href=\"#\" onclick=\"Users.reload('num_feeds')\">".__('Subscribed feeds')."</a></td>
<td width='20%'><a href=\"#\" onclick=\"Users.reload('created')\">".__('Registered')."</a></td>
<td width='20%'><a href=\"#\" onclick=\"Users.reload('last_login')\">".__('Last login')."</a></td></tr>";
$lnum = 0;
@ -412,26 +413,21 @@ class Pref_Users extends Handler_Protected {
$uid = $line["id"];
print "<tr data-row-id=\"$uid\">";
print "<tr data-row-id=\"$uid\" onclick='Users.edit($uid)'>";
$line["login"] = htmlspecialchars($line["login"]);
$line["created"] = make_local_datetime($line["created"], false);
$line["last_login"] = make_local_datetime($line["last_login"], false);
print "<td align='center'><input onclick='Tables.onRowChecked(this);'
print "<td align='center'><input onclick='Tables.onRowChecked(this); event.stopPropagation();'
dojoType=\"dijit.form.CheckBox\" type=\"checkbox\"></td>";
$onclick = "onclick='editUser($uid, event)' title='".__('Click to edit')."'";
print "<td title='".__('Click to edit')."'><img src='images/user.png' class='marked-pic' alt=''> " . $line["login"] . "</td>";
print "<td $onclick><img src='images/user.png' class='marked-pic' alt=''> " . $line["login"] . "</td>";
if (!$line["email"]) $line["email"] = "&nbsp;";
print "<td $onclick>" . $access_level_names[$line["access_level"]] . "</td>";
print "<td $onclick>" . $line["num_feeds"] . "</td>";
print "<td $onclick>" . $line["created"] . "</td>";
print "<td $onclick>" . $line["last_login"] . "</td>";
print "<td>" . $access_level_names[$line["access_level"]] . "</td>";
print "<td>" . $line["num_feeds"] . "</td>";
print "<td>" . $line["created"] . "</td>";
print "<td>" . $line["last_login"] . "</td>";
print "</tr>";

View File

@ -82,6 +82,15 @@ define(["dojo/_base/declare", "dojo/dom-construct", "lib/CheckBoxTree"], functio
getIconClass: function (item, opened) {
return (!item || this.model.store.getValue(item, 'type') == 'category') ? (opened ? "dijitFolderOpened" : "dijitFolderClosed") : "feedIcon";
},
reload: function() {
const searchElem = $("feed_search");
let search = (searchElem) ? searchElem.value : "";
xhrPost("backend.php", { op: "pref-feeds", search: search }, (transport) => {
dijit.byId('feedConfigTab').attr('content', transport.responseText);
notify("");
});
},
checkItemAcceptance: function(target, source, position) {
const item = dijit.getEnclosingWidget(target).item;
@ -113,14 +122,14 @@ define(["dojo/_base/declare", "dojo/dom-construct", "lib/CheckBoxTree"], functio
notify_progress("Loading, please wait...");
xhrPost("backend.php", {op: "pref-feeds", method: "feedsortreset"}, () => {
updateFeedList();
this.reload();
});
},
resetCatOrder: function() {
notify_progress("Loading, please wait...");
xhrPost("backend.php", {op: "pref-feeds", method: "catsortreset"}, () => {
updateFeedList();
this.reload();
});
},
removeCategory: function(id, item) {
@ -129,7 +138,7 @@ define(["dojo/_base/declare", "dojo/dom-construct", "lib/CheckBoxTree"], functio
xhrPost("backend.php", {op: "pref-feeds", method: "removeCat", ids: id}, () => {
notify('');
updateFeedList();
this.reload();
});
}
},
@ -147,7 +156,7 @@ define(["dojo/_base/declare", "dojo/dom-construct", "lib/CheckBoxTree"], functio
};
xhrPost("backend.php", query, () => {
updateFeedList();
this.reload();
});
}
@ -189,7 +198,7 @@ define(["dojo/_base/declare", "dojo/dom-construct", "lib/CheckBoxTree"], functio
};
xhrPost("backend.php", query, () => {
updateFeedList();
this.reload();
});
}
} else {
@ -284,7 +293,7 @@ define(["dojo/_base/declare", "dojo/dom-construct", "lib/CheckBoxTree"], functio
xhrPost("backend.php", query, () => {
dialog.hide();
updateFeedList();
dijit.byId("feedTree").reload();
});
}
},
@ -306,7 +315,7 @@ define(["dojo/_base/declare", "dojo/dom-construct", "lib/CheckBoxTree"], functio
notify_progress("Loading, please wait...");
xhrPost("backend.php", { op: 'pref-feeds', method: 'renamecat', id: id, title: new_name }, () => {
updateFeedList();
this.reload();
});
}
},
@ -318,7 +327,7 @@ define(["dojo/_base/declare", "dojo/dom-construct", "lib/CheckBoxTree"], functio
xhrPost("backend.php", {op: "pref-feeds", method: "addCat", cat: title}, () => {
notify('');
updateFeedList();
this.reload();
});
}
},
@ -339,7 +348,7 @@ define(["dojo/_base/declare", "dojo/dom-construct", "lib/CheckBoxTree"], functio
xhrPost("backend.php", this.attr('value'), () => {
notify("");
updateFeedList();
dijit.byId("feedTree").reload();
dialog.hide();
});
}
@ -376,8 +385,8 @@ define(["dojo/_base/declare", "dojo/dom-construct", "lib/CheckBoxTree"], functio
xhrPost("backend.php", query, () => {
notify('');
dijit.byId("feedTree").reload();
dialog.hide();
updateFeedList();
});
}

View File

@ -132,6 +132,17 @@ const App = {
};
const Prefs = {
clearFeedAccessKeys: function() {
if (confirm(__("This will invalidate all previously generated feed URLs. Continue?"))) {
notify_progress("Clearing URLs...");
xhrPost("backend.php", {op: "pref-feeds", method: "clearKeys"}, () => {
notify_info("Generated URLs cleared.");
});
}
return false;
},
clearEventLog: function() {
if (confirm(__("Clear event log?"))) {
@ -264,187 +275,120 @@ const Prefs = {
}
};
function notify_callback2(transport, sticky) {
notify_info(transport.responseText, sticky);
}
const Users = {
reload: function(sort) {
const user_search = $("user_search");
const search = user_search ? user_search.value : "";
function updateFeedList() {
xhrPost("backend.php", { op: "pref-users", sort: sort, search: search }, (transport) => {
dijit.byId('userConfigTab').attr('content', transport.responseText);
notify("");
});
},
add: function() {
const login = prompt(__("Please enter username:"), "");
const user_search = $("feed_search");
let search = "";
if (user_search) { search = user_search.value; }
if (login) {
notify_progress("Adding user...");
xhrPost("backend.php", { op: "pref-feeds", search: search }, (transport) => {
dijit.byId('feedConfigTab').attr('content', transport.responseText);
notify("");
});
}
function updateUsersList(sort_key) {
const user_search = $("user_search");
const search = user_search ? user_search.value : "";
const query = { op: "pref-users", sort: sort_key, search: search };
xhrPost("backend.php", query, (transport) => {
dijit.byId('userConfigTab').attr('content', transport.responseText);
notify("");
});
}
function addUser() {
const login = prompt(__("Please enter login:"), "");
if (login == null) {
return false;
}
if (login == "") {
alert(__("Can't create user: no login specified."));
return false;
}
notify_progress("Adding user...");
xhrPost("backend.php", { op: "pref-users", method: "add", login: login }, (transport) => {
notify_callback2(transport);
updateUsersList();
});
}
function editUser(id) {
const query = "backend.php?op=pref-users&method=edit&id=" +
param_escape(id);
if (dijit.byId("userEditDlg"))
dijit.byId("userEditDlg").destroyRecursive();
const dialog = new dijit.Dialog({
id: "userEditDlg",
title: __("User Editor"),
style: "width: 600px",
execute: function () {
if (this.validate()) {
notify_progress("Saving data...", true);
xhrPost("backend.php", dojo.formToObject("user_edit_form"), (transport) => {
dialog.hide();
updateUsersList();
});
}
},
href: query
});
dialog.show();
}
function getSelectedUsers() {
return Tables.getSelected("prefUserList");
}
function removeSelectedUsers() {
const sel_rows = getSelectedUsers();
if (sel_rows.length > 0) {
if (confirm(__("Remove selected users? Neither default admin nor your account will be removed."))) {
notify_progress("Removing selected users...");
const query = { op: "pref-users", method: "remove",
ids: sel_rows.toString() };
xhrPost("backend.php", query, () => {
updateUsersList();
xhrPost("backend.php", {op: "pref-users", method: "add", login: login}, (transport) => {
alert(transport.responseText);
Users.reload();
});
}
},
edit: function(id) {
const query = "backend.php?op=pref-users&method=edit&id=" +
param_escape(id);
} else {
alert(__("No users are selected."));
}
if (dijit.byId("userEditDlg"))
dijit.byId("userEditDlg").destroyRecursive();
return false;
}
const dialog = new dijit.Dialog({
id: "userEditDlg",
title: __("User Editor"),
style: "width: 600px",
execute: function () {
if (this.validate()) {
notify_progress("Saving data...", true);
function editSelectedUser() {
const rows = getSelectedUsers();
if (rows.length == 0) {
alert(__("No users are selected."));
return;
}
if (rows.length > 1) {
alert(__("Please select only one user."));
return;
}
notify("");
editUser(rows[0]);
}
function resetSelectedUserPass() {
const rows = getSelectedUsers();
if (rows.length == 0) {
alert(__("No users are selected."));
return;
}
if (rows.length > 1) {
alert(__("Please select only one user."));
return;
}
if (confirm(__("Reset password of selected user?"))) {
notify_progress("Resetting password for selected user...");
const id = rows[0];
xhrPost("backend.php", { op: "pref-users", method: "resetPass", id: id }, (transport) => {
notify_info(transport.responseText, true);
xhrPost("backend.php", dojo.formToObject("user_edit_form"), (transport) => {
dialog.hide();
Users.reload();
});
}
},
href: query
});
dialog.show();
},
resetSelected: function() {
const rows = this.getSelection();
if (rows.length == 0) {
alert(__("No users are selected."));
return;
}
if (rows.length > 1) {
alert(__("Please select one user."));
return;
}
if (confirm(__("Reset password of selected user?"))) {
notify_progress("Resetting password for selected user...");
const id = rows[0];
xhrPost("backend.php", {op: "pref-users", method: "resetPass", id: id}, (transport) => {
notify('');
alert(transport.responseText);
});
}
},
removeSelected: function() {
const sel_rows = this.getSelection();
if (sel_rows.length > 0) {
if (confirm(__("Remove selected users? Neither default admin nor your account will be removed."))) {
notify_progress("Removing selected users...");
const query = {
op: "pref-users", method: "remove",
ids: sel_rows.toString()
};
xhrPost("backend.php", query, () => {
this.reload();
});
}
} else {
alert(__("No users are selected."));
}
},
editSelected: function() {
const rows = this.getSelection();
if (rows.length == 0) {
alert(__("No users are selected."));
return;
}
if (rows.length > 1) {
alert(__("Please select one user."));
return;
}
this.edit(rows[0]);
},
getSelection :function() {
return Tables.getSelected("prefUserList");
}
}
function selectedUserDetails() {
const rows = getSelectedUsers();
if (rows.length == 0) {
alert(__("No users are selected."));
return;
}
if (rows.length > 1) {
alert(__("Please select only one user."));
return;
}
const query = "backend.php?op=pref-users&method=userdetails&id=" + param_escape(rows[0]);
if (dijit.byId("userDetailsDlg"))
dijit.byId("userDetailsDlg").destroyRecursive();
const dialog = new dijit.Dialog({
id: "userDetailsDlg",
title: __("User details"),
style: "width: 600px",
execute: function () {
dialog.hide();
},
href: query
});
dialog.show();
}
};
function opmlImportComplete(iframe) {
if (!iframe.contentDocument.body.innerHTML) return false;
@ -541,19 +485,6 @@ function opmlRegenKey() {
return false;
}
function clearFeedAccessKeys() {
if (confirm(__("This will invalidate all previously generated feed URLs. Continue?"))) {
notify_progress("Clearing URLs...");
xhrPost("backend.php", { op: "pref-feeds", method: "clearKeys" }, () => {
notify_info("Generated URLs cleared.");
});
}
return false;
}
function gotoExportOpml(filename, settings) {
const tmp = settings ? 1 : 0;
document.location.href = "backend.php?op=opml&method=export&filename=" + filename + "&settings=" + tmp;