Skip to content

🐛 Fix the anti-lockout allow-list when Nova is mounted at the root ("/") path - #4

Merged
mikaelpopowicz merged 1 commit into
mainfrom
fix/root-nova-path
Sep 25, 2026
Merged

mikaelpopowicz merged 1 commit into
mainfrom
fix/root-nova-path

Conversation

@mikaelpopowicz

Copy link
Copy Markdown
Collaborator

Problem

When Nova is mounted at the root path (config('nova.path') = '/'), EnsureTwoFactorEnabled fails to allow-list the User Security enrolment subtree — so an un-enrolled admin is redirected away from the very page where they'd set up 2FA (lockout / redirect loop).

Cause

$novaPath = trim(Nova::path(), '/'); // "" when the path is "/"
$request->is("{$novaPath}/user-security", ...) // → "/user-security"

Request::is() matches against the slash-less decodedPath() (user-security), so the leading-slash pattern /user-security never matches.

Fix

Build the prefix with a trailing slash only when there is one, so the patterns become user-security / user-security/* at the root:

$novaPath = trim(Nova::path(), '/');
$prefix = $novaPath === '' ? '' : "{$novaPath}/";
$request->is("{$prefix}user-security", "{$prefix}user-security/*")

Tests

Added two tests with config(['nova.path' => '/']): the enrolment subtree is allow-listed, and an un-enrolled admin is still redirected. Pint ✅ · PHPStan ✅ · Pest 45 tests, 100% coverage.

The nova-password-rotation and filament-password-rotation middlewares were checked too — they gate by route name, not path, so they're unaffected (regression tests for the / path added there as well).

…/") path

trim(Nova::path(), '/') empties a root path, so "{$novaPath}/user-security" became
"/user-security" — which never matches Request::is()'s slash-less path, blocking
the 2FA enrolment subtree and locking admins out. Build the prefix with a trailing
slash only when there is one.
Copilot AI lite review requested due to automatic review settings September 25, 2026 12:51

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot review overview

🟢 Approval recommended

No unresolved issues were identified, and all reviewers assessed it as ready.

Review effort: Lite
Findings: None

What changed in this PR

Fixes Nova’s anti-lockout path matching when mounted at /, preserving access to the 2FA enrollment flow.

Changes:

  • Corrects root-safe User Security path patterns.
  • Adds regression tests for access and redirect behavior.
File Summary
tests/​Feature/​MiddlewareTest.php Adds root-path enrollment and redirect coverage.
src/​Http/​Middleware/​EnsureTwoFactorEnabled.php Corrects allow-list matching for root-mounted Nova.

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

@mikaelpopowicz
mikaelpopowicz merged commit 7cb105a into main Sep 25, 2026
9 checks passed
@mikaelpopowicz
mikaelpopowicz deleted the fix/root-nova-path branch September 25, 2026 12:53
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.

2 participants