devise_code_authenticatable 0.0.2 → 0.0.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/app/controllers/devise/login_codes_controller.rb +34 -0
- data/app/controllers/devise_code_authenticatable/sessions_controller.rb +13 -33
- data/app/views/devise/mailer/login_code.html.erb +3 -0
- data/config/locales/zh-CN.yml +6 -0
- data/lib/devise_code_authenticatable.rb +6 -1
- data/lib/devise_code_authenticatable/login_code.rb +39 -0
- data/lib/devise_code_authenticatable/mailer.rb +1 -1
- data/lib/devise_code_authenticatable/models.rb +18 -0
- data/lib/devise_code_authenticatable/models/code_authenticatable.rb +26 -32
- data/lib/devise_code_authenticatable/parameter_sanitizer.rb +31 -0
- data/lib/devise_code_authenticatable/rails.rb +4 -5
- data/lib/devise_code_authenticatable/routes.rb +14 -0
- data/lib/devise_code_authenticatable/strategies/code_authenticatable.rb +14 -16
- data/lib/devise_code_authenticatable/version.rb +1 -1
- metadata +8 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: dc1ea3a8d3b732724bf54629e2a7dd86c97e7145fcc1f00765813c2b3b017324
|
4
|
+
data.tar.gz: b8fe672f496cdda4ca7c87b6f043b055b588295658ace9b5ef74b11a5c6fbe10
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 492a5f582df7fce07fb4a7fbdc1e33b0e38da4fc0048f73569c3837751c7ab6b9669ecc55f02726e8ee3ad02b072ca3633084c5289e333a31f53ff5447d9d870
|
7
|
+
data.tar.gz: b88f0f6283fdb15382dc096ed6c445ad753560481eb325a9596965e05cb5b65d6004a3ba700c5867138c3f7821e0a6df48a001e684bb95e321728ff2106f1308
|
@@ -0,0 +1,34 @@
|
|
1
|
+
class Devise::LoginCodesController < DeviseController
|
2
|
+
prepend_before_action :allow_params_authentication!, only: :verify
|
3
|
+
|
4
|
+
def verify
|
5
|
+
self.resource = warden.authenticate!(auth_options)
|
6
|
+
set_flash_message!(:notice, :signed_in)
|
7
|
+
sign_in(resource_name, resource)
|
8
|
+
yield resource if block_given?
|
9
|
+
respond_with resource, location: after_sign_in_path_for(resource)
|
10
|
+
end
|
11
|
+
|
12
|
+
def show
|
13
|
+
email = LoginCode.find(params[:id]).user.email
|
14
|
+
@login_code_id = params[:id]
|
15
|
+
self.resource = resource_class.new(email: email)
|
16
|
+
end
|
17
|
+
|
18
|
+
protected
|
19
|
+
def auth_options
|
20
|
+
:code_authenticatable
|
21
|
+
end
|
22
|
+
|
23
|
+
def sign_in_params
|
24
|
+
devise_parameter_sanitizer.sanitize(:sign_in)
|
25
|
+
end
|
26
|
+
|
27
|
+
def serialize_options(resource)
|
28
|
+
methods = resource_class.authentication_keys.dup
|
29
|
+
methods = methods.keys if methods.is_a?(Hash)
|
30
|
+
methods << :login_code if resource.respond_to?(:login_code)
|
31
|
+
{ methods: methods, only: [:login_code] }
|
32
|
+
end
|
33
|
+
|
34
|
+
end
|
@@ -1,43 +1,23 @@
|
|
1
1
|
class DeviseCodeAuthenticatable::SessionsController < Devise::SessionsController
|
2
|
-
before_action :configure_permitted_parameters
|
3
2
|
|
4
3
|
def create
|
5
|
-
|
6
|
-
|
7
|
-
yield resource if block_given?
|
4
|
+
self.resource = resource_class.send_code_login_instructions(resource_params)
|
5
|
+
yield resource if block_given?
|
8
6
|
|
9
|
-
|
10
|
-
|
11
|
-
respond_with(resource, location: after_sending_login_code_path_for(resource))
|
12
|
-
end
|
13
|
-
else
|
14
|
-
resource = warden.authenticate!(auth_options)
|
15
|
-
set_flash_message!(:notice, :signed_in)
|
16
|
-
sign_in(resource_name, resource)
|
17
|
-
yield resource if block_given?
|
18
|
-
respond_with resource, location: after_sign_in_path_for(resource)
|
7
|
+
if successfully_sent?(resource)
|
8
|
+
cookies[:devise_resource_email] = resource.email
|
19
9
|
end
|
20
|
-
end
|
21
|
-
|
22
|
-
protected
|
23
|
-
def auth_options
|
24
|
-
:code_authenticatable
|
25
|
-
end
|
26
|
-
|
27
|
-
def after_sending_login_code_path_for(resource)
|
28
|
-
new_session_path(resource)
|
29
|
-
end
|
30
10
|
|
31
|
-
|
32
|
-
devise_parameter_sanitizer.sanitize(:sign_in)
|
11
|
+
respond_with(resource, location: after_sending_login_code_path_for(resource_name, resource))
|
33
12
|
end
|
34
13
|
|
35
|
-
|
36
|
-
|
37
|
-
|
14
|
+
protected
|
15
|
+
def auth_options
|
16
|
+
:code_authenticatable
|
17
|
+
end
|
38
18
|
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
19
|
+
def after_sending_login_code_path_for(resource_name, resource)
|
20
|
+
byebug
|
21
|
+
login_code_path(resource_name, resource.existing_login_code) if is_navigational_format?
|
22
|
+
end
|
43
23
|
end
|
data/config/locales/zh-CN.yml
CHANGED
@@ -1,6 +1,9 @@
|
|
1
1
|
module DeviseCodeAuthenticatable
|
2
2
|
autoload :Mailer, 'devise_code_authenticatable/mailer'
|
3
|
+
autoload :LoginCode, 'devise_code_authenticatable/login_code'
|
3
4
|
autoload :Mapping, 'devise_code_authenticatable/mapping'
|
5
|
+
autoload :ParameterSanitizer, 'devise_code_authenticatable/parameter_sanitizer'
|
6
|
+
|
4
7
|
|
5
8
|
module Controllers
|
6
9
|
autoload :Helpers, 'devise_code_authenticatable/controllers/helpers'
|
@@ -11,6 +14,7 @@ end
|
|
11
14
|
|
12
15
|
require 'devise'
|
13
16
|
require 'devise_code_authenticatable/strategies/code_authenticatable'
|
17
|
+
require 'devise_code_authenticatable/routes'
|
14
18
|
require 'devise_code_authenticatable/rails'
|
15
19
|
|
16
20
|
module Devise
|
@@ -20,4 +24,5 @@ end
|
|
20
24
|
|
21
25
|
Devise.add_module :code_authenticatable,
|
22
26
|
strategy: true,
|
23
|
-
model: 'devise_code_authenticatable/models
|
27
|
+
model: 'devise_code_authenticatable/models',
|
28
|
+
route: { login_code: [nil, :new, :create] }
|
@@ -0,0 +1,39 @@
|
|
1
|
+
module DeviseCodeAuthenticatable
|
2
|
+
module LoginCode
|
3
|
+
extend ActiveSupport::Concern
|
4
|
+
|
5
|
+
included do
|
6
|
+
belongs_to :user
|
7
|
+
|
8
|
+
after_initialize :default_values
|
9
|
+
end
|
10
|
+
|
11
|
+
def default_values
|
12
|
+
self.code ||= rand(10000..99999)
|
13
|
+
self.expired ||= false
|
14
|
+
self.retry_times ||= 0
|
15
|
+
self.deliver_method ||= "email"
|
16
|
+
end
|
17
|
+
|
18
|
+
def verify(code)
|
19
|
+
if expired?
|
20
|
+
raise ActiveModel::Errors "expired code should never be validated!"
|
21
|
+
end
|
22
|
+
|
23
|
+
self.retry_times += 1; save
|
24
|
+
self.code == code
|
25
|
+
end
|
26
|
+
|
27
|
+
def expired?
|
28
|
+
retry_time_limit = 5
|
29
|
+
expire_at = (self.created_at || Time.now) + 10.minutes
|
30
|
+
|
31
|
+
self.expired = self.expired || Time.now.after?(expire_at) || self.retry_times.to_i > retry_time_limit
|
32
|
+
end
|
33
|
+
|
34
|
+
def expire_now
|
35
|
+
self.expired = true; save
|
36
|
+
end
|
37
|
+
|
38
|
+
end
|
39
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
require 'active_support/deprecation'
|
2
|
+
require 'devise_code_authenticatable/models/code_authenticatable'
|
3
|
+
|
4
|
+
module Devise
|
5
|
+
module Models
|
6
|
+
module CodeAuthenticatable
|
7
|
+
extend ActiveSupport::Concern
|
8
|
+
|
9
|
+
|
10
|
+
module ClassMethods
|
11
|
+
def send_login_token_keys
|
12
|
+
[:email]
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
@@ -4,51 +4,45 @@ module Devise
|
|
4
4
|
extend ActiveSupport::Concern
|
5
5
|
|
6
6
|
included do
|
7
|
+
has_many :login_codes
|
7
8
|
end
|
8
9
|
|
9
|
-
|
10
|
-
|
11
|
-
resource = self.find_by(resource_params)
|
12
|
-
if resource
|
13
|
-
resource.resend_login_code
|
14
|
-
resource
|
15
|
-
else
|
16
|
-
self.new(resource_params)
|
17
|
-
end
|
18
|
-
end
|
19
|
-
|
10
|
+
def login_code
|
11
|
+
existing_login_code&.code
|
20
12
|
end
|
21
13
|
|
22
|
-
def
|
23
|
-
|
24
|
-
send_devise_notification(:
|
14
|
+
def send_code_login_instructions
|
15
|
+
login_code = existing_login_code || generate_login_code
|
16
|
+
send_devise_notification(:code_login_instructions, login_code, {})
|
25
17
|
end
|
26
18
|
|
27
|
-
def
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
19
|
+
def existing_login_code
|
20
|
+
latest_code = login_codes.last
|
21
|
+
if latest_code && !latest_code.expired?
|
22
|
+
login_codes.last
|
23
|
+
else
|
24
|
+
nil
|
25
|
+
end
|
34
26
|
end
|
35
27
|
|
36
|
-
def
|
37
|
-
|
38
|
-
|
28
|
+
def generate_login_code
|
29
|
+
login_codes.create!.code
|
30
|
+
end
|
39
31
|
|
40
|
-
|
41
|
-
|
32
|
+
def after_code_authentication
|
33
|
+
expire_all_login_codes
|
42
34
|
end
|
43
35
|
|
44
|
-
def
|
45
|
-
|
46
|
-
self.update(login_code_retry_time: (self.login_code_retry_time.to_i + 1))
|
47
|
-
self.login_code == login_code
|
48
|
-
end
|
36
|
+
def expire_all_login_codes
|
37
|
+
login_codes.each &:expire_now
|
49
38
|
end
|
50
39
|
|
51
|
-
|
40
|
+
module ClassMethods
|
41
|
+
def send_code_login_instructions(attributes={})
|
42
|
+
code_authenticatable = find_or_initialize_with_errors(send_login_token_keys, attributes, :not_found)
|
43
|
+
code_authenticatable.send_code_login_instructions if code_authenticatable.persisted?
|
44
|
+
code_authenticatable
|
45
|
+
end
|
52
46
|
end
|
53
47
|
|
54
48
|
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
module DeviseCodeAuthenticatable
|
2
|
+
module ParameterSanitizer
|
3
|
+
if defined?(Devise::BaseSanitizer)
|
4
|
+
def sign_in
|
5
|
+
permit self.for(:sign_in)
|
6
|
+
end
|
7
|
+
end
|
8
|
+
|
9
|
+
private
|
10
|
+
|
11
|
+
if defined?(Devise::BaseSanitizer)
|
12
|
+
def permit(keys)
|
13
|
+
default_params.permit(*Array(keys))
|
14
|
+
end
|
15
|
+
|
16
|
+
def attributes_for(kind)
|
17
|
+
case kind
|
18
|
+
when :sign_in
|
19
|
+
[:email, :login_code]
|
20
|
+
else
|
21
|
+
super
|
22
|
+
end
|
23
|
+
end
|
24
|
+
else
|
25
|
+
def initialize(resource_class, resource_name, params)
|
26
|
+
super
|
27
|
+
permit(:login_code, keys: [:email, :login_code] )
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
@@ -14,10 +14,9 @@ module DeviseCodeAuthenticatable
|
|
14
14
|
Devise.mailer.send :include, Devise::Mailers::Helpers
|
15
15
|
end
|
16
16
|
end
|
17
|
-
#
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
# end
|
17
|
+
# extend mapping with after_initialize because it's not reloaded
|
18
|
+
config.after_initialize do
|
19
|
+
Devise::ParameterSanitizer.send :prepend, DeviseCodeAuthenticatable::ParameterSanitizer
|
20
|
+
end
|
22
21
|
end
|
23
22
|
end
|
@@ -2,31 +2,29 @@ require 'devise/strategies/base'
|
|
2
2
|
|
3
3
|
module DeviseCodeAuthenticatable
|
4
4
|
module Strategies
|
5
|
-
|
6
5
|
class CodeAuthenticatable < Devise::Strategies::Authenticatable
|
6
|
+
|
7
7
|
def authenticate!
|
8
8
|
resource = mapping.to.find_for_authentication(authentication_hash)
|
9
9
|
hashed = false
|
10
10
|
login_code = params[scope].fetch "login_code", ""
|
11
11
|
|
12
|
-
if resource
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
fail(:invalid_login_code)
|
24
|
-
end
|
25
|
-
end
|
12
|
+
if resource.existing_login_code.expired?
|
13
|
+
fail(:login_code_expired)
|
14
|
+
resource.send_login_code
|
15
|
+
respond_with(resource, location: after_sending_login_code_path_for(resource))
|
16
|
+
end
|
17
|
+
|
18
|
+
if validate(resource){ hashed = true; resource.existing_login_code.verify(login_code) }
|
19
|
+
remember_me(resource)
|
20
|
+
cookies[:devise_resource_email] = resource.email
|
21
|
+
resource.after_code_authentication
|
22
|
+
success!(resource)
|
26
23
|
else
|
27
|
-
fail(:
|
24
|
+
fail(:invalid_login_code)
|
28
25
|
end
|
29
26
|
end
|
27
|
+
|
30
28
|
end
|
31
29
|
end
|
32
30
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: devise_code_authenticatable
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.3
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- vincentying15
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2020-02-
|
11
|
+
date: 2020-02-14 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rails
|
@@ -40,14 +40,20 @@ files:
|
|
40
40
|
- LICENSE
|
41
41
|
- README.md
|
42
42
|
- Rakefile
|
43
|
+
- app/controllers/devise/login_codes_controller.rb
|
43
44
|
- app/controllers/devise_code_authenticatable/sessions_controller.rb
|
45
|
+
- app/views/devise/mailer/login_code.html.erb
|
44
46
|
- config/locales/zh-CN.yml
|
45
47
|
- lib/devise_code_authenticatable.rb
|
46
48
|
- lib/devise_code_authenticatable/controllers/helpers.rb
|
49
|
+
- lib/devise_code_authenticatable/login_code.rb
|
47
50
|
- lib/devise_code_authenticatable/mailer.rb
|
48
51
|
- lib/devise_code_authenticatable/mapping.rb
|
52
|
+
- lib/devise_code_authenticatable/models.rb
|
49
53
|
- lib/devise_code_authenticatable/models/code_authenticatable.rb
|
54
|
+
- lib/devise_code_authenticatable/parameter_sanitizer.rb
|
50
55
|
- lib/devise_code_authenticatable/rails.rb
|
56
|
+
- lib/devise_code_authenticatable/routes.rb
|
51
57
|
- lib/devise_code_authenticatable/strategies/code_authenticatable.rb
|
52
58
|
- lib/devise_code_authenticatable/version.rb
|
53
59
|
homepage: https://rubygems.org/gems/devise_code_authenticatable
|