implement 2fa system
This commit is contained in:
parent
7723c70511
commit
ef378d450d
@ -9,8 +9,18 @@ use Illuminate\Support\Facades\Auth;
|
||||
|
||||
class LogoutController extends Controller
|
||||
{
|
||||
public $user;
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
$this->user = Auth::user();
|
||||
}
|
||||
public function logout(Request $request)
|
||||
{
|
||||
$this->user->update([
|
||||
'verify2fa' => 0,
|
||||
]);
|
||||
|
||||
Auth::logout();
|
||||
|
||||
$request->session()->invalidate();
|
||||
@ -21,13 +31,12 @@ class LogoutController extends Controller
|
||||
|
||||
public function deleteAccount(Request $request)
|
||||
{
|
||||
$user = Auth::user();
|
||||
|
||||
Auth::logout();
|
||||
$request->session()->invalidate();
|
||||
$request->session()->regenerateToken();
|
||||
|
||||
$user->delete();
|
||||
$this->user->delete();
|
||||
|
||||
return redirect()->route('login')->with('success', 'Your account has been deleted successfully.');
|
||||
}
|
||||
|
||||
@ -0,0 +1,77 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Controllers\Auth;
|
||||
|
||||
use Illuminate\Http\Request;
|
||||
use App\Http\Controllers\Controller;
|
||||
use App\Http\Requests\Enable2FARequest;
|
||||
use App\Http\Requests\SecretCode2FARequest;
|
||||
use Illuminate\Support\Facades\Auth;
|
||||
|
||||
class TwoFactorAuthenticationController extends Controller
|
||||
{
|
||||
public $google2fa;
|
||||
public $user;
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
$this->google2fa = app('pragmarx.google2fa');
|
||||
$this->user = Auth::user();
|
||||
}
|
||||
|
||||
public function enable2FAShow()
|
||||
{
|
||||
$secret = $this->google2fa->generateSecretKey();
|
||||
|
||||
$urlQRCode = $this->google2fa->getQRCodeInline(
|
||||
config('app.name'),
|
||||
$this->user->email,
|
||||
$secret
|
||||
);
|
||||
|
||||
return view("auth.enable-2fa", compact(['secret', 'urlQRCode']));
|
||||
}
|
||||
|
||||
public function enable2FA(Enable2FARequest $request)
|
||||
{
|
||||
$inputs = $request->only('otp', 'secret');
|
||||
$valid = $this->google2fa->verifyKey($inputs['secret'], $inputs['otp']);
|
||||
|
||||
if ($valid) {
|
||||
$this->user->update([
|
||||
'google2fa_secret' => $inputs['secret'],
|
||||
]);
|
||||
}
|
||||
|
||||
return redirect()->route('dashboard')->with('success', '2fa is verified');
|
||||
}
|
||||
|
||||
public function disable2FA()
|
||||
{
|
||||
$this->user->update([
|
||||
'google2fa_secret' => null,
|
||||
'verify2fa' => 0,
|
||||
]);
|
||||
return redirect()->route('dashboard');
|
||||
}
|
||||
|
||||
public function secretCodeShow()
|
||||
{
|
||||
return view('auth.secret-code');
|
||||
}
|
||||
|
||||
public function secretCode(SecretCode2FARequest $request)
|
||||
{
|
||||
$secret = $this->user->google2fa_secret;
|
||||
$otp = $request->only('code');
|
||||
$valid = $this->google2fa->verifyKey($secret, $otp['code']);
|
||||
|
||||
if ($valid) {
|
||||
$this->user->update([
|
||||
'verify2fa' => 1,
|
||||
]);
|
||||
return redirect()->route('dashboard')->with('google2fa', '2fa is verify');
|
||||
}
|
||||
return redirect()->back()->withErrors(['code' => 'secret code is wrong']);
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,26 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Middleware;
|
||||
|
||||
use Closure;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Facades\Auth;
|
||||
use Symfony\Component\HttpFoundation\Response;
|
||||
|
||||
class TwoFactorAuthMiddleware
|
||||
{
|
||||
/**
|
||||
* Handle an incoming request.
|
||||
*
|
||||
* @param \Closure(\Illuminate\Http\Request): (\Symfony\Component\HttpFoundation\Response) $next
|
||||
*/
|
||||
public function handle(Request $request, Closure $next): Response
|
||||
{
|
||||
if (Auth::user()->google2fa_secret) {
|
||||
if (!Auth::user()->verify2fa) {
|
||||
return redirect()->route('secret.code.show');
|
||||
}
|
||||
}
|
||||
return $next($request);
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,29 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Requests;
|
||||
|
||||
use Illuminate\Foundation\Http\FormRequest;
|
||||
|
||||
class Enable2FARequest extends FormRequest
|
||||
{
|
||||
/**
|
||||
* Determine if the user is authorized to make this request.
|
||||
*/
|
||||
public function authorize(): bool
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the validation rules that apply to the request.
|
||||
*
|
||||
* @return array<string, \Illuminate\Contracts\Validation\ValidationRule|array<mixed>|string>
|
||||
*/
|
||||
public function rules(): array
|
||||
{
|
||||
return [
|
||||
'otp' => 'required',
|
||||
'secret' => 'required',
|
||||
];
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,28 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Requests;
|
||||
|
||||
use Illuminate\Foundation\Http\FormRequest;
|
||||
|
||||
class SecretCode2FARequest extends FormRequest
|
||||
{
|
||||
/**
|
||||
* Determine if the user is authorized to make this request.
|
||||
*/
|
||||
public function authorize(): bool
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the validation rules that apply to the request.
|
||||
*
|
||||
* @return array<string, \Illuminate\Contracts\Validation\ValidationRule|array<mixed>|string>
|
||||
*/
|
||||
public function rules(): array
|
||||
{
|
||||
return [
|
||||
'code' => 'required'
|
||||
];
|
||||
}
|
||||
}
|
||||
@ -23,7 +23,9 @@ class User extends Authenticatable implements MustVerifyEmail
|
||||
'password',
|
||||
'github_id',
|
||||
'github_token',
|
||||
'github_refresh_token'
|
||||
'github_refresh_token',
|
||||
'google2fa_secret',
|
||||
'verify2fa'
|
||||
];
|
||||
|
||||
/**
|
||||
|
||||
@ -1,5 +1,6 @@
|
||||
<?php
|
||||
|
||||
use App\Http\Middleware\TwoFactorAuthMiddleware;
|
||||
use Illuminate\Foundation\Application;
|
||||
use Illuminate\Foundation\Configuration\Exceptions;
|
||||
use Illuminate\Foundation\Configuration\Middleware;
|
||||
@ -11,7 +12,9 @@ return Application::configure(basePath: dirname(__DIR__))
|
||||
health: '/up',
|
||||
)
|
||||
->withMiddleware(function (Middleware $middleware) {
|
||||
//
|
||||
$middleware->alias([
|
||||
'2fa' => TwoFactorAuthMiddleware::class,
|
||||
]);
|
||||
})
|
||||
->withExceptions(function (Exceptions $exceptions) {
|
||||
//
|
||||
|
||||
@ -10,10 +10,12 @@
|
||||
"license": "MIT",
|
||||
"require": {
|
||||
"php": "^8.2",
|
||||
"bacon/bacon-qr-code": "^3.0",
|
||||
"laravel/framework": "^12.0",
|
||||
"laravel/socialite": "^5.20",
|
||||
"laravel/tinker": "^2.10.1",
|
||||
"mailersend/laravel-driver": "^2.9"
|
||||
"mailersend/laravel-driver": "^2.9",
|
||||
"pragmarx/google2fa-laravel": "^2.3"
|
||||
},
|
||||
"require-dev": {
|
||||
"fakerphp/faker": "^1.23",
|
||||
|
||||
301
Web-Application/Manually/composer.lock
generated
301
Web-Application/Manually/composer.lock
generated
@ -4,8 +4,62 @@
|
||||
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
|
||||
"This file is @generated automatically"
|
||||
],
|
||||
"content-hash": "cc95798219be94103b39757ba957bfb5",
|
||||
"content-hash": "7ec9c18ae33503f4d06a9ce3cef2e3cf",
|
||||
"packages": [
|
||||
{
|
||||
"name": "bacon/bacon-qr-code",
|
||||
"version": "v3.0.1",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/Bacon/BaconQrCode.git",
|
||||
"reference": "f9cc1f52b5a463062251d666761178dbdb6b544f"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/Bacon/BaconQrCode/zipball/f9cc1f52b5a463062251d666761178dbdb6b544f",
|
||||
"reference": "f9cc1f52b5a463062251d666761178dbdb6b544f",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"dasprid/enum": "^1.0.3",
|
||||
"ext-iconv": "*",
|
||||
"php": "^8.1"
|
||||
},
|
||||
"require-dev": {
|
||||
"phly/keep-a-changelog": "^2.12",
|
||||
"phpunit/phpunit": "^10.5.11 || 11.0.4",
|
||||
"spatie/phpunit-snapshot-assertions": "^5.1.5",
|
||||
"squizlabs/php_codesniffer": "^3.9"
|
||||
},
|
||||
"suggest": {
|
||||
"ext-imagick": "to generate QR code images"
|
||||
},
|
||||
"type": "library",
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"BaconQrCode\\": "src/"
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"BSD-2-Clause"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Ben Scholzen 'DASPRiD'",
|
||||
"email": "mail@dasprids.de",
|
||||
"homepage": "https://dasprids.de/",
|
||||
"role": "Developer"
|
||||
}
|
||||
],
|
||||
"description": "BaconQrCode is a QR code generator for PHP.",
|
||||
"homepage": "https://github.com/Bacon/BaconQrCode",
|
||||
"support": {
|
||||
"issues": "https://github.com/Bacon/BaconQrCode/issues",
|
||||
"source": "https://github.com/Bacon/BaconQrCode/tree/v3.0.1"
|
||||
},
|
||||
"time": "2024-10-01T13:55:55+00:00"
|
||||
},
|
||||
{
|
||||
"name": "beberlei/assert",
|
||||
"version": "v3.3.3",
|
||||
@ -268,6 +322,56 @@
|
||||
],
|
||||
"time": "2023-12-20T15:40:13+00:00"
|
||||
},
|
||||
{
|
||||
"name": "dasprid/enum",
|
||||
"version": "1.0.6",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/DASPRiD/Enum.git",
|
||||
"reference": "8dfd07c6d2cf31c8da90c53b83c026c7696dda90"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/DASPRiD/Enum/zipball/8dfd07c6d2cf31c8da90c53b83c026c7696dda90",
|
||||
"reference": "8dfd07c6d2cf31c8da90c53b83c026c7696dda90",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"php": ">=7.1 <9.0"
|
||||
},
|
||||
"require-dev": {
|
||||
"phpunit/phpunit": "^7 || ^8 || ^9 || ^10 || ^11",
|
||||
"squizlabs/php_codesniffer": "*"
|
||||
},
|
||||
"type": "library",
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"DASPRiD\\Enum\\": "src/"
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"BSD-2-Clause"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Ben Scholzen 'DASPRiD'",
|
||||
"email": "mail@dasprids.de",
|
||||
"homepage": "https://dasprids.de/",
|
||||
"role": "Developer"
|
||||
}
|
||||
],
|
||||
"description": "PHP 7.1 enum implementation",
|
||||
"keywords": [
|
||||
"enum",
|
||||
"map"
|
||||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/DASPRiD/Enum/issues",
|
||||
"source": "https://github.com/DASPRiD/Enum/tree/1.0.6"
|
||||
},
|
||||
"time": "2024-08-09T14:30:48+00:00"
|
||||
},
|
||||
{
|
||||
"name": "dflydev/dot-access-data",
|
||||
"version": "v3.0.3",
|
||||
@ -3753,6 +3857,201 @@
|
||||
],
|
||||
"time": "2024-12-14T21:12:59+00:00"
|
||||
},
|
||||
{
|
||||
"name": "pragmarx/google2fa",
|
||||
"version": "v8.0.3",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/antonioribeiro/google2fa.git",
|
||||
"reference": "6f8d87ebd5afbf7790bde1ffc7579c7c705e0fad"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/antonioribeiro/google2fa/zipball/6f8d87ebd5afbf7790bde1ffc7579c7c705e0fad",
|
||||
"reference": "6f8d87ebd5afbf7790bde1ffc7579c7c705e0fad",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"paragonie/constant_time_encoding": "^1.0|^2.0|^3.0",
|
||||
"php": "^7.1|^8.0"
|
||||
},
|
||||
"require-dev": {
|
||||
"phpstan/phpstan": "^1.9",
|
||||
"phpunit/phpunit": "^7.5.15|^8.5|^9.0"
|
||||
},
|
||||
"type": "library",
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"PragmaRX\\Google2FA\\": "src/"
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Antonio Carlos Ribeiro",
|
||||
"email": "acr@antoniocarlosribeiro.com",
|
||||
"role": "Creator & Designer"
|
||||
}
|
||||
],
|
||||
"description": "A One Time Password Authentication package, compatible with Google Authenticator.",
|
||||
"keywords": [
|
||||
"2fa",
|
||||
"Authentication",
|
||||
"Two Factor Authentication",
|
||||
"google2fa"
|
||||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/antonioribeiro/google2fa/issues",
|
||||
"source": "https://github.com/antonioribeiro/google2fa/tree/v8.0.3"
|
||||
},
|
||||
"time": "2024-09-05T11:56:40+00:00"
|
||||
},
|
||||
{
|
||||
"name": "pragmarx/google2fa-laravel",
|
||||
"version": "v2.3.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/antonioribeiro/google2fa-laravel.git",
|
||||
"reference": "60f363c16db1e94263e0560efebe9fc2e302b7ef"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/antonioribeiro/google2fa-laravel/zipball/60f363c16db1e94263e0560efebe9fc2e302b7ef",
|
||||
"reference": "60f363c16db1e94263e0560efebe9fc2e302b7ef",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"laravel/framework": "^5.4.36|^6.0|^7.0|^8.0|^9.0|^10.0|^11.0|^12.0",
|
||||
"php": ">=7.0",
|
||||
"pragmarx/google2fa-qrcode": "^1.0|^2.0|^3.0"
|
||||
},
|
||||
"require-dev": {
|
||||
"bacon/bacon-qr-code": "^2.0",
|
||||
"orchestra/testbench": "3.4.*|3.5.*|3.6.*|3.7.*|4.*|5.*|6.*|7.*|8.*|9.*|10.*",
|
||||
"phpunit/phpunit": "~5|~6|~7|~8|~9|~10|~11"
|
||||
},
|
||||
"suggest": {
|
||||
"bacon/bacon-qr-code": "Required to generate inline QR Codes.",
|
||||
"pragmarx/recovery": "Generate recovery codes."
|
||||
},
|
||||
"type": "library",
|
||||
"extra": {
|
||||
"laravel": {
|
||||
"aliases": {
|
||||
"Google2FA": "PragmaRX\\Google2FALaravel\\Facade"
|
||||
},
|
||||
"providers": [
|
||||
"PragmaRX\\Google2FALaravel\\ServiceProvider"
|
||||
]
|
||||
},
|
||||
"component": "package",
|
||||
"frameworks": [
|
||||
"Laravel"
|
||||
],
|
||||
"branch-alias": {
|
||||
"dev-master": "0.2-dev"
|
||||
}
|
||||
},
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"PragmaRX\\Google2FALaravel\\": "src/",
|
||||
"PragmaRX\\Google2FALaravel\\Tests\\": "tests/"
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Antonio Carlos Ribeiro",
|
||||
"email": "acr@antoniocarlosribeiro.com",
|
||||
"role": "Creator & Designer"
|
||||
}
|
||||
],
|
||||
"description": "A One Time Password Authentication package, compatible with Google Authenticator.",
|
||||
"keywords": [
|
||||
"Authentication",
|
||||
"Two Factor Authentication",
|
||||
"google2fa",
|
||||
"laravel"
|
||||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/antonioribeiro/google2fa-laravel/issues",
|
||||
"source": "https://github.com/antonioribeiro/google2fa-laravel/tree/v2.3.0"
|
||||
},
|
||||
"time": "2025-02-26T19:39:35+00:00"
|
||||
},
|
||||
{
|
||||
"name": "pragmarx/google2fa-qrcode",
|
||||
"version": "v3.0.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/antonioribeiro/google2fa-qrcode.git",
|
||||
"reference": "ce4d8a729b6c93741c607cfb2217acfffb5bf76b"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/antonioribeiro/google2fa-qrcode/zipball/ce4d8a729b6c93741c607cfb2217acfffb5bf76b",
|
||||
"reference": "ce4d8a729b6c93741c607cfb2217acfffb5bf76b",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"php": ">=7.1",
|
||||
"pragmarx/google2fa": ">=4.0"
|
||||
},
|
||||
"require-dev": {
|
||||
"bacon/bacon-qr-code": "^2.0",
|
||||
"chillerlan/php-qrcode": "^1.0|^2.0|^3.0|^4.0",
|
||||
"khanamiryan/qrcode-detector-decoder": "^1.0",
|
||||
"phpunit/phpunit": "~4|~5|~6|~7|~8|~9"
|
||||
},
|
||||
"suggest": {
|
||||
"bacon/bacon-qr-code": "For QR Code generation, requires imagick",
|
||||
"chillerlan/php-qrcode": "For QR Code generation"
|
||||
},
|
||||
"type": "library",
|
||||
"extra": {
|
||||
"component": "package",
|
||||
"branch-alias": {
|
||||
"dev-master": "1.0-dev"
|
||||
}
|
||||
},
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"PragmaRX\\Google2FAQRCode\\": "src/",
|
||||
"PragmaRX\\Google2FAQRCode\\Tests\\": "tests/"
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Antonio Carlos Ribeiro",
|
||||
"email": "acr@antoniocarlosribeiro.com",
|
||||
"role": "Creator & Designer"
|
||||
}
|
||||
],
|
||||
"description": "QR Code package for Google2FA",
|
||||
"keywords": [
|
||||
"2fa",
|
||||
"Authentication",
|
||||
"Two Factor Authentication",
|
||||
"google2fa",
|
||||
"qr code",
|
||||
"qrcode"
|
||||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/antonioribeiro/google2fa-qrcode/issues",
|
||||
"source": "https://github.com/antonioribeiro/google2fa-qrcode/tree/v3.0.0"
|
||||
},
|
||||
"time": "2021-08-15T12:53:48+00:00"
|
||||
},
|
||||
{
|
||||
"name": "psr/clock",
|
||||
"version": "1.0.0",
|
||||
|
||||
@ -0,0 +1,28 @@
|
||||
<?php
|
||||
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
|
||||
return new class extends Migration
|
||||
{
|
||||
/**
|
||||
* Run the migrations.
|
||||
*/
|
||||
public function up(): void
|
||||
{
|
||||
Schema::table('users', function (Blueprint $table) {
|
||||
$table->text('google2fa_secret')->nullable()->after('github_refresh_token');
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Reverse the migrations.
|
||||
*/
|
||||
public function down(): void
|
||||
{
|
||||
Schema::table('users', function (Blueprint $table) {
|
||||
//
|
||||
});
|
||||
}
|
||||
};
|
||||
@ -0,0 +1,28 @@
|
||||
<?php
|
||||
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
|
||||
return new class extends Migration
|
||||
{
|
||||
/**
|
||||
* Run the migrations.
|
||||
*/
|
||||
public function up(): void
|
||||
{
|
||||
Schema::table('users', function (Blueprint $table) {
|
||||
$table->boolean('verify2fa')->default(false)->after('google2fa_secret');
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Reverse the migrations.
|
||||
*/
|
||||
public function down(): void
|
||||
{
|
||||
Schema::table('users', function (Blueprint $table) {
|
||||
//
|
||||
});
|
||||
}
|
||||
};
|
||||
@ -0,0 +1,35 @@
|
||||
@extends('layouts.app')
|
||||
|
||||
@section('content')
|
||||
<div class="bg-[#0d1b2a] min-h-screen flex justify-center items-center space-x-4">
|
||||
<div class="mt-10 bg-[#1b263b] p-6 rounded-xl shadow-xl max-w-[600px] w-full mx-auto transition-all duration-300">
|
||||
<h3 class="text-2xl font-semibold text-center text-[#e0e1dd] mb-6">
|
||||
Two Factor Authentication Setup
|
||||
</h3>
|
||||
|
||||
<div class="mb-6 text-center">
|
||||
<p class="text-sm text-[#e0e1dd] font-mono break-all mb-3">{{ $secret }}</p>
|
||||
<div class="flex justify-center">
|
||||
{!! $urlQRCode !!}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<form method="POST" action="{{ route('enable.2fa') }}" class="space-y-4">
|
||||
@csrf
|
||||
<input type="hidden" name="secret" value="{{ $secret }}">
|
||||
|
||||
<div>
|
||||
<label for="otp" class="block text-[#e0e1dd] mb-1 font-semibold">OTP Code</label>
|
||||
<input name="otp" type="text" placeholder="Enter your OTP code"
|
||||
class="w-full px-4 py-2 rounded-md bg-[#1b263b] border border-[#e0e1dd] text-[#e0e1dd] focus:outline-none focus:ring-2 focus:ring-blue-500" />
|
||||
<p class="text-red-400 mt-1 text-sm">@error('otp') {{ $message }} @enderror</p>
|
||||
</div>
|
||||
|
||||
<button type="submit"
|
||||
class="w-full cursor-pointer py-2 bg-blue-600 hover:bg-blue-700 text-white rounded-md font-semibold transition duration-300">
|
||||
Verify OTP
|
||||
</button>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
@endsection
|
||||
@ -0,0 +1,29 @@
|
||||
@extends('layouts.app')
|
||||
|
||||
@section('content')
|
||||
<div class="bg-[#0d1b2a] h-screen flex justify-center items-center space-x-6">
|
||||
<div
|
||||
class="flex justify-center items-center p-4 flex-wrap shadow-lg rounded-xl login-form size-150 max-w-[500px] bg-[#1b263b] h-auto text-center">
|
||||
<h1 class="w-full font-bold text-4xl text-[#e0e1dd]">Two Factor Secret Code</h1>
|
||||
|
||||
<div class="w-[90%] p-5">
|
||||
<p class="text-[#e0e1dd] text-xl mb-4 font-medium">
|
||||
Please enter your secret code to login
|
||||
</p>
|
||||
<form method="POST" action="{{route('secret.code')}}">
|
||||
@csrf
|
||||
<div class="text-left my-5">
|
||||
<label for="code" class="font-bold text-[#e0e1dd]">Code:</label>
|
||||
<input wire:model.lazy='code' name="code" type="text" placeholder="Enter your text"
|
||||
class="w-full my-2 px-4 py-2 border border-[#e0e1dd] text-[#e0e1dd] rounded-md shadow-sm focus:outline-none" />
|
||||
<p class="w-full text-red-500">@error('code') {{ $message }} @enderror</p>
|
||||
</div>
|
||||
<div class="mt-8">
|
||||
<button type="submit"
|
||||
class="border border-[#e0e1dd] font-medium w-full p-2 rounded-md bg-[#e0e1dd] cursor-pointer hover:opacity-85 transition duration-300 ease-in-out text-black">Submit</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@endsection
|
||||
@ -77,7 +77,7 @@
|
||||
{{-- Two Factor Authentication --}}
|
||||
<div class="bg-[#1b263b] rounded-xl shadow">
|
||||
@if (!$user->google2fa_secret)
|
||||
<form method="GET" action="#">
|
||||
<form method="GET" action="{{route('enable.2fa.show')}}">
|
||||
@csrf
|
||||
<button type="submit"
|
||||
class="w-full cursor-pointer px-6 py-3 border border-blue-600 text-white font-semibold rounded-lg hover:bg-blue-700 transition ease-in-out duration-300">
|
||||
@ -85,7 +85,7 @@
|
||||
</button>
|
||||
</form>
|
||||
@else
|
||||
<form method="POST" action="#">
|
||||
<form method="POST" action="{{route('disable.2fa')}}">
|
||||
@csrf
|
||||
<button type="submit"
|
||||
class="w-full cursor-pointer px-6 py-3 border border-red-600 text-white font-semibold rounded-lg hover:bg-red-700 transition ease-in-out duration-300">
|
||||
|
||||
@ -9,6 +9,7 @@ use App\Http\Controllers\Auth\LoginController;
|
||||
use App\Http\Controllers\Auth\LogoutController;
|
||||
use App\Http\Controllers\Auth\PasswordController;
|
||||
use App\Http\Controllers\Auth\RegisterController;
|
||||
use App\Http\Controllers\Auth\TwoFactorAuthenticationController;
|
||||
|
||||
Route::get('/', function () {
|
||||
return view('welcome');
|
||||
@ -21,7 +22,7 @@ Route::get('login', [LoginController::class, 'create'])->name('login');
|
||||
Route::post('login', [LoginController::class, 'store'])->name('login.store');
|
||||
|
||||
Route::group(['middleware' => 'auth'], function () {
|
||||
Route::get('dashboard', [DashboardController::class, 'index'])->name('dashboard');
|
||||
Route::get('dashboard', [DashboardController::class, 'index'])->middleware('2fa')->name('dashboard');
|
||||
|
||||
Route::post('logout', action: [LogoutController::class, 'logout'])->name('logout');
|
||||
Route::post('delete-account', action: [LogoutController::class, 'deleteAccount'])->name('delete.account');
|
||||
@ -29,6 +30,13 @@ Route::group(['middleware' => 'auth'], function () {
|
||||
//verify mail
|
||||
Route::post('email/verification-notification', [MailController::class, 'notification'])->name('verification.send');
|
||||
Route::get('email/verify/{id}/{hash}', [MailController::class, 'verify'])->name('verification.verify');
|
||||
|
||||
//verify two factor authentication
|
||||
Route::get('enable-2fa-show', [TwoFactorAuthenticationController::class, 'enable2FAShow'])->name('enable.2fa.show');
|
||||
Route::post('enable-2fa', [TwoFactorAuthenticationController::class, 'enable2FA'])->name('enable.2fa');
|
||||
Route::post('disable-2fa', [TwoFactorAuthenticationController::class, 'disable2FA'])->name('disable.2fa');
|
||||
Route::get('secret-code-show', [TwoFactorAuthenticationController::class, 'secretCodeShow'])->name('secret.code.show');
|
||||
Route::post('secret-code', [TwoFactorAuthenticationController::class, 'secretCode'])->name('secret.code');
|
||||
});
|
||||
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user