diff --git a/css/main.css b/css/main.css index 72f6b76..fa22c4a 100755 --- a/css/main.css +++ b/css/main.css @@ -263,6 +263,16 @@ button { cursor: pointer; } +.red-button { + color: white; + float: right; + background-color: red; + padding: .1em .4em; + border-radius: 10px; + -moz-border-radius: 10px; + -webkit-border-radius: 10px; +} + .dropdown { display: none; position: absolute; diff --git a/helpers/position.php b/helpers/position.php index 20dd7bb..88b9f7f 100644 --- a/helpers/position.php +++ b/helpers/position.php @@ -101,6 +101,27 @@ return $positionId; } + /** + * Delete all user's positions + * + * @param string $userId User id + * @return bool True if success, false otherwise + */ + public function deleteAll($userId) { + $ret = false; + if (!empty($userId)) { + $query = "DELETE FROM positions WHERE user_id = ?"; + $stmt = self::$db->prepare($query); + $stmt->bind_param('i', $userId); + $stmt->execute(); + if (!self::$db->error && !$stmt->errno) { + $ret = true; + } + $stmt->close(); + } + return $ret; + } + /** * Fill class properties with last position data from database * (for given user if specified) diff --git a/helpers/track.php b/helpers/track.php index f299e05..39115e3 100644 --- a/helpers/track.php +++ b/helpers/track.php @@ -77,6 +77,27 @@ return $trackId; } + /** + * Delete all user's tracks + * + * @param string $userId User id + * @return bool True if success, false otherwise + */ + public function deleteAll($userId) { + $ret = false; + if (!empty($userId)) { + $query = "DELETE FROM tracks WHERE user_id = ?"; + $stmt = self::$db->prepare($query); + $stmt->bind_param('i', $userId); + $stmt->execute(); + if (!self::$db->error && !$stmt->errno) { + $ret = true; + } + $stmt->close(); + } + return $ret; + } + /** * Get all tracks * diff --git a/helpers/user.php b/helpers/user.php index 647ed5c..0fbbe0d 100644 --- a/helpers/user.php +++ b/helpers/user.php @@ -16,8 +16,10 @@ * You should have received a copy of the GNU General Public License * along with this program; if not, see . */ - require_once (ROOT_DIR . "/helpers/config.php"); - require_once (ROOT_DIR . "/helpers/db.php"); + require_once(ROOT_DIR . "/helpers/config.php"); + require_once(ROOT_DIR . "/helpers/db.php"); + require_once(ROOT_DIR . "/helpers/track.php"); + require_once(ROOT_DIR . "/helpers/position.php"); /** * User handling routines @@ -73,6 +75,38 @@ return $userid; } + /** + * Delete user + * This will also delete all user's positions and tracks + * + * @return bool True if success, false otherwise + */ + public function delete() { + $ret = false; + if ($this->isValid) { + // remove positions + $position = new uPosition(); + if ($position->deleteAll($this->id) === false) { + return false; + } + // remove tracks + $track = new uTrack(); + if ($track->deleteAll($this->id) === false) { + return false; + } + // remove user + $sql = "DELETE FROM users WHERE id = ?"; + $stmt = self::$db->prepare($sql); + $stmt->bind_param('i', $this->id); + $stmt->execute(); + if (!self::$db->error && !$stmt->errno) { + $ret = true; + } + $stmt->close(); + } + return $ret; + } + /** * Set user password * diff --git a/index.php b/index.php index 23eb4ec..5d76335 100755 --- a/index.php +++ b/index.php @@ -72,6 +72,7 @@ var init_latitude = ''; var init_longitude = ''; var lang = ; + var auth = 'isValid) ? $user->login : "null" ?>'; @@ -133,7 +134,7 @@
( s)
-
+
@@ -184,6 +185,7 @@


+
diff --git a/js/admin.js b/js/admin.js index 39bd593..faaec1d 100644 --- a/js/admin.js +++ b/js/admin.js @@ -17,7 +17,7 @@ */ function addUser() { - var form = '
'; + var form = ''; form += ''; form += ''; form += ''; @@ -26,21 +26,57 @@ function addUser() { showModal(form); } -function submitUser() { +function editUser() { + var userForm = document.getElementsByName('user')[0]; + var userLogin = userForm.options[userForm.selectedIndex].text; + if (userLogin == auth) { + alert('Your can\'t edit your own user with this tool'); + return; + } + var message = '
You are editing user ' + userLogin + '
'; + message += ''; + message += '
'; + + var form = ''; + form += ''; + form += ''; + form += ''; + form += '
'; + form += '
'; + showModal(message + form); +} + +function confirmedDelete(login) { + return confirm('Warning!\n\nYou are going to permanently delete user "' + login + '", together with all their routes and positions.\n\nAre you sure?'); +} + +function submitUser(action) { var form = document.getElementById('userForm'); var login = form.elements['login'].value; - var pass = form.elements['pass'].value; - var pass2 = form.elements['pass2'].value; - if (!login || !pass || !pass2) { - alert("All fields are required"); - return; + if (!login) { + alert("All fields are required"); + return; } - if (pass != pass2) { - alert("Passwords don't match"); - return; + var pass = null; + var pass2 = null; + if (action != 'delete') { + pass = form.elements['pass'].value; + pass2 = form.elements['pass2'].value; + if (!pass || !pass2) { + alert("All fields are required"); + return; + } + if (pass != pass2) { + alert("Passwords don't match"); + return; + } + } else { + if (!confirmedDelete(login)) { + return; + } } var xhr = getXHR(); - xhr.onreadystatechange = function () { + xhr.onreadystatechange = function() { if (xhr.readyState == 4 && xhr.status == 200) { var xml = xhr.responseXML; var message = ""; @@ -48,7 +84,13 @@ function submitUser() { var root = xml.getElementsByTagName('root'); if (root.length && getNode(root[0], 'error') == 0) { removeModal(); - alert("User successfully added"); + alert("Action completed successfully"); + if (action == 'delete') { + // select current user in users form + var f = document.getElementsByName('user')[0]; + f.remove(f.selectedIndex); + selectUser(f); + } return; } errorMsg = getNode(root[0], 'message'); @@ -58,8 +100,10 @@ function submitUser() { xhr = null; } } - xhr.open('POST', 'utils/adduser.php', true); + xhr.open('POST', 'utils/handleuser.php', true); xhr.setRequestHeader('Content-type', 'application/x-www-form-urlencoded'); - xhr.send('login=' + login + '&pass=' + pass); + var params = 'action=' + action + '&login=' + encodeURIComponent(login) + '&pass=' + encodeURIComponent(pass); + params = params.replace(/%20/g, '+'); + xhr.send(params); return; } \ No newline at end of file diff --git a/js/main.js b/js/main.js index c16a700..de4e18a 100755 --- a/js/main.js +++ b/js/main.js @@ -236,7 +236,7 @@ function getNode(p, name) { } // seconds to (d) H:M:S -Number.prototype.toHMS = function () { +Number.prototype.toHMS = function() { var s = this; var d = Math.floor(s / 86400); var h = Math.floor((s % 86400) / 3600); @@ -244,17 +244,17 @@ Number.prototype.toHMS = function () { s = ((s % 86400) % 3600) % 60; return ((d > 0) ? (d + ' d ') : '') + (('00' + h).slice(-2)) + ':' + (('00' + m).slice(-2)) + ':' + (('00' + s).slice(-2)) + ''; -} +}; // meters to km -Number.prototype.toKm = function () { +Number.prototype.toKm = function() { return Math.round(this / 10) / 100; -} +}; // m/s to km/h -Number.prototype.toKmH = function () { +Number.prototype.toKmH = function() { return Math.round(this * 3600 / 10) / 100; -} +}; // negate value function toggleLatest() { diff --git a/js/pass.js b/js/pass.js index caad414..0f92819 100644 --- a/js/pass.js +++ b/js/pass.js @@ -60,6 +60,8 @@ function submitPass() { } xhr.open('POST', 'utils/changepass.php', true); xhr.setRequestHeader('Content-type', 'application/x-www-form-urlencoded'); - xhr.send('oldpass=' + oldpass + '&pass=' + pass); + var params = 'oldpass=' + encodeURIComponent(oldpass) + '&pass=' + encodeURIComponent(pass); + params = params.replace(/%20/g, '+'); + xhr.send(params); return; } \ No newline at end of file diff --git a/lang/en.php b/lang/en.php index 43ac42c..5283df5 100644 --- a/lang/en.php +++ b/lang/en.php @@ -66,5 +66,7 @@ $lang["newpasswordrepeat"] = "Repeat new password"; $lang["changepass"] = "Change password"; $lang["gps"] = "GPS"; $lang["network"] = "Network"; +$lang["deluser"] = "Remove user"; +$lang["edituser"] = "Edit user"; ?> diff --git a/lang/pl.php b/lang/pl.php index 5e3e49d..de0dc80 100644 --- a/lang/pl.php +++ b/lang/pl.php @@ -64,5 +64,7 @@ $lang["newpasswordrepeat"] = "Powtórz nowe hasło"; $lang["changepass"] = "Zmień hasło"; $lang["gps"] = "GPS"; $lang["network"] = "Sieć"; +$lang["deluser"] = "Usuń użytkownika"; +$lang["edituser"] = "Edytuj użytkownika"; ?> diff --git a/utils/adduser.php b/utils/handleuser.php similarity index 61% rename from utils/adduser.php rename to utils/handleuser.php index fac632e..2193a10 100644 --- a/utils/adduser.php +++ b/utils/handleuser.php @@ -41,17 +41,49 @@ exit; } + $action = isset($_REQUEST['action']) ? $_REQUEST['action'] : NULL; $login = isset($_REQUEST['login']) ? trim($_REQUEST['login']) : NULL; $hash = isset($_REQUEST['pass']) ? password_hash($_REQUEST['pass'], PASSWORD_DEFAULT) : NULL; - if ($user->isAdmin && !empty($login) && !empty($hash)) { - $newUser = new uUser($login); - if ($newUser->isValid) { - exitWithStatus(true, $lang["userexists"]); - } - if ($newUser->add($login, $hash) === false) { - exitWithStatus(true, $mysqli->error); - } + if (!$user->isAdmin || empty($action) || empty($login) || $user->login == $login) { + exitWithStatus(true, "Server error"); } + + $aUser = new uUser($login); + + switch ($action) { + case 'add': + if (empty($hash)) { + exitWithStatus(true, "Server error"); + } + if ($aUser->isValid) { + exitWithStatus(true, $lang["userexists"]); + } + if ($aUser->add($login, $hash) === false) { + exitWithStatus(true, $mysqli->error); + } + break; + + case 'update': + // update password + if (empty($hash)) { + exitWithStatus(true, "Server error"); + } + if ($aUser->setPass($hash) === false) { + exitWithStatus(true, $mysqli->error); + } + break; + + case 'delete': + if ($aUser->delete() === false) { + exitWithStatus(true, $mysqli->error); + } + break; + + default: + exitWithStatus(true, "Server error"); + break; + } + exitWithStatus(false); ?> \ No newline at end of file