Commit 4dfc5d34 by Triyah Fatmawati

Add Login dan Logout

parent d3988bcd
<?php
namespace App\Actions\Fortify;
use App\Models\User;
use Illuminate\Support\Facades\Hash;
use Illuminate\Support\Facades\Validator;
use Illuminate\Validation\Rule;
use Laravel\Fortify\Contracts\CreatesNewUsers;
class CreateNewUser implements CreatesNewUsers
{
use PasswordValidationRules;
/**
* Validate and create a newly registered user.
*
* @param array<string, string> $input
*/
public function create(array $input): User
{
Validator::make($input, [
'name' => ['required', 'string', 'max:255'],
'email' => [
'required',
'string',
'email',
'max:255',
Rule::unique(User::class),
],
'password' => $this->passwordRules(),
])->validate();
return User::create([
'name' => $input['name'],
'email' => $input['email'],
'password' => Hash::make($input['password']),
]);
}
}
<?php
namespace App\Actions\Fortify;
use Illuminate\Validation\Rules\Password;
trait PasswordValidationRules
{
/**
* Get the validation rules used to validate passwords.
*
* @return array<int, \Illuminate\Contracts\Validation\Rule|array<mixed>|string>
*/
protected function passwordRules(): array
{
return ['required', 'string', Password::default(), 'confirmed'];
}
}
<?php
namespace App\Actions\Fortify;
use App\Models\User;
use Illuminate\Support\Facades\Hash;
use Illuminate\Support\Facades\Validator;
use Laravel\Fortify\Contracts\ResetsUserPasswords;
class ResetUserPassword implements ResetsUserPasswords
{
use PasswordValidationRules;
/**
* Validate and reset the user's forgotten password.
*
* @param array<string, string> $input
*/
public function reset(User $user, array $input): void
{
Validator::make($input, [
'password' => $this->passwordRules(),
])->validate();
$user->forceFill([
'password' => Hash::make($input['password']),
])->save();
}
}
<?php
namespace App\Actions\Fortify;
use App\Models\User;
use Illuminate\Support\Facades\Hash;
use Illuminate\Support\Facades\Validator;
use Laravel\Fortify\Contracts\UpdatesUserPasswords;
class UpdateUserPassword implements UpdatesUserPasswords
{
use PasswordValidationRules;
/**
* Validate and update the user's password.
*
* @param array<string, string> $input
*/
public function update(User $user, array $input): void
{
Validator::make($input, [
'current_password' => ['required', 'string', 'current_password:web'],
'password' => $this->passwordRules(),
], [
'current_password.current_password' => __('The provided password does not match your current password.'),
])->validateWithBag('updatePassword');
$user->forceFill([
'password' => Hash::make($input['password']),
])->save();
}
}
<?php
namespace App\Actions\Fortify;
use App\Models\User;
use Illuminate\Contracts\Auth\MustVerifyEmail;
use Illuminate\Support\Facades\Validator;
use Illuminate\Validation\Rule;
use Laravel\Fortify\Contracts\UpdatesUserProfileInformation;
class UpdateUserProfileInformation implements UpdatesUserProfileInformation
{
/**
* Validate and update the given user's profile information.
*
* @param array<string, string> $input
*/
public function update(User $user, array $input): void
{
Validator::make($input, [
'name' => ['required', 'string', 'max:255'],
'email' => [
'required',
'string',
'email',
'max:255',
Rule::unique('users')->ignore($user->id),
],
])->validateWithBag('updateProfileInformation');
if ($input['email'] !== $user->email &&
$user instanceof MustVerifyEmail) {
$this->updateVerifiedUser($user, $input);
} else {
$user->forceFill([
'name' => $input['name'],
'email' => $input['email'],
])->save();
}
}
/**
* Update the given verified user's profile information.
*
* @param array<string, string> $input
*/
protected function updateVerifiedUser(User $user, array $input): void
{
$user->forceFill([
'name' => $input['name'],
'email' => $input['email'],
'email_verified_at' => null,
])->save();
$user->sendEmailVerificationNotification();
}
}
<?php
namespace App\Http\Controllers\Admin\Auth;
use App\Http\Controllers\Controller;
use Illuminate\Http\RedirectResponse;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
class LoginController extends Controller
{
public function logout(Request $request) : RedirectResponse {
Auth::logout();
$request->session()->invalidate();
$request->session()->regenerateToken();
return redirect('login');
}
}
......@@ -63,5 +63,6 @@ class Kernel extends HttpKernel
'signed' => \App\Http\Middleware\ValidateSignature::class,
'throttle' => \Illuminate\Routing\Middleware\ThrottleRequests::class,
'verified' => \Illuminate\Auth\Middleware\EnsureEmailIsVerified::class,
'prevent-back-history' => \App\Http\Middleware\PreventBackHistory::class,
];
}
<?php
namespace App\Http\Middleware;
use Closure;
use Illuminate\Http\Request;
use Symfony\Component\HttpFoundation\Response;
class PreventBackHistory
{
/**
* Handle an incoming request.
*
* @param \Closure(\Illuminate\Http\Request): (\Symfony\Component\HttpFoundation\Response) $next
*/
public function handle(Request $request, Closure $next): Response
{
// return $next($request);
$response = $next($request);
return $response->header('Cache-Control','nocache, no-store, max-age=0, must-revalidate')
->header('Pragma','no-cache')
->header('Expires','Sun, 02 Jan 1990 00:00:00 GMT');
}
}
<?php
namespace App\Providers;
use App\Actions\Fortify\CreateNewUser;
use App\Actions\Fortify\ResetUserPassword;
use App\Actions\Fortify\UpdateUserPassword;
use App\Actions\Fortify\UpdateUserProfileInformation;
use Illuminate\Cache\RateLimiting\Limit;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\RateLimiter;
use Illuminate\Support\ServiceProvider;
use Illuminate\Support\Str;
use Laravel\Fortify\Fortify;
class FortifyServiceProvider extends ServiceProvider
{
/**
* Register any application services.
*/
public function register(): void
{
//
}
/**
* Bootstrap any application services.
*/
public function boot(): void
{
Fortify::createUsersUsing(CreateNewUser::class);
Fortify::updateUserProfileInformationUsing(UpdateUserProfileInformation::class);
Fortify::updateUserPasswordsUsing(UpdateUserPassword::class);
Fortify::resetUserPasswordsUsing(ResetUserPassword::class);
RateLimiter::for('login', function (Request $request) {
$throttleKey = Str::transliterate(Str::lower($request->input(Fortify::username())).'|'.$request->ip());
return Limit::perMinute(5)->by($throttleKey);
});
RateLimiter::for('two-factor', function (Request $request) {
return Limit::perMinute(5)->by($request->session()->get('login.id'));
});
Fortify::loginView(function(){
return view('Admin.login');
});
}
}
......@@ -7,6 +7,7 @@
"require": {
"php": "^8.1",
"guzzlehttp/guzzle": "^7.2",
"laravel/fortify": "^1.21",
"laravel/framework": "^10.0",
"laravel/sanctum": "^3.2",
"laravel/tinker": "^2.8"
......
......@@ -194,6 +194,7 @@
// App\Providers\BroadcastServiceProvider::class,
App\Providers\EventServiceProvider::class,
App\Providers\RouteServiceProvider::class,
App\Providers\FortifyServiceProvider::class,
],
......
<?php
use Laravel\Fortify\Features;
return [
/*
|--------------------------------------------------------------------------
| Fortify Guard
|--------------------------------------------------------------------------
|
| Here you may specify which authentication guard Fortify will use while
| authenticating users. This value should correspond with one of your
| guards that is already present in your "auth" configuration file.
|
*/
'guard' => 'web',
/*
|--------------------------------------------------------------------------
| Fortify Password Broker
|--------------------------------------------------------------------------
|
| Here you may specify which password broker Fortify can use when a user
| is resetting their password. This configured value should match one
| of your password brokers setup in your "auth" configuration file.
|
*/
'passwords' => 'users',
/*
|--------------------------------------------------------------------------
| Username / Email
|--------------------------------------------------------------------------
|
| This value defines which model attribute should be considered as your
| application's "username" field. Typically, this might be the email
| address of the users but you are free to change this value here.
|
| Out of the box, Fortify expects forgot password and reset password
| requests to have a field named 'email'. If the application uses
| another name for the field you may define it below as needed.
|
*/
'username' => 'email',
'email' => 'email',
/*
|--------------------------------------------------------------------------
| Lowercase Usernames
|--------------------------------------------------------------------------
|
| This value defines whether usernames should be lowercased before saving
| them in the database, as some database system string fields are case
| sensitive. You may disable this for your application if necessary.
|
*/
'lowercase_usernames' => true,
/*
|--------------------------------------------------------------------------
| Home Path
|--------------------------------------------------------------------------
|
| Here you may configure the path where users will get redirected during
| authentication or password reset when the operations are successful
| and the user is authenticated. You are free to change this value.
|
*/
'home' => '/home',
/*
|--------------------------------------------------------------------------
| Fortify Routes Prefix / Subdomain
|--------------------------------------------------------------------------
|
| Here you may specify which prefix Fortify will assign to all the routes
| that it registers with the application. If necessary, you may change
| subdomain under which all of the Fortify routes will be available.
|
*/
'prefix' => '',
'domain' => null,
/*
|--------------------------------------------------------------------------
| Fortify Routes Middleware
|--------------------------------------------------------------------------
|
| Here you may specify which middleware Fortify will assign to the routes
| that it registers with the application. If necessary, you may change
| these middleware but typically this provided default is preferred.
|
*/
'middleware' => ['web'],
/*
|--------------------------------------------------------------------------
| Rate Limiting
|--------------------------------------------------------------------------
|
| By default, Fortify will throttle logins to five requests per minute for
| every email and IP address combination. However, if you would like to
| specify a custom rate limiter to call then you may specify it here.
|
*/
'limiters' => [
'login' => 'login',
'two-factor' => 'two-factor',
],
/*
|--------------------------------------------------------------------------
| Register View Routes
|--------------------------------------------------------------------------
|
| Here you may specify if the routes returning views should be disabled as
| you may not need them when building your own application. This may be
| especially true if you're writing a custom single-page application.
|
*/
'views' => true,
/*
|--------------------------------------------------------------------------
| Features
|--------------------------------------------------------------------------
|
| Some of the Fortify features are optional. You may disable the features
| by removing them from this array. You're free to only remove some of
| these features or you can even remove all of these if you need to.
|
*/
'features' => [
Features::registration(),
Features::resetPasswords(),
// Features::emailVerification(),
Features::updateProfileInformation(),
Features::updatePasswords(),
Features::twoFactorAuthentication([
'confirm' => true,
'confirmPassword' => true,
// 'window' => 0,
]),
],
];
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
use Laravel\Fortify\Fortify;
return new class extends Migration
{
/**
* Run the migrations.
*/
public function up(): void
{
Schema::table('users', function (Blueprint $table) {
$table->text('two_factor_secret')
->after('password')
->nullable();
$table->text('two_factor_recovery_codes')
->after('two_factor_secret')
->nullable();
if (Fortify::confirmsTwoFactorAuthentication()) {
$table->timestamp('two_factor_confirmed_at')
->after('two_factor_recovery_codes')
->nullable();
}
});
}
/**
* Reverse the migrations.
*/
public function down(): void
{
Schema::table('users', function (Blueprint $table) {
$table->dropColumn(array_merge([
'two_factor_secret',
'two_factor_recovery_codes',
], Fortify::confirmsTwoFactorAuthentication() ? [
'two_factor_confirmed_at',
] : []));
});
}
};
<!DOCTYPE html>
<html class="loading" lang="en" data-textdirection="ltr">
<!-- BEGIN: Head-->
<head>
<link rel="apple-touch-icon" href="{{ url('theme/images/ico/apple-icon-120.png') }}">
<link rel="shortcut icon" type="image/x-icon" href="{{ url('theme/images/ico/favicon.ico') }}">
<link href="https://fonts.googleapis.com/css2?family=Montserrat:ital,wght@0,300;0,400;0,500;0,600;1,400;1,500;1,600" rel="stylesheet">
<meta http-equiv="Content-Type" charset="utf-8">
<meta name="universitas-negeri-surabaya" content="custom" />
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta name="description" content="Unesa Medical Center">
<meta name="author" content="PPTI Unesa Surabaya">
<meta name="keywords" content="sistem, informasi, klinik, obat, sakit, pengobatan, unesa, pasien, penyembuhan">
<meta name="language" content="id">
<meta name="geo.region" content="ID" />
<meta name="geo.position" content="-7.300818;112.672689">
<meta name="geo.placename" content="Surabaya">
<meta name="geo.region" content="Indonesia">
<title>SIPEKA | Sistem Informasi Pengkategorian EPK</title>
<!-- BEGIN: Vendor CSS-->
<link rel="stylesheet" type="text/css" href="{{ url('theme/vendors/css/vendors.min.css') }}">
<!-- END: Vendor CSS-->
<!-- BEGIN: Theme CSS-->
<link rel="stylesheet" type="text/css" href="{{ url('theme/css/bootstrap.css') }}">
<link rel="stylesheet" type="text/css" href="{{ url('theme/css/bootstrap-extended.css') }}">
<link rel="stylesheet" type="text/css" href="{{ url('theme/css/colors.css') }}">
<link rel="stylesheet" type="text/css" href="{{ url('theme/css/components.css') }}">
<link rel="stylesheet" type="text/css" href="{{ url('theme/css/themes/dark-layout.css') }}">
<link rel="stylesheet" type="text/css" href="{{ url('theme/css/themes/bordered-layout.css') }}">
<link rel="stylesheet" type="text/css" href="{{ url('theme/css/themes/semi-dark-layout.css') }}">
<!-- BEGIN: Page CSS-->
<link rel="stylesheet" type="text/css" href="{{ url('theme/css/core/menu/menu-types/horizontal-menu.css') }}">
<link rel="stylesheet" type="text/css" href="{{ url('theme/css/plugins/forms/form-validation.css') }}">
<link rel="stylesheet" type="text/css" href="{{ url('theme/css/pages/authentication.css') }}">
<!-- END: Page CSS-->
<!-- BEGIN: Custom CSS-->
<link rel="stylesheet" type="text/css" href="{{ url('theme/assets/css/style.css') }}">
<!-- END: Custom CSS-->
</head>
<!-- END: Head-->
<!-- BEGIN: Body-->
<body class="horizontal-layout horizontal-menu blank-page navbar-floating footer-static " data-open="hover" data-menu="horizontal-menu" data-col="blank-page">
<!-- BEGIN: Content-->
<div class="app-content content ">
<div class="content-overlay"></div>
<div class="header-navbar-shadow"></div>
<div class="content-wrapper">
<div class="content-header row">
</div>
<div class="content-body">
<div class="auth-wrapper auth-basic px-2">
<div class="auth-inner my-2">
<!-- Login basic -->
<div class="card mb-0">
<div class="card-body">
<a href="index.html" class="brand-logo">
{{-- <img src="{{ url('theme/images/logo/logoumc.png') }}" width="40%"> --}}
<h2 class="brand-text text-primary ms-1">SIPEKA</h2>
</a>
{{-- <h4 class="card-title mb-1">Welcome to SIPEKA!</h4> --}}
<form class="text-left" method="POST" action="{{ route('login') }}">
@csrf
<div class="mb-1">
<label for="login-email" class="form-label">Email</label>
<input id="email" name="email" type="text" class="form-control" placeholder="Email" :value="old('email')" required autofocus>
</div>
<div class="mb-1">
<div class="d-flex justify-content-between">
<label class="form-label" for="login-password">Password</label>
</div>
<div class="input-group input-group-merge form-password-toggle">
<input id="password" name="password" type="password" class="form-control" placeholder="Password" required autocomplete="current-password">
<span class="input-group-text cursor-pointer"><i data-feather="eye"></i></span>
</div>
</div>
<button class="btn btn-primary w-100" tabindex="4">Login</button>
</form>
</br>
</div>
</div>
<!-- /Login basic -->
</div>
</div>
</div>
</div>
</div>
<!-- END: Content-->
<!-- BEGIN: Vendor JS-->
<script src="{{ url('theme/vendors/js/vendors.min.js') }}"></script>
<!-- BEGIN Vendor JS-->
<!-- BEGIN: Page Vendor JS-->
<script src="{{ url('theme/vendors/js/ui/jquery.sticky.js') }}"></script>
<script src="{{ url('theme/vendors/js/forms/validation/jquery.validate.min.js') }}"></script>
<!-- END: Page Vendor JS-->
<!-- BEGIN: Theme JS-->
<script src="{{ url('theme/js/core/app-menu.js') }}"></script>
<script src="{{ url('theme/js/core/app.js') }}"></script>
<!-- END: Theme JS-->
<!-- BEGIN: Page JS-->
<script src="{{ url('theme/js/scripts/pages/auth-login.js') }}"></script>
<!-- END: Page JS-->
<script>
$(window).on('load', function() {
if (feather) {
feather.replace({
width: 14,
height: 14
});
}
})
</script>
</body>
<!-- END: Body-->
</html>
......@@ -27,8 +27,8 @@
</a>
<div class="dropdown-menu dropdown-menu-end" aria-labelledby="dropdown-user"><div class="dropdown-divider"></div>
<a class="dropdown-item" href="#" onclick="event.preventDefault(); document.getElementById('logout-form').submit();"><i class="me-50" data-feather="power"></i> Logout</a>
<form id="logout-form" action="#" method="POST" style="display: none;">
<a class="dropdown-item" href="{{route('admin.logout')}}" onclick="event.preventDefault(); document.getElementById('logout-form').submit();"><i class="me-50" data-feather="power"></i> Logout</a>
<form id="logout-form" action="{{route('admin.logout')}}" method="POST" style="display: none;">
{{ csrf_field() }}
</form>
</div>
......
<ul class="nav navbar-nav" id="main-menu-navigation" data-menu="menu-navigation">
<li data-menu="" class="{{ (request()->is('/')) ? 'active' : '' }}"><a href="#" class="dropdown-item nav-link d-flex align-items-center" data-bs-toggle="" data-i18n="Dashboards"><i data-feather="home"></i><span data-i18n="Dashboards">Dashboards</span></a></li>
<li data-menu="" class="{{ (request()->is('/home')) ? 'active' : '' }}"><a href="{{url('/')}}" class="dropdown-item nav-link d-flex align-items-center" data-bs-toggle="" data-i18n="Dashboards"><i data-feather="home"></i><span data-i18n="Dashboards">Dashboards</span></a></li>
{{-- @if (Auth::user()->hasAnyRole('admin', 'superadmin')) --}}
<li class="dropdown nav-item" data-menu="dropdown"><a class="dropdown-toggle nav-link d-flex align-items-center" href="#" data-bs-toggle="dropdown"><i data-feather="server"></i><span data-i18n="Data Master">Data Master</span></a>
<ul class="dropdown-menu" data-bs-popper="none">
......
<?php
use App\Http\Controllers\Admin\Auth\LoginController;
use App\Http\Controllers\Admin\KategoriController;
use App\Http\Controllers\TransaksiController;
use Illuminate\Support\Facades\Route;
......@@ -16,12 +17,15 @@
*/
Route::get('/', function () {
return view('dashboard');
return view('Admin.login');
});
Route::get('/transaksi', [TransaksiController::class, 'index'])->name('admin.index-transaksi');
// Admin
Route::resource('kategori', KategoriController::class);
// End of Admin
Route::middleware(['auth','prevent-back-history'])->group(function(){
Route::get('/home', function () {
return view('dashboard');
});
Route::resource('kategori', KategoriController::class);
Route::get('/logout', [LoginController::class, 'logout'])->name('admin.logout');
});
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment