mirror of
https://github.com/projectsend/projectsend.git
synced 2026-10-03 21:03:17 +00:00
37c9cb839f
Saving a settings form could open Inertia's error dialog showing
{"count":0}. back() prefers the Referer and falls back to the URL the
session recorded last. Laravel records every GET not marked as Ajax, and
the notification bell's plain fetch() of its unread count is not marked,
so the poll became "the previous page". Where the Referer did not arrive,
because a proxy or a browser stripped it, the save redirected to
/notifications/unread-count, and Inertia rendered the JSON as an error.
The session middleware is swapped for a subclass that skips recording
when the request asked for JSON. The rule is about the request, not about
that one route: nothing that asked for JSON is a page anybody goes back
to. Inertia visits ask for HTML and are recorded as before, and the
middleware order is unchanged (the sorter matches the subclass by its
parent).
A test reproduces it: open the privacy form, poll the count the way the
bell does, and save with no Referer. It failed with a redirect to
/notifications/unread-count before this change.
Reported by @0xVavaldi (#1799)
39 lines
1.3 KiB
PHP
39 lines
1.3 KiB
PHP
<?php
|
|
|
|
declare(strict_types=1);
|
|
|
|
namespace App\Http\Middleware;
|
|
|
|
use Illuminate\Http\Request;
|
|
use Illuminate\Session\Middleware\StartSession as FrameworkStartSession;
|
|
use Illuminate\Contracts\Session\Session;
|
|
|
|
/**
|
|
* The framework's session middleware, except that a request asking for
|
|
* JSON is never remembered as "the previous page".
|
|
*
|
|
* `back()` prefers the Referer header and falls back to the URL the
|
|
* session recorded last. Laravel records every GET not marked as Ajax,
|
|
* and a plain fetch() is not marked. So the notification bell's poll for
|
|
* its unread count became the previous page. Wherever the Referer did not
|
|
* arrive, because a proxy or a browser stripped it, saving any settings
|
|
* form redirected to /notifications/unread-count, and Inertia showed the
|
|
* raw {"count":0} in an error dialog (#1799).
|
|
*
|
|
* The rule is about the request, not about that one route: nothing that
|
|
* asked for JSON is a page anybody goes back to. Inertia visits ask for
|
|
* HTML, so they are recorded exactly as before.
|
|
*/
|
|
class StartSession extends FrameworkStartSession
|
|
{
|
|
protected function storeCurrentUrl(Request $request, $session): void
|
|
{
|
|
if ($request->wantsJson()) {
|
|
return;
|
|
}
|
|
|
|
/** @var Session $session */
|
|
parent::storeCurrentUrl($request, $session);
|
|
}
|
|
}
|