Send confirmation email to pending email with appropriate copy#1447
Send confirmation email to pending email with appropriate copy#1447
Conversation
Override Devise's send_confirmation_instructions on User to always route to unconfirmed_email when present, fixing flows where the confirmation was sent to the old email instead of the new one. Branch the confirmation email subject, HTML, and text templates: - Welcome invite (new users): unchanged - Reconfirmation (email change): new subject, CTA, and copy Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Add User model spec for send_confirmation_instructions override verifying it routes to unconfirmed_email when present. Update ProcessEmailChange and ProcessEmailManualConfirm specs to assert the DeviseMailer receives the correct `to:` address rather than just checking that send_confirmation_instructions was called. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Ensure DeviseMailer stub is set up after user factory creation so the on-create confirmation email doesn't inflate the mock count. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Devise 5.0.3 calls deliver_now instead of deliver_later, so mock mail doubles need to allow deliver_now. Also guard the confirm_within template reference since the app doesn't set a token expiry. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
| end | ||
| end | ||
|
|
||
| def authenticate_user! |
There was a problem hiding this comment.
Do we actually need to override this method at all? The only thing unique I see in it is the ahoy stuff but from the ahoy docs:
Users
Ahoy automatically attaches the current_user to the visit. With [Devise](https://github.com/heartcombo/devise), it attaches the user even if they sign in after the visit starts.
With other authentication frameworks, add this to the end of your sign in method:
ahoy.authenticate(user)
I don't have the full context on ahoy though, just point out what I found.
There was a problem hiding this comment.
we're using it for more than just visits and normal "events" -- it's also for model lifecycle tracking incl w callbacks and i couldn't figure out a different way to make sure it always had current_user in those situations.
There was a problem hiding this comment.
we prob should consider the papertrail gem or something like that instead, but it's a small enough app that this ahoy adaptation seemed worth it for all analytics data to end up in the same tables.
There was a problem hiding this comment.
I understand that ahoy needs the current user but I don't understand why we need ahoy.authenticate explicitly.
In a normal devise setup we would keep our before_action authenticate_user and that would use the devise method. The ahoy documents also say if you are using devise it automatically attaches the current_user to the visit.
It goes on to say for other frameworks you would call ahoy.authenticate.
Here is our overriding method
def authenticate_user!
return super if devise_controller?
if user_signed_in?
ahoy.authenticate(current_user)
else
redirect_to root_path
end
end
The only thing in it ahoy.authenticate. I guess I don't understand why we need to override it if devise and ahoy already work together. We also lose the devise redirect behave when we just redirect to the root_path.
There was a problem hiding this comment.
If i'm missing something regarding the ahoy flow, maybe pulling out the ahoy stuff to its own method would work instead of overriding authenticate_user
before_action :authenticate_user!
before_action :track_user_with_ahoy
def track_user_with_ahoy
ahoy.authenticate(current_user) if user_signed_in?
end
There was a problem hiding this comment.
oooo! love this suggestion!
There was a problem hiding this comment.
thought it needs to also guard for if devise_controller, bc we don't want to run the ahoy thing in that case
There was a problem hiding this comment.
def authenticate_user! by default goes to new_session_path, so we need that override to send them to root_path. still, separating the concerns is a solid idea.
443c8e8 to
df63986
Compare
Summary
Test plan
🤖 Generated with Claude Code