Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Also protect email addresses in link label #8

Open
wants to merge 3 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 11 additions & 2 deletions features/extension.feature
Original file line number Diff line number Diff line change
Expand Up @@ -15,14 +15,23 @@ Feature: Email Protection
When I go to "/with_body.html"
Then I should see:
"""
</script>
</body>
</script></body>
"""

Scenario: Does not insert script if there is no email on the page
Given the Server is running at "test-app"
When I go to "/with_no_email.html"
Then I should not see "</script>"

Scenario: Does not insert script if there is an email on the page but not as a link
Given the Server is running at "test-app"
When I go to "/with_email_as_text.html"
Then I should not see "</script>"

Scenario: Shows obfuscated email text in link
Given the Server is running at "test-app"
When I go to "/with_email_in_link.html"
Then I should see "<a href='#email-protection-rznvy@rknzcyr.pbz'>our email <span>email@email</span></a>"

Scenario: Encrypts multiple emails
Given the Server is running at "test-app"
Expand Down
1 change: 1 addition & 0 deletions fixtures/test-app/source/with_email_as_text.html
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
<html><head></head><body>email@example.com</body></html>
1 change: 1 addition & 0 deletions fixtures/test-app/source/with_email_in_link.html
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
<html><head></head><body><a href='mailto:email@example.com'>our email <span>email@example.com</span></a></body></html>
24 changes: 19 additions & 5 deletions lib/middleman-protect-emails/extension.rb
Original file line number Diff line number Diff line change
Expand Up @@ -2,18 +2,22 @@

class Middleman::ProtectEmailsExtension < ::Middleman::Extension

option :prefix, '#email-protection-', 'Prefix to use for encoded links'
option :text_replacement, 'our contact form', 'Replacement for text links'

def initialize(app, options_hash={}, &block)
super
end

def after_configuration
app.use Middleware, middleman_app: app
app.use Middleware, middleman_app: app, options: options
end

class Middleware
def initialize(app, options = {})
@rack_app = app
@middleman_app = options[:middleman_app]
@options = options[:options]
end

def call(env)
Expand All @@ -40,15 +44,23 @@ def rewrite_response(body)
replaced_email = false

# Replaces mailto links with ROT13 equivalent
# TODO: Don't replace plaintext mailto links
invalid_character = '\s"\'>'
email_username = "[^@#{invalid_character}]+"
email_domain = "[^?#{invalid_character}]+"
email_param = "[^&#{invalid_character}]+"
new_content = body.gsub /mailto:(#{email_username}@#{email_domain}(\?#{email_param}(\&#{email_param})*)?)/i do
email = "(?<email>(?<email_username>#{email_username})@#{email_domain})(?<email_params>\\?#{email_param}(\\&#{email_param})*)?"
new_content = body.gsub /<a(?<tag_before>[^>]*)mailto:(?<mailto>#{email})(?<tag_after>[^>]*)>(?<text>.*?)<\/a>/i do
replaced_email = true
email = $1.tr 'A-Za-z','N-ZA-Mn-za-m'
"#email-protection-#{email}"
mailto = Regexp.last_match(:mailto)
email = Regexp.last_match(:email)
text = Regexp.last_match(:text)
email_username = Regexp.last_match(:email_username)
tag_before = Regexp.last_match(:tag_before)
tag_after = Regexp.last_match(:tag_after)

text = text.gsub(email, @options.text_replacement)
mailto = mailto.tr 'A-Za-z','N-ZA-Mn-za-m'
"<a#{tag_before}#{@options.prefix}#{mailto}#{tag_after}>#{text}</a>"
end

# Don't do anything else if there are no emails on the page
Expand All @@ -57,6 +69,8 @@ def rewrite_response(body)
# Reads decoding script
file = File.join(File.dirname(__FILE__), 'rot13_script.html')
script_content = File.read file
script_content = script_content.gsub("#email-protection-", @options.prefix)
script_content = script_content.gsub("@email", @options.text_replacement)

# Appends decoding script at end of body or end of page
if new_content =~ /<\/body>/i
Expand Down
2 changes: 1 addition & 1 deletion lib/middleman-protect-emails/rot13_script.html
Original file line number Diff line number Diff line change
@@ -1 +1 @@
<script type="text/javascript">!function(){try{var a,b,c,d,g=document.getElementsByTagName("a");for(c=0;g.length-c;c++)try{b=g[c].getAttribute("href"),b&&b.indexOf("#email-protection-")>-1&&b.length>19&&(a="",d=19+b.indexOf("#email-protection-"),b.length>d&&(a=b.substr(18).replace(/[a-zA-Z]/g,function(a){return String.fromCharCode(("Z">=a?90:122)>=(a=a.charCodeAt(0)+13)?a:a-26)})),g[c].setAttribute("href","mailto:"+a))}catch(h){}}catch(h){}}();</script>
<script type="text/javascript">!function(){try{for(var e="#email-protection-",t=e.length,r=document.getElementsByTagName("a"),n=0;r.length-n;n++)try{var a=r[n].getAttribute("href");if(!a||a.indexOf(e)<0||a.length<=t+1)continue;var o="",c=t+1+a.indexOf(e);if(a.length>c)for(var i=(o=a.substr(t).replace(/[a-zA-Z]/g,function(e){return String.fromCharCode(("Z">=e?90:122)>=(e=e.charCodeAt(0)+13)?e:e-26)})).match(/(([^@\s"\'>]+)@[^?\s"\'>]+)/i),l=document.createTreeWalker(r[n],NodeFilter.SHOW_TEXT,null,false);l.nextNode();)l.currentNode.textContent=l.currentNode.textContent.replace("@email",i[1]);r[n].setAttribute("href","mailto:"+o)}catch(e){}}catch(e){}}();</script>