diff options
Diffstat (limited to 'actionpack')
-rw-r--r-- | actionpack/CHANGELOG.md | 5 | ||||
-rw-r--r-- | actionpack/lib/action_view/helpers/url_helper.rb | 66 | ||||
-rw-r--r-- | actionpack/test/template/url_helper_test.rb | 56 |
3 files changed, 17 insertions, 110 deletions
diff --git a/actionpack/CHANGELOG.md b/actionpack/CHANGELOG.md index d213ab057c..0228038b1b 100644 --- a/actionpack/CHANGELOG.md +++ b/actionpack/CHANGELOG.md @@ -4,6 +4,11 @@ *Vasiliy Ermolovich* +* Extract support for email address obfuscation via `:encode`, `:replace_at`, and `replace_dot` options + from the `mail_to` helper into the `actionview-encoded_mail_to` gem. + + *Nick Reed + DHH* + * Clear url helper methods when routes are reloaded. *Andrew White* * Fix a bug in `ActionDispatch::Request#raw_post` that caused `env['rack.input']` diff --git a/actionpack/lib/action_view/helpers/url_helper.rb b/actionpack/lib/action_view/helpers/url_helper.rb index fa516cf91b..aeee662071 100644 --- a/actionpack/lib/action_view/helpers/url_helper.rb +++ b/actionpack/lib/action_view/helpers/url_helper.rb @@ -415,40 +415,26 @@ module ActionView # also used as the name of the link unless +name+ is specified. Additional # HTML attributes for the link can be passed in +html_options+. # - # +mail_to+ has several methods for hindering email harvesters and customizing - # the email itself by passing special keys to +html_options+. + # +mail_to+ has several methods for customizing the email itself by + # passing special keys to +html_options+. # # ==== Options - # * <tt>:encode</tt> - This key will accept the strings "javascript" or "hex". - # Passing "javascript" will dynamically create and encode the mailto link then - # eval it into the DOM of the page. This method will not show the link on - # the page if the user has JavaScript disabled. Passing "hex" will hex - # encode the +email_address+ before outputting the mailto link. - # * <tt>:replace_at</tt> - When the link +name+ isn't provided, the - # +email_address+ is used for the link label. You can use this option to - # obfuscate the +email_address+ by substituting the @ sign with the string - # given as the value. - # * <tt>:replace_dot</tt> - When the link +name+ isn't provided, the - # +email_address+ is used for the link label. You can use this option to - # obfuscate the +email_address+ by substituting the . in the email with the - # string given as the value. # * <tt>:subject</tt> - Preset the subject line of the email. # * <tt>:body</tt> - Preset the body of the email. # * <tt>:cc</tt> - Carbon Copy additional recipients on the email. # * <tt>:bcc</tt> - Blind Carbon Copy additional recipients on the email. # + # ==== Obfuscation + # Prior to Rails 4.0, +mail_to+ provided options for encoding the address + # in order to hinder email harvesters. To take advantage of these options, + # install the +actionview-encoded_mail_to+ gem. + # # ==== Examples # mail_to "me@domain.com" # # => <a href="mailto:me@domain.com">me@domain.com</a> # - # mail_to "me@domain.com", "My email", encode: "javascript" - # # => <script>eval(decodeURIComponent('%64%6f%63...%27%29%3b'))</script> - # - # mail_to "me@domain.com", "My email", encode: "hex" - # # => <a href="mailto:%6d%65@%64%6f%6d%61%69%6e.%63%6f%6d">My email</a> - # - # mail_to "me@domain.com", nil, replace_at: "_at_", replace_dot: "_dot_", class: "email" - # # => <a href="mailto:me@domain.com" class="email">me_at_domain_dot_com</a> + # mail_to "me@domain.com", "My email" + # # => <a href="mailto:me@domain.com">My email</a> # # mail_to "me@domain.com", "My email", cc: "ccaddress@domain.com", # subject: "This is an example email" @@ -456,43 +442,15 @@ module ActionView def mail_to(email_address, name = nil, html_options = {}) email_address = ERB::Util.html_escape(email_address) - html_options = html_options.stringify_keys - encode = html_options.delete("encode").to_s + html_options.stringify_keys! extras = %w{ cc bcc body subject }.map { |item| option = html_options.delete(item) || next "#{item}=#{Rack::Utils.escape_path(option)}" }.compact extras = extras.empty? ? '' : '?' + ERB::Util.html_escape(extras.join('&')) - - email_address_obfuscated = email_address.to_str - email_address_obfuscated.gsub!(/@/, html_options.delete("replace_at")) if html_options.key?("replace_at") - email_address_obfuscated.gsub!(/\./, html_options.delete("replace_dot")) if html_options.key?("replace_dot") - case encode - when "javascript" - string = '' - html = content_tag("a", name || email_address_obfuscated.html_safe, html_options.merge("href" => "mailto:#{email_address}#{extras}".html_safe)) - html = escape_javascript(html.to_str) - "document.write('#{html}');".each_byte do |c| - string << sprintf("%%%x", c) - end - "<script>eval(decodeURIComponent('#{string}'))</script>".html_safe - when "hex" - email_address_encoded = email_address_obfuscated.unpack('C*').map {|c| - sprintf("&#%d;", c) - }.join - - string = 'mailto:'.unpack('C*').map { |c| - sprintf("&#%d;", c) - }.join + email_address.unpack('C*').map { |c| - char = c.chr - char =~ /\w/ ? sprintf("%%%x", c) : char - }.join - - content_tag "a", name || email_address_encoded.html_safe, html_options.merge("href" => "#{string}#{extras}".html_safe) - else - content_tag "a", name || email_address_obfuscated.html_safe, html_options.merge("href" => "mailto:#{email_address}#{extras}".html_safe) - end + + content_tag "a", name || email_address.html_safe, html_options.merge("href" => "mailto:#{email_address}#{extras}".html_safe) end # True if the current request URI was generated by the given +options+. diff --git a/actionpack/test/template/url_helper_test.rb b/actionpack/test/template/url_helper_test.rb index 1bb625213d..ba65349b6a 100644 --- a/actionpack/test/template/url_helper_test.rb +++ b/actionpack/test/template/url_helper_test.rb @@ -517,16 +517,6 @@ class UrlHelperTest < ActiveSupport::TestCase mail_to("david@loudthinking.com", "David Heinemeier Hansson", class: "admin") end - def test_mail_to_with_javascript - snippet = mail_to("me@domain.com", "My email", encode: "javascript") - assert_dom_equal "<script>eval(decodeURIComponent('%64%6f%63%75%6d%65%6e%74%2e%77%72%69%74%65%28%27%3c%61%20%68%72%65%66%3d%5c%22%6d%61%69%6c%74%6f%3a%6d%65%40%64%6f%6d%61%69%6e%2e%63%6f%6d%5c%22%3e%4d%79%20%65%6d%61%69%6c%3c%5c%2f%61%3e%27%29%3b'))</script>", snippet - end - - def test_mail_to_with_javascript_unicode - snippet = mail_to("unicode@example.com", "Ășnicode", encode: "javascript") - assert_dom_equal "<script>eval(decodeURIComponent('%64%6f%63%75%6d%65%6e%74%2e%77%72%69%74%65%28%27%3c%61%20%68%72%65%66%3d%5c%22%6d%61%69%6c%74%6f%3a%75%6e%69%63%6f%64%65%40%65%78%61%6d%70%6c%65%2e%63%6f%6d%5c%22%3e%c3%ba%6e%69%63%6f%64%65%3c%5c%2f%61%3e%27%29%3b'))</script>", snippet - end - def test_mail_with_options assert_dom_equal( %{<a href="mailto:me@example.com?cc=ccaddress%40example.com&bcc=bccaddress%40example.com&body=This%20is%20the%20body%20of%20the%20message.&subject=This%20is%20an%20example%20email">My email</a>}, @@ -539,54 +529,8 @@ class UrlHelperTest < ActiveSupport::TestCase mail_to('feedback@example.com', '<img src="/feedback.png" />'.html_safe) end - def test_mail_to_with_hex - assert_dom_equal( - %{<a href="mailto:%6d%65@%64%6f%6d%61%69%6e.%63%6f%6d">My email</a>}, - mail_to("me@domain.com", "My email", encode: "hex") - ) - - assert_dom_equal( - %{<a href="mailto:%6d%65@%64%6f%6d%61%69%6e.%63%6f%6d">me@domain.com</a>}, - mail_to("me@domain.com", nil, encode: "hex") - ) - end - - def test_mail_to_with_replace_options - assert_dom_equal( - %{<a href="mailto:wolfgang@stufenlos.net">wolfgang(at)stufenlos(dot)net</a>}, - mail_to("wolfgang@stufenlos.net", nil, replace_at: "(at)", replace_dot: "(dot)") - ) - - assert_dom_equal( - %{<a href="mailto:%6d%65@%64%6f%6d%61%69%6e.%63%6f%6d">me(at)domain.com</a>}, - mail_to("me@domain.com", nil, encode: "hex", replace_at: "(at)") - ) - - assert_dom_equal( - %{<a href="mailto:%6d%65@%64%6f%6d%61%69%6e.%63%6f%6d">My email</a>}, - mail_to("me@domain.com", "My email", encode: "hex", replace_at: "(at)") - ) - - assert_dom_equal( - %{<a href="mailto:%6d%65@%64%6f%6d%61%69%6e.%63%6f%6d">me(at)domain(dot)com</a>}, - mail_to("me@domain.com", nil, encode: "hex", replace_at: "(at)", replace_dot: "(dot)") - ) - - assert_dom_equal( - %{<script>eval(decodeURIComponent('%64%6f%63%75%6d%65%6e%74%2e%77%72%69%74%65%28%27%3c%61%20%68%72%65%66%3d%5c%22%6d%61%69%6c%74%6f%3a%6d%65%40%64%6f%6d%61%69%6e%2e%63%6f%6d%5c%22%3e%4d%79%20%65%6d%61%69%6c%3c%5c%2f%61%3e%27%29%3b'))</script>}, - mail_to("me@domain.com", "My email", encode: "javascript", replace_at: "(at)", replace_dot: "(dot)") - ) - - assert_dom_equal( - %{<script>eval(decodeURIComponent('%64%6f%63%75%6d%65%6e%74%2e%77%72%69%74%65%28%27%3c%61%20%68%72%65%66%3d%5c%22%6d%61%69%6c%74%6f%3a%6d%65%40%64%6f%6d%61%69%6e%2e%63%6f%6d%5c%22%3e%6d%65%28%61%74%29%64%6f%6d%61%69%6e%28%64%6f%74%29%63%6f%6d%3c%5c%2f%61%3e%27%29%3b'))</script>}, - mail_to("me@domain.com", nil, encode: "javascript", replace_at: "(at)", replace_dot: "(dot)") - ) - end - def test_mail_to_returns_html_safe_string assert mail_to("david@loudthinking.com").html_safe? - assert mail_to("me@domain.com", "My email", encode: "javascript").html_safe? - assert mail_to("me@domain.com", "My email", encode: "hex").html_safe? end def protect_against_forgery? |