Skip to content

Fix PasswordHistory rule blocking first-time registration - #50

Merged
JYOTSANASHARMAA merged 1 commit into
mainfrom
bugs/password_history_blocks_registration
Jul 9, 2026
Merged

Fix PasswordHistory rule blocking first-time registration#50
JYOTSANASHARMAA merged 1 commit into
mainfrom
bugs/password_history_blocks_registration

Conversation

@sambhav-aggarwal

Copy link
Copy Markdown
Member

Bug (reported by a consuming-app developer — confirmed)

With the shipped default neev.password rules, PasswordHistory::notReused() fails with "Unable to verify password history." whenever it cannot resolve a user. First-time registration is exactly that case: no authenticated user, and User::findByEmail() returns null for an address that belongs to nobody yet. Every registration under the default config was rejected with a 422.

Corroborating evidence that this was being masked: the package's own RegistrationTest overrides the password rules in setUp() "to simplify" — which is why the suite never caught it.

Fix

When no user resolves, the rule now passes vacuously — a nonexistent user has no password history to reuse. All flows that do resolve a user (authenticated change-password, reset via id input, email-resolved flows) keep the full history check unchanged.

Tests

  • Rule unit test flipped: test_passes_when_no_user_found (was asserting the buggy failure)
  • New regression test registers against the actual shipped default rules (loaded from config/neev.php, not the test-simplified ones)
  • Suite 1005 green; Pint and PHPStan clean

Note on the second report (no code change)

The same developer asked about email_verification_method (link vs OTP): that config existed v0.3.0–v0.4.4 and was deliberately removed in v0.4.5 — verification is always a signed link now. Documented in CHANGELOG [0.4.5] and UPGRADING; a leftover key in an app's config is ignored.

With the shipped default neev.password rules, PasswordHistory::
notReused() failed with 'Unable to verify password history.' whenever
it could not resolve a user — which is precisely the first-time-signup
case: there is no authenticated user, and User::findByEmail() returns
null for an address that belongs to nobody yet. Result: every
registration under the default config was rejected with a 422.

The rule now passes vacuously when no user resolves: a nonexistent
user has no password history to reuse. Authenticated password change,
reset (id input), and email-resolved flows are unaffected — they all
resolve a user and keep the full history check.

The package's own RegistrationTest had been masking this by overriding
the password rules in setUp() 'to simplify'; a new regression test now
registers against the actual shipped default rules. Reported by a
consuming-app developer.
@chatgpt-codex-connector

Copy link
Copy Markdown

You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard.

@codecov-commenter

Copy link
Copy Markdown

Codecov Report

Caution

This repository is currently using the Sentry GitHub App to receive Codecov PR comments. This integration will be deprecated on July 8, 2026. Please install the Codecov GitHub App to continue receiving coverage reports on your pull requests.
✅ All modified and coverable lines are covered by tests.

📢 Thoughts on this report? Let us know!

@JYOTSANASHARMAA
JYOTSANASHARMAA merged commit caae608 into main Jul 9, 2026
4 checks passed
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.

3 participants