[CLEAR-22] Implemented users registration, login & retrieving User object. Added integration tests for these endpoints.
This commit is contained in:
parent
d74315a144
commit
aa3938c404
@ -9,9 +9,9 @@ LOG_CHANNEL=stack
|
||||
DB_CONNECTION=mysql
|
||||
DB_HOST=127.0.0.1
|
||||
DB_PORT=3306
|
||||
DB_DATABASE=laravel
|
||||
DB_DATABASE=clearbowl
|
||||
DB_USERNAME=root
|
||||
DB_PASSWORD=
|
||||
DB_PASSWORD=8fcXUlCgC6JCqpoWX64
|
||||
|
||||
BROADCAST_DRIVER=log
|
||||
CACHE_DRIVER=file
|
||||
|
18
Jenkinsfile
vendored
18
Jenkinsfile
vendored
@ -1,17 +1,15 @@
|
||||
pipeline {
|
||||
agent {
|
||||
docker { image 'circleci/php:7.3' }
|
||||
}
|
||||
stages {
|
||||
stage('Build'){
|
||||
steps {
|
||||
sh 'composer install'
|
||||
sh 'cp .env.example .env && php artisan key:generate'
|
||||
cleanWs()
|
||||
docker.image('mysql:latest').withRun('-e "MYSQL_ROOT_PASSWORD=8fcXUlCgC6JCqpoWX64" -e "MYSQL_DATABASE=clearbowl" -e "MYSQL_USER=api" -e "MYSQL_PASSWORD=R23qarINlcALOk2nDg6LbJelaqk"') { c ->
|
||||
docker.image('mysql:latest').inside("--link ${c.id}:db") {
|
||||
stage("Initialize DB"){
|
||||
sh 'while ! mysqladmin ping -hdb --silent; do sleep 1; done'
|
||||
}
|
||||
}
|
||||
stage('Test') {
|
||||
steps {
|
||||
sh 'vendor/bin/phpunit'
|
||||
docker.image('php:7.4').inside("--link ${c.id}:db") {
|
||||
stage("Build") { sh 'composer install && mv .env.example .env'}
|
||||
stage("Test") { sh 'vendor/bin/phpunit' }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
12
app/Enums/UserRole.php
Normal file
12
app/Enums/UserRole.php
Normal file
@ -0,0 +1,12 @@
|
||||
<?php
|
||||
|
||||
|
||||
namespace App\Enums;
|
||||
|
||||
use BenSampo\Enum\Enum;
|
||||
|
||||
final class UserRole extends Enum
|
||||
{
|
||||
const USER = 0;
|
||||
const ADMIN = 1;
|
||||
}
|
@ -1,39 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Controllers\Auth;
|
||||
|
||||
use App\Http\Controllers\Controller;
|
||||
use Illuminate\Foundation\Auth\ConfirmsPasswords;
|
||||
|
||||
class ConfirmPasswordController extends Controller
|
||||
{
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| Confirm Password Controller
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
||||
| This controller is responsible for handling password confirmations and
|
||||
| uses a simple trait to include the behavior. You're free to explore
|
||||
| this trait and override any functions that require customization.
|
||||
|
|
||||
*/
|
||||
|
||||
use ConfirmsPasswords;
|
||||
|
||||
/**
|
||||
* Where to redirect users when the intended url fails.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $redirectTo = '/home';
|
||||
|
||||
/**
|
||||
* Create a new controller instance.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
$this->middleware('auth');
|
||||
}
|
||||
}
|
@ -1,22 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Controllers\Auth;
|
||||
|
||||
use App\Http\Controllers\Controller;
|
||||
use Illuminate\Foundation\Auth\SendsPasswordResetEmails;
|
||||
|
||||
class ForgotPasswordController extends Controller
|
||||
{
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| Password Reset Controller
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
||||
| This controller is responsible for handling password reset emails and
|
||||
| includes a trait which assists in sending these notifications from
|
||||
| your application to your users. Feel free to explore this trait.
|
||||
|
|
||||
*/
|
||||
|
||||
use SendsPasswordResetEmails;
|
||||
}
|
@ -1,39 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Controllers\Auth;
|
||||
|
||||
use App\Http\Controllers\Controller;
|
||||
use Illuminate\Foundation\Auth\AuthenticatesUsers;
|
||||
|
||||
class LoginController extends Controller
|
||||
{
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| Login Controller
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
||||
| This controller handles authenticating users for the application and
|
||||
| redirecting them to your home screen. The controller uses a trait
|
||||
| to conveniently provide its functionality to your applications.
|
||||
|
|
||||
*/
|
||||
|
||||
use AuthenticatesUsers;
|
||||
|
||||
/**
|
||||
* Where to redirect users after login.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $redirectTo = '/home';
|
||||
|
||||
/**
|
||||
* Create a new controller instance.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
$this->middleware('guest')->except('logout');
|
||||
}
|
||||
}
|
@ -1,72 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Controllers\Auth;
|
||||
|
||||
use App\Http\Controllers\Controller;
|
||||
use App\User;
|
||||
use Illuminate\Foundation\Auth\RegistersUsers;
|
||||
use Illuminate\Support\Facades\Hash;
|
||||
use Illuminate\Support\Facades\Validator;
|
||||
|
||||
class RegisterController extends Controller
|
||||
{
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| Register Controller
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
||||
| This controller handles the registration of new users as well as their
|
||||
| validation and creation. By default this controller uses a trait to
|
||||
| provide this functionality without requiring any additional code.
|
||||
|
|
||||
*/
|
||||
|
||||
use RegistersUsers;
|
||||
|
||||
/**
|
||||
* Where to redirect users after registration.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $redirectTo = '/home';
|
||||
|
||||
/**
|
||||
* Create a new controller instance.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
$this->middleware('guest');
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a validator for an incoming registration request.
|
||||
*
|
||||
* @param array $data
|
||||
* @return \Illuminate\Contracts\Validation\Validator
|
||||
*/
|
||||
protected function validator(array $data)
|
||||
{
|
||||
return Validator::make($data, [
|
||||
'name' => ['required', 'string', 'max:255'],
|
||||
'email' => ['required', 'string', 'email', 'max:255', 'unique:users'],
|
||||
'password' => ['required', 'string', 'min:8', 'confirmed'],
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new user instance after a valid registration.
|
||||
*
|
||||
* @param array $data
|
||||
* @return \App\User
|
||||
*/
|
||||
protected function create(array $data)
|
||||
{
|
||||
return User::create([
|
||||
'name' => $data['name'],
|
||||
'email' => $data['email'],
|
||||
'password' => Hash::make($data['password']),
|
||||
]);
|
||||
}
|
||||
}
|
@ -1,29 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Controllers\Auth;
|
||||
|
||||
use App\Http\Controllers\Controller;
|
||||
use Illuminate\Foundation\Auth\ResetsPasswords;
|
||||
|
||||
class ResetPasswordController extends Controller
|
||||
{
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| Password Reset Controller
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
||||
| This controller is responsible for handling password reset requests
|
||||
| and uses a simple trait to include this behavior. You're free to
|
||||
| explore this trait and override any methods you wish to tweak.
|
||||
|
|
||||
*/
|
||||
|
||||
use ResetsPasswords;
|
||||
|
||||
/**
|
||||
* Where to redirect users after resetting their password.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $redirectTo = '/home';
|
||||
}
|
@ -1,41 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Controllers\Auth;
|
||||
|
||||
use App\Http\Controllers\Controller;
|
||||
use Illuminate\Foundation\Auth\VerifiesEmails;
|
||||
|
||||
class VerificationController extends Controller
|
||||
{
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| Email Verification Controller
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
||||
| This controller is responsible for handling email verification for any
|
||||
| user that recently registered with the application. Emails may also
|
||||
| be re-sent if the user didn't receive the original email message.
|
||||
|
|
||||
*/
|
||||
|
||||
use VerifiesEmails;
|
||||
|
||||
/**
|
||||
* Where to redirect users after verification.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $redirectTo = '/home';
|
||||
|
||||
/**
|
||||
* Create a new controller instance.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
$this->middleware('auth');
|
||||
$this->middleware('signed')->only('verify');
|
||||
$this->middleware('throttle:6,1')->only('verify', 'resend');
|
||||
}
|
||||
}
|
100
app/Http/Controllers/UsersController.php
Normal file
100
app/Http/Controllers/UsersController.php
Normal file
@ -0,0 +1,100 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Controllers;
|
||||
|
||||
use App\Http\Requests\LoginRequest;
|
||||
use App\Http\Requests\RegisterRequest;
|
||||
use App\Repositories\UsersRepositoryInterface;
|
||||
use Illuminate\Http\JsonResponse;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Validation\ValidationException;
|
||||
use JWTAuth;
|
||||
use Tymon\JWTAuth\Exceptions\JWTException;
|
||||
use Validator, DB, Hash, Mail;
|
||||
|
||||
class UsersController extends Controller
|
||||
{
|
||||
private UsersRepositoryInterface $usersRepository;
|
||||
|
||||
public function __construct(UsersRepositoryInterface $usersRepository)
|
||||
{
|
||||
$this->usersRepository = $usersRepository;
|
||||
}
|
||||
|
||||
public function register(RegisterRequest $request)
|
||||
{
|
||||
$email = $request->input('email');
|
||||
$password = $request->input('password');
|
||||
|
||||
$this->usersRepository->create([
|
||||
'email' => $email,
|
||||
'password' => bcrypt($password),
|
||||
]);
|
||||
|
||||
$token = auth()->attempt($request->only(['email', 'password']));
|
||||
|
||||
return response()->json([
|
||||
'success' => true,
|
||||
'data' => ['token' => $token]
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* API Login, on success return JWT Auth token
|
||||
*
|
||||
* @param LoginRequest $request
|
||||
* @return JsonResponse
|
||||
*/
|
||||
public function login(LoginRequest $request)
|
||||
{
|
||||
|
||||
if (!$request->validated()) {
|
||||
return response()->json(['success' => false, 'error' => $request->messages()], 401);
|
||||
}
|
||||
|
||||
try {
|
||||
if (!$token = auth()->attempt($request->only('email', 'password'))) {
|
||||
return response()->json(['success' => false, 'error' => 'We cant find an account with this credentials. Please make sure you entered the right information and you have verified your email address.'], 404);
|
||||
}
|
||||
} catch (JWTException $e) {
|
||||
// something went wrong whilst attempting to encode the token
|
||||
return response()->json(['success' => false, 'error' => 'Failed to login, please try again.'], 500);
|
||||
}
|
||||
// all good so return the token
|
||||
return response()->json(['success' => true, 'data' => ['token' => $token]], 200);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Log out
|
||||
* Invalidate the token, so user cannot use it anymore
|
||||
* They have to login again to get a new token
|
||||
*
|
||||
* @param Request $request
|
||||
* @return JsonResponse
|
||||
* @throws ValidationException
|
||||
*/
|
||||
public function logout(Request $request)
|
||||
{
|
||||
$this->validate($request, ['token' => 'required']);
|
||||
|
||||
try {
|
||||
auth()->invalidate($request->input('token'));
|
||||
return response()->json(['success' => true, 'message' => "You have successfully logged out."]);
|
||||
} catch (JWTException $e) {
|
||||
// something went wrong whilst attempting to encode the token
|
||||
return response()->json(['success' => false, 'error' => 'Failed to logout, please try again.'], 500);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public function me()
|
||||
{
|
||||
$requestedBy = auth()->user();
|
||||
|
||||
return response()->json([
|
||||
'success' => true, 'data' => $requestedBy
|
||||
]);
|
||||
}
|
||||
|
||||
}
|
@ -51,16 +51,20 @@ class Kernel extends HttpKernel
|
||||
* @var array
|
||||
*/
|
||||
protected $routeMiddleware = [
|
||||
'assign.guard.auth' => \App\Http\Middleware\AssignGuardAndAuthenticate::class,
|
||||
'assign.guard' => \App\Http\Middleware\AssignGuardOnly::class,
|
||||
'auth' => \App\Http\Middleware\Authenticate::class,
|
||||
'auth.basic' => \Illuminate\Auth\Middleware\AuthenticateWithBasicAuth::class,
|
||||
'bindings' => \Illuminate\Routing\Middleware\SubstituteBindings::class,
|
||||
'cache.headers' => \Illuminate\Http\Middleware\SetCacheHeaders::class,
|
||||
'can' => \Illuminate\Auth\Middleware\Authorize::class,
|
||||
'guest' => \App\Http\Middleware\RedirectIfAuthenticated::class,
|
||||
'password.confirm' => \Illuminate\Auth\Middleware\RequirePassword::class,
|
||||
'signed' => \Illuminate\Routing\Middleware\ValidateSignature::class,
|
||||
'throttle' => \Illuminate\Routing\Middleware\ThrottleRequests::class,
|
||||
'verified' => \Illuminate\Auth\Middleware\EnsureEmailIsVerified::class,
|
||||
'jwt.auth' => 'Tymon\JWTAuth\Middleware\GetUserFromToken',
|
||||
'jwt.refresh' => 'Tymon\JWTAuth\Middleware\RefreshToken',
|
||||
|
||||
];
|
||||
|
||||
/**
|
||||
|
29
app/Http/Middleware/AssignGuardAndAuthenticate.php
Normal file
29
app/Http/Middleware/AssignGuardAndAuthenticate.php
Normal file
@ -0,0 +1,29 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Middleware;
|
||||
|
||||
use Closure;
|
||||
use Illuminate\Auth\Access\AuthorizationException;
|
||||
use Illuminate\Http\Request;
|
||||
|
||||
class AssignGuardAndAuthenticate
|
||||
{
|
||||
/**
|
||||
* Handle an incoming request.
|
||||
*
|
||||
* @param Request $request
|
||||
* @param Closure $next
|
||||
* @param null $guard
|
||||
* @return mixed
|
||||
* @throws AuthorizationException exception
|
||||
*/
|
||||
public function handle($request, Closure $next, $guard = null)
|
||||
{
|
||||
if($guard != null) {
|
||||
auth()->shouldUse($guard);
|
||||
if (!auth()->check())
|
||||
return abort(401);
|
||||
}
|
||||
return $next($request);
|
||||
}
|
||||
}
|
27
app/Http/Middleware/AssignGuardOnly.php
Normal file
27
app/Http/Middleware/AssignGuardOnly.php
Normal file
@ -0,0 +1,27 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Middleware;
|
||||
|
||||
use Closure;
|
||||
use Illuminate\Auth\Access\AuthorizationException;
|
||||
use Illuminate\Http\Request;
|
||||
|
||||
class AssignGuardOnly
|
||||
{
|
||||
/**
|
||||
* Handle an incoming request.
|
||||
*
|
||||
* @param Request $request
|
||||
* @param Closure $next
|
||||
* @param null $guard
|
||||
* @return mixed
|
||||
* @throws AuthorizationException exception
|
||||
*/
|
||||
public function handle($request, Closure $next, $guard = null)
|
||||
{
|
||||
if($guard != null) {
|
||||
auth()->shouldUse($guard);
|
||||
}
|
||||
return $next($request);
|
||||
}
|
||||
}
|
39
app/Http/Requests/LoginRequest.php
Normal file
39
app/Http/Requests/LoginRequest.php
Normal file
@ -0,0 +1,39 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Requests;
|
||||
|
||||
use Illuminate\Foundation\Http\FormRequest;
|
||||
|
||||
class LoginRequest extends FormRequest
|
||||
{
|
||||
/**
|
||||
* Determine if the user is authorized to make this request.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function authorize()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the validation rules that apply to the request.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function rules()
|
||||
{
|
||||
return [
|
||||
'email' => 'required|email',
|
||||
'password' => 'required',
|
||||
];
|
||||
}
|
||||
|
||||
public function messages()
|
||||
{
|
||||
return [
|
||||
'email.required' => 'Email is required',
|
||||
'password.required' => 'Password is required',
|
||||
];
|
||||
}
|
||||
}
|
39
app/Http/Requests/RegisterRequest.php
Normal file
39
app/Http/Requests/RegisterRequest.php
Normal file
@ -0,0 +1,39 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Requests;
|
||||
|
||||
use Illuminate\Foundation\Http\FormRequest;
|
||||
|
||||
class RegisterRequest extends FormRequest
|
||||
{
|
||||
/**
|
||||
* Determine if the user is authorized to make this request.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function authorize()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the validation rules that apply to the request.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function rules()
|
||||
{
|
||||
return [
|
||||
'email' => 'required|email',
|
||||
'password' => 'required',
|
||||
];
|
||||
}
|
||||
|
||||
public function messages()
|
||||
{
|
||||
return [
|
||||
'email.required' => 'Email is required',
|
||||
'password.required' => 'Password is required',
|
||||
];
|
||||
}
|
||||
}
|
46
app/Models/User.php
Normal file
46
app/Models/User.php
Normal file
@ -0,0 +1,46 @@
|
||||
<?php
|
||||
|
||||
namespace App\Models;
|
||||
|
||||
use Illuminate\Foundation\Auth\User as Authenticatable;
|
||||
use Tymon\JWTAuth\Contracts\JWTSubject;
|
||||
|
||||
class User extends Authenticatable implements JWTSubject
|
||||
{
|
||||
/**
|
||||
* The attributes that are mass assignable.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected array $fillable = [
|
||||
'email', 'password', 'role'
|
||||
];
|
||||
|
||||
/**
|
||||
* The attributes that should be hidden for arrays.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected array $hidden = [
|
||||
'password', 'created_at', 'updated_at'
|
||||
];
|
||||
|
||||
/**
|
||||
* Get the identifier that will be stored in the subject claim of the JWT.
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public function getJWTIdentifier()
|
||||
{
|
||||
return $this->getKey();
|
||||
}
|
||||
/**
|
||||
* Return a key value array, containing any custom claims to be added to the JWT.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getJWTCustomClaims()
|
||||
{
|
||||
return [];
|
||||
}
|
||||
}
|
93
app/Policies/UserPolicy.php
Normal file
93
app/Policies/UserPolicy.php
Normal file
@ -0,0 +1,93 @@
|
||||
<?php
|
||||
|
||||
namespace App\Policies;
|
||||
|
||||
use App\Models\User;
|
||||
use Illuminate\Auth\Access\HandlesAuthorization;
|
||||
|
||||
class UserPolicy
|
||||
{
|
||||
use HandlesAuthorization;
|
||||
|
||||
/**
|
||||
* Determine whether the user can view any models.
|
||||
*
|
||||
* @param \App\Models\User $user
|
||||
* @return mixed
|
||||
*/
|
||||
public function viewAny(User $user)
|
||||
{
|
||||
return $user->type >= 128;
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine whether the user can view the model.
|
||||
*
|
||||
* @param \App\Models\User $user
|
||||
* @param \App\Models\User $model
|
||||
* @return mixed
|
||||
*/
|
||||
public function view(User $user, User $model)
|
||||
{
|
||||
return $user->type >= 128;
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine whether the user can create models.
|
||||
*
|
||||
* @param \App\Models\User $user
|
||||
* @return mixed
|
||||
*/
|
||||
public function create(User $user)
|
||||
{
|
||||
return $user->type >= 128;
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine whether the user can update the model.
|
||||
*
|
||||
* @param \App\Models\User $user
|
||||
* @param \App\Models\User $model
|
||||
* @return mixed
|
||||
*/
|
||||
public function update(User $user, User $model)
|
||||
{
|
||||
return $user->type >= 128;
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine whether the user can delete the model.
|
||||
*
|
||||
* @param \App\Models\User $user
|
||||
* @param \App\Models\User $model
|
||||
* @return mixed
|
||||
*/
|
||||
public function delete(User $user, User $model)
|
||||
{
|
||||
return $user->type >= 128;
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine whether the user can restore the model.
|
||||
*
|
||||
* @param \App\Models\User $user
|
||||
* @param \App\Models\User $model
|
||||
* @return mixed
|
||||
*/
|
||||
public function restore(User $user, User $model)
|
||||
{
|
||||
return $user->type >= 128;
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine whether the user can permanently delete the model.
|
||||
*
|
||||
* @param \App\Models\User $user
|
||||
* @param \App\Models\User $model
|
||||
* @return mixed
|
||||
*/
|
||||
public function forceDelete(User $user, User $model)
|
||||
{
|
||||
return $user->type >= 128;
|
||||
}
|
||||
}
|
@ -3,6 +3,7 @@
|
||||
namespace App\Providers;
|
||||
|
||||
use Illuminate\Support\ServiceProvider;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
|
||||
class AppServiceProvider extends ServiceProvider
|
||||
{
|
||||
@ -23,6 +24,6 @@ class AppServiceProvider extends ServiceProvider
|
||||
*/
|
||||
public function boot()
|
||||
{
|
||||
//
|
||||
Schema::defaultStringLength(191);
|
||||
}
|
||||
}
|
||||
|
@ -2,8 +2,9 @@
|
||||
|
||||
namespace App\Providers;
|
||||
|
||||
use App\Models\User;
|
||||
use App\Policies\UserPolicy;
|
||||
use Illuminate\Foundation\Support\Providers\AuthServiceProvider as ServiceProvider;
|
||||
use Illuminate\Support\Facades\Gate;
|
||||
|
||||
class AuthServiceProvider extends ServiceProvider
|
||||
{
|
||||
@ -13,7 +14,8 @@ class AuthServiceProvider extends ServiceProvider
|
||||
* @var array
|
||||
*/
|
||||
protected $policies = [
|
||||
// 'App\Model' => 'App\Policies\ModelPolicy',
|
||||
'App\Model' => 'App\Policies\ModelPolicy',
|
||||
User::class => UserPolicy::class,
|
||||
];
|
||||
|
||||
/**
|
||||
@ -24,7 +26,5 @@ class AuthServiceProvider extends ServiceProvider
|
||||
public function boot()
|
||||
{
|
||||
$this->registerPolicies();
|
||||
|
||||
//
|
||||
}
|
||||
}
|
||||
|
30
app/Providers/RepositoriesServiceProvider.php
Normal file
30
app/Providers/RepositoriesServiceProvider.php
Normal file
@ -0,0 +1,30 @@
|
||||
<?php
|
||||
|
||||
namespace App\Providers;
|
||||
|
||||
use App\Repositories\UsersRepository;
|
||||
use App\Repositories\UsersRepositoryInterface;
|
||||
use Illuminate\Support\ServiceProvider;
|
||||
|
||||
class RepositoriesServiceProvider extends ServiceProvider
|
||||
{
|
||||
/**
|
||||
* Register services.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function register()
|
||||
{
|
||||
//
|
||||
}
|
||||
|
||||
/**
|
||||
* Bootstrap services.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function boot()
|
||||
{
|
||||
$this->app->bind(UsersRepositoryInterface::class, UsersRepository::class);
|
||||
}
|
||||
}
|
@ -25,6 +25,8 @@ class RouteServiceProvider extends ServiceProvider
|
||||
{
|
||||
//
|
||||
|
||||
Route::pattern('id', '[0-9]+');
|
||||
|
||||
parent::boot();
|
||||
}
|
||||
|
||||
|
42
app/Repositories/UsersRepository.php
Normal file
42
app/Repositories/UsersRepository.php
Normal file
@ -0,0 +1,42 @@
|
||||
<?php
|
||||
|
||||
|
||||
namespace App\Repositories;
|
||||
|
||||
|
||||
use App\Models\User;
|
||||
|
||||
class UsersRepository implements UsersRepositoryInterface
|
||||
{
|
||||
public function getAll()
|
||||
{
|
||||
return User::all();
|
||||
}
|
||||
|
||||
public function paginate($chunkSize)
|
||||
{
|
||||
return User::paginate($chunkSize);
|
||||
}
|
||||
|
||||
public function create($data)
|
||||
{
|
||||
return User::create($data);
|
||||
}
|
||||
|
||||
public function delete($id)
|
||||
{
|
||||
$user = User::find($id);
|
||||
return $user->delete();
|
||||
}
|
||||
|
||||
public function getById($id)
|
||||
{
|
||||
$user = User::find($id);
|
||||
return $user;
|
||||
}
|
||||
|
||||
public function getWhereEquals($field, $actual)
|
||||
{
|
||||
return User::where($field, $actual);
|
||||
}
|
||||
}
|
51
app/Repositories/UsersRepositoryInterface.php
Normal file
51
app/Repositories/UsersRepositoryInterface.php
Normal file
@ -0,0 +1,51 @@
|
||||
<?php
|
||||
|
||||
namespace App\Repositories;
|
||||
|
||||
use App\Models\User;
|
||||
use Illuminate\Database\Eloquent\Collection;
|
||||
|
||||
interface UsersRepositoryInterface
|
||||
{
|
||||
/**
|
||||
* Get all Users.
|
||||
* @return User[]|Collection
|
||||
*/
|
||||
public function getAll();
|
||||
|
||||
/**
|
||||
* Paginate Users, chunkSize is the size of one page.
|
||||
* @param $chunkSize
|
||||
* @return mixed
|
||||
*/
|
||||
public function paginate($chunkSize);
|
||||
|
||||
/**
|
||||
* Create user with given data.
|
||||
* @param $data
|
||||
* @return mixed
|
||||
*/
|
||||
public function create($data);
|
||||
|
||||
/**
|
||||
* Delete user with given id.
|
||||
* @param $id
|
||||
* @return mixed
|
||||
*/
|
||||
public function delete($id);
|
||||
|
||||
/**
|
||||
* Get user by id.
|
||||
* @param $userId
|
||||
* @return mixed
|
||||
*/
|
||||
public function getById($userId);
|
||||
|
||||
/**
|
||||
* Get the users where $field is equal to $actual.
|
||||
* @param $field
|
||||
* @param $actual
|
||||
* @return mixed
|
||||
*/
|
||||
public function getWhereEquals($field, $actual);
|
||||
}
|
48
app/Traits/HasCompositeKey.php
Normal file
48
app/Traits/HasCompositeKey.php
Normal file
@ -0,0 +1,48 @@
|
||||
<?php
|
||||
|
||||
|
||||
namespace App\Traits;
|
||||
|
||||
use Illuminate\Database\Eloquent\Builder;
|
||||
|
||||
trait HasCompositeKey
|
||||
{
|
||||
/**
|
||||
* Set the keys for a save update query.
|
||||
*
|
||||
* @param \Illuminate\Database\Eloquent\Builder $query
|
||||
* @return \Illuminate\Database\Eloquent\Builder
|
||||
*/
|
||||
protected function setKeysForSaveQuery(Builder $query)
|
||||
{
|
||||
$keys = $this->getKeyName();
|
||||
if (!is_array($keys)) {
|
||||
return parent::setKeysForSaveQuery($query);
|
||||
}
|
||||
|
||||
foreach ($keys as $keyName) {
|
||||
$query->where($keyName, '=', $this->getKeyForSaveQuery($keyName));
|
||||
}
|
||||
|
||||
return $query;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the primary key value for a save query.
|
||||
*
|
||||
* @param mixed $keyName
|
||||
* @return mixed
|
||||
*/
|
||||
protected function getKeyForSaveQuery($keyName = null)
|
||||
{
|
||||
if (is_null($keyName)) {
|
||||
$keyName = $this->getKeyName();
|
||||
}
|
||||
|
||||
if (isset($this->original[$keyName])) {
|
||||
return $this->original[$keyName];
|
||||
}
|
||||
|
||||
return $this->getAttribute($keyName);
|
||||
}
|
||||
}
|
39
app/User.php
39
app/User.php
@ -1,39 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace App;
|
||||
|
||||
use Illuminate\Contracts\Auth\MustVerifyEmail;
|
||||
use Illuminate\Foundation\Auth\User as Authenticatable;
|
||||
use Illuminate\Notifications\Notifiable;
|
||||
|
||||
class User extends Authenticatable
|
||||
{
|
||||
use Notifiable;
|
||||
|
||||
/**
|
||||
* The attributes that are mass assignable.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $fillable = [
|
||||
'name', 'email', 'password',
|
||||
];
|
||||
|
||||
/**
|
||||
* The attributes that should be hidden for arrays.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $hidden = [
|
||||
'password', 'remember_token',
|
||||
];
|
||||
|
||||
/**
|
||||
* The attributes that should be cast to native types.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $casts = [
|
||||
'email_verified_at' => 'datetime',
|
||||
];
|
||||
}
|
@ -1,17 +1,20 @@
|
||||
{
|
||||
"name": "laravel/laravel",
|
||||
"name": "jwtauth/laravel",
|
||||
"type": "project",
|
||||
"description": "The Laravel Framework.",
|
||||
"description": "The JWT authenticate api in Laravel 6 template.",
|
||||
"keywords": [
|
||||
"framework",
|
||||
"laravel"
|
||||
],
|
||||
"license": "MIT",
|
||||
"require": {
|
||||
"php": "^7.2",
|
||||
"php": "^7.4",
|
||||
"bensampo/laravel-enum": "^1.26",
|
||||
"fideloper/proxy": "^4.0",
|
||||
"laravel/framework": "^6.2",
|
||||
"laravel/tinker": "^1.0"
|
||||
"hesto/multi-auth": "^2.0",
|
||||
"laravel/framework": "6.0",
|
||||
"laravel/tinker": "^1.0",
|
||||
"tymon/jwt-auth": "^1.0"
|
||||
},
|
||||
"require-dev": {
|
||||
"facade/ignition": "^1.4",
|
||||
|
1185
composer.lock
generated
1185
composer.lock
generated
File diff suppressed because it is too large
Load Diff
@ -80,7 +80,7 @@ return [
|
||||
|
|
||||
*/
|
||||
|
||||
'locale' => 'en',
|
||||
'locale' => 'pl',
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
@ -174,6 +174,12 @@ return [
|
||||
// App\Providers\BroadcastServiceProvider::class,
|
||||
App\Providers\EventServiceProvider::class,
|
||||
App\Providers\RouteServiceProvider::class,
|
||||
App\Providers\RepositoriesServiceProvider::class,
|
||||
|
||||
/*
|
||||
* JWT-auth provider
|
||||
*/
|
||||
Tymon\JWTAuth\Providers\LaravelServiceProvider::class,
|
||||
|
||||
],
|
||||
|
||||
@ -226,6 +232,9 @@ return [
|
||||
'Validator' => Illuminate\Support\Facades\Validator::class,
|
||||
'View' => Illuminate\Support\Facades\View::class,
|
||||
|
||||
'JWTAuth' => Tymon\JWTAuth\Facades\JWTAuth::class,
|
||||
'JWTFactory' => Tymon\JWTAuth\Facades\JWTFactory::class,
|
||||
|
||||
],
|
||||
|
||||
];
|
||||
|
@ -14,7 +14,7 @@ return [
|
||||
*/
|
||||
|
||||
'defaults' => [
|
||||
'guard' => 'web',
|
||||
'guard' => 'users',
|
||||
'passwords' => 'users',
|
||||
],
|
||||
|
||||
@ -36,16 +36,10 @@ return [
|
||||
*/
|
||||
|
||||
'guards' => [
|
||||
'web' => [
|
||||
'driver' => 'session',
|
||||
'users' => [
|
||||
'driver' => 'jwt',
|
||||
'provider' => 'users',
|
||||
],
|
||||
|
||||
'api' => [
|
||||
'driver' => 'token',
|
||||
'provider' => 'users',
|
||||
'hash' => false,
|
||||
],
|
||||
],
|
||||
|
||||
/*
|
||||
@ -68,13 +62,8 @@ return [
|
||||
'providers' => [
|
||||
'users' => [
|
||||
'driver' => 'eloquent',
|
||||
'model' => App\User::class,
|
||||
'model' => App\Models\User::class,
|
||||
],
|
||||
|
||||
// 'users' => [
|
||||
// 'driver' => 'database',
|
||||
// 'table' => 'users',
|
||||
// ],
|
||||
],
|
||||
|
||||
/*
|
||||
@ -95,23 +84,9 @@ return [
|
||||
'passwords' => [
|
||||
'users' => [
|
||||
'provider' => 'users',
|
||||
'table' => 'password_resets',
|
||||
'table' => 'user_password_resets',
|
||||
'expire' => 60,
|
||||
'throttle' => 60,
|
||||
],
|
||||
],
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| Password Confirmation Timeout
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
||||
| Here you may define the amount of seconds before a password confirmation
|
||||
| times out and the user is prompted to re-enter their password via the
|
||||
| confirmation screen. By default, the timeout lasts for three hours.
|
||||
|
|
||||
*/
|
||||
|
||||
'password_timeout' => 10800,
|
||||
|
||||
];
|
||||
|
@ -44,7 +44,7 @@ return [
|
||||
*/
|
||||
|
||||
'argon' => [
|
||||
'memory' => 1024,
|
||||
'memory' => 8192,
|
||||
'threads' => 2,
|
||||
'time' => 2,
|
||||
],
|
||||
|
304
config/jwt.php
Normal file
304
config/jwt.php
Normal file
@ -0,0 +1,304 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of jwt-auth.
|
||||
*
|
||||
* (c) Sean Tymon <tymon148@gmail.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
return [
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| JWT Authentication Secret
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
||||
| Don't forget to set this in your .env file, as it will be used to sign
|
||||
| your tokens. A helper command is provided for this:
|
||||
| `php artisan jwt:secret`
|
||||
|
|
||||
| Note: This will be used for Symmetric algorithms only (HMAC),
|
||||
| since RSA and ECDSA use a private/public key combo (See below).
|
||||
|
|
||||
*/
|
||||
|
||||
'secret' => env('JWT_SECRET'),
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| JWT Authentication Keys
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
||||
| The algorithm you are using, will determine whether your tokens are
|
||||
| signed with a random string (defined in `JWT_SECRET`) or using the
|
||||
| following public & private keys.
|
||||
|
|
||||
| Symmetric Algorithms:
|
||||
| HS256, HS384 & HS512 will use `JWT_SECRET`.
|
||||
|
|
||||
| Asymmetric Algorithms:
|
||||
| RS256, RS384 & RS512 / ES256, ES384 & ES512 will use the keys below.
|
||||
|
|
||||
*/
|
||||
|
||||
'keys' => [
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| Public Key
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
||||
| A path or resource to your public key.
|
||||
|
|
||||
| E.g. 'file://path/to/public/key'
|
||||
|
|
||||
*/
|
||||
|
||||
'public' => env('JWT_PUBLIC_KEY'),
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| Private Key
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
||||
| A path or resource to your private key.
|
||||
|
|
||||
| E.g. 'file://path/to/private/key'
|
||||
|
|
||||
*/
|
||||
|
||||
'private' => env('JWT_PRIVATE_KEY'),
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| Passphrase
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
||||
| The passphrase for your private key. Can be null if none set.
|
||||
|
|
||||
*/
|
||||
|
||||
'passphrase' => env('JWT_PASSPHRASE'),
|
||||
|
||||
],
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| JWT time to live
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
||||
| Specify the length of time (in minutes) that the token will be valid for.
|
||||
| Defaults to 1 hour.
|
||||
|
|
||||
| You can also set this to null, to yield a never expiring token.
|
||||
| Some people may want this behaviour for e.g. a mobile app.
|
||||
| This is not particularly recommended, so make sure you have appropriate
|
||||
| systems in place to revoke the token if necessary.
|
||||
| Notice: If you set this to null you should remove 'exp' element from 'required_claims' list.
|
||||
|
|
||||
*/
|
||||
|
||||
'ttl' => env('JWT_TTL', 60),
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| Refresh time to live
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
||||
| Specify the length of time (in minutes) that the token can be refreshed
|
||||
| within. I.E. The user can refresh their token within a 2 week window of
|
||||
| the original token being created until they must re-authenticate.
|
||||
| Defaults to 2 weeks.
|
||||
|
|
||||
| You can also set this to null, to yield an infinite refresh time.
|
||||
| Some may want this instead of never expiring tokens for e.g. a mobile app.
|
||||
| This is not particularly recommended, so make sure you have appropriate
|
||||
| systems in place to revoke the token if necessary.
|
||||
|
|
||||
*/
|
||||
|
||||
'refresh_ttl' => env('JWT_REFRESH_TTL', 20160),
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| JWT hashing algorithm
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
||||
| Specify the hashing algorithm that will be used to sign the token.
|
||||
|
|
||||
| See here: https://github.com/namshi/jose/tree/master/src/Namshi/JOSE/Signer/OpenSSL
|
||||
| for possible values.
|
||||
|
|
||||
*/
|
||||
|
||||
'algo' => env('JWT_ALGO', 'HS256'),
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| Required Claims
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
||||
| Specify the required claims that must exist in any token.
|
||||
| A TokenInvalidException will be thrown if any of these claims are not
|
||||
| present in the payload.
|
||||
|
|
||||
*/
|
||||
|
||||
'required_claims' => [
|
||||
'iss',
|
||||
'iat',
|
||||
'exp',
|
||||
'nbf',
|
||||
'sub',
|
||||
'jti',
|
||||
],
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| Persistent Claims
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
||||
| Specify the claim keys to be persisted when refreshing a token.
|
||||
| `sub` and `iat` will automatically be persisted, in
|
||||
| addition to the these claims.
|
||||
|
|
||||
| Note: If a claim does not exist then it will be ignored.
|
||||
|
|
||||
*/
|
||||
|
||||
'persistent_claims' => [
|
||||
// 'foo',
|
||||
// 'bar',
|
||||
],
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| Lock Subject
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
||||
| This will determine whether a `prv` claim is automatically added to
|
||||
| the token. The purpose of this is to ensure that if you have multiple
|
||||
| authentication models e.g. `App\User` & `App\OtherPerson`, then we
|
||||
| should prevent one authentication request from impersonating another,
|
||||
| if 2 tokens happen to have the same id across the 2 different models.
|
||||
|
|
||||
| Under specific circumstances, you may want to disable this behaviour
|
||||
| e.g. if you only have one authentication model, then you would save
|
||||
| a little on token size.
|
||||
|
|
||||
*/
|
||||
|
||||
'lock_subject' => true,
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| Leeway
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
||||
| This property gives the jwt timestamp claims some "leeway".
|
||||
| Meaning that if you have any unavoidable slight clock skew on
|
||||
| any of your servers then this will afford you some level of cushioning.
|
||||
|
|
||||
| This applies to the claims `iat`, `nbf` and `exp`.
|
||||
|
|
||||
| Specify in seconds - only if you know you need it.
|
||||
|
|
||||
*/
|
||||
|
||||
'leeway' => env('JWT_LEEWAY', 0),
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| Blacklist Enabled
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
||||
| In order to invalidate tokens, you must have the blacklist enabled.
|
||||
| If you do not want or need this functionality, then set this to false.
|
||||
|
|
||||
*/
|
||||
|
||||
'blacklist_enabled' => env('JWT_BLACKLIST_ENABLED', true),
|
||||
|
||||
/*
|
||||
| -------------------------------------------------------------------------
|
||||
| Blacklist Grace Period
|
||||
| -------------------------------------------------------------------------
|
||||
|
|
||||
| When multiple concurrent requests are made with the same JWT,
|
||||
| it is possible that some of them fail, due to token regeneration
|
||||
| on every request.
|
||||
|
|
||||
| Set grace period in seconds to prevent parallel request failure.
|
||||
|
|
||||
*/
|
||||
|
||||
'blacklist_grace_period' => env('JWT_BLACKLIST_GRACE_PERIOD', 0),
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| Cookies encryption
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
||||
| By default Laravel encrypt cookies for security reason.
|
||||
| If you decide to not decrypt cookies, you will have to configure Laravel
|
||||
| to not encrypt your cookie token by adding its name into the $except
|
||||
| array available in the middleware "EncryptCookies" provided by Laravel.
|
||||
| see https://laravel.com/docs/master/responses#cookies-and-encryption
|
||||
| for details.
|
||||
|
|
||||
| Set it to true if you want to decrypt cookies.
|
||||
|
|
||||
*/
|
||||
|
||||
'decrypt_cookies' => false,
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| Providers
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
||||
| Specify the various providers used throughout the package.
|
||||
|
|
||||
*/
|
||||
|
||||
'providers' => [
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| JWT Provider
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
||||
| Specify the provider that is used to create and decode the tokens.
|
||||
|
|
||||
*/
|
||||
|
||||
'jwt' => Tymon\JWTAuth\Providers\JWT\Lcobucci::class,
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| Authentication Provider
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
||||
| Specify the provider that is used to authenticate users.
|
||||
|
|
||||
*/
|
||||
|
||||
'auth' => Tymon\JWTAuth\Providers\Auth\Illuminate::class,
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| Storage Provider
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
||||
| Specify the provider that is used to store tokens in the blacklist.
|
||||
|
|
||||
*/
|
||||
|
||||
'storage' => Tymon\JWTAuth\Providers\Storage\Illuminate::class,
|
||||
|
||||
],
|
||||
|
||||
];
|
@ -1,6 +1,5 @@
|
||||
<?php
|
||||
|
||||
use Monolog\Handler\NullHandler;
|
||||
use Monolog\Handler\StreamHandler;
|
||||
use Monolog\Handler\SyslogUdpHandler;
|
||||
|
||||
@ -90,11 +89,6 @@ return [
|
||||
'driver' => 'errorlog',
|
||||
'level' => 'debug',
|
||||
],
|
||||
|
||||
'null' => [
|
||||
'driver' => 'monolog',
|
||||
'handler' => NullHandler::class,
|
||||
],
|
||||
],
|
||||
|
||||
];
|
||||
|
@ -1,7 +1,7 @@
|
||||
<?php
|
||||
|
||||
/** @var \Illuminate\Database\Eloquent\Factory $factory */
|
||||
use App\User;
|
||||
use App\Models\User;
|
||||
use Faker\Generator as Faker;
|
||||
use Illuminate\Support\Str;
|
||||
|
@ -1,32 +0,0 @@
|
||||
<?php
|
||||
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
|
||||
class CreatePasswordResetsTable extends Migration
|
||||
{
|
||||
/**
|
||||
* Run the migrations.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function up()
|
||||
{
|
||||
Schema::create('password_resets', function (Blueprint $table) {
|
||||
$table->string('email')->index();
|
||||
$table->string('token');
|
||||
$table->timestamp('created_at')->nullable();
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Reverse the migrations.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function down()
|
||||
{
|
||||
Schema::dropIfExists('password_resets');
|
||||
}
|
||||
}
|
@ -1,35 +0,0 @@
|
||||
<?php
|
||||
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
|
||||
class CreateFailedJobsTable extends Migration
|
||||
{
|
||||
/**
|
||||
* Run the migrations.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function up()
|
||||
{
|
||||
Schema::create('failed_jobs', function (Blueprint $table) {
|
||||
$table->bigIncrements('id');
|
||||
$table->text('connection');
|
||||
$table->text('queue');
|
||||
$table->longText('payload');
|
||||
$table->longText('exception');
|
||||
$table->timestamp('failed_at')->useCurrent();
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Reverse the migrations.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function down()
|
||||
{
|
||||
Schema::dropIfExists('failed_jobs');
|
||||
}
|
||||
}
|
@ -1,8 +1,9 @@
|
||||
<?php
|
||||
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use App\Enums\UserRole;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
|
||||
class CreateUsersTable extends Migration
|
||||
{
|
||||
@ -15,11 +16,9 @@ class CreateUsersTable extends Migration
|
||||
{
|
||||
Schema::create('users', function (Blueprint $table) {
|
||||
$table->bigIncrements('id');
|
||||
$table->string('name');
|
||||
$table->string('email')->unique();
|
||||
$table->timestamp('email_verified_at')->nullable();
|
||||
$table->string('password');
|
||||
$table->rememberToken();
|
||||
$table->integer('role')->default(UserRole::USER);
|
||||
$table->timestamps();
|
||||
});
|
||||
}
|
@ -11,6 +11,6 @@ class DatabaseSeeder extends Seeder
|
||||
*/
|
||||
public function run()
|
||||
{
|
||||
// $this->call(UsersTableSeeder::class);
|
||||
$this->call(UsersTableSeeder::class);
|
||||
}
|
||||
}
|
||||
|
22
database/seeds/UsersTableSeeder.php
Normal file
22
database/seeds/UsersTableSeeder.php
Normal file
@ -0,0 +1,22 @@
|
||||
<?php
|
||||
|
||||
use Illuminate\Database\Seeder;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
|
||||
class UsersTableSeeder extends Seeder
|
||||
{
|
||||
/**
|
||||
* Run the database seeds.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function run()
|
||||
{
|
||||
DB::table('admin')->insert([
|
||||
'name' => 'adminTargi',
|
||||
'email' => 'adminTargi@poleng.pl',
|
||||
'password' => bcrypt('password'),
|
||||
'type' => 256
|
||||
]);
|
||||
}
|
||||
}
|
21
package.json
21
package.json
@ -1,21 +0,0 @@
|
||||
{
|
||||
"private": true,
|
||||
"scripts": {
|
||||
"dev": "npm run development",
|
||||
"development": "cross-env NODE_ENV=development node_modules/webpack/bin/webpack.js --progress --hide-modules --config=node_modules/laravel-mix/setup/webpack.config.js",
|
||||
"watch": "npm run development -- --watch",
|
||||
"watch-poll": "npm run watch -- --watch-poll",
|
||||
"hot": "cross-env NODE_ENV=development node_modules/webpack-dev-server/bin/webpack-dev-server.js --inline --hot --config=node_modules/laravel-mix/setup/webpack.config.js",
|
||||
"prod": "npm run production",
|
||||
"production": "cross-env NODE_ENV=production node_modules/webpack/bin/webpack.js --no-progress --hide-modules --config=node_modules/laravel-mix/setup/webpack.config.js"
|
||||
},
|
||||
"devDependencies": {
|
||||
"axios": "^0.19",
|
||||
"cross-env": "^5.1",
|
||||
"laravel-mix": "^4.0.7",
|
||||
"lodash": "^4.17.13",
|
||||
"resolve-url-loader": "^2.3.1",
|
||||
"sass": "^1.15.2",
|
||||
"sass-loader": "^7.1.0"
|
||||
}
|
||||
}
|
@ -17,6 +17,5 @@ return [
|
||||
'sent' => 'We have e-mailed your password reset link!',
|
||||
'token' => 'This password reset token is invalid.',
|
||||
'user' => "We can't find a user with that e-mail address.",
|
||||
'throttled' => 'Please wait before retrying.',
|
||||
|
||||
];
|
||||
|
@ -93,7 +93,6 @@ return [
|
||||
'not_in' => 'The selected :attribute is invalid.',
|
||||
'not_regex' => 'The :attribute format is invalid.',
|
||||
'numeric' => 'The :attribute must be a number.',
|
||||
'password' => 'The password is incorrect.',
|
||||
'present' => 'The :attribute field must be present.',
|
||||
'regex' => 'The :attribute format is invalid.',
|
||||
'required' => 'The :attribute field is required.',
|
||||
|
@ -1,100 +0,0 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="{{ str_replace('_', '-', app()->getLocale()) }}">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
|
||||
<title>Laravel</title>
|
||||
|
||||
<!-- Fonts -->
|
||||
<link href="https://fonts.googleapis.com/css?family=Nunito:200,600" rel="stylesheet">
|
||||
|
||||
<!-- Styles -->
|
||||
<style>
|
||||
html, body {
|
||||
background-color: #fff;
|
||||
color: #636b6f;
|
||||
font-family: 'Nunito', sans-serif;
|
||||
font-weight: 200;
|
||||
height: 100vh;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.full-height {
|
||||
height: 100vh;
|
||||
}
|
||||
|
||||
.flex-center {
|
||||
align-items: center;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.position-ref {
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.top-right {
|
||||
position: absolute;
|
||||
right: 10px;
|
||||
top: 18px;
|
||||
}
|
||||
|
||||
.content {
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.title {
|
||||
font-size: 84px;
|
||||
}
|
||||
|
||||
.links > a {
|
||||
color: #636b6f;
|
||||
padding: 0 25px;
|
||||
font-size: 13px;
|
||||
font-weight: 600;
|
||||
letter-spacing: .1rem;
|
||||
text-decoration: none;
|
||||
text-transform: uppercase;
|
||||
}
|
||||
|
||||
.m-b-md {
|
||||
margin-bottom: 30px;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="flex-center position-ref full-height">
|
||||
@if (Route::has('login'))
|
||||
<div class="top-right links">
|
||||
@auth
|
||||
<a href="{{ url('/home') }}">Home</a>
|
||||
@else
|
||||
<a href="{{ route('login') }}">Login</a>
|
||||
|
||||
@if (Route::has('register'))
|
||||
<a href="{{ route('register') }}">Register</a>
|
||||
@endif
|
||||
@endauth
|
||||
</div>
|
||||
@endif
|
||||
|
||||
<div class="content">
|
||||
<div class="title m-b-md">
|
||||
Laravel
|
||||
</div>
|
||||
|
||||
<div class="links">
|
||||
<a href="https://laravel.com/docs">Docs</a>
|
||||
<a href="https://laracasts.com">Laracasts</a>
|
||||
<a href="https://laravel-news.com">News</a>
|
||||
<a href="https://blog.laravel.com">Blog</a>
|
||||
<a href="https://nova.laravel.com">Nova</a>
|
||||
<a href="https://forge.laravel.com">Forge</a>
|
||||
<a href="https://vapor.laravel.com">Vapor</a>
|
||||
<a href="https://github.com/laravel/laravel">GitHub</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
@ -1,18 +1,9 @@
|
||||
<?php
|
||||
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Facades\Route;
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| API Routes
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
||||
| Here is where you can register API routes for your application. These
|
||||
| routes are loaded by the RouteServiceProvider within a group which
|
||||
| is assigned the "api" middleware group. Enjoy building your API!
|
||||
|
|
||||
*/
|
||||
|
||||
Route::middleware('auth:api')->get('/user', function (Request $request) {
|
||||
return $request->user();
|
||||
Route::group(['prefix' => 'user', 'middleware' => ['assign.guard:users']], function () {
|
||||
Route::post('/register', 'UsersController@register');
|
||||
Route::post('/login', 'UsersController@login');
|
||||
Route::get('/me', 'UsersController@me');
|
||||
});
|
||||
|
@ -10,7 +10,3 @@
|
||||
| contains the "web" middleware group. Now create something great!
|
||||
|
|
||||
*/
|
||||
|
||||
Route::get('/', function () {
|
||||
return view('welcome');
|
||||
});
|
||||
|
@ -1,21 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace Tests\Feature;
|
||||
|
||||
use Illuminate\Foundation\Testing\RefreshDatabase;
|
||||
use Tests\TestCase;
|
||||
|
||||
class ExampleTest extends TestCase
|
||||
{
|
||||
/**
|
||||
* A basic test example.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function testBasicTest()
|
||||
{
|
||||
$response = $this->get('/');
|
||||
|
||||
$response->assertStatus(200);
|
||||
}
|
||||
}
|
53
tests/Feature/UsersTest.php
Normal file
53
tests/Feature/UsersTest.php
Normal file
@ -0,0 +1,53 @@
|
||||
<?php
|
||||
|
||||
namespace Tests\Feature;
|
||||
|
||||
use Illuminate\Foundation\Testing\RefreshDatabase;
|
||||
use Tests\TestCase;
|
||||
|
||||
class UsersTest extends TestCase
|
||||
{
|
||||
use RefreshDatabase;
|
||||
|
||||
private array $loginData = ['email' => 'artur.nowakowski@gmail.com', 'password' => 'test123'];
|
||||
|
||||
public function getToken()
|
||||
{
|
||||
$response = $this->post('http://localhost:8000/api/user/login', $this->loginData)->decodeResponseJson();
|
||||
|
||||
return $response['data']['token'];
|
||||
}
|
||||
|
||||
/**
|
||||
* A basic test example.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function testRegistration()
|
||||
{
|
||||
|
||||
$response = $this->post('http://localhost:8000/api/user/register', $this->loginData);
|
||||
|
||||
$response->assertStatus(200);
|
||||
$response->assertJsonStructure(['success', 'data' => ['token']]);
|
||||
}
|
||||
|
||||
public function testLogin()
|
||||
{
|
||||
$this->testRegistration();
|
||||
$response = $this->post('http://localhost:8000/api/user/login', $this->loginData);
|
||||
|
||||
$response->assertStatus(200);
|
||||
$response->assertJsonStructure(['success', 'data' => ['token']]);
|
||||
}
|
||||
|
||||
public function testMe()
|
||||
{
|
||||
$this->testRegistration();
|
||||
$token = $this->getToken();
|
||||
$response = $this->get('http://localhost:8000/api/user/me', ['Authorization' => "Bearer $token"]);
|
||||
|
||||
$response->assertStatus(200);
|
||||
$response->assertJsonStructure(['success', 'data' => ['email', 'role']]);
|
||||
}
|
||||
}
|
@ -1,15 +0,0 @@
|
||||
const mix = require('laravel-mix');
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| Mix Asset Management
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
||||
| Mix provides a clean, fluent API for defining some Webpack build steps
|
||||
| for your Laravel application. By default, we are compiling the Sass
|
||||
| file for the application as well as bundling up all the JS files.
|
||||
|
|
||||
*/
|
||||
|
||||
mix.js('resources/js/app.js', 'public/js')
|
||||
.sass('resources/sass/app.scss', 'public/css');
|
Loading…
Reference in New Issue
Block a user