new_google_recaptcha_turbo 1.2.1
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 +7 -0
 - data/MIT-LICENSE +20 -0
 - data/README.md +237 -0
 - data/Rakefile +27 -0
 - data/lib/generators/USAGE +8 -0
 - data/lib/generators/new_google_recaptcha_generator.rb +6 -0
 - data/lib/generators/templates/new_google_recaptcha.rb +7 -0
 - data/lib/new_google_recaptcha.rb +61 -0
 - data/lib/new_google_recaptcha/railtie.rb +9 -0
 - data/lib/new_google_recaptcha/validator.rb +30 -0
 - data/lib/new_google_recaptcha/version.rb +3 -0
 - data/lib/new_google_recaptcha/view_ext.rb +41 -0
 - data/lib/tasks/new_google_recaptcha_tasks.rake +4 -0
 - metadata +168 -0
 
    
        checksums.yaml
    ADDED
    
    | 
         @@ -0,0 +1,7 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            ---
         
     | 
| 
      
 2 
     | 
    
         
            +
            SHA256:
         
     | 
| 
      
 3 
     | 
    
         
            +
              metadata.gz: 3c5cd7372d8cb66ef663b5d79f4c252e949189f9f60be5ea0a5d32691f5a8aa0
         
     | 
| 
      
 4 
     | 
    
         
            +
              data.tar.gz: cc6f097e61eb5be159f6ac0e165f2f037e2ef94ac9e0a3e549532a7d743ba880
         
     | 
| 
      
 5 
     | 
    
         
            +
            SHA512:
         
     | 
| 
      
 6 
     | 
    
         
            +
              metadata.gz: e0ce6734d58c2e7f9b4d9c53a24fd9754b6aeb09b0688bc657989aceacd5c1ce76638b967367148cde449bd2ff7af8ef1e6770963d7d51b7291b20c0f1394f2b
         
     | 
| 
      
 7 
     | 
    
         
            +
              data.tar.gz: 84570ddaeb15737ab5f3c2645ea1cd9e32a5c54d09ff378df6a3f2606a285297a56fb77fe37bb16e42bee837a592100240b8f1523da23687e60ee713cef03610
         
     | 
    
        data/MIT-LICENSE
    ADDED
    
    | 
         @@ -0,0 +1,20 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            Copyright 2018 Igor Kasyanchuk
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
      
 3 
     | 
    
         
            +
            Permission is hereby granted, free of charge, to any person obtaining
         
     | 
| 
      
 4 
     | 
    
         
            +
            a copy of this software and associated documentation files (the
         
     | 
| 
      
 5 
     | 
    
         
            +
            "Software"), to deal in the Software without restriction, including
         
     | 
| 
      
 6 
     | 
    
         
            +
            without limitation the rights to use, copy, modify, merge, publish,
         
     | 
| 
      
 7 
     | 
    
         
            +
            distribute, sublicense, and/or sell copies of the Software, and to
         
     | 
| 
      
 8 
     | 
    
         
            +
            permit persons to whom the Software is furnished to do so, subject to
         
     | 
| 
      
 9 
     | 
    
         
            +
            the following conditions:
         
     | 
| 
      
 10 
     | 
    
         
            +
             
     | 
| 
      
 11 
     | 
    
         
            +
            The above copyright notice and this permission notice shall be
         
     | 
| 
      
 12 
     | 
    
         
            +
            included in all copies or substantial portions of the Software.
         
     | 
| 
      
 13 
     | 
    
         
            +
             
     | 
| 
      
 14 
     | 
    
         
            +
            THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
         
     | 
| 
      
 15 
     | 
    
         
            +
            EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
         
     | 
| 
      
 16 
     | 
    
         
            +
            MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
         
     | 
| 
      
 17 
     | 
    
         
            +
            NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
         
     | 
| 
      
 18 
     | 
    
         
            +
            LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
         
     | 
| 
      
 19 
     | 
    
         
            +
            OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
         
     | 
| 
      
 20 
     | 
    
         
            +
            WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
         
     | 
    
        data/README.md
    ADDED
    
    | 
         @@ -0,0 +1,237 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            # Google Recaptcha v3 + Rails
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
      
 3 
     | 
    
         
            +
            [](https://travis-ci.org/igorkasyanchuk/new_google_recaptcha)
         
     | 
| 
      
 4 
     | 
    
         
            +
            [](https://www.railsjazz.com)
         
     | 
| 
      
 5 
     | 
    
         
            +
             
     | 
| 
      
 6 
     | 
    
         
            +
            Integrate Google Recaptcha v3 with Rails app.
         
     | 
| 
      
 7 
     | 
    
         
            +
             
     | 
| 
      
 8 
     | 
    
         
            +
            Google Recaptcha console: https://www.google.com/recaptcha/admin#list
         
     | 
| 
      
 9 
     | 
    
         
            +
             
     | 
| 
      
 10 
     | 
    
         
            +
            Recaptcha v3 documentation: https://developers.google.com/recaptcha/docs/v3
         
     | 
| 
      
 11 
     | 
    
         
            +
             
     | 
| 
      
 12 
     | 
    
         
            +
            ## Usage
         
     | 
| 
      
 13 
     | 
    
         
            +
             
     | 
| 
      
 14 
     | 
    
         
            +
            - Open https://www.google.com/recaptcha/admin#list
         
     | 
| 
      
 15 
     | 
    
         
            +
            - register a new site
         
     | 
| 
      
 16 
     | 
    
         
            +
            - copy `site_key` and `secret_key` and put into config/initializers/new_google_recaptcha.rb
         
     | 
| 
      
 17 
     | 
    
         
            +
            - optionally, change the `minimum_score` in the initializer to a preferred float value (from 0.0 to 1.0)
         
     | 
| 
      
 18 
     | 
    
         
            +
            - in layout:
         
     | 
| 
      
 19 
     | 
    
         
            +
              ```erb
         
     | 
| 
      
 20 
     | 
    
         
            +
              <head>
         
     | 
| 
      
 21 
     | 
    
         
            +
                ...
         
     | 
| 
      
 22 
     | 
    
         
            +
                <%= yield :recaptcha_js %>
         
     | 
| 
      
 23 
     | 
    
         
            +
              </head>
         
     | 
| 
      
 24 
     | 
    
         
            +
              ```
         
     | 
| 
      
 25 
     | 
    
         
            +
            - in view where you for example you have a form:
         
     | 
| 
      
 26 
     | 
    
         
            +
              ```erb
         
     | 
| 
      
 27 
     | 
    
         
            +
              <%= content_for :recaptcha_js do %>
         
     | 
| 
      
 28 
     | 
    
         
            +
                <%= include_recaptcha_js %>
         
     | 
| 
      
 29 
     | 
    
         
            +
              <% end %>
         
     | 
| 
      
 30 
     | 
    
         
            +
              <form ...>
         
     | 
| 
      
 31 
     | 
    
         
            +
                <%#= 'checkout' is action name to be verified later %>
         
     | 
| 
      
 32 
     | 
    
         
            +
                <%= recaptcha_action('checkout') %>
         
     | 
| 
      
 33 
     | 
    
         
            +
              </form>
         
     | 
| 
      
 34 
     | 
    
         
            +
              ```
         
     | 
| 
      
 35 
     | 
    
         
            +
            - in controller:
         
     | 
| 
      
 36 
     | 
    
         
            +
              ```ruby
         
     | 
| 
      
 37 
     | 
    
         
            +
              def create
         
     | 
| 
      
 38 
     | 
    
         
            +
                @post = Post.new(post_params)
         
     | 
| 
      
 39 
     | 
    
         
            +
                if NewGoogleRecaptcha.human?(
         
     | 
| 
      
 40 
     | 
    
         
            +
                    params[:new_google_recaptcha_token],
         
     | 
| 
      
 41 
     | 
    
         
            +
                    "checkout",
         
     | 
| 
      
 42 
     | 
    
         
            +
                    NewGoogleRecaptcha.minimum_score,
         
     | 
| 
      
 43 
     | 
    
         
            +
                    @post
         
     | 
| 
      
 44 
     | 
    
         
            +
                  ) && @post.save
         
     | 
| 
      
 45 
     | 
    
         
            +
                  redirect_to @post, notice: 'Post was successfully created.'
         
     | 
| 
      
 46 
     | 
    
         
            +
                else
         
     | 
| 
      
 47 
     | 
    
         
            +
                  render :new
         
     | 
| 
      
 48 
     | 
    
         
            +
                end
         
     | 
| 
      
 49 
     | 
    
         
            +
              end
         
     | 
| 
      
 50 
     | 
    
         
            +
             
     | 
| 
      
 51 
     | 
    
         
            +
             
     | 
| 
      
 52 
     | 
    
         
            +
              # or
         
     | 
| 
      
 53 
     | 
    
         
            +
              # if you need to capture a humanity `score` from Google
         
     | 
| 
      
 54 
     | 
    
         
            +
              # before you need to add a column for example `humanity_score` (type: float) where this score will be saved.
         
     | 
| 
      
 55 
     | 
    
         
            +
             
     | 
| 
      
 56 
     | 
    
         
            +
             
     | 
| 
      
 57 
     | 
    
         
            +
              def create
         
     | 
| 
      
 58 
     | 
    
         
            +
                @post = Post.new(post_params)
         
     | 
| 
      
 59 
     | 
    
         
            +
                humanity_details =
         
     | 
| 
      
 60 
     | 
    
         
            +
                  NewGoogleRecaptcha.get_humanity_detailed(
         
     | 
| 
      
 61 
     | 
    
         
            +
                    params[:new_google_recaptcha_token],
         
     | 
| 
      
 62 
     | 
    
         
            +
                    "checkout",
         
     | 
| 
      
 63 
     | 
    
         
            +
                    NewGoogleRecaptcha.minimum_score,
         
     | 
| 
      
 64 
     | 
    
         
            +
                    @post
         
     | 
| 
      
 65 
     | 
    
         
            +
                  )
         
     | 
| 
      
 66 
     | 
    
         
            +
             
     | 
| 
      
 67 
     | 
    
         
            +
                @post.humanity_score = humanity_details[:score]
         
     | 
| 
      
 68 
     | 
    
         
            +
             
     | 
| 
      
 69 
     | 
    
         
            +
                if humanity_details[:is_human] && @post.save
         
     | 
| 
      
 70 
     | 
    
         
            +
                  redirect_to @post, notice: 'Post was successfully created.'
         
     | 
| 
      
 71 
     | 
    
         
            +
                else
         
     | 
| 
      
 72 
     | 
    
         
            +
                  render :new
         
     | 
| 
      
 73 
     | 
    
         
            +
                end
         
     | 
| 
      
 74 
     | 
    
         
            +
              end
         
     | 
| 
      
 75 
     | 
    
         
            +
              ```
         
     | 
| 
      
 76 
     | 
    
         
            +
             
     | 
| 
      
 77 
     | 
    
         
            +
            There are two mandatory arguments for `human?` method:
         
     | 
| 
      
 78 
     | 
    
         
            +
             
     | 
| 
      
 79 
     | 
    
         
            +
            - `token` - token valid for your site
         
     | 
| 
      
 80 
     | 
    
         
            +
            - `action` - the action name for this request
         
     | 
| 
      
 81 
     | 
    
         
            +
              (the gem checks if it is the same as the name used with the token,
         
     | 
| 
      
 82 
     | 
    
         
            +
              otherwise a hacker could replace it on frontend to some another action used,
         
     | 
| 
      
 83 
     | 
    
         
            +
              but with lower score requirement and thus pass the verification)
         
     | 
| 
      
 84 
     | 
    
         
            +
             
     | 
| 
      
 85 
     | 
    
         
            +
            You can verify recaptcha without using these arguments:
         
     | 
| 
      
 86 
     | 
    
         
            +
             
     | 
| 
      
 87 
     | 
    
         
            +
            - `minimum_score` - defaults to value set in the initializer
         
     | 
| 
      
 88 
     | 
    
         
            +
              (reCAPTCHA recommends using 0.5 as default)
         
     | 
| 
      
 89 
     | 
    
         
            +
            - `model` - defaults to `nil` which will result in not adding an error to model;
         
     | 
| 
      
 90 
     | 
    
         
            +
              any custom failure handling is applicable here
         
     | 
| 
      
 91 
     | 
    
         
            +
             
     | 
| 
      
 92 
     | 
    
         
            +
            like this:
         
     | 
| 
      
 93 
     | 
    
         
            +
             
     | 
| 
      
 94 
     | 
    
         
            +
            ```ruby
         
     | 
| 
      
 95 
     | 
    
         
            +
              NewGoogleRecaptcha.human?(params[:new_google_recaptcha_token], "checkout")
         
     | 
| 
      
 96 
     | 
    
         
            +
            ```
         
     | 
| 
      
 97 
     | 
    
         
            +
             
     | 
| 
      
 98 
     | 
    
         
            +
            ### Saving humanity score from Google in your model
         
     | 
| 
      
 99 
     | 
    
         
            +
             
     | 
| 
      
 100 
     | 
    
         
            +
            `get_humanity_detailed` method acts like `human?` method, the only difference is that it returns following hash with three key-value pairs:
         
     | 
| 
      
 101 
     | 
    
         
            +
             
     | 
| 
      
 102 
     | 
    
         
            +
            - `is_human` - whether actor is a human or not (same as result of `human?` method)
         
     | 
| 
      
 103 
     | 
    
         
            +
            - `score` - actual humanity score from recaptcha response
         
     | 
| 
      
 104 
     | 
    
         
            +
            - `model` - model which you trying to save
         
     | 
| 
      
 105 
     | 
    
         
            +
             
     | 
| 
      
 106 
     | 
    
         
            +
            It could be handy if you want to store score in db or put it into logs or smth else. Real example is above in the code samples.
         
     | 
| 
      
 107 
     | 
    
         
            +
             
     | 
| 
      
 108 
     | 
    
         
            +
            Add to your navigation links `data-turbolinks="false"` to make it works with `turbolinks`.
         
     | 
| 
      
 109 
     | 
    
         
            +
             
     | 
| 
      
 110 
     | 
    
         
            +
            ## Installation
         
     | 
| 
      
 111 
     | 
    
         
            +
             
     | 
| 
      
 112 
     | 
    
         
            +
            ```ruby
         
     | 
| 
      
 113 
     | 
    
         
            +
            gem 'new_google_recaptcha'
         
     | 
| 
      
 114 
     | 
    
         
            +
            ```
         
     | 
| 
      
 115 
     | 
    
         
            +
             
     | 
| 
      
 116 
     | 
    
         
            +
            And then execute:
         
     | 
| 
      
 117 
     | 
    
         
            +
            ```bash
         
     | 
| 
      
 118 
     | 
    
         
            +
            $ bundle
         
     | 
| 
      
 119 
     | 
    
         
            +
            ```
         
     | 
| 
      
 120 
     | 
    
         
            +
             
     | 
| 
      
 121 
     | 
    
         
            +
            And then run:
         
     | 
| 
      
 122 
     | 
    
         
            +
             
     | 
| 
      
 123 
     | 
    
         
            +
            ```bash
         
     | 
| 
      
 124 
     | 
    
         
            +
            $ rails generate new_google_recaptcha initializer
         
     | 
| 
      
 125 
     | 
    
         
            +
            ```
         
     | 
| 
      
 126 
     | 
    
         
            +
             
     | 
| 
      
 127 
     | 
    
         
            +
            And edit new_google_recaptcha.rb and enter your site_key and secret_key.
         
     | 
| 
      
 128 
     | 
    
         
            +
             
     | 
| 
      
 129 
     | 
    
         
            +
            ## API
         
     | 
| 
      
 130 
     | 
    
         
            +
             
     | 
| 
      
 131 
     | 
    
         
            +
            `NewGoogleRecaptcha.human?(token, model)` or `NewGoogleRecaptcha.get_humanity_detailed(token, model)` in contoller
         
     | 
| 
      
 132 
     | 
    
         
            +
             
     | 
| 
      
 133 
     | 
    
         
            +
            - token is received from google, must be sent to backend
         
     | 
| 
      
 134 
     | 
    
         
            +
            - model optional parameter. if you want to add error to model.
         
     | 
| 
      
 135 
     | 
    
         
            +
             
     | 
| 
      
 136 
     | 
    
         
            +
            `<%= include_recaptcha_js %>` in layout (by using yield)
         
     | 
| 
      
 137 
     | 
    
         
            +
             
     | 
| 
      
 138 
     | 
    
         
            +
            Include Google Recaptcha v3 JS into your Rails app. In head, right before `</head>`.
         
     | 
| 
      
 139 
     | 
    
         
            +
             
     | 
| 
      
 140 
     | 
    
         
            +
            `<%= recaptcha_action(action_name) %>` in view
         
     | 
| 
      
 141 
     | 
    
         
            +
             
     | 
| 
      
 142 
     | 
    
         
            +
            Action where recaptcha action was executed. Actions could be viewed in Admin console. More docs: https://developers.google.com/recaptcha/docs/v3. Action name could be "comments", "checkout", etc. Put any name and check scores in console.
         
     | 
| 
      
 143 
     | 
    
         
            +
             
     | 
| 
      
 144 
     | 
    
         
            +
            ## How to add to the Devise
         
     | 
| 
      
 145 
     | 
    
         
            +
             
     | 
| 
      
 146 
     | 
    
         
            +
            Generate Devise controllers and views, and edit "create" method.
         
     | 
| 
      
 147 
     | 
    
         
            +
             
     | 
| 
      
 148 
     | 
    
         
            +
            ```ruby
         
     | 
| 
      
 149 
     | 
    
         
            +
            class Users::RegistrationsController < Devise::RegistrationsController
         
     | 
| 
      
 150 
     | 
    
         
            +
            ...
         
     | 
| 
      
 151 
     | 
    
         
            +
              def create
         
     | 
| 
      
 152 
     | 
    
         
            +
                build_resource(sign_up_params)
         
     | 
| 
      
 153 
     | 
    
         
            +
             
     | 
| 
      
 154 
     | 
    
         
            +
                NewGoogleRecaptcha.human?(
         
     | 
| 
      
 155 
     | 
    
         
            +
                  params[:new_google_recaptcha_token],
         
     | 
| 
      
 156 
     | 
    
         
            +
                  "user",
         
     | 
| 
      
 157 
     | 
    
         
            +
                  NewGoogleRecaptcha.minimum_score,
         
     | 
| 
      
 158 
     | 
    
         
            +
                  resource) && resource.save
         
     | 
| 
      
 159 
     | 
    
         
            +
             
     | 
| 
      
 160 
     | 
    
         
            +
                yield resource if block_given?
         
     | 
| 
      
 161 
     | 
    
         
            +
                if resource.persisted?
         
     | 
| 
      
 162 
     | 
    
         
            +
                  if resource.active_for_authentication?
         
     | 
| 
      
 163 
     | 
    
         
            +
                    set_flash_message! :notice, :signed_up
         
     | 
| 
      
 164 
     | 
    
         
            +
                    sign_up(resource_name, resource)
         
     | 
| 
      
 165 
     | 
    
         
            +
                    respond_with resource, location: after_sign_up_path_for(resource)
         
     | 
| 
      
 166 
     | 
    
         
            +
                  else
         
     | 
| 
      
 167 
     | 
    
         
            +
                    set_flash_message! :notice, :"signed_up_but_#{resource.inactive_message}"
         
     | 
| 
      
 168 
     | 
    
         
            +
                    expire_data_after_sign_in!
         
     | 
| 
      
 169 
     | 
    
         
            +
                    respond_with resource, location: after_inactive_sign_up_path_for(resource)
         
     | 
| 
      
 170 
     | 
    
         
            +
                  end
         
     | 
| 
      
 171 
     | 
    
         
            +
                else
         
     | 
| 
      
 172 
     | 
    
         
            +
                  clean_up_passwords resource
         
     | 
| 
      
 173 
     | 
    
         
            +
                  set_minimum_password_length
         
     | 
| 
      
 174 
     | 
    
         
            +
                  respond_with resource
         
     | 
| 
      
 175 
     | 
    
         
            +
                end
         
     | 
| 
      
 176 
     | 
    
         
            +
              end
         
     | 
| 
      
 177 
     | 
    
         
            +
            ```
         
     | 
| 
      
 178 
     | 
    
         
            +
             
     | 
| 
      
 179 
     | 
    
         
            +
            ## How to use in test or specs
         
     | 
| 
      
 180 
     | 
    
         
            +
             
     | 
| 
      
 181 
     | 
    
         
            +
            At the end of the spec/rails_helper.rb put:
         
     | 
| 
      
 182 
     | 
    
         
            +
             
     | 
| 
      
 183 
     | 
    
         
            +
            ```ruby
         
     | 
| 
      
 184 
     | 
    
         
            +
            module NewGoogleRecaptcha
         
     | 
| 
      
 185 
     | 
    
         
            +
              def self.human?(*attrs)
         
     | 
| 
      
 186 
     | 
    
         
            +
                true
         
     | 
| 
      
 187 
     | 
    
         
            +
              end
         
     | 
| 
      
 188 
     | 
    
         
            +
            end
         
     | 
| 
      
 189 
     | 
    
         
            +
            ```
         
     | 
| 
      
 190 
     | 
    
         
            +
             
     | 
| 
      
 191 
     | 
    
         
            +
            Tests are located in `specs` folder and `test/dummy/tests` folder.
         
     | 
| 
      
 192 
     | 
    
         
            +
             
     | 
| 
      
 193 
     | 
    
         
            +
             
     | 
| 
      
 194 
     | 
    
         
            +
            ## I18n support
         
     | 
| 
      
 195 
     | 
    
         
            +
             
     | 
| 
      
 196 
     | 
    
         
            +
            reCAPTCHA passes one types of error explanation to a linked model. It will use the I18n gem
         
     | 
| 
      
 197 
     | 
    
         
            +
            to translate the default error message if I18n is available. To customize the messages to your locale,
         
     | 
| 
      
 198 
     | 
    
         
            +
            add these keys to your I18n backend:
         
     | 
| 
      
 199 
     | 
    
         
            +
             
     | 
| 
      
 200 
     | 
    
         
            +
            `new_google_recaptcha.errors.verification_human` error message displayed when it is something like a robot, or a suspicious action
         
     | 
| 
      
 201 
     | 
    
         
            +
             
     | 
| 
      
 202 
     | 
    
         
            +
            Also you can translate API response errors to human friendly by adding translations to the locale (`config/locales/en.yml`):
         
     | 
| 
      
 203 
     | 
    
         
            +
             
     | 
| 
      
 204 
     | 
    
         
            +
            ```Yaml
         
     | 
| 
      
 205 
     | 
    
         
            +
            en:
         
     | 
| 
      
 206 
     | 
    
         
            +
              new_google_recaptcha:
         
     | 
| 
      
 207 
     | 
    
         
            +
                errors:
         
     | 
| 
      
 208 
     | 
    
         
            +
                  verification_human: 'Fail'
         
     | 
| 
      
 209 
     | 
    
         
            +
            ```
         
     | 
| 
      
 210 
     | 
    
         
            +
             
     | 
| 
      
 211 
     | 
    
         
            +
            ## TODO
         
     | 
| 
      
 212 
     | 
    
         
            +
             
     | 
| 
      
 213 
     | 
    
         
            +
            - check everything works with turbolinks
         
     | 
| 
      
 214 
     | 
    
         
            +
            - allow custom ID for input
         
     | 
| 
      
 215 
     | 
    
         
            +
            - more tests
         
     | 
| 
      
 216 
     | 
    
         
            +
            - handle exceptions with timeouts, json is not parsed
         
     | 
| 
      
 217 
     | 
    
         
            +
            - add support for non-Rails apps
         
     | 
| 
      
 218 
     | 
    
         
            +
            - add support for older Rails (should be easy since code is very simple)
         
     | 
| 
      
 219 
     | 
    
         
            +
             
     | 
| 
      
 220 
     | 
    
         
            +
            ## Contributors
         
     | 
| 
      
 221 
     | 
    
         
            +
             
     | 
| 
      
 222 
     | 
    
         
            +
            You are welcome to contribute.
         
     | 
| 
      
 223 
     | 
    
         
            +
             
     | 
| 
      
 224 
     | 
    
         
            +
            * [Igor Kasyanchuk](https://github.com/igorkasyanchuk) (maintainer)
         
     | 
| 
      
 225 
     | 
    
         
            +
            * [gilcierweb](https://github.com/gilcierweb)
         
     | 
| 
      
 226 
     | 
    
         
            +
            * [RoRElessar](https://github.com/RoRElessar)
         
     | 
| 
      
 227 
     | 
    
         
            +
            * [rubyconvict](https://github.com/rubyconvict)
         
     | 
| 
      
 228 
     | 
    
         
            +
            * [adelnabiullin](https://github.com/adelnabiullin)
         
     | 
| 
      
 229 
     | 
    
         
            +
            * [jhill](https://github.com/jhill)
         
     | 
| 
      
 230 
     | 
    
         
            +
             
     | 
| 
      
 231 
     | 
    
         
            +
            ## License
         
     | 
| 
      
 232 
     | 
    
         
            +
             
     | 
| 
      
 233 
     | 
    
         
            +
            The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
         
     | 
| 
      
 234 
     | 
    
         
            +
             
     | 
| 
      
 235 
     | 
    
         
            +
             
     | 
| 
      
 236 
     | 
    
         
            +
            [<img src="https://github.com/igorkasyanchuk/rails_time_travel/blob/main/docs/more_gems.png?raw=true"
         
     | 
| 
      
 237 
     | 
    
         
            +
            />](https://www.railsjazz.com/)
         
     | 
    
        data/Rakefile
    ADDED
    
    | 
         @@ -0,0 +1,27 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            begin
         
     | 
| 
      
 2 
     | 
    
         
            +
              require 'bundler/setup'
         
     | 
| 
      
 3 
     | 
    
         
            +
            rescue LoadError
         
     | 
| 
      
 4 
     | 
    
         
            +
              puts 'You must `gem install bundler` and `bundle install` to run rake tasks'
         
     | 
| 
      
 5 
     | 
    
         
            +
            end
         
     | 
| 
      
 6 
     | 
    
         
            +
             
     | 
| 
      
 7 
     | 
    
         
            +
            require 'rdoc/task'
         
     | 
| 
      
 8 
     | 
    
         
            +
             
     | 
| 
      
 9 
     | 
    
         
            +
            RDoc::Task.new(:rdoc) do |rdoc|
         
     | 
| 
      
 10 
     | 
    
         
            +
              rdoc.rdoc_dir = 'rdoc'
         
     | 
| 
      
 11 
     | 
    
         
            +
              rdoc.title    = 'NewGoogleRecaptcha'
         
     | 
| 
      
 12 
     | 
    
         
            +
              rdoc.options << '--line-numbers'
         
     | 
| 
      
 13 
     | 
    
         
            +
              rdoc.rdoc_files.include('README.md')
         
     | 
| 
      
 14 
     | 
    
         
            +
              rdoc.rdoc_files.include('lib/**/*.rb')
         
     | 
| 
      
 15 
     | 
    
         
            +
            end
         
     | 
| 
      
 16 
     | 
    
         
            +
             
     | 
| 
      
 17 
     | 
    
         
            +
            require 'bundler/gem_tasks'
         
     | 
| 
      
 18 
     | 
    
         
            +
             
     | 
| 
      
 19 
     | 
    
         
            +
            require 'rake/testtask'
         
     | 
| 
      
 20 
     | 
    
         
            +
             
     | 
| 
      
 21 
     | 
    
         
            +
            Rake::TestTask.new(:test) do |t|
         
     | 
| 
      
 22 
     | 
    
         
            +
              t.libs << 'test'
         
     | 
| 
      
 23 
     | 
    
         
            +
              t.pattern = 'test/**/*_test.rb'
         
     | 
| 
      
 24 
     | 
    
         
            +
              t.verbose = false
         
     | 
| 
      
 25 
     | 
    
         
            +
            end
         
     | 
| 
      
 26 
     | 
    
         
            +
             
     | 
| 
      
 27 
     | 
    
         
            +
            task default: :test
         
     | 
| 
         @@ -0,0 +1,61 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            require "new_google_recaptcha/railtie"
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
      
 3 
     | 
    
         
            +
            module NewGoogleRecaptcha
         
     | 
| 
      
 4 
     | 
    
         
            +
              mattr_accessor :site_key
         
     | 
| 
      
 5 
     | 
    
         
            +
              mattr_accessor :secret_key
         
     | 
| 
      
 6 
     | 
    
         
            +
              mattr_accessor :minimum_score
         
     | 
| 
      
 7 
     | 
    
         
            +
             
     | 
| 
      
 8 
     | 
    
         
            +
              def self.setup
         
     | 
| 
      
 9 
     | 
    
         
            +
                yield(self)
         
     | 
| 
      
 10 
     | 
    
         
            +
              end
         
     | 
| 
      
 11 
     | 
    
         
            +
             
     | 
| 
      
 12 
     | 
    
         
            +
              def self.human?(token, action, minimum_score = self.minimum_score, model = nil)
         
     | 
| 
      
 13 
     | 
    
         
            +
                is_valid =
         
     | 
| 
      
 14 
     | 
    
         
            +
                  NewGoogleRecaptcha::Validator.new(
         
     | 
| 
      
 15 
     | 
    
         
            +
                    token: token,
         
     | 
| 
      
 16 
     | 
    
         
            +
                    action: action,
         
     | 
| 
      
 17 
     | 
    
         
            +
                    minimum_score: minimum_score
         
     | 
| 
      
 18 
     | 
    
         
            +
                  ).call
         
     | 
| 
      
 19 
     | 
    
         
            +
             
     | 
| 
      
 20 
     | 
    
         
            +
                if model && !is_valid
         
     | 
| 
      
 21 
     | 
    
         
            +
                  model.errors.add(:base, self.i18n("new_google_recaptcha.errors.verification_human", "Looks like you are not a human"))
         
     | 
| 
      
 22 
     | 
    
         
            +
                end
         
     | 
| 
      
 23 
     | 
    
         
            +
             
     | 
| 
      
 24 
     | 
    
         
            +
                is_valid
         
     | 
| 
      
 25 
     | 
    
         
            +
              end
         
     | 
| 
      
 26 
     | 
    
         
            +
             
     | 
| 
      
 27 
     | 
    
         
            +
              def self.get_humanity_detailed(token, action, minimum_score = self.minimum_score, model = nil)
         
     | 
| 
      
 28 
     | 
    
         
            +
                validator =
         
     | 
| 
      
 29 
     | 
    
         
            +
                  NewGoogleRecaptcha::Validator.new(
         
     | 
| 
      
 30 
     | 
    
         
            +
                    token: token,
         
     | 
| 
      
 31 
     | 
    
         
            +
                    action: action,
         
     | 
| 
      
 32 
     | 
    
         
            +
                    minimum_score: minimum_score
         
     | 
| 
      
 33 
     | 
    
         
            +
                  )
         
     | 
| 
      
 34 
     | 
    
         
            +
             
     | 
| 
      
 35 
     | 
    
         
            +
                is_valid = validator.call
         
     | 
| 
      
 36 
     | 
    
         
            +
             
     | 
| 
      
 37 
     | 
    
         
            +
                if model && !is_valid
         
     | 
| 
      
 38 
     | 
    
         
            +
                  model.errors.add(:base, self.i18n("new_google_recaptcha.errors.verification_human", "Looks like you are not a human"))
         
     | 
| 
      
 39 
     | 
    
         
            +
                end
         
     | 
| 
      
 40 
     | 
    
         
            +
             
     | 
| 
      
 41 
     | 
    
         
            +
                { is_human: is_valid, score: validator.score, model: model }
         
     | 
| 
      
 42 
     | 
    
         
            +
              end
         
     | 
| 
      
 43 
     | 
    
         
            +
             
     | 
| 
      
 44 
     | 
    
         
            +
              def self.i18n(key, default)
         
     | 
| 
      
 45 
     | 
    
         
            +
                if defined?(I18n)
         
     | 
| 
      
 46 
     | 
    
         
            +
                  I18n.translate(key, default: default)
         
     | 
| 
      
 47 
     | 
    
         
            +
                else
         
     | 
| 
      
 48 
     | 
    
         
            +
                  default
         
     | 
| 
      
 49 
     | 
    
         
            +
                end
         
     | 
| 
      
 50 
     | 
    
         
            +
              end
         
     | 
| 
      
 51 
     | 
    
         
            +
             
     | 
| 
      
 52 
     | 
    
         
            +
              def self.compose_uri(token)
         
     | 
| 
      
 53 
     | 
    
         
            +
                URI(
         
     | 
| 
      
 54 
     | 
    
         
            +
                  "https://www.google.com/recaptcha/api/siteverify?"\
         
     | 
| 
      
 55 
     | 
    
         
            +
                  "secret=#{self.secret_key}&response=#{token}"
         
     | 
| 
      
 56 
     | 
    
         
            +
                )
         
     | 
| 
      
 57 
     | 
    
         
            +
              end
         
     | 
| 
      
 58 
     | 
    
         
            +
            end
         
     | 
| 
      
 59 
     | 
    
         
            +
             
     | 
| 
      
 60 
     | 
    
         
            +
            require_relative "new_google_recaptcha/view_ext"
         
     | 
| 
      
 61 
     | 
    
         
            +
            require_relative "new_google_recaptcha/validator"
         
     | 
| 
         @@ -0,0 +1,30 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            require 'net/http'
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
      
 3 
     | 
    
         
            +
            module NewGoogleRecaptcha
         
     | 
| 
      
 4 
     | 
    
         
            +
              class Validator
         
     | 
| 
      
 5 
     | 
    
         
            +
                attr_reader :score
         
     | 
| 
      
 6 
     | 
    
         
            +
                attr_reader :token, :action, :minimum_score
         
     | 
| 
      
 7 
     | 
    
         
            +
             
     | 
| 
      
 8 
     | 
    
         
            +
                def initialize(token:, action:, minimum_score:)
         
     | 
| 
      
 9 
     | 
    
         
            +
                  @token         = token
         
     | 
| 
      
 10 
     | 
    
         
            +
                  @action        = action
         
     | 
| 
      
 11 
     | 
    
         
            +
                  @minimum_score = minimum_score
         
     | 
| 
      
 12 
     | 
    
         
            +
                end
         
     | 
| 
      
 13 
     | 
    
         
            +
             
     | 
| 
      
 14 
     | 
    
         
            +
                def call
         
     | 
| 
      
 15 
     | 
    
         
            +
                  uri    = NewGoogleRecaptcha.compose_uri(token)
         
     | 
| 
      
 16 
     | 
    
         
            +
                  
         
     | 
| 
      
 17 
     | 
    
         
            +
                  http = Net::HTTP.new(uri.host, uri.port)
         
     | 
| 
      
 18 
     | 
    
         
            +
                  http.use_ssl = true if uri.scheme == 'https' 
         
     | 
| 
      
 19 
     | 
    
         
            +
                  result = JSON.parse(http.request(Net::HTTP::Get.new(uri)).body)
         
     | 
| 
      
 20 
     | 
    
         
            +
             
     | 
| 
      
 21 
     | 
    
         
            +
                  @score = result['score'].to_f
         
     | 
| 
      
 22 
     | 
    
         
            +
             
     | 
| 
      
 23 
     | 
    
         
            +
                  conditions = []
         
     | 
| 
      
 24 
     | 
    
         
            +
                  conditions << !!result['success']
         
     | 
| 
      
 25 
     | 
    
         
            +
                  conditions << (result['score'].to_f >= minimum_score)
         
     | 
| 
      
 26 
     | 
    
         
            +
                  conditions << (result['action'].to_s == action.to_s)
         
     | 
| 
      
 27 
     | 
    
         
            +
                  conditions.none?(&:!)
         
     | 
| 
      
 28 
     | 
    
         
            +
                end
         
     | 
| 
      
 29 
     | 
    
         
            +
              end
         
     | 
| 
      
 30 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -0,0 +1,41 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            module NewGoogleRecaptcha
         
     | 
| 
      
 2 
     | 
    
         
            +
              module ViewExt
         
     | 
| 
      
 3 
     | 
    
         
            +
                include ActionView::Helpers::TagHelper
         
     | 
| 
      
 4 
     | 
    
         
            +
             
     | 
| 
      
 5 
     | 
    
         
            +
                def include_recaptcha_js
         
     | 
| 
      
 6 
     | 
    
         
            +
                  generate_recaptcha_callback + javascript_include_tag("https://www.google.com/recaptcha/api.js?render=#{NewGoogleRecaptcha.site_key}&onload=newGoogleRecaptchaCallback", defer: true, 'data-turbolinks-track': "reload")
         
     | 
| 
      
 7 
     | 
    
         
            +
                end
         
     | 
| 
      
 8 
     | 
    
         
            +
             
     | 
| 
      
 9 
     | 
    
         
            +
                def recaptcha_action(action)
         
     | 
| 
      
 10 
     | 
    
         
            +
                  id = "new_google_recaptcha_token_#{SecureRandom.hex(10)}"
         
     | 
| 
      
 11 
     | 
    
         
            +
                  hidden_field_tag(
         
     | 
| 
      
 12 
     | 
    
         
            +
                    "new_recaptcha_token",
         
     | 
| 
      
 13 
     | 
    
         
            +
                    nil,
         
     | 
| 
      
 14 
     | 
    
         
            +
                    :readonly => true,
         
     | 
| 
      
 15 
     | 
    
         
            +
                    "data-google-recaptcha-action" => action,
         
     | 
| 
      
 16 
     | 
    
         
            +
                    :id => id
         
     | 
| 
      
 17 
     | 
    
         
            +
                  )
         
     | 
| 
      
 18 
     | 
    
         
            +
                end
         
     | 
| 
      
 19 
     | 
    
         
            +
             
     | 
| 
      
 20 
     | 
    
         
            +
                private
         
     | 
| 
      
 21 
     | 
    
         
            +
             
     | 
| 
      
 22 
     | 
    
         
            +
                def generate_recaptcha_callback
         
     | 
| 
      
 23 
     | 
    
         
            +
                  javascript_tag %(
         
     | 
| 
      
 24 
     | 
    
         
            +
                    function newGoogleRecaptchaCallback () {
         
     | 
| 
      
 25 
     | 
    
         
            +
                      grecaptcha.ready(function () {
         
     | 
| 
      
 26 
     | 
    
         
            +
                        var elements = document.querySelectorAll('[data-google-recaptcha-action]')
         
     | 
| 
      
 27 
     | 
    
         
            +
                        Array.prototype.slice.call(elements).forEach(function (el) {
         
     | 
| 
      
 28 
     | 
    
         
            +
                          var action = el.dataset.googleRecaptchaAction
         
     | 
| 
      
 29 
     | 
    
         
            +
                          if (!action) return
         
     | 
| 
      
 30 
     | 
    
         
            +
                          grecaptcha
         
     | 
| 
      
 31 
     | 
    
         
            +
                            .execute("#{NewGoogleRecaptcha.site_key}", { action: action })
         
     | 
| 
      
 32 
     | 
    
         
            +
                            .then(function (token) {
         
     | 
| 
      
 33 
     | 
    
         
            +
                              el.value = token
         
     | 
| 
      
 34 
     | 
    
         
            +
                            })
         
     | 
| 
      
 35 
     | 
    
         
            +
                        })
         
     | 
| 
      
 36 
     | 
    
         
            +
                      })
         
     | 
| 
      
 37 
     | 
    
         
            +
                    }
         
     | 
| 
      
 38 
     | 
    
         
            +
                  )
         
     | 
| 
      
 39 
     | 
    
         
            +
                end
         
     | 
| 
      
 40 
     | 
    
         
            +
              end
         
     | 
| 
      
 41 
     | 
    
         
            +
            end
         
     | 
    
        metadata
    ADDED
    
    | 
         @@ -0,0 +1,168 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            --- !ruby/object:Gem::Specification
         
     | 
| 
      
 2 
     | 
    
         
            +
            name: new_google_recaptcha_turbo
         
     | 
| 
      
 3 
     | 
    
         
            +
            version: !ruby/object:Gem::Version
         
     | 
| 
      
 4 
     | 
    
         
            +
              version: 1.2.1
         
     | 
| 
      
 5 
     | 
    
         
            +
            platform: ruby
         
     | 
| 
      
 6 
     | 
    
         
            +
            authors:
         
     | 
| 
      
 7 
     | 
    
         
            +
            - Igor Kasyanchuk
         
     | 
| 
      
 8 
     | 
    
         
            +
            - rubyconvict
         
     | 
| 
      
 9 
     | 
    
         
            +
            autorequire:
         
     | 
| 
      
 10 
     | 
    
         
            +
            bindir: bin
         
     | 
| 
      
 11 
     | 
    
         
            +
            cert_chain: []
         
     | 
| 
      
 12 
     | 
    
         
            +
            date: 2021-02-01 00:00:00.000000000 Z
         
     | 
| 
      
 13 
     | 
    
         
            +
            dependencies:
         
     | 
| 
      
 14 
     | 
    
         
            +
            - !ruby/object:Gem::Dependency
         
     | 
| 
      
 15 
     | 
    
         
            +
              name: rails
         
     | 
| 
      
 16 
     | 
    
         
            +
              requirement: !ruby/object:Gem::Requirement
         
     | 
| 
      
 17 
     | 
    
         
            +
                requirements:
         
     | 
| 
      
 18 
     | 
    
         
            +
                - - ">="
         
     | 
| 
      
 19 
     | 
    
         
            +
                  - !ruby/object:Gem::Version
         
     | 
| 
      
 20 
     | 
    
         
            +
                    version: 4.2.0
         
     | 
| 
      
 21 
     | 
    
         
            +
              type: :runtime
         
     | 
| 
      
 22 
     | 
    
         
            +
              prerelease: false
         
     | 
| 
      
 23 
     | 
    
         
            +
              version_requirements: !ruby/object:Gem::Requirement
         
     | 
| 
      
 24 
     | 
    
         
            +
                requirements:
         
     | 
| 
      
 25 
     | 
    
         
            +
                - - ">="
         
     | 
| 
      
 26 
     | 
    
         
            +
                  - !ruby/object:Gem::Version
         
     | 
| 
      
 27 
     | 
    
         
            +
                    version: 4.2.0
         
     | 
| 
      
 28 
     | 
    
         
            +
            - !ruby/object:Gem::Dependency
         
     | 
| 
      
 29 
     | 
    
         
            +
              name: sqlite3
         
     | 
| 
      
 30 
     | 
    
         
            +
              requirement: !ruby/object:Gem::Requirement
         
     | 
| 
      
 31 
     | 
    
         
            +
                requirements:
         
     | 
| 
      
 32 
     | 
    
         
            +
                - - ">="
         
     | 
| 
      
 33 
     | 
    
         
            +
                  - !ruby/object:Gem::Version
         
     | 
| 
      
 34 
     | 
    
         
            +
                    version: '1.3'
         
     | 
| 
      
 35 
     | 
    
         
            +
              type: :development
         
     | 
| 
      
 36 
     | 
    
         
            +
              prerelease: false
         
     | 
| 
      
 37 
     | 
    
         
            +
              version_requirements: !ruby/object:Gem::Requirement
         
     | 
| 
      
 38 
     | 
    
         
            +
                requirements:
         
     | 
| 
      
 39 
     | 
    
         
            +
                - - ">="
         
     | 
| 
      
 40 
     | 
    
         
            +
                  - !ruby/object:Gem::Version
         
     | 
| 
      
 41 
     | 
    
         
            +
                    version: '1.3'
         
     | 
| 
      
 42 
     | 
    
         
            +
            - !ruby/object:Gem::Dependency
         
     | 
| 
      
 43 
     | 
    
         
            +
              name: byebug
         
     | 
| 
      
 44 
     | 
    
         
            +
              requirement: !ruby/object:Gem::Requirement
         
     | 
| 
      
 45 
     | 
    
         
            +
                requirements:
         
     | 
| 
      
 46 
     | 
    
         
            +
                - - ">="
         
     | 
| 
      
 47 
     | 
    
         
            +
                  - !ruby/object:Gem::Version
         
     | 
| 
      
 48 
     | 
    
         
            +
                    version: '10.0'
         
     | 
| 
      
 49 
     | 
    
         
            +
              type: :development
         
     | 
| 
      
 50 
     | 
    
         
            +
              prerelease: false
         
     | 
| 
      
 51 
     | 
    
         
            +
              version_requirements: !ruby/object:Gem::Requirement
         
     | 
| 
      
 52 
     | 
    
         
            +
                requirements:
         
     | 
| 
      
 53 
     | 
    
         
            +
                - - ">="
         
     | 
| 
      
 54 
     | 
    
         
            +
                  - !ruby/object:Gem::Version
         
     | 
| 
      
 55 
     | 
    
         
            +
                    version: '10.0'
         
     | 
| 
      
 56 
     | 
    
         
            +
            - !ruby/object:Gem::Dependency
         
     | 
| 
      
 57 
     | 
    
         
            +
              name: webmock
         
     | 
| 
      
 58 
     | 
    
         
            +
              requirement: !ruby/object:Gem::Requirement
         
     | 
| 
      
 59 
     | 
    
         
            +
                requirements:
         
     | 
| 
      
 60 
     | 
    
         
            +
                - - ">="
         
     | 
| 
      
 61 
     | 
    
         
            +
                  - !ruby/object:Gem::Version
         
     | 
| 
      
 62 
     | 
    
         
            +
                    version: '3.5'
         
     | 
| 
      
 63 
     | 
    
         
            +
              type: :development
         
     | 
| 
      
 64 
     | 
    
         
            +
              prerelease: false
         
     | 
| 
      
 65 
     | 
    
         
            +
              version_requirements: !ruby/object:Gem::Requirement
         
     | 
| 
      
 66 
     | 
    
         
            +
                requirements:
         
     | 
| 
      
 67 
     | 
    
         
            +
                - - ">="
         
     | 
| 
      
 68 
     | 
    
         
            +
                  - !ruby/object:Gem::Version
         
     | 
| 
      
 69 
     | 
    
         
            +
                    version: '3.5'
         
     | 
| 
      
 70 
     | 
    
         
            +
            - !ruby/object:Gem::Dependency
         
     | 
| 
      
 71 
     | 
    
         
            +
              name: mocha
         
     | 
| 
      
 72 
     | 
    
         
            +
              requirement: !ruby/object:Gem::Requirement
         
     | 
| 
      
 73 
     | 
    
         
            +
                requirements:
         
     | 
| 
      
 74 
     | 
    
         
            +
                - - "~>"
         
     | 
| 
      
 75 
     | 
    
         
            +
                  - !ruby/object:Gem::Version
         
     | 
| 
      
 76 
     | 
    
         
            +
                    version: 0.14.0
         
     | 
| 
      
 77 
     | 
    
         
            +
              type: :development
         
     | 
| 
      
 78 
     | 
    
         
            +
              prerelease: false
         
     | 
| 
      
 79 
     | 
    
         
            +
              version_requirements: !ruby/object:Gem::Requirement
         
     | 
| 
      
 80 
     | 
    
         
            +
                requirements:
         
     | 
| 
      
 81 
     | 
    
         
            +
                - - "~>"
         
     | 
| 
      
 82 
     | 
    
         
            +
                  - !ruby/object:Gem::Version
         
     | 
| 
      
 83 
     | 
    
         
            +
                    version: 0.14.0
         
     | 
| 
      
 84 
     | 
    
         
            +
            - !ruby/object:Gem::Dependency
         
     | 
| 
      
 85 
     | 
    
         
            +
              name: redis-store-testing
         
     | 
| 
      
 86 
     | 
    
         
            +
              requirement: !ruby/object:Gem::Requirement
         
     | 
| 
      
 87 
     | 
    
         
            +
                requirements:
         
     | 
| 
      
 88 
     | 
    
         
            +
                - - ">="
         
     | 
| 
      
 89 
     | 
    
         
            +
                  - !ruby/object:Gem::Version
         
     | 
| 
      
 90 
     | 
    
         
            +
                    version: '0'
         
     | 
| 
      
 91 
     | 
    
         
            +
              type: :development
         
     | 
| 
      
 92 
     | 
    
         
            +
              prerelease: false
         
     | 
| 
      
 93 
     | 
    
         
            +
              version_requirements: !ruby/object:Gem::Requirement
         
     | 
| 
      
 94 
     | 
    
         
            +
                requirements:
         
     | 
| 
      
 95 
     | 
    
         
            +
                - - ">="
         
     | 
| 
      
 96 
     | 
    
         
            +
                  - !ruby/object:Gem::Version
         
     | 
| 
      
 97 
     | 
    
         
            +
                    version: '0'
         
     | 
| 
      
 98 
     | 
    
         
            +
            - !ruby/object:Gem::Dependency
         
     | 
| 
      
 99 
     | 
    
         
            +
              name: connection_pool
         
     | 
| 
      
 100 
     | 
    
         
            +
              requirement: !ruby/object:Gem::Requirement
         
     | 
| 
      
 101 
     | 
    
         
            +
                requirements:
         
     | 
| 
      
 102 
     | 
    
         
            +
                - - "~>"
         
     | 
| 
      
 103 
     | 
    
         
            +
                  - !ruby/object:Gem::Version
         
     | 
| 
      
 104 
     | 
    
         
            +
                    version: 1.2.0
         
     | 
| 
      
 105 
     | 
    
         
            +
              type: :development
         
     | 
| 
      
 106 
     | 
    
         
            +
              prerelease: false
         
     | 
| 
      
 107 
     | 
    
         
            +
              version_requirements: !ruby/object:Gem::Requirement
         
     | 
| 
      
 108 
     | 
    
         
            +
                requirements:
         
     | 
| 
      
 109 
     | 
    
         
            +
                - - "~>"
         
     | 
| 
      
 110 
     | 
    
         
            +
                  - !ruby/object:Gem::Version
         
     | 
| 
      
 111 
     | 
    
         
            +
                    version: 1.2.0
         
     | 
| 
      
 112 
     | 
    
         
            +
            - !ruby/object:Gem::Dependency
         
     | 
| 
      
 113 
     | 
    
         
            +
              name: appraisal
         
     | 
| 
      
 114 
     | 
    
         
            +
              requirement: !ruby/object:Gem::Requirement
         
     | 
| 
      
 115 
     | 
    
         
            +
                requirements:
         
     | 
| 
      
 116 
     | 
    
         
            +
                - - ">="
         
     | 
| 
      
 117 
     | 
    
         
            +
                  - !ruby/object:Gem::Version
         
     | 
| 
      
 118 
     | 
    
         
            +
                    version: '0'
         
     | 
| 
      
 119 
     | 
    
         
            +
              type: :development
         
     | 
| 
      
 120 
     | 
    
         
            +
              prerelease: false
         
     | 
| 
      
 121 
     | 
    
         
            +
              version_requirements: !ruby/object:Gem::Requirement
         
     | 
| 
      
 122 
     | 
    
         
            +
                requirements:
         
     | 
| 
      
 123 
     | 
    
         
            +
                - - ">="
         
     | 
| 
      
 124 
     | 
    
         
            +
                  - !ruby/object:Gem::Version
         
     | 
| 
      
 125 
     | 
    
         
            +
                    version: '0'
         
     | 
| 
      
 126 
     | 
    
         
            +
            description: Google reCAPTCHA v3 + Rails (integration)
         
     | 
| 
      
 127 
     | 
    
         
            +
            email:
         
     | 
| 
      
 128 
     | 
    
         
            +
            - igorkasyanchuk@gmail.com
         
     | 
| 
      
 129 
     | 
    
         
            +
            executables: []
         
     | 
| 
      
 130 
     | 
    
         
            +
            extensions: []
         
     | 
| 
      
 131 
     | 
    
         
            +
            extra_rdoc_files: []
         
     | 
| 
      
 132 
     | 
    
         
            +
            files:
         
     | 
| 
      
 133 
     | 
    
         
            +
            - MIT-LICENSE
         
     | 
| 
      
 134 
     | 
    
         
            +
            - README.md
         
     | 
| 
      
 135 
     | 
    
         
            +
            - Rakefile
         
     | 
| 
      
 136 
     | 
    
         
            +
            - lib/generators/USAGE
         
     | 
| 
      
 137 
     | 
    
         
            +
            - lib/generators/new_google_recaptcha_generator.rb
         
     | 
| 
      
 138 
     | 
    
         
            +
            - lib/generators/templates/new_google_recaptcha.rb
         
     | 
| 
      
 139 
     | 
    
         
            +
            - lib/new_google_recaptcha.rb
         
     | 
| 
      
 140 
     | 
    
         
            +
            - lib/new_google_recaptcha/railtie.rb
         
     | 
| 
      
 141 
     | 
    
         
            +
            - lib/new_google_recaptcha/validator.rb
         
     | 
| 
      
 142 
     | 
    
         
            +
            - lib/new_google_recaptcha/version.rb
         
     | 
| 
      
 143 
     | 
    
         
            +
            - lib/new_google_recaptcha/view_ext.rb
         
     | 
| 
      
 144 
     | 
    
         
            +
            - lib/tasks/new_google_recaptcha_tasks.rake
         
     | 
| 
      
 145 
     | 
    
         
            +
            homepage: https://github.com/igorkasyanchuk/new_google_recaptcha
         
     | 
| 
      
 146 
     | 
    
         
            +
            licenses:
         
     | 
| 
      
 147 
     | 
    
         
            +
            - MIT
         
     | 
| 
      
 148 
     | 
    
         
            +
            metadata: {}
         
     | 
| 
      
 149 
     | 
    
         
            +
            post_install_message:
         
     | 
| 
      
 150 
     | 
    
         
            +
            rdoc_options: []
         
     | 
| 
      
 151 
     | 
    
         
            +
            require_paths:
         
     | 
| 
      
 152 
     | 
    
         
            +
            - lib
         
     | 
| 
      
 153 
     | 
    
         
            +
            required_ruby_version: !ruby/object:Gem::Requirement
         
     | 
| 
      
 154 
     | 
    
         
            +
              requirements:
         
     | 
| 
      
 155 
     | 
    
         
            +
              - - ">="
         
     | 
| 
      
 156 
     | 
    
         
            +
                - !ruby/object:Gem::Version
         
     | 
| 
      
 157 
     | 
    
         
            +
                  version: '0'
         
     | 
| 
      
 158 
     | 
    
         
            +
            required_rubygems_version: !ruby/object:Gem::Requirement
         
     | 
| 
      
 159 
     | 
    
         
            +
              requirements:
         
     | 
| 
      
 160 
     | 
    
         
            +
              - - ">="
         
     | 
| 
      
 161 
     | 
    
         
            +
                - !ruby/object:Gem::Version
         
     | 
| 
      
 162 
     | 
    
         
            +
                  version: '0'
         
     | 
| 
      
 163 
     | 
    
         
            +
            requirements: []
         
     | 
| 
      
 164 
     | 
    
         
            +
            rubygems_version: 3.1.4
         
     | 
| 
      
 165 
     | 
    
         
            +
            signing_key:
         
     | 
| 
      
 166 
     | 
    
         
            +
            specification_version: 4
         
     | 
| 
      
 167 
     | 
    
         
            +
            summary: Google reCAPTCHA v3 + Rails
         
     | 
| 
      
 168 
     | 
    
         
            +
            test_files: []
         
     |