From d9ca8fcb1ab82d73d00d86c15dbcd63670a690fa Mon Sep 17 00:00:00 2001 From: JonatanRek Date: Sun, 13 Oct 2019 12:29:07 +0200 Subject: [PATCH 01/15] Better Login --- app/class/UserManager.php | 21 ++++++++++++++++++++- app/controls/setting.php | 10 ++++++++++ app/templates/setting.phtml | 22 +++++++++++++++++++++- 3 files changed, 51 insertions(+), 2 deletions(-) create mode 100644 app/controls/setting.php diff --git a/app/class/UserManager.php b/app/class/UserManager.php index cc9e54a..7ba528d 100644 --- a/app/class/UserManager.php +++ b/app/class/UserManager.php @@ -62,9 +62,14 @@ class UserManager } public function logout () { - setcookie ("rememberMe","", time() - (30 * 24 * 60 * 60 * 1000), str_replace("login", "", str_replace('https://' . $_SERVER['HTTP_HOST'], "", $_SERVER['REQUEST_URI'])), $_SERVER['HTTP_HOST'], 1); unset($_SESSION['user']); session_destroy(); + if (isset($_COOKIE['rememberMe'])){ + //unset($_COOKIE['rememberMe']); + setcookie ("rememberMe2", $this->setEncryptedCookie($user['username']), time () + (30 * 24 * 60 * 60 * 1000), '/vasek/home/', $_SERVER['HTTP_HOST'], 1); + setcookie("token", "restt", time() - 36000, "/"); + die(); + } } public function setEncryptedCookie($value){ @@ -176,5 +181,19 @@ class UserManager die(); } } + + public function changePassword($oldPassword, $newPassword, $newPassword2){ + if ($newPassword == $newPassword2) { + //Password Criteria + $oldPasswordSaved = self::getUserData('password'); + if (self::getHashPassword($oldPassword) == $oldPasswordSaved) { + self::setUserData('password', self::getHashPassword($newPassword)); + } else { + throw new ChybaUzivatele ("old password did not match"); + } + } else { + throw new ChybaUzivatele ("new password arent same"); + } + } } ?> diff --git a/app/controls/setting.php b/app/controls/setting.php new file mode 100644 index 0000000..63c5e55 --- /dev/null +++ b/app/controls/setting.php @@ -0,0 +1,10 @@ +echo('b_rooms') ?> +
+

echo('t_changePassword') ?>

+
+
+
echo('l_oldPassword') ?>:
+ +
+
+
echo('l_newPassword') ?>:
+ +
+
+
echo('l_newPassword') ?>:
+ +
+
+ +
+
+
@@ -65,6 +85,6 @@ $partial = new Partial('footer'); $partial->render(); ?> - + From 0ff234d61d2b53c04c0d782ca99f8902c72736c1 Mon Sep 17 00:00:00 2001 From: JonatanRek Date: Sun, 13 Oct 2019 12:55:22 +0200 Subject: [PATCH 02/15] Better Loggin #2 --- app/class/UserManager.php | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/app/class/UserManager.php b/app/class/UserManager.php index 7ba528d..93687c5 100644 --- a/app/class/UserManager.php +++ b/app/class/UserManager.php @@ -26,7 +26,7 @@ class UserManager if ($user = Db::loadOne ('SELECT * FROM users WHERE LOWER(username)=LOWER(?)', array ($username))) { if ($user['password'] == UserManager::getHashPassword($password)) { if (isset($rememberMe) && $rememberMe == 'true') { - setcookie ("rememberMe", $this->setEncryptedCookie($user['username']), time () + (30 * 24 * 60 * 60 * 1000), str_replace("login", "", str_replace('https://' . $_SERVER['HTTP_HOST'], "", $_SERVER['REQUEST_URI'])), $_SERVER['HTTP_HOST'], 1); + setcookie ("rememberMe", $this->setEncryptedCookie($user['username']), time () + (30 * 24 * 60 * 60 * 1000), BASEDIR, $_SERVER['HTTP_HOST'], 1); } $_SESSION['user']['id'] = $user['user_id']; $page = "./index.php"; @@ -64,11 +64,12 @@ class UserManager public function logout () { unset($_SESSION['user']); session_destroy(); + + + if (isset($_COOKIE['rememberMe'])){ - //unset($_COOKIE['rememberMe']); - setcookie ("rememberMe2", $this->setEncryptedCookie($user['username']), time () + (30 * 24 * 60 * 60 * 1000), '/vasek/home/', $_SERVER['HTTP_HOST'], 1); - setcookie("token", "restt", time() - 36000, "/"); - die(); + unset($_COOKIE['rememberMe']); + setcookie("rememberMe", 'false', time(), BASEDIR, $_SERVER['HTTP_HOST']); } } From 0830637271401bdafe4a342c92cf07f83eb174ac Mon Sep 17 00:00:00 2001 From: JonatanRek Date: Sun, 13 Oct 2019 14:00:24 +0200 Subject: [PATCH 03/15] User Creation --- app/class/UserManager.php | 28 +++++++++++++++++++++------- 1 file changed, 21 insertions(+), 7 deletions(-) diff --git a/app/class/UserManager.php b/app/class/UserManager.php index 93687c5..1d19cfd 100644 --- a/app/class/UserManager.php +++ b/app/class/UserManager.php @@ -3,8 +3,8 @@ class UserManager { public function getUsers () { try { - $allRoom = Db::loadAll ("SELECT * FROM users"); - return $allRoom; + $allUsers = Db::loadAll ("SELECT user_id, username FROM users"); + return $allUsers; } catch(PDOException $error) { echo $error->getMessage(); die(); @@ -64,9 +64,6 @@ class UserManager public function logout () { unset($_SESSION['user']); session_destroy(); - - - if (isset($_COOKIE['rememberMe'])){ unset($_COOKIE['rememberMe']); setcookie("rememberMe", 'false', time(), BASEDIR, $_SERVER['HTTP_HOST']); @@ -190,10 +187,27 @@ class UserManager if (self::getHashPassword($oldPassword) == $oldPasswordSaved) { self::setUserData('password', self::getHashPassword($newPassword)); } else { - throw new ChybaUzivatele ("old password did not match"); + throw new Exception ("old password did not match"); } } else { - throw new ChybaUzivatele ("new password arent same"); + throw new Exception ("new password arent same"); + } + } + + public function createUser($userName, $password){ + $userId = Db::loadOne('SELECT * FROM users WHERE username = ?;', array($userName))['user_id']; + if ($userId != null) { + return false; + }; + try { + $user = [ + 'username' => $userName, + 'password' => self::getHashPassword($password), + ]; + return Db::add ('users', $user); + } catch(PDOException $error) { + echo $error->getMessage(); + die(); } } } From 7998c9eedc77d7c31c4919b2448d8408173d03db Mon Sep 17 00:00:00 2001 From: JonatanRek Date: Sun, 13 Oct 2019 14:00:41 +0200 Subject: [PATCH 04/15] User Creation #2 --- app/controls/setting.php | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/app/controls/setting.php b/app/controls/setting.php index 63c5e55..dcda809 100644 --- a/app/controls/setting.php +++ b/app/controls/setting.php @@ -5,6 +5,13 @@ if (isset($_POST) && !empty($_POST)){ $newPassword = $_POST['newPassword1']; $newPassword2 = $_POST['newPassword2']; UserManager::changePassword($oldPassword, $newPassword, $newPassword2); - //TODO: pridat odhlášení + header('Location: ' . BASEDIR . 'logout'); + die(); + } else if (isset($_POST['submitCreateUser']) && $_POST['submitCreateUser'] != "") { + $userName = $_POST['userName']; + $password = $_POST['userPassword']; + UserManager::createUser($userName, $password); + header('Location: ' . BASEDIR . 'setting'); + die(); } } From 515628c9f08c76bb154249493e8a1286aeab7674 Mon Sep 17 00:00:00 2001 From: JonatanRek Date: Sun, 13 Oct 2019 14:01:02 +0200 Subject: [PATCH 05/15] Some New Strings --- app/lang/cs.php | 37 ++++++++++++++++++++++++++++++++++--- app/lang/en.php | 9 ++++++++- app/lang/pl.php | 10 +++++++++- 3 files changed, 51 insertions(+), 5 deletions(-) diff --git a/app/lang/cs.php b/app/lang/cs.php index ae31830..4b1c20b 100644 --- a/app/lang/cs.php +++ b/app/lang/cs.php @@ -18,10 +18,16 @@ return $lang = [ 'b_create' => 'Vytvořit', 'b_edit' => 'Upravit', 'b_remove' => 'Smazat', + 'b_finish' => 'Dokončit', 'b_approve' => 'Povolit', 'b_disable' => 'Zakázat', 'b_save' => 'Uložit', - + 'b_logOut' => 'Odhlásit', + 'b_sendTestNotification' => 'Odeslat testovací notifikaci', + 'b_rooms' => 'Místnosti', + 'b_restart' => 'Restart', + 'b_disable' => 'Deaktivovat', + 'b_select' => 'Zvolit', //labels 'l_choseDevice' => 'Zvolte zařízení:', @@ -46,14 +52,24 @@ return $lang = [ 'l_atHome' => 'Doma Jsou', 'l_nameAt' => 'Název', 'l_lastSeen' => 'Naposledy připojeno', + 'l_notificationStatus' => 'Notification status', + 'l_userName' => 'Username', + 'l_password' => 'Password', + 'l_oldPassword' => 'Old Password', + 'l_newPassword' => 'New Password', //Title 't_createScene' => 'Vytvořit scénu', 't_editScene' => 'Upravit scénu', - 't_createAutomation' => 'Vytvořit Automatizaci', - + 't_addDevice' => 'Přidat Zařízení', 't_editDevice' => 'Upravit Zařízení', + 't_pageAfterLogIn' => 'stránka po přihlášení', + 't_profile' => 'Profil', + 't_notification' => 'Notificatifikace', + 't_experimental' => 'Experimental', + 't_createuser' => 'Vytvořit Uživatele', + 't_changePassword' => 'Změnit Heslo', //constants 'temp' => 'Teplota', @@ -74,6 +90,21 @@ return $lang = [ 'w_neni' => 'Není', 'w_is' => 'je', + //tables + 't_time' => 'Čas', + 't_state' => 'Stav', + 't_userName' => 'Uživatelské Jméno', + 't_action' => 'Akce', + + //Days Long + 'd_monday' => 'Pondělí', + 'd_tuesday' => 'Ůterí', + 'd_wednesday' => 'Středa', + 'd_thursday' => 'Čtvrtek', + 'd_friday' => 'Pátek', + 'd_saturday' => 'Sobota', + 'd_sunday' => 'Neděle', + //example '' => '', ]; diff --git a/app/lang/en.php b/app/lang/en.php index 762d19f..4cded3a 100644 --- a/app/lang/en.php +++ b/app/lang/en.php @@ -29,7 +29,6 @@ return $lang = [ 'b_disable' => 'disabele', 'b_select' => 'Select', - //labels 'l_choseDevice' => 'Chose device:', 'l_inHome' => 'When entering', @@ -54,6 +53,10 @@ return $lang = [ 'l_nameAt' => 'Name', 'l_lastSeen' => 'Last Seen', 'l_notificationStatus' => 'Notification status', + 'l_userName' => 'Username', + 'l_password' => 'Password', + 'l_oldPassword' => 'Old Password', + 'l_newPassword' => 'New Password', //Title 't_createScene' => 'Create Scene', @@ -65,6 +68,8 @@ return $lang = [ 't_profile' => 'Profile', 't_notification' => 'Notification', 't_experimental' => 'Experimental', + 't_createuser' => 'Create User', + 't_changePassword' => 'Change Password', //constants 'humi' => 'Humidity', @@ -88,6 +93,8 @@ return $lang = [ //tables 't_time' => 'Time', 't_state' => 'State', + 't_userName' => 'State', + 't_action' => 'Action', //Days Long 'd_monday' => 'Monday', diff --git a/app/lang/pl.php b/app/lang/pl.php index ff9a762..087fb7e 100644 --- a/app/lang/pl.php +++ b/app/lang/pl.php @@ -18,6 +18,7 @@ return $lang = [ 'b_create' => 'Utwórz', 'b_edit' => 'Edytuj', 'b_remove' => 'Usuń', + 'b_finish' => 'Dokončit', //newOne 'b_approve' => 'Zaakceptuj', 'b_disable' => 'Wyłącz', 'b_save' => 'Zapisz', @@ -50,9 +51,12 @@ return $lang = [ 'l_sleepTime' => 'Czas snu urządzenia', 'l_atHome' => 'W domu', 'l_nameAt' => 'Nazwa', - 'l_nameAt' => 'Nazwa', 'l_lastSeen' => 'Ostatnio zaktualizowany', 'l_notificationStatus' => 'Stan powiadomienia', + 'l_userName' => 'Username', //newOne + 'l_password' => 'Password', //newOne + 'l_oldPassword' => 'Old Password', //newOne + 'l_newPassword' => 'New Password', //newOne //Title 't_createScene' => 'Utwórz scenariusz', @@ -64,6 +68,8 @@ return $lang = [ 't_profile' => 'Profil', 't_notification' => 'Powiadomienie', 't_experimental' => 'Eksperymentalne', + 't_createuser' => 'Vytvořit Uživatele', //newOne + 't_changePassword' => 'Změnit Heslo', //newOne //constants 'humi' => 'Wilgotność', @@ -87,6 +93,8 @@ return $lang = [ //tables 't_time' => 'Czas', 't_state' => 'Stan', + 't_userName' => 'State', //newOne + 't_action' => 'Action', //newOne //Days Long 'd_monday' => 'Poniedziałek', From c8ae3cede378d03753b4fb64c42b17632b994820 Mon Sep 17 00:00:00 2001 From: JonatanRek Date: Sun, 13 Oct 2019 14:01:33 +0200 Subject: [PATCH 06/15] User Creation #3 & Password Restart --- app/templates/setting.phtml | 32 ++++++++++++++++++++++++++++++++ app/views/Setting.php | 4 ++++ 2 files changed, 36 insertions(+) diff --git a/app/templates/setting.phtml b/app/templates/setting.phtml index 519171e..0940c5c 100644 --- a/app/templates/setting.phtml +++ b/app/templates/setting.phtml @@ -76,6 +76,38 @@ +
+

echo('t_createuser') ?>

+ + + + + + + + + $user) { ?> + + + + + + +
echo('t_userName');?>echo('t_action');?>
+
+
+
echo('l_userName') ?>:
+ +
+
+
echo('l_password') ?>:
+ +
+
+ +
+
+
diff --git a/app/views/Setting.php b/app/views/Setting.php index 79618d9..f1de7bb 100644 --- a/app/views/Setting.php +++ b/app/views/Setting.php @@ -27,6 +27,10 @@ class Setting extends Template $template->prepare('langMng', $langMng); $template->prepare('automations', $automations); + $users = $userManager->getUsers(); + $template->prepare('users', $users); + + $template->render(); } } From daa07595442ad19931e4af83aea289a58a5037b7 Mon Sep 17 00:00:00 2001 From: JonatanRek Date: Sun, 13 Oct 2019 14:10:33 +0200 Subject: [PATCH 07/15] Instalation user table fix --- _INSTALATION/_SQL_TABLES.sql | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/_INSTALATION/_SQL_TABLES.sql b/_INSTALATION/_SQL_TABLES.sql index 9223dd5..a7bc3a2 100644 --- a/_INSTALATION/_SQL_TABLES.sql +++ b/_INSTALATION/_SQL_TABLES.sql @@ -141,7 +141,7 @@ CREATE TABLE `users` ( `username` varchar(255) NOT NULL, `password` varchar(255) NOT NULL, `startPage` int(11) NOT NULL, - `at_home` varchar(255) NOT NULL + `at_home` varchar(255) NOT NULL DEFAULT 'false' ) ENGINE=InnoDB DEFAULT CHARSET=utf8; From ec4b808d33e0af71f2e2a4189a5bfee5d63b2c29 Mon Sep 17 00:00:00 2001 From: JonatanRek Date: Sun, 13 Oct 2019 14:17:18 +0200 Subject: [PATCH 08/15] At home users Fix --- app/class/UserManager.php | 2 +- app/views/Home.php | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/app/class/UserManager.php b/app/class/UserManager.php index 1d19cfd..c3b7864 100644 --- a/app/class/UserManager.php +++ b/app/class/UserManager.php @@ -3,7 +3,7 @@ class UserManager { public function getUsers () { try { - $allUsers = Db::loadAll ("SELECT user_id, username FROM users"); + $allUsers = Db::loadAll ("SELECT user_id, username, at_home FROM users"); return $allUsers; } catch(PDOException $error) { echo $error->getMessage(); diff --git a/app/views/Home.php b/app/views/Home.php index 0f2cb2a..e3f068a 100644 --- a/app/views/Home.php +++ b/app/views/Home.php @@ -22,10 +22,10 @@ class Home extends Template $usersAtHome = ''; $i = 0; foreach ($users as $user) { - $i++; if ($user['at_home'] == 'true') { + $i++; $usersAtHome .= $user['username']; - if ($usersAtHome != "" && isset($users[$i + 1])){ + if ($usersAtHome != "" && isset($users[$i + 1]) && $users[$i + 1]['at_home'] == 'true'){ $usersAtHome .= ', '; } } From c0759ff3a1d5813bca4db1c99948128885ead4f0 Mon Sep 17 00:00:00 2001 From: JonatanRek Date: Sun, 13 Oct 2019 14:17:30 +0200 Subject: [PATCH 09/15] Overide CSS + Table --- app/templates/css/override.css | 16 ++++++++++++++++ app/templates/part/head.phtml | 1 + 2 files changed, 17 insertions(+) create mode 100644 app/templates/css/override.css diff --git a/app/templates/css/override.css b/app/templates/css/override.css new file mode 100644 index 0000000..5fc5698 --- /dev/null +++ b/app/templates/css/override.css @@ -0,0 +1,16 @@ +table.table td, table.table th { + border: 2px solid #121a2b; + padding: 8px; +} + +/*tr:nth-child(even){background-color: #f2f2f2;}*/ + +table.table tr:hover {background-color: #121a2b;} + +table.table th { + padding-top: 12px; + padding-bottom: 12px; + text-align: left; + background-color: #121a2b; + color: white; +} \ No newline at end of file diff --git a/app/templates/part/head.phtml b/app/templates/part/head.phtml index 3ce6abe..445fcae 100644 --- a/app/templates/part/head.phtml +++ b/app/templates/part/head.phtml @@ -23,3 +23,4 @@ + From 55fa87cbce9bf5cb0b8d8a738c7a93c435a6aa65 Mon Sep 17 00:00:00 2001 From: JonatanRek Date: Sun, 13 Oct 2019 14:18:41 +0200 Subject: [PATCH 10/15] Delete user Button + Som Czech Translation --- app/lang/cs.php | 8 ++++---- app/templates/setting.phtml | 4 ++-- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/app/lang/cs.php b/app/lang/cs.php index 4b1c20b..e3f84e9 100644 --- a/app/lang/cs.php +++ b/app/lang/cs.php @@ -53,10 +53,10 @@ return $lang = [ 'l_nameAt' => 'Název', 'l_lastSeen' => 'Naposledy připojeno', 'l_notificationStatus' => 'Notification status', - 'l_userName' => 'Username', - 'l_password' => 'Password', - 'l_oldPassword' => 'Old Password', - 'l_newPassword' => 'New Password', + 'l_userName' => 'Uživatelské jméno', + 'l_password' => 'Heslo', + 'l_oldPassword' => 'Staré Heslo', + 'l_newPassword' => 'Nové Heslo', //Title 't_createScene' => 'Vytvořit scénu', diff --git a/app/templates/setting.phtml b/app/templates/setting.phtml index 0940c5c..1f7c808 100644 --- a/app/templates/setting.phtml +++ b/app/templates/setting.phtml @@ -88,8 +88,8 @@ $user) { ?> - - + + From 8ab1a6b69f91a68c628b817120102c3c680ce96d Mon Sep 17 00:00:00 2001 From: JonatanRek Date: Tue, 22 Oct 2019 16:52:45 +0200 Subject: [PATCH 11/15] OTA PART 1 --- app/class/UserManager.php | 152 +++++++---------- app/controls/login.php | 43 +++++ app/templates/login.phtml | 30 ++-- app/templates/part/loginForm.phtml | 20 +++ app/templates/part/loginOta.phtml | 13 ++ app/templates/setting.phtml | 7 + app/vendor/GoogleAuthenticator.php | 252 +++++++++++++++++++++++++++++ index.php | 9 +- 8 files changed, 407 insertions(+), 119 deletions(-) create mode 100644 app/controls/login.php create mode 100644 app/templates/part/loginForm.phtml create mode 100644 app/templates/part/loginOta.phtml create mode 100644 app/vendor/GoogleAuthenticator.php diff --git a/app/class/UserManager.php b/app/class/UserManager.php index c3b7864..3ea2ff8 100644 --- a/app/class/UserManager.php +++ b/app/class/UserManager.php @@ -29,9 +29,9 @@ class UserManager setcookie ("rememberMe", $this->setEncryptedCookie($user['username']), time () + (30 * 24 * 60 * 60 * 1000), BASEDIR, $_SERVER['HTTP_HOST'], 1); } $_SESSION['user']['id'] = $user['user_id']; - $page = "./index.php"; + $page = "home"; if ($user["startPage"] == 1) { - $page = "./dashboard.php"; + $page = "dashboard"; } unset($_POST['login']); return $page; @@ -101,12 +101,14 @@ class UserManager return false; } - public static function getUserData ($type) { + public static function getUserData ($type, $userId = '') { if (isset($_SESSION['user']['id'])) { - $user = Db::loadOne ('SELECT ' . $type . ' FROM users WHERE user_id=?', array ($_SESSION['user']['id'])); - return $user[$type]; + $userId = $_SESSION['user']['id']; + } else { + return ""; } - return ""; + $user = Db::loadOne ('SELECT ' . $type . ' FROM users WHERE user_id=?', array ($userId)); + return $user[$type]; } public function setUserData ($type, $value) { @@ -121,94 +123,54 @@ class UserManager return $hashPassword; } - public function ulozitObrazek ($file, $path = "", $name = "") { - if (!@is_array (getimagesize($file['tmp_name']))) { - throw new ChybaUzivatele("Formát obrázku ". $file['name'] ." není podporován!"); - } else { - $extension = strtolower(strrchr($file['name'], '.')); - switch ($extension) { - case '.jpg': - case '.jpeg': - $img = @imagecreatefromjpeg($file['tmp_name']); - break; - case '.gif': - $img = @imagecreatefromgif($file['tmp_name']); - break; - case '.png': - $img2 = @imagecreatefrompng($file['tmp_name']); - break; - case '.ico': - $img3 = @$file['tmp_name']; - break; - default: - $img = false; - break; - } - if($name == ""){ - $nazev = substr($file['name'], 0, strpos($file['name'], ".")) ."_". round(microtime(true) * 1000); - }else{ - $nazev = $name; - } - if(!file_exists($path)){ - mkdir($path, 0777, true); - } - if (@$img) { - if (!imagejpeg ($img, $path . $nazev .".jpg", 95)) { - throw new ChybaUzivatele ("Obrázek neuložen!"); - } - imagedestroy ($img); - } else if (@$img2) { - if (!imagepng ($img2, $path . $nazev .".jpg")) { - throw new ChybaUzivatele ("Obrázek neuložen!"); - } - imagedestroy ($img2); - } else if (@$img3) { - if (!copy($img3, $path . $nazev .'.ico')) { - throw new ChybaUzivatele ("Obrázek neuložen!"); - } - } - return array('success' => true, 'url' => $path . $nazev .".jpg"); - } - } - - public function atHome($userId, $atHome){ - try { - Db::edit ('users', ['at_home' => $atHome], 'WHERE user_id = ?', array($userId)); - } catch(PDOException $error) { - echo $error->getMessage(); - die(); - } - } - - public function changePassword($oldPassword, $newPassword, $newPassword2){ - if ($newPassword == $newPassword2) { - //Password Criteria - $oldPasswordSaved = self::getUserData('password'); - if (self::getHashPassword($oldPassword) == $oldPasswordSaved) { - self::setUserData('password', self::getHashPassword($newPassword)); - } else { - throw new Exception ("old password did not match"); - } - } else { - throw new Exception ("new password arent same"); - } - } - - public function createUser($userName, $password){ - $userId = Db::loadOne('SELECT * FROM users WHERE username = ?;', array($userName))['user_id']; - if ($userId != null) { - return false; - }; - try { - $user = [ - 'username' => $userName, - 'password' => self::getHashPassword($password), - ]; - return Db::add ('users', $user); - } catch(PDOException $error) { - echo $error->getMessage(); - die(); - } + public function atHome($userId, $atHome){ + try { + Db::edit ('users', ['at_home' => $atHome], 'WHERE user_id = ?', array($userId)); + } catch(PDOException $error) { + echo $error->getMessage(); + die(); } } - ?> + + public function changePassword($oldPassword, $newPassword, $newPassword2){ + if ($newPassword == $newPassword2) { + //Password Criteria + $oldPasswordSaved = self::getUserData('password'); + if (self::getHashPassword($oldPassword) == $oldPasswordSaved) { + self::setUserData('password', self::getHashPassword($newPassword)); + } else { + throw new Exception ("old password did not match"); + } + } else { + throw new Exception ("new password arent same"); + } + } + + public function createUser($userName, $password){ + $userId = Db::loadOne('SELECT * FROM users WHERE username = ?;', array($userName))['user_id']; + if ($userId != null) { + return false; + }; + try { + $user = [ + 'username' => $userName, + 'password' => self::getHashPassword($password), + ]; + return Db::add ('users', $user); + } catch(PDOException $error) { + echo $error->getMessage(); + die(); + } + } + + public function haveOtaEnabled($userName){ + $ota = $this->getUser($userName)['ota']; + + if ($ota != ''){ + return ($ota != '' ? $ota : false); + } else { + return false; + } + } +} +?> diff --git a/app/controls/login.php b/app/controls/login.php new file mode 100644 index 0000000..57d306d --- /dev/null +++ b/app/controls/login.php @@ -0,0 +1,43 @@ +haveOtaEnabled($userName); + + $_SESSION['USERNAME'] = $userName; + $_SESSION['PASSWORD'] = $userPassword; + $_SESSION['OTA'] = $ota; +} else if ( + isset($_POST['otaCode']) && + $_POST['otaCode'] != '' +) { + + $otaCode = $_POST['otaCode']; + $otaSecret = $_POST['otaSecret']; + + $ga = new PHPGangsta_GoogleAuthenticator(); + $ota = $_SESSION['OTA']; + $userName = $_SESSION['USERNAME']; + $userPassword = $_SESSION['PASSWORD']; + unset($_SESSION['OTA']); + $checkResult = $ga->verifyCode($otaSecret, $otaCode, 6); // 2 = 2*30sec clock tolerance + if ($checkResult) { + $landingPage = $userManager->login($userName, $userPassword); + header('Location: ' . BASEDIR . $landingPage); + echo 'OK'; + } else { + echo 'FAILED'; + } + //TODO: upravi a ověřit jeslti ja zabezpečené + //TODO: + die(); +} diff --git a/app/templates/login.phtml b/app/templates/login.phtml index 6c37b8b..ae0636b 100644 --- a/app/templates/login.phtml +++ b/app/templates/login.phtml @@ -8,26 +8,16 @@ <?php echo $TITLE ?> - + prepare('ota',$ota); + $partial->render(); + } else { + $partial = new Partial('loginForm'); + $partial->render(); + } + ?> + + diff --git a/app/templates/part/loginOta.phtml b/app/templates/part/loginOta.phtml new file mode 100644 index 0000000..3e8d294 --- /dev/null +++ b/app/templates/part/loginOta.phtml @@ -0,0 +1,13 @@ + diff --git a/app/templates/setting.phtml b/app/templates/setting.phtml index 1f7c808..0b11493 100644 --- a/app/templates/setting.phtml +++ b/app/templates/setting.phtml @@ -76,6 +76,13 @@ +
+

+ +
+ +
+

echo('t_createuser') ?>

diff --git a/app/vendor/GoogleAuthenticator.php b/app/vendor/GoogleAuthenticator.php new file mode 100644 index 0000000..bf7d116 --- /dev/null +++ b/app/vendor/GoogleAuthenticator.php @@ -0,0 +1,252 @@ +_getBase32LookupTable(); + + // Valid secret lengths are 80 to 640 bits + if ($secretLength < 16 || $secretLength > 128) { + throw new Exception('Bad secret length'); + } + $secret = ''; + $rnd = false; + if (function_exists('random_bytes')) { + $rnd = random_bytes($secretLength); + } elseif (function_exists('mcrypt_create_iv')) { + $rnd = mcrypt_create_iv($secretLength, MCRYPT_DEV_URANDOM); + } elseif (function_exists('openssl_random_pseudo_bytes')) { + $rnd = openssl_random_pseudo_bytes($secretLength, $cryptoStrong); + if (!$cryptoStrong) { + $rnd = false; + } + } + if ($rnd !== false) { + for ($i = 0; $i < $secretLength; ++$i) { + $secret .= $validChars[ord($rnd[$i]) & 31]; + } + } else { + throw new Exception('No source of secure random'); + } + + return $secret; + } + + /** + * Calculate the code, with given secret and point in time. + * + * @param string $secret + * @param int|null $timeSlice + * + * @return string + */ + public function getCode($secret, $timeSlice = null) + { + if ($timeSlice === null) { + $timeSlice = floor(time() / 30); + } + + $secretkey = $this->_base32Decode($secret); + + // Pack time into binary string + $time = chr(0).chr(0).chr(0).chr(0).pack('N*', $timeSlice); + // Hash it with users secret key + $hm = hash_hmac('SHA1', $time, $secretkey, true); + // Use last nipple of result as index/offset + $offset = ord(substr($hm, -1)) & 0x0F; + // grab 4 bytes of the result + $hashpart = substr($hm, $offset, 4); + + // Unpak binary value + $value = unpack('N', $hashpart); + $value = $value[1]; + // Only 32 bits + $value = $value & 0x7FFFFFFF; + + $modulo = pow(10, $this->_codeLength); + + return str_pad($value % $modulo, $this->_codeLength, '0', STR_PAD_LEFT); + } + + /** + * Get QR-Code URL for image, from google charts. + * + * @param string $name + * @param string $secret + * @param string $title + * @param array $params + * + * @return string + */ + public function getQRCodeGoogleUrl($name, $secret, $title = null, $params = array()) + { + $width = !empty($params['width']) && (int) $params['width'] > 0 ? (int) $params['width'] : 200; + $height = !empty($params['height']) && (int) $params['height'] > 0 ? (int) $params['height'] : 200; + $level = !empty($params['level']) && array_search($params['level'], array('L', 'M', 'Q', 'H')) !== false ? $params['level'] : 'M'; + + $urlencoded = urlencode('otpauth://totp/'.$name.'?secret='.$secret.''); + if (isset($title)) { + $urlencoded .= urlencode('&issuer='.urlencode($title)); + } + + return "https://api.qrserver.com/v1/create-qr-code/?data=$urlencoded&size=${width}x${height}&ecc=$level"; + } + + /** + * Check if the code is correct. This will accept codes starting from $discrepancy*30sec ago to $discrepancy*30sec from now. + * + * @param string $secret + * @param string $code + * @param int $discrepancy This is the allowed time drift in 30 second units (8 means 4 minutes before or after) + * @param int|null $currentTimeSlice time slice if we want use other that time() + * + * @return bool + */ + public function verifyCode($secret, $code, $discrepancy = 1, $currentTimeSlice = null) + { + if ($currentTimeSlice === null) { + $currentTimeSlice = floor(time() / 30); + } + + if (strlen($code) != 6) { + return false; + } + + for ($i = -$discrepancy; $i <= $discrepancy; ++$i) { + $calculatedCode = $this->getCode($secret, $currentTimeSlice + $i); + if ($this->timingSafeEquals($calculatedCode, $code)) { + return true; + } + } + + return false; + } + + /** + * Set the code length, should be >=6. + * + * @param int $length + * + * @return PHPGangsta_GoogleAuthenticator + */ + public function setCodeLength($length) + { + $this->_codeLength = $length; + + return $this; + } + + /** + * Helper class to decode base32. + * + * @param $secret + * + * @return bool|string + */ + protected function _base32Decode($secret) + { + if (empty($secret)) { + return ''; + } + + $base32chars = $this->_getBase32LookupTable(); + $base32charsFlipped = array_flip($base32chars); + + $paddingCharCount = substr_count($secret, $base32chars[32]); + $allowedValues = array(6, 4, 3, 1, 0); + if (!in_array($paddingCharCount, $allowedValues)) { + return false; + } + for ($i = 0; $i < 4; ++$i) { + if ($paddingCharCount == $allowedValues[$i] && + substr($secret, -($allowedValues[$i])) != str_repeat($base32chars[32], $allowedValues[$i])) { + return false; + } + } + $secret = str_replace('=', '', $secret); + $secret = str_split($secret); + $binaryString = ''; + for ($i = 0; $i < count($secret); $i = $i + 8) { + $x = ''; + if (!in_array($secret[$i], $base32chars)) { + return false; + } + for ($j = 0; $j < 8; ++$j) { + $x .= str_pad(base_convert(@$base32charsFlipped[@$secret[$i + $j]], 10, 2), 5, '0', STR_PAD_LEFT); + } + $eightBits = str_split($x, 8); + for ($z = 0; $z < count($eightBits); ++$z) { + $binaryString .= (($y = chr(base_convert($eightBits[$z], 2, 10))) || ord($y) == 48) ? $y : ''; + } + } + + return $binaryString; + } + + /** + * Get array with all 32 characters for decoding from/encoding to base32. + * + * @return array + */ + protected function _getBase32LookupTable() + { + return array( + 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', // 7 + 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', // 15 + 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', // 23 + 'Y', 'Z', '2', '3', '4', '5', '6', '7', // 31 + '=', // padding char + ); + } + + /** + * A timing safe equals comparison + * more info here: http://blog.ircmaxell.com/2014/11/its-all-about-time.html. + * + * @param string $safeString The internal (safe) value to be checked + * @param string $userString The user submitted (unsafe) value + * + * @return bool True if the two strings are identical + */ + private function timingSafeEquals($safeString, $userString) + { + if (function_exists('hash_equals')) { + return hash_equals($safeString, $userString); + } + $safeLen = strlen($safeString); + $userLen = strlen($userString); + + if ($userLen != $safeLen) { + return false; + } + + $result = 0; + + for ($i = 0; $i < $userLen; ++$i) { + $result |= (ord($safeString[$i]) ^ ord($userString[$i])); + } + + // They are only identical strings if $result is exactly 0... + return $result === 0; + } +} diff --git a/index.php b/index.php index 5dc8647..e10f582 100644 --- a/index.php +++ b/index.php @@ -13,7 +13,7 @@ mb_internal_encoding ("UTF-8"); //Autoloader -foreach (["class", "views"] as $dir) { +foreach (["vendor","class", "views"] as $dir) { $files = scandir('./app/'.$dir.'/'); $files = array_diff($files, array('.', '..', 'app')); @@ -47,9 +47,10 @@ Db::connect (DBHOST, DBUSER, DBPASS, DBNAME); //TODO: Přesunout do Login Pohledu $userManager = new UserManager(); -if (isset($_POST['username']) && isset($_POST['password']) ) { - $userManager->login($_POST['username'], $_POST['password'], (isset ($_POST['remember']) ? $_POST['remember'] : 'false')); -} + +// if (isset($_POST['username']) && isset($_POST['password']) ) { +// $userManager->login($_POST['username'], $_POST['password'], (isset ($_POST['remember']) ? $_POST['remember'] : 'false')); +// } //Logs $logManager = new LogManager(); From 66b433950bec0c4cee4c0016d887c95f8e0bd0b5 Mon Sep 17 00:00:00 2001 From: unknown Date: Tue, 22 Oct 2019 18:31:14 +0200 Subject: [PATCH 12/15] small fix --- app/class/UserManager.php | 2 +- app/controls/login.php | 10 +++++++++- app/controls/settings.php | 17 +++++++++++++++++ app/templates/setting.phtml | 26 +++++++++++++------------- app/views/Setting.php | 15 +++++++++++++++ 5 files changed, 55 insertions(+), 15 deletions(-) create mode 100644 app/controls/settings.php diff --git a/app/class/UserManager.php b/app/class/UserManager.php index 3ea2ff8..4211ce1 100644 --- a/app/class/UserManager.php +++ b/app/class/UserManager.php @@ -29,7 +29,7 @@ class UserManager setcookie ("rememberMe", $this->setEncryptedCookie($user['username']), time () + (30 * 24 * 60 * 60 * 1000), BASEDIR, $_SERVER['HTTP_HOST'], 1); } $_SESSION['user']['id'] = $user['user_id']; - $page = "home"; + $page = ""; if ($user["startPage"] == 1) { $page = "dashboard"; } diff --git a/app/controls/login.php b/app/controls/login.php index 57d306d..db4c325 100644 --- a/app/controls/login.php +++ b/app/controls/login.php @@ -11,10 +11,17 @@ if ( $ota = false; $userName = $_POST['username']; $userPassword = $_POST['password']; + $rememberMe = (isset ($_POST['remember']) ? $_POST['remember'] : ""); $ota = $userManager->haveOtaEnabled($userName); + if ($ota == "") { + $landingPage = $userManager->login($userName, $userPassword, $rememberMe); + header('Location: ' . BASEDIR . $landingPage); + die(); + } $_SESSION['USERNAME'] = $userName; $_SESSION['PASSWORD'] = $userPassword; + $_SESSION['REMEMBER'] = $rememberMe; $_SESSION['OTA'] = $ota; } else if ( isset($_POST['otaCode']) && @@ -28,10 +35,11 @@ if ( $ota = $_SESSION['OTA']; $userName = $_SESSION['USERNAME']; $userPassword = $_SESSION['PASSWORD']; + $rememberMe = $_SESSION['REMEMBER']; unset($_SESSION['OTA']); $checkResult = $ga->verifyCode($otaSecret, $otaCode, 6); // 2 = 2*30sec clock tolerance if ($checkResult) { - $landingPage = $userManager->login($userName, $userPassword); + $landingPage = $userManager->login($userName, $userPassword, $rememberMe); header('Location: ' . BASEDIR . $landingPage); echo 'OK'; } else { diff --git a/app/controls/settings.php b/app/controls/settings.php new file mode 100644 index 0000000..dcda809 --- /dev/null +++ b/app/controls/settings.php @@ -0,0 +1,17 @@ +
-

+

echo('t_pageAfterLogIn') ?>

@@ -61,27 +61,27 @@
echo('l_oldPassword') ?>:
- +
echo('l_newPassword') ?>:
- +
echo('l_newPassword') ?>:
- +
- +

- +
- - + +

echo('t_createuser') ?>

@@ -104,20 +104,20 @@
echo('l_userName') ?>:
- +
echo('l_password') ?>:
- +
- +
- - + + getUsers(); $template->prepare('users', $users); + if ($userManager->getUserData('ota') == ''){ + $ga = new PHPGangsta_GoogleAuthenticator(); + $secret = $ga->createSecret(); + $qrCodeUrl = $ga->getQRCodeGoogleUrl('SmartHome', $secret); + $oneCode = $ga->getCode($otaSecret); + $template->prepare('qrUrl', $qrCodeUrl); + $template->prepare('otaSecret', $otaSecret); + $template->prepare('otacode', $oneCode); + + // echo "Secret is: ".$secret."\n\n"; + // echo "Google Charts URL for the QR-Code: ".$qrCodeUrl."\n\n"; + // echo "Checking Code '$oneCode' and Secret '$otaSecret':\n"; + } + $template->render(); } From 1e464e6e536f67430f09437f24cd4476789ef67f Mon Sep 17 00:00:00 2001 From: JonatanRek Date: Fri, 25 Oct 2019 18:48:48 +0200 Subject: [PATCH 13/15] OTA PART 2 Setting Page --- app/class/UserManager.php | 2 +- app/templates/js/setting.js | 20 +++++++++++++++++++- app/templates/setting.phtml | 19 +++++++++++-------- 3 files changed, 31 insertions(+), 10 deletions(-) diff --git a/app/class/UserManager.php b/app/class/UserManager.php index 4211ce1..0b1e4ed 100644 --- a/app/class/UserManager.php +++ b/app/class/UserManager.php @@ -3,7 +3,7 @@ class UserManager { public function getUsers () { try { - $allUsers = Db::loadAll ("SELECT user_id, username, at_home FROM users"); + $allUsers = Db::loadAll ("SELECT user_id, username, at_home, ota FROM users"); return $allUsers; } catch(PDOException $error) { echo $error->getMessage(); diff --git a/app/templates/js/setting.js b/app/templates/js/setting.js index 16614c8..664069a 100644 --- a/app/templates/js/setting.js +++ b/app/templates/js/setting.js @@ -37,4 +37,22 @@ function sendTestNotification(){ console.log("ERROR ", request, error); } }); -} \ No newline at end of file +} + +$( "button[name='deactivateOta']" ).click(function(){ + console.log("Didabling ota"); + $.ajax({ + url: 'ajax', + type: 'POST', + data: { + "ota" : 'X', + "action": 'disable' + }, + success: function(data){ + console.log(data); + }, + error: function (request, status, error) { + console.log("ERROR ", request, error); + } + }); +}) diff --git a/app/templates/setting.phtml b/app/templates/setting.phtml index 859b6a5..442e701 100644 --- a/app/templates/setting.phtml +++ b/app/templates/setting.phtml @@ -77,11 +77,12 @@
-

- -
- - +

echo('t_ota') ?>

+ + + + +

echo('t_createuser') ?>

@@ -89,6 +90,7 @@
+ @@ -96,6 +98,7 @@ $user) { ?> + @@ -116,14 +119,14 @@ - - + + - render(); ?> + From 633ba88fe26f2a997bd92496060681d7c5881b7e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=A1clav=20=C5=A0paninger?= Date: Sat, 2 Nov 2019 20:04:03 +0100 Subject: [PATCH 14/15] Discord Inwite Change --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 2a4c14f..672c39f 100644 --- a/README.md +++ b/README.md @@ -25,7 +25,7 @@ [![JS](https://img.shields.io/badge/JS-red.svg)](https://github.com/GamerClassN7/Smart_Home/search?l=js) [![HTML](https://img.shields.io/badge/HTML-blue.svg)](https://github.com/GamerClassN7/Smart_Home/search?l=html) [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT) -[![Discord](https://img.shields.io/discord/604697675430101003.svg?color=Blue&label=Discord&logo=Discord)](https://discord.gg/6BPErAS) +[![Discord](https://img.shields.io/discord/604697675430101003.svg?color=Blue&label=Discord&logo=Discord)](https://discord.gg/XJpT3UQ) ## About Smart_Home From 4203ccdebd8aa8f7ea208b2f94265898e11a419e Mon Sep 17 00:00:00 2001 From: JonatanRek Date: Sat, 2 Nov 2019 20:05:47 +0100 Subject: [PATCH 15/15] DeboogMode Tweek --- api.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/api.php b/api.php index 7c411ce..ce72603 100644 --- a/api.php +++ b/api.php @@ -172,7 +172,7 @@ if ($values != null || $values != "") { ]; break; } - + if (DEBUGMOD) $notificationData['body'] .= ' value='.$value['value']; if ($notificationData != []) { $subscribers = $notificationMng::getSubscription(); foreach ($subscribers as $key => $subscriber) {
echo('t_userName');?>echo('t_ota');?> echo('t_action');?>
' : ''); ?>