diff --git a/controller/LoginController.php b/controller/LoginController.php index a870bcc..12f0c9a 100644 --- a/controller/LoginController.php +++ b/controller/LoginController.php @@ -18,17 +18,24 @@ public function __construct() { if ($_SERVER['REQUEST_METHOD'] === 'GET') { $this->view = new View(); - if (!Session::isUserLoggedIn() && Cookie::isCookiesSet()) { - LoginModel::validateCookieLogin(Cookie::get('LoginView::CookieName'), Cookie::get('LoginView::CookiePassword')); - } - $data = [ - 'message' => Session::get('feedback'), - 'username' => Session::get('username'), + 'message' => '', + 'username' => '', ]; - if (Session::get('isUserLoggedIn')) { - $this->view->render('LogoutView', $data); + if (!(Session::isUserLoggedIn() && LoginModel::checkIfConcurrentSessionExists())) { + if (!Session::isUserLoggedIn() && Cookie::isCookiesSet()) { + LoginModel::validateCookieLogin(Cookie::get('LoginView::CookieName'), Cookie::get('LoginView::CookiePassword')); + } + + $data = [ + 'message' => Session::get('feedback'), + 'username' => Session::get('username'), + ]; + + if (Session::get('isUserLoggedIn')) { + $this->view->render('LogoutView', $data); + } } $this->view->render('LoginView', $data); diff --git a/model/LoginModel.php b/model/LoginModel.php index db97378..17b794e 100644 --- a/model/LoginModel.php +++ b/model/LoginModel.php @@ -51,10 +51,12 @@ public static function login(string $username, string $password, bool $remember) * @param string $message The message to be displayed instead of default 'Bye bye!' */ public static function logout(string $message = '') { - // Clear stored token and sessionId on logout + // Clear stored session data in database on logout if (Session::get('user')) { UserModel::saveTokenByUserName(Session::get('user')['username'], ''); UserModel::saveSessionIdByUserName(Session::get('user')['username'], ''); + UserModel::saveIpAdressByUserName(Session::get('user')['username'], ''); + UserModel::saveBrowserInfoByUserName(Session::get('user')['username'], ''); } Session::destroy(); @@ -82,6 +84,9 @@ private static function validateUserCredentials(string $username, string $passwo Session::set('isUserLoggedIn', true); Session::setOnce('feedback', 'Welcome'); UserModel::saveSessionIdByUserName($username, session_id()); + UserModel::saveIpAdressByUserName($username, $_SERVER['REMOTE_ADDR']); + UserModel::saveBrowserInfoByUserName($username, $_SERVER['HTTP_USER_AGENT']); + return true; } @@ -116,4 +121,23 @@ public static function validateCookieLogin(string $username, string $token) : bo self::logout('Wrong information in cookies'); return false; } + + /** + * @return bool + */ + public static function checkIfConcurrentSessionExists() : bool { + $newUserIpAddress = $_SERVER['REMOTE_ADDR']; + $newUserBrowser = $_SERVER['HTTP_USER_AGENT']; + $newUserSessionId = session_id(); + + $existingUser = UserModel::getUserByUserName(Session::get('user')['username']); + + if ($newUserSessionId === $existingUser['sessionId'] && ($newUserBrowser !== $existingUser['browser'] || $newUserIpAddress !== $existingUser['ip'])) { + session_regenerate_id(false); + Session::destroy(); + return true; + } + + return false; + } } \ No newline at end of file diff --git a/model/UserModel.php b/model/UserModel.php index 26cabec..b448a01 100644 --- a/model/UserModel.php +++ b/model/UserModel.php @@ -53,38 +53,58 @@ public static function registerNewUser(string $username, string $password) { /** * @param string $username * @param string $token - * @throws Exception */ public static function saveTokenByUserName(string $username, string $token) { - if (empty($username)) { - throw new \Exception('Username must not be empty'); - } + self::saveDataToDatabase($username, $token, "token"); + } - $token = empty($token) ? null : $token; + /** + * @param string $username + * @param string $sessionId + */ + public static function saveSessionIdByUserName(string $username, string $sessionId) { + self::saveDataToDatabase($username, $sessionId, "sessionId"); + } - $database = DatabaseFactory::getFactory()->getConnection(); + /** + * @param string $username + * @param string $ipAddress + */ + public static function saveIpAdressByUserName(string $username, string $ipAddress) { + self::saveDataToDatabase($username, $ipAddress, "ip"); + } - $sql = 'UPDATE AppUser SET token = :token WHERE username = :user_name;'; - $query = $database->prepare($sql); - $query->execute([':token' => $token, ':user_name' => $username]); + /** + * @param string $username + * @param string $browser + */ + public static function saveBrowserInfoByUserName(string $username, string $browser) { + self::saveDataToDatabase($username, $browser, "browser"); } /** * @param string $username - * @param string $sessionId + * @param string $data + * @param string $columnName * @throws Exception */ - public static function saveSessionIdByUserName(string $username, string $sessionId) { + private static function saveDataToDatabase(string $username, string $data, string $columnName) { if (empty($username)) { throw new \Exception('Username must not be empty'); } - $sessionId = empty($sessionId) ? null : $sessionId; + $validColumnNames = ['sessionId', 'token', 'ip', 'browser']; - $database = DatabaseFactory::getFactory()->getConnection(); + if (in_array($columnName, $validColumnNames)) { + $data = empty($data) ? null : $data; - $sql = 'UPDATE AppUser SET sessionId = :session_id WHERE username = :user_name;'; - $query = $database->prepare($sql); - $query->execute([':session_id' => $sessionId, ':user_name' => $username]); + $database = DatabaseFactory::getFactory()->getConnection(); + + $sql = 'UPDATE AppUser SET ' . $columnName . ' = :data WHERE username = :user_name;'; + $query = $database->prepare($sql); + $query->execute([':data' => $data, ':user_name' => $username]); + } else { + throw new \Exception('Invalid columnName'); + } } } diff --git a/view/LayoutView.php b/view/LayoutView.php index 5497bc0..5ceb4f8 100644 --- a/view/LayoutView.php +++ b/view/LayoutView.php @@ -9,10 +9,10 @@ Logged in'; } else { - if (Session::get('action') === "login") { - echo 'Register a new user'; - } else if (Session::get('action') === "register") { + if (Session::get('action') === "register") { echo 'Back to login'; + } else { + echo 'Register a new user'; } echo '