diff options
-rw-r--r-- | classes/pref/users.php | 112 | ||||
-rw-r--r-- | js/App.js | 9 | ||||
-rw-r--r-- | js/PrefUsers.js | 84 |
3 files changed, 105 insertions, 100 deletions
diff --git a/classes/pref/users.php b/classes/pref/users.php index b34f85d88..bc125d0ce 100644 --- a/classes/pref/users.php +++ b/classes/pref/users.php @@ -1,7 +1,7 @@ <?php class Pref_Users extends Handler_Administrative { function csrf_ignore($method) { - $csrf_ignored = array("index", "userdetails"); + $csrf_ignored = array("index"); return array_search($method, $csrf_ignored) !== false; } @@ -9,105 +9,19 @@ class Pref_Users extends Handler_Administrative { function edit() { global $access_level_names; - print "<form id='user_edit_form' onsubmit='return false' dojoType='dijit.form.Form'>"; + $id = (int)clean($_REQUEST["id"]); - print '<div dojoType="dijit.layout.TabContainer" style="height : 400px"> - <div dojoType="dijit.layout.ContentPane" title="'.__('Edit user').'">'; - - //print "<form id=\"user_edit_form\" onsubmit='return false' dojoType=\"dijit.form.Form\">"; - - $id = (int) clean($_REQUEST["id"]); - - print_hidden("id", "$id"); - print_hidden("op", "pref-users"); - print_hidden("method", "editSave"); - - $sth = $this->pdo->prepare("SELECT * FROM ttrss_users WHERE id = ?"); + $sth = $this->pdo->prepare("SELECT id, login, access_level, email FROM ttrss_users WHERE id = ?"); $sth->execute([$id]); - if ($row = $sth->fetch()) { - - $login = $row["login"]; - $access_level = $row["access_level"]; - $email = $row["email"]; - - $sel_disabled = ($id == $_SESSION["uid"] || $login == "admin") ? "disabled" : ""; - - print "<header>".__("User")."</header>"; - print "<section>"; - - if ($sel_disabled) { - print_hidden("login", "$login"); - } - - print "<fieldset>"; - print "<label>" . __("Login:") . "</label>"; - print "<input style='font-size : 16px' - dojoType='dijit.form.ValidationTextBox' required='1' - $sel_disabled name='login' value=\"$login\">"; - print "</fieldset>"; - - print "</section>"; - - print "<header>".__("Authentication")."</header>"; - print "<section>"; - - print "<fieldset>"; - - print "<label>" . __('Access level: ') . "</label> "; - - if (!$sel_disabled) { - print_select_hash("access_level", $access_level, $access_level_names, - "dojoType=\"fox.form.Select\" $sel_disabled"); - } else { - print_select_hash("", $access_level, $access_level_names, - "dojoType=\"fox.form.Select\" $sel_disabled"); - print_hidden("access_level", "$access_level"); - } - - print "</fieldset>"; - print "<fieldset>"; - - print "<label>" . __("New password:") . "</label> "; - print "<input dojoType='dijit.form.TextBox' type='password' size='20' placeholder='Change password' - name='password'>"; - - print "</fieldset>"; - - print "</section>"; - - print "<header>".__("Options")."</header>"; - print "<section>"; - - print "<fieldset>"; - print "<label>" . __("E-mail:") . "</label> "; - print "<input dojoType='dijit.form.TextBox' size='30' name='email' - value=\"$email\">"; - print "</fieldset>"; - - print "</section>"; - - print "</table>"; - + if ($row = $sth->fetch(PDO::FETCH_ASSOC)) { + print json_encode([ + "user" => $row, + "access_level_names" => $access_level_names + ]); + } else { + print json_encode(["error" => "USER_NOT_FOUND"]); } - - print '</div>'; #tab - print "<div href=\"backend.php?op=pref-users&method=userdetails&id=$id\" - dojoType=\"dijit.layout.ContentPane\" title=\"".__('User details')."\">"; - - print '</div>'; - print '</div>'; - - print "<footer> - <button dojoType='dijit.form.Button' class='alt-primary' type='submit' onclick='App.dialogOf(this).execute()'>". - __('Save')."</button> - <button dojoType='dijit.form.Button' onclick='App.dialogOf(this).hide()'>". - __('Cancel')."</button> - </footer>"; - - print "</form>"; - - return; } function userdetails() { @@ -186,6 +100,12 @@ class Pref_Users extends Handler_Administrative { $email = clean($_REQUEST["email"]); $password = clean($_REQUEST["password"]); + // no blank usernames + if (!$login) return; + + // forbid renaming admin + if ($uid == 1) $login = "admin"; + if ($password) { $salt = substr(bin2hex(get_random_bytes(125)), 0, 250); $pwd_hash = encrypt_password($password, $salt, true); @@ -20,6 +20,15 @@ const App = { FormFields: { hidden: function(name, value, id = "") { return `<input id="${id}" dojoType="dijit.form.TextBox" style="display : none" name="${name}" value="${App.escapeHtml(value)}"></input>` + }, + select_hash: function(name, value, values, attributes) { + return ` + <select name="${name}" dojoType="fox.form.Select" ${attributes}> + ${Object.keys(values).map((vk) => + `<option name="" ${vk == value ? 'selected="selected"' : ''} value="${App.escapeHtml(vk)}">${App.escapeHtml(values[vk])}</option>` + ).join("")} + </select> + ` } }, Scrollable: { diff --git a/js/PrefUsers.js b/js/PrefUsers.js index e5c281811..1fe4db150 100644 --- a/js/PrefUsers.js +++ b/js/PrefUsers.js @@ -1,7 +1,7 @@ 'use strict' /* global __ */ -/* global xhrPost, dojo, dijit, Notify, Tables, fox */ +/* global xhrPost, xhrJson, dojo, dijit, Notify, Tables, App, fox */ const Users = { reload: function(sort) { @@ -27,7 +27,10 @@ const Users = { } }, edit: function(id) { - xhrPost('backend.php', {op: 'pref-users', method: 'edit', id: id}, (transport) => { + xhrJson('backend.php', {op: 'pref-users', method: 'edit', id: id}, (reply) => { + const user = reply.user; + const is_disabled = (user.id == 1) ? "disabled='disabled'" : ''; + const dialog = new fox.SingleUseDialog({ id: "userEditDlg", title: __("User Editor"), @@ -35,13 +38,86 @@ const Users = { if (this.validate()) { Notify.progress("Saving data...", true); - xhrPost("backend.php", dojo.formToObject("user_edit_form"), (/* transport */) => { + xhrPost("backend.php", this.attr('value'), () => { dialog.hide(); Users.reload(); }); } }, - content: transport.responseText + content: ` + <form onsubmit='return false'> + + ${App.FormFields.hidden('id', user.id.toString())} + ${App.FormFields.hidden('op', 'pref-users')} + ${App.FormFields.hidden('method', 'editSave')} + + <div dojoType="dijit.layout.TabContainer" style="height : 400px"> + <div dojoType="dijit.layout.ContentPane" title="${__('Edit user')}"> + + <header>${__("User")}</header> + + <section> + <fieldset> + <label>${__("Login:")}</label> + <input style='font-size : 16px' + ${is_disabled} + dojoType='dijit.form.ValidationTextBox' required='1' + name='login' value="${App.escapeHtml(user.login)}"> + + ${is_disabled ? App.FormFields.hidden("login", user.login) : ''} + </fieldset> + </section> + + <header>${__("Authentication")}</header> + + <section> + <fieldset> + <label>${__('Access level: ')}</label> + ${App.FormFields.select_hash("access_level", + user.access_level, reply.access_level_names, is_disabled)} + + ${is_disabled ? App.FormFields.hidden("access_level", + user.access_level.toString()) : ''} + </fieldset> + <fieldset> + <label>${__("New password:")}</label> + <input dojoType='dijit.form.TextBox' type='password' size='20' + placeholder='${__("Change password")}' name='password'> + </fieldset> + </section> + + <header>${__("Options")}</header> + + <section> + <fieldset> + <label>${__("E-mail:")}</label> + <input dojoType='dijit.form.TextBox' size='30' name='email' + value="${App.escapeHtml(user.email)}"> + </fieldset> + </section> + </div> + <div dojoType="dijit.layout.ContentPane" title="${__('User details')}"> + <script type='dojo/method' event='onShow' args='evt'> + if (this.domNode.querySelector('.loading')) { + xhrPost("backend.php", {op: 'pref-users', method: 'userdetails', id: ${user.id}}, (transport) => { + this.attr('content', transport.responseText); + }); + } + </script> + <span class='loading'>${__("Loading, please wait...")}</span> + </div> + </div> + + <footer> + <button dojoType='dijit.form.Button' class='alt-primary' type='submit' onclick='App.dialogOf(this).execute()'> + ${__('Save')} + </button> + <button dojoType='dijit.form.Button' onclick='App.dialogOf(this).hide()'> + ${__('Cancel')} + </button> + </footer> + </form> + ` }); dialog.show(); |