63 lines
2.6 KiB
PHP
63 lines
2.6 KiB
PHP
<?php
|
|
|
|
namespace App\Http\Responses;
|
|
|
|
use App\Support\AdminArea;
|
|
use Illuminate\Http\JsonResponse;
|
|
use Illuminate\Http\RedirectResponse;
|
|
use Illuminate\Support\Facades\Auth;
|
|
use Laravel\Fortify\Fortify;
|
|
use Symfony\Component\HttpFoundation\Response;
|
|
|
|
/**
|
|
* Where a completed sign-in lands, shared by both ways of completing one.
|
|
*
|
|
* Fortify has two exits: LoginResponse for an ordinary sign-in, and
|
|
* TwoFactorLoginResponse after a challenge. Binding only the first left every
|
|
* account with two-factor enabled on the old behaviour — landing in the
|
|
* customer portal, and on a console-only host landing on a 404. Whichever exit
|
|
* is taken, the decision has to be the same one.
|
|
*/
|
|
trait LandsWhereSignedIn
|
|
{
|
|
protected function landing($request, JsonResponse $success): Response
|
|
{
|
|
// Where they were heading counts as much as where they posted from: in
|
|
// shared mode everyone signs in at /login, so the request itself never
|
|
// looks like the console even when /admin is the destination.
|
|
$onConsole = AdminArea::isConsole($request)
|
|
|| AdminArea::pointsAtConsole($request->session()?->get('url.intended'));
|
|
|
|
// Authorization first, before any branch. Answering JSON early let a
|
|
// non-operator keep the session on the console host that a browser
|
|
// request would have had taken away.
|
|
if ($onConsole && ! $request->user()?->can('console.view')) {
|
|
// Taken away at the moment it was created: the session exists as
|
|
// soon as Fortify authenticates, and a guard that merely refuses
|
|
// each page afterwards leaves it sitting in the browser.
|
|
Auth::guard('web')->logout();
|
|
$request->session()->invalidate();
|
|
$request->session()->regenerateToken();
|
|
|
|
if ($request->wantsJson()) {
|
|
return new JsonResponse(['message' => __('auth.not_an_operator')], 403);
|
|
}
|
|
|
|
return redirect()->to(AdminArea::home())->withErrors([
|
|
Fortify::username() => __('auth.not_an_operator'),
|
|
]);
|
|
}
|
|
|
|
// Fortify answers JSON to a JSON client. Replacing that with a redirect
|
|
// would break every caller that is not a browser.
|
|
if ($request->wantsJson()) {
|
|
// The caller supplies it: Fortify answers {"two_factor":false} to an
|
|
// ordinary sign-in and an empty 204 after a challenge, and a client
|
|
// keying off the status code breaks if the two are merged.
|
|
return $success;
|
|
}
|
|
|
|
return redirect()->intended($onConsole ? AdminArea::home() : Fortify::redirects('login'));
|
|
}
|
|
}
|