From 0ebadb8939a7a84d8f31f8c75418d38de367e035 Mon Sep 17 00:00:00 2001 From: Bartek Fabiszewski Date: Thu, 6 Apr 2017 23:23:25 +0200 Subject: [PATCH] Add password change form --- changepass.php | 73 ++++++++++++++++++++++++++++++++++++++++++++++++ helpers/user.php | 13 +++++++++ index.php | 14 +++++++++- lang.php | 24 ++++++++++++++++ main.css | 21 +++++++++++++- main.js | 24 ++++++++++++++-- pass.js | 66 +++++++++++++++++++++++++++++++++++++++++++ 7 files changed, 231 insertions(+), 4 deletions(-) create mode 100644 changepass.php create mode 100644 pass.js diff --git a/changepass.php b/changepass.php new file mode 100644 index 0000000..f845952 --- /dev/null +++ b/changepass.php @@ -0,0 +1,73 @@ +openURI("php://output"); + $xml->startDocument("1.0"); + $xml->setIndent(true); + $xml->startElement('root'); + $xml->writeElement("error", (int) $isError); + if ($isError) { + $xml->writeElement("message", $errorMessage); + } + $xml->endElement(); + $xml->endDocument(); + $xml->flush(); + exit; + } + + $login = isset($_REQUEST['login']) ? trim($_REQUEST['login']) : NULL; + $oldpass = isset($_REQUEST['oldpass']) ? $_REQUEST['oldpass'] : NULL; + $hash = isset($_REQUEST['pass']) ? password_hash($_REQUEST['pass'], PASSWORD_DEFAULT) : NULL; + if (empty($hash)) { + exitWithError("Empty password"); + } + if ($user->isAdmin && !empty($login)) { + // different user, only admin + $passUser = new uUser($login); + if (!$passUser->valid) { + exitWithError("User unknown"); + } + } else { + // current user + $passUser = $user; + if (!$passUser->validPassword($oldpass)) { + exitWithError("Wrong old password"); + } + } + if ($passUser->setPass($hash) === false) { + exitWithError("Server error"); + } + + exitWithStatus(); + +?> \ No newline at end of file diff --git a/helpers/user.php b/helpers/user.php index 4fa51ae..edf660d 100644 --- a/helpers/user.php +++ b/helpers/user.php @@ -63,6 +63,19 @@ class uUser { return $userid; } + public function setPass($hash) { + $ret = false; + $sql = "UPDATE users SET password = ? WHERE login = ?"; + $stmt = self::$db->prepare($sql); + $stmt->bind_param('ss', $hash, $this->login); + $stmt->execute(); + if (!self::$db->error && !$stmt->errno) { + $ret = true; + } + $stmt->close(); + return $ret; + } + public function validPassword($password) { return password_verify($password, $this->hash); } diff --git a/index.php b/index.php index 3f9ada1..93c2b29 100755 --- a/index.php +++ b/index.php @@ -19,7 +19,16 @@ */ require_once ("auth.php"); if ($user->isValid) { - $userHeader = $user->login . ' (' . $lang_logout . ')'; + $itemPass = '' . $lang_changepass . ''; + $itemLogout = '' . $lang_logout . ''; + $userHeader = ' +
+ ' . $user->login . ' + +
'; } else { $userHeader = '' . $lang_login . ''; } @@ -153,6 +162,9 @@ print ' var lang_passwordrepeat = "' . $lang_passwordrepeat . '"; var lang_passwordenter = "' . $lang_passwordenter . '"; var lang_usernameenter = "' . $lang_usernameenter . '"; + var lang_oldpassword = "' . $lang_oldpassword . '"; + var lang_newpassword = "' . $lang_newpassword . '"; + var lang_newpasswordrepeat = "' . $lang_newpasswordrepeat . '"; var lang_cancel = "' . $lang_cancel . '"; var lang_submit = "' . $lang_submit . '"; var units = "' . $config::$units . '"; diff --git a/lang.php b/lang.php index 34a6cc8..bb3f31f 100755 --- a/lang.php +++ b/lang.php @@ -57,6 +57,10 @@ switch($config::$lang) { $lang_passwordrepeat = "Repeat password"; $lang_passwordenter = "Enter password"; $lang_usernameenter = "Enter username"; + $lang_oldpassword = "Old password"; + $lang_newpassword = "New password"; + $lang_newpasswordrepeat = "Repeat new password"; + $lang_changepass = "Change password"; $lang_adduser = "Add user"; $lang_userexists = "User exists"; $lang_cancel ="Cancel"; @@ -100,6 +104,10 @@ switch($config::$lang) { $lang_passwordrepeat = "Ripeti password"; $lang_passwordenter = "Immetti password"; $lang_usernameenter = "Immetti nome utente"; + $lang_oldpassword = "Old password"; // todo: translate + $lang_newpassword = "New password"; // todo: translate + $lang_newpasswordrepeat = "Repeat new password"; // todo: translate + $lang_changepass = "Change password"; // todo: translate $lang_adduser = "Aggiungi utente"; $lang_userexists = "L'utente esiste già"; $lang_cancel ="Annulla"; @@ -144,6 +152,10 @@ switch($config::$lang) { $lang_passwordrepeat = "Powtórz hasło"; $lang_passwordenter = "Podaj hasło"; $lang_usernameenter = "Podaj użytkownika"; + $lang_oldpassword = "Obecne hasło"; + $lang_newpassword = "Nowe hasło"; + $lang_newpasswordrepeat = "Powtórz nowe hasło"; + $lang_changepass = "Zmień hasło"; $lang_adduser = "Dodaj użytkownika"; $lang_userexists = "Użytkownik istnieje"; $lang_cancel ="Anuluj"; @@ -188,6 +200,10 @@ switch($config::$lang) { $lang_passwordrepeat = "Repeat password"; // todo: translate $lang_passwordenter = "Enter password"; // todo: translate $lang_usernameenter = "Enter username"; // todo: translate + $lang_oldpassword = "Old password"; // todo: translate + $lang_newpassword = "New password"; // todo: translate + $lang_newpasswordrepeat = "Repeat new password"; // todo: translate + $lang_changepass = "Change password"; // todo: translate $lang_adduser = "Add user"; // todo: translate $lang_userexists = "User exists"; // todo: translate $lang_cancel ="Cancel"; // todo: translate @@ -232,6 +248,10 @@ switch($config::$lang) { $lang_passwordrepeat = "Repeat password"; // todo: translate $lang_passwordenter = "Enter password"; // todo: translate $lang_usernameenter = "Enter username"; // todo: translate + $lang_oldpassword = "Old password"; // todo: translate + $lang_newpassword = "New password"; // todo: translate + $lang_newpasswordrepeat = "Repeat new password"; // todo: translate + $lang_changepass = "Change password"; // todo: translate $lang_adduser = "Add user"; // todo: translate $lang_userexists = "User exists"; // todo: translate $lang_cancel ="Cancel"; // todo: translate @@ -276,6 +296,10 @@ switch($config::$lang) { $lang_passwordrepeat = "Répetez le mot de passe"; $lang_passwordenter = "Entrez votre mot de passe"; $lang_usernameenter = "Entrez votre nom d'utilisateur"; + $lang_oldpassword = "Old password"; // todo: translate + $lang_newpassword = "New password"; // todo: translate + $lang_newpasswordrepeat = "Repeat new password"; // todo: translate + $lang_changepass = "Change password"; // todo: translate $lang_adduser = "Ajouter un utilisateur"; $lang_userexists = "Cet utilisateur existe déjà"; $lang_cancel ="Annuler"; diff --git a/main.css b/main.css index 358dcd9..6e9244f 100755 --- a/main.css +++ b/main.css @@ -242,4 +242,23 @@ select { -webkit-border-radius: 5px; } -button { cursor:pointer; } \ No newline at end of file +button { + cursor: pointer; +} + +.dropdown { + display: none; + position: absolute; + background-color: gray; + padding: 1em; + width: 130px; + border: 1px solid #888; +} + +.dropdown a { + display: block; + padding-bottom: .5em; + padding-top: .5em; +} + +.show { display: block; } \ No newline at end of file diff --git a/main.js b/main.js index bfcafa8..8b57a6e 100755 --- a/main.js +++ b/main.js @@ -405,8 +405,8 @@ function setUnits(unit) { } function showModal(contentHTML) { - var div = document.createElement("div"); - div.setAttribute("id", "modal"); + var div = document.createElement('div'); + div.setAttribute('id', 'modal'); div.innerHTML = ''; document.body.appendChild(div); var modalBody = document.getElementById('modal-body'); @@ -415,4 +415,24 @@ function showModal(contentHTML) { function removeModal() { document.body.removeChild(document.getElementById('modal')); +} + +function userMenu() { + var dropdown = document.getElementById('user_dropdown'); + if (dropdown.classList.contains('show')) { + dropdown.classList.remove('show'); + } else { + dropdown.classList.add('show'); + window.addEventListener('click', removeOnClick, true); + } +} + +function removeOnClick(event) { + var parent = event.target.parentElement; + var dropdown = document.getElementById('user_dropdown'); + dropdown.classList.remove('show'); + window.removeEventListener('click', removeOnClick, true); + if (!parent.classList.contains('dropdown')) { + event.stopPropagation(); + } } \ No newline at end of file diff --git a/pass.js b/pass.js new file mode 100644 index 0000000..f60b773 --- /dev/null +++ b/pass.js @@ -0,0 +1,66 @@ +/* μlogger + * + * Copyright(C) 2017 Bartek Fabiszewski (www.fabiszewski.net) + * + * This is free software; you can redistribute it and/or modify it under + * the terms of the GNU Library General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +function changePass() { + var form = '
'; + form += ''; + form += ''; + form += ''; + form += ''; + form += '
'; + showModal(form); +} + +function submitPass() { + var form = document.getElementById('passForm'); + var oldpass = form.elements['oldpass'].value; + var pass = form.elements['pass'].value; + var pass2 = form.elements['pass2'].value; + if (!oldpass || !pass || !pass2) { + alert("All fields are required"); + return; + } + if (pass != pass2) { + alert("Passwords don't match"); + return; + } + var xhr = getXHR(); + xhr.onreadystatechange = function() { + if (xhr.readyState==4 && xhr.status==200) { + var xml = xhr.responseXML; + var message = ""; + if (xml) { + var root = xml.getElementsByTagName('root'); + if (root.length && getNode(root[0], 'error') == 0) { + removeModal(); + alert("Password successfully changed"); + return; + } + errorMsg = getNode(root[0], 'message'); + if (errorMsg) { message = errorMsg; } + } + alert("Something went wrong\n" + message); + xhr = null; + } + } + xhr.open('POST', 'changepass.php', true); + xhr.setRequestHeader('Content-type', 'application/x-www-form-urlencoded'); + xhr.send('oldpass=' + oldpass + '&pass=' + pass); + return; +} \ No newline at end of file