invisible-captcha-0.12.2/ 0000755 0001750 0001750 00000000000 13541745065 015731 5 ustar utkarsh2102 utkarsh2102 invisible-captcha-0.12.2/spec/ 0000755 0001750 0001750 00000000000 13541745065 016663 5 ustar utkarsh2102 utkarsh2102 invisible-captcha-0.12.2/spec/spec_helper.rb 0000644 0001750 0001750 00000001411 13541745065 021476 0 ustar utkarsh2102 utkarsh2102 ENV['RAILS_ENV'] = 'test'
require File.expand_path("../dummy/config/environment.rb", __FILE__)
require 'rspec/rails'
require 'invisible_captcha'
RSpec.configure do |config|
config.disable_monkey_patching!
config.order = :random
config.expect_with :rspec
config.mock_with :rspec do |mocks|
mocks.verify_partial_doubles = true
end
end
# Rails 4.2 call `initialize` inside `recycle!`. However Ruby 2.6 doesn't allow calling `initialize` twice.
# More info: https://github.com/rails/rails/issues/34790
if RUBY_VERSION >= "2.6.0" && Rails.version < "5"
module ActionController
class TestResponse < ActionDispatch::TestResponse
def recycle!
@mon_mutex_owner_object_id = nil
@mon_mutex = nil
initialize
end
end
end
end
invisible-captcha-0.12.2/spec/invisible_captcha_spec.rb 0000644 0001750 0001750 00000003650 13541745065 023675 0 ustar utkarsh2102 utkarsh2102 RSpec.describe InvisibleCaptcha do
it 'initialize with defaults' do
InvisibleCaptcha.init!
expect(InvisibleCaptcha.sentence_for_humans).to eq('If you are a human, ignore this field')
expect(InvisibleCaptcha.timestamp_threshold).to eq(4.seconds)
expect(InvisibleCaptcha.timestamp_error_message).to eq('Sorry, that was too quick! Please resubmit.')
expect(InvisibleCaptcha.honeypots).to be_an_instance_of(Array)
expect(InvisibleCaptcha.injectable_styles).to eq(false)
end
it 'allow setup via block' do
InvisibleCaptcha.setup do |ic|
ic.sentence_for_humans = 'Another sentence'
end
expect(InvisibleCaptcha.sentence_for_humans).to eq('Another sentence')
end
it 'It uses I18n when available' do
InvisibleCaptcha.init!
I18n.available_locales = [:en, :fr]
I18n.backend.store_translations(:en,
'invisible_captcha' => {
'sentence_for_humans' => "Can't touch this",
'timestamp_error_message' => 'Fast and furious' })
I18n.backend.store_translations(:fr,
'invisible_captcha' => {
'sentence_for_humans' => 'Ne touchez pas',
'timestamp_error_message' => 'Plus doucement SVP' })
I18n.locale = :en
expect(InvisibleCaptcha.sentence_for_humans).to eq("Can't touch this")
expect(InvisibleCaptcha.timestamp_error_message).to eq('Fast and furious')
I18n.locale = :fr
expect(InvisibleCaptcha.sentence_for_humans).to eq('Ne touchez pas')
expect(InvisibleCaptcha.timestamp_error_message).to eq('Plus doucement SVP')
I18n.backend.reload!
expect(InvisibleCaptcha.sentence_for_humans).to eq('If you are a human, ignore this field')
expect(InvisibleCaptcha.timestamp_error_message).to eq('Sorry, that was too quick! Please resubmit.')
end
end
invisible-captcha-0.12.2/spec/dummy/ 0000755 0001750 0001750 00000000000 13541745065 020016 5 ustar utkarsh2102 utkarsh2102 invisible-captcha-0.12.2/spec/dummy/lib/ 0000755 0001750 0001750 00000000000 13541745065 020564 5 ustar utkarsh2102 utkarsh2102 invisible-captcha-0.12.2/spec/dummy/lib/assets/ 0000755 0001750 0001750 00000000000 13541745065 022066 5 ustar utkarsh2102 utkarsh2102 invisible-captcha-0.12.2/spec/dummy/lib/assets/.gitkeep 0000644 0001750 0001750 00000000000 13541745065 023505 0 ustar utkarsh2102 utkarsh2102 invisible-captcha-0.12.2/spec/dummy/config/ 0000755 0001750 0001750 00000000000 13541745065 021263 5 ustar utkarsh2102 utkarsh2102 invisible-captcha-0.12.2/spec/dummy/config/locales/ 0000755 0001750 0001750 00000000000 13541745065 022705 5 ustar utkarsh2102 utkarsh2102 invisible-captcha-0.12.2/spec/dummy/config/locales/en.yml 0000644 0001750 0001750 00000001172 13541745065 024033 0 ustar utkarsh2102 utkarsh2102 # Files in the config/locales directory are used for internationalization
# and are automatically loaded by Rails. If you want to use locales other
# than English, add the necessary files in this directory.
#
# To use the locales, use `I18n.t`:
#
# I18n.t 'hello'
#
# In views, this is aliased to just `t`:
#
# <%= t('hello') %>
#
# To use a different locale, set it with `I18n.locale`:
#
# I18n.locale = :es
#
# This would use the information in config/locales/es.yml.
#
# To learn more, please read the Rails Internationalization guide
# available at http://guides.rubyonrails.org/i18n.html.
en:
hello: "Hello world"
invisible-captcha-0.12.2/spec/dummy/config/application.rb 0000644 0001750 0001750 00000002400 13541745065 024107 0 ustar utkarsh2102 utkarsh2102 require File.expand_path('../boot', __FILE__)
require 'action_controller/railtie'
require 'action_view/railtie'
require 'action_mailer/railtie'
require 'active_model/railtie'
require 'sprockets/railtie'
# Require the gems listed in Gemfile, including any gems
# you've limited to :test, :development, or :production.
Bundler.require(*Rails.groups)
require 'invisible_captcha'
module Dummy
class Application < Rails::Application
# Settings in config/environments/* take precedence over those specified here.
# Application configuration should go into files in config/initializers
# -- all .rb files in that directory are automatically loaded.
# Set Time.zone default to the specified zone and make Active Record auto-convert to this zone.
# Run "rake -D time" for a list of tasks for finding time zone names. Default is UTC.
# config.time_zone = 'Central Time (US & Canada)'
# The default locale is :en and all translations from config/locales/*.rb,yml are auto loaded.
# config.i18n.load_path += Dir[Rails.root.join('my', 'locales', '*.{rb,yml}').to_s]
# config.i18n.default_locale = :de
# Do not swallow errors in after_commit/after_rollback callbacks.
# config.active_record.raise_in_transactional_callbacks = true
end
end
invisible-captcha-0.12.2/spec/dummy/config/routes.rb 0000644 0001750 0001750 00000000232 13541745065 023126 0 ustar utkarsh2102 utkarsh2102 Rails.application.routes.draw do
resources :topics do
post :publish, on: :member
post :copy, on: :collection
end
root to: 'topics#new'
end
invisible-captcha-0.12.2/spec/dummy/config/initializers/ 0000755 0001750 0001750 00000000000 13541745065 023771 5 ustar utkarsh2102 utkarsh2102 invisible-captcha-0.12.2/spec/dummy/config/initializers/inflections.rb 0000644 0001750 0001750 00000001207 13541745065 026633 0 ustar utkarsh2102 utkarsh2102 # Be sure to restart your server when you modify this file.
# Add new inflection rules using the following format. Inflections
# are locale specific, and you may define rules for as many different
# locales as you wish. All of these examples are active by default:
# ActiveSupport::Inflector.inflections(:en) do |inflect|
# inflect.plural /^(ox)$/i, '\1en'
# inflect.singular /^(ox)en/i, '\1'
# inflect.irregular 'person', 'people'
# inflect.uncountable %w( fish sheep )
# end
# These inflection rules are supported but not enabled by default:
# ActiveSupport::Inflector.inflections(:en) do |inflect|
# inflect.acronym 'RESTful'
# end
invisible-captcha-0.12.2/spec/dummy/config/initializers/wrap_parameters.rb 0000644 0001750 0001750 00000001005 13541745065 027506 0 ustar utkarsh2102 utkarsh2102 # Be sure to restart your server when you modify this file.
# This file contains settings for ActionController::ParamsWrapper which
# is enabled by default.
# Enable parameter wrapping for JSON. You can disable this by setting :format to an empty array.
ActiveSupport.on_load(:action_controller) do
wrap_parameters format: [:json] if respond_to?(:wrap_parameters)
end
# To enable root element in JSON for ActiveRecord objects.
# ActiveSupport.on_load(:active_record) do
# self.include_root_in_json = true
# end
invisible-captcha-0.12.2/spec/dummy/config/initializers/backtrace_silencers.rb 0000644 0001750 0001750 00000000624 13541745065 030306 0 ustar utkarsh2102 utkarsh2102 # Be sure to restart your server when you modify this file.
# You can add backtrace silencers for libraries that you're using but don't wish to see in your backtraces.
# Rails.backtrace_cleaner.add_silencer { |line| line =~ /my_noisy_library/ }
# You can also remove all the silencers if you're trying to debug a problem that might stem from framework code.
# Rails.backtrace_cleaner.remove_silencers!
invisible-captcha-0.12.2/spec/dummy/config/initializers/secret_token.rb 0000644 0001750 0001750 00000000760 13541745065 027006 0 ustar utkarsh2102 utkarsh2102 # Be sure to restart your server when you modify this file.
# Your secret key for verifying the integrity of signed cookies.
# If you change this key, all old signed cookies will become invalid!
# Make sure the secret is at least 30 characters and all random,
# no regular words or you'll be exposed to dictionary attacks.
Dummy::Application.config.secret_token = '99a354dfaace29d4d6daae4be11b63c13799e60ddff44a5880b12bf2e551de5daef2688495da1475131b5b0a85e57c4303a6b72834edc8a1b51a8c94d9949d59'
invisible-captcha-0.12.2/spec/dummy/config/initializers/cookies_serializer.rb 0000644 0001750 0001750 00000000204 13541745065 030177 0 ustar utkarsh2102 utkarsh2102 # Be sure to restart your server when you modify this file.
Rails.application.config.action_dispatch.cookies_serializer = :marshal
invisible-captcha-0.12.2/spec/dummy/config/initializers/mime_types.rb 0000644 0001750 0001750 00000000234 13541745065 026470 0 ustar utkarsh2102 utkarsh2102 # Be sure to restart your server when you modify this file.
# Add new mime types for use in respond_to blocks:
# Mime::Type.register "text/richtext", :rtf
invisible-captcha-0.12.2/spec/dummy/config/initializers/session_store.rb 0000644 0001750 0001750 00000000211 13541745065 027207 0 ustar utkarsh2102 utkarsh2102 # Be sure to restart your server when you modify this file.
Rails.application.config.session_store :cookie_store, key: '_dummy_session'
invisible-captcha-0.12.2/spec/dummy/config/initializers/filter_parameter_logging.rb 0000644 0001750 0001750 00000000302 13541745065 031344 0 ustar utkarsh2102 utkarsh2102 # Be sure to restart your server when you modify this file.
# Configure sensitive parameters which will be filtered from the log file.
Rails.application.config.filter_parameters += [:password]
invisible-captcha-0.12.2/spec/dummy/config/environments/ 0000755 0001750 0001750 00000000000 13541745065 024012 5 ustar utkarsh2102 utkarsh2102 invisible-captcha-0.12.2/spec/dummy/config/environments/production.rb 0000644 0001750 0001750 00000006772 13541745065 026541 0 ustar utkarsh2102 utkarsh2102 Rails.application.configure do
# Settings specified here will take precedence over those in config/application.rb.
# Code is not reloaded between requests.
config.cache_classes = true
# Eager load code on boot. This eager loads most of Rails and
# your application in memory, allowing both threaded web servers
# and those relying on copy on write to perform better.
# Rake tasks automatically ignore this option for performance.
config.eager_load = true
# Full error reports are disabled and caching is turned on.
config.consider_all_requests_local = false
config.action_controller.perform_caching = true
# Disable serving static files from the `/public` folder by default since
# Apache or NGINX already handles this.
config.public_file_server.enabled = ENV['RAILS_SERVE_STATIC_FILES'].present?
# Compress JavaScripts and CSS.
config.assets.js_compressor = :uglifier
# config.assets.css_compressor = :sass
# Do not fallback to assets pipeline if a precompiled asset is missed.
config.assets.compile = false
# `config.assets.precompile` and `config.assets.version` have moved to config/initializers/assets.rb
# Enable serving of images, stylesheets, and JavaScripts from an asset server.
# config.action_controller.asset_host = 'http://assets.example.com'
# Specifies the header that your server uses for sending files.
# config.action_dispatch.x_sendfile_header = 'X-Sendfile' # for Apache
# config.action_dispatch.x_sendfile_header = 'X-Accel-Redirect' # for NGINX
# Mount Action Cable outside main process or domain
# config.action_cable.mount_path = nil
# config.action_cable.url = 'wss://example.com/cable'
# config.action_cable.allowed_request_origins = [ 'http://example.com', /http:\/\/example.*/ ]
# Force all access to the app over SSL, use Strict-Transport-Security, and use secure cookies.
# config.force_ssl = true
# Use the lowest log level to ensure availability of diagnostic information
# when problems arise.
config.log_level = :debug
# Prepend all log lines with the following tags.
config.log_tags = [ :request_id ]
# Use a different cache store in production.
# config.cache_store = :mem_cache_store
# Use a real queuing backend for Active Job (and separate queues per environment)
# config.active_job.queue_adapter = :resque
# config.active_job.queue_name_prefix = "dummy_#{Rails.env}"
config.action_mailer.perform_caching = false
# Ignore bad email addresses and do not raise email delivery errors.
# Set this to true and configure the email server for immediate delivery to raise delivery errors.
# config.action_mailer.raise_delivery_errors = false
# Enable locale fallbacks for I18n (makes lookups for any locale fall back to
# the I18n.default_locale when a translation cannot be found).
config.i18n.fallbacks = true
# Send deprecation notices to registered listeners.
config.active_support.deprecation = :notify
# Use default logging formatter so that PID and timestamp are not suppressed.
config.log_formatter = ::Logger::Formatter.new
# Use a different logger for distributed setups.
# require 'syslog/logger'
# config.logger = ActiveSupport::TaggedLogging.new(Syslog::Logger.new 'app-name')
if ENV["RAILS_LOG_TO_STDOUT"].present?
logger = ActiveSupport::Logger.new(STDOUT)
logger.formatter = config.log_formatter
config.logger = ActiveSupport::TaggedLogging.new(logger)
end
# Do not dump schema after migrations.
config.active_record.dump_schema_after_migration = false
end
invisible-captcha-0.12.2/spec/dummy/config/environments/test.rb 0000644 0001750 0001750 00000003352 13541745065 025321 0 ustar utkarsh2102 utkarsh2102 Dummy::Application.configure do
# Settings specified here will take precedence over those in config/application.rb.
# The test environment is used exclusively to run your application's
# test suite. You never need to work with it otherwise. Remember that
# your test database is "scratch space" for the test suite and is wiped
# and recreated between test runs. Don't rely on the data there!
config.cache_classes = true
# Do not eager load code on boot. This avoids loading your whole application
# just for the purpose of running a single test. If you are using a tool that
# preloads Rails for running tests, you may have to set it to true.
config.eager_load = false
# Disable serving static files from the `/public` folder by default since
# Apache or NGINX already handles this.
if Rails.version >= "5.0.0"
config.public_file_server.enabled = true
config.public_file_server.headers = {'Cache-Control' => 'public, max-age=3600'}
else
config.serve_static_files = true
config.static_cache_control = "public, max-age=3600"
end
# Show full error reports and disable caching.
config.consider_all_requests_local = true
config.action_controller.perform_caching = false
# Raise exceptions instead of rendering exception templates.
config.action_dispatch.show_exceptions = false
# Disable request forgery protection in test environment.
config.action_controller.allow_forgery_protection = false
# Tell Action Mailer not to deliver emails to the real world.
# The :test delivery method accumulates sent emails in the
# ActionMailer::Base.deliveries array.
config.action_mailer.delivery_method = :test
# Print deprecation notices to the stderr.
config.active_support.deprecation = :stderr
end invisible-captcha-0.12.2/spec/dummy/config/environments/development.rb 0000644 0001750 0001750 00000003170 13541745065 026662 0 ustar utkarsh2102 utkarsh2102 Dummy::Application.configure do
# Settings specified here will take precedence over those in config/application.rb.
# In the development environment your application's code is reloaded on
# every request. This slows down response time but is perfect for development
# since you don't have to restart the web server when you make code changes.
config.cache_classes = false
# Do not eager load code on boot.
config.eager_load = false
# Show full error reports and disable caching.
config.consider_all_requests_local = true
config.action_controller.perform_caching = false
# Don't care if the mailer can't send.
config.action_mailer.raise_delivery_errors = false
# Print deprecation notices to the Rails logger.
config.active_support.deprecation = :log
# Raise an error on page load if there are pending migrations.
# config.active_record.migration_error = :page_load
# Debug mode disables concatenation and preprocessing of assets.
# This option may cause significant delays in view rendering with a large
# number of complex assets.
# config.assets.debug = true
# Asset digests allow you to set far-future HTTP expiration dates on all assets,
# yet still be able to expire them through the digest params.
# config.assets.digest = true
# quiet assets
config.assets.quiet = true
# Adds additional error checking when serving assets at runtime.
# Checks for improperly declared sprockets dependencies.
# Raises helpful error messages.
# config.assets.raise_runtime_errors = true
# Raises error for missing translations
# config.action_view.raise_on_missing_translations = true
end
invisible-captcha-0.12.2/spec/dummy/config/boot.rb 0000644 0001750 0001750 00000000200 13541745065 022543 0 ustar utkarsh2102 utkarsh2102 ENV['BUNDLE_GEMFILE'] ||= File.expand_path('../Gemfile', __dir__)
require 'bundler/setup' # Set up gems listed in the Gemfile.
invisible-captcha-0.12.2/spec/dummy/config/secrets.yml 0000644 0001750 0001750 00000001704 13541745065 023460 0 ustar utkarsh2102 utkarsh2102 # Be sure to restart your server when you modify this file.
# Your secret key is used for verifying the integrity of signed cookies.
# If you change this key, all old signed cookies will become invalid!
# Make sure the secret is at least 30 characters and all random,
# no regular words or you'll be exposed to dictionary attacks.
# You can use `rake secret` to generate a secure secret key.
# Make sure the secrets in this file are kept private
# if you're sharing your code publicly.
development:
secret_key_base: d55ed9a6ec6fc0b93d2404994c8632220ab5835d77ccbd52760c6fc4b9e0c83f87d78d9c2b66d366a698933feeac81efc445b29bad22c9f267ebdadbc5aebbd4
test:
secret_key_base: 5df5772ea2c76236d1444a2e7a491c9f99f9bc96770b6b52e995555ea7a70b2bd3a3d0a45bbe7d32bf1a0eb450db7e32a838e6aa17c494b464ff381bb4bf9910
# Do not keep production secrets in the repository,
# instead read values from the environment.
production:
secret_key_base: <%= ENV["SECRET_KEY_BASE"] %>
invisible-captcha-0.12.2/spec/dummy/config/environment.rb 0000644 0001750 0001750 00000000200 13541745065 024144 0 ustar utkarsh2102 utkarsh2102 # Load the Rails application.
require_relative 'application'
# Initialize the Rails application.
Rails.application.initialize!
invisible-captcha-0.12.2/spec/dummy/Rakefile 0000644 0001750 0001750 00000000416 13541745065 021464 0 ustar utkarsh2102 utkarsh2102 #!/usr/bin/env rake
# Add your own tasks in files placed in lib/tasks ending in .rake,
# for example lib/tasks/capistrano.rake, and they will automatically be available to Rake.
require File.expand_path('../config/application', __FILE__)
Dummy::Application.load_tasks
invisible-captcha-0.12.2/spec/dummy/app/ 0000755 0001750 0001750 00000000000 13541745065 020576 5 ustar utkarsh2102 utkarsh2102 invisible-captcha-0.12.2/spec/dummy/app/controllers/ 0000755 0001750 0001750 00000000000 13541745065 023144 5 ustar utkarsh2102 utkarsh2102 invisible-captcha-0.12.2/spec/dummy/app/controllers/application_controller.rb 0000644 0001750 0001750 00000000120 13541745065 030230 0 ustar utkarsh2102 utkarsh2102 class ApplicationController < ActionController::Base
protect_from_forgery
end
invisible-captcha-0.12.2/spec/dummy/app/controllers/topics_controller.rb 0000644 0001750 0001750 00000002203 13541745065 027232 0 ustar utkarsh2102 utkarsh2102 class TopicsController < ApplicationController
invisible_captcha honeypot: :subtitle, only: :create
invisible_captcha honeypot: :subtitle, only: :update,
on_spam: :custom_callback,
on_timestamp_spam: :custom_timestamp_callback
invisible_captcha honeypot: :subtitle, only: :publish, timestamp_threshold: 2
invisible_captcha honeypot: :subtitle, only: :copy, timestamp_enabled: false
def index
redirect_to new_topic_path
end
def new
@topic = Topic.new
end
def create
@topic = Topic.new(params[:topic])
if @topic.valid?
redirect_to new_topic_path(context: params[:context]), notice: 'Topic valid!'
else
render action: 'new'
end
end
def update
end
def publish
redirect_to new_topic_path
end
def copy
@topic = Topic.new(params[:topic])
if @topic.valid?
redirect_to new_topic_path(context: params[:context]), notice: 'Success!'
else
render action: 'new'
end
end
private
def custom_callback
redirect_to new_topic_path
end
def custom_timestamp_callback
head(204)
end
end
invisible-captcha-0.12.2/spec/dummy/app/models/ 0000755 0001750 0001750 00000000000 13541745065 022061 5 ustar utkarsh2102 utkarsh2102 invisible-captcha-0.12.2/spec/dummy/app/models/topic.rb 0000644 0001750 0001750 00000000631 13541745065 023524 0 ustar utkarsh2102 utkarsh2102 class Topic
include ActiveModel::Validations
include ActiveModel::Conversion
attr_accessor :title, :author, :body, :subtitle
validates :title, length: { minimum: 5 }
validates :author, presence: true
validates :body, length: { minimum: 10 }
def initialize(attributes = {})
attributes.each do |name, value|
send("#{name}=", value)
end
end
def persisted?
false
end
end
invisible-captcha-0.12.2/spec/dummy/app/mailers/ 0000755 0001750 0001750 00000000000 13541745065 022232 5 ustar utkarsh2102 utkarsh2102 invisible-captcha-0.12.2/spec/dummy/app/mailers/.gitkeep 0000644 0001750 0001750 00000000000 13541745065 023651 0 ustar utkarsh2102 utkarsh2102 invisible-captcha-0.12.2/spec/dummy/app/helpers/ 0000755 0001750 0001750 00000000000 13541745065 022240 5 ustar utkarsh2102 utkarsh2102 invisible-captcha-0.12.2/spec/dummy/app/helpers/application_helper.rb 0000644 0001750 0001750 00000000035 13541745065 026425 0 ustar utkarsh2102 utkarsh2102 module ApplicationHelper
end
invisible-captcha-0.12.2/spec/dummy/app/views/ 0000755 0001750 0001750 00000000000 13541745065 021733 5 ustar utkarsh2102 utkarsh2102 invisible-captcha-0.12.2/spec/dummy/app/views/layouts/ 0000755 0001750 0001750 00000000000 13541745065 023433 5 ustar utkarsh2102 utkarsh2102 invisible-captcha-0.12.2/spec/dummy/app/views/layouts/application.html.erb 0000644 0001750 0001750 00000001341 13541745065 027372 0 ustar utkarsh2102 utkarsh2102
<% end %>
invisible-captcha-0.12.2/spec/dummy/app/assets/ 0000755 0001750 0001750 00000000000 13541745065 022100 5 ustar utkarsh2102 utkarsh2102 invisible-captcha-0.12.2/spec/dummy/app/assets/stylesheets/ 0000755 0001750 0001750 00000000000 13541745065 024454 5 ustar utkarsh2102 utkarsh2102 invisible-captcha-0.12.2/spec/dummy/app/assets/stylesheets/application.css 0000644 0001750 0001750 00000000547 13541745065 027477 0 ustar utkarsh2102 utkarsh2102 body {
font-family: Arial, Helvetica, sans-serif;
background-color: #ccc;
margin: 2em;
}
h1 {
border-bottom: 3px solid;
}
input,
textarea {
border: 0;
margin-bottom: 1.5em;
}
input {
height: 2em;
}
button {
background-color: #f0f0f0;
border-radius: 0.25em;
height: 3em;
width: 10em;
font-size: 1em;
}
.errors {
color: darkred;
} invisible-captcha-0.12.2/spec/dummy/app/assets/javascripts/ 0000755 0001750 0001750 00000000000 13541745065 024431 5 ustar utkarsh2102 utkarsh2102 invisible-captcha-0.12.2/spec/dummy/app/assets/javascripts/application.js 0000644 0001750 0001750 00000000052 13541745065 027267 0 ustar utkarsh2102 utkarsh2102 console.log('Hi from Invisible Captcha!'); invisible-captcha-0.12.2/spec/dummy/bin/ 0000755 0001750 0001750 00000000000 13541745065 020566 5 ustar utkarsh2102 utkarsh2102 invisible-captcha-0.12.2/spec/dummy/bin/rails 0000755 0001750 0001750 00000000221 13541745065 021621 0 ustar utkarsh2102 utkarsh2102 #!/usr/bin/env ruby
APP_PATH = File.expand_path('../../config/application', __FILE__)
require_relative '../config/boot'
require 'rails/commands'
invisible-captcha-0.12.2/spec/dummy/bin/rake 0000755 0001750 0001750 00000000132 13541745065 021432 0 ustar utkarsh2102 utkarsh2102 #!/usr/bin/env ruby
require_relative '../config/boot'
require 'rake'
Rake.application.run
invisible-captcha-0.12.2/spec/dummy/bin/bundle 0000755 0001750 0001750 00000000201 13541745065 021756 0 ustar utkarsh2102 utkarsh2102 #!/usr/bin/env ruby
ENV['BUNDLE_GEMFILE'] ||= File.expand_path('../../Gemfile', __FILE__)
load Gem.bin_path('bundler', 'bundle')
invisible-captcha-0.12.2/spec/dummy/bin/setup 0000755 0001750 0001750 00000001445 13541745065 021660 0 ustar utkarsh2102 utkarsh2102 #!/usr/bin/env ruby
require 'pathname'
# path to your application root.
APP_ROOT = Pathname.new File.expand_path('../../', __FILE__)
Dir.chdir APP_ROOT do
# This script is a starting point to setup your application.
# Add necessary setup steps to this file:
puts "== Installing dependencies =="
system "gem install bundler --conservative"
system "bundle check || bundle install"
# puts "\n== Copying sample files =="
# unless File.exist?("config/database.yml")
# system "cp config/database.yml.sample config/database.yml"
# end
puts "\n== Preparing database =="
system "bin/rake db:setup"
puts "\n== Removing old logs and tempfiles =="
system "rm -f log/*"
system "rm -rf tmp/cache"
puts "\n== Restarting application server =="
system "touch tmp/restart.txt"
end
invisible-captcha-0.12.2/spec/dummy/README.md 0000644 0001750 0001750 00000000520 13541745065 021272 0 ustar utkarsh2102 utkarsh2102 # Dummy App
Dummy Rails Application to test `Invisible Captcha`.
It's also used as a demo application to show `Invisible Captcha` in action. You can run the app by using the following command, from the root of the project:
> bundle exec rake web
[« Back to Docs](https://github.com/markets/invisible_captcha#invisible-captcha)
invisible-captcha-0.12.2/spec/dummy/public/ 0000755 0001750 0001750 00000000000 13541745065 021274 5 ustar utkarsh2102 utkarsh2102 invisible-captcha-0.12.2/spec/dummy/public/422.html 0000644 0001750 0001750 00000001307 13541745065 022472 0 ustar utkarsh2102 utkarsh2102
The change you wanted was rejected (422)
The change you wanted was rejected.
Maybe you tried to change something you didn't have access to.
invisible-captcha-0.12.2/spec/dummy/public/500.html 0000644 0001750 0001750 00000001203 13541745065 022462 0 ustar utkarsh2102 utkarsh2102
We're sorry, but something went wrong (500)
We're sorry, but something went wrong.
invisible-captcha-0.12.2/spec/dummy/public/404.html 0000644 0001750 0001750 00000001330 13541745065 022466 0 ustar utkarsh2102 utkarsh2102
The page you were looking for doesn't exist (404)
The page you were looking for doesn't exist.
You may have mistyped the address or the page may have moved.
invisible-captcha-0.12.2/spec/dummy/public/favicon.ico 0000644 0001750 0001750 00000000000 13541745065 023403 0 ustar utkarsh2102 utkarsh2102 invisible-captcha-0.12.2/spec/dummy/config.ru 0000644 0001750 0001750 00000000233 13541745065 021631 0 ustar utkarsh2102 utkarsh2102 # This file is used by Rack-based servers to start the application.
require ::File.expand_path('../config/environment', __FILE__)
run Dummy::Application
invisible-captcha-0.12.2/spec/dummy/log/ 0000755 0001750 0001750 00000000000 13541745065 020577 5 ustar utkarsh2102 utkarsh2102 invisible-captcha-0.12.2/spec/dummy/log/.gitkeep 0000644 0001750 0001750 00000000000 13541745065 022216 0 ustar utkarsh2102 utkarsh2102 invisible-captcha-0.12.2/spec/controllers_spec.rb 0000644 0001750 0001750 00000010223 13541745065 022566 0 ustar utkarsh2102 utkarsh2102 RSpec.describe InvisibleCaptcha::ControllerExt, type: :controller do
render_views
def switchable_post(action, params = {})
if ::Rails::VERSION::STRING > '5'
post action, params: params
else
post action, params
end
end
def switchable_put(action, params = {})
if ::Rails::VERSION::STRING > '5'
put action, params: params
else
put action, params
end
end
before(:each) do
@controller = TopicsController.new
request.env['HTTP_REFERER'] = 'http://test.host/topics'
InvisibleCaptcha.init!
InvisibleCaptcha.timestamp_threshold = 1
end
context 'without invisible_captcha_timestamp in session' do
it 'fails like if it was submitted too fast' do
switchable_post :create, topic: { title: 'foo' }
expect(response).to redirect_to 'http://test.host/topics'
expect(flash[:error]).to eq(InvisibleCaptcha.timestamp_error_message)
end
it 'passes if disabled at action level' do
switchable_post :copy, topic: { title: 'foo' }
expect(flash[:error]).not_to be_present
expect(response.body).to be_present
end
it 'passes if disabled at app level' do
InvisibleCaptcha.timestamp_enabled = false
switchable_post :create, topic: { title: 'foo' }
expect(flash[:error]).not_to be_present
expect(response.body).to be_present
end
end
context 'submission timestamp_threshold' do
before(:each) do
session[:invisible_captcha_timestamp] = Time.zone.now.iso8601
end
it 'fails if submission before timestamp_threshold' do
switchable_post :create, topic: { title: 'foo' }
expect(response).to redirect_to 'http://test.host/topics'
expect(flash[:error]).to eq(InvisibleCaptcha.timestamp_error_message)
# Make sure session is cleared
expect(session[:invisible_captcha_timestamp]).to be_nil
end
it 'allows a custom on_timestamp_spam callback' do
switchable_put :update, id: 1, topic: { title: 'bar' }
expect(response.status).to eq(204)
end
it 'allows a new timestamp to be set in the on_timestamp_spam callback' do
@controller.singleton_class.class_eval do
def custom_timestamp_callback
session[:invisible_captcha_timestamp] = 2.seconds.from_now(Time.zone.now).iso8601
head(204)
end
end
expect { switchable_put :update, id: 1, topic: { title: 'bar' } }
.to change { session[:invisible_captcha_timestamp] }
.to be_present
end
context 'successful submissions' do
it 'passes if submission on or after timestamp_threshold' do
sleep InvisibleCaptcha.timestamp_threshold
switchable_post :create, topic: {
title: 'foobar',
author: 'author',
body: 'body that passes validation'
}
expect(flash[:error]).not_to be_present
expect(response.body).to be_present
# Make sure session is cleared
expect(session[:invisible_captcha_timestamp]).to be_nil
end
it 'allow to set a custom timestamp_threshold per action' do
sleep 2 # custom threshold
switchable_post :publish, id: 1
expect(flash[:error]).not_to be_present
expect(response.body).to be_present
end
end
end
context 'honeypot attribute' do
before(:each) do
session[:invisible_captcha_timestamp] = Time.zone.now.iso8601
# Wait for valid submission
sleep InvisibleCaptcha.timestamp_threshold
end
it 'fails with spam' do
switchable_post :create, topic: { subtitle: 'foo' }
expect(response.body).to be_blank
end
it 'passes with no spam' do
switchable_post :create, topic: { title: 'foo' }
expect(response.body).to be_present
end
it 'allow a custom on_spam callback' do
switchable_put :update, id: 1, topic: { subtitle: 'foo' }
expect(response.body).to redirect_to(new_topic_path)
end
it 'honeypot is removed from params if you use a custom honeypot' do
switchable_post :create, topic: { title: 'foo', subtitle: '' }
expect(flash[:error]).not_to be_present
expect(@controller.params[:topic].key?(:subtitle)).to eq(false)
end
end
end
invisible-captcha-0.12.2/spec/view_helpers_spec.rb 0000644 0001750 0001750 00000004677 13541745065 022734 0 ustar utkarsh2102 utkarsh2102 RSpec.describe InvisibleCaptcha::ViewHelpers, type: :helper do
before(:each) do
allow(Time.zone).to receive(:now).and_return(Time.zone.parse('Feb 19 1986'))
allow(InvisibleCaptcha).to receive(:css_strategy).and_return("display:none;")
# to test content_for and provide
@view_flow = ActionView::OutputFlow.new
InvisibleCaptcha.init!
end
it 'with no arguments' do
InvisibleCaptcha.honeypots = [:foo_id]
expect(invisible_captcha).to match(/name="foo_id"/)
end
it 'with specific honeypot' do
expect(invisible_captcha(:subtitle)).to match(/name="subtitle"/)
end
it 'with specific honeypot and scope' do
expect(invisible_captcha(:subtitle, :topic)).to match(/name="topic\[subtitle\]"/)
end
it 'with custom html options' do
expect(invisible_captcha(:subtitle, :topic, { class: 'foo_class' })).to match(/class="foo_class"/)
end
it 'generated html + styles' do
InvisibleCaptcha.honeypots = [:foo_id]
output = invisible_captcha.gsub("\"", "'")
regexp = %r{
}
expect(output).to match(regexp)
end
context "honeypot visibilty" do
it 'visible from defaults' do
InvisibleCaptcha.visual_honeypots = true
expect(invisible_captcha).not_to match(/display:none/)
end
it 'visible from given instance (default override)' do
expect(invisible_captcha(visual_honeypots: true)).not_to match(/display:none/)
end
it 'invisible from given instance (default override)' do
InvisibleCaptcha.visual_honeypots = true
expect(invisible_captcha(visual_honeypots: false)).to match(/display:none/)
end
end
it 'should set spam timestamp' do
invisible_captcha
expect(session[:invisible_captcha_timestamp]).to eq(Time.zone.now.iso8601)
end
context 'injectable_styles option' do
it 'by default, render styles along with the honeypot' do
expect(invisible_captcha).to match(/display:none/)
expect(@view_flow.content[:invisible_captcha_styles]).to be_blank
end
it 'if injectable_styles is set, do not append styles inline' do
InvisibleCaptcha.injectable_styles = true
expect(invisible_captcha).not_to match(/display:none;/)
expect(@view_flow.content[:invisible_captcha_styles]).to match(/display:none;/)
end
end
end
invisible-captcha-0.12.2/gemfiles/ 0000755 0001750 0001750 00000000000 13541745065 017524 5 ustar utkarsh2102 utkarsh2102 invisible-captcha-0.12.2/gemfiles/rails_3.2.gemfile 0000644 0001750 0001750 00000000164 13541745065 022553 0 ustar utkarsh2102 utkarsh2102 # This file was generated by Appraisal
source "https://rubygems.org"
gem "rails", "~> 3.2.0"
gemspec path: "../"
invisible-captcha-0.12.2/gemfiles/rails_5.1.gemfile 0000644 0001750 0001750 00000000164 13541745065 022554 0 ustar utkarsh2102 utkarsh2102 # This file was generated by Appraisal
source "https://rubygems.org"
gem "rails", "~> 5.1.0"
gemspec path: "../"
invisible-captcha-0.12.2/gemfiles/rails_5.2.gemfile 0000644 0001750 0001750 00000000164 13541745065 022555 0 ustar utkarsh2102 utkarsh2102 # This file was generated by Appraisal
source "https://rubygems.org"
gem "rails", "~> 5.2.0"
gemspec path: "../"
invisible-captcha-0.12.2/gemfiles/rails_5.0.gemfile 0000644 0001750 0001750 00000000164 13541745065 022553 0 ustar utkarsh2102 utkarsh2102 # This file was generated by Appraisal
source "https://rubygems.org"
gem "rails", "~> 5.0.0"
gemspec path: "../"
invisible-captcha-0.12.2/gemfiles/rails_4.2.gemfile 0000644 0001750 0001750 00000000164 13541745065 022554 0 ustar utkarsh2102 utkarsh2102 # This file was generated by Appraisal
source "https://rubygems.org"
gem "rails", "~> 4.2.0"
gemspec path: "../"
invisible-captcha-0.12.2/gemfiles/rails_6.0.gemfile 0000644 0001750 0001750 00000000164 13541745065 022554 0 ustar utkarsh2102 utkarsh2102 # This file was generated by Appraisal
source "https://rubygems.org"
gem "rails", "~> 6.0.0"
gemspec path: "../"
invisible-captcha-0.12.2/Appraisals 0000644 0001750 0001750 00000000511 13541745065 017750 0 ustar utkarsh2102 utkarsh2102 appraise "rails-6.0" do
gem "rails", "~> 6.0.0"
end
appraise "rails-5.2" do
gem "rails", "~> 5.2.0"
end
appraise "rails-5.1" do
gem "rails", "~> 5.1.0"
end
appraise "rails-5.0" do
gem "rails", "~> 5.0.0"
end
appraise "rails-4.2" do
gem "rails", "~> 4.2.0"
end
appraise "rails-3.2" do
gem "rails", "~> 3.2.0"
end
invisible-captcha-0.12.2/.rspec 0000644 0001750 0001750 00000000065 13541745065 017047 0 ustar utkarsh2102 utkarsh2102 --format documentation
--color
--require spec_helper
invisible-captcha-0.12.2/LICENSE 0000644 0001750 0001750 00000002046 13541745065 016740 0 ustar utkarsh2102 utkarsh2102 Copyright 2012-2017 Marc Anguera Insa
Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
"Software"), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sublicense, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so, subject to
the following conditions:
The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
invisible-captcha-0.12.2/lib/ 0000755 0001750 0001750 00000000000 13541745065 016477 5 ustar utkarsh2102 utkarsh2102 invisible-captcha-0.12.2/lib/invisible_captcha/ 0000755 0001750 0001750 00000000000 13541745065 022146 5 ustar utkarsh2102 utkarsh2102 invisible-captcha-0.12.2/lib/invisible_captcha/form_helpers.rb 0000644 0001750 0001750 00000000267 13541745065 025165 0 ustar utkarsh2102 utkarsh2102 module InvisibleCaptcha
module FormHelpers
def invisible_captcha(honeypot, options = {})
@template.invisible_captcha(honeypot, self.object_name, options)
end
end
end invisible-captcha-0.12.2/lib/invisible_captcha/view_helpers.rb 0000644 0001750 0001750 00000004552 13541745065 025175 0 ustar utkarsh2102 utkarsh2102 module InvisibleCaptcha
module ViewHelpers
# Builds the honeypot html
#
# @param honeypot [Symbol] name of honeypot, ie: subtitle => input name: subtitle
# @param scope [Symbol] name of honeypot scope, ie: topic => input name: topic[subtitle]
# @param options [Hash] html_options for input and invisible_captcha options
#
# @return [String] the generated html
def invisible_captcha(honeypot = nil, scope = nil, options = {})
if InvisibleCaptcha.timestamp_enabled
session[:invisible_captcha_timestamp] = Time.zone.now.iso8601
end
build_invisible_captcha(honeypot, scope, options)
end
def invisible_captcha_styles
if content_for?(:invisible_captcha_styles)
content_for(:invisible_captcha_styles)
end
end
private
def build_invisible_captcha(honeypot = nil, scope = nil, options = {})
if honeypot.is_a?(Hash)
options = honeypot
honeypot = nil
end
honeypot = honeypot ? honeypot.to_s : InvisibleCaptcha.get_honeypot
label = options.delete(:sentence_for_humans) || InvisibleCaptcha.sentence_for_humans
css_class = "#{honeypot}_#{Time.zone.now.to_i}"
styles = visibility_css(css_class, options)
provide(:invisible_captcha_styles) do
styles
end if InvisibleCaptcha.injectable_styles
content_tag(:div, class: css_class) do
concat styles unless InvisibleCaptcha.injectable_styles
concat label_tag(build_label_name(honeypot, scope), label)
concat text_field_tag(build_input_name(honeypot, scope), nil, default_honeypot_options.merge(options))
end
end
def visibility_css(css_class, options)
visible = if options.key?(:visual_honeypots)
options.delete(:visual_honeypots)
else
InvisibleCaptcha.visual_honeypots
end
return if visible
content_tag(:style, media: 'screen') do
".#{css_class} {#{InvisibleCaptcha.css_strategy}}"
end
end
def build_label_name(honeypot, scope = nil)
if scope.present?
"#{scope}_#{honeypot}"
else
honeypot
end
end
def build_input_name(honeypot, scope = nil)
if scope.present?
"#{scope}[#{honeypot}]"
else
honeypot
end
end
def default_honeypot_options
{ autocomplete: 'off', tabindex: -1 }
end
end
end
invisible-captcha-0.12.2/lib/invisible_captcha/version.rb 0000644 0001750 0001750 00000000061 13541745065 024155 0 ustar utkarsh2102 utkarsh2102 module InvisibleCaptcha
VERSION = "0.12.2"
end
invisible-captcha-0.12.2/lib/invisible_captcha/railtie.rb 0000644 0001750 0001750 00000000752 13541745065 024130 0 ustar utkarsh2102 utkarsh2102 module InvisibleCaptcha
class Railtie < Rails::Railtie
initializer 'invisible_captcha.rails_integration' do
ActiveSupport.on_load(:action_controller) do
include InvisibleCaptcha::ControllerExt
extend InvisibleCaptcha::ControllerExt::ClassMethods
end
ActiveSupport.on_load(:action_view) do
include InvisibleCaptcha::ViewHelpers
ActionView::Helpers::FormBuilder.send :include, InvisibleCaptcha::FormHelpers
end
end
end
end
invisible-captcha-0.12.2/lib/invisible_captcha/controller_ext.rb 0000644 0001750 0001750 00000006305 13541745065 025542 0 ustar utkarsh2102 utkarsh2102 module InvisibleCaptcha
module ControllerExt
module ClassMethods
def invisible_captcha(options = {})
if respond_to?(:before_action)
before_action(options) do
detect_spam(options)
end
else
before_filter(options) do
detect_spam(options)
end
end
end
end
private
def detect_spam(options = {})
if timestamp_spam?(options)
on_timestamp_spam(options)
elsif honeypot_spam?(options)
on_spam(options)
end
end
def on_timestamp_spam(options = {})
if action = options[:on_timestamp_spam]
send(action)
else
if respond_to?(:redirect_back)
redirect_back(fallback_location: root_path, flash: { error: InvisibleCaptcha.timestamp_error_message })
else
redirect_to :back, flash: { error: InvisibleCaptcha.timestamp_error_message }
end
end
end
def on_spam(options = {})
if action = options[:on_spam]
send(action)
else
head(200)
end
end
def timestamp_spam?(options = {})
enabled = if options.key?(:timestamp_enabled)
options[:timestamp_enabled]
else
InvisibleCaptcha.timestamp_enabled
end
return false unless enabled
@invisible_captcha_timestamp ||= session.delete(:invisible_captcha_timestamp)
# Consider as spam if timestamp not in session, cause that means the form was not fetched at all
unless @invisible_captcha_timestamp
warn("Invisible Captcha timestamp not found in session.")
return true
end
time_to_submit = Time.zone.now - DateTime.iso8601(@invisible_captcha_timestamp)
threshold = options[:timestamp_threshold] || InvisibleCaptcha.timestamp_threshold
# Consider as spam if form submitted too quickly
if time_to_submit < threshold
warn("Invisible Captcha timestamp threshold not reached (took #{time_to_submit.to_i}s).")
return true
end
return false
end
def honeypot_spam?(options = {})
honeypot = options[:honeypot]
scope = options[:scope] || controller_name.singularize
if honeypot
# If honeypot is defined for this controller-action, search for:
# - honeypot: params[:subtitle]
# - honeypot with scope: params[:topic][:subtitle]
if params[honeypot].present? || (params[scope] && params[scope][honeypot].present?)
warn("Invisible Captcha honeypot param '#{honeypot}' was present.")
return true
else
# No honeypot spam detected, remove honeypot from params to avoid UnpermittedParameters exceptions
params.delete(honeypot) if params.key?(honeypot)
params[scope].try(:delete, honeypot) if params.key?(scope)
end
else
InvisibleCaptcha.honeypots.each do |default_honeypot|
if params[default_honeypot].present?
warn("Invisible Captcha honeypot param '#{default_honeypot}' was present.")
return true
end
end
end
false
end
def warn(message)
logger.warn("Potential spam detected for IP #{request.remote_ip}. #{message}")
end
end
end
invisible-captcha-0.12.2/lib/invisible_captcha.rb 0000644 0001750 0001750 00000004315 13541745065 022476 0 ustar utkarsh2102 utkarsh2102 require 'invisible_captcha/version'
require 'invisible_captcha/controller_ext'
require 'invisible_captcha/view_helpers'
require 'invisible_captcha/form_helpers'
require 'invisible_captcha/railtie'
module InvisibleCaptcha
class << self
attr_writer :sentence_for_humans,
:timestamp_error_message
attr_accessor :honeypots,
:timestamp_threshold,
:timestamp_enabled,
:visual_honeypots,
:injectable_styles
def init!
# Default sentence for real users if text field was visible
self.sentence_for_humans = -> { I18n.t('invisible_captcha.sentence_for_humans', default: 'If you are a human, ignore this field') }
# Timestamp check enabled by default
self.timestamp_enabled = true
# Fastest time (in seconds) to expect a human to submit the form
self.timestamp_threshold = 4
# Default error message for validator when form submitted too quickly
self.timestamp_error_message = -> { I18n.t('invisible_captcha.timestamp_error_message', default: 'Sorry, that was too quick! Please resubmit.') }
# Make honeypots visibles
self.visual_honeypots = false
# If enabled, you should call anywhere in of your layout the following helper, to inject the honeypot styles:
# <%= invisible_captcha_styles %>
self.injectable_styles = false
end
def sentence_for_humans
call_lambda_or_return(@sentence_for_humans)
end
def timestamp_error_message
call_lambda_or_return(@timestamp_error_message)
end
def setup
yield(self) if block_given?
end
def honeypots
@honeypots ||= (1..5).map { generate_random_honeypot }
end
def generate_random_honeypot
"abcdefghijkl-mnopqrstuvwxyz".chars.sample(rand(10..20)).join
end
def get_honeypot
honeypots.sample
end
def css_strategy
[
"display:none;",
"position:absolute!important;top:-9999px;left:-9999px;",
"position:absolute!important;height:1px;width:1px;overflow:hidden;"
].sample
end
private
def call_lambda_or_return(obj)
obj.respond_to?(:call) ? obj.call : obj
end
end
end
InvisibleCaptcha.init!
invisible-captcha-0.12.2/CHANGELOG.md 0000644 0001750 0001750 00000006752 13541745065 017554 0 ustar utkarsh2102 utkarsh2102 # Changelog
All notable changes to this project will be documented in this file.
## [0.12.2]
- Allow new timestamp to be set during `on_timestamp_spam` callback (#53)
## [0.12.1]
- Clear timestamp stored in `session[:invisible_captcha_timestamp]` (#50)
- Rails 6 support
## [0.12.0]
- Honeypot input with autocomplete="off" by default (#42)
## [0.11.0]
- Improve logging (#40, #41)
- Official Rails 5.2 support
- Drop Ruby 2.1 from CI
## [0.10.0]
- New timestamp on each request to avoid stale timestamps (#24)
- Allow to inject styles manually anywhere in the layout (#27)
- Allow to change threshold per action
- Dynamic css strategy to hide the honeypot
- Remove Ruby 1.9 support
- Random default honeypots on each restart
- Allow to pass html_options to honeypot input (#28)
- Improvements on demo application and tests
- Better strong parameters interaction (#30, #33)
## [0.9.3]
- Rails 5.1 support (#29)
- Modernize CI Rubies
## [0.9.2]
- Rails 5.0 official support (#23)
- Travis CI matrix improvements
## [0.9.1]
- Add option (`timestamp_enabled`) to disable timestamp check (#22)
## [0.9.0]
- Remove model style validations (#14)
- Consider as spam if timestamp not in session (#11)
- Allow to define a different threshold per action (#8)
- Appraisals integration (#8)
- CI improvements: use new Travis infrastructure (#8)
## [0.8.2]
- Default timestamp action redirects to back (#19)
- Stores timestamps as string in session (#17)
## [0.8.1]
- Time-sensitive form submissions (#7)
- I18n integration (#13)
## [0.8.0]
- Better Rails integration with `ActiveSupport.on_load` callbacks (#5)
- Allow to override settings via the view helper (#5)
## [0.7.0]
- Revamped code base to allow more customizations (#2)
- Added basic specs (#2)
- Travis integration (#2)
- Demo app (#2)
## [0.6.5]
- Stop using Jeweler
## [0.6.4]
- Docs! (#1)
## [0.6.3]
- Internal re-naming
## [0.6.2]
- Fix gem initialization
## [0.6.0]
- Allow to configure via `InvisibleCaptcha.setup` block
## [0.5.0]
- First version of controller filters
[0.12.2]: https://github.com/markets/invisible_captcha/compare/v0.12.1...v0.12.2
[0.12.1]: https://github.com/markets/invisible_captcha/compare/v0.12.0...v0.12.1
[0.12.0]: https://github.com/markets/invisible_captcha/compare/v0.11.0...v0.12.0
[0.11.0]: https://github.com/markets/invisible_captcha/compare/v0.10.0...v0.11.0
[0.10.0]: https://github.com/markets/invisible_captcha/compare/v0.9.3...v0.10.0
[0.9.3]: https://github.com/markets/invisible_captcha/compare/v0.9.2...v0.9.3
[0.9.2]: https://github.com/markets/invisible_captcha/compare/v0.9.1...v0.9.2
[0.9.1]: https://github.com/markets/invisible_captcha/compare/v0.9.0...v0.9.1
[0.9.0]: https://github.com/markets/invisible_captcha/compare/v0.8.2...v0.9.0
[0.8.2]: https://github.com/markets/invisible_captcha/compare/v0.8.1...v0.8.2
[0.8.1]: https://github.com/markets/invisible_captcha/compare/v0.8.0...v0.8.1
[0.8.0]: https://github.com/markets/invisible_captcha/compare/v0.7.0...v0.8.0
[0.7.0]: https://github.com/markets/invisible_captcha/compare/v0.6.5...v0.7.0
[0.6.5]: https://github.com/markets/invisible_captcha/compare/v0.6.4...v0.6.5
[0.6.4]: https://github.com/markets/invisible_captcha/compare/v0.6.3...v0.6.4
[0.6.3]: https://github.com/markets/invisible_captcha/compare/v0.6.2...v0.6.3
[0.6.2]: https://github.com/markets/invisible_captcha/compare/v0.6.0...v0.6.2
[0.6.0]: https://github.com/markets/invisible_captcha/compare/v0.5.0...v0.6.0
[0.5.0]: https://github.com/markets/invisible_captcha/compare/v0.4.1...v0.5.0
invisible-captcha-0.12.2/invisible_captcha.gemspec 0000644 0001750 0001750 00000002027 13541745065 022746 0 ustar utkarsh2102 utkarsh2102 require './lib/invisible_captcha/version'
Gem::Specification.new do |spec|
spec.name = "invisible_captcha"
spec.version = InvisibleCaptcha::VERSION
spec.authors = ["Marc Anguera Insa"]
spec.email = ["srmarc.ai@gmail.com"]
spec.description = "Unobtrusive, flexible and simple spam protection for Rails applications using honeypot strategy for better user experience."
spec.summary = "Simple honeypot protection for RoR apps"
spec.homepage = "https://github.com/markets/invisible_captcha"
spec.license = "MIT"
spec.files = `git ls-files`.split($/)
spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
spec.require_paths = ["lib"]
spec.add_dependency 'rails', '>= 3.2.0'
spec.add_development_dependency 'rspec-rails', '~> 3.1'
spec.add_development_dependency 'appraisal'
spec.add_development_dependency 'test-unit', '~> 3.0'
spec.add_development_dependency 'byebug'
end
invisible-captcha-0.12.2/Rakefile 0000644 0001750 0001750 00000000532 13541745065 017376 0 ustar utkarsh2102 utkarsh2102 require "bundler/gem_tasks"
require 'rspec/core/rake_task'
RSpec::Core::RakeTask.new(:spec)
task :default => :spec
desc 'Start development Rails app'
task :web do
app_path = 'spec/dummy'
port = ENV['PORT'] || 3000
puts "Starting application in http://localhost:#{port} ... \n"
Dir.chdir(app_path)
exec("rails s -p #{port}")
end invisible-captcha-0.12.2/README.md 0000644 0001750 0001750 00000017173 13541745065 017221 0 ustar utkarsh2102 utkarsh2102 # Invisible Captcha
[](https://rubygems.org/gems/invisible_captcha)
[](https://travis-ci.org/markets/invisible_captcha)
> Simple and flexible spam protection solution for Rails applications.
Invisible Captcha provides different techniques to protect your application against spambots.
The main protection is a solution based on the `honeypot` principle, which provides a better user experience, since there is no extra steps for real users, but for the bots.
Essentially, the strategy consists on adding an input field :honey_pot: into the form that:
- shouldn't be visible by the real users
- should be left empty by the real users
- will most be filled by spam bots
It also comes with a time-sensitive :hourglass: form submission.
## Installation
Invisible Captcha is tested against Rails `>= 3.2` and Ruby `>= 2.2`.
Add this line to your Gemfile and then execute `bundle install`:
```ruby
gem 'invisible_captcha'
```
## Usage
View code:
```erb
<%= form_for(@topic) do |f| %>
<%= f.invisible_captcha :subtitle %>
<%= invisible_captcha :subtitle, :topic %>
<% end %>
```
Controller code:
```ruby
class TopicsController < ApplicationController
invisible_captcha only: [:create, :update], honeypot: :subtitle
end
```
This method will act as a `before_action` that triggers when spam is detected (honeypot field has some value). By default it responds with no content (only headers: `head(200)`). This is a good default, since the bot will surely read the response code and will think that it has achieved to submit the form properly. But, anyway, you are able to define your own callback by passing a method to the `on_spam` option:
```ruby
class TopicsController < ApplicationController
invisible_captcha only: [:create, :update], on_spam: :your_spam_callback_method
private
def your_spam_callback_method
redirect_to root_path
end
end
```
Note that is not mandatory to specify a `honeypot` attribute (nor in the view, nor in the controller). In this case, the engine will take a random field from `InvisibleCaptcha.honeypots`. So, if you're integrating it following this path, in your form:
```erb
<%= form_tag(new_contact_path) do |f| %>
<%= invisible_captcha %>
<% end %>
```
In you controller:
```
invisible_captcha only: [:new_contact]
```
## Options and customization
This section contains a description of all plugin options and customizations.
### Plugin options:
You can customize:
- `sentence_for_humans`: text for real users if input field was visible. By default, it uses I18n (see below).
- `honeypots`: collection of default honeypots. Used by the view helper, called with no args, to generate a random honeypot field name. By default, a random collection is already generated.
- `visual_honeypots`: make honeypots visible, also useful to test/debug your implementation.
- `timestamp_threshold`: fastest time (in seconds) to expect a human to submit the form (see [original article by Yoav Aner](https://blog.gingerlime.com/2012/simple-detection-of-comment-spam-in-rails/) outlining the idea). By default, 4 seconds. **NOTE:** It's recommended to deactivate the autocomplete feature to avoid false positives (`autocomplete="off"`).
- `timestamp_enabled`: option to disable the time threshold check at application level. Could be useful, for example, on some testing scenarios. By default, true.
- `timestamp_error_message`: flash error message thrown when form submitted quicker than the `timestamp_threshold` value. It uses I18n by default.
- `injectable_styles`: if enabled, you should call anywhere in your layout the following helper `<%= invisible_captcha_styles %>`. This allows you to inject styles, for example, in ``. False by default, styles are injected inline with the honeypot.
To change these defaults, add the following to an initializer (recommended `config/initializers/invisible_captcha.rb`):
```ruby
InvisibleCaptcha.setup do |config|
# config.honeypots << ['more', 'fake', 'attribute', 'names']
# config.visual_honeypots = false
# config.timestamp_threshold = 4
# config.timestamp_enabled = true
# config.injectable_styles = false
# Leave these unset if you want to use I18n (see below)
# config.sentence_for_humans = 'If you are a human, ignore this field'
# config.timestamp_error_message = 'Sorry, that was too quick! Please resubmit.'
end
```
### Controller method options:
The `invisible_captcha` method accepts some options:
- `only`: apply to given controller actions.
- `except`: exclude to given controller actions.
- `honeypot`: name of custom honeypot.
- `scope`: name of scope, ie: 'topic[subtitle]' -> 'topic' is the scope.
- `on_spam`: custom callback to be called on spam detection.
- `timestamp_enabled`: enable/disable this technique at action level.
- `on_timestamp_spam`: custom callback to be called when form submitted too quickly. The default action redirects to `:back` printing a warning in `flash[:error]`.
- `timestamp_threshold`: custom threshold per controller/action. Overrides the global value for `InvisibleCaptcha.timestamp_threshold`.
### View helpers options:
Using the view/form helper you can override some defaults for the given instance. Actually, it allows to change:
- `sentence_for_humans`
```erb
<%= form_for(@topic) do |f| %>
<%= f.invisible_captcha :subtitle, sentence_for_humans: "hey! leave this input empty!" %>
<% end %>
```
- `visual_honeypots`
```erb
<%= form_for(@topic) do |f| %>
<%= f.invisible_captcha :subtitle, visual_honeypots: true %>
<% end %>
```
You can also pass html options to the input:
```erb
<%= invisible_captcha :subtitle, :topic, id: "your_id", class: "your_class" %>
```
### I18n
`invisible_captcha` tries to use I18n when it's available by default. The keys it looks for are the following:
```yaml
en:
invisible_captcha:
sentence_for_humans: "If you are human, ignore this field"
timestamp_error_message: "Sorry, that was too quick! Please resubmit."
```
You can override the english ones in your own i18n config files as well as add new ones for other locales.
If you intend to use I18n with `invisible_captcha`, you _must not_ set `sentence_for_humans` or `timestamp_error_message` to strings in the setup phase.
## Testing your controllers
If you're encountering unexpected behaviour while testing controllers that use the `invisible_captcha` action filter, you may want to disable timestamp check for the test environment:
```ruby
# test/test_helper.rb, spec/rails_helper.rb, ...
InvisibleCaptcha.timestamp_enabled = false
```
Another option is to wait for the timestamp check to be valid:
```ruby
# Maybe in a before block
InvisibleCaptcha.init!
InvisibleCaptcha.timestamp_threshold = 1
# Before testing your controller action
sleep InvisibleCaptcha.timestamp_threshold
```
## Contribute
Any kind of idea, feedback or bug report are welcome! Open an [issue](https://github.com/markets/invisible_captcha/issues) or send a [pull request](https://github.com/markets/invisible_captcha/pulls).
## Development
Clone/fork this repository, start to hack on it and send a pull request.
Run the test suite:
```
$ bundle exec rspec
```
Run the test suite against all supported versions:
```
$ bundle exec appraisal install
$ bundle exec appraisal rspec
```
Run specs against specific version:
```
$ bundle exec appraisal rails-5.2 rspec
```
### Demo
Start a sample Rails app ([source code](spec/dummy)) with `InvisibleCaptcha` integrated:
```
$ bundle exec rake web # PORT=4000 (default: 3000)
```
## License
Copyright (c) Marc Anguera. Invisible Captcha is released under the [MIT](LICENSE) License.
invisible-captcha-0.12.2/.travis.yml 0000644 0001750 0001750 00000002005 13541745065 020037 0 ustar utkarsh2102 utkarsh2102 language: ruby
cache: bundler
sudo: false
rvm:
- ruby-head
- 2.6.2
- 2.5.5
- 2.4.5
- 2.3.8
- 2.2.10
gemfile:
- gemfiles/rails_6.0.gemfile
- gemfiles/rails_5.2.gemfile
- gemfiles/rails_5.1.gemfile
- gemfiles/rails_5.0.gemfile
- gemfiles/rails_4.2.gemfile
- gemfiles/rails_3.2.gemfile
before_install:
# Rails 4.x requires Bundler version < 2.0.
- "find /home/travis/.rvm/rubies -wholename '*default/bundler-*.gemspec' -delete"
- rvm @global do gem uninstall bundler -a -x
- rvm @global do yes | gem install bundler -v '< 2'
matrix:
exclude:
- rvm: 2.4.5
gemfile: gemfiles/rails_6.0.gemfile
- rvm: 2.3.8
gemfile: gemfiles/rails_6.0.gemfile
- rvm: 2.2.10
gemfile: gemfiles/rails_6.0.gemfile
- rvm: ruby-head
gemfile: gemfiles/rails_3.2.gemfile
- rvm: 2.6.2
gemfile: gemfiles/rails_3.2.gemfile
- rvm: 2.5.5
gemfile: gemfiles/rails_3.2.gemfile
- rvm: 2.4.5
gemfile: gemfiles/rails_3.2.gemfile
allow_failures:
- rvm: ruby-head invisible-captcha-0.12.2/.gitignore 0000644 0001750 0001750 00000000177 13541745065 017726 0 ustar utkarsh2102 utkarsh2102 .bundle
pkg
.rvmrc
.ruby-version
.ruby-gemset
Gemfile.lock
*.gemfile.lock
spec/dummy/log/*.log
spec/dummy/tmp/
.byebug_history
invisible-captcha-0.12.2/Gemfile 0000644 0001750 0001750 00000000047 13541745065 017225 0 ustar utkarsh2102 utkarsh2102 source 'https://rubygems.org'
gemspec