devise_jwt_auth 0.1.5 → 0.1.6
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/README.md +1 -1
- data/app/controllers/devise_jwt_auth/application_controller.rb +14 -11
- data/app/controllers/devise_jwt_auth/concerns/resource_finder.rb +2 -6
- data/app/controllers/devise_jwt_auth/concerns/set_user_by_token.rb +17 -19
- data/app/controllers/devise_jwt_auth/confirmations_controller.rb +10 -19
- data/app/controllers/devise_jwt_auth/omniauth_callbacks_controller.rb +32 -33
- data/app/controllers/devise_jwt_auth/passwords_controller.rb +29 -19
- data/app/controllers/devise_jwt_auth/refresh_token_controller.rb +4 -1
- data/app/controllers/devise_jwt_auth/registrations_controller.rb +40 -21
- data/app/controllers/devise_jwt_auth/sessions_controller.rb +18 -12
- data/app/controllers/devise_jwt_auth/unlocks_controller.rb +5 -4
- data/app/models/devise_jwt_auth/concerns/active_record_support.rb +3 -0
- data/app/models/devise_jwt_auth/concerns/confirmable_support.rb +7 -4
- data/app/models/devise_jwt_auth/concerns/mongoid_support.rb +3 -0
- data/app/models/devise_jwt_auth/concerns/tokens_serialization.rb +4 -1
- data/app/models/devise_jwt_auth/concerns/user.rb +18 -9
- data/app/models/devise_jwt_auth/concerns/user_omniauth_callbacks.rb +11 -3
- data/app/validators/devise_jwt_auth_email_validator.rb +4 -3
- data/lib/devise_jwt_auth/blacklist.rb +2 -0
- data/lib/devise_jwt_auth/controllers/url_helpers.rb +1 -2
- data/lib/devise_jwt_auth/engine.rb +4 -4
- data/lib/devise_jwt_auth/rails/routes.rb +35 -24
- data/lib/devise_jwt_auth/token_factory.rb +3 -2
- data/lib/devise_jwt_auth/url.rb +2 -4
- data/lib/devise_jwt_auth/version.rb +1 -1
- data/lib/generators/devise_jwt_auth/install_generator.rb +7 -6
- data/lib/generators/devise_jwt_auth/install_generator_helpers.rb +14 -7
- data/lib/generators/devise_jwt_auth/install_mongoid_generator.rb +3 -2
- data/lib/generators/devise_jwt_auth/templates/devise_jwt_auth.rb +2 -3
- data/test/controllers/custom/custom_confirmations_controller_test.rb +2 -2
- data/test/controllers/custom/custom_passwords_controller_test.rb +4 -4
- data/test/controllers/custom/custom_refresh_token_controller_test.rb +2 -3
- data/test/controllers/custom/custom_registrations_controller_test.rb +2 -2
- data/test/controllers/demo_mang_controller_test.rb +206 -210
- data/test/controllers/demo_user_controller_test.rb +358 -374
- data/test/controllers/devise_jwt_auth/confirmations_controller_test.rb +5 -5
- data/test/controllers/devise_jwt_auth/omniauth_callbacks_controller_test.rb +6 -7
- data/test/controllers/devise_jwt_auth/passwords_controller_test.rb +11 -13
- data/test/controllers/devise_jwt_auth/refresh_token_controller_test.rb +8 -12
- data/test/controllers/devise_jwt_auth/registrations_controller_test.rb +23 -25
- data/test/controllers/devise_jwt_auth/sessions_controller_test.rb +30 -32
- data/test/controllers/devise_jwt_auth/unlocks_controller_test.rb +2 -2
- data/test/controllers/overrides/confirmations_controller_test.rb +1 -1
- data/test/controllers/overrides/passwords_controller_test.rb +1 -1
- data/test/controllers/overrides/refresh_token_controller_test.rb +1 -2
- data/test/controllers/overrides/registrations_controller_test.rb +1 -1
- data/test/dummy/app/controllers/custom/refresh_token_controller.rb +2 -1
- data/test/dummy/app/controllers/custom/registrations_controller.rb +1 -1
- data/test/dummy/app/controllers/overrides/confirmations_controller.rb +4 -4
- data/test/dummy/app/controllers/overrides/omniauth_callbacks_controller.rb +4 -4
- data/test/dummy/app/controllers/overrides/passwords_controller.rb +4 -4
- data/test/dummy/app/controllers/overrides/refresh_token_controller.rb +1 -1
- data/test/dummy/app/controllers/overrides/registrations_controller.rb +2 -2
- data/test/dummy/app/controllers/overrides/sessions_controller.rb +2 -2
- data/test/dummy/app/models/concerns/favorite_color.rb +11 -9
- data/test/dummy/config.ru +2 -2
- data/test/dummy/config/application.rb +1 -0
- data/test/dummy/config/boot.rb +1 -1
- data/test/dummy/config/environments/test.rb +11 -7
- data/test/dummy/config/initializers/figaro.rb +1 -1
- data/test/dummy/config/initializers/omniauth.rb +2 -2
- data/test/dummy/config/routes.rb +8 -8
- data/test/dummy/db/migrate/20141222035835_devise_jwt_auth_create_only_email_users.rb +9 -9
- data/test/dummy/db/migrate/20190924101113_devise_jwt_auth_create_confirmable_users.rb +6 -5
- data/test/dummy/db/schema.rb +170 -170
- data/test/dummy/tmp/generators/app/controllers/application_controller.rb +6 -0
- data/test/dummy/tmp/generators/config/initializers/devise_jwt_auth.rb +2 -3
- data/test/dummy/tmp/generators/db/migrate/{20200228012905_devise_jwt_auth_create_users.rb → 20201006030349_devise_jwt_auth_create_users.rb} +0 -0
- data/test/factories/users.rb +5 -3
- data/test/lib/devise_jwt_auth/token_factory_test.rb +6 -6
- data/test/lib/generators/devise_jwt_auth/install_generator_test.rb +3 -20
- data/test/lib/generators/devise_jwt_auth/install_generator_with_namespace_test.rb +4 -21
- data/test/models/concerns/tokens_serialization_test.rb +68 -68
- data/test/models/user_test.rb +35 -37
- data/test/support/controllers/routes.rb +7 -5
- data/test/test_helper.rb +1 -1
- metadata +50 -54
- data/test/dummy/tmp/generators/app/models/mang.rb +0 -9
- data/test/dummy/tmp/generators/config/routes.rb +0 -9
- data/test/dummy/tmp/generators/db/migrate/20200228012905_devise_jwt_auth_create_mangs.rb +0 -54
    
        checksums.yaml
    CHANGED
    
    | @@ -1,7 +1,7 @@ | |
| 1 1 | 
             
            ---
         | 
| 2 2 | 
             
            SHA256:
         | 
| 3 | 
            -
              metadata.gz:  | 
| 4 | 
            -
              data.tar.gz:  | 
| 3 | 
            +
              metadata.gz: 9c1a405bebeaa7813dc0b99465db4530d29bf458fe392dd968f11b8abc5b11ab
         | 
| 4 | 
            +
              data.tar.gz: d1c81c134b4031df4ef862041a4dfc4a0bc021f2cd538c020c23aaccc485e298
         | 
| 5 5 | 
             
            SHA512:
         | 
| 6 | 
            -
              metadata.gz:  | 
| 7 | 
            -
              data.tar.gz:  | 
| 6 | 
            +
              metadata.gz: 06141ad295c58d63e8f4e87bc26be3af1b223b52ac2a865329c0ea438bfb7409e7e0466ad2fb1a70b156ba773346dca676d04b6f3fe00e1297b900a3cc482bdd
         | 
| 7 | 
            +
              data.tar.gz: b7de2ecb350212b5fc8e91b0066bd5cb5050ca1e5c1c344a116b8d2ce77273b5f8066dc654a26ab0412bb4d8e5b679f4852a16c022cee60a04b0408e2f0a1a12
         | 
    
        data/README.md
    CHANGED
    
    | @@ -57,7 +57,7 @@ See our [Contribution Guidelines](https://github.com/aarona/devise_jwt_auth/blob | |
| 57 57 |  | 
| 58 58 | 
             
            ## Live Demos
         | 
| 59 59 |  | 
| 60 | 
            -
            Live demos will hopefully be added in the future.  | 
| 60 | 
            +
            Live demos will hopefully be added in the future. Currently, I have a [repository](https://github.com/aarona/dja_example) available that is a proof of concept for DJA that uses React as the client. However, the example application only supports sigining up, sigining in and singing out. It doesn't provide a way to reset a user's password for example and other things that DJA supports. Those will be added in the near future.
         | 
| 61 61 |  | 
| 62 62 | 
             
            ## License
         | 
| 63 63 |  | 
| @@ -20,17 +20,17 @@ module DeviseJwtAuth | |
| 20 20 | 
             
                  DeviseJwtAuth.redirect_whitelist && !DeviseJwtAuth::Url.whitelisted?(redirect_url)
         | 
| 21 21 | 
             
                end
         | 
| 22 22 |  | 
| 23 | 
            -
                def build_redirect_headers(access_token,  | 
| 23 | 
            +
                def build_redirect_headers(access_token, _client, redirect_header_options = {})
         | 
| 24 24 | 
             
                  {
         | 
| 25 25 | 
             
                    # DeviseJwtAuth.headers_names[:"access-token"] => access_token,
         | 
| 26 26 | 
             
                    # DeviseJwtAuth.headers_names[:"client"] => client,
         | 
| 27 | 
            -
                    : | 
| 27 | 
            +
                    config: params[:config],
         | 
| 28 28 |  | 
| 29 29 | 
             
                    # Legacy parameters which may be removed in a future release.
         | 
| 30 30 | 
             
                    # Consider using "client" and "access-token" in client code.
         | 
| 31 31 | 
             
                    # See: github.com/lynndylanhurley/devise_jwt_auth/issues/993
         | 
| 32 32 | 
             
                    # :client_id => client,
         | 
| 33 | 
            -
                    : | 
| 33 | 
            +
                    token: access_token
         | 
| 34 34 | 
             
                  }.merge(redirect_header_options)
         | 
| 35 35 | 
             
                end
         | 
| 36 36 |  | 
| @@ -42,20 +42,23 @@ module DeviseJwtAuth | |
| 42 42 | 
             
                end
         | 
| 43 43 |  | 
| 44 44 | 
             
                def resource_class(m = nil)
         | 
| 45 | 
            -
                  if m
         | 
| 46 | 
            -
             | 
| 47 | 
            -
             | 
| 48 | 
            -
             | 
| 49 | 
            -
             | 
| 45 | 
            +
                  mapping = if m
         | 
| 46 | 
            +
                              Devise.mappings[m]
         | 
| 47 | 
            +
                            else
         | 
| 48 | 
            +
                              Devise.mappings[resource_name] || Devise.mappings.values.first
         | 
| 49 | 
            +
                            end
         | 
| 50 50 |  | 
| 51 51 | 
             
                  mapping.to
         | 
| 52 52 | 
             
                end
         | 
| 53 53 |  | 
| 54 54 | 
             
                def json_api?
         | 
| 55 55 | 
             
                  return false unless defined?(ActiveModel::Serializer)
         | 
| 56 | 
            -
             | 
| 57 | 
            -
             | 
| 58 | 
            -
             | 
| 56 | 
            +
             | 
| 57 | 
            +
                  if ActiveModel::Serializer.respond_to?(:setup)
         | 
| 58 | 
            +
                    return ActiveModel::Serializer.setup do |config|
         | 
| 59 | 
            +
                      config.adapter == :json_api
         | 
| 60 | 
            +
                    end
         | 
| 61 | 
            +
                  end
         | 
| 59 62 | 
             
                  ActiveModelSerializers.config.adapter == :json_api
         | 
| 60 63 | 
             
                end
         | 
| 61 64 |  | 
| @@ -8,13 +8,9 @@ module DeviseJwtAuth::Concerns::ResourceFinder | |
| 8 8 | 
             
                # honor Devise configuration for case_insensitive keys
         | 
| 9 9 | 
             
                q_value = resource_params[field.to_sym]
         | 
| 10 10 |  | 
| 11 | 
            -
                if resource_class.case_insensitive_keys.include?(field.to_sym)
         | 
| 12 | 
            -
                  q_value.downcase!
         | 
| 13 | 
            -
                end
         | 
| 11 | 
            +
                q_value.downcase! if resource_class.case_insensitive_keys.include?(field.to_sym)
         | 
| 14 12 |  | 
| 15 | 
            -
                if resource_class.strip_whitespace_keys.include?(field.to_sym)
         | 
| 16 | 
            -
                  q_value.strip!
         | 
| 17 | 
            -
                end
         | 
| 13 | 
            +
                q_value.strip! if resource_class.strip_whitespace_keys.include?(field.to_sym)
         | 
| 18 14 |  | 
| 19 15 | 
             
                q_value
         | 
| 20 16 | 
             
              end
         | 
| @@ -5,7 +5,6 @@ module DeviseJwtAuth::Concerns::SetUserByToken | |
| 5 5 | 
             
              include DeviseJwtAuth::Concerns::ResourceFinder
         | 
| 6 6 |  | 
| 7 7 | 
             
              included do
         | 
| 8 | 
            -
             | 
| 9 8 | 
             
              end
         | 
| 10 9 |  | 
| 11 10 | 
             
              protected
         | 
| @@ -22,10 +21,10 @@ module DeviseJwtAuth::Concerns::SetUserByToken | |
| 22 21 | 
             
                  devise_warden_user = warden.user(rc.to_s.underscore.to_sym)
         | 
| 23 22 | 
             
                  @resource = devise_warden_user if devise_warden_user
         | 
| 24 23 | 
             
                end
         | 
| 25 | 
            -
             | 
| 24 | 
            +
             | 
| 26 25 | 
             
                # user has already been found and authenticated
         | 
| 27 | 
            -
                return @resource if @resource | 
| 28 | 
            -
             | 
| 26 | 
            +
                return @resource if @resource&.is_a?(rc)
         | 
| 27 | 
            +
             | 
| 29 28 | 
             
                # TODO: Look for the access token in an 'Authentication' header
         | 
| 30 29 | 
             
                token = request.headers[DeviseJwtAuth.access_token_name]
         | 
| 31 30 | 
             
                return unless token
         | 
| @@ -33,8 +32,9 @@ module DeviseJwtAuth::Concerns::SetUserByToken | |
| 33 32 | 
             
                payload = DeviseJwtAuth::TokenFactory.decode_access_token(token)
         | 
| 34 33 | 
             
                return if payload.empty?
         | 
| 35 34 | 
             
                return if payload && payload['sub'].blank?
         | 
| 35 | 
            +
             | 
| 36 36 | 
             
                uid = payload['sub']
         | 
| 37 | 
            -
             | 
| 37 | 
            +
             | 
| 38 38 | 
             
                # mitigate timing attacks by finding by uid instead of auth token
         | 
| 39 39 | 
             
                user = uid && rc.dta_find_by(uid: uid)
         | 
| 40 40 | 
             
                scope = rc.to_s.underscore.to_sym
         | 
| @@ -46,10 +46,10 @@ module DeviseJwtAuth::Concerns::SetUserByToken | |
| 46 46 | 
             
                  else
         | 
| 47 47 | 
             
                    sign_in(scope, user, store: false, event: :fetch, bypass: DeviseJwtAuth.bypass_sign_in)
         | 
| 48 48 | 
             
                  end
         | 
| 49 | 
            -
                   | 
| 49 | 
            +
                  @resource = user
         | 
| 50 50 | 
             
                else
         | 
| 51 51 | 
             
                  # zero all values previously set values
         | 
| 52 | 
            -
                   | 
| 52 | 
            +
                  @resource = nil
         | 
| 53 53 | 
             
                end
         | 
| 54 54 | 
             
              end
         | 
| 55 55 |  | 
| @@ -65,10 +65,10 @@ module DeviseJwtAuth::Concerns::SetUserByToken | |
| 65 65 | 
             
                  devise_warden_user = warden.user(rc.to_s.underscore.to_sym)
         | 
| 66 66 | 
             
                  @resource = devise_warden_user if devise_warden_user
         | 
| 67 67 | 
             
                end
         | 
| 68 | 
            -
             | 
| 68 | 
            +
             | 
| 69 69 | 
             
                # user has already been found and authenticated
         | 
| 70 | 
            -
                return @resource if @resource | 
| 71 | 
            -
             | 
| 70 | 
            +
                return @resource if @resource&.is_a?(rc)
         | 
| 71 | 
            +
             | 
| 72 72 | 
             
                token = request.cookies[DeviseJwtAuth.refresh_token_name]
         | 
| 73 73 |  | 
| 74 74 | 
             
                return unless token
         | 
| @@ -76,6 +76,7 @@ module DeviseJwtAuth::Concerns::SetUserByToken | |
| 76 76 | 
             
                payload = DeviseJwtAuth::TokenFactory.decode_refresh_token(token)
         | 
| 77 77 | 
             
                return if payload.empty?
         | 
| 78 78 | 
             
                return if payload && payload['sub'].blank?
         | 
| 79 | 
            +
             | 
| 79 80 | 
             
                uid = payload['sub']
         | 
| 80 81 |  | 
| 81 82 | 
             
                # mitigate timing attacks by finding by uid instead of auth token
         | 
| @@ -89,13 +90,12 @@ module DeviseJwtAuth::Concerns::SetUserByToken | |
| 89 90 | 
             
                  else
         | 
| 90 91 | 
             
                    sign_in(scope, user, store: false, event: :fetch, bypass: DeviseJwtAuth.bypass_sign_in)
         | 
| 91 92 | 
             
                  end
         | 
| 92 | 
            -
                   | 
| 93 | 
            +
                  @resource = user
         | 
| 93 94 | 
             
                else
         | 
| 94 95 | 
             
                  # zero all values previously set values
         | 
| 95 | 
            -
                   | 
| 96 | 
            +
                  @resource = nil
         | 
| 96 97 | 
             
                end
         | 
| 97 98 | 
             
              end
         | 
| 98 | 
            -
              
         | 
| 99 99 |  | 
| 100 100 | 
             
              def update_refresh_token_cookie
         | 
| 101 101 | 
             
                response.set_cookie(DeviseJwtAuth.refresh_token_name,
         | 
| @@ -103,15 +103,13 @@ module DeviseJwtAuth::Concerns::SetUserByToken | |
| 103 103 | 
             
                                    path: '/auth/refresh_token', # TODO: Use configured auth path
         | 
| 104 104 | 
             
                                    expires: Time.zone.now + DeviseJwtAuth.refresh_token_lifespan,
         | 
| 105 105 | 
             
                                    httponly: true,
         | 
| 106 | 
            -
                                    secure: Rails.env.production?
         | 
| 107 | 
            -
                )
         | 
| 106 | 
            +
                                    secure: Rails.env.production?)
         | 
| 108 107 | 
             
              end
         | 
| 109 | 
            -
             | 
| 108 | 
            +
             | 
| 110 109 | 
             
              def clear_refresh_token_cookie
         | 
| 111 110 | 
             
                response.set_cookie(DeviseJwtAuth.refresh_token_name,
         | 
| 112 111 | 
             
                                    value: '',
         | 
| 113 112 | 
             
                                    path: '/auth/refresh_token', # TODO: Use configured auth path
         | 
| 114 | 
            -
                                    expires: Time.zone.now
         | 
| 115 | 
            -
                )
         | 
| 113 | 
            +
                                    expires: Time.zone.now)
         | 
| 116 114 | 
             
              end
         | 
| 117 | 
            -
            end
         | 
| 115 | 
            +
            end
         | 
| @@ -2,7 +2,6 @@ | |
| 2 2 |  | 
| 3 3 | 
             
            module DeviseJwtAuth
         | 
| 4 4 | 
             
              class ConfirmationsController < DeviseJwtAuth::ApplicationController
         | 
| 5 | 
            -
             | 
| 6 5 | 
             
                def show
         | 
| 7 6 | 
             
                  @resource = resource_class.confirm_by_token(resource_params[:confirmation_token])
         | 
| 8 7 |  | 
| @@ -12,19 +11,12 @@ module DeviseJwtAuth | |
| 12 11 | 
             
                    redirect_header_options = { account_confirmation_success: true }
         | 
| 13 12 |  | 
| 14 13 | 
             
                    if signed_in?(resource_name)
         | 
| 15 | 
            -
                       | 
| 16 | 
            -
             | 
| 17 | 
            -
                      # redirect_headers = build_redirect_headers(token.token,
         | 
| 18 | 
            -
                      #                                           token.client,
         | 
| 19 | 
            -
                      #                                           redirect_header_options)
         | 
| 20 | 
            -
                      
         | 
| 21 | 
            -
                      redirect_headers = signed_in_resource.create_named_token_pair.
         | 
| 22 | 
            -
                                         merge(redirect_header_options)
         | 
| 14 | 
            +
                      redirect_headers = signed_in_resource.create_named_token_pair
         | 
| 15 | 
            +
                                           .merge(redirect_header_options)
         | 
| 23 16 |  | 
| 24 | 
            -
                      # TODO: add a refresh token cookie in the response.
         | 
| 25 17 | 
             
                      update_refresh_token_cookie
         | 
| 26 | 
            -
             | 
| 27 | 
            -
                      #redirect_to_link = signed_in_resource.build_auth_url(redirect_url, redirect_headers)
         | 
| 18 | 
            +
             | 
| 19 | 
            +
                      # redirect_to_link = signed_in_resource.build_auth_url(redirect_url, redirect_headers)
         | 
| 28 20 | 
             
                      redirect_to_link = DeviseJwtAuth::Url.generate(redirect_url, redirect_headers)
         | 
| 29 21 | 
             
                    else
         | 
| 30 22 | 
             
                      redirect_to_link = DeviseJwtAuth::Url.generate(redirect_url, redirect_header_options)
         | 
| @@ -46,11 +38,11 @@ module DeviseJwtAuth | |
| 46 38 | 
             
                  return render_not_found_error unless @resource
         | 
| 47 39 |  | 
| 48 40 | 
             
                  @resource.send_confirmation_instructions({
         | 
| 49 | 
            -
             | 
| 50 | 
            -
             | 
| 51 | 
            -
             | 
| 41 | 
            +
                                                             redirect_url: redirect_url,
         | 
| 42 | 
            +
                                                             client_config: resource_params[:config_name]
         | 
| 43 | 
            +
                                                           })
         | 
| 52 44 |  | 
| 53 | 
            -
                   | 
| 45 | 
            +
                  render_create_success
         | 
| 54 46 | 
             
                end
         | 
| 55 47 |  | 
| 56 48 | 
             
                protected
         | 
| @@ -61,8 +53,8 @@ module DeviseJwtAuth | |
| 61 53 |  | 
| 62 54 | 
             
                def render_create_success
         | 
| 63 55 | 
             
                  render json: {
         | 
| 64 | 
            -
             | 
| 65 | 
            -
             | 
| 56 | 
            +
                    success: true,
         | 
| 57 | 
            +
                    message: I18n.t('devise_jwt_auth.confirmations.sended', email: @email)
         | 
| 66 58 | 
             
                  }
         | 
| 67 59 | 
             
                end
         | 
| 68 60 |  | 
| @@ -83,6 +75,5 @@ module DeviseJwtAuth | |
| 83 75 | 
             
                    DeviseJwtAuth.default_confirm_success_url
         | 
| 84 76 | 
             
                  )
         | 
| 85 77 | 
             
                end
         | 
| 86 | 
            -
             | 
| 87 78 | 
             
              end
         | 
| 88 79 | 
             
            end
         | 
| @@ -7,12 +7,10 @@ module DeviseJwtAuth | |
| 7 7 | 
             
                before_action :validate_auth_origin_url_param
         | 
| 8 8 |  | 
| 9 9 | 
             
                skip_before_action :set_user_by_jwt_token, raise: false
         | 
| 10 | 
            -
                # skip_after_action :update_auth_header
         | 
| 11 10 |  | 
| 12 11 | 
             
                # intermediary route for successful omniauth authentication. omniauth does
         | 
| 13 12 | 
             
                # not support multiple models, so we must resort to this terrible hack.
         | 
| 14 13 | 
             
                def redirect_callbacks
         | 
| 15 | 
            -
             | 
| 16 14 | 
             
                  # derive target redirect route from 'resource_class' param, which was set
         | 
| 17 15 | 
             
                  # before authentication.
         | 
| 18 16 | 
             
                  devise_mapping = get_devise_mapping
         | 
| @@ -29,15 +27,17 @@ module DeviseJwtAuth | |
| 29 27 | 
             
                def get_redirect_route(devise_mapping)
         | 
| 30 28 | 
             
                  path = "#{Devise.mappings[devise_mapping.to_sym].fullpath}/#{params[:provider]}/callback"
         | 
| 31 29 | 
             
                  klass = request.scheme == 'https' ? URI::HTTPS : URI::HTTP
         | 
| 32 | 
            -
                   | 
| 30 | 
            +
                  klass.build(host: request.host, port: request.port, path: path).to_s
         | 
| 33 31 | 
             
                end
         | 
| 34 32 |  | 
| 35 33 | 
             
                def get_devise_mapping
         | 
| 36 | 
            -
             | 
| 37 | 
            -
             | 
| 38 | 
            -
             | 
| 39 | 
            -
             | 
| 40 | 
            -
             | 
| 34 | 
            +
                  # derive target redirect route from 'resource_class' param, which was set
         | 
| 35 | 
            +
                  # before authentication.
         | 
| 36 | 
            +
                  [
         | 
| 37 | 
            +
                    request.env['omniauth.params']['namespace_name'],
         | 
| 38 | 
            +
                    request.env['omniauth.params']['resource_class'].underscore.gsub('/', '_')
         | 
| 39 | 
            +
                  ].compact.join('_')
         | 
| 40 | 
            +
                rescue NoMethodError
         | 
| 41 41 | 
             
                  default_devise_mapping
         | 
| 42 42 | 
             
                end
         | 
| 43 43 |  | 
| @@ -45,13 +45,13 @@ module DeviseJwtAuth | |
| 45 45 | 
             
                # find the mapping in `omniauth.params`.
         | 
| 46 46 | 
             
                #
         | 
| 47 47 | 
             
                # One example use-case here is for IDP-initiated SAML login.  In that
         | 
| 48 | 
            -
                # case, there will have been no initial request in which to save | 
| 48 | 
            +
                # case, there will have been no initial request in which to save
         | 
| 49 49 | 
             
                # the devise mapping.  If you are in a situation like that, and
         | 
| 50 50 | 
             
                # your app allows for you to determine somehow what the devise
         | 
| 51 51 | 
             
                # mapping should be (because, for example, it is always the same),
         | 
| 52 52 | 
             
                # then you can handle it by overriding this method.
         | 
| 53 53 | 
             
                def default_devise_mapping
         | 
| 54 | 
            -
                  raise NotImplementedError | 
| 54 | 
            +
                  raise NotImplementedError, 'no default_devise_mapping set'
         | 
| 55 55 | 
             
                end
         | 
| 56 56 |  | 
| 57 57 | 
             
                def omniauth_success
         | 
| @@ -78,10 +78,11 @@ module DeviseJwtAuth | |
| 78 78 | 
             
                  render_data_or_redirect('authFailure', error: @error)
         | 
| 79 79 | 
             
                end
         | 
| 80 80 |  | 
| 81 | 
            -
                def validate_auth_origin_url_param | 
| 82 | 
            -
                  return  | 
| 81 | 
            +
                def validate_auth_origin_url_param
         | 
| 82 | 
            +
                  return unless auth_origin_url && blacklisted_redirect_url?(auth_origin_url)
         | 
| 83 | 
            +
             | 
| 84 | 
            +
                  render_error_not_allowed_auth_origin_url
         | 
| 83 85 | 
             
                end
         | 
| 84 | 
            -
              
         | 
| 85 86 |  | 
| 86 87 | 
             
                protected
         | 
| 87 88 |  | 
| @@ -95,19 +96,19 @@ module DeviseJwtAuth | |
| 95 96 | 
             
                # are added as query params in our monkey patch to OmniAuth in engine.rb
         | 
| 96 97 | 
             
                def omniauth_params
         | 
| 97 98 | 
             
                  unless defined?(@_omniauth_params)
         | 
| 98 | 
            -
                    if request.env['omniauth.params'] | 
| 99 | 
            +
                    if request.env['omniauth.params']&.any?
         | 
| 99 100 | 
             
                      @_omniauth_params = request.env['omniauth.params']
         | 
| 100 | 
            -
                    elsif session['dta.omniauth.params'] | 
| 101 | 
            +
                    elsif session['dta.omniauth.params']&.any?
         | 
| 101 102 | 
             
                      @_omniauth_params ||= session.delete('dta.omniauth.params')
         | 
| 102 103 | 
             
                      @_omniauth_params
         | 
| 103 104 | 
             
                    elsif params['omniauth_window_type']
         | 
| 104 | 
            -
                      @_omniauth_params = | 
| 105 | 
            +
                      @_omniauth_params =
         | 
| 106 | 
            +
                        params.slice('omniauth_window_type', 'auth_origin_url', 'resource_class', 'origin')
         | 
| 105 107 | 
             
                    else
         | 
| 106 108 | 
             
                      @_omniauth_params = {}
         | 
| 107 109 | 
             
                    end
         | 
| 108 110 | 
             
                  end
         | 
| 109 111 | 
             
                  @_omniauth_params
         | 
| 110 | 
            -
             | 
| 111 112 | 
             
                end
         | 
| 112 113 |  | 
| 113 114 | 
             
                # break out provider attribute assignment for easy method extension
         | 
| @@ -120,14 +121,13 @@ module DeviseJwtAuth | |
| 120 121 | 
             
                def whitelisted_params
         | 
| 121 122 | 
             
                  whitelist = params_for_resource(:sign_up)
         | 
| 122 123 |  | 
| 123 | 
            -
                  whitelist. | 
| 124 | 
            +
                  whitelist.each_with_object({}) do |key, coll|
         | 
| 124 125 | 
             
                    param = omniauth_params[key.to_s]
         | 
| 125 126 | 
             
                    coll[key] = param if param
         | 
| 126 | 
            -
                    coll
         | 
| 127 127 | 
             
                  end
         | 
| 128 128 | 
             
                end
         | 
| 129 129 |  | 
| 130 | 
            -
                def resource_class( | 
| 130 | 
            +
                def resource_class(_mapping = nil)
         | 
| 131 131 | 
             
                  if omniauth_params['resource_class']
         | 
| 132 132 | 
             
                    omniauth_params['resource_class'].constantize
         | 
| 133 133 | 
             
                  elsif params['resource_class']
         | 
| @@ -149,18 +149,18 @@ module DeviseJwtAuth | |
| 149 149 | 
             
                  omniauth_params['auth_origin_url'] || omniauth_params['origin']
         | 
| 150 150 | 
             
                end
         | 
| 151 151 |  | 
| 152 | 
            -
             | 
| 153 152 | 
             
                def auth_origin_url
         | 
| 154 | 
            -
                  if unsafe_auth_origin_url && blacklisted_redirect_url?(unsafe_auth_origin_url)
         | 
| 155 | 
            -
             | 
| 156 | 
            -
                   | 
| 157 | 
            -
                  return unsafe_auth_origin_url
         | 
| 153 | 
            +
                  return nil if unsafe_auth_origin_url && blacklisted_redirect_url?(unsafe_auth_origin_url)
         | 
| 154 | 
            +
             | 
| 155 | 
            +
                  unsafe_auth_origin_url
         | 
| 158 156 | 
             
                end
         | 
| 159 157 |  | 
| 160 158 | 
             
                # in the success case, omniauth_window_type is in the omniauth_params.
         | 
| 161 159 | 
             
                # in the failure case, it is in a query param.  See monkey patch above
         | 
| 162 160 | 
             
                def omniauth_window_type
         | 
| 163 | 
            -
                   | 
| 161 | 
            +
                  return params['omniauth_window_type'] if omniauth_params.nil?
         | 
| 162 | 
            +
             | 
| 163 | 
            +
                  omniauth_params['omniauth_window_type']
         | 
| 164 164 | 
             
                end
         | 
| 165 165 |  | 
| 166 166 | 
             
                # this sesison value is set by the redirect_callbacks method. its purpose
         | 
| @@ -208,7 +208,10 @@ module DeviseJwtAuth | |
| 208 208 | 
             
                end
         | 
| 209 209 |  | 
| 210 210 | 
             
                def render_error_not_allowed_auth_origin_url
         | 
| 211 | 
            -
                  message = | 
| 211 | 
            +
                  message =
         | 
| 212 | 
            +
                    I18n.t('devise_jwt_auth.omniauth.not_allowed_redirect_url',
         | 
| 213 | 
            +
                           redirect_url: unsafe_auth_origin_url)
         | 
| 214 | 
            +
             | 
| 212 215 | 
             
                  render_data_or_redirect('authFailure', error: message)
         | 
| 213 216 | 
             
                end
         | 
| 214 217 |  | 
| @@ -218,7 +221,6 @@ module DeviseJwtAuth | |
| 218 221 | 
             
                end
         | 
| 219 222 |  | 
| 220 223 | 
             
                def render_data_or_redirect(message, data, user_data = {})
         | 
| 221 | 
            -
             | 
| 222 224 | 
             
                  # We handle inAppBrowser and newWindow the same, but it is nice
         | 
| 223 225 | 
             
                  # to support values in case people need custom implementations for each case
         | 
| 224 226 | 
             
                  # (For example, nbrustein does not allow new users to be created if logging in with
         | 
| @@ -245,7 +247,7 @@ module DeviseJwtAuth | |
| 245 247 | 
             
                end
         | 
| 246 248 |  | 
| 247 249 | 
             
                def fallback_render(text)
         | 
| 248 | 
            -
             | 
| 250 | 
            +
                  render inline: %(
         | 
| 249 251 |  | 
| 250 252 | 
             
                        <html>
         | 
| 251 253 | 
             
                                <head></head>
         | 
| @@ -271,9 +273,7 @@ module DeviseJwtAuth | |
| 271 273 | 
             
                    provider: auth_hash['provider']
         | 
| 272 274 | 
             
                  ).first_or_initialize
         | 
| 273 275 |  | 
| 274 | 
            -
                  if @resource.new_record?
         | 
| 275 | 
            -
                    handle_new_resource
         | 
| 276 | 
            -
                  end
         | 
| 276 | 
            +
                  handle_new_resource if @resource.new_record?
         | 
| 277 277 |  | 
| 278 278 | 
             
                  # sync user info with provider, update/generate auth token
         | 
| 279 279 | 
             
                  assign_provider_attrs(@resource, auth_hash)
         | 
| @@ -287,5 +287,4 @@ module DeviseJwtAuth | |
| 287 287 | 
             
                  @resource
         | 
| 288 288 | 
             
                end
         | 
| 289 289 | 
             
              end
         | 
| 290 | 
            -
             | 
| 291 290 | 
             
            end
         | 
| @@ -3,7 +3,6 @@ | |
| 3 3 | 
             
            module DeviseJwtAuth
         | 
| 4 4 | 
             
              class PasswordsController < DeviseJwtAuth::ApplicationController
         | 
| 5 5 | 
             
                before_action :validate_redirect_url_param, only: [:create, :edit]
         | 
| 6 | 
            -
                # skip_after_action :update_auth_header, only: [:create, :edit]
         | 
| 7 6 |  | 
| 8 7 | 
             
                # this action is responsible for generating password reset tokens and sending emails
         | 
| 9 8 | 
             
                def create
         | 
| @@ -22,7 +21,7 @@ module DeviseJwtAuth | |
| 22 21 | 
             
                    )
         | 
| 23 22 |  | 
| 24 23 | 
             
                    if @resource.errors.empty?
         | 
| 25 | 
            -
                       | 
| 24 | 
            +
                      render_create_success
         | 
| 26 25 | 
             
                    else
         | 
| 27 26 | 
             
                      render_create_error @resource.errors
         | 
| 28 27 | 
             
                    end
         | 
| @@ -36,12 +35,13 @@ module DeviseJwtAuth | |
| 36 35 | 
             
                  # if a user is not found, return nil
         | 
| 37 36 | 
             
                  @resource = resource_class.with_reset_password_token(resource_params[:reset_password_token])
         | 
| 38 37 |  | 
| 39 | 
            -
                  if @resource | 
| 38 | 
            +
                  if @resource&.reset_password_period_valid?
         | 
| 40 39 | 
             
                    # TODO: add a token invalidator
         | 
| 41 40 | 
             
                    # token = @resource.create_token unless require_client_password_reset_token?
         | 
| 42 41 |  | 
| 43 42 | 
             
                    # ensure that user is confirmed
         | 
| 44 43 | 
             
                    @resource.skip_confirmation! if confirmable_enabled? && !@resource.confirmed_at
         | 
| 44 | 
            +
             | 
| 45 45 | 
             
                    # allow user to change password once without current_password
         | 
| 46 46 | 
             
                    @resource.allow_password_change = true if recoverable_enabled?
         | 
| 47 47 | 
             
                    @resource.save!
         | 
| @@ -49,16 +49,19 @@ module DeviseJwtAuth | |
| 49 49 | 
             
                    yield @resource if block_given?
         | 
| 50 50 |  | 
| 51 51 | 
             
                    if require_client_password_reset_token?
         | 
| 52 | 
            -
                      redirect_to DeviseJwtAuth::Url.generate( | 
| 52 | 
            +
                      redirect_to DeviseJwtAuth::Url.generate(
         | 
| 53 | 
            +
                        @redirect_url,
         | 
| 54 | 
            +
                        reset_password_token: resource_params[:reset_password_token]
         | 
| 55 | 
            +
                      )
         | 
| 53 56 | 
             
                    else
         | 
| 54 57 | 
             
                      redirect_header_options = { reset_password: true }
         | 
| 55 | 
            -
                      redirect_headers = @resource.create_named_token_pair | 
| 56 | 
            -
             | 
| 58 | 
            +
                      redirect_headers = @resource.create_named_token_pair
         | 
| 59 | 
            +
                                           .merge(redirect_header_options)
         | 
| 57 60 |  | 
| 58 61 | 
             
                      # TODO: do we put the refresh token here?
         | 
| 59 62 | 
             
                      # we do if token exists (see line 41)
         | 
| 60 63 | 
             
                      update_refresh_token_cookie
         | 
| 61 | 
            -
             | 
| 64 | 
            +
             | 
| 62 65 | 
             
                      redirect_to_link = DeviseJwtAuth::Url.generate(@redirect_url, redirect_headers)
         | 
| 63 66 |  | 
| 64 67 | 
             
                      redirect_to redirect_to_link
         | 
| @@ -82,9 +85,7 @@ module DeviseJwtAuth | |
| 82 85 | 
             
                  return render_update_error_unauthorized unless @resource
         | 
| 83 86 |  | 
| 84 87 | 
             
                  # make sure account doesn't use oauth2 provider
         | 
| 85 | 
            -
                  unless @resource.provider == 'email'
         | 
| 86 | 
            -
                    return render_update_error_password_not_required
         | 
| 87 | 
            -
                  end
         | 
| 88 | 
            +
                  return render_update_error_password_not_required unless @resource.provider == 'email'
         | 
| 88 89 |  | 
| 89 90 | 
             
                  # ensure that password params were sent
         | 
| 90 91 | 
             
                  unless password_resource_params[:password] && password_resource_params[:password_confirmation]
         | 
| @@ -100,16 +101,20 @@ module DeviseJwtAuth | |
| 100 101 | 
             
                    # send refresh cookie
         | 
| 101 102 | 
             
                    # send access token
         | 
| 102 103 | 
             
                    update_refresh_token_cookie
         | 
| 103 | 
            -
                     | 
| 104 | 
            +
                    render_update_success
         | 
| 104 105 | 
             
                  else
         | 
| 105 | 
            -
                     | 
| 106 | 
            +
                    render_update_error
         | 
| 106 107 | 
             
                  end
         | 
| 107 108 | 
             
                end
         | 
| 108 109 |  | 
| 109 110 | 
             
                protected
         | 
| 110 111 |  | 
| 111 112 | 
             
                def resource_update_method
         | 
| 112 | 
            -
                  allow_password_change = | 
| 113 | 
            +
                  allow_password_change =
         | 
| 114 | 
            +
                    recoverable_enabled? &&
         | 
| 115 | 
            +
                    @resource.allow_password_change == true ||
         | 
| 116 | 
            +
                    require_client_password_reset_token?
         | 
| 117 | 
            +
             | 
| 113 118 | 
             
                  if DeviseJwtAuth.check_current_password_before_update == false || allow_password_change
         | 
| 114 119 | 
             
                    'update'
         | 
| 115 120 | 
             
                  else
         | 
| @@ -128,9 +133,10 @@ module DeviseJwtAuth | |
| 128 133 | 
             
                def render_error_not_allowed_redirect_url
         | 
| 129 134 | 
             
                  response = {
         | 
| 130 135 | 
             
                    status: 'error',
         | 
| 131 | 
            -
                    data: | 
| 136 | 
            +
                    data: resource_data
         | 
| 132 137 | 
             
                  }
         | 
| 133 | 
            -
                  message = I18n.t('devise_jwt_auth.passwords.not_allowed_redirect_url', | 
| 138 | 
            +
                  message = I18n.t('devise_jwt_auth.passwords.not_allowed_redirect_url',
         | 
| 139 | 
            +
                                   redirect_url: @redirect_url)
         | 
| 134 140 | 
             
                  render_error(422, message, response)
         | 
| 135 141 | 
             
                end
         | 
| 136 142 |  | 
| @@ -157,7 +163,8 @@ module DeviseJwtAuth | |
| 157 163 | 
             
                end
         | 
| 158 164 |  | 
| 159 165 | 
             
                def render_update_error_password_not_required
         | 
| 160 | 
            -
                  render_error(422, I18n.t('devise_jwt_auth.passwords.password_not_required', | 
| 166 | 
            +
                  render_error(422, I18n.t('devise_jwt_auth.passwords.password_not_required',
         | 
| 167 | 
            +
                                           provider: @resource.provider.humanize))
         | 
| 161 168 | 
             
                end
         | 
| 162 169 |  | 
| 163 170 | 
             
                def render_update_error_missing_password
         | 
| @@ -170,7 +177,7 @@ module DeviseJwtAuth | |
| 170 177 | 
             
                    data: resource_data,
         | 
| 171 178 | 
             
                    message: I18n.t('devise_jwt_auth.passwords.successfully_updated')
         | 
| 172 179 | 
             
                  }.merge!(@resource.create_named_token_pair)
         | 
| 173 | 
            -
             | 
| 180 | 
            +
             | 
| 174 181 | 
             
                  render json: response_body
         | 
| 175 182 | 
             
                end
         | 
| 176 183 |  | 
| @@ -203,11 +210,14 @@ module DeviseJwtAuth | |
| 203 210 | 
             
                  )
         | 
| 204 211 |  | 
| 205 212 | 
             
                  return render_create_error_missing_redirect_url unless @redirect_url
         | 
| 206 | 
            -
             | 
| 213 | 
            +
             | 
| 214 | 
            +
                  render_error_not_allowed_redirect_url if blacklisted_redirect_url?(@redirect_url)
         | 
| 207 215 | 
             
                end
         | 
| 208 216 |  | 
| 209 217 | 
             
                def reset_password_token_as_raw?(recoverable)
         | 
| 210 | 
            -
                  recoverable && | 
| 218 | 
            +
                  recoverable &&
         | 
| 219 | 
            +
                    recoverable.reset_password_token.present? &&
         | 
| 220 | 
            +
                    !require_client_password_reset_token?
         | 
| 211 221 | 
             
                end
         | 
| 212 222 |  | 
| 213 223 | 
             
                def require_client_password_reset_token?
         |