Added blocking, started e-mail validation, fixed locale strings

This commit is contained in:
Exynox 2023-07-29 11:43:34 +03:00
parent c26d8e4642
commit 7de2a637c4
13 changed files with 237 additions and 139 deletions

View File

@ -16,8 +16,8 @@ class LoginController extends Controller
public function login(Request $request): RedirectResponse
{
$validator = Validator::make($request->all(), [
'login' => ['required'],
'password' => ['required'],
'login' => 'required|string',
'password' => 'required|string',
]);
if ($validator->fails())
@ -25,19 +25,36 @@ class LoginController extends Controller
$credentials = $validator->validated();
if (Auth::attempt($credentials)) {
$request->session()->regenerate();
$user = Auth::user();
$user->ip = $request->ip();
$user->saveOrFail();
return redirect()->intended('user/administration');
// Validate the credentials
if (!Auth::once($credentials)) {
return redirect('user/login')->withErrors([
'login' => 'The provided credentials do not match our records.',
])->onlyInput('login');
}
return redirect('user/login')->withErrors([
'login' => 'The provided credentials do not match our records.',
])->onlyInput('login');
// The user is now available
$user = Auth::user();
// Check if the user is banned
if ($user->status->isBlocked()) {
Auth::logout();
$request->session()->invalidate();
return redirect('user/login')->withErrors([
'login' => 'Your account is blocked.',
])->onlyInput('login');
}
// Authenticate user
Auth::login($user);
$request->session()->regenerate();
// Save user's IP address
$user->ip = $request->ip();
$user->saveOrFail();
return redirect()->intended('user/administration');
}

View File

@ -21,7 +21,7 @@ class RedirectIfAuthenticated
foreach ($guards as $guard) {
if (Auth::guard($guard)->check()) {
return redirect(RouteServiceProvider::HOME);
return redirect('user/administration');
}
}

View File

@ -2,13 +2,15 @@
namespace App\Models;
// use Illuminate\Contracts\Auth\MustVerifyEmail;
use App\Models\Enums\AccountStatusEnum;
use Illuminate\Auth\Notifications\VerifyEmail;
use Illuminate\Contracts\Auth\MustVerifyEmail;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Foundation\Auth\User;
use Illuminate\Notifications\Notifiable;
use Laravel\Sanctum\HasApiTokens;
class Account extends User
class Account extends User implements MustVerifyEmail
{
use HasApiTokens, HasFactory, Notifiable;
@ -26,9 +28,20 @@ class Account extends User
*/
protected $table = 'account';
const UPDATED_AT = null;
/**
* The name of the "created at" column.
*
* @var string|null
*/
const CREATED_AT = 'create_time';
/**
* The name of the "updated at" column.
*
* @var string|null
*/
const UPDATED_AT = null;
/**
* The attributes that are mass assignable.
*
@ -59,5 +72,48 @@ class Account extends User
protected $casts = [
'email_verified_at' => 'datetime',
'password' => 'hashed',
'status' => AccountStatusEnum::class
];
/**
* Determine if the user has verified their email address.
*
* @return bool
*/
public function hasVerifiedEmail(): bool
{
return $this->status != AccountStatusEnum::NOT_AVAILABLE;
}
/**
* Mark the given user's email as verified.
*
* @return bool
*/
public function markEmailAsVerified(): bool
{
return $this->forceFill([
'status' => AccountStatusEnum::OK,
])->save();
}
/**
* Send the email verification notification.
*
* @return void
*/
public function sendEmailVerificationNotification(): void
{
$this->notify(new VerifyEmail);
}
/**
* Get the email address that should be used for verification.
*
* @return string
*/
public function getEmailForVerification(): string
{
return $this->email;
}
}

View File

@ -0,0 +1,22 @@
<?php
namespace App\Models\Enums;
enum AccountStatusEnum: string
{
case OK = 'OK';
case REPAIR = 'REPAIR';
case BLOCK = 'BLOCK';
case NOT_AVAILABLE = 'NOTAVAIL';
case BILLING_EXPIRED = 'NOBILL';
case BLOCK_LOGIN = 'BLKLOGIN';
case WEB_BLOCK = 'WEBBLK';
public function isBlocked(): bool
{
return match($this) {
self::BLOCK, self::BILLING_EXPIRED, self::BLOCK_LOGIN, self::WEB_BLOCK => true,
default => false,
};
}
}

View File

@ -0,0 +1,18 @@
<div id="progressTracker">
@php($progressTexts = [
1 => 'Înregistrare',
2 => 'Activează și descarcă',
3 => 'Instalează și joacă-te',
])
@for ($i = 1; $i <= 3; $i++)
<div id="progress{{ $i }}" @class([
'inactive' => $step < $i,
'active' => $step == $i,
'passed' => $step > $i,
])>
<div class="step">{{ $i }}</div>
<p class="progress-text">{{ $progressTexts[$i] }}</p>
</div>
@endfor
</div>

View File

@ -175,37 +175,47 @@
<div class="col-3">
<div class="boxes-top">&nbsp;</div>
@guest
<div class="modul-box">
<div class="modul-box-bg">
<div class="modul-box-bg-bottom">
<h3>Logare</h3>
<form action="{{ url('user/login') }}" method="post">
@csrf
<div class="modul-box">
<div class="modul-box-bg">
<div class="modul-box-bg-bottom">
<h3>Logare</h3>
<form action="{{ url('user/login') }}" method="post">
@csrf
<div class="form-login">
<label>Nume de utilizator</label>
<div class="input">
<input type="text" name="login"><br>
</div>
<div class="form-login">
<label>Nume de utilizator</label>
<div class="input">
<input type="text" name="login"><br>
</div>
<label>Parola</label>
<div class="input">
<input type="password" name="password"><br>
<label>Parola</label>
<div class="input">
<input type="password" name="password"><br>
</div>
<div>
<input type="submit" class="button btn-login" value="Login">
<p class="agbok">
Intrând aici, accept <a href="{{ url('legal/terms') }}"><strong>Termenii și condițiile</strong></a>.
<a href="{{ url('user/passwordlostrequest') }}" rel="nofollow" class="password">Ai uitat parola?</a>
<a href="{{ url('user/resendack') }}" rel="nofollow" class="password">Retrimiterea emailului de înregistrare</a>
</p>
</div>
</div>
<div>
<input type="submit" class="button btn-login" value="Login">
<p class="agbok">
Intrând aici, accept <a href="{{ url('legal/terms') }}"><strong>Termenii și condițiile</strong></a>.
<a href="{{ url('user/passwordlostrequest') }}" rel="nofollow" class="password">Ai uitat parola?</a>
<a href="{{ url('user/resendack') }}" rel="nofollow" class="password">Retrimiterea emailului de înregistrare</a>
</p>
</div>
</div>
</form>
</form>
</div>
</div>
</div>
</div>
<div class="boxes-middle"></div>
<div class="modul-box modul-box-2">
<div class="modul-box-bg">
<div class="modul-box-bg-bottom">
<h3>Descărcare</h3>
<a href="{{ url('main/download') }}" class="btn download-btn"></a>
</div>
</div>
</div>
@else
<div class="modul-box modul-box-2">
<div class="modul-box-bg">
@ -216,27 +226,17 @@
</div>
</div>
<div class="boxes-middle">&nbsp;</div>
<div class="modul-box modul-box-2">
<div class="modul-box-bg">
<div class="modul-box-bg-bottom">
<h3>Magazinul de item-uri</h3>
<a href="/is/" class="itemshop btn itemshop-btn iframe" title="Magazinul de item-uri"></a>
@if (Auth::user()->status == \App\Models\Enums\AccountStatusEnum::OK)
<div class="boxes-middle"></div>
<div class="modul-box modul-box-2">
<div class="modul-box-bg">
<div class="modul-box-bg-bottom">
<h3>Magazinul de item-uri</h3>
<a href="/is/" class="itemshop btn itemshop-btn iframe" title="Magazinul de item-uri"></a>
</div>
</div>
</div>
</div>
@endguest
@guest
<div class="boxes-middle">&nbsp;</div>
<div class="modul-box modul-box-2">
<div class="modul-box-bg">
<div class="modul-box-bg-bottom">
<h3>Descărcare</h3>
<a href="{{ url('main/download') }}" class="btn download-btn"></a>
</div>
</div>
</div>
@endif
@endguest
{{--
@ -251,7 +251,7 @@
</div>
--}}
<div class="boxes-middle">&nbsp;</div>
<div class="boxes-middle"></div>
<div class="modul-box modul-box-2">
<div class="modul-box-bg">
<div class="modul-box-bg-bottom">
@ -261,74 +261,8 @@
</div>
</div>
<?php /* <div class="boxes-middle">&nbsp;</div>
<div class="modul-box modul-box-2">
<div class="modul-box-bg">
<div class="modul-box-bg-bottom">
<h3>Jucatori</h3>
<form action="#">
<div class="form-score">
<ul id="highscore">
<?php
$result = mysqli_query($con, "SELECT * FROM `player`.`player` WHERE `name` NOT LIKE '[%]%' ORDER BY `level` DESC, `exp` DESC LIMIT 0, 10");
$rank = 1;
$i = 1;
while($row = mysqli_fetch_array($result)) {
if ($i == 0) {
$i = 1;
echo "<li class=\"light\">";
} else {
$i = 0;
echo "<li>";
}
echo '<strong>' . $rank . '</strong> - <a href="?s=highscore" class="first">' . $row['name'] .'</a></li>';
$rank++;
}
?>
</ul>
<a href="?s=highscore" class="btn">Tot Clasamentul</a>
</div>
</form>
</div>
</div>
</div>
<div class="boxes-middle"></div>
<div class="modul-box modul-box-2">
<div class="modul-box-bg">
<div class="modul-box-bg-bottom">
<h3>Bresle</h3>
<form action="#">
<div class="form-score">
<ul id="guild">
<?php
$result = mysqli_query($con, "SELECT * FROM player.guild WHERE name NOT LIKE '[%]%' ORDER BY level desc, exp desc LIMIT 0, 10");
$rank = 1;
$i = 1;
while($row = mysqli_fetch_array($result)) {
if ($i == 0) {
$i = 1;
echo "<li class=\"light\">";
} else {
$i = 0;
echo "<li>";
}
echo '<strong>' . $rank . '</strong> - <a href="?s=guild" class="first">' . $row['name'] . '</a></li>';
$rank++;
}
?>
</ul>
<a href="?s=guild&search=search&empirechoice=-1&classchoice=-1&characterchoice=" class="btn">Tot Clasamentul</a>
</div>
</form>
</div>
</div>
</div>
<div class="boxes-bottom"></div> */ ?>
<div class="boxes-middle">&nbsp;</div>
<div class="modul-box modul-box-2">
<div class="modul-box-bg">
<div class="modul-box-bg-bottom">

View File

@ -24,7 +24,7 @@
<img src="{{ asset('img/tutorial/1_4.jpg') }}" width="480" height="360" alt="" />
<p class="pager">4/ 4</p>
<p class="txt">Exista 4 clase diferite in joc, fiecare cu caracteristici individuale.<br />
Poti sa te folosesti de sageti pentru a alege clasa. Cand caracterul tau este afisat in fata, poti folosi linkul din cutie (cu verde marcat) pentru a schimba aspectul caracterului prin alegerea intre 1 si 2. Intr-un final caracterul tau are nevoie de un nume. Dupa ce ai ales numele apasa pe " Creaza " pentru a da viata caracterului. Acum poti apasa pe Start pentru a intra in joc.</p>
Poti sa te folosesti de sageti pentru a alege clasa. Cand caracterul tau este afisat in fata, poti folosi linkul din cutie (cu verde marcat) pentru a schimba aspectul caracterului prin alegerea intre 1 si 2. Intr-un final caracterul tau are nevoie de un nume. Dupa ce ai ales numele apasa pe " Creeaza " pentru a da viata caracterului. Acum poti apasa pe Start pentru a intra in joc.</p>
</div>
</div>
</div>

View File

@ -40,7 +40,7 @@
<div id="subscribe">
<h3>Încă nu ai cont?</h3>
<p>Crearea unui jucător (cont) este rapidă, usoară și gratis.</p>
<a class="btn-big" href="{{ url('user/register') }}" title="Crează un cont">Crează un cont</a>
<a class="btn-big" href="{{ url('user/register') }}" title="Creează un cont">Creează un cont</a>
</div>
</div>
</div>

View File

@ -0,0 +1,45 @@
@extends('layouts.app')
@section('content')
<!-- center column -->
<div class="col-2" id="authenticated">
<div class="content content-last">
<div class="content-bg">
<div class="content-bg-bottom">
<h2>Contul tău</h2>
<x-registration.progress :step="2" />
<div class="pass-lost-inner-content">
<div class="input-data-box">
<div id="activateAccount" class="inner-form-border">
<div class="inner-form-box clearfix">
<h3>Activează-ți contul!</h3>
<div class="trenner"></div>
<div id="activateBox">
<p>
Pentru finalizarea înregistrării tale, trebuie îți verificăm adresa
de e-mail. Accesează-ți căsuța de e-mail și urmează link-ul din mesaj pentru activare.
</p>
<p id="resendNormal">
<a href="{{ url('user/resendack') }}">
Nu ai primit un e-mail? Retrimite mailul de activare
</a>
</p>
</div>
<h3>Descarcă jocul</h3>
<div class="trenner"></div>
<a href="{{ url('main/download') }}" id="bigDownload">
Descarcă<br/>jocul acum
</a>
</div>
</div>
</div>
<div class="box-foot"></div>
</div>
</div>
</div>
</div>
<div class="shadow">&nbsp;</div>
</div>
@endsection

View File

@ -23,7 +23,7 @@
</div>
<div class="inner-form-border">
<div class="inner-form-box">
<h3><a id="toLogin" href="{{ url('user/login') }}" title="sau la autentificare">sau la autentificare</a>Crează un cont</h3>
<h3><a id="toLogin" href="{{ url('user/login') }}" title="sau la autentificare">sau la autentificare</a>Creează un cont</h3>
<div class="trenner"></div>
<form name="registerForm" id="registerForm" method="post" action="{{ url('user/register') }}">
<div>

View File

@ -49,18 +49,24 @@ Route::prefix('main')->group(function() {
});
Route::prefix('user')->group(function() {
Route::get('/register', fn () => view('user/register'));
Route::get('/login', fn () => view('user/login'))->name('login');
Route::post('/login', [LoginController::class, 'login']);
// will autocomplete the username
Route::get('/login/{username}', fn ($username) => view('user/login'));
# Registration
Route::get('/register', fn () => view('user/registration/register'))->middleware('guest');
Route::get('/activate', fn () => view('user/registration/activation-pending'))->name('verification.notice');
Route::get('/resendack', fn () => view('user/registration/resendack'));
# Authentication
Route::middleware('guest')->group(function() {
Route::get('/login', fn () => view('user/login'))->name('login');
Route::post('/login', [LoginController::class, 'login']);
// will autocomplete the username
Route::get('/login/{username}', fn ($username) => view('user/login'));
});
Route::get('/logout', [LoginController::class, 'logout']);
Route::get('/passwordlostrequest', fn () => view('user/passwordlostrequest'));
Route::get('/passwordlost/{username}/{hash}', fn ($username, $hash) => view('user/passwordlost-expired'));
Route::get('/resendack', fn () => view('user/resendack'));
Route::middleware('auth')->group(function() {
Route::middleware(['auth', 'verified'])->group(function() {
Route::get('/administration', fn () => view('user/administration'));
Route::get('/characters', fn () => view('user/characters'));