lib/models/phone.rb in devise_phone-0.0.16 vs lib/models/phone.rb in devise_phone-0.0.17
- old
+ new
@@ -1,215 +1,114 @@
require "devise_phone/hooks"
module Devise
module Models
- # SmsActivable is responsible to verify if an account is already confirmed to
- # sign in, and to send sms with confirmation instructions.
- # Confirmation instructions are sent to the user phone after creating a
- # record and when manually requested by a new confirmation instruction request.
- #
- # == Options
- #
- # Confirmable adds the following options to devise_for:
- #
- # * +sms_confirm_within+: the time you want to allow the user to access his account
- # before confirming it. After this period, the user access is denied. You can
- # use this to let your user access some features of your application without
- # confirming the account, but blocking it after a certain period (ie 7 days).
- # By default confirm_within is 0 days, so the user must confirm before entering.
- # If you want to allow user to use parts of the site and block others override
- # sms_confirmation_required? and check manually on selected pages using the
- # require_sms_activated! helper or sms_confirmed? property on record
- #
- # == Examples
- #
- # User.find(1).sms_confirm! # returns true unless it's already confirmed
- # User.find(1).sms_confirmed? # true/false
- # User.find(1).send_sms_token # manually send token
- #
module Phone
extend ActiveSupport::Concern
included do
- before_create :set_phone_attributes, :if => :phone_verification_needed?
- after_create :generate_verification_code_and_send_sms, :if => :phone_verification_needed?
+ before_create :set_unverified_phone_attributes, :if => :phone_verification_needed?
+ # after_create :private_generate_verification_code_and_send_sms, :if => :phone_verification_needed?
+ # before_save :remember_old_phone_number
+ after_save :private_generate_verification_code_and_send_sms, :if => :regenerate_phone_verification_needed?
end
- # # Confirm a user by setting it's sms_confirmed_at to actual time. If the user
- # # is already confirmed, add en error to email field
- # def confirm_sms!
- # unless_sms_confirmed do
- # self.sms_confirmation_token = nil
- # self.sms_confirmed_at = Time.now
- # save(:validate => false)
- # end
- # end
-
- # # Verifies whether a user is sms-confirmed or not
- # def confirmed_sms?
- # !!sms_confirmed_at
- # end
-
- # Send confirmation token by sms
def generate_verification_code_and_send_sms
- if(self.phone_number?)
- self.phone_verification_code = generate_phone_verification_code
- ::Devise.sms_sender.send_sms_verification_code_to(self)
+ if(phone_verification_needed?)
+ private_generate_verification_code_and_send_sms
+ end
+ self.save!
+ end
+
+ def verify_phone_number_with_code_entered(code_entered)
+ if phone_verification_needed? && (code_entered == self.phone_verification_code)
+ mark_phone_as_verified!
+ true
else
- # self.errors.add(:sms_confirmation_token, :no_phone_associated)
false
end
end
- # # Resend sms confirmation token. This method does not need to generate a new token.
- # def resend_sms_token
- # unless_sms_confirmed { send_sms_token }
- # end
+ private
- # Overwrites active? from Devise::Models::Activatable for sms confirmation
- # by verifying whether a user is active to sign in or not. If the user
- # is already confirmed, it should never be blocked. Otherwise we need to
- # calculate if the confirm time has not expired for this user.
+ def private_generate_verification_code_and_send_sms
+ self.phone_verification_code = generate_phone_verification_code
+ set_unverified_phone_attributes
+ if phone_number.present?
+ send_sms_verification_code
+ end
+ end
- # def active?
- # !sms_confirmation_required? || confirmed_sms? || confirmation_sms_period_valid?
- # end
- # # The message to be shown if the account is inactive.
- # def inactive_message
- # !confirmed_sms? ? I18n.t(:"devise.sms_activations.unconfirmed_sms") : super
- # end
+ def mark_phone_as_verified!
+ update!(phone_number_verified: true,
+ phone_verification_code: nil,
+ phone_verification_code_sent_at: nil,
+ phone_verified_at: DateTime.now)
+ end
- # # If you don't want confirmation to be sent on create, neither a code
- # # to be generated, call skip_sms_confirmation!
- # def skip_sms_confirmation!
- # self.sms_confirmed_at = Time.now
- # end
-
- protected
-
- # Callback to overwrite if an sms confirmation is required or not.
+ # check if phone verification is needed and set errors here
def phone_verification_needed?
- phone_number.present? && !phone_number_verified
+ if phone_number.blank?
+ self.errors.add(:phone_verification_code, :empty_phone_number_field)
+ false
+ elsif phone_number_verified
+ self.errors.add(:phone_verification_code, :phone_verification_not_needed)
+ false
+ else
+ true
+ end
end
- # def sms_confirmation_required?
- # !confirmed_sms?
- # end
+ def regenerate_phone_verification_needed?
+ if phone_number.present?
+ if phone_number_changed?
+ true
+ else
+ false
+ end
+ # self.errors.add(:phone_verification_code, :empty_phone_number_field)
+ # false
+ else
+ false
+ end
+ end
- # Checks if the confirmation for the user is within the limit time.
- # We do this by calculating if the difference between today and the
- # confirmation sent date does not exceed the confirm in time configured.
- # Confirm_in is a model configuration, must always be an integer value.
- #
- # Example:
- #
- # # sms_confirm_within = 1.day and sms_confirmation_sent_at = today
- # confirmation_period_valid? # returns true
- #
- # # sms_confirm_within = 5.days and sms_confirmation_sent_at = 4.days.ago
- # confirmation_period_valid? # returns true
- #
- # # sms_confirm_within = 5.days and sms_confirmation_sent_at = 5.days.ago
- # confirmation_period_valid? # returns false
- #
- # # sms_confirm_within = 0.days
- # confirmation_period_valid? # will always return false
- #
- # def confirmation_sms_period_valid?
- # sms_confirmation_sent_at && sms_confirmation_sent_at.utc >= self.class.sms_confirm_within.ago
- # end
-
- # # Checks whether the record is confirmed or not, yielding to the block
- # # if it's already confirmed, otherwise adds an error to email.
- # def unless_sms_confirmed
- # unless confirmed_sms?
- # yield
- # else
- # self.errors.add(:sms_confirmation_token, :sms_already_confirmed)
- # false
- # end
- # end
-
- # Generates a new random token for confirmation, and stores the time
- # this token is being generated
- def set_phone_attributes
-
+ # set attributes to user indicating the phone number is unverified
+ def set_unverified_phone_attributes
self.phone_number_verified = false
self.phone_verification_code_sent_at = DateTime.now
self.phone_verified_at = nil
# removes all white spaces, hyphens, and parenthesis
- self.phone_number.gsub!(/[\s\-\(\)]+/, '')
+ if self.phone_number
+ self.phone_number.gsub!(/[\s\-\(\)]+/, '')
+ end
end
+ # return 4 digits random code 0-9
def generate_phone_verification_code
- # begin
- verification_code = SecureRandom.hex(3)
- # end while self.class.exists?(phone_verification_code: verification_code)
+ verification_code = SecureRandom.random_number(10 ** 4).to_s.rjust(4,'0')
verification_code
end
- # def generate_sms_token!
- # generate_sms_token && save(:validate => false)
- # end
+ # sends a message to number indicated in the secrets.yml
+ def send_sms_verification_code
+ number_to_send_to = self.phone_number
+ verification_code = self.phone_verification_code
- module ClassMethods
- # # Attempt to find a user by it's email. If a record is found, send a new
- # # sms token instructions to it. If not user is found, returns a new user
- # # with an email not found error.
- # # Options must contain the user email
- # def send_sms_token(attributes={})
- # sms_confirmable = find_or_initialize_with_errors(sms_confirmation_keys, attributes, :not_found)
- # sms_confirmable.resend_sms_token if sms_confirmable.persisted?
- # sms_confirmable
- # end
+ twilio_sid = Rails.application.config.twilio[:sid]
+ twilio_token = Rails.application.config.twilio[:token]
+ twilio_phone_number = Rails.application.config.twilio[:phone_number]
+ twilio_message_body = I18n.t("devise.phone.message_body", :verification_code => verification_code)
- # # Find a user by it's sms confirmation token and try to confirm it.
- # # If no user is found, returns a new user with an error.
- # # If the user is already confirmed, create an error for the user
- # # Options must have the sms_confirmation_token
- # def confirm_by_sms_token(sms_confirmation_token)
- # sms_confirmable = find_or_initialize_with_error_by(:sms_confirmation_token, sms_confirmation_token)
- # sms_confirmable.confirm_sms! if sms_confirmable.persisted?
- # sms_confirmable
- # end
-
- def mark_phone_as_verified!
- update!(phone_number_verified: true,
- phone_verification_code: nil,
- phone_verification_code_sent_at: nil,
- phone_verified_at: DateTime.now)
- end
-
- def verify_phone_number_with_code_entered(code_entered)
- if self.phone_verification_code == code_entered
- mark_phone_as_verified!
- end
- end
-
- def send_verification_code
- self.set_phone_attributes
- if self.save!
- send_sms_for_phone_verification
- end
- end
-
- # # Generates a small token that can be used conveniently on SMS's.
- # # The token is 5 chars long and uppercased.
-
- # def generate_small_token(column)
- # loop do
- # token = Devise.friendly_token[0,5].upcase
- # break token unless to_adapter.find_first({ column => token })
- # end
- # end
-
- # # Generate an sms token checking if one does not already exist in the database.
- # def sms_confirmation_token
- # generate_small_token(:sms_confirmation_token)
- # end
-
- # Devise::Models.config(self, :sms_confirm_within, :sms_confirmation_keys)
+ @twilio_client = Twilio::REST::Client.new twilio_sid, twilio_token
+
+ @twilio_client.account.messages.create(
+ :from => "+1#{twilio_phone_number}",
+ :to => number_to_send_to,
+ :body => twilio_message_body
+ )
end
+
end
end
end