MAPG-115 add login functionality
This commit is contained in:
parent
d93a758cd2
commit
edc2e4111a
@ -12,6 +12,9 @@ if (($pos = strpos($url, '?')) !== false) {
|
||||
$url = rawurldecode($url);
|
||||
|
||||
Container::$routeCollection->get('index', '', [MapGuesser\Controller\HomeController::class, 'getIndex']);
|
||||
Container::$routeCollection->get('login', 'login', [MapGuesser\Controller\LoginController::class, 'getLoginForm']);
|
||||
Container::$routeCollection->post('login-action', 'login', [MapGuesser\Controller\LoginController::class, 'login']);
|
||||
Container::$routeCollection->get('logout', 'logout', [MapGuesser\Controller\LoginController::class, 'logout']);
|
||||
Container::$routeCollection->get('maps', 'maps', [MapGuesser\Controller\MapsController::class, 'getMaps']);
|
||||
Container::$routeCollection->group('game', function (MapGuesser\Routing\RouteCollection $routeCollection) {
|
||||
$routeCollection->get('game', '{mapId}', [MapGuesser\Controller\GameController::class, 'getGame']);
|
||||
|
@ -17,7 +17,7 @@ button::-moz-focus-inner, input::-moz-focus-inner {
|
||||
border: 0;
|
||||
}
|
||||
|
||||
p, h1, h2, button, a {
|
||||
p, h1, h2, input, textarea, select, button, a {
|
||||
font-family: 'Roboto', sans-serif;
|
||||
}
|
||||
|
||||
@ -93,6 +93,10 @@ sub {
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
|
||||
.right {
|
||||
text-align: right;
|
||||
}
|
||||
|
||||
svg.inline, img.inline {
|
||||
display: inline-block;
|
||||
width: 1em;
|
||||
@ -158,6 +162,54 @@ button.red:hover, button.red:focus, a.button.red:hover, a.button.red:focus {
|
||||
background-color: #7f2929;
|
||||
}
|
||||
|
||||
input, select, textarea {
|
||||
background-color: #f9fafb;
|
||||
border: solid #c8d2e1 1px;
|
||||
border-radius: 2px;
|
||||
padding: 4px;
|
||||
box-sizing: border-box;
|
||||
font-size: 15px;
|
||||
font-weight: 300;
|
||||
}
|
||||
|
||||
textarea {
|
||||
font-size: 13px;
|
||||
resize: none;
|
||||
}
|
||||
|
||||
input.big, select.big, textarea.big {
|
||||
padding: 5px;
|
||||
font-size: 18px;
|
||||
}
|
||||
|
||||
input.fullWidth, select.fullWidth, textarea.fullWidth {
|
||||
display: block;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
input:disabled, select:disabled, textarea:disabled {
|
||||
background-color: #dfdfdf;
|
||||
border: solid #dfdfdf 1px;
|
||||
color: #000000;
|
||||
}
|
||||
|
||||
input:focus, select:focus, textarea:focus {
|
||||
background-color: #ffffff;
|
||||
border: solid #29457f 2px;
|
||||
padding: 3px;
|
||||
outline: none;
|
||||
}
|
||||
|
||||
input.big:focus, select.big:focus, textarea.big:focus {
|
||||
padding: 4px;
|
||||
}
|
||||
|
||||
p.formError {
|
||||
color: #7f2929;
|
||||
font-weight: 500;
|
||||
display: none;
|
||||
}
|
||||
|
||||
div.header {
|
||||
background-color: #333333;
|
||||
height: 50px;
|
||||
@ -200,6 +252,15 @@ div.buttonContainer>button {
|
||||
visibility: hidden;
|
||||
}
|
||||
|
||||
div.box {
|
||||
width: 576px;
|
||||
background-color: #eeeeee;
|
||||
border-radius: 3px;
|
||||
margin: 10px auto;
|
||||
padding: 10px;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
@media screen and (max-width: 599px) {
|
||||
div.header.small h1 span {
|
||||
display: none;
|
||||
@ -208,4 +269,7 @@ div.buttonContainer>button {
|
||||
padding: 0;
|
||||
width: 100%;
|
||||
}
|
||||
div.box {
|
||||
width: initial;
|
||||
}
|
||||
}
|
||||
|
42
public/static/js/login.js
Normal file
42
public/static/js/login.js
Normal file
@ -0,0 +1,42 @@
|
||||
(function () {
|
||||
var form = document.getElementById('loginForm');
|
||||
|
||||
form.onsubmit = function (e) {
|
||||
document.getElementById('loading').style.visibility = 'visible';
|
||||
|
||||
e.preventDefault();
|
||||
|
||||
var formData = new FormData(form);
|
||||
|
||||
var xhr = new XMLHttpRequest();
|
||||
xhr.responseType = 'json';
|
||||
xhr.onload = function () {
|
||||
document.getElementById('loading').style.visibility = 'hidden';
|
||||
|
||||
if (this.response.error) {
|
||||
var errorText;
|
||||
switch (this.response.error) {
|
||||
case 'user_not_found':
|
||||
errorText = 'No user found with the given email address.';
|
||||
break;
|
||||
case 'password_not_match':
|
||||
errorText = 'The given password is wrong.'
|
||||
break;
|
||||
}
|
||||
|
||||
var loginFormError = document.getElementById('loginFormError');
|
||||
loginFormError.style.display = 'block';
|
||||
loginFormError.innerHTML = errorText;
|
||||
|
||||
form.elements.email.select();
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
window.location.replace('/');
|
||||
};
|
||||
|
||||
xhr.open('POST', form.action, true);
|
||||
xhr.send(formData);
|
||||
};
|
||||
})();
|
@ -22,9 +22,10 @@ class AddUserCommand extends Command
|
||||
{
|
||||
$user = new User([
|
||||
'email' => $input->getArgument('email'),
|
||||
'password' => $input->getArgument('password')
|
||||
]);
|
||||
|
||||
$user->setPlainPassword($input->getArgument('password'));
|
||||
|
||||
if ($input->hasArgument('type')) {
|
||||
$user->setType($input->getArgument('type'));
|
||||
}
|
||||
|
73
src/Controller/LoginController.php
Normal file
73
src/Controller/LoginController.php
Normal file
@ -0,0 +1,73 @@
|
||||
<?php namespace MapGuesser\Controller;
|
||||
|
||||
use MapGuesser\Database\Query\Select;
|
||||
use MapGuesser\Interfaces\Database\IResultSet;
|
||||
use MapGuesser\Interfaces\Request\IRequest;
|
||||
use MapGuesser\Interfaces\Response\IContent;
|
||||
use MapGuesser\Interfaces\Response\IRedirect;
|
||||
use MapGuesser\Model\User;
|
||||
use MapGuesser\Response\HtmlContent;
|
||||
use MapGuesser\Response\JsonContent;
|
||||
use MapGuesser\Response\Redirect;
|
||||
|
||||
class LoginController
|
||||
{
|
||||
private IRequest $request;
|
||||
|
||||
public function __construct(IRequest $request)
|
||||
{
|
||||
$this->request = $request;
|
||||
}
|
||||
|
||||
public function getLoginForm()
|
||||
{
|
||||
$session = $this->request->session();
|
||||
|
||||
if ($session->get('user')) {
|
||||
return new Redirect([\Container::$routeCollection->getRoute('index'), []], IRedirect::TEMPORARY);
|
||||
}
|
||||
|
||||
$data = [];
|
||||
return new HtmlContent('login', $data);
|
||||
}
|
||||
|
||||
public function login(): IContent
|
||||
{
|
||||
$session = $this->request->session();
|
||||
|
||||
if ($session->get('user')) {
|
||||
$data = ['success' => true];
|
||||
return new JsonContent($data);
|
||||
}
|
||||
|
||||
$select = new Select(\Container::$dbConnection, 'users');
|
||||
$select->columns(User::getFields());
|
||||
$select->where('email', '=', $this->request->post('email'));
|
||||
|
||||
$userData = $select->execute()->fetch(IResultSet::FETCH_ASSOC);
|
||||
|
||||
if ($userData === null) {
|
||||
$data = ['error' => 'user_not_found'];
|
||||
return new JsonContent($data);
|
||||
}
|
||||
|
||||
$user = new User($userData);
|
||||
|
||||
if (!$user->checkPassword($this->request->post('password'))) {
|
||||
$data = ['error' => 'password_not_match'];
|
||||
return new JsonContent($data);
|
||||
}
|
||||
|
||||
$session->set('user', $user);
|
||||
|
||||
$data = ['success' => true];
|
||||
return new JsonContent($data);
|
||||
}
|
||||
|
||||
public function logout(): IRedirect
|
||||
{
|
||||
$this->request->session()->delete('user');
|
||||
|
||||
return new Redirect([\Container::$routeCollection->getRoute('login'), []], IRedirect::TEMPORARY);
|
||||
}
|
||||
}
|
17
views/login.php
Normal file
17
views/login.php
Normal file
@ -0,0 +1,17 @@
|
||||
<?php require ROOT . '/views/templates/main_header.php'; ?>
|
||||
<?php require ROOT . '/views/templates/header.php'; ?>
|
||||
<div class="main">
|
||||
<h2>Login</h2>
|
||||
<div class="box">
|
||||
<form id="loginForm" action="/login" method="post">
|
||||
<input class="big fullWidth" type="email" name="email" placeholder="Email address" autofocus>
|
||||
<input class="big fullWidth marginTop" type="password" name="password" placeholder="Password">
|
||||
<p id="loginFormError" class="formError marginTop"></p>
|
||||
<div class="right marginTop">
|
||||
<button type="submit">Login</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
<script src="/static/js/login.js"></script>
|
||||
<?php require ROOT . '/views/templates/main_footer.php'; ?>
|
Loading…
Reference in New Issue
Block a user