Devise - create user account with confirmed without sending out an email? - ruby-on-rails

I integrated devise with facebook. Now when I create a user account after the user has logged in with his/her facebook account,
user = User.create(:email => data["email"],
:password => Devise.friendly_token[0,20])
user.confirmed_at = DateTime.now
user.save!
even though the account has been confirmed, an confirmation email is still fired. Any idea how I can turn the email firing off?

The confirm callback happens after create, so it's happening on line 1 of your example, before you set confirmed_at manually.
As per the comments, the most correct thing to do would be to use the method provided for this purpose, #skip_confirmation!. Setting confirmed_at manually will work, but it circumvents the provided API, which is something which should be avoided when possible.
So, something like:
user = User.new(user_attrs)
user.skip_confirmation!
user.save!
Original answer:
If you pass the confirmed_at along with your create arguments, the mail should not be sent, as the test of whether or not an account is already "confirmed" is to look at whether or not that date is set.
User.create(
:email => data['email'],
:password => Devise.friendly_token[0,20],
:confirmed_at => DateTime.now
)
That, or just use new instead of create to build your user record.

If you just want to prevent sending the email, you can use #skip_confirmation_notification, like so:
user = User.new(your, args)
user.skip_confirmation_notification!
user.save!
See documentation
Skips sending the confirmation/reconfirmation notification email
after_create/after_update. Unlike #skip_confirmation!, record still
requires confirmation.

Open up the Rails console
rails c
Note the user (through id) or using rails helper methods, eg. first, last.
Create a variable to hold the user.
user = User.last
Use the skip_confirmation helper to confirm the user, then save.
user.skip_confirmation
user.save

Related

Devise skip reconfirmation

I need to skip, not the confirmation email, but REconfirmation emails.
Suppose I have a user with a confirmed email. I want to manually change its email for testing/support purposes
u.email # => email1#example.com
u.email = 'email2#example.com'
u.save
u.email # => email1#example.com
u.unconfirmed_email # 'email2#example.com'
I tried u.skip_confirmation! before and after saving but it doesn't seem to help for reconfirmation emails... the unconfirmed email is not transferred to the email field
Is there any way to force the new unconfirmed email to switch to the normal email ?
That method only skips sending of mail, that does not confirm the new mail which is stored in unconfirmed_mail. maybe you could just confirm the user manually like u.confirm.
confirm method works only after object is saved.
To skip reconfirmation email notification use : skip_confirmation_notification!
Here is the Code reference.
Or try skip_reconfirmation! this may confirm new email and avoid sending email notification. I have not used it but I understand so from the comment in code reference above(next method of skip_confirmation_notification! defination). so try it and let me know.

Devise .skip_confirmation! is not saving

I have added a custom method to my (Devise) User controller:
def confirm
#user = User.find(params[:id])
#user.skip_confirmation!
respond_to
if #user.save
//display success message
else
// display error message
end
end
end
When I try to confirm a user via that, the save fails and I have two errors in #user.errors: password and password_confirm
Even in the rails console, if I try
#user.skip_confirmation!
#save
I get a rollback and the save fails.
Any ideas would be appreciated..
Additional Info
The problem causing this is the
validates_presence_of :password, :password_confirmation
in my User model. Even though a password and password confirmation was entered by the user on signup, those get hashed together to make the encrypted_password. For example, when I find a user in the console, the user has an encrypted_password, but no password or password_confirmation.
I have tried this
validates_presence_of :password, :password_confirmation, :on => :create
However it doesn't force the user to enter both a password and a confirm on the Change Password screen.
Any idea on how to get around this?
I think you're misunderstanding what skip_confirmation! does.
Devise's confirmable module will send a new user an e-mail with a link back to your app. Until they click that link, they'll be "unconfirmed" and unable to sign in. What skip_confirmation! does is skip this workflow -- the user will be immediately confirmed, and can log in without first having to go through the e-mail confirmation flow.
You're getting the error you're getting because of validations on the user model. In particular, the user you're trying to save doesn't appear to have an existing password, so it's requiring a password and matching password_confirmation attribute.
I suspect that there's a better way to accomplish whatever your purpose is. Why isn't the normal confirmation workflow sufficient? What's this extra controller action trying to accomplish?
I think skip_confirmation! actually does the saving.
What you want to check is probably if #user.persisted?

Preventing Devise from sending an email when changing password

I am using Devise with my Rails 3 application. The current behavior for resetting a password, is to click on the "Forgot your password?" link. The link here is:
(url)/password/new.user
Which will call the following method in the Devise passwords_controller.rb:
def new
build_resource({})
end
This method will do:
generates the password reset token and adds it to the database,
sends an email to the person with a link that includes the token:
(url)/password/edit?reset_password_token=xxxxxxxxxxxxxxx
Is there any way to convince Devise to perform step 1 ONLY and not step 2? Are there any security issues I should be aware of if this is possible, and I did take this approach in an effort to simplify a portion of the web site.
I would recommend overriding send_devise_notification on your User (?) model and return true when the notification value is :reset_password_instructions. Something like this:
# app/models/user.rb
def send_devise_notification(notification)
return true if notification == :reset_password_instructions
end
Check their example on how to override/customize behavior for sending emails
https://github.com/plataformatec/devise/blob/master/lib/devise/models/authenticatable.rb#L127
You can disable it at instance level:
# disable all notifications
user.define_singleton_method(:send_devise_notification) { |*_| true }
# disable the one you want
user.define_singleton_method(:send_devise_notification) do |*args|
return true if args[0] == :reset_password_instructions
super
end
The title of the question is general, but the question itself is more specific. This is the answer to the general question as of 2021.
To prevent a password changed email notification from being sent when changing a user password, call skip_password_change_notification! on the user before saving the user.
user = User.find(123)
user.skip_password_change_notification!
user.password = 'DoNotUse$123'
user.save

Rails Devise: Set password reset token and redirect user

In my app for a certain use case I create a new user (programmatically set the password) and send them a confirmation email.
I would like them to be able to change their password immediately after confirming (without having to enter the system generated one which I don't want to send them)
In effect I would like
1) System creates a new user account with generated password.
2) System sends confirmation email.
3) User clicks confirmation and is redirected to enter in their password (effectively send them to a URL like below)
Change my password
Any help / pointers would be great.
A simple way to have just one step for users to confirm email address and set initial password using the link you proposed...
Send one email your app generates, including a reset_password_token, and consider user's possession of that token confirmation of the validity of that email address.
In system account generation code, assuming User model is set up with :recoverable and :database_authenticatable Devise modules...
acct = User.new
acct.password = User.reset_password_token #won't actually be used...
acct.reset_password_token = User.reset_password_token
acct.email = "user#usercompany.com" #assuming users will identify themselves with this field
#set other acct fields you may need
acct.save
Make the devise reset password view a little clearer for users when setting initial password.
views/devise/passwords/edit.html.erb
...
<%= "true" == params[:initial] ? "Set your password" : "Reset your password" %>
...
Generated Email
Hi <%= #user.name %>
An account has been generated for you.
Please visit www.oursite.com/users/password/edit?initial=true&reset_password_token=<%= #user.reset_password_token %> to set your password.
No need to include :confirmable Devise module in your User model, since accounts created by your app won't get accessed without the reset_password_token in the email.
Devise will handle the submit and clear the reset_password_token field.
See devise_gem_folder/lib/devise/models/recoverable.rb and database_authenticatable.rb for details on reset_password_token method and friends.
If you want to use Devise :confirmable module rather than this approach, see the Devise wiki page.
In Rails 4.1, the following modification of Anatortoise House's reply works:
user = User.new
user.password = SecureRandom.hex #some random unguessable string
raw_token, hashed_token = Devise.token_generator.generate(User, :reset_password_token)
user.reset_password_token = hashed_token
user.reset_password_sent_at = Time.now.utc
user.email = 'user#usercompany.com'
user.save!
# Use a mailer you've written, such as:
AccountMailer.set_password_notice(user, raw_token).deliver
The email view has this link:
www.oursite.com/users/password/edit?initial=true&reset_password_token=<%= #raw_token %>
Here is my snippet for mailer preview
class Devise::MailerPreview < ActionMailer::Preview
def reset_password_instructions
user = User.last
token = user.send(:set_reset_password_token)
Devise::Mailer.reset_password_instructions(user, token)
end
end
You can call
user.send(:set_reset_password_token)
It may not be stable, as it's a protected method but it can work for your case. Just cover it with a test.
(tested on Devise v. 3.4)

Rails 3 with Devise for Authentication - How do I manually create a user?

I would like to manually create new Users, without forcing them to verify their email address.
The idea is to allow existing users to automatically add their friends without requiring their registration. It makes sense for the business case I'm working to solve.
How can this be achieved with Devise?
The skip_confirmation! method is available to any confirmable model.
#user = User.new params[:user]
#user.skip_confirmation! # Sets confirmed_at to Time.now, activating the account
#user.save
The user account will be activated though. If you don't want that, continue reading.
Devise uses conditional callbacks to generate the confirmation token and send the email. The callbacks will be called only if confirmation_required? returns true. Redefine it on your model:
def confirmation_required?
false
end
However, this will make the active_for_authentication? method always return true because it takes whether or not confirmation is required into account. We have to redefine that as well:
def active_for_authentication?
confirmed? || confirmation_period_valid?
end
This way, the account will stay inactive and no confirmation email will be sent. You will have to manually activate the user by calling confirm! on the record or just setting confirmed_at to any date.
It's quite a hack, but it should work.
For reference: confirmable.rb
I just want to add for future reference that since Devise 2.2 there is now a skip_confirmation_notification! method available as well which basically does everything from Matheus' post without redefining the methods in the model.

Resources