I am using devise for authentication. What I am trying to do is send a reset_password_token in the link which is sent to the user. I am creating an agent from ActiveAdmin portal once it is created I am sending a link to the agent's email address so they can reset their password but I am not able to figure out how to send the reset_password_token with the link which is sent to the agent. Please have a look at the code below and help me find the solution
organisation_mailer.rb
class OrganisationMailer < ApplicationMailer
default from: 'abc#yahoo.com'
def send_link(agent_id)
#agent = Agent.find(agent_id)
token = SecureRandom.urlsafe_base64
#agent.update(organisation_token: token)
#link = "#{ActionMailer::Base.default_url_options[:host]}/organisation?token=#{token}"
mail to: #agent.email, subject: "On boarding link for #{#agent.full_name}"
end
end
routes.rb
get 'organisation', to: 'agents#organisation', constraints: ->(req) { req.format == :json }
agents_controller.rb
def organisation
return if params[:token].blank?
#agent = Agent.find_by(organisation: params[:token])
sign_in(#agent, scope: :agent)
end
agents.rb
ActiveAdmin.register Agent do
action_item :send_email, only: :show do
link_to 'Send Email', send_email_admin_agent_path, method: :post
end
member_action :send_email, method: :post do
OrganisationMailer.send_link(resource.id).deliver_now
redirect_to admin_agent_path(resource.id), notice: 'Organisation link has been sent'
end
Related
I have a website that connect to an API which requires that I generate a reference code along with other information i will need to complete my registration. After the registration has been confirmed the server will respond with a redirect to my controller action to complete the whole process where I have to verify same with another controller action. However, I have tried the following but still have some difficulty making my website respond to the redirect ie: showing a message 'book confirmed!'
Here is the url i get:
http/example.com/?ref=2755558333388=referencecode=2755558333388
instead of
http/example.com/book?ref=2755558333388=referencecode=2755558333388
# route
Rails.application.routes.draw do
get 'confirmations/register'
post 'confirmations/verified'
end
# controller:
class ConfirmationsController < ApplicationController
def register
registerationObj = Registration.new(ENV["BOOKREG_PUBLIC_KEY"], ENV["BOOKREG_PRIVATE_KEY"])
book = RegistrationBooks.new(registrationObj)
:action = books.create(
:book_title => #book.title,
:phone => current_user.phone,
:email => current_user.email,
:referencecode => #book.referencecode
end
def verified
if params[:referencecode == #book.referencecode
flash[:alert] = "Your book has been verified"
redirect_to books_path
else
redirect_to current_user_edit_path, notice: "Sorry your book was not verified"
end
end
In order to send new confirmation instructions, an email has to be entered. I want to avoid that because my users are logged in at that moment, so there's no need for email asking. I just want to send new instructions to the current_user.email
I don't want to do client side stuff like this:
= f.email_field :email, value: current_user.email, class: "hidden"
I need a server side solution.
Thanks guys!
As per the devise codebase, sending confirmation email can be invoked on a user as follows:
user = User.find(1)
user.send_confirmation_instructions
So you don't really need to get an email from the form.
You have access to device method , this should work.
See the documentation here
routes.rb
devise_for :users, controllers: { confirmations: "confirmations" }
In view
= link_to "resend confirmation", user_confirmation_path, data: { method: :post }
I ended up with this:
First, override devise controller:
config/routes.rb
devise_for :users, controllers: { confirmations: "users/confirmations" }
controllers/users/confirmations_controller.rb
class Users::ConfirmationsController < Devise::ConfirmationsController
def create
redirect_to new_user_session_path unless user_signed_in?
if current_user.confirmed?
redirect_to root_path
else
current_user.send_confirmation_instructions
redirect_to after_resending_confirmation_instructions_path_for(:user)
end
end
end
protected
# The path used after resending confirmation instructions.
def after_resending_confirmation_instructions_path_for(resource_name)
flash[:notice] = "Instructions sent successfully."
is_navigational_format? ? root_path (or whatever route) : '/'
end
end
Then remove the email field from the view.
views/devise/confirmations/new.html.haml
= form_for(resource, as: resource_name, url: confirmation_path(resource_name), method: :post }) do |f|
= f.submit "Resend confirmation instructions"
Thanks everyone for your answers.
Currently I have ActionMailer send an email when a user registers, and I generate a random :sign_in_token with the user.
How can a user then click on the link sent to his email and update the users :registration_complete boolean value to TRUE?
Currently, I am able to send the link and generates a random token, but I don't know how to update the boolean value through the email.
MODELS
class User < ActiveRecord::Base
attr_accessible :name, :email, :password, :password_confirmation, :sign_in_token,
:registration_complete
###This generates my sign_in_token
def generate_sign_in_token
self.sign_in_token = Digest::SHA1.hexdigest([Time.now, rand].join)
end
end
CONTROLLER
def create
#user = RegularUser.new(params[:regular_user])
if #user.save
###Sends the User an email with sign_in_token
UserMailer.registration_confirmation(#user, login_url+"/#{#user.sign_in_token}").deliver
flash[:success] = "Please Check Your Email to Verify your Registration!"
redirect_to (verifyemail_path)
else
render 'new'
end
end
USER_MAILER
def registration_confirmation(user, login_url)
#login_url = login_url
#user = user
mail(:to => "#{user.name} <#{user.email}>", :subject => "Welcome to APP")
end
VIEWS
###Redirects User to Login Page, But how do i connect it to my activate method?
<%= link_to "Complete Registration", #login_url %>
ROUTES
match '/login/:sign_in_token', :to => 'sessions#new'
When they click a link, it takes them to a controller with an action of set_complete using a GET request, which sets the boolean value.
Something like:
def set_complete
user = User.find(params[:user])
user.update_attribute(registration_complete => true)
redirect_to login_path # or whatever your login url is...
end
For the controller action and something like this for the link:
<a href="example.com/registrations/set_complete?user=1" />
Here is a sample of what might go in the routes file:
get "/users/set_complete", :to => "users#set_complete"
You'd probably need to set the user id to whatever you want using erb, andmake a few other app-specific customizations, but this is the general idea.
Hope this helps!
I want to integrate Paypal within the Devise user registration process. What I want is to have a standard rails form based on the devise resource, that also has custom fields belonging to the user's model.
When a user fills in those fields and clicks on signup, it will be redirected to Paypal, when he clears from paypal and returns to our site then the user data must be created.
For the scenario where the user fill's out the paypal form but doesn't come back to our site, we have to keep record of user before redirecting to Paypal.
For this we can create a flag in user model and use Paypal IPN and when the user transaction notified, set that flag.
But in the case when the user is redirected to Paypal but doesn't complete the transaction, if the user returns to registration and signup again, our model should not throw error saying that the email entered already exists in the table.
How can we handle all these scenarios, is there any gem or plugin available to work with?
Here i am posting the detail code for performing the whole process.
registration_controller.rb
module Auth
class RegistrationController < Devise::RegistrationsController
include Auth::RegistrationHelper
def create
#user = User.new params[:user]
if #user.valid?
redirect_to get_subscribe_url(#user, request)
else
super
end
end
end
end
registration_helper.rb
module Auth::RegistrationHelper
def get_subscribe_url(user, request)
url = Rails.env == "production" ? "https://www.paypal.com/cgi-bin/webscr/?" : "https://www.sandbox.paypal.com/cgi-bin/webscr/?"
url + {
:ip => request.remote_ip,
:cmd => '_s-xclick',
:hosted_button_id => (Rails.env == "production" ? "ID_FOR_BUTTON" : "ID_FOR_BUTTON"),
:return_url => root_url,
:cancel_return_url => root_url,
:notify_url => payment_notifications_create_url,
:allow_note => true,
:custom => Base64.encode64("#{user.email}|#{user.organization_type_id}|#{user.password}")
}.to_query
end
end
payment_notification_controller.rb
class PaymentNotificationsController < ApplicationController
protect_from_forgery :except => [:create]
layout "single_column", :only => :show
def create
#notification = PaymentNotification.new
#notification.transaction_id = params[:ipn_track_id]
#notification.params = params
#notification.status = "paid"
#custom = Base64.decode64(params[:custom])
#custom = #custom.split("|")
#user = User.new
#user.email = #custom[0]
#user.organization_type_id = #custom[1].to_i
#user.password = #custom[2]
if #user.valid?
#user.save
#notification.user = #user
#notification.save
#user.send_confirmation_instructions
end
render :nothing => true
end
def show
end
end
I'd like to have an "edit profile" page, in which the user can change the email address registered when signing up.
I'd like to have the following process:
the user has to input his password to confirm before he makes changes in the email field.
after submitting that page, the user should receive a verification mail just like Devise's default sign up.
the email change is completed as soon as the user clicks the verification token URL on the mail.
How would I do this?
I created this same flow for a site of mine. Here's an example of what you can do:
add to config/routes.rb
(note that the routing could be better, but I did this a while ago)
scope :path => '/users', :controller => 'users' do
match 'verify_email' => :verify_email, :as => 'verify_email'
match 'edit_account_email' => :edit_account_email, :as => 'edit_account_email'
match 'update_account_email' => :update_account_email, :as => 'update_account_email'
end
add to app/controllers/users_controller.rb
def edit_account_email
#user=current_user
end
def update_account_email
#user=current_user
#user.password_not_needed=true
#user.email=params[:address]
if #user.save
flash[:notice]="your login email has been successfully updated."
else
flash[:alert]="oops! we were unable to activate your new login email. #{#user.errors}"
end
redirect_to edit_user_path
end
def verify_email
#user=current_user
#address=params[:address]
UserMailer.confirm_account_email(#user, #address).deliver
end
app/mailers/user_mailer.rb
class UserMailer < ActionMailer::Base
def confirm_account_email(user, address)
#user = user
#address = address
mail(
:to=>"#{user.name} <#{#address}>",
:from=>"your name <'your_email#domain.com'>",
:subject=>"account email confirmation for #{user.name}"
)
end
end
app/views/user_mailer/confirm_account_email.html.erb
<p>you can confirm that you'd like to use this email address to log in to your account by clicking the link below:</p>
<p><%= link_to('update your email', update_account_email_url(#user, :address=>#address)) %></p>
<p>if you choose not to confirm the new address, your current login email will remain active.