Added back email confirmation check in middleware

During writing of the update notes, found that the upgrade path would be
tricky from a security point of view. If people were pending email
confirmation but had an active session, they could technically be
actively logged in after the next release.

Added middlware as an extra precaution for now.
This commit is contained in:
Dan Brown 2021-08-30 21:28:17 +01:00
parent 3e870c30e1
commit 2740603d99
No known key found for this signature in database
GPG Key ID: 46D9F943C24A2EF9
3 changed files with 66 additions and 0 deletions

View File

@ -30,6 +30,7 @@ class Kernel extends HttpKernel
\Illuminate\Session\Middleware\StartSession::class,
\Illuminate\View\Middleware\ShareErrorsFromSession::class,
\BookStack\Http\Middleware\VerifyCsrfToken::class,
\BookStack\Http\Middleware\CheckEmailConfirmed::class,
\BookStack\Http\Middleware\RunThemeActions::class,
\BookStack\Http\Middleware\Localization::class,
],
@ -38,6 +39,7 @@ class Kernel extends HttpKernel
\BookStack\Http\Middleware\EncryptCookies::class,
\BookStack\Http\Middleware\StartSessionIfCookieExists::class,
\BookStack\Http\Middleware\ApiAuthenticate::class,
\BookStack\Http\Middleware\CheckEmailConfirmed::class,
],
];

View File

@ -0,0 +1,48 @@
<?php
namespace BookStack\Http\Middleware;
use BookStack\Auth\Access\EmailConfirmationService;
use BookStack\Auth\User;
use Closure;
/**
* Check that the user's email address is confirmed.
*
* As of v21.08 this is technically not required but kept as a prevention
* to log out any users that may be logged in but in an "awaiting confirmation" state.
* We'll keep this for a while until it'd be very unlikely for a user to be upgrading from
* a pre-v21.08 version.
*
* Ideally we'd simply invalidate all existing sessions upon update but that has
* proven to be a lot more difficult than expected.
*/
class CheckEmailConfirmed
{
protected $confirmationService;
public function __construct(EmailConfirmationService $confirmationService)
{
$this->confirmationService = $confirmationService;
}
/**
* Handle an incoming request.
*
* @param \Illuminate\Http\Request $request
* @param \Closure $next
* @return mixed
*/
public function handle($request, Closure $next)
{
/** @var User $user */
$user = auth()->user();
if (auth()->check() && !$user->email_confirmed && $this->confirmationService->confirmationRequired()) {
auth()->logout();
return redirect()->to('/');
}
return $next($request);
}
}

View File

@ -459,6 +459,22 @@ class AuthTest extends BrowserKitTest
$this->assertFalse($log->hasWarningThatContains('Failed login for admin@admin.com'));
}
public function test_logged_in_user_with_unconfirmed_email_is_logged_out()
{
$this->setSettings(['registration-confirmation' => 'true']);
$user = $this->getEditor();
$user->email_confirmed = false;
$user->save();
auth()->login($user);
$this->assertTrue(auth()->check());
$this->get('/books');
$this->assertRedirectedTo("/");
$this->assertFalse(auth()->check());
}
/**
* Perform a login.
*/