Repository navigation
Allow pending invitees to recover account access - #24911
Conversation
|
Could you please add a AI checklist to your PR description? |
chippison
left a comment
There was a problem hiding this comment.
Hi @drewmt
Thanks for looking into this. 👍
There is 1 thing that needs fixing below, and also please update the ###AI Checklist above that we need. This is a requirement for our repo now especially when AI was used for this fix. You can just leave it NA if you did not use AI for this.
Also 2 other minor things I found:
- The
initiatePasswordResetProcessdocblock (and the class docblock) still say the email contains a password-reset token — that's no longer true for the invitation branch, so it's worth updating. - The new fallback in
getUserInformationForPasswordResetInitiationcallsfindUserByLoginOrEmail()directly instead of going throughgetUserInformation(), which plugins are meant to be able to override. Routing it through an overridable method would keep that extension point intact.
chippison
left a comment
There was a problem hiding this comment.
Hi @drewmt ,
Aside from below, can I also ask why we still need the old(original) email link to be not be invalidated (and the original invitation token is not invalidated.)?
Would it be more simple to just invalidate the original email token when a new one is created?
|
Yes, agreed — the updated flow now keeps a single current activation token. Recovery replaces the original invitation token instead of creating a second valid credential, while preserving the existing invitation expiry. I also updated the PR description and added coverage for reassignment and concurrent email-change cases. |
) (#24944) Co-authored-by: drewmt <idrew.mt@gmail.com> Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
Description
Pending invitees currently reach the password recovery form because they have not set a password yet, but the flow treats them as invalid and sends no email.
This change lets an invitee with an unexpired pending invitation receive a fresh activation link from the recovery flow. The link points to
acceptInvitation, preserves the existinginvite_expired_atvalue, and shows the remaining validity in the email. Expired or malformed invitations still fail closed, while active users keep the existing password reset and cancellation flow.Recovery now atomically replaces the pending user's existing invitation token instead of creating a second valid activation credential. The update succeeds only when the login, previous token, email, and unexpired pending state still match. If acceptance, expiry, or an email reassignment wins the race, no stale link is sent and the temporary reset state is removed.
Re-inviting a pending user or changing the invitation email also clears any previously generated recovery link, so the previous mailbox owner cannot complete an outdated invitation.
The existing recovery request limit remains in place.
Fixes #20297
Validation
PasswordResetterTest: 17 tests, 77 assertions passed.ControllerTest: 7 tests, 9 assertions passed.UserInviteTest, including local HTTP acceptance and decline routes: 2 tests, 9 assertions passed.git diff --checkpassed.Checklist