devise_jwt_auth 0.1.0

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.
Files changed (179) hide show
  1. checksums.yaml +7 -0
  2. data/LICENSE +13 -0
  3. data/README.md +99 -0
  4. data/Rakefile +42 -0
  5. data/app/controllers/devise_jwt_auth/application_controller.rb +80 -0
  6. data/app/controllers/devise_jwt_auth/concerns/resource_finder.rb +44 -0
  7. data/app/controllers/devise_jwt_auth/concerns/set_user_by_jwt_token.rb +111 -0
  8. data/app/controllers/devise_jwt_auth/confirmations_controller.rb +88 -0
  9. data/app/controllers/devise_jwt_auth/omniauth_callbacks_controller.rb +291 -0
  10. data/app/controllers/devise_jwt_auth/passwords_controller.rb +217 -0
  11. data/app/controllers/devise_jwt_auth/refresh_token_controller.rb +41 -0
  12. data/app/controllers/devise_jwt_auth/registrations_controller.rb +203 -0
  13. data/app/controllers/devise_jwt_auth/sessions_controller.rb +131 -0
  14. data/app/controllers/devise_jwt_auth/unlocks_controller.rb +99 -0
  15. data/app/models/devise_jwt_auth/concerns/active_record_support.rb +16 -0
  16. data/app/models/devise_jwt_auth/concerns/confirmable_support.rb +27 -0
  17. data/app/models/devise_jwt_auth/concerns/mongoid_support.rb +19 -0
  18. data/app/models/devise_jwt_auth/concerns/tokens_serialization.rb +19 -0
  19. data/app/models/devise_jwt_auth/concerns/user.rb +117 -0
  20. data/app/models/devise_jwt_auth/concerns/user_omniauth_callbacks.rb +28 -0
  21. data/app/validators/devise_jwt_auth_email_validator.rb +23 -0
  22. data/app/views/devise/mailer/confirmation_instructions.html.erb +5 -0
  23. data/app/views/devise/mailer/reset_password_instructions.html.erb +8 -0
  24. data/app/views/devise/mailer/unlock_instructions.html.erb +7 -0
  25. data/app/views/devise_jwt_auth/omniauth_external_window.html.erb +38 -0
  26. data/config/locales/da-DK.yml +52 -0
  27. data/config/locales/de.yml +51 -0
  28. data/config/locales/en.yml +57 -0
  29. data/config/locales/es.yml +51 -0
  30. data/config/locales/fr.yml +51 -0
  31. data/config/locales/he.yml +52 -0
  32. data/config/locales/it.yml +48 -0
  33. data/config/locales/ja.yml +48 -0
  34. data/config/locales/ko.yml +51 -0
  35. data/config/locales/nl.yml +32 -0
  36. data/config/locales/pl.yml +50 -0
  37. data/config/locales/pt-BR.yml +48 -0
  38. data/config/locales/pt.yml +50 -0
  39. data/config/locales/ro.yml +48 -0
  40. data/config/locales/ru.yml +52 -0
  41. data/config/locales/sq.yml +48 -0
  42. data/config/locales/sv.yml +52 -0
  43. data/config/locales/uk.yml +61 -0
  44. data/config/locales/vi.yml +52 -0
  45. data/config/locales/zh-CN.yml +48 -0
  46. data/config/locales/zh-HK.yml +50 -0
  47. data/config/locales/zh-TW.yml +50 -0
  48. data/lib/devise_jwt_auth.rb +14 -0
  49. data/lib/devise_jwt_auth/blacklist.rb +2 -0
  50. data/lib/devise_jwt_auth/controllers/helpers.rb +161 -0
  51. data/lib/devise_jwt_auth/controllers/url_helpers.rb +10 -0
  52. data/lib/devise_jwt_auth/engine.rb +96 -0
  53. data/lib/devise_jwt_auth/errors.rb +8 -0
  54. data/lib/devise_jwt_auth/rails/routes.rb +118 -0
  55. data/lib/devise_jwt_auth/token_factory.rb +51 -0
  56. data/lib/devise_jwt_auth/url.rb +44 -0
  57. data/lib/devise_jwt_auth/version.rb +5 -0
  58. data/lib/generators/devise_jwt_auth/USAGE +31 -0
  59. data/lib/generators/devise_jwt_auth/install_generator.rb +91 -0
  60. data/lib/generators/devise_jwt_auth/install_generator_helpers.rb +98 -0
  61. data/lib/generators/devise_jwt_auth/install_mongoid_generator.rb +46 -0
  62. data/lib/generators/devise_jwt_auth/install_views_generator.rb +18 -0
  63. data/lib/generators/devise_jwt_auth/templates/devise_jwt_auth.rb +74 -0
  64. data/lib/generators/devise_jwt_auth/templates/devise_jwt_auth_create_users.rb.erb +51 -0
  65. data/lib/generators/devise_jwt_auth/templates/user.rb.erb +9 -0
  66. data/lib/generators/devise_jwt_auth/templates/user_mongoid.rb.erb +56 -0
  67. data/lib/tasks/devise_token_auth_tasks.rake +6 -0
  68. data/test/controllers/custom/custom_confirmations_controller_test.rb +25 -0
  69. data/test/controllers/custom/custom_omniauth_callbacks_controller_test.rb +33 -0
  70. data/test/controllers/custom/custom_passwords_controller_test.rb +79 -0
  71. data/test/controllers/custom/custom_refresh_token_controller_test.rb +36 -0
  72. data/test/controllers/custom/custom_registrations_controller_test.rb +59 -0
  73. data/test/controllers/custom/custom_sessions_controller_test.rb +39 -0
  74. data/test/controllers/demo_group_controller_test.rb +150 -0
  75. data/test/controllers/demo_mang_controller_test.rb +286 -0
  76. data/test/controllers/demo_user_controller_test.rb +650 -0
  77. data/test/controllers/devise_jwt_auth/confirmations_controller_test.rb +194 -0
  78. data/test/controllers/devise_jwt_auth/omniauth_callbacks_controller_test.rb +462 -0
  79. data/test/controllers/devise_jwt_auth/passwords_controller_test.rb +881 -0
  80. data/test/controllers/devise_jwt_auth/refresh_token_controller_test.rb +84 -0
  81. data/test/controllers/devise_jwt_auth/registrations_controller_test.rb +944 -0
  82. data/test/controllers/devise_jwt_auth/sessions_controller_test.rb +510 -0
  83. data/test/controllers/devise_jwt_auth/unlocks_controller_test.rb +197 -0
  84. data/test/controllers/overrides/confirmations_controller_test.rb +47 -0
  85. data/test/controllers/overrides/omniauth_callbacks_controller_test.rb +53 -0
  86. data/test/controllers/overrides/passwords_controller_test.rb +65 -0
  87. data/test/controllers/overrides/refresh_token_controller_test.rb +37 -0
  88. data/test/controllers/overrides/registrations_controller_test.rb +47 -0
  89. data/test/controllers/overrides/sessions_controller_test.rb +35 -0
  90. data/test/dummy/README.rdoc +28 -0
  91. data/test/dummy/app/active_record/confirmable_user.rb +11 -0
  92. data/test/dummy/app/active_record/lockable_user.rb +7 -0
  93. data/test/dummy/app/active_record/mang.rb +5 -0
  94. data/test/dummy/app/active_record/only_email_user.rb +7 -0
  95. data/test/dummy/app/active_record/scoped_user.rb +9 -0
  96. data/test/dummy/app/active_record/unconfirmable_user.rb +9 -0
  97. data/test/dummy/app/active_record/unregisterable_user.rb +9 -0
  98. data/test/dummy/app/active_record/user.rb +6 -0
  99. data/test/dummy/app/controllers/application_controller.rb +18 -0
  100. data/test/dummy/app/controllers/auth_origin_controller.rb +7 -0
  101. data/test/dummy/app/controllers/custom/confirmations_controller.rb +13 -0
  102. data/test/dummy/app/controllers/custom/omniauth_callbacks_controller.rb +13 -0
  103. data/test/dummy/app/controllers/custom/passwords_controller.rb +39 -0
  104. data/test/dummy/app/controllers/custom/refresh_token_controller.rb +20 -0
  105. data/test/dummy/app/controllers/custom/registrations_controller.rb +39 -0
  106. data/test/dummy/app/controllers/custom/sessions_controller.rb +29 -0
  107. data/test/dummy/app/controllers/demo_group_controller.rb +15 -0
  108. data/test/dummy/app/controllers/demo_mang_controller.rb +14 -0
  109. data/test/dummy/app/controllers/demo_user_controller.rb +27 -0
  110. data/test/dummy/app/controllers/overrides/confirmations_controller.rb +37 -0
  111. data/test/dummy/app/controllers/overrides/omniauth_callbacks_controller.rb +16 -0
  112. data/test/dummy/app/controllers/overrides/passwords_controller.rb +45 -0
  113. data/test/dummy/app/controllers/overrides/refresh_token_controller.rb +22 -0
  114. data/test/dummy/app/controllers/overrides/registrations_controller.rb +29 -0
  115. data/test/dummy/app/controllers/overrides/sessions_controller.rb +36 -0
  116. data/test/dummy/app/helpers/application_helper.rb +1058 -0
  117. data/test/dummy/app/models/concerns/favorite_color.rb +19 -0
  118. data/test/dummy/app/mongoid/confirmable_user.rb +52 -0
  119. data/test/dummy/app/mongoid/lockable_user.rb +38 -0
  120. data/test/dummy/app/mongoid/mang.rb +46 -0
  121. data/test/dummy/app/mongoid/only_email_user.rb +33 -0
  122. data/test/dummy/app/mongoid/scoped_user.rb +50 -0
  123. data/test/dummy/app/mongoid/unconfirmable_user.rb +44 -0
  124. data/test/dummy/app/mongoid/unregisterable_user.rb +47 -0
  125. data/test/dummy/app/mongoid/user.rb +49 -0
  126. data/test/dummy/app/views/layouts/application.html.erb +14 -0
  127. data/test/dummy/config.ru +18 -0
  128. data/test/dummy/config/application.rb +48 -0
  129. data/test/dummy/config/application.yml.bk +0 -0
  130. data/test/dummy/config/boot.rb +11 -0
  131. data/test/dummy/config/environment.rb +7 -0
  132. data/test/dummy/config/environments/development.rb +46 -0
  133. data/test/dummy/config/environments/production.rb +84 -0
  134. data/test/dummy/config/environments/test.rb +50 -0
  135. data/test/dummy/config/initializers/assets.rb +10 -0
  136. data/test/dummy/config/initializers/backtrace_silencers.rb +9 -0
  137. data/test/dummy/config/initializers/cookies_serializer.rb +5 -0
  138. data/test/dummy/config/initializers/devise.rb +290 -0
  139. data/test/dummy/config/initializers/devise_jwt_auth.rb +55 -0
  140. data/test/dummy/config/initializers/figaro.rb +3 -0
  141. data/test/dummy/config/initializers/filter_parameter_logging.rb +6 -0
  142. data/test/dummy/config/initializers/inflections.rb +18 -0
  143. data/test/dummy/config/initializers/mime_types.rb +6 -0
  144. data/test/dummy/config/initializers/omniauth.rb +11 -0
  145. data/test/dummy/config/initializers/session_store.rb +5 -0
  146. data/test/dummy/config/initializers/wrap_parameters.rb +16 -0
  147. data/test/dummy/config/routes.rb +57 -0
  148. data/test/dummy/config/spring.rb +3 -0
  149. data/test/dummy/db/migrate/20140715061447_devise_token_auth_create_users.rb +58 -0
  150. data/test/dummy/db/migrate/20140715061805_devise_token_auth_create_mangs.rb +57 -0
  151. data/test/dummy/db/migrate/20140829044006_add_operating_thetan_to_user.rb +8 -0
  152. data/test/dummy/db/migrate/20140916224624_add_favorite_color_to_mangs.rb +7 -0
  153. data/test/dummy/db/migrate/20141222035835_devise_token_auth_create_only_email_users.rb +55 -0
  154. data/test/dummy/db/migrate/20141222053502_devise_token_auth_create_unregisterable_users.rb +56 -0
  155. data/test/dummy/db/migrate/20150708104536_devise_token_auth_create_unconfirmable_users.rb +56 -0
  156. data/test/dummy/db/migrate/20160103235141_devise_token_auth_create_scoped_users.rb +56 -0
  157. data/test/dummy/db/migrate/20160629184441_devise_token_auth_create_lockable_users.rb +56 -0
  158. data/test/dummy/db/migrate/20190924101113_devise_token_auth_create_confirmable_users.rb +49 -0
  159. data/test/dummy/db/schema.rb +198 -0
  160. data/test/dummy/lib/migration_database_helper.rb +43 -0
  161. data/test/dummy/tmp/generators/app/models/user.rb +9 -0
  162. data/test/dummy/tmp/generators/config/initializers/devise_jwt_auth.rb +74 -0
  163. data/test/dummy/tmp/generators/config/routes.rb +4 -0
  164. data/test/dummy/tmp/generators/db/migrate/20200206224309_devise_jwt_auth_create_users.rb +51 -0
  165. data/test/factories/users.rb +41 -0
  166. data/test/lib/devise_jwt_auth/blacklist_test.rb +11 -0
  167. data/test/lib/devise_jwt_auth/token_factory_test.rb +115 -0
  168. data/test/lib/devise_jwt_auth/url_test.rb +26 -0
  169. data/test/lib/generators/devise_jwt_auth/install_generator_test.rb +219 -0
  170. data/test/lib/generators/devise_jwt_auth/install_generator_with_namespace_test.rb +224 -0
  171. data/test/lib/generators/devise_jwt_auth/install_views_generator_test.rb +25 -0
  172. data/test/models/concerns/mongoid_support_test.rb +31 -0
  173. data/test/models/concerns/tokens_serialization_test.rb +72 -0
  174. data/test/models/confirmable_user_test.rb +35 -0
  175. data/test/models/only_email_user_test.rb +29 -0
  176. data/test/models/user_test.rb +110 -0
  177. data/test/support/controllers/routes.rb +43 -0
  178. data/test/test_helper.rb +91 -0
  179. metadata +503 -0
@@ -0,0 +1,14 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'devise'
4
+
5
+ module DeviseJwtAuth
6
+ end
7
+
8
+ require 'devise_jwt_auth/engine'
9
+ require 'devise_jwt_auth/controllers/helpers'
10
+ require 'devise_jwt_auth/controllers/url_helpers'
11
+ require 'devise_jwt_auth/url'
12
+ require 'devise_jwt_auth/errors'
13
+ require 'devise_jwt_auth/blacklist'
14
+ require 'devise_jwt_auth/token_factory'
@@ -0,0 +1,2 @@
1
+ # don't serialize tokens
2
+ Devise::Models::Authenticatable::BLACKLIST_FOR_SERIALIZATION << :tokens
@@ -0,0 +1,161 @@
1
+ # frozen_string_literal: true
2
+
3
+ module DeviseJwtAuth
4
+ module Controllers
5
+ module Helpers
6
+ extend ActiveSupport::Concern
7
+
8
+ module ClassMethods
9
+ # Define authentication filters and accessor helpers for a group of mappings.
10
+ # These methods are useful when you are working with multiple mappings that
11
+ # share some functionality. They are pretty much the same as the ones
12
+ # defined for normal mappings.
13
+ #
14
+ # Example:
15
+ #
16
+ # inside BlogsController (or any other controller, it doesn't matter which):
17
+ # devise_group :blogger, contains: [:user, :admin]
18
+ #
19
+ # Generated methods:
20
+ # authenticate_blogger! # Redirects unless user or admin are signed in
21
+ # blogger_signed_in? # Checks whether there is either a user or an admin signed in
22
+ # current_blogger # Currently signed in user or admin
23
+ # current_bloggers # Currently signed in user and admin
24
+ # render_authenticate_error # Render error unless user or admin are signed in
25
+ #
26
+ # Use:
27
+ # before_action :authenticate_blogger! # Redirects unless either a user or an admin are authenticated
28
+ # before_action ->{ authenticate_blogger! :admin } # Redirects to the admin login page
29
+ # current_blogger :user # Preferably returns a User if one is signed in
30
+ #
31
+ def devise_jwt_auth_group(group_name, opts = {})
32
+ mappings = "[#{opts[:contains].map { |m| ":#{m}" }.join(',')}]"
33
+
34
+ class_eval <<-METHODS, __FILE__, __LINE__ + 1
35
+ def authenticate_#{group_name}!(favourite=nil, opts={})
36
+ unless #{group_name}_signed_in?
37
+ mappings = #{mappings}
38
+ mappings.unshift mappings.delete(favourite.to_sym) if favourite
39
+ mappings.each do |mapping|
40
+ set_user_by_token(mapping)
41
+ end
42
+
43
+ unless current_#{group_name}
44
+ render_authenticate_error
45
+ end
46
+ end
47
+ end
48
+
49
+ def #{group_name}_signed_in?
50
+ #{mappings}.any? do |mapping|
51
+ set_user_by_token(mapping)
52
+ end
53
+ end
54
+
55
+ def current_#{group_name}(favourite=nil)
56
+ mappings = #{mappings}
57
+ mappings.unshift mappings.delete(favourite.to_sym) if favourite
58
+ mappings.each do |mapping|
59
+ current = set_user_by_token(mapping)
60
+ return current if current
61
+ end
62
+ nil
63
+ end
64
+
65
+ def current_#{group_name.to_s.pluralize}
66
+ #{mappings}.map do |mapping|
67
+ set_user_by_token(mapping)
68
+ end.compact
69
+ end
70
+
71
+ def render_authenticate_error
72
+ return render json: {
73
+ errors: [I18n.t('devise.failure.unauthenticated')]
74
+ }, status: 401
75
+ end
76
+
77
+ if respond_to?(:helper_method)
78
+ helper_method(
79
+ "current_#{group_name}",
80
+ "current_#{group_name.to_s.pluralize}",
81
+ "#{group_name}_signed_in?",
82
+ "render_authenticate_error"
83
+ )
84
+ end
85
+ METHODS
86
+ end
87
+
88
+ def log_process_action(payload)
89
+ payload[:status] ||= 401 unless payload[:exception]
90
+ super
91
+ end
92
+ end
93
+
94
+ # Define authentication filters and accessor helpers based on mappings.
95
+ # These filters should be used inside the controllers as before_actions,
96
+ # so you can control the scope of the user who should be signed in to
97
+ # access that specific controller/action.
98
+ # Example:
99
+ #
100
+ # Roles:
101
+ # User
102
+ # Admin
103
+ #
104
+ # Generated methods:
105
+ # authenticate_user! # Signs user in or 401
106
+ # authenticate_admin! # Signs admin in or 401
107
+ # user_signed_in? # Checks whether there is a user signed in or not
108
+ # admin_signed_in? # Checks whether there is an admin signed in or not
109
+ # current_user # Current signed in user
110
+ # current_admin # Current signed in admin
111
+ # user_session # Session data available only to the user scope
112
+ # admin_session # Session data available only to the admin scope
113
+ # render_authenticate_error # Render error unless user or admin is signed in
114
+ #
115
+ # Use:
116
+ # before_action :authenticate_user! # Tell devise to use :user map
117
+ # before_action :authenticate_admin! # Tell devise to use :admin map
118
+ #
119
+ def self.define_helpers(mapping) #:nodoc:
120
+ mapping = mapping.name
121
+
122
+ class_eval <<-METHODS, __FILE__, __LINE__ + 1
123
+ def authenticate_#{mapping}!(opts={})
124
+ unless current_#{mapping}
125
+ render_authenticate_error
126
+ end
127
+ end
128
+
129
+ def #{mapping}_signed_in?
130
+ !!current_#{mapping}
131
+ end
132
+
133
+ def current_#{mapping}
134
+ @current_#{mapping} ||= set_user_by_token(:#{mapping})
135
+ end
136
+
137
+ def #{mapping}_session
138
+ current_#{mapping} && warden.session(:#{mapping})
139
+ end
140
+
141
+ def render_authenticate_error
142
+ return render json: {
143
+ errors: [I18n.t('devise.failure.unauthenticated')]
144
+ }, status: 401
145
+ end
146
+ METHODS
147
+
148
+ ActiveSupport.on_load(:action_controller) do
149
+ if respond_to?(:helper_method)
150
+ helper_method(
151
+ "current_#{mapping}",
152
+ "#{mapping}_signed_in?",
153
+ "#{mapping}_session",
154
+ 'render_authenticate_error'
155
+ )
156
+ end
157
+ end
158
+ end
159
+ end
160
+ end
161
+ end
@@ -0,0 +1,10 @@
1
+ # frozen_string_literal: true
2
+
3
+ module DeviseJwtAuth
4
+ module Controllers
5
+ module UrlHelpers
6
+ def self.define_helpers(mapping)
7
+ end
8
+ end
9
+ end
10
+ end
@@ -0,0 +1,96 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'devise_jwt_auth/rails/routes'
4
+
5
+ module DeviseJwtAuth
6
+ class Engine < ::Rails::Engine
7
+ isolate_namespace DeviseJwtAuth
8
+
9
+ initializer 'devise_jwt_auth.url_helpers' do
10
+ Devise.helpers << DeviseJwtAuth::Controllers::Helpers
11
+ end
12
+ end
13
+
14
+ mattr_accessor :send_new_access_token_on_each_request,
15
+ :refresh_token_lifespan,
16
+ :access_token_lifespan,
17
+ :refresh_token_name,
18
+ :access_token_name,
19
+ :refresh_token_encryption_key,
20
+ :access_token_encryption_key,
21
+ :batch_request_buffer_throttle,
22
+ :omniauth_prefix,
23
+ :default_confirm_success_url,
24
+ :default_password_reset_url,
25
+ :redirect_whitelist,
26
+ :check_current_password_before_update,
27
+ :enable_standard_devise_support,
28
+ :update_token_version_after_password_reset,
29
+ :default_callbacks,
30
+ :bypass_sign_in,
31
+ :send_confirmation_email,
32
+ :require_client_password_reset_token
33
+
34
+ self.send_new_access_token_on_each_request = false
35
+ self.refresh_token_lifespan = 1.week
36
+ self.access_token_lifespan = 1.day
37
+ self.refresh_token_name = 'refresh-token'
38
+ self.access_token_name = 'access-token'
39
+ self.refresh_token_encryption_key = 'your-refresh-token-secret-key-here'
40
+ self.access_token_encryption_key = 'your-access-token-secret-key-here'
41
+ self.batch_request_buffer_throttle = 5.seconds
42
+ self.omniauth_prefix = '/omniauth'
43
+ self.default_confirm_success_url = nil
44
+ self.default_password_reset_url = nil
45
+ self.redirect_whitelist = nil
46
+ self.check_current_password_before_update = false
47
+ self.enable_standard_devise_support = false
48
+ self.update_token_version_after_password_reset = true
49
+ self.default_callbacks = true
50
+ self.bypass_sign_in = true
51
+ self.send_confirmation_email = false
52
+ self.require_client_password_reset_token = false
53
+
54
+ def self.setup(&block)
55
+ yield self
56
+
57
+ Rails.application.config.after_initialize do
58
+ if defined?(::OmniAuth)
59
+ ::OmniAuth::config.path_prefix = Devise.omniauth_path_prefix = omniauth_prefix
60
+
61
+ # Omniauth currently does not pass along omniauth.params upon failure redirect
62
+ # see also: https://github.com/intridea/omniauth/issues/626
63
+ OmniAuth::FailureEndpoint.class_eval do
64
+ def redirect_to_failure
65
+ message_key = env['omniauth.error.type']
66
+ origin_query_param = env['omniauth.origin'] ? "&origin=#{CGI.escape(env['omniauth.origin'])}" : ''
67
+ strategy_name_query_param = env['omniauth.error.strategy'] ? "&strategy=#{env['omniauth.error.strategy'].name}" : ''
68
+ extra_params = env['omniauth.params'] ? "&#{env['omniauth.params'].to_query}" : ''
69
+ new_path = "#{env['SCRIPT_NAME']}#{OmniAuth.config.path_prefix}/failure?message=#{message_key}#{origin_query_param}#{strategy_name_query_param}#{extra_params}"
70
+ Rack::Response.new(['302 Moved'], 302, 'Location' => new_path).finish
71
+ end
72
+ end
73
+
74
+ # Omniauth currently removes omniauth.params during mocked requests
75
+ # see also: https://github.com/intridea/omniauth/pull/812
76
+ OmniAuth::Strategy.class_eval do
77
+ def mock_callback_call
78
+ setup_phase
79
+ @env['omniauth.origin'] = session.delete('omniauth.origin')
80
+ @env['omniauth.origin'] = nil if env['omniauth.origin'] == ''
81
+ @env['omniauth.params'] = session.delete('omniauth.params') || {}
82
+ mocked_auth = OmniAuth.mock_auth_for(name.to_s)
83
+ if mocked_auth.is_a?(Symbol)
84
+ fail!(mocked_auth)
85
+ else
86
+ @env['omniauth.auth'] = mocked_auth
87
+ OmniAuth.config.before_callback_phase.call(@env) if OmniAuth.config.before_callback_phase
88
+ call_app!
89
+ end
90
+ end
91
+ end
92
+
93
+ end
94
+ end
95
+ end
96
+ end
@@ -0,0 +1,8 @@
1
+ # frozen_string_literal: true
2
+
3
+ module DeviseJwtAuth
4
+ module Errors
5
+ class NoResourceDefinedError < StandardError; end
6
+ class InvalidModel < StandardError; end
7
+ end
8
+ end
@@ -0,0 +1,118 @@
1
+ # frozen_string_literal: true
2
+
3
+ module ActionDispatch::Routing
4
+ class Mapper
5
+ def mount_devise_jwt_auth_for(resource, opts)
6
+ # ensure objects exist to simplify attr checks
7
+ opts[:controllers] ||= {}
8
+ opts[:skip] ||= []
9
+
10
+ # check for ctrl overrides, fall back to defaults
11
+ sessions_ctrl = opts[:controllers][:sessions] || 'devise_jwt_auth/sessions'
12
+ registrations_ctrl = opts[:controllers][:registrations] || 'devise_jwt_auth/registrations'
13
+ passwords_ctrl = opts[:controllers][:passwords] || 'devise_jwt_auth/passwords'
14
+ confirmations_ctrl = opts[:controllers][:confirmations] || 'devise_jwt_auth/confirmations'
15
+ # token_validations_ctrl = opts[:controllers][:token_validations] || 'devise_jwt_auth/token_validations'
16
+ refresh_token_ctrl = opts[:controllers][:refresh_token] || 'devise_jwt_auth/refresh_token'
17
+ omniauth_ctrl = opts[:controllers][:omniauth_callbacks] || 'devise_jwt_auth/omniauth_callbacks'
18
+ unlocks_ctrl = opts[:controllers][:unlocks] || 'devise_jwt_auth/unlocks'
19
+
20
+ # define devise controller mappings
21
+ controllers = { sessions: sessions_ctrl,
22
+ registrations: registrations_ctrl,
23
+ passwords: passwords_ctrl,
24
+ confirmations: confirmations_ctrl }
25
+
26
+ controllers[:unlocks] = unlocks_ctrl if unlocks_ctrl
27
+
28
+ # remove any unwanted devise modules
29
+ opts[:skip].each{ |item| controllers.delete(item) }
30
+
31
+ devise_for resource.pluralize.underscore.gsub('/', '_').to_sym,
32
+ class_name: resource,
33
+ module: :devise,
34
+ path: opts[:at].to_s,
35
+ controllers: controllers,
36
+ skip: opts[:skip] + [:omniauth_callbacks]
37
+
38
+ unnest_namespace do
39
+ # get full url path as if it were namespaced
40
+ full_path = "#{@scope[:path]}/#{opts[:at]}"
41
+
42
+ # get namespace name
43
+ namespace_name = @scope[:as]
44
+
45
+ # clear scope so controller routes aren't namespaced
46
+ @scope = ActionDispatch::Routing::Mapper::Scope.new(
47
+ path: '',
48
+ shallow_path: '',
49
+ constraints: {},
50
+ defaults: {},
51
+ options: {},
52
+ parent: nil
53
+ )
54
+
55
+ mapping_name = resource.underscore.gsub('/', '_')
56
+ mapping_name = "#{namespace_name}_#{mapping_name}" if namespace_name
57
+
58
+ devise_scope mapping_name.to_sym do
59
+ # path to refresh access tokens
60
+ get "#{full_path}/refresh_token", controller: refresh_token_ctrl.to_s, action: 'show' if !opts[:skip].include?(:refresh_token)
61
+ # get "#{full_path}/validate_token", controller: token_validations_ctrl.to_s, action: 'validate_token' if !opts[:skip].include?(:token_validations)
62
+
63
+ # omniauth routes. only define if omniauth is installed and not skipped.
64
+ if defined?(::OmniAuth) && !opts[:skip].include?(:omniauth_callbacks)
65
+ match "#{full_path}/failure", controller: omniauth_ctrl, action: 'omniauth_failure', via: [:get]
66
+ match "#{full_path}/:provider/callback", controller: omniauth_ctrl, action: 'omniauth_success', via: [:get]
67
+
68
+ match "#{DeviseJwtAuth.omniauth_prefix}/:provider/callback", controller: omniauth_ctrl, action: 'redirect_callbacks', via: [:get, :post]
69
+ match "#{DeviseJwtAuth.omniauth_prefix}/failure", controller: omniauth_ctrl, action: 'omniauth_failure', via: [:get, :post]
70
+
71
+ # preserve the resource class thru oauth authentication by setting name of
72
+ # resource as "resource_class" param
73
+ match "#{full_path}/:provider", to: redirect{ |params, request|
74
+ # get the current querystring
75
+ qs = CGI::parse(request.env['QUERY_STRING'])
76
+
77
+ # append name of current resource
78
+ qs['resource_class'] = [resource]
79
+ qs['namespace_name'] = [namespace_name] if namespace_name
80
+
81
+ set_omniauth_path_prefix!(DeviseJwtAuth.omniauth_prefix)
82
+
83
+ redirect_params = {}.tap { |hash| qs.each{ |k, v| hash[k] = v.first } }
84
+
85
+ if DeviseJwtAuth.redirect_whitelist
86
+ redirect_url = request.params['auth_origin_url']
87
+ unless DeviseJwtAuth::Url.whitelisted?(redirect_url)
88
+ message = I18n.t(
89
+ 'devise_jwt_auth.registrations.redirect_url_not_allowed',
90
+ redirect_url: redirect_url
91
+ )
92
+ redirect_params['message'] = message
93
+ next "#{::OmniAuth.config.path_prefix}/failure?#{redirect_params.to_param}"
94
+ end
95
+ end
96
+
97
+ # re-construct the path for omniauth
98
+ "#{::OmniAuth.config.path_prefix}/#{params[:provider]}?#{redirect_params.to_param}"
99
+ }, via: [:get]
100
+ end
101
+ end
102
+ end
103
+ end
104
+
105
+ # this allows us to use namespaced paths without namespacing the routes
106
+ def unnest_namespace
107
+ current_scope = @scope.dup
108
+ yield
109
+ ensure
110
+ @scope = current_scope
111
+ end
112
+
113
+ # ignore error about omniauth/multiple model support
114
+ def set_omniauth_path_prefix!(path_prefix)
115
+ ::OmniAuth.config.path_prefix = path_prefix
116
+ end
117
+ end
118
+ end
@@ -0,0 +1,51 @@
1
+ require 'jwt'
2
+
3
+ module DeviseJwtAuth
4
+ # A token management factory which allow generate token objects and check them.
5
+ module TokenFactory
6
+
7
+ def self.create_refresh_token(payload)
8
+ if payload[:exp].blank? && payload['exp'].blank?
9
+ payload[:exp] = (Time.zone.now + DeviseJwtAuth.refresh_token_lifespan).to_i
10
+ end
11
+
12
+ JWT.encode payload, DeviseJwtAuth.refresh_token_encryption_key
13
+ end
14
+
15
+ def self.create_access_token(payload)
16
+ if payload[:exp].blank? && payload['exp'].blank?
17
+ payload[:exp] = (Time.zone.now + DeviseJwtAuth.access_token_lifespan).to_i
18
+ end
19
+
20
+ JWT.encode payload, DeviseJwtAuth.access_token_encryption_key
21
+ end
22
+
23
+ def self.decode_refresh_token(token)
24
+ JWT.decode(token, DeviseJwtAuth.refresh_token_encryption_key).first
25
+ rescue JWT::ExpiredSignature
26
+ {}
27
+ rescue JWT::DecodeError
28
+ {}
29
+ rescue JWT::VerificationError
30
+ {}
31
+ rescue NoMethodError
32
+ {}
33
+ rescue TypeError
34
+ {}
35
+ end
36
+
37
+ def self.decode_access_token(token)
38
+ JWT.decode(token, DeviseJwtAuth.access_token_encryption_key).first
39
+ rescue JWT::ExpiredSignature
40
+ {}
41
+ rescue JWT::DecodeError
42
+ {}
43
+ rescue JWT::VerificationError
44
+ {}
45
+ rescue NoMethodError
46
+ {}
47
+ rescue TypeError
48
+ {}
49
+ end
50
+ end
51
+ end