diff --git a/.gitignore b/.gitignore index 0284fa91fd941f6089ab9a57ac383d9ee9514148..4a24e4f3182517eb3ddae2b3084fa170a604c794 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,6 @@ dev.env .DS_Store uploads/* -images/ \ No newline at end of file +images/ +fatApp.spec +question.md \ No newline at end of file diff --git a/Register.php b/Register.php index d411b840e0c34e358507cb87c746569450278bd0..2c91b660e466ed2a227b04f7dff86e32d0ef31b7 100644 --- a/Register.php +++ b/Register.php @@ -40,10 +40,18 @@ if (isset($_POST['bio'])) { $provided_bio = $_POST['bio']; } +$allfildsOk = ( + (isset($provided_age) && !empty($provided_age)) + && isset($provided_email) && !empty($provided_email)) + && (isset($provided_password) && !empty($provided_password)) + && (isset($provided_age) && !empty($provided_age)) + && (isset($provided_bio) && !empty($provided_bio)); -if (isset($provided_email) && isset($provided_password) && isset($provided_age)) { +if ($allfildsOk) { // check if user already exists + $provided_email = mysqli_real_escape_string($obj->connection, $provided_email); + $query = "SELECT * FROM users where email = '$provided_email';"; $result = $obj->executeQuery($query); $num_rows = mysqli_num_rows($result); @@ -55,17 +63,20 @@ if (isset($provided_email) && isset($provided_password) && isset($provided_age)) // hashed password $hashed_password = password_hash($provided_password, PASSWORD_BCRYPT); - // signup token - $token = hash('sha256', time() . $provided_email . 'BX'); + // user token + $token = hash('sha256', time() . $provided_email . $obj->getENV()['SECRET']); - $message = ['email' => $provided_email, 'token' => $token]; // we can add the valid_until time also + $message = ['email' => $provided_email, 'token' => $token, 'validat_until' => time() + ($obj->getENV()['token_validation_time'] * 60)]; // valid_until time $verification_token = ['message' => $message, 'reset' => 0, 'hash_of_message' => $obj->encrypt(json_encode($message))]; $encrypted_token = $obj->encrypt(json_encode($verification_token)); + $provided_user_name = mysqli_real_escape_string($obj->connection, $provided_user_name); + $provided_age = mysqli_real_escape_string($obj->connection, $provided_age); + $provided_bio = mysqli_real_escape_string($obj->connection, $provided_bio); $query = "INSERT INTO `users` VALUE (null, '$provided_user_name', '$provided_age','$provided_email',1,'$token',null,'$hashed_password', '$provided_bio', 0, 0, '$token', null, null);"; $result = $obj->executeQuery($query); @@ -153,5 +164,4 @@ if (isset($provided_email) && isset($provided_password) && isset($provided_age)) </div> <?php include_once 'footer.php'; -?> - +?> \ No newline at end of file diff --git a/accepte_or_reject_friend.php b/accepte_or_reject_friend.php index b7d107bb9032c89e00ff2b9771e8d609bf71a1bc..5c738eb2894faec19ecd01cca015a3d080a5dba2 100644 --- a/accepte_or_reject_friend.php +++ b/accepte_or_reject_friend.php @@ -3,8 +3,7 @@ require_once 'header.php'; if (!$obj->loggedin($obj)) { header("Location: login.php"); -} -if (!$obj->acountVerified($obj)) { +} else if (!$obj->acountVerified($obj)) { header("Location: verifyemail.php"); } $loged_user_email = $_SESSION['logged_user']; diff --git a/add_friend.php b/add_friend.php index e6443029a0af625651d7c9c980a562c8b943cd36..404138b1ea5465ddfcd030975cee910b84debc35 100644 --- a/add_friend.php +++ b/add_friend.php @@ -3,8 +3,7 @@ require_once 'header.php'; if (!$obj->loggedin($obj)) { header("Location: login.php"); -} -if (!$obj->acountVerified($obj)) { +} else if (!$obj->acountVerified($obj)) { header("Location: verifyemail.php"); } diff --git a/admin.php b/admin.php index 4104b084c029f50597e0c44b710130857964977f..c7584c4b893b5dfd4d4b989091201f97e9be432f 100644 --- a/admin.php +++ b/admin.php @@ -3,12 +3,9 @@ require_once 'header.php'; if (!$obj->loggedin($obj)) { header("Location: login.php"); -} -if (!$obj->acountVerified($obj)) { +} else if (!$obj->acountVerified($obj)) { header("Location: verifyemail.php"); -} - -if (!$obj->isAdmin($obj)) { +} else if (!$obj->isAdmin($obj)) { header("Location: " . $_SERVER['HTTP_REFERER']); } @@ -43,6 +40,18 @@ if (isset($_POST["delete_post"]) && !empty(isset($_POST["delete_post"]))) { } +if (isset($_POST["disable_post"]) && !empty(isset($_POST["disable_post"]))) { + $post_id = $_POST["disable_post"]; + + + // disable reported post image + $query = "UPDATE posts SET active=NOT active WHERE id='$post_id'"; + $result = $obj->executeQuery($query); + + header("Location: " . $_SERVER['HTTP_REFERER']); // to refresh + +} + $toggle_disabled_user = NULL; if (isset($_POST["toggle_disabled_user"]) && !empty(isset($_POST["toggle_disabled_user"]))) { $toggle_disabled_user = $_POST["toggle_disabled_user"]; @@ -147,7 +156,7 @@ if (isset($_POST["delete_user_id"]) && !empty(isset($_POST["delete_user_id"]))) </div> <?php -$query = "SELECT * FROM reports +$query = "SELECT reports.*, posts.*, posts.active as post_active,users.* FROM reports LEFT JOIN posts ON reports.post_id = posts.id LEFT JOIN users ON posts.user_id = users.id"; $reports = $obj->executeQuery($query); @@ -178,9 +187,21 @@ $reports = $obj->executeQuery($query); <th><p>' . $row['report_body'] . '</p></th> <td> <form action="" method="POST"> - <input type="text" name="delete_post" value="' . $row['post_id'] . '" style="display:none"> - <button type="submit" class="btn btn-sm btn-danger">Delete <i class="fa-solid fa-trash"></i></button></td> + <input type="text" name="delete_post" value="' . $row['post_id'] . '" style="display:none"> + <button type="submit" class="btn btn-sm btn-danger">Delete <i class="fa-solid fa-trash"></i></button> </form> + + <form action="" method="POST"> + <input type="text" name="disable_post" value="' . $row['post_id'] . '" style="display:none"> + '; + if ($row['post_active'] == 1) { + echo '<button type="submit" class="btn btn-sm btn-primary">enabled <i class="fa-solid fa-play"></i></button> '; + } else { + echo '<button type="submit" class="btn btn-sm btn-warning">disabled <i class="fa-solid fa-stop"></i></button>'; + } + + + echo '</form> </td> </tr>'; diff --git a/api.php b/api.php index c405455d9669813ed7e2e6df16057c799887a48d..141833b39badb48f52e3079a6b896190b498b32c 100644 --- a/api.php +++ b/api.php @@ -3,6 +3,7 @@ include 'connection.php'; $obj = new Connection(); + // request method $requestMethod = $_SERVER['REQUEST_METHOD']; @@ -36,21 +37,27 @@ function sendBadRequest() { header("HTTP/1.1 401 Unauthorized"); sendResponse(["message", "un authorized request"]); + die(); } - - - if ($userToken == '') { sendBadRequest(); die(); } +$userToken = mysqli_real_escape_string($obj->connection, $userToken); $query = "SELECT * FROM users WHERE user_token = '$userToken'"; $result = $obj->executeQuery($query); $data = mysqli_fetch_assoc($result); + +// account is not active +if ($data['active'] == 0) { + sendResponse(['message' => 'acount is not active please contact your admin']); + die(); +} + if (count($requestPath) > 2) { sendBadRequest(); } else if (1 == 2) { @@ -63,12 +70,12 @@ if (count($requestPath) > 2) { if (count($requestPath) == 1 && $requestPath[2] == 'messages' && $requestMethod == 'GET') { // read all messages : GET /messages with admin token if ($userToken == $saved_token && $isAdmin == 1) { - $query = "SELECT * FROM posts;"; + $query = "SELECT id FROM posts;"; $result = $obj->executeQuery($query); sendResponse(parseSQLResult($result)); } else if ($userToken == $saved_token && $isAdmin == 0) { - $query = "SELECT * FROM posts where user_id = " . $data['id'] . ";"; + $query = "SELECT id FROM posts where user_id = " . $data['id'] . ";"; $result = $obj->executeQuery($query); sendResponse(parseSQLResult($result)); @@ -76,32 +83,48 @@ if (count($requestPath) > 2) { } // GET /message/<Id> // > Header XAPITOKEN token (if admin token, read all messages) - else if (count($requestPath) == 2 && $requestPath[2] == 'messages' && !empty($requestPath[3]) && $requestMethod == 'GET') { + else if (count($requestPath) == 2 && $requestPath[2] == 'message' && !empty($requestPath[3]) && $requestMethod == 'GET') { + $post_id = mysqli_real_escape_string($obj->connection, $requestPath[3]); if ($userToken == $saved_token && $isAdmin == 1) { - - $query = "SELECT * FROM posts where id = $requestPath[3];"; + $query = "SELECT id,title,body FROM posts where id = $post_id;"; $result = $obj->executeQuery($query); sendResponse(parseSQLResult($result)); } else if ($userToken == $saved_token && $isAdmin == 0) { - $query = "SELECT * FROM posts where user_id = " . $data['id'] . " AND id = " . $requestPath[3] . ";"; + $query = "SELECT id,title,body FROM posts where user_id = " . $data['id'] . " AND id = $post_id;"; $result = $obj->executeQuery($query); sendResponse(parseSQLResult($result)); } - } else if (count($requestPath) == 1 && $requestPath[2] == 'messages' && $requestMethod == 'POST') { + } else if (count($requestPath) == 1 && $requestPath[2] == 'message' && $requestMethod == 'POST') { if ($userToken == $saved_token && $isAdmin == 0) { - $requestBody = file_get_contents("php://input"); + $requestBody = file_get_contents("php://input"); // get post request body - // You can then parse the request body, for example, if it's JSON data: + // parse the request body $recieved_data = json_decode($requestBody, true); - $query = "INSERT INTO posts VALUES (NULL, '" . $recieved_data['title'] . "','" . $recieved_data['body'] . "', '" . $recieved_data['image_url'] . "', CURRENT_TIMESTAMP, " . $data['id'] . ") ;"; - $result = $obj->executeQuery($query); - if ($result) { - sendResponse(['message' => 'post created successfully']); + // verifiy data + + if (empty($recieved_data["title"])) { + sendResponse(["error" => "title is required"]); + } else if (empty($recieved_data["body"])) { + sendResponse(["error" => "body is required"]); + } else if (empty($recieved_data["image_url"])) { + sendResponse(["error" => "post image is required"]); + } else if (!((strncmp($recieved_data["image_url"], 'https://', 8) === 0) || (strncmp($recieved_data["image_url"], 'http://', 7) === 0))) { + sendResponse(['error' => 'post image should be valid']); + } else { + $post_is_valid = !empty($recieved_data["title"]) && !empty($recieved_data["body"]) && !empty($recieved_data["image_url"]); + + if ($post_is_valid) { + $query = "INSERT INTO posts VALUES (NULL, '" . $recieved_data['title'] . "','" . $recieved_data['body'] . "', '" . $recieved_data['image_url'] . "', CURRENT_TIMESTAMP, " . $data['id'] . ") ;"; + $result = $obj->executeQuery($query); + if ($result) { + sendResponse(['message' => 'post created successfully']); + } + } } } } else { diff --git a/connection.php b/connection.php index d19959593291fb4af4482c2454f409615a9ec44e..9a4c70ef685e892c89c574cfb2c2751ba91ac157 100644 --- a/connection.php +++ b/connection.php @@ -1,8 +1,11 @@ <?php error_reporting(0); +ini_set('display_errors', 0); + require_once '/var/www/html/PHPMailer/src/PHPMailer.php'; require_once '/var/www/html/PHPMailer/src/SMTP.php'; +require_once './rateLimiter.php'; class Connection @@ -28,13 +31,25 @@ class Connection $this->key = $this->env['ecryption_key']; // Create connection + mysqli_report(MYSQLI_REPORT_STRICT); $this->connection = mysqli_connect($this->servername, $this->username, $this->password, $this->DB_name); // Check connection if (!$this->connection) { - die("Connection failed: " . mysqli_connect_error()); + die("Connection failed: "); } $this->USER_SESSION_DURATION = time() + $this->env['SESSION_DURATION']; // 1 hour + + $rateLimter = new RateLimiterGaurd(100000, 10); + + $userIP = $_SERVER['REMOTE_ADDR']; + + if (!$rateLimter->isAllowed($userIP)) { + die('<h3>too much request please try again later</h3>'); + } + + + $query = 'CREATE TABLE IF NOT EXISTS users ( id INT PRIMARY KEY AUTO_INCREMENT, user_name VARCHAR(64), @@ -56,7 +71,7 @@ class Connection $result = mysqli_query($this->connection, $query); // Check if the query was successful if (!$result) { - die("Query failed: " . mysqli_error($this->connection)); + die("Query failed: "); } @@ -72,7 +87,7 @@ class Connection $result = mysqli_query($this->connection, $query); // Check if the query was successful if (!$result) { - die("Query failed: " . mysqli_error($this->connection)); + die("Query failed: "); } @@ -84,6 +99,7 @@ class Connection image_url varchar(255), posted_at DATETIME default CURRENT_TIMESTAMP, user_id INT, + active TINYINT default 1, foreign key (user_id) references users (id) )'; @@ -133,7 +149,7 @@ class Connection $result = mysqli_query($this->connection, $query); // Check if the query was successful if (!$result) { - die("Query failed: " . mysqli_error($this->connection)); + die("Query failed:"); } return $result; } @@ -185,7 +201,7 @@ class Connection public function acountActive($obj) { - $loged_user_email = $_SESSION['logged_user']; + $loged_user_email = mysqli_real_escape_string($obj->connection, $_SESSION['logged_user']); $query = "SELECT * FROM users where email='$loged_user_email'"; $result = $obj->executeQuery($query); $result = mysqli_fetch_assoc($result)['active']; @@ -195,7 +211,7 @@ class Connection public function isAdmin($obj) { - $loged_user_email = $_SESSION['logged_user']; + $loged_user_email = mysqli_real_escape_string($obj->connection, $_SESSION['logged_user']); $query = "SELECT * FROM users where email='$loged_user_email'"; $result = $obj->executeQuery($query); $result = mysqli_fetch_assoc($result)['isAdmin']; @@ -206,7 +222,8 @@ class Connection public function getUserIdByEmail($obj, $email) { - // echo $_SESSION['logged_user']; + + $email = mysqli_real_escape_string($obj->connection, $email); $query = "SELECT * FROM users where email='$email'"; $result = $obj->executeQuery($query); return mysqli_fetch_assoc($result)['id']; @@ -216,7 +233,7 @@ class Connection public function getUserByEmail($obj, $email) { - // echo $_SESSION['logged_user']; + $email = mysqli_real_escape_string($obj->connection, $email); $query = "SELECT * FROM users where email='$email'"; $result = $obj->executeQuery($query); return mysqli_fetch_assoc($result); @@ -224,6 +241,7 @@ class Connection public function getUserById($obj, $id) { + $id = mysqli_real_escape_string($obj->connection, $id); // echo $_SESSION['logged_user']; $query = "SELECT * FROM users where id='$id'"; $result = $obj->executeQuery($query); @@ -278,7 +296,10 @@ class Connection return openssl_decrypt($message, 'aes-256-cbc', $this->key, 0, $iv); } - + public function getENV() + { + return $this->env; + } public function __destruct() { $this->closeConnection(); diff --git a/css/main.css b/css/main.css index f798fe277d34ea4b7d64cdf3782da5d3b0561e5b..dbdf6a6b6c2916afc5a1a13bd6c37bc7d5a01f0a 100644 --- a/css/main.css +++ b/css/main.css @@ -174,7 +174,16 @@ body { .freind-list .videos video { width: 50%; } - +#remoteVideo { + width: 100vw; +} +#localVideo { + width: 200px; + height: 200px; + position: absolute; + bottom: 0px; + left: 58%; +} @@ -747,7 +756,7 @@ body { /* admin */ -.admin-page { +.admin-page, .settings { width: 150%; } .admin-page tbody { diff --git a/dist/fatApp b/dist/fatApp new file mode 100755 index 0000000000000000000000000000000000000000..47fdb5ed8d6ffa4d8ed22ac870fbffd9f8b3880d Binary files /dev/null and b/dist/fatApp differ diff --git a/edit_profile.php b/edit_profile.php index 01a20c88a393bb26fa782d83a6cb70ef1b0fd2b1..1481f8e4831811150862583b869befd05793f586 100644 --- a/edit_profile.php +++ b/edit_profile.php @@ -131,10 +131,10 @@ if ( } else if (!empty($profileImageName) && empty($provided_password)) { if ($fileError === 0) { // delete pervious image_profile - - if (!unlink($user['profile_image'])) { - $errors = "can't delete old image"; - } + unlink($user['profile_image']); + // if (!) { + // // $errors = "can't delete old image"; + // } // upload directory $uploadDir = "uploads/"; diff --git a/fatApp.py b/fatApp.py new file mode 100644 index 0000000000000000000000000000000000000000..3b27eba8a6ba2e9809f8cbfda9b3bbeda8c2937e --- /dev/null +++ b/fatApp.py @@ -0,0 +1,44 @@ +import os +import requests + +def get_posts(api_url, x_api_token): + headers = { + 'XAPITOKEN': x_api_token, + } + + response = requests.get(api_url, headers=headers) + if response.status_code == 200: + data = response.json() + return data + else: + print(f"Error: {response.status_code}") + return None + + + +if __name__ == "__main__": + # Get X-API-Token from environment variable + x_api_token = os.environ.get('XAPITOKEN') + + if not x_api_token: + print("XAPITOKEN not found in environment variables. Please set the XAPITOKEN variable.") + else: + api_url = 'http://localhost/api.php/messages' + posts_data = get_posts(api_url, x_api_token) + + if posts_data: + print("API Response:") + for posts in posts_data: + # print(posts.get('id')) + id = posts.get('id') + api_url = f'http://localhost/api.php/message/{id}' + + data = get_posts(api_url, x_api_token) + print(f'api : {api_url}') + print(data) + + +""" compiled by +requirement pip3 install requests +pyinstaller fatApp.py -F --onefile +""" \ No newline at end of file diff --git a/forgotpassword.php b/forgotpassword.php index 1c204187af747b9c948538ab6bdcd13e632ee1d2..b692b8c6a96587d225418b711591eadafd27935d 100644 --- a/forgotpassword.php +++ b/forgotpassword.php @@ -27,22 +27,18 @@ if (isset($_POST['password']) && empty($_POST['password'])) { if (!empty($_POST['email']) && !empty($_POST['password'])) { - $query = "select * from users where email='$provided_email';"; - $result = mysqli_fetch_assoc($obj->executeQuery($query)); + $result = $obj->getUserByEmail($obj, $provided_email); if (!empty($result)) { // hashed password $hashed_password = password_hash($provided_password, PASSWORD_BCRYPT); + // reset token + $token = hash('sha256', time() . $provided_email . $obj->getENV()['SECRET']); - $token = hash('sha256', time() . $provided_email . 'BX'); - // signup token - $token = hash('sha256', time() . $provided_email . 'BX'); - - - $message = ['email' => $provided_email, 'token' => $token]; + $message = ['email' => $provided_email, 'token' => $token, 'validat_until' => time() + ($obj->getENV()['token_validation_time'] * 60)]; $verification_token = ['message' => $message, 'reset' => 1, 'hash_of_message' => $obj->encrypt(json_encode($message))]; diff --git a/friends.php b/friends.php index 8f2919134fadb2bdd60d8f6298ec71549de9533e..7a6f51967b769a120c5403c6d550d89eb8ef257f 100644 --- a/friends.php +++ b/friends.php @@ -4,8 +4,7 @@ require_once 'header.php'; if (!$obj->loggedin($obj)) { header("Location: login.php"); -} -if (!$obj->acountVerified($obj)) { +} else if (!$obj->acountVerified($obj)) { header("Location: verifyemail.php"); } $loged_user_email = $_SESSION['logged_user']; @@ -201,7 +200,7 @@ $friends = $obj->executeQuery($query); var getUserMedia = navigator.mediaDevices.getUserMedia || navigator.mediaDevices.webkitGetUserMedia || navigator.mediaDevices.mozGetUserMedia; getUserMedia({ video: isVideo, audio: true }) .then(function (stream) { - + video_div.classList.toggle("video_toggle"); var call = peer.call(userid, stream); console.log("calling ...", userid); diff --git a/header.php b/header.php index f0f915b6cc432c4febfc5b8b97e00b6ff79e81bc..1188e91d84f1ada5c69fdaca7c4ad7ab5eedf774 100644 --- a/header.php +++ b/header.php @@ -41,7 +41,7 @@ $obj = new Connection(); </a>'; } else { echo ' - <a class="btn btn-sm btn-outline-success me-2" href="Register.php">Register</a> + <a class="btn btn-sm btn-outline-success me-2" href="register.php">Register</a> <a href="/login.php" class="btn btn-sm btn-outline-primary me-2"> login </a>'; diff --git a/index.php b/index.php index 69553e9cbdb9e86f608725f9d47b6f218e3c3540..cde2a6c54efdfedea1bd51617fc5f6867f7ffc0d 100644 --- a/index.php +++ b/index.php @@ -3,9 +3,7 @@ include_once 'header.php'; if (!$obj->loggedin($obj)) { header("Location: login.php"); -} - -if (!$obj->acountVerified($obj)) { +} else if (!$obj->acountVerified($obj)) { header("Location: verifyemail.php"); } @@ -61,14 +59,14 @@ $users = $obj->executeQuery($query); <?php -$query = "SELECT posts.id as post_id, title, body, image_url, posted_at, user_id, user_name, email, profile_image FROM posts -LEFT JOIN users on users.id = posts.user_id order by posted_at DESC; +$query = "SELECT posts.id as post_id, title, body, image_url,isAdmin, posted_at, user_id, user_name, email, profile_image FROM posts +LEFT JOIN users on users.id = posts.user_id where posts.active=1 order by posted_at DESC; "; $posts = $obj->executeQuery($query); while ($row = mysqli_fetch_array($posts)) { $isAdmin = ''; - if ($row['isAdmin'] == false) { + if ($row['isAdmin'] == 0) { $isAdmin = '@USER'; } else { $isAdmin = '@ADMIN'; @@ -123,4 +121,5 @@ while ($row = mysqli_fetch_array($posts)) { <?php include_once 'footer.php'; -?> \ No newline at end of file +?> + diff --git a/log/logs.txt b/log/logs.txt new file mode 100644 index 0000000000000000000000000000000000000000..5944913af4432bd2510b8a213e0ffff03871b375 --- /dev/null +++ b/log/logs.txt @@ -0,0 +1,6 @@ +[2023-11-10 18:12:25] Successful login for user: kh241994@gmail.com +[2023-11-10 18:47:19] Failed login attempt for user: kh241994@gmail.com +[2023-11-10 18:51:30] Successful login for user: zabio.ahmadi@gmail.com +[2023-11-10 18:52:19] Successful login for user: kh241994@gmail.com +[2023-11-10 19:55:58] Successful login for user: zabio.ahmadi@gmail.com +[2023-11-10 19:57:44] Successful login for user: kh241994@gmail.com diff --git a/login.php b/login.php index 9c8189feae5846bade58ecfd156b5df360a3aae2..e406404019364d97c8882e6da36cdc5939cfcc06 100644 --- a/login.php +++ b/login.php @@ -21,38 +21,33 @@ if (isset($_POST['password'])) { if (isset($provided_email) && isset($provided_password)) { // check if user exists with provided email - $query = "SELECT * FROM users where email = '$provided_email';"; - - $result = $obj->executeQuery($query); - $email = ''; - $password = ''; - while ($query_row = mysqli_fetch_assoc($result)) { - $email = $query_row['email']; - $password = $query_row['password']; - } + $target_user = $obj->getUserByEmail($obj, $provided_email); + $email = $target_user['email']; + $password = $target_user['password']; if (password_verify($provided_password, $password)) { // Password is correct - $target_user = $obj->getUserByEmail($obj, $email); - if ($target_user['active'] == 0) { header("Location: account_disabled.php"); } else if ($target_user['email_verified'] == 0) { header("Location: verifyemail.php"); } else { + + $log_message = "[" . date("Y-m-d H:i:s") . "] Successful login for user: $email" . PHP_EOL; + file_put_contents("./log/logs.txt", $log_message, FILE_APPEND); + + $_SESSION['logged_user'] = $email; $_SESSION['valid_until'] = $obj->USER_SESSION_DURATION; header("Location: index.php"); } - - - - } else { // Password is incorrect + $log_message = "[" . date("Y-m-d H:i:s") . "] Failed login attempt for user: $email" . PHP_EOL; + file_put_contents("./log/logs.txt", $log_message, FILE_APPEND); $errors = "invalid email or password"; } diff --git a/prod.env b/prod.env index df7fba888f070dc7cf3e92854067a65798463d5f..bfcb9dae3a17508aa44db7b6f56de1b545dfb159 100644 --- a/prod.env +++ b/prod.env @@ -9,4 +9,6 @@ SMTP_PORT=465 SMTP_PROTOCOL=ssl SMTP_SENDER_EMAIL_ADDRESS=webmaster@secur-app.ch SESSION_DURATION=3600 -ecryption_key=your_secret_key \ No newline at end of file +ecryption_key=your_secret_key +SECRET=token_secret +token_validation_time=15 #in minutes \ No newline at end of file diff --git a/rateLimiter.php b/rateLimiter.php new file mode 100644 index 0000000000000000000000000000000000000000..5a478e6fcc43326675fac5b77f7ca386120d6eee --- /dev/null +++ b/rateLimiter.php @@ -0,0 +1,57 @@ +<?php + +class RateLimiterGaurd +{ + private $storagePath = './gaurd'; + private $limit; // Number requests allowed + private $interval; // Time interval in seconds + + public function __construct($limit = 3, $interval = 10) + { + $this->limit = $limit; + $this->interval = $interval; + } + public function isAllowed($user_ip) + { + + $fileName = $this->storagePath . '/' . $user_ip; + + $attemptObject = json_decode($this->readAttempts($fileName)); + + + // Remove attempts that are older than the interval + $attemptObject->attempt = array_filter($attemptObject->attempt, function ($time) { + return $time > (time() - $this->interval); + }); + + // If the number of attempts is less than the limit, increment the counter and allow access + if (count($attemptObject->attempt) < $this->limit) { + $attemptObject->attempt[] = time(); + + + $this->writeAttempts($fileName, $attemptObject); + return true; + } else { + return false; + } + } + + public function readAttempts($fileName) + { + + if (file_exists($fileName)) { + $contents = file_get_contents($fileName); + return json_decode($contents, true); + } else { + return json_encode(['user_ip' => $_SERVER['REMOTE_ADDR'], 'attempt' => []]); + } + } + + public function writeAttempts($fileName, $loginAttempts) + { + touch($fileName); + file_put_contents($fileName, json_encode(json_encode($loginAttempts))); + } +} + +?> \ No newline at end of file diff --git a/settings.php b/settings.php index a2fe115fb9667e7dbb41e75063f5675ace205c28..a9cd66f635624e86ff3a6b8eab92e387eef6ff98 100644 --- a/settings.php +++ b/settings.php @@ -49,6 +49,21 @@ if (isset($_POST['delete'])) { } + +if ( + isset($_POST["regenerate_token"]) + && !empty($_POST['regenerate_token']) + && $_POST['regenerate_token'] == 'regenerate' +) { + + $token = hash('sha256', time() . $logged_user . $obj->getENV()['SECRET']); + + $query = "UPDATE users SET user_token = '$token' WHERE email = '$logged_user';"; + + $result = $obj->executeQuery($query); + header("Location: " . $_SERVER['HTTP_REFERER']); +} + ?> <div class="settings"> @@ -146,6 +161,12 @@ if (isset($_POST['delete'])) { <?php echo $user['user_token'] ?> </p> </div> + <div> + <form action="" method="POST"> + <input style="display:none" type="text" name="regenerate_token" value="regenerate"> + <button type="submit" class="btn btn-sm btn-primary">regenerate token</button> + </form> + </div> </div> <div class="line"> <div class="profile_bio"> @@ -171,8 +192,4 @@ if (isset($_POST['delete'])) { </div> </div> -</div> - -<?php -include_once 'footer.php'; -?> \ No newline at end of file +</div> \ No newline at end of file diff --git a/twits.php b/twits.php index 283f762ade313d569ca4398e8d6813c01c72daf0..429f467d9d039c46d80c13b3275e5666f79687c9 100644 --- a/twits.php +++ b/twits.php @@ -60,7 +60,9 @@ if ((isset($post_title) && $post_title != null) && (isset($post_body) && $post_b if (isset($post_url_image) && ((strncmp($post_url_image, 'https://', 8) === 0) || strncmp($post_url_image, 'http://', 7) === 0)) { // create posts $user_id = $obj->getUserIdByEmail($obj, $_SESSION['logged_user']); - $query = "INSERT INTO posts VALUE (null,'$post_title','$post_body', '$post_url_image',CURRENT_TIMESTAMP, '$user_id');"; + $query = "INSERT INTO posts VALUE (null,'$post_title','$post_body', '$post_url_image',CURRENT_TIMESTAMP, '$user_id', 1);"; + + echo $query; $result = $obj->executeQuery($query); // refresh session time @@ -83,7 +85,7 @@ if ((isset($post_title) && $post_title != null) && (isset($post_body) && $post_b // Move the file from the temporary location to the desired directory if (move_uploaded_file($postImageTmpName, $uniqueFileName)) { // create posts - $query = "INSERT INTO posts VALUE (null,'$post_title','$post_body', '$uniqueFileName',CURRENT_TIMESTAMP, '$user_id');"; + $query = "INSERT INTO posts VALUE (null,'$post_title','$post_body', '$uniqueFileName',CURRENT_TIMESTAMP, '$user_id', 1);"; $result = $obj->executeQuery($query); // refresh session time diff --git a/verifyAcount.php b/verifyAcount.php index d27450b9a394971298fdfa34de32f8f90d1d3551..1c9dc4cbad544878f67e2afd610b89df83e0cdd6 100644 --- a/verifyAcount.php +++ b/verifyAcount.php @@ -5,8 +5,8 @@ if ($obj->loggedin($obj) && $obj->acountVerified($obj)) { header("Location: index.php"); } -$email = $_GET['email']; -$reset = $_GET['reset']; +// $email = $_GET['email']; +// $reset = $_GET['reset']; $token = $_GET['token']; @@ -19,29 +19,62 @@ if ((isset($_GET['token']) && !empty($token))) { $calculated_hash_of_message = $obj->encrypt(json_encode($json_obj->message)); - // check the generated hash : here we are not sure that the message is not altered + + + // check the generated hash : the message is not altered if (($json_obj->hash_of_message == $calculated_hash_of_message)) { + // if we have created an account and the token time expires + if ($json_obj->reset == 0 && $json_obj->message->validat_until < time()) { + + $email = $json_obj->message->email; + $query = "DELETE FROM users where email ='$email';"; + $result = $obj->executeQuery($query); + echo ' + <div class="verify_account"> + <div class="alert alert-warning" role="alert"> + your token linked with email: ' . $json_obj->message->email . ' has been expired <br> + please recreate your account your account has been deleted by security mesures. + </div> + </div> + '; + + die(); + } else if ($json_obj->reset == 1 && $json_obj->message->validat_until < time()) { + + echo ' + <div class="verify_account"> + <div class="alert alert-warning" role="alert"> + your token linked with email: ' . $json_obj->message->email . ' has been expired <br> + please restart the reset password. + </div> + </div> + '; + + die(); - $target_user = $obj->getUserByEmail($obj, $json_obj->message->email); + } else { - $verify_token = ($json_obj->reset == 1) ? $target_user['password_reset_token'] : $target_user['verify_token']; + $target_user = $obj->getUserByEmail($obj, $json_obj->message->email); - // verify_token and sended token is the same : means that the token is not changed - if ($verify_token == $json_obj->message->token && $target_user['email'] == $json_obj->message->email) { + $verify_token = ($json_obj->reset == 1) ? $target_user['password_reset_token'] : $target_user['verify_token']; - // message is not altered and - $email = $target_user['email']; - $query = "UPDATE users SET active=1, email_verified =1,password_reset_token=null,verify_token=null, verified_at = CURRENT_TIMESTAMP where email = '$email'"; + // verify_token and sended token is the same : means that the token is not changed + if ($verify_token == $json_obj->message->token && $target_user['email'] == $json_obj->message->email) { - $result = $obj->executeQuery($query); + // message is not altered and + $email = $target_user['email']; + + $query = "UPDATE users SET active=1, email_verified =1,password_reset_token=null,verify_token=null, verified_at = CURRENT_TIMESTAMP where email = '$email'"; - $verifed = $obj->connection->affected_rows; + $result = $obj->executeQuery($query); - if ($verifed == 1) { - echo ' + $verifed = $obj->connection->affected_rows; + + if ($verifed == 1) { + echo ' <div class="verify_account"> <div class="alert alert-success" role="alert"> your email: ' . $email . ' has been verified @@ -51,8 +84,8 @@ if ((isset($_GET['token']) && !empty($token))) { '; - } else { - echo ' + } else { + echo ' <div class="verify_account"> <div class="alert alert-danger" role="alert"> error email verification @@ -60,14 +93,19 @@ if ((isset($_GET['token']) && !empty($token))) { </div> '; + } + } } + + + } else { echo ' <div class="verify_account"> <div class="alert alert-danger" role="alert"> - invalid email or token + invalid token </div> </div> '; @@ -77,7 +115,7 @@ if ((isset($_GET['token']) && !empty($token))) { echo ' <div class="verify_account"> <div class="alert alert-danger" role="alert"> - invalid email or token + invalid token </div> </div> ';