devise_token_auth 1.0.0 → 1.2.2
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 +5 -5
- data/README.md +6 -3
- data/app/controllers/devise_token_auth/application_controller.rb +23 -3
- data/app/controllers/devise_token_auth/concerns/resource_finder.rb +24 -11
- data/app/controllers/devise_token_auth/concerns/set_user_by_token.rb +78 -57
- data/app/controllers/devise_token_auth/confirmations_controller.rb +69 -19
- data/app/controllers/devise_token_auth/omniauth_callbacks_controller.rb +89 -44
- data/app/controllers/devise_token_auth/passwords_controller.rb +55 -31
- data/app/controllers/devise_token_auth/registrations_controller.rb +33 -40
- data/app/controllers/devise_token_auth/sessions_controller.rb +36 -14
- data/app/controllers/devise_token_auth/unlocks_controller.rb +12 -7
- data/app/models/devise_token_auth/concerns/active_record_support.rb +14 -0
- data/app/models/devise_token_auth/concerns/confirmable_support.rb +28 -0
- data/app/models/devise_token_auth/concerns/mongoid_support.rb +19 -0
- data/app/models/devise_token_auth/concerns/tokens_serialization.rb +31 -0
- data/app/models/devise_token_auth/concerns/user.rb +79 -80
- data/app/models/devise_token_auth/concerns/user_omniauth_callbacks.rb +12 -5
- data/app/validators/{email_validator.rb → devise_token_auth_email_validator.rb} +11 -3
- data/app/views/devise_token_auth/omniauth_external_window.html.erb +1 -1
- data/config/locales/da-DK.yml +2 -0
- data/config/locales/de.yml +2 -0
- data/config/locales/en.yml +10 -0
- data/config/locales/es.yml +2 -0
- data/config/locales/fr.yml +2 -0
- data/config/locales/he.yml +52 -0
- data/config/locales/it.yml +2 -0
- data/config/locales/ja.yml +16 -2
- data/config/locales/ko.yml +51 -0
- data/config/locales/nl.yml +2 -0
- data/config/locales/pl.yml +6 -3
- data/config/locales/pt-BR.yml +2 -0
- data/config/locales/pt.yml +6 -3
- data/config/locales/ro.yml +2 -0
- data/config/locales/ru.yml +2 -0
- data/config/locales/sq.yml +2 -0
- data/config/locales/sv.yml +2 -0
- data/config/locales/uk.yml +2 -0
- data/config/locales/vi.yml +2 -0
- data/config/locales/zh-CN.yml +2 -0
- data/config/locales/zh-HK.yml +2 -0
- data/config/locales/zh-TW.yml +2 -0
- data/lib/devise_token_auth/blacklist.rb +6 -0
- data/lib/devise_token_auth/controllers/helpers.rb +5 -9
- data/lib/devise_token_auth/engine.rb +17 -2
- data/lib/devise_token_auth/rails/routes.rb +22 -16
- data/lib/devise_token_auth/token_factory.rb +126 -0
- data/lib/devise_token_auth/url.rb +3 -0
- data/lib/devise_token_auth/version.rb +1 -1
- data/lib/devise_token_auth.rb +6 -3
- data/lib/generators/devise_token_auth/USAGE +1 -1
- data/lib/generators/devise_token_auth/install_generator.rb +7 -91
- data/lib/generators/devise_token_auth/install_generator_helpers.rb +98 -0
- data/lib/generators/devise_token_auth/install_mongoid_generator.rb +46 -0
- data/lib/generators/devise_token_auth/templates/devise_token_auth.rb +21 -5
- data/lib/generators/devise_token_auth/templates/devise_token_auth_create_users.rb.erb +1 -8
- data/lib/generators/devise_token_auth/templates/user.rb.erb +2 -2
- data/lib/generators/devise_token_auth/templates/user_mongoid.rb.erb +56 -0
- data/test/controllers/custom/custom_confirmations_controller_test.rb +2 -2
- data/test/controllers/custom/custom_omniauth_callbacks_controller_test.rb +1 -1
- data/test/controllers/demo_mang_controller_test.rb +37 -8
- data/test/controllers/demo_user_controller_test.rb +39 -10
- data/test/controllers/devise_token_auth/confirmations_controller_test.rb +170 -22
- data/test/controllers/devise_token_auth/omniauth_callbacks_controller_test.rb +117 -53
- data/test/controllers/devise_token_auth/passwords_controller_test.rb +299 -122
- data/test/controllers/devise_token_auth/registrations_controller_test.rb +56 -16
- data/test/controllers/devise_token_auth/sessions_controller_test.rb +139 -75
- data/test/controllers/devise_token_auth/token_validations_controller_test.rb +43 -2
- data/test/controllers/devise_token_auth/unlocks_controller_test.rb +44 -5
- data/test/controllers/overrides/confirmations_controller_test.rb +1 -1
- data/test/controllers/overrides/omniauth_callbacks_controller_test.rb +1 -1
- data/test/dummy/app/active_record/confirmable_user.rb +11 -0
- data/test/dummy/app/{models → active_record}/scoped_user.rb +2 -2
- data/test/dummy/app/{models → active_record}/unconfirmable_user.rb +1 -2
- data/test/dummy/app/{models → active_record}/unregisterable_user.rb +3 -3
- data/test/dummy/app/active_record/user.rb +6 -0
- data/test/dummy/app/controllers/application_controller.rb +2 -6
- data/test/dummy/app/controllers/overrides/confirmations_controller.rb +5 -4
- data/test/dummy/app/controllers/overrides/passwords_controller.rb +5 -4
- data/test/dummy/app/controllers/overrides/registrations_controller.rb +1 -1
- data/test/dummy/app/controllers/overrides/sessions_controller.rb +2 -2
- data/test/dummy/app/models/{user.rb → concerns/favorite_color.rb} +7 -8
- data/test/dummy/app/mongoid/confirmable_user.rb +52 -0
- data/test/dummy/app/mongoid/lockable_user.rb +38 -0
- data/test/dummy/app/mongoid/mang.rb +46 -0
- data/test/dummy/app/mongoid/only_email_user.rb +33 -0
- data/test/dummy/app/mongoid/scoped_user.rb +50 -0
- data/test/dummy/app/mongoid/unconfirmable_user.rb +44 -0
- data/test/dummy/app/mongoid/unregisterable_user.rb +47 -0
- data/test/dummy/app/mongoid/user.rb +49 -0
- data/test/dummy/app/views/layouts/application.html.erb +0 -2
- data/test/dummy/config/application.rb +22 -1
- data/test/dummy/config/boot.rb +4 -0
- data/test/dummy/config/environments/development.rb +0 -10
- data/test/dummy/config/environments/production.rb +0 -16
- data/test/dummy/config/environments/test.rb +6 -2
- data/test/dummy/config/initializers/devise.rb +285 -0
- data/test/dummy/config/initializers/devise_token_auth.rb +35 -4
- data/test/dummy/config/initializers/figaro.rb +1 -1
- data/test/dummy/config/initializers/omniauth.rb +1 -0
- data/test/dummy/config/routes.rb +2 -0
- data/test/dummy/db/migrate/20140715061447_devise_token_auth_create_users.rb +0 -7
- data/test/dummy/db/migrate/20140715061805_devise_token_auth_create_mangs.rb +0 -7
- data/test/dummy/db/migrate/20141222035835_devise_token_auth_create_only_email_users.rb +0 -7
- data/test/dummy/db/migrate/20141222053502_devise_token_auth_create_unregisterable_users.rb +0 -7
- data/test/dummy/db/migrate/20150708104536_devise_token_auth_create_unconfirmable_users.rb +0 -7
- data/test/dummy/db/migrate/20160103235141_devise_token_auth_create_scoped_users.rb +0 -7
- data/test/dummy/db/migrate/20160629184441_devise_token_auth_create_lockable_users.rb +0 -7
- data/test/dummy/db/migrate/20190924101113_devise_token_auth_create_confirmable_users.rb +49 -0
- data/test/dummy/db/schema.rb +31 -33
- data/test/dummy/tmp/generators/app/models/user.rb +9 -0
- data/test/dummy/tmp/generators/config/initializers/devise_token_auth.rb +66 -0
- data/test/dummy/tmp/generators/db/migrate/20230415183419_devise_token_auth_create_users.rb +49 -0
- data/test/factories/users.rb +3 -2
- data/test/lib/devise_token_auth/blacklist_test.rb +19 -0
- data/test/lib/devise_token_auth/rails/custom_routes_test.rb +29 -0
- data/test/lib/devise_token_auth/rails/routes_test.rb +87 -0
- data/test/lib/devise_token_auth/token_factory_test.rb +191 -0
- data/test/lib/devise_token_auth/url_test.rb +2 -2
- data/test/lib/generators/devise_token_auth/install_generator_test.rb +51 -31
- data/test/lib/generators/devise_token_auth/install_generator_with_namespace_test.rb +51 -31
- data/test/models/concerns/mongoid_support_test.rb +31 -0
- data/test/models/concerns/tokens_serialization_test.rb +104 -0
- data/test/models/confirmable_user_test.rb +35 -0
- data/test/models/only_email_user_test.rb +0 -8
- data/test/models/user_test.rb +13 -23
- data/test/test_helper.rb +45 -4
- metadata +190 -97
- data/config/initializers/devise.rb +0 -198
- data/test/dummy/config/initializers/assets.rb +0 -10
- data/test/dummy/tmp/generators/app/views/devise/mailer/confirmation_instructions.html.erb +0 -5
- data/test/dummy/tmp/generators/app/views/devise/mailer/reset_password_instructions.html.erb +0 -8
- /data/test/dummy/app/{models → active_record}/lockable_user.rb +0 -0
- /data/test/dummy/app/{models → active_record}/mang.rb +0 -0
- /data/test/dummy/app/{models → active_record}/only_email_user.rb +0 -0
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
|
-
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
2
|
+
SHA256:
|
|
3
|
+
metadata.gz: 135b5088d17b20d187a6ffe314356dd2a2474d9bd98898bc9e36bc931e6c9fef
|
|
4
|
+
data.tar.gz: cf3c3c6fc19564248bdcb22e3b99624bd25a027383649a45c7e7bf1fddfd5bbd
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 5f6e88376261bcea31e98d8af66cc298755d2cbc2724c481a100d78273824b1dcfcc016bbc2af2b43d1dcac945fc6a4015d351f321da9a432ec4c5129f8c58f0
|
|
7
|
+
data.tar.gz: bde72417d1882c6f69076d3bfe8cebd077e39a681898fb0c5603643770a3d81eb0ac3d42dd46f8ae27aff4dae74a138159160974c1996ef4e28d252baf6b52ba
|
data/README.md
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
# Devise Token Auth
|
|
2
2
|
|
|
3
3
|
[](http://badge.fury.io/rb/devise_token_auth)
|
|
4
|
-
[](https://github.com/lynndylanhurley/devise_token_auth/actions/workflows/test.yml)
|
|
5
5
|
[](https://codeclimate.com/github/lynndylanhurley/devise_token_auth)
|
|
6
6
|
[](https://codeclimate.com/github/lynndylanhurley/devise_token_auth/coverage)
|
|
7
7
|
[](https://rubygems.org/gems/devise_token_auth)
|
|
@@ -19,9 +19,10 @@ Also, it maintains a session for each client/device, so you can have as many ses
|
|
|
19
19
|
|
|
20
20
|
* Seamless integration with:
|
|
21
21
|
* [ng-token-auth](https://github.com/lynndylanhurley/ng-token-auth) for [AngularJS](https://github.com/angular/angular.js)
|
|
22
|
-
* [
|
|
22
|
+
* [Angular-Token](https://github.com/neroniaky/angular-token) for [Angular](https://github.com/angular/angular)
|
|
23
23
|
* [redux-token-auth](https://github.com/kylecorbelli/redux-token-auth) for [React with Redux](https://github.com/reactjs/react-redux)
|
|
24
24
|
* [jToker](https://github.com/lynndylanhurley/j-toker) for [jQuery](https://jquery.com/)
|
|
25
|
+
* [vanilla-token-auth](https://github.com/theblang/vanilla-token-auth) for an unopinionated client
|
|
25
26
|
* Oauth2 authentication using [OmniAuth](https://github.com/intridea/omniauth).
|
|
26
27
|
* Email authentication using [Devise](https://github.com/plataformatec/devise), including:
|
|
27
28
|
* User registration, update and deletion
|
|
@@ -65,11 +66,13 @@ Please read the [issue template](https://github.com/lynndylanhurley/devise_token
|
|
|
65
66
|
|
|
66
67
|
See our [Contribution Guidelines](https://github.com/lynndylanhurley/devise_token_auth/blob/master/.github/CONTRIBUTING.md). Feel free to submit pull requests, review pull requests, or review open issues. If you'd like to get in contact, [Zach Feldman](https://github.com/zachfeldman) has been wrangling this effort, you can reach him with his name @gmail. Further discussion of this in [this issue](https://github.com/lynndylanhurley/devise_token_auth/issues/969).
|
|
67
68
|
|
|
69
|
+
We have some bounties for some issues, [check them out](https://github.com/lynndylanhurley/devise_token_auth/issues?q=is%3Aopen+is%3Aissue+label%3Abounty)!
|
|
70
|
+
|
|
68
71
|
## Live Demos
|
|
69
72
|
|
|
70
73
|
[Here is a demo](http://ng-token-auth-demo.herokuapp.com/) of this app running with the [ng-token-auth](https://github.com/lynndylanhurley/ng-token-auth) module and [AngularJS](https://github.com/angular/angular.js).
|
|
71
74
|
|
|
72
|
-
[Here is a demo](https://
|
|
75
|
+
[Here is a demo](https://stackblitz.com/github/neroniaky/angular-token) of this app running with the [Angular-Token](https://github.com/neroniaky/angular-token) service and [Angular](https://github.com/angular/angular).
|
|
73
76
|
|
|
74
77
|
[Here is a demo](https://j-toker-demo.herokuapp.com/) of this app using the [jToker](https://github.com/lynndylanhurley/j-toker) plugin and [React](http://facebook.github.io/react/).
|
|
75
78
|
|
|
@@ -3,7 +3,6 @@
|
|
|
3
3
|
module DeviseTokenAuth
|
|
4
4
|
class ApplicationController < DeviseController
|
|
5
5
|
include DeviseTokenAuth::Concerns::SetUserByToken
|
|
6
|
-
include DeviseTokenAuth::Concerns::ResourceFinder
|
|
7
6
|
|
|
8
7
|
def resource_data(opts = {})
|
|
9
8
|
response_data = opts[:resource_json] || @resource.as_json
|
|
@@ -17,8 +16,8 @@ module DeviseTokenAuth
|
|
|
17
16
|
|
|
18
17
|
protected
|
|
19
18
|
|
|
20
|
-
def blacklisted_redirect_url?
|
|
21
|
-
DeviseTokenAuth.redirect_whitelist && !DeviseTokenAuth::Url.whitelisted?(
|
|
19
|
+
def blacklisted_redirect_url?(redirect_url)
|
|
20
|
+
DeviseTokenAuth.redirect_whitelist && !DeviseTokenAuth::Url.whitelisted?(redirect_url)
|
|
22
21
|
end
|
|
23
22
|
|
|
24
23
|
def build_redirect_headers(access_token, client, redirect_header_options = {})
|
|
@@ -76,5 +75,26 @@ module DeviseTokenAuth
|
|
|
76
75
|
response = response.merge(data) if data
|
|
77
76
|
render json: response, status: status
|
|
78
77
|
end
|
|
78
|
+
|
|
79
|
+
def success_message(name, email)
|
|
80
|
+
if Devise.paranoid
|
|
81
|
+
I18n.t("devise_token_auth.#{name}.sended_paranoid")
|
|
82
|
+
else
|
|
83
|
+
I18n.t("devise_token_auth.#{name}.sended", email: email)
|
|
84
|
+
end
|
|
85
|
+
end
|
|
86
|
+
|
|
87
|
+
def redirect_options
|
|
88
|
+
{}
|
|
89
|
+
end
|
|
90
|
+
|
|
91
|
+
# When using a cookie to transport the auth token we can set it immediately in flows such as
|
|
92
|
+
# reset password and OmniAuth success, rather than making the client scrape the token from
|
|
93
|
+
# query params (to then send in the initial validate_token request).
|
|
94
|
+
# TODO: We should be able to stop exposing the token in query params when this method is used
|
|
95
|
+
def set_token_in_cookie(resource, token)
|
|
96
|
+
auth_header = resource.build_auth_headers(token.token, token.client)
|
|
97
|
+
cookies[DeviseTokenAuth.cookie_name] = DeviseTokenAuth.cookie_attributes.merge(value: auth_header.to_json)
|
|
98
|
+
end
|
|
79
99
|
end
|
|
80
100
|
end
|
|
@@ -20,21 +20,34 @@ module DeviseTokenAuth::Concerns::ResourceFinder
|
|
|
20
20
|
end
|
|
21
21
|
|
|
22
22
|
def find_resource(field, value)
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
23
|
+
@resource = if database_adapter&.include?('mysql')
|
|
24
|
+
# fix for mysql default case insensitivity
|
|
25
|
+
field_sanitized = resource_class.connection.quote_column_name(field)
|
|
26
|
+
resource_class.where("BINARY #{field_sanitized} = ? AND provider= ?", value, provider).first
|
|
27
|
+
else
|
|
28
|
+
resource_class.dta_find_by(field => value, 'provider' => provider)
|
|
29
|
+
end
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
def database_adapter
|
|
33
|
+
@database_adapter ||= begin
|
|
34
|
+
rails_version = [Rails::VERSION::MAJOR, Rails::VERSION::MINOR].join(".")
|
|
28
35
|
|
|
29
|
-
|
|
36
|
+
adapter =
|
|
37
|
+
if rails_version >= "6.1"
|
|
38
|
+
resource_class.try(:connection_db_config)&.try(:adapter)
|
|
39
|
+
else
|
|
40
|
+
resource_class.try(:connection_config)&.try(:[], :adapter)
|
|
41
|
+
end
|
|
42
|
+
end
|
|
30
43
|
end
|
|
31
44
|
|
|
32
45
|
def resource_class(m = nil)
|
|
33
|
-
if m
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
46
|
+
mapping = if m
|
|
47
|
+
Devise.mappings[m]
|
|
48
|
+
else
|
|
49
|
+
Devise.mappings[resource_name] || Devise.mappings.values.first
|
|
50
|
+
end
|
|
38
51
|
|
|
39
52
|
mapping.to
|
|
40
53
|
end
|
|
@@ -17,24 +17,11 @@ module DeviseTokenAuth::Concerns::SetUserByToken
|
|
|
17
17
|
@used_auth_by_token = true
|
|
18
18
|
|
|
19
19
|
# initialize instance variables
|
|
20
|
-
@
|
|
20
|
+
@token ||= DeviseTokenAuth::TokenFactory.new
|
|
21
21
|
@resource ||= nil
|
|
22
|
-
@token ||= nil
|
|
23
22
|
@is_batch_request ||= nil
|
|
24
23
|
end
|
|
25
24
|
|
|
26
|
-
def ensure_pristine_resource
|
|
27
|
-
if @resource.changed?
|
|
28
|
-
# Stash pending changes in the resource before reloading.
|
|
29
|
-
changes = @resource.changes
|
|
30
|
-
@resource.reload
|
|
31
|
-
end
|
|
32
|
-
yield
|
|
33
|
-
ensure
|
|
34
|
-
# Reapply pending changes
|
|
35
|
-
@resource.assign_attributes(changes) if changes
|
|
36
|
-
end
|
|
37
|
-
|
|
38
25
|
# user auth
|
|
39
26
|
def set_user_by_token(mapping = nil)
|
|
40
27
|
# determine target authentication class
|
|
@@ -45,21 +32,37 @@ module DeviseTokenAuth::Concerns::SetUserByToken
|
|
|
45
32
|
|
|
46
33
|
# gets the headers names, which was set in the initialize file
|
|
47
34
|
uid_name = DeviseTokenAuth.headers_names[:'uid']
|
|
35
|
+
other_uid_name = DeviseTokenAuth.other_uid && DeviseTokenAuth.headers_names[DeviseTokenAuth.other_uid.to_sym]
|
|
48
36
|
access_token_name = DeviseTokenAuth.headers_names[:'access-token']
|
|
49
37
|
client_name = DeviseTokenAuth.headers_names[:'client']
|
|
38
|
+
authorization_name = DeviseTokenAuth.headers_names[:"authorization"]
|
|
39
|
+
|
|
40
|
+
# Read Authorization token and decode it if present
|
|
41
|
+
decoded_authorization_token = decode_bearer_token(request.headers[authorization_name])
|
|
42
|
+
|
|
43
|
+
# gets values from cookie if configured and present
|
|
44
|
+
parsed_auth_cookie = {}
|
|
45
|
+
if DeviseTokenAuth.cookie_enabled
|
|
46
|
+
auth_cookie = request.cookies[DeviseTokenAuth.cookie_name]
|
|
47
|
+
if auth_cookie.present?
|
|
48
|
+
parsed_auth_cookie = JSON.parse(auth_cookie)
|
|
49
|
+
end
|
|
50
|
+
end
|
|
50
51
|
|
|
51
52
|
# parse header for values necessary for authentication
|
|
52
|
-
uid
|
|
53
|
-
|
|
54
|
-
@
|
|
53
|
+
uid = request.headers[uid_name] || params[uid_name] || parsed_auth_cookie[uid_name] || decoded_authorization_token[uid_name]
|
|
54
|
+
other_uid = other_uid_name && request.headers[other_uid_name] || params[other_uid_name] || parsed_auth_cookie[other_uid_name]
|
|
55
|
+
@token = DeviseTokenAuth::TokenFactory.new unless @token
|
|
56
|
+
@token.token ||= request.headers[access_token_name] || params[access_token_name] || parsed_auth_cookie[access_token_name] || decoded_authorization_token[access_token_name]
|
|
57
|
+
@token.client ||= request.headers[client_name] || params[client_name] || parsed_auth_cookie[client_name] || decoded_authorization_token[client_name]
|
|
55
58
|
|
|
56
|
-
#
|
|
57
|
-
@
|
|
59
|
+
# client isn't required, set to 'default' if absent
|
|
60
|
+
@token.client ||= 'default'
|
|
58
61
|
|
|
59
62
|
# check for an existing user, authenticated via warden/devise, if enabled
|
|
60
63
|
if DeviseTokenAuth.enable_standard_devise_support
|
|
61
|
-
devise_warden_user = warden.user(
|
|
62
|
-
if devise_warden_user && devise_warden_user.tokens[@
|
|
64
|
+
devise_warden_user = warden.user(mapping)
|
|
65
|
+
if devise_warden_user && devise_warden_user.tokens[@token.client].nil?
|
|
63
66
|
@used_auth_by_token = false
|
|
64
67
|
@resource = devise_warden_user
|
|
65
68
|
# REVIEW: The following line _should_ be safe to remove;
|
|
@@ -71,53 +74,55 @@ module DeviseTokenAuth::Concerns::SetUserByToken
|
|
|
71
74
|
# user has already been found and authenticated
|
|
72
75
|
return @resource if @resource && @resource.is_a?(rc)
|
|
73
76
|
|
|
74
|
-
# ensure we clear the
|
|
75
|
-
unless @token
|
|
76
|
-
@
|
|
77
|
+
# ensure we clear the client
|
|
78
|
+
unless @token.present?
|
|
79
|
+
@token.client = nil
|
|
77
80
|
return
|
|
78
81
|
end
|
|
79
82
|
|
|
80
|
-
return false unless @token
|
|
81
|
-
|
|
82
83
|
# mitigate timing attacks by finding by uid instead of auth token
|
|
83
|
-
user = uid && rc.
|
|
84
|
+
user = (uid && rc.dta_find_by(uid: uid)) || (other_uid && rc.dta_find_by("#{DeviseTokenAuth.other_uid}": other_uid))
|
|
85
|
+
scope = rc.to_s.underscore.to_sym
|
|
84
86
|
|
|
85
|
-
if user && user.valid_token?(@token, @
|
|
87
|
+
if user && user.valid_token?(@token.token, @token.client)
|
|
86
88
|
# sign_in with bypass: true will be deprecated in the next version of Devise
|
|
87
89
|
if respond_to?(:bypass_sign_in) && DeviseTokenAuth.bypass_sign_in
|
|
88
|
-
bypass_sign_in(user, scope:
|
|
90
|
+
bypass_sign_in(user, scope: scope)
|
|
89
91
|
else
|
|
90
|
-
sign_in(
|
|
92
|
+
sign_in(scope, user, store: false, event: :fetch, bypass: DeviseTokenAuth.bypass_sign_in)
|
|
91
93
|
end
|
|
92
94
|
return @resource = user
|
|
93
95
|
else
|
|
94
96
|
# zero all values previously set values
|
|
95
|
-
@
|
|
97
|
+
@token.client = nil
|
|
96
98
|
return @resource = nil
|
|
97
99
|
end
|
|
98
100
|
end
|
|
99
101
|
|
|
100
102
|
def update_auth_header
|
|
101
103
|
# cannot save object if model has invalid params
|
|
104
|
+
return unless @resource && @token.client
|
|
102
105
|
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
# Generate new client_id with existing authentication
|
|
106
|
-
@client_id = nil unless @used_auth_by_token
|
|
106
|
+
# Generate new client with existing authentication
|
|
107
|
+
@token.client = nil unless @used_auth_by_token
|
|
107
108
|
|
|
108
109
|
if @used_auth_by_token && !DeviseTokenAuth.change_headers_on_each_request
|
|
109
110
|
# should not append auth header if @resource related token was
|
|
110
111
|
# cleared by sign out in the meantime
|
|
111
|
-
return if @resource.reload.tokens[@
|
|
112
|
+
return if @resource.reload.tokens[@token.client].nil?
|
|
112
113
|
|
|
113
|
-
auth_header = @resource.
|
|
114
|
+
auth_header = @resource.build_auth_headers(@token.token, @token.client)
|
|
114
115
|
|
|
115
116
|
# update the response header
|
|
116
117
|
response.headers.merge!(auth_header)
|
|
117
118
|
|
|
119
|
+
# set a server cookie if configured
|
|
120
|
+
if DeviseTokenAuth.cookie_enabled
|
|
121
|
+
set_cookie(auth_header)
|
|
122
|
+
end
|
|
118
123
|
else
|
|
119
124
|
unless @resource.reload.valid?
|
|
120
|
-
@resource =
|
|
125
|
+
@resource = @resource.class.find(@resource.to_param) # errors remain after reload
|
|
121
126
|
# if we left the model in a bad state, something is wrong in our app
|
|
122
127
|
unless @resource.valid?
|
|
123
128
|
raise DeviseTokenAuth::Errors::InvalidModel, "Cannot set auth token in invalid model. Errors: #{@resource.errors.full_messages}"
|
|
@@ -129,38 +134,54 @@ module DeviseTokenAuth::Concerns::SetUserByToken
|
|
|
129
134
|
|
|
130
135
|
private
|
|
131
136
|
|
|
137
|
+
def decode_bearer_token(bearer_token)
|
|
138
|
+
return {} if bearer_token.blank?
|
|
139
|
+
|
|
140
|
+
encoded_token = bearer_token.split.last # Removes the 'Bearer' from the string
|
|
141
|
+
JSON.parse(Base64.strict_decode64(encoded_token)) rescue {}
|
|
142
|
+
end
|
|
143
|
+
|
|
132
144
|
def refresh_headers
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
@resource
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
+
# Lock the user record during any auth_header updates to ensure
|
|
146
|
+
# we don't have write contention from multiple threads
|
|
147
|
+
@resource.with_lock do
|
|
148
|
+
# should not append auth header if @resource related token was
|
|
149
|
+
# cleared by sign out in the meantime
|
|
150
|
+
return if @used_auth_by_token && @resource.tokens[@token.client].nil?
|
|
151
|
+
|
|
152
|
+
_auth_header_from_batch_request = auth_header_from_batch_request
|
|
153
|
+
|
|
154
|
+
# update the response header
|
|
155
|
+
response.headers.merge!(_auth_header_from_batch_request)
|
|
156
|
+
|
|
157
|
+
# set a server cookie if configured and is not a batch request
|
|
158
|
+
if DeviseTokenAuth.cookie_enabled && !@is_batch_request
|
|
159
|
+
set_cookie(_auth_header_from_batch_request)
|
|
160
|
+
end
|
|
161
|
+
end # end lock
|
|
162
|
+
end
|
|
163
|
+
|
|
164
|
+
def set_cookie(auth_header)
|
|
165
|
+
cookies[DeviseTokenAuth.cookie_name] = DeviseTokenAuth.cookie_attributes.merge(value: auth_header.to_json)
|
|
145
166
|
end
|
|
146
167
|
|
|
147
|
-
def is_batch_request?(user,
|
|
168
|
+
def is_batch_request?(user, client)
|
|
148
169
|
!params[:unbatch] &&
|
|
149
|
-
user.tokens[
|
|
150
|
-
user.tokens[
|
|
151
|
-
|
|
170
|
+
user.tokens[client] &&
|
|
171
|
+
user.tokens[client]['updated_at'] &&
|
|
172
|
+
user.tokens[client]['updated_at'].to_time > @request_started_at - DeviseTokenAuth.batch_request_buffer_throttle
|
|
152
173
|
end
|
|
153
174
|
|
|
154
175
|
def auth_header_from_batch_request
|
|
155
176
|
# determine batch request status after request processing, in case
|
|
156
177
|
# another processes has updated it during that processing
|
|
157
|
-
@is_batch_request = is_batch_request?(@resource, @
|
|
178
|
+
@is_batch_request = is_batch_request?(@resource, @token.client)
|
|
158
179
|
|
|
159
180
|
auth_header = {}
|
|
160
181
|
# extend expiration of batch buffer to account for the duration of
|
|
161
182
|
# this request
|
|
162
183
|
if @is_batch_request
|
|
163
|
-
auth_header = @resource.extend_batch_buffer(@token, @
|
|
184
|
+
auth_header = @resource.extend_batch_buffer(@token.token, @token.client)
|
|
164
185
|
|
|
165
186
|
# Do not return token for batch requests to avoid invalidated
|
|
166
187
|
# tokens returned to the client in case of race conditions.
|
|
@@ -171,7 +192,7 @@ module DeviseTokenAuth::Concerns::SetUserByToken
|
|
|
171
192
|
auth_header[DeviseTokenAuth.headers_names[:"expiry"]] = ' '
|
|
172
193
|
else
|
|
173
194
|
# update Authorization response header with new token
|
|
174
|
-
auth_header = @resource.create_new_auth_token(@
|
|
195
|
+
auth_header = @resource.create_new_auth_token(@token.client)
|
|
175
196
|
end
|
|
176
197
|
auth_header
|
|
177
198
|
end
|
|
@@ -2,38 +2,88 @@
|
|
|
2
2
|
|
|
3
3
|
module DeviseTokenAuth
|
|
4
4
|
class ConfirmationsController < DeviseTokenAuth::ApplicationController
|
|
5
|
+
|
|
5
6
|
def show
|
|
6
|
-
@resource = resource_class.confirm_by_token(
|
|
7
|
+
@resource = resource_class.confirm_by_token(resource_params[:confirmation_token])
|
|
8
|
+
|
|
9
|
+
if @resource.errors.empty?
|
|
10
|
+
yield @resource if block_given?
|
|
11
|
+
|
|
12
|
+
redirect_header_options = { account_confirmation_success: true }
|
|
13
|
+
|
|
14
|
+
if signed_in?(resource_name)
|
|
15
|
+
token = signed_in_resource.create_token
|
|
16
|
+
signed_in_resource.save!
|
|
7
17
|
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
18
|
+
redirect_headers = build_redirect_headers(token.token,
|
|
19
|
+
token.client,
|
|
20
|
+
redirect_header_options)
|
|
21
|
+
|
|
22
|
+
redirect_to_link = signed_in_resource.build_auth_url(redirect_url, redirect_headers)
|
|
23
|
+
else
|
|
24
|
+
redirect_to_link = DeviseTokenAuth::Url.generate(redirect_url, redirect_header_options)
|
|
12
25
|
end
|
|
13
26
|
|
|
14
|
-
|
|
27
|
+
redirect_to(redirect_to_link, redirect_options)
|
|
28
|
+
else
|
|
29
|
+
if redirect_url
|
|
30
|
+
redirect_to DeviseTokenAuth::Url.generate(redirect_url, account_confirmation_success: false)
|
|
31
|
+
else
|
|
32
|
+
raise ActionController::RoutingError, 'Not Found'
|
|
33
|
+
end
|
|
34
|
+
end
|
|
35
|
+
end
|
|
15
36
|
|
|
16
|
-
|
|
17
|
-
|
|
37
|
+
def create
|
|
38
|
+
return render_create_error_missing_email if resource_params[:email].blank?
|
|
18
39
|
|
|
19
|
-
|
|
40
|
+
@email = get_case_insensitive_field_from_resource_params(:email)
|
|
20
41
|
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
42
|
+
@resource = resource_class.dta_find_by(uid: @email, provider: provider)
|
|
43
|
+
|
|
44
|
+
return render_not_found_error unless @resource
|
|
45
|
+
|
|
46
|
+
@resource.send_confirmation_instructions({
|
|
47
|
+
redirect_url: redirect_url,
|
|
48
|
+
client_config: resource_params[:config_name]
|
|
49
|
+
})
|
|
25
50
|
|
|
26
|
-
|
|
27
|
-
|
|
51
|
+
return render_create_success
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
protected
|
|
28
55
|
|
|
29
|
-
|
|
30
|
-
|
|
56
|
+
def render_create_error_missing_email
|
|
57
|
+
render_error(401, I18n.t('devise_token_auth.confirmations.missing_email'))
|
|
58
|
+
end
|
|
31
59
|
|
|
60
|
+
def render_create_success
|
|
61
|
+
render json: {
|
|
62
|
+
success: true,
|
|
63
|
+
message: success_message('confirmations', @email)
|
|
64
|
+
}
|
|
65
|
+
end
|
|
32
66
|
|
|
33
|
-
|
|
67
|
+
def render_not_found_error
|
|
68
|
+
if Devise.paranoid
|
|
69
|
+
render_create_success
|
|
34
70
|
else
|
|
35
|
-
|
|
71
|
+
render_error(404, I18n.t('devise_token_auth.confirmations.user_not_found', email: @email))
|
|
36
72
|
end
|
|
37
73
|
end
|
|
74
|
+
|
|
75
|
+
private
|
|
76
|
+
|
|
77
|
+
def resource_params
|
|
78
|
+
params.permit(:email, :confirmation_token, :config_name)
|
|
79
|
+
end
|
|
80
|
+
|
|
81
|
+
# give redirect value from params priority or fall back to default value if provided
|
|
82
|
+
def redirect_url
|
|
83
|
+
params.fetch(
|
|
84
|
+
:redirect_url,
|
|
85
|
+
DeviseTokenAuth.default_confirm_success_url
|
|
86
|
+
)
|
|
87
|
+
end
|
|
38
88
|
end
|
|
39
89
|
end
|