Skip to content

Show the app's own error pages, and drop a guard that guarded nothing - #13

Merged
SourovCodes merged 1 commit into
mainfrom
chore/drop-dead-verified-middleware
Sep 20, 2026
Merged

SourovCodes merged 1 commit into
mainfrom
chore/drop-dead-verified-middleware

Conversation

@SourovCodes

Copy link
Copy Markdown
Member

Two bits of drift from ProductSync, which had both already.

Error pages

A 403, 404 or 500 dropped the user out of the app onto Laravel's plain stock page — sidebar, theme and every way back gone, in an app they were signed into a moment earlier.

They render inside the app now:

  • 403 and 404 always.
  • 500 and 503 only where debug mode is off, so the debug screen still wins locally.
  • 419 is not worth a page at all: an expired session flashes a toast and sends the user back to the form they were already looking at.
  • Anything else passes through untouched, and JSON callers keep their JSON.

If the app cannot render — database down, assets not built — the handler falls back to the stock page rather than failing twice. That branch is not theoretical: it is what caught me while writing these tests, because the Vite manifest did not yet contain error-page.tsx and the fallback quietly did its job.

An ErrorBoundary goes around the app for the other half of the problem: a render error unmounts the React tree and leaves a white screen, which says even less than the stock page does.

The dead guard

Every workspace route carried 'verified', and it did nothing. Laravel's EnsureEmailIsVerified only bites when the user implements MustVerifyEmail, and this User never did — so it passed everyone through while reading as though it protected them.

Implementing the contract is not the fix: there is no verification flow here to send anyone to. 3agApp/Accounts#4 stops Accounts issuing a code for an unverified address, and the SSO callback already refuses an explicit email_verified of false behind it.

email_verified_at stays — it records when this app first saw Accounts vouch for the address.

Also

.env.example now points at https://accounts.test, which it has needed since the move to Herd left it naming an artisan serve port nothing listens on.

Testing

Six new ErrorPageTest cases covering each status, the debug-mode split, the JSON path and the 419 toast. Full suite, Pint, PHPStan, vp check and tsc --noEmit clean. Also confirmed the 404 renders in a real browser against the local Herd site.

🤖 Generated with Claude Code

Two bits of drift from ProductSync, which had both already.

A 403, 404 or 500 dropped the user out of the app onto Laravel's plain
stock page -- the sidebar, the theme and every way back gone, in an app
they were signed into a moment earlier. They render inside the app now:
403 and 404 always, 500 and 503 only where debug mode is off, so the debug
screen still wins locally. A 419 is not worth a page at all, so an expired
session flashes a toast and sends the user back to the form they were
already looking at. If the app cannot render -- database down, assets not
built -- the handler falls back to the stock page rather than failing
twice, which is what it did while I was writing the tests for it.

An ErrorBoundary goes around the app for the other half of the problem: a
render error unmounts the React tree and leaves a white screen, which says
even less than the stock page does.

The other bit is a `verified` middleware on every workspace route that did
nothing. EnsureEmailIsVerified only bites when the user implements
MustVerifyEmail, and this User never did, so it passed everyone through
while reading as though it protected them. Implementing the contract is not
the fix: there is no verification flow here to send anyone to, and 3AG
Accounts now refuses to issue a code for an unverified address, with the
SSO callback refusing an explicit email_verified of false behind it.

Also point .env.example at accounts.test, which it has needed since the
move to Herd left it naming an artisan serve port nothing listens on.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@SourovCodes
SourovCodes merged commit bb9ebec into main Sep 20, 2026
1 check passed
@SourovCodes
SourovCodes deleted the chore/drop-dead-verified-middleware branch September 20, 2026 05:44
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant