sanitize_email 0.3.9 → 1.0.0.alpha2
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.
- data/.rspec +2 -0
- data/CHANGELOG +23 -0
- data/Gemfile +11 -11
- data/Gemfile.lock +129 -0
- data/{LICENSE.txt → MIT-LICENSE} +1 -3
- data/README.rdoc +28 -71
- data/Rakefile +54 -9
- data/VERSION.yml +4 -4
- data/lib/sanitize_email.rb +28 -9
- data/lib/sanitize_email/config.rb +34 -0
- data/lib/sanitize_email/engine.rb +12 -0
- data/lib/sanitize_email/hook.rb +30 -0
- data/lib/sanitize_email/railtie.rb +12 -0
- data/lib/sanitize_email/sanitizer.rb +73 -0
- data/lib/sanitize_email/version.rb +3 -1
- data/sanitize_email.gemspec +80 -21
- data/spec/sanitize_email_spec.rb +68 -0
- data/spec/spec_helper.rb +40 -0
- data/spec/tmp/mail_dump/1343461037_3f3edd7/plain.html +76 -0
- metadata +201 -68
- checksums.yaml +0 -7
- data/.gitignore +0 -20
- data/CHANGELOG.md +0 -27
- data/lib/sanitize_email/custom_environments.rb +0 -21
- data/lib/sanitize_email/sanitize_email.rb +0 -114
- data/test/sample_mailer.rb +0 -24
- data/test/sanitize_email_test.rb +0 -76
- data/test/test_helper.rb +0 -25
@@ -0,0 +1,34 @@
|
|
1
|
+
module SanitizeEmail
|
2
|
+
class Config
|
3
|
+
cattr_accessor :config
|
4
|
+
self.config ||= {
|
5
|
+
# Adds the following class attributes to the classes that include NinthBit::SanitizeEmail
|
6
|
+
:force_sanitize => nil,
|
7
|
+
|
8
|
+
# Specify the BCC addresses for the messages that go out in 'local' environments
|
9
|
+
:sanitized_bcc => nil,
|
10
|
+
|
11
|
+
# Specify the CC addresses for the messages that go out in 'local' environments
|
12
|
+
:sanitized_cc => nil,
|
13
|
+
|
14
|
+
# The recipient addresses for the messages, either as a string (for a single
|
15
|
+
# address) or an array (for multiple addresses) that go out in 'local' environments
|
16
|
+
:sanitized_recipients => nil,
|
17
|
+
|
18
|
+
# Use the 'real' email address as the username for the sanitized email address
|
19
|
+
# e.g. "real@example.com <sanitized@example.com>"
|
20
|
+
:use_actual_email_as_sanitized_user_name => false,
|
21
|
+
|
22
|
+
# Prepend the 'real' email address onto the Subject line of the message
|
23
|
+
# e.g. "real@example.com rest of subject"
|
24
|
+
:use_actual_email_prepended_to_subject => false,
|
25
|
+
|
26
|
+
:local_environments => %w( development test )
|
27
|
+
}
|
28
|
+
|
29
|
+
def self.configure &block
|
30
|
+
yield self.config
|
31
|
+
end
|
32
|
+
|
33
|
+
end
|
34
|
+
end
|
@@ -0,0 +1,12 @@
|
|
1
|
+
#Copyright (c) 2008-12 Peter H. Boling of 9thBit LLC
|
2
|
+
#Released under the MIT license
|
3
|
+
# For Rails >= 3.1
|
4
|
+
module SanitizeEmail
|
5
|
+
class Engine < ::Rails::Engine
|
6
|
+
|
7
|
+
config.to_prepare do
|
8
|
+
ActionMailer::Base.register_interceptor(SanitizeEmail::Hook)
|
9
|
+
end
|
10
|
+
|
11
|
+
end
|
12
|
+
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
#Copyright (c) 2008-12 Peter H. Boling of 9thBit LLC
|
2
|
+
#Released under the MIT license
|
3
|
+
|
4
|
+
module SanitizeEmail
|
5
|
+
class Hook
|
6
|
+
|
7
|
+
include SanitizeEmail::Sanitizer
|
8
|
+
|
9
|
+
def self.delivering_email(message)
|
10
|
+
if self.localish?
|
11
|
+
message.subject = self.subject_override(message.subject, message.to)
|
12
|
+
message.to = self.recipients_override(message.to)
|
13
|
+
message.cc = self.cc_override(message.cc)
|
14
|
+
message.bcc = self.bcc_override(message.bcc)
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
def self.consider_local?
|
19
|
+
SanitizeEmail.local_environments.include?(Rails.env) if defined?(Rails)
|
20
|
+
end
|
21
|
+
|
22
|
+
# This method will be called by the Hook to determine if an override should occur
|
23
|
+
def self.localish?
|
24
|
+
!SanitizeEmail.force_sanitize.nil? ? SanitizeEmail.force_sanitize : self.consider_local?
|
25
|
+
end
|
26
|
+
|
27
|
+
end # end Class Hook
|
28
|
+
end # end Module SanitizeEmail
|
29
|
+
|
30
|
+
|
@@ -0,0 +1,12 @@
|
|
1
|
+
#Copyright (c) 2008-12 Peter H. Boling of 9thBit LLC
|
2
|
+
#Released under the MIT license
|
3
|
+
# For Rails 3.0, which didn't yet support Engines'
|
4
|
+
module SanitizeEmail
|
5
|
+
class Railtie < ::Rails::Railtie
|
6
|
+
|
7
|
+
config.before_configuration do
|
8
|
+
ActionMailer::Base.register_interceptor(SanitizeEmail::Hook)
|
9
|
+
end
|
10
|
+
|
11
|
+
end
|
12
|
+
end
|
@@ -0,0 +1,73 @@
|
|
1
|
+
#Copyright (c) 2008-12 Peter H. Boling of 9thBit LLC
|
2
|
+
#Released under the MIT license
|
3
|
+
module SanitizeEmail
|
4
|
+
module Sanitizer
|
5
|
+
def self.included(base)
|
6
|
+
base.extend SanitizeEmail::Sanitizer::ClassMethods
|
7
|
+
end
|
8
|
+
|
9
|
+
module ClassMethods
|
10
|
+
|
11
|
+
def subject_override(real_subject, actual_addresses)
|
12
|
+
if actual_addresses.nil? || !SanitizeEmail.use_actual_email_prepended_to_subject
|
13
|
+
real_subject
|
14
|
+
else
|
15
|
+
"(#{actual_addresses.join(',').gsub(/@/,' at ').gsub(/[<>]/,'~')}) #{real_subject}"
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
def recipients_override(actual_addresses)
|
20
|
+
override_email(:recipients, actual_addresses)
|
21
|
+
end
|
22
|
+
|
23
|
+
def cc_override(actual_addresses)
|
24
|
+
override_email(:cc, actual_addresses)
|
25
|
+
end
|
26
|
+
|
27
|
+
def bcc_override(actual_addresses)
|
28
|
+
override_email(:bcc, actual_addresses)
|
29
|
+
end
|
30
|
+
|
31
|
+
#######
|
32
|
+
private
|
33
|
+
#######
|
34
|
+
|
35
|
+
def override_email(type, actual_addresses)
|
36
|
+
real_addresses, sanitized_addresses = case type
|
37
|
+
when :recipients
|
38
|
+
[actual_addresses, SanitizeEmail.sanitized_recipients]
|
39
|
+
when :cc
|
40
|
+
[actual_addresses, SanitizeEmail.sanitized_cc]
|
41
|
+
when :bcc
|
42
|
+
[actual_addresses, SanitizeEmail.sanitized_bcc]
|
43
|
+
else raise "sanitize_email error: unknown email override"
|
44
|
+
end
|
45
|
+
# Normalize to an array
|
46
|
+
real_addresses = [real_addresses] unless real_addresses.is_a?(Array)
|
47
|
+
# Normalize to an array
|
48
|
+
sanitized_addresses = [sanitized_addresses] unless sanitized_addresses.is_a?(Array)
|
49
|
+
|
50
|
+
# If there were no original recipients, then we DO NOT override the nil with the sanitized recipients
|
51
|
+
return nil if real_addresses.blank?
|
52
|
+
# If there are no sanitized addresses we can't override!
|
53
|
+
return nil if sanitized_addresses.blank?
|
54
|
+
# If we don't want to inject the actual email in the 'user name' section of the sanitized recipients,
|
55
|
+
# then just return the default sanitized recipients
|
56
|
+
return sanitized_addresses unless SanitizeEmail.use_actual_email_as_sanitized_user_name
|
57
|
+
|
58
|
+
out = real_addresses.inject([]) do |result, real_recipient|
|
59
|
+
if real_recipient.nil?
|
60
|
+
new_recipient = sanitized_addresses
|
61
|
+
else
|
62
|
+
new_recipient = sanitized_addresses.map{|sanitized| "#{real_recipient.gsub(/@/,' at ').gsub(/[<>]/,'~')} <#{sanitized}>"}
|
63
|
+
end
|
64
|
+
result << new_recipient
|
65
|
+
result
|
66
|
+
end.flatten
|
67
|
+
return out
|
68
|
+
end
|
69
|
+
|
70
|
+
end
|
71
|
+
|
72
|
+
end
|
73
|
+
end
|
data/sanitize_email.gemspec
CHANGED
@@ -1,26 +1,85 @@
|
|
1
|
-
#
|
2
|
-
|
3
|
-
|
4
|
-
|
1
|
+
# Generated by jeweler
|
2
|
+
# DO NOT EDIT THIS FILE DIRECTLY
|
3
|
+
# Instead, edit Jeweler::Tasks in Rakefile, and run 'rake gemspec'
|
4
|
+
# -*- encoding: utf-8 -*-
|
5
5
|
|
6
|
-
Gem::Specification.new do |
|
7
|
-
|
8
|
-
|
9
|
-
spec.authors = ["Peter Boling", "John Trupiano", "George Anderson"]
|
10
|
-
spec.email = ["peter.boling@gmail.com", "jtrupiano@gmail.com", "george@benevolentcode.com"]
|
11
|
-
spec.summary = %q{Test an application's email abilities without ever sending a message to actual live addresses}
|
12
|
-
spec.description = %q{Test an application's email abilities without ever sending a message to actual live addresses}
|
13
|
-
spec.homepage = "http://github.com/pboling/sanitize_email"
|
14
|
-
spec.license = "MIT"
|
15
|
-
spec.rdoc_options = ["--charset=UTF-8"]
|
6
|
+
Gem::Specification.new do |s|
|
7
|
+
s.name = "sanitize_email"
|
8
|
+
s.version = "1.0.0.alpha2"
|
16
9
|
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
10
|
+
s.required_rubygems_version = Gem::Requirement.new("> 1.3.1") if s.respond_to? :required_rubygems_version=
|
11
|
+
s.authors = ["Peter Boling", "John Trupiano", "George Anderson"]
|
12
|
+
s.date = "2012-07-28"
|
13
|
+
s.description = "Tool to aid in development, testing, qa, and production troubleshooting of email issues without worrying that emails will get sent to actual live addresses."
|
14
|
+
s.email = ["peter.boling@gmail.com", "jtrupiano@gmail.com", "george@benevolentcode.com"]
|
15
|
+
s.extra_rdoc_files = [
|
16
|
+
"README.rdoc"
|
17
|
+
]
|
18
|
+
s.files = [
|
19
|
+
".rspec",
|
20
|
+
"CHANGELOG",
|
21
|
+
"Gemfile",
|
22
|
+
"Gemfile.lock",
|
23
|
+
"MIT-LICENSE",
|
24
|
+
"README.rdoc",
|
25
|
+
"Rakefile",
|
26
|
+
"VERSION.yml",
|
27
|
+
"init.rb",
|
28
|
+
"lib/sanitize_email.rb",
|
29
|
+
"lib/sanitize_email/config.rb",
|
30
|
+
"lib/sanitize_email/engine.rb",
|
31
|
+
"lib/sanitize_email/hook.rb",
|
32
|
+
"lib/sanitize_email/railtie.rb",
|
33
|
+
"lib/sanitize_email/sanitizer.rb",
|
34
|
+
"lib/sanitize_email/version.rb",
|
35
|
+
"sanitize_email.gemspec",
|
36
|
+
"spec/sanitize_email_spec.rb",
|
37
|
+
"spec/spec_helper.rb",
|
38
|
+
"spec/tmp/mail_dump/1343461037_3f3edd7/plain.html"
|
39
|
+
]
|
40
|
+
s.homepage = "http://github.com/pboling/sanitize_email"
|
41
|
+
s.licenses = ["MIT"]
|
42
|
+
s.require_paths = ["lib"]
|
43
|
+
s.rubygems_version = "1.8.24"
|
44
|
+
s.summary = "Test an application's email abilities without ever sending a message to actual live addresses"
|
21
45
|
|
22
|
-
|
46
|
+
if s.respond_to? :specification_version then
|
47
|
+
s.specification_version = 3
|
23
48
|
|
24
|
-
|
25
|
-
|
49
|
+
if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
|
50
|
+
s.add_runtime_dependency(%q<rails>, ["> 3"])
|
51
|
+
s.add_runtime_dependency(%q<actionmailer>, ["> 3"])
|
52
|
+
s.add_development_dependency(%q<jeweler>, [">= 0"])
|
53
|
+
s.add_development_dependency(%q<letter_opener>, [">= 0"])
|
54
|
+
s.add_development_dependency(%q<launchy>, [">= 0"])
|
55
|
+
s.add_development_dependency(%q<rspec>, [">= 0"])
|
56
|
+
s.add_development_dependency(%q<mail>, [">= 0"])
|
57
|
+
s.add_development_dependency(%q<rdoc>, [">= 3.12"])
|
58
|
+
s.add_development_dependency(%q<reek>, [">= 1.2.8"])
|
59
|
+
s.add_development_dependency(%q<roodi>, [">= 2.1.0"])
|
60
|
+
else
|
61
|
+
s.add_dependency(%q<rails>, ["> 3"])
|
62
|
+
s.add_dependency(%q<actionmailer>, ["> 3"])
|
63
|
+
s.add_dependency(%q<jeweler>, [">= 0"])
|
64
|
+
s.add_dependency(%q<letter_opener>, [">= 0"])
|
65
|
+
s.add_dependency(%q<launchy>, [">= 0"])
|
66
|
+
s.add_dependency(%q<rspec>, [">= 0"])
|
67
|
+
s.add_dependency(%q<mail>, [">= 0"])
|
68
|
+
s.add_dependency(%q<rdoc>, [">= 3.12"])
|
69
|
+
s.add_dependency(%q<reek>, [">= 1.2.8"])
|
70
|
+
s.add_dependency(%q<roodi>, [">= 2.1.0"])
|
71
|
+
end
|
72
|
+
else
|
73
|
+
s.add_dependency(%q<rails>, ["> 3"])
|
74
|
+
s.add_dependency(%q<actionmailer>, ["> 3"])
|
75
|
+
s.add_dependency(%q<jeweler>, [">= 0"])
|
76
|
+
s.add_dependency(%q<letter_opener>, [">= 0"])
|
77
|
+
s.add_dependency(%q<launchy>, [">= 0"])
|
78
|
+
s.add_dependency(%q<rspec>, [">= 0"])
|
79
|
+
s.add_dependency(%q<mail>, [">= 0"])
|
80
|
+
s.add_dependency(%q<rdoc>, [">= 3.12"])
|
81
|
+
s.add_dependency(%q<reek>, [">= 1.2.8"])
|
82
|
+
s.add_dependency(%q<roodi>, [">= 2.1.0"])
|
83
|
+
end
|
26
84
|
end
|
85
|
+
|
@@ -0,0 +1,68 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe SanitizeEmail do
|
4
|
+
|
5
|
+
SanitizeEmail::Config.configure do |config|
|
6
|
+
config[:sanitized_recipients] = 'to@sanitize_email.org'
|
7
|
+
config[:sanitized_bcc] = 'bcc@sanitize_email.org'
|
8
|
+
config[:sanitized_cc] = 'cc@sanitize_email.org'
|
9
|
+
config[:local_environments] = []
|
10
|
+
config[:use_actual_email_prepended_to_subject] = true
|
11
|
+
config[:use_actual_email_as_sanitized_user_name] = true
|
12
|
+
end
|
13
|
+
|
14
|
+
def sanitize_mail_delivery(sanitization_switch = false)
|
15
|
+
# Ensure that localish? will returns sanitization_switch
|
16
|
+
SanitizeEmail::Config.config[:force_sanitize] = sanitization_switch
|
17
|
+
Launchy.should_receive(:open)
|
18
|
+
mail = Mail.deliver do
|
19
|
+
from 'from@example.org'
|
20
|
+
to 'to@example.org'
|
21
|
+
cc 'cc@example.org'
|
22
|
+
reply_to 'reply_to@example.org'
|
23
|
+
subject 'original subject'
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
before(:each) do
|
28
|
+
Launchy.stub(:open)
|
29
|
+
location = File.expand_path('../tmp/mail_dump', __FILE__)
|
30
|
+
FileUtils.rm_rf(location)
|
31
|
+
Mail.defaults do
|
32
|
+
delivery_method LetterOpener::DeliveryMethod, :location => location
|
33
|
+
end
|
34
|
+
Mail.register_interceptor(SanitizeEmail::Hook)
|
35
|
+
@location = location
|
36
|
+
end
|
37
|
+
|
38
|
+
context "localish? is false" do
|
39
|
+
it "alters nothing" do
|
40
|
+
sanitize_mail_delivery(false)
|
41
|
+
# All the email gets dumped to file once for each type of recipient (:to, :cc, :bcc)
|
42
|
+
# Each file is identical, so we only need to check one of them:
|
43
|
+
email = File.read(Dir["#{@location}/*/plain.html"].first)
|
44
|
+
email.should have_from("from@example.org")
|
45
|
+
email.should have_to("to@example.org")
|
46
|
+
# Letter Opener won't let us test the cc
|
47
|
+
#email.should have_cc("cc@example.org")
|
48
|
+
# Letter Opener won't let us test the bcc
|
49
|
+
#email.should have_bcc("cc@example.org")
|
50
|
+
email.should have_subject("original subject")
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
context "localish? is true" do
|
55
|
+
it "should override" do
|
56
|
+
sanitize_mail_delivery(true)
|
57
|
+
# All the email gets dumped to file once for each type of recipient (:to, :cc, :bcc)
|
58
|
+
# Each file is identical, so we only need to check one of them:
|
59
|
+
email = File.read(Dir["#{@location}/*/plain.html"].first)
|
60
|
+
email.should have_from("from@example.org")
|
61
|
+
# Letter Opener won't let us test the to when the to has a 'user name'
|
62
|
+
#email.should have_to("~to at example.org~ <to@sanitize_email.org>")
|
63
|
+
# Letter Opener won't let us test the bcc
|
64
|
+
#email.should have_cc("cc@sanitize_email.org")
|
65
|
+
email.should have_subject("(to at example.org) original subject")
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,40 @@
|
|
1
|
+
require 'sanitize_email'
|
2
|
+
require 'launchy'
|
3
|
+
require 'mail'
|
4
|
+
require 'rails'
|
5
|
+
require 'letter_opener'
|
6
|
+
|
7
|
+
# See http://rubydoc.info/gems/rspec-core/RSpec/Core/Configuration
|
8
|
+
RSpec.configure do |config|
|
9
|
+
config.treat_symbols_as_metadata_keys_with_true_values = true
|
10
|
+
config.run_all_when_everything_filtered = true
|
11
|
+
#config.filter_run :focus
|
12
|
+
end
|
13
|
+
|
14
|
+
RSpec::Matchers.define :have_from do |from|
|
15
|
+
match do |container|
|
16
|
+
container =~ Regexp.new(Regexp.escape(from))
|
17
|
+
end
|
18
|
+
end
|
19
|
+
RSpec::Matchers.define :have_to do |to|
|
20
|
+
match do |container|
|
21
|
+
container =~ Regexp.new(Regexp.escape(to))
|
22
|
+
end
|
23
|
+
end
|
24
|
+
RSpec::Matchers.define :have_cc do |cc|
|
25
|
+
match do |container|
|
26
|
+
container =~ Regexp.new(Regexp.escape(cc))
|
27
|
+
end
|
28
|
+
end
|
29
|
+
# The ActionMailer :file delivery method never prints bcc recipients...
|
30
|
+
# so not testable as such, but with letter_opener we can work magic
|
31
|
+
RSpec::Matchers.define :have_bcc do |bcc|
|
32
|
+
match do |container|
|
33
|
+
container =~ Regexp.new(Regexp.escape(bcc))
|
34
|
+
end
|
35
|
+
end
|
36
|
+
RSpec::Matchers.define :have_subject do |subject|
|
37
|
+
match do |container|
|
38
|
+
container =~ Regexp.new(Regexp.escape(subject))
|
39
|
+
end
|
40
|
+
end
|
@@ -0,0 +1,76 @@
|
|
1
|
+
<style type="text/css">
|
2
|
+
#message_headers {
|
3
|
+
position: absolute;
|
4
|
+
top: 0px;
|
5
|
+
left: 0;
|
6
|
+
width: 100%;
|
7
|
+
height: 85px;
|
8
|
+
padding: 10px 0 0 0;
|
9
|
+
margin: 0;
|
10
|
+
background: #fff;
|
11
|
+
font-size: 12px;
|
12
|
+
font-family: "Lucida Grande";
|
13
|
+
border-bottom: 1px solid #dedede;
|
14
|
+
overflow: hidden;
|
15
|
+
}
|
16
|
+
|
17
|
+
#message_headers dl {
|
18
|
+
margin: 0;
|
19
|
+
padding: 0;
|
20
|
+
}
|
21
|
+
|
22
|
+
#message_headers dt {
|
23
|
+
width: 60px;
|
24
|
+
padding: 1px;
|
25
|
+
float: left;
|
26
|
+
text-align: right;
|
27
|
+
font-weight: bold;
|
28
|
+
color: #7f7f7f;
|
29
|
+
}
|
30
|
+
|
31
|
+
#message_headers dd {
|
32
|
+
margin-left: 70px;
|
33
|
+
padding: 1px;
|
34
|
+
}
|
35
|
+
|
36
|
+
#message_headers p.alternate {
|
37
|
+
position: absolute;
|
38
|
+
top: 0;
|
39
|
+
right: 15px;
|
40
|
+
}
|
41
|
+
|
42
|
+
#message_headers p.alternate a {
|
43
|
+
color: #09c;
|
44
|
+
}
|
45
|
+
|
46
|
+
pre#message_body {
|
47
|
+
padding: 10px;
|
48
|
+
word-wrap: break-word;
|
49
|
+
}
|
50
|
+
|
51
|
+
body {
|
52
|
+
margin-top: 96px;
|
53
|
+
}
|
54
|
+
</style>
|
55
|
+
|
56
|
+
<div id="message_headers">
|
57
|
+
<dl>
|
58
|
+
<dt>From:</dt>
|
59
|
+
<dd>from@example.org</dd>
|
60
|
+
|
61
|
+
<dt>Subject:</dt>
|
62
|
+
<dd><strong>(to at example.org) original subject</strong></dd>
|
63
|
+
|
64
|
+
<dt>Date:</dt>
|
65
|
+
<dd>Jul 28, 2012 03:37:17 AM EDT</dd>
|
66
|
+
|
67
|
+
<dt>To:</dt>
|
68
|
+
<dd>to@sanitize_email.org</dd>
|
69
|
+
</dl>
|
70
|
+
|
71
|
+
|
72
|
+
</div>
|
73
|
+
|
74
|
+
|
75
|
+
<pre id="message_body"></pre>
|
76
|
+
|