devise: Initial confirmation email not being sent
Per the documentation “Confirmation instructions are sent to the user email after creating a record and when manually requested by a new confirmation instruction request.”. However, in my deployment I’m currently not receiving the confirmation emails on initial user creation. The manual request for a confirmation is working perfectly.
I am unsure if it is some side effect of a configuration that I have. I am able to resolve the issue by adding the following code change to send_confirmation_notification?
to consider the unconfirmed_email as the email value is initially blank:
# lib/devise/models/confirmable.rb
def send_confirmation_notification?
confirmation_required? && !@skip_confirmation_notification && (!self.email.blank? || !self.unconfirmed_email.blank?)
end
I’m running with Devise 3.1.1 and have the following config settings related to confirmations:
# config/devise.rb
config.allow_unconfirmed_access_for = 0.days
config.confirm_within = 3.days
config.reconfirmable = true
Curious if anybody else is seeing this issue or comments / thoughts on the implications of the code change I have made?
Thanks!
About this issue
- Original URL
- State: closed
- Created 11 years ago
- Reactions: 2
- Comments: 25 (4 by maintainers)
Commits related to this issue
- fix: devise now send confirmation email in sign_up https://github.com/plataformatec/devise/issues/2688#issuecomment-243728805 — committed to recipyhq/recipy by deleted user 6 years ago
I’m having this issue too. And it’s apparently because of DeviseTokenAuth, for me:
Removing the DeviseTokenAuth concerns solves this issue, as does placing it above the devise settings. However, I’ve currently not tested whether the tokens still work…
My fixed User class:
For now, I have a hugly workaround: In my User model, I added this:
Works like a charm… except that I suspect a
skip_confirmation
call would work anymore 😕Any help is more than welcome
Same issue with three solutions. I discovered it using devise_invitable and when sending a new invite I got the error:
An SMTP To address is required to send a message. Set the message smtp_envelope_to, to, cc, or bcc address.
After tracing through devise_invitable and devise, I determined it happened during
if save(:validate => false)
in the class instance methodinvite!
inlib/devise_invitable/model.rb
. After checking the callbacks I focused on the devisebefore_update
callbackpostpone_email_change_until_confirmation_and_regenerate_confirmation_token
.By itself, this callback isn’t an issue even with devise_invitable. As described by others, the problem occurs when another save happens during creation (typically within
after_create
,after_save
, orafter_commit
). This will trigger the update flow and callbacks which leads topostpone_email_change_until_confirmation_and_regenerate_confirmation_token
.At this point,
self.email = self.email_was
sets email to""
.self.email_was
is part of ActiveModel::Dirty. Because the same model instance is being used,self.email_was
returns""
- becauseemail
did not have a previous value when the record was created. Devise is assuming that the change in email is due to an update and not because of the creation. This assumption plays out here as it relies uponemail_changed?
(also from ActiveModel::Dirty) and if this new email should be reconfirmed.The following user model code produces the issue. In this example,
sign_in_count
will be set 1 only if 0 and then saves.You can then verify it in the console.
Create user and see that email is present in the
user
instance:user = User.new(email: "sim@ple.ton", password:"simpleton", password_confirmation: "simpleton")
Save user:
user.save
Check user and email is now
""
:user
Check last user stored and email is present:
User.last
Obviously a trivial example, but I found the issue because I had an
after_save
that was updating the username to a default that had the userid
as part of the username. This could only happen after the record was saved so I could use the assignedid
.The following solutions have been tested only so far that the model instance
email
is not set to""
.Solution 1
Use
skip_reconfirmation!
to bypasspostpone_email_change_until_confirmation_and_regenerate_confirmation_token
during this update. I prefer this and it works well.Solution 2
Make the updates after creation only if confirmation has occurred. This only works for
after_save
andafter_commit
.after_create
only fires once upon creation so it would never execute the code.Solution 3
Force a record reload before making updates. This fulfills the devise assumption concerning the state of the instance though it is another database hit.
Same here, @lkol’s “config.reconfirmable = false” did resolve this, wondering what the implication might be?
I was experiencing the same problem and was only able to resolve it by setting
config.reconfirmable = false
for now. If the field is set as true, the original confirmation email won’t be sent.