diff --git a/lib/active_model/one_time_password.rb b/lib/active_model/one_time_password.rb index 6fd2466..67fc476 100644 --- a/lib/active_model/one_time_password.rb +++ b/lib/active_model/one_time_password.rb @@ -15,7 +15,7 @@ def has_one_time_password(options = {}) include InstanceMethodsOnActivation - before_create do + before_create(options.slice(:if, :unless)) do self.otp_regenerate_secret if !otp_column self.otp_regenerate_counter if otp_counter_based && !otp_counter end diff --git a/test/models/opt_in_two_factor.rb b/test/models/opt_in_two_factor.rb new file mode 100644 index 0000000..666fd5d --- /dev/null +++ b/test/models/opt_in_two_factor.rb @@ -0,0 +1,16 @@ +# frozen_string_literal: true + +class OptInTwoFactor + extend ActiveModel::Callbacks + include ActiveModel::Validations + include ActiveModel::OneTimePassword + + define_model_callbacks :create + attr_accessor :otp_secret_key, :email + + has_one_time_password unless: :otp_opt_in? + + def otp_opt_in? + true + end +end diff --git a/test/one_time_password_test.rb b/test/one_time_password_test.rb index 31c73f1..eb6e463 100644 --- a/test/one_time_password_test.rb +++ b/test/one_time_password_test.rb @@ -17,6 +17,10 @@ def setup @ar_user = ActiverecordUser.new @ar_user.email = 'roberto@heapsource.com' @ar_user.run_callbacks :create + + @opt_in = OptInTwoFactor.new + @opt_in.email = 'roberto@heapsource.com' + @opt_in.run_callbacks :create end def test_authenticate_with_otp @@ -49,6 +53,14 @@ def test_counter_based_otp_active_record assert code != @ar_user.otp_code(auto_increment: true) end + def test_opt_in_two_factor + assert @opt_in.otp_column.nil? + + @opt_in.otp_regenerate_secret + code = @opt_in.otp_code + assert @opt_in.authenticate_otp(code) + end + def test_authenticate_with_otp_when_drift_is_allowed code = @user.otp_code(Time.now - 30) assert @user.authenticate_otp(code, drift: 60)