diff --git a/config/devdojo/auth/descriptions.php b/config/devdojo/auth/descriptions.php
index b13ee64..0e90cf4 100644
--- a/config/devdojo/auth/descriptions.php
+++ b/config/devdojo/auth/descriptions.php
@@ -10,6 +10,7 @@
'registration_include_name_field' => 'During registration, include the Name field.',
'registration_require_email_verification' => 'During registration, require users to verify their email.',
'enable_branding' => 'This will toggle on/off the Auth branding at the bottom of each auth screen. Consider leaving on to support and help grow this project.',
- 'dev_mode' => 'This is for development mode, when set in Dev Mode Assets will be loaded from Vite'
+ 'dev_mode' => 'This is for development mode, when set in Dev Mode Assets will be loaded from Vite',
+ 'enable_2fa' => 'Enable the ability for users to turn on Two Factor Authentication'
]
];
\ No newline at end of file
diff --git a/package.json b/package.json
index 5f14614..858f918 100644
--- a/package.json
+++ b/package.json
@@ -18,6 +18,7 @@
"@invoate/alpine-query-string": "^1.0.0",
"highlightjs": "^9.16.2",
"phaser": "^3.80.1",
- "split.js": "^1.6.5"
+ "split.js": "^1.6.5",
+ "@tailwindcss/container-queries": "^0.1.1"
}
}
diff --git a/resources/views/components/elements/button.blade.php b/resources/views/components/elements/button.blade.php
index cf4d1fa..b7bb0f3 100644
--- a/resources/views/components/elements/button.blade.php
+++ b/resources/views/components/elements/button.blade.php
@@ -17,6 +17,19 @@
};
@endphp
+@php
+ $typeClasses = match ($type) {
+ 'primary' => '',
+ 'secondary' => 'bg-zinc-100 border text-gray-500 hover:text-gray-700 border-zinc-100 dark:focus:ring-offset-gray-900 dark:border-gray-400/10 active:bg-white dark:focus:ring-gray-700 focus:bg-white focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-gray-200/60 dark:bg-gray-800/50 dark:hover:bg-gray-800/70 dark:text-gray-400 focus:shadow-outline',
+ 'success' => 'bg-green-600 text-white hover:bg-green-600/90 focus:ring-2 focus:ring-offset-2 dark:focus:ring-offset-gray-900 focus:bg-green-700/90 focus:ring-green-700',
+ 'info' => 'bg-blue-600 text-white hover:bg-blue-600/90 focus:ring-2 focus:ring-offset-2 dark:focus:ring-offset-gray-900 focus:bg-blue-700/90 focus:ring-blue-700',
+ 'warning' => 'bg-amber-500 text-white hover:bg-amber-500/90 focus:ring-2 focus:ring-offset-2 dark:focus:ring-offset-gray-900 focus:bg-amber-600/90 focus:ring-amber-600',
+ 'danger' => 'bg-red-600 text-white hover:bg-red-600/90 focus:ring-2 focus:ring-offset-2 dark:focus:ring-offset-gray-900 focus:bg-red-700/90 focus:ring-red-700',
+ };
+
+ $loadingTarget = $attributes['wire:target'];
+@endphp
+
@php
switch ($tag ?? 'button') {
case 'button':
@@ -35,7 +48,7 @@
}
@endphp
-<{!! $tagAttr !!} {!! $attributes->except(['class']) !!} class="{{ $sizeClasses }} auth-component-button opacity-[95%] hover:opacity-100 focus:ring-2 focus:ring-offset-2 cursor-pointer inline-flex items-center w-full justify-center disabled:opacity-50 font-semibold focus:outline-none" style="color:{{ config('devdojo.auth.appearance.color.button_text') }}; background-color:{{ config('devdojo.auth.appearance.color.button') }};">
-
+<{!! $tagAttr !!} {!! $attributes->except(['class']) !!} class="@if($type == 'primary'){{ 'auth-component-button' }}@endif {{ $sizeClasses }} {{ $typeClasses }} opacity-[95%] hover:opacity-100 focus:ring-2 focus:ring-offset-2 cursor-pointer inline-flex items-center w-full justify-center disabled:opacity-50 font-semibold focus:outline-none" style="@if($type == 'primary') color:{{ config('devdojo.auth.appearance.color.button_text') }}; background-color:{{ config('devdojo.auth.appearance.color.button') }}; @endif">
+
{{ $slot }}
{{ $tagClose }}>
\ No newline at end of file
diff --git a/resources/views/components/elements/input-code.blade.php b/resources/views/components/elements/input-code.blade.php
index 12174f8..420cf32 100644
--- a/resources/views/components/elements/input-code.blade.php
+++ b/resources/views/components/elements/input-code.blade.php
@@ -31,6 +31,8 @@
this.$refs['input' + (index-1)].focus();
}
}
+ } else {
+ this.$refs['input' + index].value = '';
}
} else {
@@ -98,6 +100,7 @@ class="relative"
type="number"
x-on:paste="pasteValue"
x-on:keydown="moveCursorNext({{ $x }}, {{ $digits }}, event)"
+ x-on:focus="$el.select()"
class="w-12 h-12 font-light text-center text-black rounded-md border shadow-sm appearance-none auth-component-code-input dark:text-dark-400 border-zinc-200 focus:border-2"
maxlength="1"
/>
diff --git a/resources/views/pages/auth/login.blade.php b/resources/views/pages/auth/login.blade.php
index 266df09..2fcb050 100644
--- a/resources/views/pages/auth/login.blade.php
+++ b/resources/views/pages/auth/login.blade.php
@@ -41,6 +41,7 @@
public function mount(){
$this->loadConfigs();
+ $this->twoFactorEnabled = $this->settings->enable_2fa;
}
public function editIdentity(){
@@ -49,6 +50,7 @@ public function editIdentity(){
public function authenticate()
{
+
if(!$this->showPasswordField){
$this->validateOnly('email');
$this->showPasswordField = true;
diff --git a/resources/views/pages/auth/two-factor-challenge.blade.php b/resources/views/pages/auth/two-factor-challenge.blade.php
index c0dcce5..9d2bfea 100644
--- a/resources/views/pages/auth/two-factor-challenge.blade.php
+++ b/resources/views/pages/auth/two-factor-challenge.blade.php
@@ -5,6 +5,7 @@
use Illuminate\Support\Facades\Route;
use Illuminate\Auth\Events\Login;
use Livewire\Attributes\On;
+use Livewire\Attributes\Validate;
use Livewire\Volt\Component;
use PragmaRX\Google2FA\Google2FA;
use Devdojo\Auth\Traits\HasConfigs;
@@ -21,6 +22,7 @@
public $recovery = false;
public $google2fa;
+ #[Validate('required|min:5')]
public $auth_code;
public $recovery_code;
@@ -36,6 +38,7 @@ public function switchToRecovery()
if($this->recovery){
$this->js("setTimeout(function(){ console.log('made'); window.dispatchEvent(new CustomEvent('focus-auth-2fa-recovery-code', {})); }, 10);");
} else {
+ // TODO - this we need to autofocus the first input of the auth code input
$this->js("setTimeout(function(){ window.dispatchEvent(new CustomEvent('focus-auth-2fa-auth-code', {})); }, 10);");
}
return;
@@ -46,23 +49,28 @@ public function switchToRecovery()
#[On('submitCode')]
public function submitCode($code)
{
+ $this->auth_code = $code;
+
+ $this->validate();
+
if(empty($code) || strlen($code) < 5){
dd('show validation error');
return;
}
- $google2fa = new Google2FA();
- $valid = $google2fa->verifyKey($this->secret, $code);
+ $user = User::find(session()->get('login.id'));
+ $secret = decrypt($user->two_factor_secret);
+ $google2fa = new Google2FA();
+ $valid = $google2fa->verifyKey($secret, $code);
if($valid){
- $user = User::find(session()->get('login.id'));
Auth::login($user);
- event(new Login(auth()->guard('web'), User::where('email', $this->email)->first(), true));
+ event(new Login(auth()->guard('web'), $user, true));
return redirect()->intended('/');
} else {
-
+ dd('invalid');
}
}
@@ -141,7 +149,7 @@ public function submit_recovery_code(){
Incorrect Auth Code
+{{ $message }}
@enderrorWhen two factor authentication is enabled, you will be prompted for a secure, random token during authentication. You may retrieve this token from your phone's Google Authenticator application.
@if($showRecoveryCodes)Store these recovery codes in a secure password manager. They can be used to recover access to your account if your two factor authentication device is lost.
+Store these recovery codes in a secure password manager. They can be used to recover access to your account if your two factor authentication device is lost.
When two factor authentication is enabled, you will be prompted for a secure, random token during authentication. You may retrieve this token from your phone's Google Authenticator application.
+When you enabled 2FA, you will be prompted for a secure code during authentication. This code can be retrieved from your phone's Google Authenticator application.
When two factor authentication is enabled, you will be prompted for a secure, random token during authentication. You may retrieve this token from your phone's Google Authenticator application.
-To finish enabling two factor authentication, scan the following QR code using your phone's authenticator application or enter the setup key and provide the generated OTP code.
+Enable two-factor authentication to receive a secure token from your phone's Google Authenticator during login.
+To enable two-factor authentication, scan the QR code or enter the setup key using your phone's authenticator app and provide the OTP code.
+
{{ __('Setup Key') }}: {{ $secret }}