Skip to content

Commit

Permalink
Add password change form
Browse files Browse the repository at this point in the history
  • Loading branch information
bfabiszewski committed Apr 6, 2017
1 parent 79a31aa commit 0ebadb8
Show file tree
Hide file tree
Showing 7 changed files with 231 additions and 4 deletions.
73 changes: 73 additions & 0 deletions changepass.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
<?php
/* μ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.
*/

require_once("auth.php"); // sets $mysqli, $user

function exitWithError($errorMessage) {
return exitWithStatus(true, $errorMessage);
}
/**
* Exit with xml response
* @param boolean $isError Error if true
* @param string $errorMessage Optional error message
*/
function exitWithStatus($isError = false, $errorMessage = NULL) {
header("Content-type: text/xml");
$xml = new XMLWriter();
$xml->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();

?>
13 changes: 13 additions & 0 deletions helpers/user.php
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,19 @@ public function add($login, $hash) {
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);
}
Expand Down
14 changes: 13 additions & 1 deletion index.php
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,16 @@
*/
require_once ("auth.php");
if ($user->isValid) {
$userHeader = $user->login . ' (<a href="logout.php">' . $lang_logout . '</a>)';
$itemPass = '<a href="javascript:void(0)" onclick="changePass()">' . $lang_changepass . '</a>';
$itemLogout = '<a href="logout.php">' . $lang_logout . '</a>';
$userHeader = '
<div id="user_menu">
<a href="javascript:void(0);" onclick="userMenu()">' . $user->login . '</a>
<div id="user_dropdown" class="dropdown">
' . $itemPass . '
' . $itemLogout . '
</div>
</div>';
} else {
$userHeader = '<a href="index.php?force_login=1">' . $lang_login . '</a>';
}
Expand Down Expand Up @@ -153,6 +162,9 @@
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 . '";
Expand Down
24 changes: 24 additions & 0 deletions lang.php
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,10 @@
$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";
Expand Down Expand Up @@ -100,6 +104,10 @@
$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";
Expand Down Expand Up @@ -144,6 +152,10 @@
$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";
Expand Down Expand Up @@ -188,6 +200,10 @@
$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
Expand Down Expand Up @@ -232,6 +248,10 @@
$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
Expand Down Expand Up @@ -276,6 +296,10 @@
$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";
Expand Down
21 changes: 20 additions & 1 deletion main.css
Original file line number Diff line number Diff line change
Expand Up @@ -242,4 +242,23 @@ select {
-webkit-border-radius: 5px;
}

button { cursor:pointer; }
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; }
24 changes: 22 additions & 2 deletions main.js
Original file line number Diff line number Diff line change
Expand Up @@ -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 = '<div id="modal-header"><button type="button" onclick="removeModal()">&times;</button></div><div id="modal-body"></div>';
document.body.appendChild(div);
var modalBody = document.getElementById('modal-body');
Expand All @@ -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();
}
}
66 changes: 66 additions & 0 deletions pass.js
Original file line number Diff line number Diff line change
@@ -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 id="passForm" method="post" onsubmit="submitPass(); return false">';
form += '<label><b>' + lang_oldpassword + '</b></label><input type="password" placeholder="' + lang_passwordenter + '" name="oldpass" required>';
form += '<label><b>' + lang_newpassword + '</b></label><input type="password" placeholder="' + lang_passwordenter + '" name="pass" required>';
form += '<label><b>' + lang_newpasswordrepeat + '</b></label><input type="password" placeholder="' + lang_passwordenter + '" name="pass2" required>';
form += '<button type="button" onclick="removeModal()">' + lang_cancel + '</button><button type="submit">' + lang_submit + '</button>';
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;
}

0 comments on commit 0ebadb8

Please sign in to comment.