Devise skip reconfirmation - ruby-on-rails

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.

Related

confirmation mail to unconfirmed mail

When I update the email id in devise like this:
current_user.update!(email: params[:email])
Email is sent to current email id. I want to send the confirmation email to the new email id which is to be updated.
If you don't want to send an info to the old email but want to send confirmation instructions to the new email, what you're looking for is two settings in config/initializers/devise.rb, namely reconfirmable and send_email_changed_notification. The former sends an email to the new email with confirmation instructions (basically repeating what's happening at initial creation where a confirmation email is sent to the email being used) while the latter sends an info that an email was changed to the old email. Consequently, you need to set the values to true and false respectively:
# in config/initializers/devise.rb
Devise.setup do |config|
# ...
config.reconfirmable = true
config.send_email_changed_notification = false
end
It could be that these are already in your devise.rb – if they are, make sure to set them there to not have them twice and accidentally override each other in ways you don't want.

Omniauth-Facebook giving error in callback - Email can't be blank?

Hi my devise login appears to work, but for some reason Facebook is not sending me the email in my API request. Then I am getting this error:
I read up on the July 18th, 2015 adjustment and added scope. No luck. Here is the initializer:
config.omniauth :facebook, ENV['FACEBOOK_APP_KEY'],
ENV['FACEBOOK_APP_SECRET'], scope: 'email', info_fields:'email,name'
Maybe I'm missing something on the FB Developer Page?
You will have to handle it :
Some Facebook users have unverified emails, so Facebook will not give it to you
There is Facebook users with only telephone numbers and no email
Facebook allow the user to not provide some information to your app, for example the email
It happens with profiles with unverified emails and when user choose not to provide your app with their email
rescue that error and redirect user to normal sign up page so they continue with providing their email address
Ok, if what Nicolas is saying is correct then you can easily solve this problem. Before save populate some fake and unique email with "+":
Add to your User model something like this:
class User < ActiveRecord::Base
before_validation :adjust_email, on: :create
private
def adjust_email
self.email = "fake+#{generate_token}" if email.blank?
true
end
def generate_token
rand(36**8).to_s(36)
end
end
And you will have to show your user this fake email, so that she will be able to login with it later. A downside of this solution is that you will not be able to send emails to such users, but maybe you don't want to.
What Remon suggested is also a valid option to redirect to sign up in case you get this particular error.
So, it all depends on what you actually plan to do with the email.

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?

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

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

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)

Resources