unity-captcha 1.0.1 → 1.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
- SHA1:
3
- metadata.gz: 674e45a2d8771ef6be513c4e0699fe7fd02ddae9
4
- data.tar.gz: 99ef29699c26e68c8478494669be994ba4afb847
2
+ SHA256:
3
+ metadata.gz: deeedbca2eb3ab588afbf187fbf0ce5774e72f2aa397413ece0acea8be11621b
4
+ data.tar.gz: ecde9d84d493838e6e456dee4dfe64d64d6c766c4015cff2414f4333a657f50e
5
5
  SHA512:
6
- metadata.gz: 555ee315a14a243b5bceaef420f0005d335565f1d00600581ee291527583997a5fb019abfc9e6ecaba75168945c81bc5370fdd2c9291016cc2ba324859946821
7
- data.tar.gz: bc433a006182033752483ef1499fb8a0f42258b5beb1909d0418cb17f72b1244f77e67395cc3c1bae0ec69833576c6758fcb870aad18b47df7860f73386c253f
6
+ metadata.gz: 14f34e0f4bffec3b2a05ba50b38f4fa73300c4a296173320dadbd14a3e269253d5913fd91e9163b97f8b434aa1d2ecd74e217819b80e32a10a3dc436a1f4d89e
7
+ data.tar.gz: dfe30b94b448f72749ce1e1e08916d60f8ea4366da8ac9fe8e8e597f326c8be6a92c2c729093801b6bc90c320fab31f3a7e1711b820dd339ba94e926b566409f
data/README.md CHANGED
@@ -1,13 +1,13 @@
1
1
  # Unity Captcha
2
2
 
3
- Unity Captcha is a gem that use two levels of Captcha. First level is about Left Hemisphere: Logic and Math. Second level is about Right Hemisphere: Intuition and Drawing. This two levels functioning in complete harmony creates unity and this is the base design of this Captcha.
3
+ Unity Captcha is a gem that uses two levels of Captcha:
4
4
 
5
- The Left Hemisphere Level use a simple question of addition and multiplication. This works in the server side.
5
+ 1. **Left Hemisphere Level**: Logic and Math - A simple math question (addition or multiplication) handled on the server side.
6
+ 2. **Right Hemisphere Level**: Intuition and Drawing - Uses MotionCAPTCHA, requiring users to draw a shape they see in a canvas (client-side verification).
6
7
 
7
- The Right Hemisphere Level use MotionCAPTCHA (https://github.com/wjcrowcroft/MotionCAPTCHA), that is a jQuery CAPTCHA plugin that requires users to sketch the shape they see in the canvas in order to submit a form. This works in the client side.
8
-
9
- Dra. Jill Bolte Taylor got a research opportunity to study from inside of her brain how Left and Right Hemisphere works. I recommend to watch her in this video: https://www.ted.com/talks/jill_bolte_taylor_s_powerful_stroke_of_insight#t-1102370
8
+ These two levels, functioning in harmony, create a secure and engaging captcha experience.
10
9
 
10
+ Inspired by Dr. Jill Bolte Taylor's research on brain hemispheres. Learn more: [TED Talk](https://www.ted.com/talks/jill_bolte_taylor_s_powerful_stroke_of_insight)
11
11
 
12
12
  ## Installation
13
13
 
@@ -19,145 +19,165 @@ gem 'unity-captcha'
19
19
 
20
20
  And then execute:
21
21
 
22
- $ bundle
22
+ ```bash
23
+ $ bundle
24
+ ```
23
25
 
24
26
  Or install it yourself as:
25
27
 
26
- $ gem install unity-captcha
28
+ ```bash
29
+ $ gem install unity-captcha
30
+ ```
27
31
 
28
32
  ## Usage
29
33
 
30
- For the First level - Left Hemisphere: Logic and Math ( Server Side ) we use some code in the controller and the view.
34
+ ### Quick Start with `captcha_for` Helper
35
+
36
+ The gem now provides a simple `captcha_for` helper that automatically adds all required assets and markup:
37
+
38
+ ```erb
39
+ <%= form_tag(send_invite_path, method: :post, id: "mc-form") do %>
40
+ <%= label_tag :friend_email, "Email" %>
41
+ <%= text_field_tag :friend_email %>
42
+
43
+ <%= captcha_for %>
44
+
45
+ <%= submit_tag "Send Invitation" %>
46
+ <% end %>
47
+ ```
31
48
 
32
- 1. In your controller, for example if you have a method inside the controller called 'send_invite':
49
+ In your controller:
33
50
 
34
51
  ```ruby
35
52
  class InviteController < ApplicationController
36
- def new
37
- @captcha = Unity::Captcha::Captcha.new
38
- end
39
53
  def send_invite
40
54
  @captcha = Unity::Captcha::Captcha.decrypt(params[:captcha_secret])
41
- email = params[:friend_email]
55
+
42
56
  unless @captcha.correct?(params[:captcha])
43
- @captcha = Unity::Captcha::Captcha.new
44
- redirect_to invite_url, :alert => "Please make sure you entered correct value for captcha."
45
- else
46
- InviteMailer.invite_email(current_user, email).deliver_now
47
- flash[:notice] = "Thank you for inviting your friend! Please feel free to invite more!"
48
- redirect_to invite_url
49
- end
57
+ redirect_to invite_url, alert: "Please enter the correct captcha value."
58
+ else
59
+ # Process your form...
60
+ redirect_to success_url, notice: "Form submitted successfully!"
61
+ end
50
62
  end
51
63
  end
52
64
  ```
53
65
 
54
- 2. Ask the question in the form, example:
66
+ ### Form Builder Integration
67
+
68
+ Works with form builders like simple_form:
55
69
 
56
70
  ```erb
57
- <%= form_tag(send_invite_path, :method => :post) do %>
58
- <%= label_tag :friend_email, "Email" %>
59
- <%= text_field_tag :friend_email, nil, :size =>50, :class => "placeholder" %>
60
- <%= label_tag :question, "Question: "+@captcha.question %>
61
- <%= text_field_tag :captcha %>
62
- <%= hidden_field_tag :captcha_secret, @captcha.encrypt %>
63
-
64
- <%= submit_tag "Send Invitation" %>
65
- <% end %>
71
+ <%= simple_form_for(@invite, html: {id: 'mc-form'}) do |f| %>
72
+ <%= f.input :email %>
73
+
74
+ <%= captcha_for(f) %>
75
+
76
+ <%= f.button :submit %>
77
+ <% end %>
66
78
  ```
67
79
 
68
- For the Second level - Right Hemisphere: Intuition and Drawing ( Cliend Side ) we just need to add some code in the form and make sure to add the plugin scripts: (MotionCAPTCHA is supported down to jQuery 1.4)
69
-
70
- 1. Adding plugin scripts ( usually added in application.html.erb ):
80
+ ### Customization Options
71
81
 
72
82
  ```erb
73
- <%= javascript_include_tag "https://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js"%>
74
- <%= stylesheet_link_tag "jquery.motionCaptcha.1.0" %>
75
- <%= javascript_include_tag "jquery.motionCaptcha.1.0" %>
76
- <%= javascript_include_tag "jquery.placeholder.1.1.1.min" %>
83
+ <%= captcha_for(f, {
84
+ # Canvas appearance
85
+ label: 'Draw the shape to verify:',
86
+ canvas_id: 'my-custom-canvas',
87
+ form_id: 'my-form-id',
88
+ html_options: { class: 'custom-canvas', style: 'border: 3px solid #333' },
89
+
90
+ # Shape options
91
+ shapes: ['triangle', 'x', 'rectangle', 'circle', 'check'],
92
+
93
+ # Messages
94
+ error_msg: 'Not quite right, try again.',
95
+ success_msg: 'Perfect! Form submitted.',
96
+
97
+ # Asset options
98
+ skip_jquery: true, # Skip jQuery if you already include it
99
+
100
+ # Form submission
101
+ action_path: custom_submit_path
102
+ }) %>
77
103
  ```
78
104
 
79
- 2. Replace the submit_tag with the CAPTCHA canvas and a hidden_field_tag, like the following code ( remember to add :id => "mc-form" in form):
105
+ ### Available Shapes
80
106
 
81
- ```erb
82
- <%= form_tag(send_invite_path, :method => :post, :id => "mc-form") do %>
83
- <%= label_tag :friend_email, "Email" %>
84
- <%= text_field_tag :friend_email, nil, :size =>50, :class => "placeholder" %
85
- <%= label_tag :question, "Question: "+@captcha.question %>
86
- <%= text_field_tag :captcha %>
87
- <%= hidden_field_tag :captcha_secret, @captcha.encrypt %>
88
-
89
- <p>CAPTCHA: Please draw the shape in the box to submit the form: (<a onclick="window.location.reload()" href="#" title="Click for a new shape">new shape</a>)</p>
90
- <canvas id="mc-canvas"></canvas>
91
- <%= hidden_field_tag 'mc-action', send_invite_path.to_s %>
92
- <% end %>
107
+ The following shapes are available (you can use any subset):
108
+
109
+ ```
110
+ 'triangle', 'x', 'rectangle', 'circle', 'check', 'caret', 'zigzag',
111
+ 'arrow', 'leftbracket', 'rightbracket', 'v', 'delete', 'star', 'pigtail'
93
112
  ```
94
113
 
95
- You can also use simple_form:
114
+ ## How It Works
96
115
 
97
- ```erb
98
- <%= simple_form_for send_invite_path, :html => {:class => 'form-horizontal',:id => "mc-form" } do |f| %>
99
- <%= f.input :friend_email, label: 'Email',:class => "placeholder", :required => true %>
100
- <%= f.input :captcha, label: @captcha.question, :required => true %>
101
- <%= f.input :captcha_secret, :as => :hidden, :input_html => { :value => @captcha.encrypt } %>
102
-
103
- <p>CAPTCHA: Please draw the shape in the box to submit the form: (<a onclick="window.location.reload()" href="#" title="Click for a new shape">new shape</a>)</p>
104
- <canvas id="mc-canvas"></canvas>
105
- <%= f.input :mc_action, :as => :hidden, :input_html => { :value => send_invite_path.to_s } %>
106
- <% end %>
107
- ```
116
+ Unity Captcha combines:
117
+
118
+ 1. **Math Challenge**: Server-side validation of a simple math problem
119
+ 2. **Drawing Challenge**: Client-side validation of a drawn shape using pattern recognition
120
+
121
+ Both must be correct for the form to submit, providing dual-layer security.
122
+
123
+ ## Advanced Usage
108
124
 
109
- 3. Initialize the javascrit component in the same form:
125
+ For more control or custom implementations, you can use the traditional approach:
126
+
127
+ ```ruby
128
+ # Controller
129
+ def new
130
+ @captcha = Unity::Captcha::Captcha.new
131
+ end
132
+ ```
110
133
 
111
134
  ```erb
112
- <script type="text/javaScript">
135
+ <%# View %>
136
+ <%= form_tag(submit_path, method: :post, id: "mc-form") do %>
137
+ <%# Math captcha %>
138
+ <%= label_tag :captcha, @captcha.question %>
139
+ <%= text_field_tag :captcha %>
140
+ <%= hidden_field_tag :captcha_secret, @captcha.encrypt %>
141
+
142
+ <%# Drawing captcha %>
143
+ <p>Please draw the shape: <a onclick="window.location.reload()" href="#">(new shape)</a></p>
144
+ <canvas id="mc-canvas"></canvas>
145
+ <%= hidden_field_tag 'mc-action', submit_path %>
146
+
147
+ <%= submit_tag "Submit" %>
148
+ <% end %>
149
+
150
+ <%# Initialize JavaScript %>
151
+ <script>
113
152
  jQuery(document).ready(function($) {
114
153
  $('#mc-form').motionCaptcha({
115
- shapes: ['triangle', 'x', 'rectangle', 'circle', 'check', 'zigzag', 'arrow', 'delete', 'pigtail', 'star']
116
- });
117
- $("input.placeholder").placeholder();
154
+ shapes: ['triangle', 'x', 'rectangle', 'circle', 'check']
155
+ });
118
156
  });
119
157
  </script>
120
158
  ```
121
159
 
122
- 4. Other options are available to initialize the canvas javascript component:
160
+ Make sure to include the required assets:
123
161
 
124
162
  ```erb
125
- <script type="text/javaScript">
126
- jQuery(document).ready(function($) {
127
- $('#mc-form').motioncaptcha({
128
- // Basics:
129
- action: '#mc-action', // the ID of the input containing the form action
130
- divId: '#mc', // if you use an ID other than '#mc' for the placeholder, pass it in here
131
- cssClass: '.mc-active', // this CSS class is applied to the 'mc' div when the plugin is active
132
- canvasId: '#mc-canvas', // the ID of the MotionCAPTCHA canvas element
133
-
134
- // An array of shape names that you want MotionCAPTCHA to use:
135
- shapes: ['triangle', 'x', 'rectangle', 'circle', 'check', 'caret', 'zigzag', 'arrow', 'leftbracket', 'rightbracket', 'v', 'delete', 'star', 'pigtail'],
136
-
137
- // These messages are displayed inside the canvas after a user finishes drawing:
138
- errorMsg: 'Please try again.',
139
- successMsg: 'Captcha passed!',
140
-
141
- // This message is displayed if the user's browser doesn't support canvas:
142
- noCanvasMsg: "Your browser doesn't support <canvas> - try Chrome, FF4, Safari or IE9."
143
-
144
- // This could be any HTML string (eg. '<label>Draw this shit yo:</label>'):
145
- label: '<p>Please draw the shape in the box to submit the form:</p>'
146
- });
147
- });
148
- </script>
163
+ <%= javascript_include_tag "jquery.min" %>
164
+ <%= stylesheet_link_tag "jquery.motionCaptcha.1.0" %>
165
+ <%= javascript_include_tag "jquery.motionCaptcha.1.0", "jquery.placeholder.1.1.1.min" %>
149
166
  ```
150
167
 
168
+ ## Sites Using Unity Captcha
169
+
170
+ * [Artavita.com](http://artavita.com/) - Invitation form and exhibit contact forms
171
+
151
172
  ## Development
152
173
 
153
- After checking out the repo, run `bin/setup` to install dependencies. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
174
+ After checking out the repo, run `bin/setup` to install dependencies. You can also run `bin/console` for an interactive prompt.
154
175
 
155
- To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and tags, and push the `.gem` file to [rubygems.org](https://rubygems.org).
176
+ To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`.
156
177
 
157
178
  ## Contributing
158
179
 
159
- Bug reports and pull requests are welcome on GitHub at https://github.com/papayalabs/unity-captcha. This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the [Contributor Covenant](http://contributor-covenant.org) code of conduct.
160
-
180
+ Bug reports and pull requests are welcome on GitHub at https://github.com/papayalabs/unity-captcha. Contributors are expected to adhere to the [Contributor Covenant](http://contributor-covenant.org) code of conduct.
161
181
 
162
182
  ## License
163
183
 
@@ -4,6 +4,13 @@ module Unity
4
4
  initializer 'static_assets.load_static_assets' do |app|
5
5
  app.middleware.use ::ActionDispatch::Static, "#{root}/vendor"
6
6
  end
7
+
8
+ initializer 'unity_captcha.action_view.helpers' do
9
+ ActiveSupport.on_load :action_view do
10
+ require 'unity/captcha/view_helpers'
11
+ include Unity::Captcha::ViewHelpers
12
+ end
13
+ end
7
14
  end
8
15
  end
9
16
  end
@@ -1,5 +1,5 @@
1
1
  module Unity
2
2
  module Captcha
3
- VERSION = "1.0.1"
3
+ VERSION = "1.1.0"
4
4
  end
5
5
  end
@@ -0,0 +1,96 @@
1
+ module Unity
2
+ module Captcha
3
+ module ViewHelpers
4
+ # Helper method to generate a Unity Captcha field in forms
5
+ #
6
+ # @param form [FormBuilder] The form object
7
+ # @param options [Hash] Options for customizing the captcha
8
+ # @option options [String] :label The label for the captcha field
9
+ # @option options [Array<String>] :shapes List of shapes to use
10
+ # @option options [String] :error_msg Error message to display
11
+ # @option options [String] :success_msg Success message to display
12
+ # @option options [String] :form_id ID for the form (defaults to "mc-form")
13
+ # @option options [String] :canvas_id ID for the canvas (defaults to "mc-canvas")
14
+ # @option options [Hash] :html_options Additional HTML options for the canvas
15
+ #
16
+ # @return [String] HTML markup for the captcha
17
+ def captcha_for(form = nil, options = {})
18
+ # Create the captcha object if not passed
19
+ @captcha ||= Unity::Captcha::Captcha.new
20
+
21
+ options = {
22
+ label: 'Please draw the shape in the box to submit the form:',
23
+ shapes: ['triangle', 'x', 'rectangle', 'circle', 'check', 'zigzag', 'arrow', 'delete', 'pigtail', 'star'],
24
+ error_msg: 'Please try again.',
25
+ success_msg: 'Captcha passed!',
26
+ form_id: 'mc-form',
27
+ canvas_id: 'mc-canvas',
28
+ html_options: {}
29
+ }.merge(options)
30
+
31
+ # Include required assets
32
+ output = javascript_include_tag("https://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js") unless options[:skip_jquery]
33
+ output = (output || '').html_safe
34
+ output += javascript_include_tag("jquery.motionCaptcha.1.0", "jquery.placeholder.1.1.1.min")
35
+ output += stylesheet_link_tag("jquery.motionCaptcha.1.0")
36
+
37
+ # Generate the form ID - if we're in a form, use that form's ID or set it
38
+ form_id = options[:form_id]
39
+ if form.present?
40
+ # If we're in a form_for/simple_form_for block
41
+ form.object_name # make sure it's a form object
42
+
43
+ # Math captcha question field
44
+ output += form.label :captcha, @captcha.question
45
+ output += form.text_field :captcha
46
+ output += form.hidden_field :captcha_secret, value: @captcha.encrypt
47
+
48
+ # Drawing captcha
49
+ output += content_tag(:p, options[:label].html_safe +
50
+ content_tag(:a, ' (new shape)', href: '#',
51
+ onclick: "window.location.reload()",
52
+ title: "Click for a new shape"))
53
+ output += content_tag(:canvas, '', { id: options[:canvas_id] }.merge(options[:html_options]))
54
+
55
+ # Hidden action field
56
+ action_path = options[:action_path] || request.path
57
+ output += form.hidden_field :mc_action, value: action_path
58
+ else
59
+ # If we're just rendering the captcha standalone
60
+ output += label_tag :captcha, @captcha.question
61
+ output += text_field_tag :captcha
62
+ output += hidden_field_tag :captcha_secret, @captcha.encrypt
63
+
64
+ # Drawing captcha
65
+ output += content_tag(:p, options[:label].html_safe +
66
+ content_tag(:a, ' (new shape)', href: '#',
67
+ onclick: "window.location.reload()",
68
+ title: "Click for a new shape"))
69
+ output += content_tag(:canvas, '', { id: options[:canvas_id] }.merge(options[:html_options]))
70
+
71
+ # Hidden action field
72
+ action_path = options[:action_path] || request.path
73
+ output += hidden_field_tag :mc_action, action_path
74
+ end
75
+
76
+ # Initialize the javascript
77
+ shapes_json = options[:shapes].to_json
78
+ script = <<-JAVASCRIPT
79
+ <script type="text/javascript">
80
+ jQuery(document).ready(function($) {
81
+ $('##{form_id}').motionCaptcha({
82
+ shapes: #{shapes_json},
83
+ errorMsg: "#{options[:error_msg]}",
84
+ successMsg: "#{options[:success_msg]}"
85
+ });
86
+ $("input.placeholder").placeholder();
87
+ });
88
+ </script>
89
+ JAVASCRIPT
90
+
91
+ output += script.html_safe
92
+ output
93
+ end
94
+ end
95
+ end
96
+ end
data/lib/unity/captcha.rb CHANGED
@@ -1,5 +1,7 @@
1
1
  require "unity/captcha/version"
2
2
  require "unity/captcha/engine"
3
+ require "base64"
4
+ require "yaml"
3
5
 
4
6
  module Unity
5
7
  module Captcha
@@ -30,6 +30,6 @@ Gem::Specification.new do |spec|
30
30
  spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
31
31
  spec.require_paths = ["lib"]
32
32
 
33
- spec.add_development_dependency "bundler", "~> 1.13"
34
- spec.add_development_dependency "rake", "~> 10.0"
33
+ spec.add_development_dependency "bundler", "~> 2.5.23"
34
+ spec.add_development_dependency "rake", "~> 12.3.3"
35
35
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: unity-captcha
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.1
4
+ version: 1.1.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Manuel Fernandez
8
- autorequire:
8
+ autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2017-07-28 00:00:00.000000000 Z
11
+ date: 2025-03-11 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -16,28 +16,28 @@ dependencies:
16
16
  requirements:
17
17
  - - "~>"
18
18
  - !ruby/object:Gem::Version
19
- version: '1.13'
19
+ version: 2.5.23
20
20
  type: :development
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
24
  - - "~>"
25
25
  - !ruby/object:Gem::Version
26
- version: '1.13'
26
+ version: 2.5.23
27
27
  - !ruby/object:Gem::Dependency
28
28
  name: rake
29
29
  requirement: !ruby/object:Gem::Requirement
30
30
  requirements:
31
31
  - - "~>"
32
32
  - !ruby/object:Gem::Version
33
- version: '10.0'
33
+ version: 12.3.3
34
34
  type: :development
35
35
  prerelease: false
36
36
  version_requirements: !ruby/object:Gem::Requirement
37
37
  requirements:
38
38
  - - "~>"
39
39
  - !ruby/object:Gem::Version
40
- version: '10.0'
40
+ version: 12.3.3
41
41
  description: 'Unity Captcha is a gem that use two levels of Captcha. First level is
42
42
  about Left Hemisphere: Logic and Math. Second level is about Right Hemisphere: Intuition
43
43
  and Drawing. This two levels functioning in complete harmony creates unity and this
@@ -60,6 +60,7 @@ files:
60
60
  - lib/unity/captcha.rb
61
61
  - lib/unity/captcha/engine.rb
62
62
  - lib/unity/captcha/version.rb
63
+ - lib/unity/captcha/view_helpers.rb
63
64
  - unity-captcha.gemspec
64
65
  - vendor/.DS_Store
65
66
  - vendor/assets/.DS_Store
@@ -72,7 +73,7 @@ licenses:
72
73
  - MIT
73
74
  metadata:
74
75
  allowed_push_host: https://rubygems.org
75
- post_install_message:
76
+ post_install_message:
76
77
  rdoc_options: []
77
78
  require_paths:
78
79
  - lib
@@ -87,9 +88,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
87
88
  - !ruby/object:Gem::Version
88
89
  version: '0'
89
90
  requirements: []
90
- rubyforge_project:
91
- rubygems_version: 2.4.8
92
- signing_key:
91
+ rubygems_version: 3.4.1
92
+ signing_key:
93
93
  specification_version: 4
94
94
  summary: Unity Captcha is a gem that use two levels of captcha based on the hemispheres
95
95
  of the brain