diff --git a/plugins/register/bootstrap.php b/plugins/register/bootstrap.php new file mode 100644 index 0000000..2faab84 --- /dev/null +++ b/plugins/register/bootstrap.php @@ -0,0 +1,22 @@ +register'; +}); diff --git a/plugins/register/controllers/register.php b/plugins/register/controllers/register.php new file mode 100644 index 0000000..bcc3697 --- /dev/null +++ b/plugins/register/controllers/register.php @@ -0,0 +1,110 @@ +sanitizeArray($_POST, ['username', 'password', 'confirm_password', 'csrf_token', 'terms']); + + // Validate CSRF token + if (!$security->verifyCsrfToken($formData['csrf_token'] ?? '')) { + throw new Exception(Feedback::get('ERROR', 'CSRF_INVALID')['message']); + } + + $validator = new Validator($formData); + $rules = [ + 'username' => [ + 'required' => true, + 'min' => 3, + 'max' => 20 + ], + 'password' => [ + 'required' => true, + 'min' => 8, + 'max' => 100 + ], + 'confirm_password' => [ + 'required' => true, + 'matches' => 'password' + ], + 'terms' => [ + 'required' => true, + 'equals' => 'on' + ] + ]; + + $username = $formData['username'] ?? 'unknown'; + + if ($validator->validate($rules)) { + $password = $formData['password']; + + // registering + $register = new Register($db); + $result = $register->register($username, $password); + + // redirect to login + if ($result === true) { + // Get the new user's ID for logging + $userId = $userObject->getUserId($username)[0]['id']; + $logObject->insertLog($userId, "Registration: New user \"$username\" registered successfully. IP: $user_IP", 'user'); + Feedback::flash('NOTICE', 'DEFAULT', "Registration successful. You can log in now."); + header('Location: ' . htmlspecialchars($app_root . '?page=login')); + exit(); + // registration fail, redirect to login + } else { + $logObject->insertLog(null, "Registration: Failed registration attempt for user \"$username\". IP: $user_IP. Reason: $result", 'system'); + Feedback::flash('ERROR', 'DEFAULT', "Registration failed. $result"); + header('Location: ' . htmlspecialchars($app_root . '?page=register')); + exit(); + } + } else { + $error = $validator->getFirstError(); + $logObject->insertLog(null, "Registration: Failed validation for user \"" . ($username ?? 'unknown') . "\". IP: $user_IP. Reason: $error", 'system'); + Feedback::flash('ERROR', 'DEFAULT', $error); + header('Location: ' . htmlspecialchars($app_root . '?page=register')); + exit(); + } + } + } catch (Exception $e) { + $logObject->insertLog(null, "Registration: System error. IP: $user_IP. Error: " . $e->getMessage(), 'system'); + Feedback::flash('ERROR', 'DEFAULT', $e->getMessage()); + } + + // Get any new feedback messages + include dirname(__FILE__, 4) . '/app/helpers/feedback.php'; + + // Load the template + include PLUGIN_REGISTER_PATH . 'views/form-register.php'; + +// registration disabled +} else { + echo Feedback::render('NOTICE', 'DEFAULT', 'Registration is disabled', false); +} diff --git a/plugins/register/models/register.php b/plugins/register/models/register.php new file mode 100644 index 0000000..927187d --- /dev/null +++ b/plugins/register/models/register.php @@ -0,0 +1,92 @@ +db = $database; + } else { + $this->db = $database->getConnection(); + } + require_once dirname(__FILE__, 4) . '/app/classes/ratelimiter.php'; + require_once dirname(__FILE__, 4) . '/app/classes/twoFactorAuth.php'; + + $this->rateLimiter = new RateLimiter($database); + $this->twoFactorAuth = new TwoFactorAuthentication($database); + } + + + /** + * Registers a new user. + * + * @param string $username The username of the new user. + * @param string $password The password for the new user. + * + * @return bool|string True if registration is successful, error message otherwise. + */ + public function register($username, $password) { + try { + // we have two inserts, start a transaction + $this->db->beginTransaction(); + + // hash the password, don't store it plain + $hashedPassword = password_hash($password, PASSWORD_DEFAULT); + + // insert into users table + $sql = 'INSERT + INTO users (username, password) + VALUES (:username, :password)'; + $query = $this->db->prepare($sql); + $query->bindValue(':username', $username); + $query->bindValue(':password', $hashedPassword); + + // execute the first query + if (!$query->execute()) { + // rollback on error + $this->db->rollBack(); + return false; + } + + // insert the last user id into user_meta table + $sql2 = 'INSERT + INTO user_meta (user_id) + VALUES (:user_id)'; + $query2 = $this->db->prepare($sql2); + $query2->bindValue(':user_id', $this->db->lastInsertId()); + + // execute the second query + if (!$query2->execute()) { + // rollback on error + $this->db->rollBack(); + return false; + } + + // if all is OK, commit the transaction + $this->db->commit(); + return true; + + } catch (Exception $e) { + // rollback on any error + $this->db->rollBack(); + return $e->getMessage(); + } + } + +} diff --git a/plugins/register/plugin.json b/plugins/register/plugin.json new file mode 100644 index 0000000..b24df87 --- /dev/null +++ b/plugins/register/plugin.json @@ -0,0 +1,6 @@ +{ + "name": "Registration Plugin", + "version": "1.0.0", + "enabled": true, + "description": "Provides registration functionality as a plugin." +} diff --git a/plugins/register/views/form-register.php b/plugins/register/views/form-register.php new file mode 100644 index 0000000..c6f4050 --- /dev/null +++ b/plugins/register/views/form-register.php @@ -0,0 +1,38 @@ + +
+

Register

+
+

Enter credentials for registration:

+
+ +
+ +
+
+ +
+
+ +
+
+
+ +
+ + We use cookies to improve your experience. See our cookies policy + +
+ +
+
+
+