devise_challenge_questionable 0.1.2 → 0.2.2

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
- ---
2
- SHA512:
3
- metadata.gz: a032acd8c06fc6a969d5211b301a01d0c06cbdd401bf9590aad7f4b2f1176c0fa1a511fd2a41b5dba39ee5bd126c563582bae5656b90face681c445c6f09d6a9
4
- data.tar.gz: 2c227dd0209959c9f3470795c486478ffda5fd480db8afa18db3c96ebdb9528589b36e153c1e37506484179ab0e5078cfc67dc73f1ce71dbb867e7fb36c177c0
5
- SHA1:
6
- metadata.gz: 6d27ff4286361e800bdefec8d14dc4ccac6fc5fa
7
- data.tar.gz: 24439532250c4be4f6c0e5b6b20a732184710f9e
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 97b2602ce519f20e3226c3484585eaacda4bb334
4
+ data.tar.gz: d2456cee8d307d5786b4d1a63a61d9bddeef7081
5
+ SHA512:
6
+ metadata.gz: 63ff1a9fe2170091b9cdf43c65e8ebf86c64f318e6e88949312b1975b45d77f7d3b1e6150d5696c1741180081b9311a43cab1cbdd07be966307b4b71d9636806
7
+ data.tar.gz: adceea3b356dd2b0693f10c60d43127f178cb91141fecf18c3f754f9c39c83d0b08cf8caba5aa6446fb801170af2d759a2001f934662e6622ee26403f1fbdbd4
data/README.md CHANGED
@@ -1,11 +1,12 @@
1
1
  ## Challenge questions plugin for Devise
2
2
 
3
- This plugin forces a two step login process. After entering username and password, you must then answer a challenge question. Unlike security questions which are typically used when doing things like changing passwords, the challenge question must be answered each time logging in. You can set which users(or preferred resource) need to answer a challenge question
3
+ This plugin forces a two step login process. After entering username/email and password, you must then answer a challenge question. Unlike security questions which are typically used when doing things like changing passwords, the challenge question must be answered each time logging in. You can set which users or admins need to answer a challenge question. We will assume your resource is User for the remainder of the Readme.
4
4
  ## Features
5
5
 
6
6
  * configure max challenge question attempts
7
- * configure number of challenge questions stored for each {resource}
8
- * per {resource} level control if he really need challenge question authentication
7
+ * configure number of challenge questions stored for each user
8
+ * configure number of challenge questions asked for each user
9
+ * per user level control if he really need challenge question authentication
9
10
 
10
11
  ## Configuration
11
12
 
@@ -28,7 +29,7 @@ In order to add challenge questions to a model, run the command:
28
29
 
29
30
  bundle exec rails g devise_challenge_questionable:install
30
31
 
31
- bundle exec rails g devise_challenge_questionable:views {resource}s
32
+ bundle exec rails g devise_challenge_questionable:views users
32
33
 
33
34
  Where MODEL is your model name (e.g. User or Admin). This generator will add `:challenge_questionable` to your model
34
35
  and create a migration in `db/migrate/`, which will add `:reset_challenge_questions_token` and `:challenge_question_failed_attempts` to your table.
@@ -39,22 +40,22 @@ Finally, run the migration with:
39
40
 
40
41
  ### Manual installation
41
42
 
42
- To manually enable challenge questions for the {Resource} model, you should add the following. Set up relationships. You should already have a devise line so you would just add :challenge_questionable to it. Also, you need to allow accessibility to `:{resource}_challenge_questions_attributes`. Replace {resource} with whatever resource you are using. Typically it would be {resource} or admin.
43
+ To manually enable challenge questions for the User model, you should add the following. Set up relationships. You should already have a devise line so you would just add :challenge_questionable to it. Also, you need to allow accessibility to `:user_challenge_questions_attributes`. Replace user with whatever resource you are using. Typically it would be user or admin.
43
44
 
44
45
  ```ruby
45
- has_many :{resource}_challenge_questions, :validate => true, :inverse_of => :{resource}
46
- accepts_nested_attributes_for :{resource}_challenge_questions, :allow_destroy => true
46
+ has_many :user_challenge_questions, :validate => true, :inverse_of => :user
47
+ accepts_nested_attributes_for :user_challenge_questions, :allow_destroy => true
47
48
 
48
49
  devise :challenge_questionable
49
50
 
50
- attr_accessible :{resource}_challenge_questions_attributes
51
+ attr_accessible :user_challenge_questions_attributes
51
52
  ```
52
53
 
53
- You also need to add the `{resource}_challenge_question.rb` Model.
54
+ You also need to add the `user_challenge_question.rb` Model.
54
55
 
55
56
  ```ruby
56
- class {Resource}ChallengeQuestion < ActiveRecord::Base
57
- belongs_to :{resource}
57
+ class UserChallengeQuestion < ActiveRecord::Base
58
+ belongs_to :user
58
59
 
59
60
  validates :challenge_question, :challenge_answer, :presence => true
60
61
  validates :challenge_answer, :length => { :in => 4..56 }, :format => {:with => /^[\w\s:]*$/, :message => "can not contain special characters"}, :allow_blank => true
@@ -72,13 +73,13 @@ You also need to add the `{resource}_challenge_question.rb` Model.
72
73
 
73
74
  private
74
75
  def challenge_question_uniqueness
75
- if self.challenge_question.present? && self.{resource}.{resource}_challenge_questions.select{|q| q.challenge_question == self.challenge_question}.count > 1
76
+ if self.challenge_question.present? && self.user.user_challenge_questions.select{|q| q.challenge_question == self.challenge_question}.count > 1
76
77
  errors.add(:challenge_question, 'can only be used once')
77
78
  end
78
79
  end
79
80
 
80
81
  def challenge_answer_uniqueness
81
- if self.challenge_answer.present? && self.{resource}.{resource}_challenge_questions.select{|q| q.challenge_answer == self.challenge_answer}.count > 1
82
+ if self.challenge_answer.present? && self.user.user_challenge_questions.select{|q| q.challenge_answer == self.challenge_answer}.count > 1
82
83
  errors.add(:challenge_answer, 'can only be used once')
83
84
  end
84
85
  end
@@ -115,7 +116,7 @@ Configuration settings
115
116
  # Max challenge question attempts
116
117
  config.max_challenge_question_attempts = 3
117
118
 
118
- # Number of challenge questions to store for each {resource}
119
+ # Number of challenge questions to store for each user
119
120
  config.number_of_challenge_questions = 3
120
121
 
121
122
  # Default challenge question options
@@ -125,12 +126,16 @@ Configuration settings
125
126
 
126
127
  ### Customization
127
128
 
128
- By default challenge questions are enabled for each {resource}, you can change it with this method in your User model:
129
+ By default challenge questions are enabled for each user, you can change it with this method in your User model:
129
130
 
130
131
  ```ruby
131
- def need_challenge_questions?(request)
132
+ def login_challenge_questions?(request)
133
+ request.ip != '127.0.0.1'
134
+ end
135
+
136
+ def set_challenge_questions?(request)
132
137
  request.ip != '127.0.0.1'
133
138
  end
134
139
  ```
135
140
 
136
- this will disable challenge questions for local {resource}s
141
+ this will disable challenge questions for local users
@@ -1,8 +1,8 @@
1
1
  class Devise::ChallengeQuestionsController < ApplicationController
2
2
  include Devise::Controllers::InternalHelpers
3
- prepend_before_filter :require_no_authentication, :only => [ :new, :create, :edit, :update ]
3
+ prepend_before_filter :require_no_authentication, :only => [ :new, :create, :edit, :update, :max_challenge_question_attempts_reached ]
4
4
  prepend_before_filter :authenticate_scope!, :only => [:show, :authenticate, :manage, :forgot]
5
- before_filter :prepare_and_validate, :handle_challenge_questions, :only => [:show, :authenticate]
5
+ before_filter :prepare_and_validate, :handle_challenge_questions, :only => [:show, :authenticate]
6
6
 
7
7
  # GET /resource/challenge_question/new
8
8
  def new
@@ -13,7 +13,6 @@ class Devise::ChallengeQuestionsController < ApplicationController
13
13
  # POST /resource/challenge_question
14
14
  def create
15
15
  self.resource = resource_class.send_reset_challenge_questions_instructions(params[resource_name])
16
-
17
16
  if resource.errors.empty?
18
17
  set_flash_message :notice, :send_instructions
19
18
  redirect_to new_session_path(resource_name)
@@ -26,7 +25,7 @@ class Devise::ChallengeQuestionsController < ApplicationController
26
25
  def edit
27
26
  self.resource = resource_class.new
28
27
  resource.reset_challenge_questions_token = params[:reset_challenge_questions_token]
29
- Devise.number_of_challenge_questions.times { resource.send("#{resource_name}_challenge_questions").build }
28
+ Devise.number_of_challenge_questions_stored.times { resource.send("#{resource_name}_challenge_questions").build }
30
29
  render_with_scope :edit
31
30
  end
32
31
 
@@ -44,37 +43,25 @@ class Devise::ChallengeQuestionsController < ApplicationController
44
43
 
45
44
  # GET /resource/challenge_question
46
45
  def show
47
- @challenge_question = resource.send("#{resource_name}_challenge_questions").sample
48
- if @challenge_question.nil?
49
- resource.set_reset_challenge_questions_token
50
- sign_out(resource)
51
- redirect_to edit_challenge_question_path(resource, :reset_challenge_questions_token => resource.reset_challenge_questions_token)
52
- else
53
- render_with_scope :show
46
+ @challenge_questions = resource.send("#{resource_name}_challenge_questions").sample(params[:limit].try(:to_i) || Devise.number_of_challenge_questions_asked)
47
+ respond_to do |format|
48
+ format.html { render_with_scope :show }
49
+ format.json { render :json => @challenge_questions.as_json(:only => [:id, :challenge_question]) }
54
50
  end
55
51
  end
56
-
52
+
57
53
  def authenticate
58
- render_with_scope :show and return if params[:challenge_answer].nil?
59
- @challenge_question = resource.send("#{resource_name}_challenge_questions").find(params[:challenge_question_id])
60
- md5 = Digest::MD5.hexdigest(params[:challenge_answer].downcase)
61
- if md5.eql?(@challenge_question.challenge_answer)
62
- warden.session(resource_name)[:need_challenge_questions] = false
63
- sign_in resource_name, resource
64
- redirect_to stored_location_for(resource_name) || :root
65
- resource.update_attribute(:challenge_question_failed_attempts, 0)
54
+ build_challenge_questions
55
+ if @challenge_questions.present? && challenge_questions_authenticated?
56
+ challenge_questions_authenticated
66
57
  else
67
- resource.challenge_question_failed_attempts += 1
68
- resource.save
69
- set_flash_message :notice, :attempt_failed
58
+ set_failed_attempt
70
59
  if resource.max_challenge_question_attempts?
71
- resource.max_challenge_question_lock_account
72
- sign_out(resource)
73
- render_with_scope :max_challenge_question_attempts_reached and return
60
+ max_failed_attempts
74
61
  else
75
- redirect_to send("#{resource_name}_challenge_question_path")
62
+ failed_attempts
76
63
  end
77
- end
64
+ end
78
65
  end
79
66
 
80
67
  # Build token and redirect
@@ -88,6 +75,9 @@ class Devise::ChallengeQuestionsController < ApplicationController
88
75
  sign_out(resource)
89
76
  redirect_to new_challenge_question_path(resource_name)
90
77
  end
78
+
79
+ def max_challenge_question_attempts_reached
80
+ end
91
81
 
92
82
  private
93
83
 
@@ -103,4 +93,47 @@ class Devise::ChallengeQuestionsController < ApplicationController
103
93
  render_with_scope :max_challenge_question_attempts_reached and return
104
94
  end
105
95
  end
96
+
97
+ def challenge_questions_authenticated?
98
+ @challenge_questions.all?{|question| Digest::MD5.hexdigest(question[:challenge_answer].try(:downcase).to_s).eql?(question[:answer])}
99
+ end
100
+
101
+ def build_challenge_questions
102
+ respond_to do |format|
103
+ format.html { @challenge_questions = (params[:challenge_questions] || []).map{|cq, params| params.merge(:answer => resource.send("#{resource_name}_challenge_questions").find(params[:id]).challenge_answer)} }
104
+ format.json { @challenge_questions = (params[:challenge_questions] || []).map{|cq| cq.merge(:answer => resource.send("#{resource_name}_challenge_questions").find(cq[:id]).challenge_answer)} }
105
+ end
106
+ end
107
+
108
+ def challenge_questions_authenticated
109
+ respond_to do |format|
110
+ format.html do
111
+ warden.session(resource_name)[:login_challenge_questions] = false
112
+ redirect_to stored_location_for(resource_name) || :root
113
+ end
114
+ format.json { render :json => {:success => true} }
115
+ end
116
+ resource.update_attribute(:challenge_question_failed_attempts, 0)
117
+ end
118
+
119
+ def set_failed_attempt
120
+ resource.challenge_question_failed_attempts += 1
121
+ resource.save
122
+ end
123
+
124
+ def max_failed_attempts
125
+ resource.max_challenge_question_lock_account
126
+ sign_out(resource)
127
+ respond_to do |format|
128
+ format.html { render_with_scope :max_challenge_question_attempts_reached and return }
129
+ format.json { render :json => {:max_attempts_reached => true, :errors => I18n.t(:"#{resource_name}.#{:max_attempts_reached}", :resource_name => resource_name, :scope => [:devise, controller_name.to_sym], :default => :attempt_failed)} }
130
+ end
131
+ end
132
+
133
+ def failed_attempts
134
+ respond_to do |format|
135
+ format.html { redirect_to send("#{resource_name}_challenge_question_path" ) }
136
+ format.json { render :json => {:errors => I18n.t(:"#{resource_name}.#{:attempt_failed}", :resource_name => resource_name, :scope => [:devise, controller_name.to_sym], :default => :attempt_failed)} }
137
+ end
138
+ end
106
139
  end
@@ -2,7 +2,7 @@
2
2
  <p>Change your current challenge questions by filling out the form below. The questions you set up previously will be replaced with these new questions. All fields are required.</p>
3
3
 
4
4
  <fieldset>
5
- <h4>Please select <%= Devise.number_of_challenge_questions %> questions below, 1 from each drop down. Then type your answers in the field provided.</h4>
5
+ <h4>Please select <%= Devise.number_of_challenge_questions_stored %> questions below, 1 from each drop down. Then type your answers in the field provided.</h4>
6
6
  <%= form_for(resource, :as => resource_name, :url => challenge_question_path(resource_name), :html => { :method => :put }) do |f| %>
7
7
  <%= devise_error_messages! %>
8
8
  <%= f.hidden_field :id %>
@@ -2,12 +2,15 @@
2
2
 
3
3
  <%= form_tag([:authenticate, resource_name, :challenge_question], :method => :put) do %>
4
4
  <fieldset>
5
- <p>
6
- <%= hidden_field_tag :challenge_question_id, @challenge_question.id%>
7
- <%= label_tag :challege_question, @challenge_question.challenge_question %>
8
- <br>
9
- <%= password_field_tag :challenge_answer, nil, :placeholder => 'Answer', :class => 'wide', :style => 'font-size: 1.8em;padding:5px', :autofocus => 'true', :autocomplete => "off" %>
10
- </p>
5
+ <%= hidden_field_tag :limit, params[:limit]%>
6
+ <%- @challenge_questions.each_with_index do |cq, index| %>
7
+ <p>
8
+ <%= hidden_field_tag "challenge_questions[#{cq.id}][id]", cq.id%>
9
+ <%= label_tag "challenge_questions[#{cq.id}][challenge_question]", cq.challenge_question %>
10
+ <br>
11
+ <%= password_field_tag "challenge_questions[#{cq.id}][challenge_answer]", nil, :placeholder => 'Answer', :class => 'wide', :style => 'font-size: 1.8em;padding:5px', :autofocus => (true if index == 0), :autocomplete => "off" %>
12
+ </p>
13
+ <% end %>
11
14
  <p>
12
15
  <%= submit_tag "Submit", :style => 'font-size:1.8em;'%>
13
16
  or
@@ -7,7 +7,8 @@ en:
7
7
  challenge_answer: "Answer"
8
8
  devise:
9
9
  challenge_questions:
10
- attempt_failed: "Attempt failed."
10
+ attempt_failed: "Attempt failed. Please try again."
11
+ max_attempts_reached: "You have reached the maximum attempts."
11
12
  updated_challenge_questions: "Successfully updated challenge questions."
12
13
  send_instructions: "You will receive an email with instructions about how to reset your challenge questions in a few minutes."
13
14
 
@@ -12,12 +12,21 @@ module DeviseChallengeQuestionable
12
12
  def handle_challenge_questions
13
13
  unless devise_controller? && (controller_name != 'registrations' && ![:edit, :update, :destroy].include?(action_name))
14
14
  Devise.mappings.keys.flatten.any? do |scope|
15
- if signed_in?(scope) and warden.session(scope)[:need_challenge_questions]
16
- failed_challenge_question(scope)
15
+ if signed_in?(scope)
16
+ set_challenge_questions(scope) and return if warden.session(scope)[:set_challenge_questions]
17
+ failed_challenge_question(scope) and return if warden.session(scope)[:login_challenge_questions]
17
18
  end
18
19
  end
19
20
  end
20
21
  end
22
+
23
+ def set_challenge_questions(scope)
24
+ if request.format.present? and request.format.html?
25
+ redirect_to set_challenge_questions_path_for(scope)
26
+ else
27
+ render :nothing => true, :status => :unauthorized
28
+ end
29
+ end
21
30
 
22
31
  def failed_challenge_question(scope)
23
32
  if request.format.present? and request.format.html?
@@ -27,6 +36,12 @@ module DeviseChallengeQuestionable
27
36
  render :nothing => true, :status => :unauthorized
28
37
  end
29
38
  end
39
+
40
+ def set_challenge_questions_path_for(resource_or_scope = nil)
41
+ scope = Devise::Mapping.find_scope!(resource_or_scope)
42
+ change_path = "manage_#{scope}_challenge_question_path"
43
+ send(change_path)
44
+ end
30
45
 
31
46
  def challenge_questions_path_for(resource_or_scope = nil)
32
47
  scope = Devise::Mapping.find_scope!(resource_or_scope)
@@ -2,7 +2,7 @@ module DeviseChallengeQuestionable
2
2
  module Controllers
3
3
  module UrlHelpers
4
4
  [:path, :url].each do |path_or_url|
5
- [nil, :edit_, :authenticate_, :manage_, :forgot_].each do |action|
5
+ [nil, :edit_, :authenticate_, :manage_, :forgot_, :max_challenge_question_attempts_reached_].each do |action|
6
6
  class_eval <<-URL_HELPERS, __FILE__, __LINE__ + 1
7
7
  def #{action}challenge_question_#{path_or_url}(resource, *args)
8
8
  resource = case resource
@@ -1,8 +1,18 @@
1
1
  Warden::Manager.after_authentication do |user, auth, options|
2
- if user.respond_to?(:need_challenge_questions?)
3
- auth.session(options[:scope])[:need_challenge_questions] = user.need_challenge_questions?(auth.request)
4
- end
2
+
5
3
  if Devise.respond_to?(:token_authentication_key) && auth.env["action_dispatch.request.parameters"].keys.include?(Devise.token_authentication_key.to_s)
6
- auth.session(options[:scope])[:need_challenge_questions] = false
4
+ auth.session(options[:scope])[:login_challenge_questions] = false
5
+ auth.session(options[:scope])[:set_challenge_questions] = false
6
+ else
7
+
8
+ if user.respond_to?(:login_challenge_questions?)
9
+ auth.session(options[:scope])[:login_challenge_questions] = user.login_challenge_questions?(auth.request)
10
+ end
11
+
12
+ if user.respond_to?(:set_challenge_questions?)
13
+ auth.session(options[:scope])[:set_challenge_questions] = user.set_challenge_questions?(auth.request)
14
+ end
15
+
7
16
  end
17
+
8
18
  end
@@ -13,7 +13,11 @@ module Devise
13
13
  self.save
14
14
  end
15
15
 
16
- def need_challenge_questions?(request)
16
+ def login_challenge_questions?(request)
17
+ true
18
+ end
19
+
20
+ def set_challenge_questions?(request)
17
21
  true
18
22
  end
19
23
 
@@ -7,6 +7,7 @@ module ActionDispatch::Routing
7
7
  put :authenticate, :path => mapping.path_names[:authenticate]
8
8
  get :manage, :path => mapping.path_names[:manage]
9
9
  get :forgot, :path => mapping.path_names[:forgot]
10
+ get :max_challenge_question_attempts_reached, :path => mapping.path_names[:max_challenge_question_attempts_reached]
10
11
  end
11
12
  end
12
13
  end
@@ -1,3 +1,3 @@
1
1
  module DeviseChallengeQuestionable
2
- VERSION = "0.1.2"
2
+ VERSION = "0.2.2"
3
3
  end
@@ -10,9 +10,11 @@ module Devise
10
10
  mattr_accessor :challenge_questions
11
11
  @@challenge_questions = ["What was your high school mascot?","In which city was your first elementary school?","In which city was your mother born?","What is the name of your favorite movie?","Who is your favorite athlete?","What was your most memorable gift as a child?","What is your favorite cartoon character?","What is the name of your favorite novel?","Name of favorite childhood pet?","What is the name of your elementary school?","What is your youngest child's middle name?","Last Name of your kindergarten teacher?","What is the first name of your grandmother (your father's mother)?","What is your spouse's nickname?","Name of the place where your wedding reception was held?","Name of a college you applied to but did not attend?","What is the first name of the youngest of your siblings?","What is the first name of the eldest of your siblings?","What is your favorite television show?","If you needed a new first name, what would it be?","What is the first name of your youngest child?","When is your mother's birthday (MM/DD)?","What is your eldest child's middle name?","What is the last name of the funniest friend you know?","Name the highest mountain you've been to the top of?","What is the first name of your grandmother (your mother's mother)?","What is the first name of your grandfather (your mother's father)?","What was the first name of your best man/maid of honor?","What was the last name of your first grade teacher?","What is the last name of your first boyfriend or girlfriend?","Which high school did you attend?","What was your major during college?","What was the name of your first pet?","What was your favorite place from your childhood?","What is your favorite song?","What is your favorite car?","What is your mother’s middle name?","What is the (MM/DD) of your employment?","What is the make/model of first car?","What is the name of the city or town where you were born?","What is the name of your favorite childhood teacher?","What is the name of your favorite childhood friend?","What are your oldest sibling’s (MM/YYYY) of birth?","What is your oldest sibling’s middle name?","What school did you attend for sixth grade?","On what street did you live in third grade?"]
12
12
 
13
+ mattr_accessor :number_of_challenge_questions_stored
14
+ @@number_of_challenge_questions_stored = 3
13
15
 
14
- mattr_accessor :number_of_challenge_questions
15
- @@number_of_challenge_questions = 3
16
+ mattr_accessor :number_of_challenge_questions_asked
17
+ @@number_of_challenge_questions_asked = 1
16
18
  end
17
19
 
18
20
  module DeviseChallengeQuestionable
@@ -29,7 +29,7 @@ CONTENT
29
29
  belongs_to :#{class_name.underscore}
30
30
 
31
31
  validates :challenge_question, :challenge_answer, :presence => true
32
- validates :challenge_answer, :length => { :in => 3..56 }, :format => {:with => /^[\\w\\s:]*$/, :message => "can not contain special characters"}, :allow_blank => true
32
+ validates :challenge_answer, :length => { :in => 3..56 }, :format => {:with => /^[\\w\\s:\/]*$/, :message => "can not contain special characters"}, :allow_blank => true
33
33
 
34
34
  # Must use custom validation since uniqueness scope will not work with has_many association
35
35
  validate :challenge_question_uniqueness
@@ -79,7 +79,8 @@ CONTENT
79
79
  inject_into_file path, :after => "devise:\n" do
80
80
  <<-CONTENT
81
81
  challenge_questions:
82
- attempt_failed: "Attempt failed."
82
+ attempt_failed: "Attempt failed. Please try again."
83
+ max_attempts_reached: "You have reached the maximum attempts."
83
84
  updated_challenge_questions: "Successfully updated challenge questions."
84
85
  send_instructions: "You will receive an email with instructions about how to reset your challenge questions in a few minutes."
85
86
  CONTENT
@@ -19,10 +19,13 @@ module DeviseChallengeQuestionable
19
19
  config.max_challenge_question_attempts = 3
20
20
 
21
21
  # Number of challenge questions to store for each user
22
- config.number_of_challenge_questions = 3
22
+ config.number_of_challenge_questions_stored = 3
23
+
24
+ # Number of challenge questions to ask for each user
25
+ config.number_of_challenge_questions_asked = 1
23
26
 
24
27
  # Default challenge question options
25
- config.challenge_questions = ["What was your high school mascot?","In which city was your first elementary school?","In which city was your mother born?","What is the name of your favorite movie?","Who is your favorite athlete?","What was your most memorable gift as a child?","What is your favorite cartoon character?","What is the name of your favorite novel?","Name of favorite childhood pet?","What is the name of your elementary school?","What is your youngest child's middle name?","Last Name of your kindergarten teacher?","What is the first name of your grandmother (your father's mother)?","What is your spouse's nickname?","Name of the place where your wedding reception was held?","Name of a college you applied to but did not attend?","What is the first name of the youngest of your siblings?","What is the first name of the eldest of your siblings?","What is your favorite television show?","If you needed a new first name, what would it be?","What is the first name of your youngest child?","When is your mother's birthday (MM/DD)?","What is your eldest child's middle name?","What is the last name of the funniest friend you know?","Name the highest mountain you've been to the top of?","What is the first name of your grandmother (your mother's mother)?","What is the first name of your grandfather (your mother's father)?","What was the first name of your best man/maid of honor?","What was the last name of your first grade teacher?","What is the last name of your first boyfriend or girlfriend?","Which high school did you attend?","What was your major during college?","What was the name of your first pet?","What was your favorite place from your childhood?","What is your favorite song?","What is your favorite car?","What is your mother’s middle name?","What is the (MM/DD) of your employment?","What is the make/model of first car?","What is the name of the city or town where you were born?","What is the name of your favorite childhood teacher?","What is the name of your favorite childhood friend?","What are your oldest sibling’s (MM/YYYY) of birth?","What is your oldest sibling’s middle name?","What school did you attend for sixth grade?","On what street did you live in third grade?"]
28
+ config.challenge_questions = ["What was your high school mascot?","In which city was your first elementary school?","In which city was your mother born?","What is the name of your favorite movie?","Who is your favorite athlete?","What was your most memorable gift as a child?","What is your favorite cartoon character?","What is the name of your favorite novel?","Name of favorite childhood pet?","What is the name of your elementary school?","What is your youngest child's middle name?","What is the last name of your kindergarten teacher?","What is the first name of your grandmother (your father's mother)?","What is your spouse's nickname?","What is the name of the place where your wedding reception was held?","What is the name of a college you applied to but did not attend?","What is the first name of the youngest of your siblings?","What is the first name of the eldest of your siblings?","What is your favorite television show?","If you needed a new first name, what would it be?","What is the first name of your youngest child?","When is your mother's birthday (MM/DD)?","What is your eldest child's middle name?","What is the last name of the funniest friend you know?","What is the name the highest mountain you've been to the top of?","What is the first name of your grandmother (your mother's mother)?","What is the first name of your grandfather (your mother's father)?","What was the first name of your best man/maid of honor?","What was the last name of your first grade teacher?","What is the last name of your first boyfriend or girlfriend?","Which high school did you attend?","What was your major during college?","What was the name of your first pet?","What was your favorite place from your childhood?","What is your favorite song?","What is your favorite car?","What is your mother’s middle name?","What is the (MM/DD) of your employment?","What is the make/model of first car?","What is the name of the city or town where you were born?","What is the name of your favorite childhood teacher?","What is the name of your favorite childhood friend?","What are your oldest sibling’s month and year (MM/YYYY) of birth?","What is your oldest sibling’s middle name?","What school did you attend for sixth grade?","On what street did you live in third grade?","What is the name of the street where you first lived?","How many full bathrooms are in your home?","What type of home do you live in?","Where was your wedding rehearsal dinner held?","In what dormitory did you live in college?","What is the first name of your oldest cousin?","What is the last name of your high school counselor?","What is the first name of your favorite aunt?","How many nieces / nephews does / did your mother have?","How many nieces / nephews does / did your father have?","What instrument did you play in school?","What is the name of your favorite college professor?","In how many states have you lived?","How many windows does your kitchen have?","How many televisions do you have in your home?","What is the brand name of your hair dryer?","What is your favorite lipstick color?","What is the name of your favorite reality show?","Who is the designer of your wedding dress?","What is your favorite shoe style?","What is your favorite flower?","What physical attribute do you most admire of your boyfriend / girlfriend / spouse?","What is the brand name of your vacuum?","What’s your favorite fitness class?","What is your favorite spa treatment?","What is the color of your first car?","What is your favorite dessert?","Who is your cell phone carrier?","What is the name of your favorite restaurant?"]
26
29
 
27
30
  CONTENT
28
31
  end
metadata CHANGED
@@ -1,60 +1,69 @@
1
- --- !ruby/object:Gem::Specification
1
+ --- !ruby/object:Gem::Specification
2
2
  name: devise_challenge_questionable
3
- version: !ruby/object:Gem::Version
4
- version: 0.1.2
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.2.2
5
5
  platform: ruby
6
- authors:
6
+ authors:
7
7
  - Andrew Kennedy
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
-
12
- date: 2014-02-13 00:00:00 Z
13
- dependencies:
14
- - !ruby/object:Gem::Dependency
11
+ date: 2014-02-20 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
15
14
  name: rails
16
- prerelease: false
17
- requirement: &id001 !ruby/object:Gem::Requirement
18
- requirements:
19
- - - "="
20
- - !ruby/object:Gem::Version
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - '='
18
+ - !ruby/object:Gem::Version
21
19
  version: 3.0.20
22
20
  type: :runtime
23
- version_requirements: *id001
24
- - !ruby/object:Gem::Dependency
25
- name: devise
26
21
  prerelease: false
27
- requirement: &id002 !ruby/object:Gem::Requirement
28
- requirements:
29
- - - "="
30
- - !ruby/object:Gem::Version
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - '='
25
+ - !ruby/object:Gem::Version
26
+ version: 3.0.20
27
+ - !ruby/object:Gem::Dependency
28
+ name: devise
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - '='
32
+ - !ruby/object:Gem::Version
31
33
  version: 1.1.3
32
34
  type: :runtime
33
- version_requirements: *id002
34
- - !ruby/object:Gem::Dependency
35
- name: bundler
36
35
  prerelease: false
37
- requirement: &id003 !ruby/object:Gem::Requirement
38
- requirements:
39
- - &id004
40
- - ">="
41
- - !ruby/object:Gem::Version
42
- version: "0"
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - '='
39
+ - !ruby/object:Gem::Version
40
+ version: 1.1.3
41
+ - !ruby/object:Gem::Dependency
42
+ name: bundler
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - '>='
46
+ - !ruby/object:Gem::Version
47
+ version: '0'
43
48
  type: :development
44
- version_requirements: *id003
45
- description: " ### Features ###\n * configure max challenge question attempts\n * per user level control if he really need challenge questions\n"
46
- email:
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - '>='
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
55
+ description: |2
56
+ ### Features ###
57
+ * configure max challenge question attempts
58
+ * per user level control if he really need challenge questions
59
+ email:
47
60
  - andrew@akennedy.io
48
61
  executables: []
49
-
50
62
  extensions: []
51
-
52
63
  extra_rdoc_files: []
53
-
54
- files:
64
+ files:
55
65
  - .gitignore
56
66
  - Gemfile
57
- - LICENSE
58
67
  - README.md
59
68
  - Rakefile
60
69
  - app/controllers/devise/challenge_questions_controller.rb
@@ -83,26 +92,25 @@ files:
83
92
  - lib/generators/devise_challenge_questionable/views_generator.rb
84
93
  homepage: https://github.com/akennedy/devise_challenge_questionable
85
94
  licenses: []
86
-
87
95
  metadata: {}
88
-
89
96
  post_install_message:
90
97
  rdoc_options: []
91
-
92
- require_paths:
98
+ require_paths:
93
99
  - lib
94
- required_ruby_version: !ruby/object:Gem::Requirement
95
- requirements:
96
- - *id004
97
- required_rubygems_version: !ruby/object:Gem::Requirement
98
- requirements:
99
- - *id004
100
+ required_ruby_version: !ruby/object:Gem::Requirement
101
+ requirements:
102
+ - - '>='
103
+ - !ruby/object:Gem::Version
104
+ version: '0'
105
+ required_rubygems_version: !ruby/object:Gem::Requirement
106
+ requirements:
107
+ - - '>='
108
+ - !ruby/object:Gem::Version
109
+ version: '0'
100
110
  requirements: []
101
-
102
111
  rubyforge_project: devise_challenge_questionable
103
- rubygems_version: 2.0.13
112
+ rubygems_version: 2.1.10
104
113
  signing_key:
105
114
  specification_version: 4
106
115
  summary: Challenge question plugin for devise
107
116
  test_files: []
108
-
data/LICENSE DELETED
@@ -1,19 +0,0 @@
1
- Copyright (C) 2012 Dmitrii Golub
2
-
3
- Permission is hereby granted, free of charge, to any person obtaining a copy of
4
- this software and associated documentation files (the "Software"), to deal in
5
- the Software without restriction, including without limitation the rights to
6
- use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
7
- of the Software, and to permit persons to whom the Software is furnished to do
8
- so, subject to the following conditions:
9
-
10
- The above copyright notice and this permission notice shall be included in all
11
- copies or substantial portions of the Software.
12
-
13
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14
- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15
- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16
- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17
- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18
- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
19
- SOFTWARE.