mirror of
https://github.com/BookStackApp/BookStack.git
synced 2025-07-28 17:02:04 +03:00
Added login redirect system to confirm/mfa
Also continued a bit on the MFA verification system. Moved some MFA routes to public space using updated login service to get the current user that is either logged in or last attempted login (With correct creds).
This commit is contained in:
@ -47,12 +47,11 @@ class ConfirmEmailController extends Controller
|
||||
/**
|
||||
* Shows a notice that a user's email address has not been confirmed,
|
||||
* Also has the option to re-send the confirmation email.
|
||||
*
|
||||
* @return View
|
||||
*/
|
||||
public function showAwaiting()
|
||||
{
|
||||
return view('auth.user-unconfirmed');
|
||||
$user = $this->loginService->getLastLoginAttemptUser();
|
||||
return view('auth.user-unconfirmed', ['user' => $user]);
|
||||
}
|
||||
|
||||
/**
|
||||
|
22
app/Http/Controllers/Auth/HandlesPartialLogins.php
Normal file
22
app/Http/Controllers/Auth/HandlesPartialLogins.php
Normal file
@ -0,0 +1,22 @@
|
||||
<?php
|
||||
|
||||
namespace BookStack\Http\Controllers\Auth;
|
||||
|
||||
use BookStack\Auth\Access\LoginService;
|
||||
use BookStack\Auth\User;
|
||||
use BookStack\Exceptions\NotFoundException;
|
||||
|
||||
trait HandlesPartialLogins
|
||||
{
|
||||
protected function currentOrLastAttemptedUser(): User
|
||||
{
|
||||
$loginService = app()->make(LoginService::class);
|
||||
$user = auth()->user() ?? $loginService->getLastLoginAttemptUser();
|
||||
|
||||
if (!$user) {
|
||||
throw new NotFoundException('A user for this action could not be found');
|
||||
}
|
||||
|
||||
return $user;
|
||||
}
|
||||
}
|
@ -10,6 +10,8 @@ use Exception;
|
||||
|
||||
class MfaBackupCodesController extends Controller
|
||||
{
|
||||
use HandlesPartialLogins;
|
||||
|
||||
protected const SETUP_SECRET_SESSION_KEY = 'mfa-setup-backup-codes';
|
||||
|
||||
/**
|
||||
@ -39,7 +41,7 @@ class MfaBackupCodesController extends Controller
|
||||
}
|
||||
|
||||
$codes = decrypt(session()->pull(self::SETUP_SECRET_SESSION_KEY));
|
||||
MfaValue::upsertWithValue(user(), MfaValue::METHOD_BACKUP_CODES, json_encode($codes));
|
||||
MfaValue::upsertWithValue($this->currentOrLastAttemptedUser(), MfaValue::METHOD_BACKUP_CODES, json_encode($codes));
|
||||
|
||||
$this->logActivity(ActivityType::MFA_SETUP_METHOD, 'backup-codes');
|
||||
return redirect('/mfa/setup');
|
||||
|
@ -5,15 +5,19 @@ namespace BookStack\Http\Controllers\Auth;
|
||||
use BookStack\Actions\ActivityType;
|
||||
use BookStack\Auth\Access\Mfa\MfaValue;
|
||||
use BookStack\Http\Controllers\Controller;
|
||||
use BookStack\Http\Request;
|
||||
|
||||
class MfaController extends Controller
|
||||
{
|
||||
use HandlesPartialLogins;
|
||||
|
||||
/**
|
||||
* Show the view to setup MFA for the current user.
|
||||
*/
|
||||
public function setup()
|
||||
{
|
||||
$userMethods = user()->mfaValues()
|
||||
$userMethods = $this->currentOrLastAttemptedUser()
|
||||
->mfaValues()
|
||||
->get(['id', 'method'])
|
||||
->groupBy('method');
|
||||
return view('mfa.setup', [
|
||||
@ -41,14 +45,26 @@ class MfaController extends Controller
|
||||
/**
|
||||
* Show the page to start an MFA verification.
|
||||
*/
|
||||
public function verify()
|
||||
public function verify(Request $request)
|
||||
{
|
||||
$userMethods = user()->mfaValues()
|
||||
// TODO - Test this
|
||||
$desiredMethod = $request->get('method');
|
||||
$userMethods = $this->currentOrLastAttemptedUser()
|
||||
->mfaValues()
|
||||
->get(['id', 'method'])
|
||||
->groupBy('method');
|
||||
|
||||
// Basic search for the default option for a user.
|
||||
// (Prioritises totp over backup codes)
|
||||
$method = $userMethods->has($desiredMethod) ? $desiredMethod : $userMethods->keys()->sort()->reverse()->first();
|
||||
$otherMethods = $userMethods->keys()->filter(function($userMethod) use ($method) {
|
||||
return $method !== $userMethod;
|
||||
})->all();
|
||||
|
||||
return view('mfa.verify', [
|
||||
'userMethods' => $userMethods,
|
||||
'method' => $method,
|
||||
'otherMethods' => $otherMethods,
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
@ -6,12 +6,15 @@ use BookStack\Actions\ActivityType;
|
||||
use BookStack\Auth\Access\Mfa\MfaValue;
|
||||
use BookStack\Auth\Access\Mfa\TotpService;
|
||||
use BookStack\Auth\Access\Mfa\TotpValidationRule;
|
||||
use BookStack\Exceptions\NotFoundException;
|
||||
use BookStack\Http\Controllers\Controller;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Validation\ValidationException;
|
||||
|
||||
class MfaTotpController extends Controller
|
||||
{
|
||||
use HandlesPartialLogins;
|
||||
|
||||
protected const SETUP_SECRET_SESSION_KEY = 'mfa-setup-totp-secret';
|
||||
|
||||
/**
|
||||
@ -39,6 +42,7 @@ class MfaTotpController extends Controller
|
||||
* Confirm the setup of TOTP and save the auth method secret
|
||||
* against the current user.
|
||||
* @throws ValidationException
|
||||
* @throws NotFoundException
|
||||
*/
|
||||
public function confirm(Request $request)
|
||||
{
|
||||
@ -51,7 +55,7 @@ class MfaTotpController extends Controller
|
||||
]
|
||||
]);
|
||||
|
||||
MfaValue::upsertWithValue(user(), MfaValue::METHOD_TOTP, $totpSecret);
|
||||
MfaValue::upsertWithValue($this->currentOrLastAttemptedUser(), MfaValue::METHOD_TOTP, $totpSecret);
|
||||
session()->remove(static::SETUP_SECRET_SESSION_KEY);
|
||||
$this->logActivity(ActivityType::MFA_SETUP_METHOD, 'totp');
|
||||
|
||||
|
@ -140,9 +140,9 @@ class SocialController extends Controller
|
||||
}
|
||||
|
||||
$user = $this->registrationService->registerUser($userData, $socialAccount, $emailVerified);
|
||||
$this->showSuccessNotification(trans('auth.register_success'));
|
||||
$this->loginService->login($user, $socialDriver);
|
||||
|
||||
$this->showSuccessNotification(trans('auth.register_success'));
|
||||
return redirect('/');
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user