Dragon-Knight/server/modules/GateModule.php

122 lines
3.4 KiB
PHP

<?php
class GateModule
{
private const GUEST = ['login', 'register'];
public static function handle()
{
$s = App::$req->uri(1) ?? ''; // second segment
$m = App::$req->method; // request method
if (App::auth() && in_array($s, self::GUEST)) redirect('/');
if ($s == '' || $s == 'login') return self::login($m);
if ($s == 'logout' && $m == 'POST') return self::logout();
if ($s == 'register') return self::register($m);
}
public static function login(string $method)
{
// just display the login page
if ($method == 'GET') {
echo render('layout', ['title' => 'Login', 'content' => 'gate/login']);
return;
}
// handle the login form
$id = trim($_POST['id'] ?? ''); // identifier; let a user log in with email or username
$pw = $_POST['pw'] ?? ''; // password
// fields are required
if (empty($id) || empty($pw)) {
App::flash('error', 'Please fill out all fields.');
redirect('/gate/login');
}
// find the user, login if valid
$found = App::$auth->login($id, $pw, isset($_POST['remember']));
// Login is valid!
if ($found) {
App::flash('success', 'Welcome back!');
redirect('/');
} else {
App::flash('error', 'Player account not found.');
redirect('/gate/login');
}
}
private static function logout()
{
App::$auth->logout();
App::flash('success', 'You have been logged out.');
redirect('/');
}
private static function register(string $method)
{
// just display the register page
if ($method == 'GET') {
echo render('layout', ['title' => 'Register', 'content' => 'gate/register']);
return;
}
// handle the register form
$un = trim($_POST['username'] ?? '');
$em = trim($_POST['email'] ?? '');
$pw = $_POST['password'] ?? '';
$pw2 = $_POST['password2'] ?? '';
$cl = $_POST['class'] ?? 1;
$errors = [];
// fields are required
if (empty($un)) $errors['un'] = 'Please enter a username.';
if (empty($em)) $errors['em'] = 'Please enter an email address.';
if (empty($pw)) $errors['pw'] = 'Please enter a password.';
if (empty($pw2)) $errors['pw2'] = 'Please confirm your password.';
if (!empty($errors)) {
App::flash('errors', $errors);
redirect('/gate/register');
}
// password must be at least 6 characters
if (strlen($pw) < 6) $errors['pw'] = 'Password must be at least 6 characters.';
// passwords must match
if ($pw != $pw2) $errors['pw2'] = 'Passwords do not match.';
// email address must be valid format
if (!filter_var($em, FILTER_VALIDATE_EMAIL)) $errors['em'] = 'Invalid email address.';
// username must be alphanumeric and between 2 and 20 characters, allow single spaces
if (!Player::goodUsername($un)) $errors['un'] = 'Invalid username. Must be alphanumeric and between 2 and 20 characters, and can contain spaces.';
// username must be unique
if (!Player::uniqueUsername($un)) $errors['un'] = 'Username already exists.';
// email address must be unique
if (!Player::uniqueEmail($em)) $errors['em'] = 'Email address already exists.';
// flash errors and redirect back to form
if (!empty($errors)) {
App::flash('errors', $errors);
redirect('/gate/register');
}
// create the player
Player::create([
'username' => $un,
'email' => $em,
'password' => password_hash($pw, PASSWORD_ARGON2ID),
'class_id' => $cl
]);
// redirect to login
App::flash('success', "You're now an adventurer! Go forth, $un!");
redirect('/gate/login');
}
}