== Регистрација на нов член == === Актери === * Нов корисник === Чекор 1 === Новиот корисник треба да ја пополни регистрацијата со внесување на лични податоци како што се username, email и password [[Image(BT-Sign-Up.png)]] {{{#!sql beginTransaction(); // Check for existing username $stmt = $conn->prepare("CALL register_user(:username, :email, :password, :role)"); // Hash password $hashed_password = password_hash($input_password, PASSWORD_ARGON2ID, [ 'memory_cost' => 65536, 'time_cost' => 4, 'threads' => 3 ]); $stmt->bindParam(':username', $input_name, PDO::PARAM_STR); $stmt->bindParam(':email', $input_email, PDO::PARAM_STR); $stmt->bindParam(':password', $hashed_password, PDO::PARAM_STR); $stmt->bindParam(':role', $role, PDO::PARAM_STR); $stmt->execute(); // Commit the transaction $conn->commit(); // Set session variables for automatic login session_regenerate_id(true); $_SESSION['username'] = $input_name; $_SESSION['userid'] = $conn->lastInsertId(); $_SESSION['role'] = $role; $_SESSION['last_activity'] = time(); $_SESSION['ip_address'] = $_SERVER['REMOTE_ADDR']; // Redirect to homepage after successful registration header("Location: ./HomePage.php"); exit(); } catch (PDOException $e) { // Roll back the transaction if something failed $conn->rollBack(); error_log("Registration error: " . $e->getMessage()); header("Location: /Sign&Log.php?error=SERVER_ERROR"); exit(); } ?> }}} * '''''Се користи POST метод за испраќање на податоците од формата. Кодот врши основна валидација на внесените податоци (email, корисничко име, лозинка) и проверува дали се соодветни (на пр., дали лозинката е доволно силна, дали email-от е валиден). Ако сите податоци се точни, кодот ги чисти и валидира внесените вредности, а потоа ги зачувува во базата на податоци преку SQL процедура (CALL register_user). Лозинката се хашира со PASSWORD_ARGON2ID за подобар ентитет. Ако регистрацијата е успешна, корисникот се логира автоматски и се пренасочува кон почетната страница (HomePage.php). Ако има грешка, корисникот се враќа на страницата за регистрација со соодветна порака за грешка. Се користат сесии за следење на активност и зачувување на корисничките податоци.''''' === Чекор 2 === По успешна регистрација корисникот се најавува со своето корисничко име и лозинка за да да пристапи до платформата. [[Image(BT-Sign-In.png)]] {{{#!sql 5) { $timeout = 300; // 5 minutes timeout if (time() - $_SESSION['last_attempt'] < $timeout) { header("Location: /Sign&Log.php?error=TOO_MANY_ATTEMPTS"); exit(); } else { $_SESSION['login_attempts'] = 0; } } // Input validation if (empty($_POST['username']) || empty($_POST['password'])) { header("Location: /Sign&Log.php?error=INVALID_CREDENTIALS"); exit(); } require 'connect.php'; try { $username = trim(htmlspecialchars($_POST['username'])); $sql = "SELECT * FROM Users WHERE username = :username"; $stmt = $conn->prepare($sql); $stmt->bindParam(':username', $username, PDO::PARAM_STR); $stmt->execute(); if ($stmt->rowCount() <= 0) { $_SESSION['login_attempts'] = isset($_SESSION['login_attempts']) ? $_SESSION['login_attempts'] + 1 : 1; $_SESSION['last_attempt'] = time(); header("Location: /Sign&Log.php?error=INVALID_CREDENTIALS"); exit(); } $res = $stmt->fetch(PDO::FETCH_ASSOC); if (!password_verify($_POST['password'], $res['password'])) { $_SESSION['login_attempts'] = isset($_SESSION['login_attempts']) ? $_SESSION['login_attempts'] + 1 : 1; $_SESSION['last_attempt'] = time(); header("Location: /Sign&Log.php?error=INVALID_CREDENTIALS"); exit(); } $_SESSION['username'] = $username; $_SESSION['userid'] = $res['userid']; $_SESSION['role'] = $res['role']; $_SESSION['last_activity'] = time(); $_SESSION['ip_address'] = $_SERVER['REMOTE_ADDR']; $_SESSION['login_attempts'] = 0; // Redirect based on role if ($res['role'] == 'Admin') { header("Location: ./Admin.php"); } else { header("Location: ./HomePage.php"); } } catch (PDOException $e) { error_log("Login error: " . $e->getMessage()); header("Location: /Sign&Log.php?error=SERVER_ERROR"); exit(); } }}} === Чекор 3 === Преглед на успешен Чекор 2 [[Image(BT-3.1.png)]]