devise_challenge_questionable 2.0.0 → 3.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -7
- data/app/controllers/devise/challenge_questions_controller.rb +25 -25
- data/app/views/devise/challenge_questions/edit.html.erb +7 -22
- data/devise_challenge_questionable.gemspec +2 -2
- data/lib/devise_challenge_questionable/model.rb +16 -13
- data/lib/devise_challenge_questionable/version.rb +1 -1
- metadata +59 -50
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
|
-
---
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: acd5b7ad0c084ac1b32b14e5b1a99304331bcf69
|
4
|
+
data.tar.gz: 0b5a8e1beda7d9fa6122cf82c1cc8d84d8f60888
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 51f20aadea678518607ad1218657ac8f94090b02bc37a6a55a8229c3d5c36c0966997979774727f79ec6d3894eeb158ad2195503cd7298a4984854cd66095717
|
7
|
+
data.tar.gz: bb3661027fe1009ee2f309931a0857ec9004671c10915c8a473daaf206d2dd1e3a7f916f719368bb9ad372e573f7b858095f91dd9e9aba86e21a627e780397b3
|
@@ -3,13 +3,13 @@ class Devise::ChallengeQuestionsController < DeviseController
|
|
3
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
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
|
9
9
|
build_resource
|
10
|
-
|
10
|
+
render :new
|
11
11
|
end
|
12
|
-
|
12
|
+
|
13
13
|
# POST /resource/challenge_question
|
14
14
|
def create
|
15
15
|
self.resource = resource_class.send_reset_challenge_questions_instructions(params[resource_name])
|
@@ -17,18 +17,18 @@ class Devise::ChallengeQuestionsController < DeviseController
|
|
17
17
|
set_flash_message :notice, :send_instructions
|
18
18
|
redirect_to new_session_path(resource_name)
|
19
19
|
else
|
20
|
-
|
20
|
+
render :new
|
21
21
|
end
|
22
22
|
end
|
23
|
-
|
23
|
+
|
24
24
|
# GET /resource/challenge_question/edit?reset_challenge_questions_token=abcdef
|
25
25
|
def edit
|
26
26
|
self.resource = resource_class.new
|
27
27
|
resource.reset_challenge_questions_token = params[:reset_challenge_questions_token]
|
28
28
|
Devise.number_of_challenge_questions_stored.times { resource.send("#{resource_name}_challenge_questions").build }
|
29
|
-
|
29
|
+
render :edit
|
30
30
|
end
|
31
|
-
|
31
|
+
|
32
32
|
# PUT /resource/challenge_question
|
33
33
|
def update
|
34
34
|
self.resource = resource_class.reset_challenge_questions_by_token(params[resource_name])
|
@@ -37,7 +37,7 @@ class Devise::ChallengeQuestionsController < DeviseController
|
|
37
37
|
set_flash_message :notice, :updated_challenge_questions
|
38
38
|
redirect_to :root
|
39
39
|
else
|
40
|
-
|
40
|
+
render :edit
|
41
41
|
end
|
42
42
|
end
|
43
43
|
|
@@ -45,11 +45,11 @@ class Devise::ChallengeQuestionsController < DeviseController
|
|
45
45
|
def show
|
46
46
|
@challenge_questions = resource.send("#{resource_name}_challenge_questions").sample(params[:limit].try(:to_i) || Devise.number_of_challenge_questions_asked)
|
47
47
|
respond_to do |format|
|
48
|
-
format.html {
|
48
|
+
format.html { render :show }
|
49
49
|
format.json { render :json => @challenge_questions.as_json(:only => [:id, :challenge_question]) }
|
50
50
|
end
|
51
51
|
end
|
52
|
-
|
52
|
+
|
53
53
|
def authenticate
|
54
54
|
build_challenge_questions
|
55
55
|
if @challenge_questions.present? && challenge_questions_authenticated?
|
@@ -61,21 +61,21 @@ class Devise::ChallengeQuestionsController < DeviseController
|
|
61
61
|
else
|
62
62
|
failed_attempts
|
63
63
|
end
|
64
|
-
end
|
64
|
+
end
|
65
65
|
end
|
66
|
-
|
66
|
+
|
67
67
|
# Build token and redirect
|
68
68
|
def manage
|
69
69
|
resource.set_reset_challenge_questions_token
|
70
70
|
sign_out(resource)
|
71
|
-
redirect_to edit_challenge_question_path(resource, :reset_challenge_questions_token => resource.reset_challenge_questions_token)
|
71
|
+
redirect_to edit_challenge_question_path(resource, :reset_challenge_questions_token => resource.reset_challenge_questions_token)
|
72
72
|
end
|
73
|
-
|
73
|
+
|
74
74
|
def forgot
|
75
75
|
sign_out(resource)
|
76
|
-
redirect_to new_challenge_question_path(resource_name)
|
76
|
+
redirect_to new_challenge_question_path(resource_name)
|
77
77
|
end
|
78
|
-
|
78
|
+
|
79
79
|
def max_challenge_question_attempts_reached
|
80
80
|
end
|
81
81
|
|
@@ -90,21 +90,21 @@ class Devise::ChallengeQuestionsController < DeviseController
|
|
90
90
|
@limit = resource.class.max_challenge_question_attempts
|
91
91
|
if resource.max_challenge_question_attempts?
|
92
92
|
sign_out(resource)
|
93
|
-
|
93
|
+
render :max_challenge_question_attempts_reached and return
|
94
94
|
end
|
95
95
|
end
|
96
|
-
|
96
|
+
|
97
97
|
def challenge_questions_authenticated?
|
98
98
|
@challenge_questions.all?{|question| Digest::MD5.hexdigest(question[:challenge_answer].try(:downcase).to_s).eql?(question[:answer])}
|
99
99
|
end
|
100
|
-
|
100
|
+
|
101
101
|
def build_challenge_questions
|
102
102
|
respond_to do |format|
|
103
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
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
105
|
end
|
106
106
|
end
|
107
|
-
|
107
|
+
|
108
108
|
def challenge_questions_authenticated
|
109
109
|
respond_to do |format|
|
110
110
|
format.html do
|
@@ -115,25 +115,25 @@ class Devise::ChallengeQuestionsController < DeviseController
|
|
115
115
|
end
|
116
116
|
resource.update_attribute(:challenge_question_failed_attempts, 0)
|
117
117
|
end
|
118
|
-
|
118
|
+
|
119
119
|
def set_failed_attempt
|
120
120
|
resource.challenge_question_failed_attempts += 1
|
121
121
|
resource.save
|
122
122
|
end
|
123
|
-
|
123
|
+
|
124
124
|
def max_failed_attempts
|
125
125
|
resource.max_challenge_question_lock_account
|
126
126
|
sign_out(resource)
|
127
127
|
respond_to do |format|
|
128
|
-
format.html {
|
128
|
+
format.html { render :max_challenge_question_attempts_reached and return }
|
129
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
130
|
end
|
131
131
|
end
|
132
|
-
|
132
|
+
|
133
133
|
def failed_attempts
|
134
134
|
respond_to do |format|
|
135
135
|
format.html { redirect_to send("#{resource_name}_challenge_question_path" ) }
|
136
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
137
|
end
|
138
138
|
end
|
139
|
-
end
|
139
|
+
end
|
@@ -7,7 +7,7 @@
|
|
7
7
|
<%= devise_error_messages! %>
|
8
8
|
<%= f.hidden_field :id %>
|
9
9
|
<%= f.hidden_field :reset_challenge_questions_token %>
|
10
|
-
|
10
|
+
|
11
11
|
<%= f.fields_for :"#{resource_name}_challenge_questions", resource.send("#{resource_name}_challenge_questions") do |cq| %>
|
12
12
|
<% if cq.object.new_record? %>
|
13
13
|
<p>
|
@@ -40,25 +40,10 @@
|
|
40
40
|
|
41
41
|
<script type="text/javascript" language="javascript">
|
42
42
|
if (window.jQuery) {
|
43
|
-
|
44
|
-
$
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
otherSelects.find('option:contains('+ $(this).val() +')').attr('disabled', 'disabled');
|
49
|
-
if (prevVal) {
|
50
|
-
otherSelects.find('option:contains('+ prevVal +')').removeAttr('disabled');
|
51
|
-
}
|
52
|
-
$this.data("prev", $this.val());
|
53
|
-
});
|
54
|
-
|
55
|
-
$("select").each(function () {
|
56
|
-
var $this = $(this);
|
57
|
-
var prevVal = $this.data("prev");
|
58
|
-
var otherSelects = $("select").not(this);
|
59
|
-
otherSelects.find('option:contains('+ $(this).val() +')').attr('disabled', 'disabled');
|
60
|
-
$this.data("prev", $this.val());
|
61
|
-
});
|
62
|
-
});
|
43
|
+
$('select').on('change', function(e) {
|
44
|
+
var $this = $(this);
|
45
|
+
var otherSelects = $("select").not(this);
|
46
|
+
otherSelects.find('option:contains('+ $(this).val() +')').attr('disabled','disabled')
|
47
|
+
})
|
63
48
|
}
|
64
|
-
</script>
|
49
|
+
</script>
|
@@ -22,8 +22,8 @@ Gem::Specification.new do |s|
|
|
22
22
|
s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
|
23
23
|
s.require_paths = ["lib"]
|
24
24
|
|
25
|
-
s.add_runtime_dependency 'rails', '>=
|
26
|
-
s.add_runtime_dependency 'devise', '>=
|
25
|
+
s.add_runtime_dependency 'rails', '>= 4.0.0'
|
26
|
+
s.add_runtime_dependency 'devise', '>= 4.0.0'
|
27
27
|
|
28
28
|
s.add_development_dependency 'bundler'
|
29
29
|
end
|
@@ -3,12 +3,12 @@ module Devise
|
|
3
3
|
module Models
|
4
4
|
module ChallengeQuestionable
|
5
5
|
extend ActiveSupport::Concern
|
6
|
-
|
6
|
+
|
7
7
|
# Update challenge questions saving the record and clearing token. Returns true if
|
8
8
|
# the challenge questions are valid and the record was saved, false otherwise.
|
9
9
|
def reset_challenge_questions!(attributes)
|
10
10
|
self.send("#{self.class.name.underscore}_challenge_questions").destroy_all
|
11
|
-
self.attributes = {"#{self.class.name.underscore}_challenge_questions_attributes" => attributes["#{self.class.name.underscore}_challenge_questions_attributes"]}
|
11
|
+
self.attributes = {"#{self.class.name.underscore}_challenge_questions_attributes" => attributes["#{self.class.name.underscore}_challenge_questions_attributes"]}
|
12
12
|
clear_reset_challenge_questions_token if self.valid?
|
13
13
|
self.save
|
14
14
|
end
|
@@ -16,11 +16,11 @@ module Devise
|
|
16
16
|
def login_challenge_questions?(request)
|
17
17
|
true
|
18
18
|
end
|
19
|
-
|
19
|
+
|
20
20
|
def set_challenge_questions?(request)
|
21
21
|
true
|
22
22
|
end
|
23
|
-
|
23
|
+
|
24
24
|
def max_challenge_question_lock_account
|
25
25
|
self.lock_access! if self.class.lock_strategy_enabled?(:failed_attempts)
|
26
26
|
end
|
@@ -28,18 +28,18 @@ module Devise
|
|
28
28
|
def max_challenge_question_attempts?
|
29
29
|
challenge_question_failed_attempts >= self.class.max_challenge_question_attempts
|
30
30
|
end
|
31
|
-
|
31
|
+
|
32
32
|
# Resets reset challenge question token and send reset challenge question instructions by email
|
33
33
|
def send_reset_challenge_questions_instructions
|
34
34
|
generate_reset_challenge_questions_token!
|
35
35
|
::Devise.mailer.reset_challenge_questions_instructions(self).deliver
|
36
36
|
end
|
37
|
-
|
37
|
+
|
38
38
|
# Generates a new random token for reset challenge_question
|
39
39
|
def set_reset_challenge_questions_token
|
40
40
|
generate_reset_challenge_questions_token!
|
41
41
|
end
|
42
|
-
|
42
|
+
|
43
43
|
def unlock_access_including_challenge_questions!
|
44
44
|
if_access_locked do
|
45
45
|
self.locked_at = nil
|
@@ -49,7 +49,7 @@ module Devise
|
|
49
49
|
save(:validate => false)
|
50
50
|
end
|
51
51
|
end
|
52
|
-
|
52
|
+
|
53
53
|
protected
|
54
54
|
|
55
55
|
# Generates a new random token for reset challenge_question
|
@@ -67,14 +67,14 @@ module Devise
|
|
67
67
|
def clear_reset_challenge_questions_token
|
68
68
|
self.reset_challenge_questions_token = nil
|
69
69
|
end
|
70
|
-
|
70
|
+
|
71
71
|
def clear_challenge_question_failed_attempts
|
72
72
|
self.challenge_question_failed_attempts = 0
|
73
73
|
end
|
74
|
-
|
74
|
+
|
75
75
|
module ClassMethods
|
76
76
|
::Devise::Models.config(self, :max_challenge_question_attempts)
|
77
|
-
|
77
|
+
|
78
78
|
# Attempt to find a user by it's email. If a record is found, send new
|
79
79
|
# challenge_question instructions to it. If not user is found, returns a new user
|
80
80
|
# with an email not found error.
|
@@ -87,7 +87,10 @@ module Devise
|
|
87
87
|
|
88
88
|
# Generate a token checking if one does not already exist in the database.
|
89
89
|
def reset_challenge_questions_token
|
90
|
-
|
90
|
+
loop do
|
91
|
+
token = Devise.friendly_token
|
92
|
+
break token unless User.find_by(:reset_challenge_questions_token => token)
|
93
|
+
end
|
91
94
|
end
|
92
95
|
|
93
96
|
# Attempt to find a user by it's reset_challenge_questions_token to reset it's
|
@@ -103,4 +106,4 @@ module Devise
|
|
103
106
|
end
|
104
107
|
end
|
105
108
|
end
|
106
|
-
end
|
109
|
+
end
|
metadata
CHANGED
@@ -1,58 +1,68 @@
|
|
1
|
-
--- !ruby/object:Gem::Specification
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
2
|
name: devise_challenge_questionable
|
3
|
-
version: !ruby/object:Gem::Version
|
4
|
-
version:
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 3.0.0
|
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
|
-
|
13
|
-
|
14
|
-
- !ruby/object:Gem::Dependency
|
11
|
+
date: 2017-01-26 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
15
14
|
name: rails
|
16
|
-
|
17
|
-
|
18
|
-
requirements:
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
19
17
|
- - ">="
|
20
|
-
- !ruby/object:Gem::Version
|
21
|
-
version:
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: 4.0.0
|
22
20
|
type: :runtime
|
23
|
-
version_requirements: *id001
|
24
|
-
- !ruby/object:Gem::Dependency
|
25
|
-
name: devise
|
26
21
|
prerelease: false
|
27
|
-
|
28
|
-
requirements:
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
29
24
|
- - ">="
|
30
|
-
- !ruby/object:Gem::Version
|
31
|
-
version:
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: 4.0.0
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: devise
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - ">="
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: 4.0.0
|
32
34
|
type: :runtime
|
33
|
-
version_requirements: *id002
|
34
|
-
- !ruby/object:Gem::Dependency
|
35
|
-
name: bundler
|
36
35
|
prerelease: false
|
37
|
-
|
38
|
-
requirements:
|
39
|
-
-
|
40
|
-
-
|
41
|
-
|
42
|
-
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - ">="
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: 4.0.0
|
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
|
-
|
45
|
-
|
46
|
-
|
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
|
-
|
55
|
-
- .gitignore
|
64
|
+
files:
|
65
|
+
- ".gitignore"
|
56
66
|
- Gemfile
|
57
67
|
- README.md
|
58
68
|
- Rakefile
|
@@ -82,26 +92,25 @@ files:
|
|
82
92
|
- lib/generators/devise_challenge_questionable/views_generator.rb
|
83
93
|
homepage: https://github.com/akennedy/devise_challenge_questionable
|
84
94
|
licenses: []
|
85
|
-
|
86
95
|
metadata: {}
|
87
|
-
|
88
96
|
post_install_message:
|
89
97
|
rdoc_options: []
|
90
|
-
|
91
|
-
require_paths:
|
98
|
+
require_paths:
|
92
99
|
- lib
|
93
|
-
required_ruby_version: !ruby/object:Gem::Requirement
|
94
|
-
requirements:
|
95
|
-
-
|
96
|
-
|
97
|
-
|
98
|
-
|
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'
|
99
110
|
requirements: []
|
100
|
-
|
101
111
|
rubyforge_project: devise_challenge_questionable
|
102
|
-
rubygems_version: 2.
|
112
|
+
rubygems_version: 2.6.6
|
103
113
|
signing_key:
|
104
114
|
specification_version: 4
|
105
115
|
summary: Challenge question plugin for devise
|
106
116
|
test_files: []
|
107
|
-
|