wip on password reset

This commit is contained in:
2023-12-03 10:40:53 +05:00
parent e940d17bad
commit 1429757b42
11 changed files with 206 additions and 38 deletions

View File

@@ -1 +1,5 @@
# Online tbbank dashboard
# Password Reset
# Status uytganden son uytgedip bilenok
# Etraplar goshmaly

View File

@@ -60,7 +60,7 @@ class RegisterController extends Controller
*/
protected function validator(array $data)
{
$data['phone'] = unMaskPhone($data['phone']);
$data['phone'] = unMaskPhone($data['phone'] ?? '');
return Validator::make($data, [
'name' => ['required', 'string', 'max:255'],

View File

@@ -0,0 +1,33 @@
<?php
namespace App\Http\Controllers\Auth;
use App\Http\Controllers\Controller;
use App\Models\User;
use Illuminate\Contracts\View\View;
use Illuminate\Http\Request;
class ResetPasswordController extends Controller
{
/**
* Reset password page
*/
public function index(): View
{
return view('vendor.nova.pages.reset-password');
}
/**
* Store new password
*/
public function store(Request $request)
{
$request->validate(['username' => ['required', 'string', 'max:250', 'exists:users,username']]);
$user = User::where('username', $request->username)->first();
// sendSMSVerification($user->phone);
return response()->json(['message' => __('We send you a code')]);
}
}

View File

@@ -39,11 +39,13 @@ class UsersTableSeeder extends Seeder
'username' => 'nurmuhammet',
'name' => 'Nurmuhammet Allanov',
'email' => 'nurmuhammet@mail.com',
'phone' => '61929248',
'password' => '$2y$10$O7LFNdFIT3Rmfeo8tUfbqekB0x0incovkRP6eQuzvb7dVXysQyyBC',
], [
'username' => 'mahmyt',
'name' => 'Mahmyt Allaberdiyev',
'email' => 'mahmyt1206@gmail.com',
'phone' => '65707012',
'password' => '$2y$10$O7LFNdFIT3Rmfeo8tUfbqekB0x0incovkRP6eQuzvb7dVXysQyyBC',
], [
'username' => 'dowran',

View File

@@ -42,7 +42,6 @@
"Expectation Failed": "Garaşmak başa barmady",
"Failed Dependency": "Şowsuzlyk",
"Forbidden": "Gadagan",
"Forgot Your Password?": "Açar sözüni ýatdan çykardyňyzmy?",
"Found": "Tapyldy",
"Gateway Timeout": "Derweze wagty",
"Go to page :page": ":Page-nji sahypa geçiň",
@@ -219,5 +218,6 @@
"Go to login page": "Login sahypa geç",
"Submit": "Tassyklamak",
"Verification code": "Tassyklaýyş belgi",
"Please, verify your phone": "Telefon beligiňizi tassyklamagyňyzy haýyş edýäris."
"Please, verify your phone": "Telefon beligiňizi tassyklamagyňyzy haýyş edýäris.",
"Enter your username to continue": "Dowam etmek üçin ulanyjy adyny giriziň"
}

45
public/assets/js/fn.js Normal file
View File

@@ -0,0 +1,45 @@
function $_ID(id) {
return document.getElementById(id)
}
function getFormData(event) {
return Object.fromEntries(new FormData(event.target).entries())
}
function loopObject(obj, callback) {
for (let [key, value] of Object.entries(obj)) {
callback({ key, value })
}
}
async function postData(url = '', data = {}) {
const response = await fetch(url, {
method: 'POST',
mode: 'cors',
cache: 'no-cache',
credentials: 'same-origin',
headers: {
'Content-Type': 'application/json',
'X-Requested-With': 'XMLHttpRequest'
},
referrerPolicy: 'no-referrer',
body: JSON.stringify(data)
})
return response.json()
}
function addValidationClasses(item) {
$_ID(item.key).classList.add('form-input-border-error')
$_ID(`${item.key}-error-box`).innerHTML = `<strong>${item.value}</strong>`
}
function removeValidationClasess() {
Array.from(document.getElementsByClassName('form-input-border-error')).forEach(element => {
element.classList.remove('form-input-border-error')
});
Array.from(document.getElementsByClassName('error-box')).forEach(element => {
element.innerHTML = ''
})
}

View File

@@ -10,14 +10,6 @@
<!-- Styles -->
<link rel="stylesheet" href="/vendor/nova/app.css?id=496e3383c5e2918c7bc875f45870e701">
<style>
.bg-secondary-500 {
background-color: rgb(186,230,253);
}
.hover:bg-secondary-400 {
background-color: rgba(24, 182, 155, 0.5);
}
</style>
</head>
<body class="min-w-site text-sm font-medium min-h-full text-gray-500 dark:text-gray-400 bg-gray-100 dark:bg-gray-900">
<div class="py-6 px-1 md:px-2 lg:px-6">
@@ -35,23 +27,29 @@
<label class="block mb-2" for="username">
{{ __('Username') }}
</label>
<input class="form-control form-input form-input-bordered w-full" id="username" type="text" name="username" autofocus="" required="">
<input class="form-control form-input form-input-bordered w-full @error('username') form-input-border-error @enderror" id="username" type="text" name="username" autofocus="">
@error('username')
<span class="text-red-500 text-italic">
<strong>{{ $message }}</strong>
</span>
@enderror
</div>
<div class="mb-6">
<label class="block mb-2" for="password">
{{ __('Password') }}
</label>
<input class="form-control form-input form-input-bordered w-full" id="password" type="password" name="password" required="">
<input class="form-control form-input form-input-bordered w-full @error('username') form-input-border-error @enderror" id="password" type="password" name="password">
@if($errors->any())
@foreach($errors->all() as $error)
<p class="mt-2 text-red-500">{{ $error }}</p>
@endforeach
@endif
@error('password')
<span class="text-red-500 text-italic">
<strong>{{ $message }}</strong>
</span>
@enderror
</div>
<div class="flex mb-6">
<div class="ml-auto">
<a class="text-gray-500 font-bold no-underline" href="">
<a href="{{ route('reset-password') }}" class="text-gray-500 font-bold no-underline">
{{ __('Forgot your password?') }}
</a>
</div>
@@ -65,7 +63,5 @@
</form>
</div>
</div>
<script src="/assets/js/inputmask.min.js"></script>
</body>
</html>

View File

@@ -9,14 +9,6 @@
<!-- Styles -->
<link rel="stylesheet" href="/vendor/nova/app.css?id=496e3383c5e2918c7bc875f45870e701">
<style>
.bg-secondary-500 {
background-color: rgb(186,230,253);
}
.hover:bg-secondary-400 {
background-color: rgba(24, 182, 155, 0.5);
}
</style>
</head>
<body class="min-w-site text-sm font-medium min-h-full text-gray-500 dark:text-gray-400 bg-gray-100 dark:bg-gray-900">
<div class="py-6 px-1 md:px-2 lg:px-6">
@@ -24,7 +16,7 @@
<span class="text-4xl">{{ __('Online panel') }}</span>
</div>
<div>
<form class="bg-white dark:bg-gray-800 shadow rounded-lg p-8 max-w-[25rem] mx-auto" method="POST" action="{{ route('register') }}">
<form class="bg-white dark:bg-gray-800 shadow rounded-lg p-8 max-w-lg mx-auto" method="POST" action="{{ route('register') }}">
@csrf
<h2 class="text-2xl text-center font-normal mb-6">{{ __('Welcome Back!') }}</h2>
<svg class="block mx-auto mb-6" xmlns="http://www.w3.org/2000/svg" width="100" height="2" viewBox="0 0 100 2">
@@ -34,7 +26,7 @@
<label class="block mb-1" for="username">
{{ __('Full Name') }}
</label>
<input class="form-control form-input form-input-bordered w-full @error('name') form-input-border-error @enderror" id="name" type="text" name="name" autofocus="" required="" value="{{ old('name') }}">
<input class="form-control form-input form-input-bordered w-full @error('name') form-input-border-error @enderror" id="name" type="text" name="name" autofocus="" value="{{ old('name') }}">
@error('name')
<span class="text-red-500 text-italic">
@@ -46,7 +38,7 @@
<label class="block mb-1" for="username">
{{ __('Phone') }}
</label>
<input class="form-control form-input form-input-bordered w-full" id="phone" type="text" name="phone" autofocus="" required="" value="{{ old('phone') }}">
<input class="form-control form-input form-input-bordered w-full" id="phone" type="text" name="phone" autofocus="" value="{{ old('phone') }}">
@error('phone')
<span class="text-red-500 text-italic">
@@ -58,7 +50,7 @@
<label class="block mb-1" for="username">
{{ __('Username') }}
</label>
<input class="form-control form-input form-input-bordered w-full" id="username" type="text" name="username" autofocus="" required="" value="{{ old('username') }}">
<input class="form-control form-input form-input-bordered w-full" id="username" type="text" name="username" autofocus="" value="{{ old('username') }}">
@error('username')
<span class="text-red-500 text-italic">
@@ -70,7 +62,7 @@
<label class="block mb-1" for="password">
{{ __('Password') }}
</label>
<input class="form-control form-input form-input-bordered w-full" id="password" type="password" name="password" required="">
<input class="form-control form-input form-input-bordered w-full" id="password" type="password" name="password" >
@error('password')
<span class="text-red-500 text-italic">
@@ -82,7 +74,7 @@
<label class="block mb-1" for="password_confirmation">
{{ __('Confirm Password') }}
</label>
<input class="form-control form-input form-input-bordered w-full" id="password_confirmation" type="password" name="password_confirmation" required="">
<input class="form-control form-input form-input-bordered w-full" id="password_confirmation" type="password" name="password_confirmation" >
@error('password_confirmation')
<span class="text-red-500 text-italic">

View File

@@ -0,0 +1,92 @@
<!DOCTYPE html>
<html lang="tk" dir="ltr" class="h-full font-sans antialiased">
<head>
<meta name="theme-color" content="#fff">
<meta charset="utf-8">
<meta name="viewport" content="width=device-width"/>
<meta name="locale" content="tk"/>
<meta name="robots" content="noindex">
<!-- Styles -->
<link rel="stylesheet" href="/vendor/nova/app.css?id=496e3383c5e2918c7bc875f45870e701">
<style>
.bg-secondary-500 {
background-color: rgb(186,230,253);
}
.hover:bg-secondary-400 {
background-color: rgba(24, 182, 155, 0.5);
}
</style>
</head>
<body class="min-w-site text-sm font-medium min-h-full text-gray-500 dark:text-gray-400 bg-gray-100 dark:bg-gray-900">
<div class="py-6 px-1 md:px-2 lg:px-6">
<div class="mx-auto py-8 max-w-md flex justify-center">
<span class="text-4xl text-center">{{ __('Forgot your password?') }}</span>
</div>
<div>
<form
method="POST"
action="{{ route('reset-password') }}"
onsubmit="event.preventDefault();resetPassword(event)"
class="bg-white dark:bg-gray-800 shadow rounded-lg p-8 max-w-lg mx-auto"
>
@csrf
<h2 class="text-2xl text-center font-normal mb-6">{{ __('Enter your username to continue') }}</h2>
<svg class="block mx-auto mb-6" xmlns="http://www.w3.org/2000/svg" width="100" height="2" viewBox="0 0 100 2">
<path fill="#D8E3EC" d="M0 0h100v2H0z"></path>
</svg>
<div class="mb-6">
<label class="block mb-2" for="username">
{{ __('Username') }}
</label>
<input
id="username"
type="text"
name="username"
class="form-control form-input form-input-bordered w-full"
autofocus=""
>
<span id="username-error-box" class="text-red-500 text-italic error-box"></span>
</div>
<div class="mb-6" id="verification-code-box"></div>
{{-- <div class="mb-6">
<label class="block mb-2" for="password">
{{ __('Password') }}
</label>
<input class="form-control form-input form-input-bordered w-full" id="password" type="password" name="password" required="">
</div> --}}
<button class="w-full flex justify-center shadow relative bg-primary-500 hover:bg-primary-400 text-white dark:text-gray-900 w-full flex justify-center cursor-pointer rounded text-sm font-bold focus:outline-none focus:ring ring-primary-200 dark:ring-gray-600 inline-flex items-center justify-center h-9 px-3 mb-3 w-full flex justify-center shadow relative bg-primary-500 hover:bg-primary-400 text-white dark:text-gray-900 w-full flex justify-center" type="submit">
<span class=""><span>{{ __('Submit') }}</span></span>
</button>
<a href="{{ route('register') }}" class="w-full flex justify-center shadow relative bg-primary-500 hover:bg-primary-400 text-white dark:text-gray-900 w-full flex justify-center cursor-pointer rounded text-sm font-bold focus:outline-none focus:ring ring-primary-200 dark:ring-gray-600 inline-flex items-center justify-center h-9 px-3 mb-3 w-full flex justify-center shadow relative bg-primary-500 hover:bg-primary-400 text-white dark:text-gray-900 w-full flex justify-center">
<span class=""><span>{{ __('Go to login page') }}</span></span>
</a>
</form>
</div>
</div>
<script src="/assets/js/fn.js"></script>
<script>
async function resetPassword(event) {
const response = await postData(event.target.action, getFormData(event))
if (response.errors) {
loopObject(response.errors, item => addValidationClasses(item));
} else {
removeValidationClasess()
$_ID('verification-code-box').innerHTML = `
<label class="block mb-2" for="password">
{{ __('Verification code') }}
</label>
<input class="form-control form-input form-input-bordered w-full" id="password" type="password" name="password" required="">
`;
}
}
</script>
</body>
</html>

View File

@@ -2,6 +2,7 @@
use App\Http\Controllers\Auth\LoginController;
use App\Http\Controllers\Auth\RegisterController;
use App\Http\Controllers\Auth\ResetPasswordController;
use Illuminate\Support\Facades\Route;
/*
@@ -18,6 +19,12 @@ use Illuminate\Support\Facades\Route;
Route::middleware('guest')->group(function () {
Route::get('/register', [RegisterController::class, 'showNovaRegisterpageForm'])->name('register');
Route::post('/register', [RegisterController::class, 'register']);
Route::get('/login', [LoginController::class, 'showLoginForm'])->name('login');
Route::post('/login', [LoginController::class, 'login']);
Route::get('reset-password', [ResetPasswordController::class, 'index'])->name('reset-password');
Route::post('reset-password', [ResetPasswordController::class, 'store']);
});
Route::middleware(['auth', 'un_verified'])->group(function () {
@@ -25,7 +32,4 @@ Route::middleware(['auth', 'un_verified'])->group(function () {
Route::post('sms-verification', [RegisterController::class, 'verifySmsCode']);
});
Route::get('/login', [LoginController::class, 'showLoginForm'])->name('login');
Route::post('/login', [LoginController::class, 'login']);
Route::redirect('/', config('nova.path'));