mail_safe 0.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.
- data/LICENSE +20 -0
- data/README.rdoc +65 -0
- data/VERSION.yml +4 -0
- data/lib/mail_safe.rb +8 -0
- data/lib/mail_safe/action_mailer.rb +14 -0
- data/lib/mail_safe/address_replacer.rb +113 -0
- data/lib/mail_safe/config.rb +25 -0
- data/test/config_test.rb +75 -0
- data/test/mailer_test.rb +88 -0
- data/test/mailers/test_mailer.rb +38 -0
- data/test/test_helper.rb +22 -0
- metadata +106 -0
data/LICENSE
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
Copyright (c) 2009 Myron Marston
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
4
|
+
a copy of this software and associated documentation files (the
|
5
|
+
"Software"), to deal in the Software without restriction, including
|
6
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
7
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
8
|
+
permit persons to whom the Software is furnished to do so, subject to
|
9
|
+
the following conditions:
|
10
|
+
|
11
|
+
The above copyright notice and this permission notice shall be
|
12
|
+
included in all copies or substantial portions of the Software.
|
13
|
+
|
14
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
15
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
16
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
17
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
18
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
19
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
20
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.rdoc
ADDED
@@ -0,0 +1,65 @@
|
|
1
|
+
= mail_safe
|
2
|
+
|
3
|
+
Mail safe provides a safety net while you're developing an application that uses ActionMailer.
|
4
|
+
It keeps emails from escaping into the wild.
|
5
|
+
|
6
|
+
Once you've installed and configured this gem, you can rest assure that your app won't send
|
7
|
+
emails to external email addresses. Instead, emails that would normally be delivered to external
|
8
|
+
addresses will be sent to an address of your choosing, and the body of the email will be appended
|
9
|
+
with a note stating where the email was originally intended to go.
|
10
|
+
|
11
|
+
== Download
|
12
|
+
|
13
|
+
Github: http://github.com/myronmarston/mail_safe/tree/master
|
14
|
+
|
15
|
+
Gem:
|
16
|
+
gem install myronmarston-mail_safe --source http://gems.github.com
|
17
|
+
|
18
|
+
== Usage
|
19
|
+
|
20
|
+
Load the gem in your non-production environments using Rails' 2.1+ gem support. For example, I'm loading this in
|
21
|
+
config/environments/development.rb and config/environments/staging.rb:
|
22
|
+
|
23
|
+
config.gem 'myronmarston-mail_safe', :lib => 'mail_safe', :source => 'http://gems.github.com'
|
24
|
+
|
25
|
+
Be sure not to load this in your production or test environment, otherwise, your emails won't be sent to the proper
|
26
|
+
recipients. (The Rails test environment ensures that no emails are ever sent.)
|
27
|
+
|
28
|
+
Next, configure mail safe. Create a file at config/initializers/mail_safe.rb, similar to the following:
|
29
|
+
|
30
|
+
if defined?(MailSafe::Config)
|
31
|
+
MailSafe::Config.internal_address_definition = /.*@my-domain\.com/i
|
32
|
+
MailSafe::Config.replacement_address = 'me@my-domain.com'
|
33
|
+
end
|
34
|
+
|
35
|
+
The internal address definition determines which addresses will be ignored (i.e. sent normally) and which will be replaced. Email being sent to internal
|
36
|
+
addresses will be sent normally; all other email addresses will be replaced by the replacement address.
|
37
|
+
|
38
|
+
These settings can also take procs if you need something more flexible:
|
39
|
+
|
40
|
+
if defined?(MailSafe::Config)
|
41
|
+
# Emails sent to addresses longer than 15 characters long will be sent to the replacement address instead.
|
42
|
+
MailSafe::Config.internal_address_definition = lambda { |address| address.size <= 15 }
|
43
|
+
|
44
|
+
# Useful if your mail server allows + dynamic email addresses like gmail.
|
45
|
+
MailSafe::Config.replacement_address = lambda { |address| "my-address+#{address.gsub(/[\w\-.]/, '_')}@gmail.com" }
|
46
|
+
end
|
47
|
+
|
48
|
+
When mail safe replaces an email address, it appends a notice to the bottom of the email body, such as:
|
49
|
+
|
50
|
+
**************************************************
|
51
|
+
This email originally had different recipients,
|
52
|
+
but MailSafe has prevented it from being sent to them.
|
53
|
+
|
54
|
+
The original recipients were:
|
55
|
+
- to:
|
56
|
+
- external-address-1@domain.com
|
57
|
+
- external-address-2@domain.com
|
58
|
+
- cc:
|
59
|
+
- external-address-3@domain.com
|
60
|
+
|
61
|
+
**************************************************
|
62
|
+
|
63
|
+
== Copyright
|
64
|
+
|
65
|
+
Copyright (c) 2009 Myron Marston, Kashless.org. See LICENSE for details.
|
data/VERSION.yml
ADDED
data/lib/mail_safe.rb
ADDED
@@ -0,0 +1,8 @@
|
|
1
|
+
require 'active_support'
|
2
|
+
require 'action_mailer'
|
3
|
+
|
4
|
+
require 'mail_safe/config'
|
5
|
+
require 'mail_safe/action_mailer'
|
6
|
+
require 'mail_safe/address_replacer'
|
7
|
+
|
8
|
+
ActionMailer::Base.send(:include, MailSafe::ActionMailer) unless ActionMailer::Base.ancestors.include?(MailSafe::ActionMailer)
|
@@ -0,0 +1,14 @@
|
|
1
|
+
module MailSafe
|
2
|
+
module ActionMailer
|
3
|
+
def self.included(base)
|
4
|
+
base.class_eval do
|
5
|
+
alias_method_chain :deliver!, :mail_safe
|
6
|
+
end
|
7
|
+
end
|
8
|
+
|
9
|
+
def deliver_with_mail_safe!(mail = @mail)
|
10
|
+
MailSafe::AddressReplacer.replace_external_addresses(mail) if mail
|
11
|
+
deliver_without_mail_safe!(mail)
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
@@ -0,0 +1,113 @@
|
|
1
|
+
module MailSafe
|
2
|
+
class AddressReplacer
|
3
|
+
class << self
|
4
|
+
include ::ActionMailer::Utils
|
5
|
+
ADDRESS_TYPES = [:to, :cc, :bcc].freeze
|
6
|
+
|
7
|
+
def replace_external_addresses(mail)
|
8
|
+
replaced_addresses = {}
|
9
|
+
|
10
|
+
ADDRESS_TYPES.each do |address_type|
|
11
|
+
if addresses = mail.send(address_type)
|
12
|
+
new_addresses = []
|
13
|
+
|
14
|
+
addresses.each do |a|
|
15
|
+
new_addresses << if MailSafe::Config.is_internal_address?(a)
|
16
|
+
a
|
17
|
+
else
|
18
|
+
(replaced_addresses[address_type] ||= []) << a
|
19
|
+
MailSafe::Config.get_replacement_address(a)
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
mail.send("#{address_type}=", new_addresses)
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
self.add_body_postscript(mail, replaced_addresses)
|
28
|
+
end
|
29
|
+
|
30
|
+
protected
|
31
|
+
|
32
|
+
def add_body_postscript(part, replaced_addresses)
|
33
|
+
return unless replaced_addresses.size > 0
|
34
|
+
|
35
|
+
case part.content_type
|
36
|
+
when 'text/plain' then add_text_postscript(part, replaced_addresses)
|
37
|
+
when 'text/html' then add_html_postscript(part, replaced_addresses)
|
38
|
+
end
|
39
|
+
|
40
|
+
part.parts.each { |p| add_body_postscript(p, replaced_addresses) }
|
41
|
+
end
|
42
|
+
|
43
|
+
def add_text_postscript(part, replaced_addresses)
|
44
|
+
address_type_postscripts = []
|
45
|
+
ADDRESS_TYPES.each do |address_type|
|
46
|
+
next unless addresses = replaced_addresses[address_type]
|
47
|
+
address_type_postscripts << "- #{address_type}:\n - #{addresses.join("\n - ")}"
|
48
|
+
end
|
49
|
+
|
50
|
+
postscript = <<-EOS
|
51
|
+
|
52
|
+
|
53
|
+
**************************************************
|
54
|
+
This email originally had different recipients,
|
55
|
+
but MailSafe has prevented it from being sent to them.
|
56
|
+
|
57
|
+
The original recipients were:
|
58
|
+
#{address_type_postscripts.join("\n\n")}
|
59
|
+
|
60
|
+
**************************************************
|
61
|
+
EOS
|
62
|
+
|
63
|
+
set_part_body(part, part.body + postscript)
|
64
|
+
end
|
65
|
+
|
66
|
+
def add_html_postscript(part, replaced_addresses)
|
67
|
+
address_type_postscripts = []
|
68
|
+
ADDRESS_TYPES.each do |address_type|
|
69
|
+
next unless addresses = replaced_addresses[address_type]
|
70
|
+
address_type_postscripts << "#{address_type}:<ul>\n<li>#{addresses.join("</li>\n<li>")}</li>\n</ul>"
|
71
|
+
end
|
72
|
+
|
73
|
+
postscript = <<-EOS
|
74
|
+
<div class="mail-safe-postscript">
|
75
|
+
<hr />
|
76
|
+
|
77
|
+
<p>
|
78
|
+
This email originally had different recipients,
|
79
|
+
but MailSafe has prevented it from being sent to them.
|
80
|
+
</p>
|
81
|
+
|
82
|
+
<p>
|
83
|
+
The original recipients were:
|
84
|
+
</p>
|
85
|
+
|
86
|
+
<ul>
|
87
|
+
<li>
|
88
|
+
#{address_type_postscripts.join("</li>\n<li>")}
|
89
|
+
</li>
|
90
|
+
</ul>
|
91
|
+
|
92
|
+
<hr/ >
|
93
|
+
</div>
|
94
|
+
EOS
|
95
|
+
|
96
|
+
set_part_body(part, part.body + postscript)
|
97
|
+
end
|
98
|
+
|
99
|
+
def set_part_body(part, body)
|
100
|
+
# taken from action mailer:
|
101
|
+
# http://github.com/rails/rails/blob/05d7409ae5fd423be6f747ad553f659fcecbf548/actionmailer/lib/action_mailer/part.rb#L58-65
|
102
|
+
case part.content_transfer_encoding.to_s.downcase
|
103
|
+
when "base64" then
|
104
|
+
part.body = TMail::Base64.folding_encode(body)
|
105
|
+
when "quoted-printable"
|
106
|
+
part.body = [normalize_new_lines(body)].pack("M*")
|
107
|
+
else
|
108
|
+
part.body = body
|
109
|
+
end
|
110
|
+
end
|
111
|
+
end
|
112
|
+
end
|
113
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
module MailSafe
|
2
|
+
class InvalidConfigSettingError < StandardError; end
|
3
|
+
|
4
|
+
class Config
|
5
|
+
cattr_accessor :internal_address_definition
|
6
|
+
|
7
|
+
def self.is_internal_address?(address)
|
8
|
+
case internal_address_definition
|
9
|
+
when Regexp then address =~ internal_address_definition
|
10
|
+
when Proc then internal_address_definition.call(address)
|
11
|
+
else raise InvalidConfigSettingError.new("internal_address_definition must be a Regexp or Proc, but was: #{internal_address_definition.class.to_s}")
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
cattr_accessor :replacement_address
|
16
|
+
|
17
|
+
def self.get_replacement_address(original_address)
|
18
|
+
case replacement_address
|
19
|
+
when String then replacement_address
|
20
|
+
when Proc then replacement_address.call(original_address)
|
21
|
+
else raise InvalidConfigSettingError.new("replacement_address must be a String or Proc, but was: #{replacement_address.class.to_s}")
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
data/test/config_test.rb
ADDED
@@ -0,0 +1,75 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
|
3
|
+
class ConfigTest < Test::Unit::TestCase
|
4
|
+
context 'When internal_address_definition is set to a regexp, #is_internal_address?' do
|
5
|
+
setup do
|
6
|
+
MailSafe::Config.internal_address_definition = /.*@example\.com/
|
7
|
+
end
|
8
|
+
|
9
|
+
should 'return true if the address matches the regexp' do
|
10
|
+
assert MailSafe::Config.is_internal_address?('someone@example.com')
|
11
|
+
end
|
12
|
+
|
13
|
+
should 'return false if the address does not match the regexp' do
|
14
|
+
assert !MailSafe::Config.is_internal_address?('someone@another-domain.com')
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
context 'When internal_address_definition is set to a lambda, #is_internal_address?' do
|
19
|
+
setup do
|
20
|
+
MailSafe::Config.internal_address_definition = lambda { |address| address.size < 15 }
|
21
|
+
end
|
22
|
+
|
23
|
+
should 'return true if the lambda returns true for the given address' do
|
24
|
+
assert MailSafe::Config.is_internal_address?('abc@foo.com')
|
25
|
+
end
|
26
|
+
|
27
|
+
should 'return false if the lambda returns false for the given address' do
|
28
|
+
assert !MailSafe::Config.is_internal_address?('a-long-address@example.com')
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
context 'When internal_address_definition is not set, #is_internal_address?' do
|
33
|
+
setup do
|
34
|
+
MailSafe::Config.internal_address_definition = nil
|
35
|
+
end
|
36
|
+
|
37
|
+
should 'raise an error' do
|
38
|
+
assert_raise MailSafe::InvalidConfigSettingError do
|
39
|
+
MailSafe::Config.is_internal_address?('abc@foo.com')
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
context 'When replacement_address is set to a string, #get_replacement_address' do
|
45
|
+
setup do
|
46
|
+
MailSafe::Config.replacement_address = 'me@mydomain.com'
|
47
|
+
end
|
48
|
+
|
49
|
+
should 'return the configured replacement address' do
|
50
|
+
assert_equal 'me@mydomain.com', MailSafe::Config.get_replacement_address('you@example.com')
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
context 'When replacement_address is set to a proc, #get_replacement_address' do
|
55
|
+
setup do
|
56
|
+
MailSafe::Config.replacement_address = lambda { |address| "me+#{address.split('@').first}@mydomain.com" }
|
57
|
+
end
|
58
|
+
|
59
|
+
should 'return the configured replacement address' do
|
60
|
+
assert_equal 'me+you@mydomain.com', MailSafe::Config.get_replacement_address('you@example.com')
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
context 'When replacement_address is not set, #get_replacement_address' do
|
65
|
+
setup do
|
66
|
+
MailSafe::Config.replacement_address = nil
|
67
|
+
end
|
68
|
+
|
69
|
+
should 'raise an error' do
|
70
|
+
assert_raise MailSafe::InvalidConfigSettingError do
|
71
|
+
MailSafe::Config.get_replacement_address('you@example.com')
|
72
|
+
end
|
73
|
+
end
|
74
|
+
end
|
75
|
+
end
|
data/test/mailer_test.rb
ADDED
@@ -0,0 +1,88 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
|
3
|
+
class MailerTest < Test::Unit::TestCase
|
4
|
+
TEXT_POSTSCRIPT_PHRASE = /The original recipients were:/
|
5
|
+
HTML_POSTSCRIPT_PHRASE = /<p>\s+The original recipients were:\s+<\/p>/
|
6
|
+
|
7
|
+
context 'Delivering a plain text email to internal addresses' do
|
8
|
+
setup do
|
9
|
+
MailSafe::Config.stubs(:is_internal_address? => true)
|
10
|
+
@email = TestMailer.deliver_plain_text_message(:to => 'internal-to@address.com', :bcc => 'internal-bcc@address.com', :cc => 'internal-cc@address.com')
|
11
|
+
end
|
12
|
+
|
13
|
+
should 'send the email to the original addresses' do
|
14
|
+
assert_equal ['internal-to@address.com'], @email.to
|
15
|
+
assert_equal ['internal-cc@address.com'], @email.cc
|
16
|
+
assert_equal ['internal-bcc@address.com'], @email.bcc
|
17
|
+
end
|
18
|
+
|
19
|
+
should 'not add a post script to the body' do
|
20
|
+
assert_no_match TEXT_POSTSCRIPT_PHRASE, @email.body
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
context 'Delivering a plain text email to external addresses' do
|
25
|
+
setup do
|
26
|
+
MailSafe::Config.stubs(:is_internal_address? => false, :get_replacement_address => 'replacement@example.com')
|
27
|
+
@email = TestMailer.deliver_plain_text_message(:to => 'internal-to@address.com', :bcc => 'internal-bcc@address.com', :cc => 'internal-cc@address.com')
|
28
|
+
end
|
29
|
+
|
30
|
+
should 'send the email to the replacement address' do
|
31
|
+
assert_equal ['replacement@example.com'], @email.to
|
32
|
+
assert_equal ['replacement@example.com'], @email.cc
|
33
|
+
assert_equal ['replacement@example.com'], @email.bcc
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
def deliver_email_with_mix_of_internal_and_external_addresses(delivery_method)
|
38
|
+
MailSafe::Config.internal_address_definition = /internal/
|
39
|
+
MailSafe::Config.replacement_address = 'internal@domain.com'
|
40
|
+
@email = TestMailer.send(delivery_method,
|
41
|
+
{
|
42
|
+
:to => ['internal1@address.com', 'external1@address.com'],
|
43
|
+
:cc => ['internal1@address.com', 'internal2@address.com'],
|
44
|
+
:bcc => ['external1@address.com', 'external2@address.com']
|
45
|
+
}
|
46
|
+
)
|
47
|
+
end
|
48
|
+
|
49
|
+
context 'Delivering a plain text email to a mix of internal and external addresses' do
|
50
|
+
setup do
|
51
|
+
deliver_email_with_mix_of_internal_and_external_addresses(:deliver_plain_text_message)
|
52
|
+
end
|
53
|
+
|
54
|
+
should 'send the email to the appropriate address' do
|
55
|
+
assert_same_elements ['internal1@address.com', 'internal@domain.com'], @email.to
|
56
|
+
assert_same_elements ['internal1@address.com', 'internal2@address.com'], @email.cc
|
57
|
+
assert_same_elements ['internal@domain.com', 'internal@domain.com'], @email.bcc
|
58
|
+
end
|
59
|
+
|
60
|
+
should 'add a plain text post script to the body' do
|
61
|
+
assert_match TEXT_POSTSCRIPT_PHRASE, @email.body
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
context 'Delivering an html email to a mix of internal and external addresses' do
|
66
|
+
setup do
|
67
|
+
deliver_email_with_mix_of_internal_and_external_addresses(:deliver_html_message)
|
68
|
+
end
|
69
|
+
|
70
|
+
should 'add an html post script to the body' do
|
71
|
+
assert_match HTML_POSTSCRIPT_PHRASE, @email.body
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
75
|
+
context 'Delivering a multipart email to a mix of internal and external addresses' do
|
76
|
+
setup do
|
77
|
+
deliver_email_with_mix_of_internal_and_external_addresses(:deliver_multipart_message)
|
78
|
+
end
|
79
|
+
|
80
|
+
should 'add an text post script to the body of the text part' do
|
81
|
+
assert_match TEXT_POSTSCRIPT_PHRASE, @email.parts.detect { |p| p.content_type == 'text/plain' }.body
|
82
|
+
end
|
83
|
+
|
84
|
+
should 'add an html post script to the body of the html part' do
|
85
|
+
assert_match HTML_POSTSCRIPT_PHRASE, @email.parts.detect { |p| p.content_type == 'text/html' }.body
|
86
|
+
end
|
87
|
+
end
|
88
|
+
end
|
@@ -0,0 +1,38 @@
|
|
1
|
+
class TestMailer < ActionMailer::Base
|
2
|
+
# template root must be set for multipart emails, or ActionMailer will throw an exception.
|
3
|
+
self.template_root = File.dirname(__FILE__)
|
4
|
+
|
5
|
+
def plain_text_message(options)
|
6
|
+
setup_recipients(options)
|
7
|
+
from 'test@mailsafe.org'
|
8
|
+
subject "Plain text Message Test"
|
9
|
+
body "Here is the message body."
|
10
|
+
end
|
11
|
+
|
12
|
+
def html_message(options)
|
13
|
+
setup_recipients(options)
|
14
|
+
from 'test@mailsafe.org'
|
15
|
+
subject "Html Message Test"
|
16
|
+
body "<p>Here is the message body.</p>"
|
17
|
+
content_type 'text/html'
|
18
|
+
end
|
19
|
+
|
20
|
+
def multipart_message(options)
|
21
|
+
setup_recipients(options)
|
22
|
+
from 'test@mailsafe.org'
|
23
|
+
subject "Html Message Test"
|
24
|
+
|
25
|
+
content_type 'multipart/alternative'
|
26
|
+
|
27
|
+
part :content_type => 'text/plain', :body => "Here is the message body."
|
28
|
+
part :content_type => 'text/html', :body => "<p>Here is the message body.</p>"
|
29
|
+
end
|
30
|
+
|
31
|
+
protected
|
32
|
+
|
33
|
+
def setup_recipients(options)
|
34
|
+
recipients options[:to]
|
35
|
+
cc options[:cc]
|
36
|
+
bcc options[:bcc]
|
37
|
+
end
|
38
|
+
end
|
data/test/test_helper.rb
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'test/unit'
|
3
|
+
require 'shoulda'
|
4
|
+
require 'mocha'
|
5
|
+
|
6
|
+
begin
|
7
|
+
require 'ruby-debug'
|
8
|
+
Debugger.start
|
9
|
+
Debugger.settings[:autoeval] = true if Debugger.respond_to?(:settings)
|
10
|
+
rescue LoadError
|
11
|
+
# ruby-debug wasn't available so neither can the debugging be
|
12
|
+
end
|
13
|
+
|
14
|
+
$LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
|
15
|
+
$LOAD_PATH.unshift(File.dirname(__FILE__))
|
16
|
+
require 'mail_safe'
|
17
|
+
require 'mailers/test_mailer'
|
18
|
+
|
19
|
+
ActionMailer::Base.delivery_method = :test
|
20
|
+
|
21
|
+
class Test::Unit::TestCase
|
22
|
+
end
|
metadata
ADDED
@@ -0,0 +1,106 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: mail_safe
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Myron Marston
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
|
12
|
+
date: 2009-08-28 00:00:00 -07:00
|
13
|
+
default_executable:
|
14
|
+
dependencies:
|
15
|
+
- !ruby/object:Gem::Dependency
|
16
|
+
name: activesupport
|
17
|
+
type: :runtime
|
18
|
+
version_requirement:
|
19
|
+
version_requirements: !ruby/object:Gem::Requirement
|
20
|
+
requirements:
|
21
|
+
- - ">="
|
22
|
+
- !ruby/object:Gem::Version
|
23
|
+
version: "0"
|
24
|
+
version:
|
25
|
+
- !ruby/object:Gem::Dependency
|
26
|
+
name: actionmailer
|
27
|
+
type: :runtime
|
28
|
+
version_requirement:
|
29
|
+
version_requirements: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - ">="
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: "0"
|
34
|
+
version:
|
35
|
+
- !ruby/object:Gem::Dependency
|
36
|
+
name: Shoulda
|
37
|
+
type: :development
|
38
|
+
version_requirement:
|
39
|
+
version_requirements: !ruby/object:Gem::Requirement
|
40
|
+
requirements:
|
41
|
+
- - ">="
|
42
|
+
- !ruby/object:Gem::Version
|
43
|
+
version: "0"
|
44
|
+
version:
|
45
|
+
- !ruby/object:Gem::Dependency
|
46
|
+
name: mocha
|
47
|
+
type: :development
|
48
|
+
version_requirement:
|
49
|
+
version_requirements: !ruby/object:Gem::Requirement
|
50
|
+
requirements:
|
51
|
+
- - ">="
|
52
|
+
- !ruby/object:Gem::Version
|
53
|
+
version: "0"
|
54
|
+
version:
|
55
|
+
description:
|
56
|
+
email: myron.marston@gmail.com
|
57
|
+
executables: []
|
58
|
+
|
59
|
+
extensions: []
|
60
|
+
|
61
|
+
extra_rdoc_files:
|
62
|
+
- README.rdoc
|
63
|
+
- LICENSE
|
64
|
+
files:
|
65
|
+
- README.rdoc
|
66
|
+
- VERSION.yml
|
67
|
+
- lib/mail_safe/action_mailer.rb
|
68
|
+
- lib/mail_safe/address_replacer.rb
|
69
|
+
- lib/mail_safe/config.rb
|
70
|
+
- lib/mail_safe.rb
|
71
|
+
- test/config_test.rb
|
72
|
+
- test/mailer_test.rb
|
73
|
+
- test/mailers/test_mailer.rb
|
74
|
+
- test/test_helper.rb
|
75
|
+
- LICENSE
|
76
|
+
has_rdoc: true
|
77
|
+
homepage: http://github.com/myronmarston/mail_safe
|
78
|
+
licenses: []
|
79
|
+
|
80
|
+
post_install_message:
|
81
|
+
rdoc_options:
|
82
|
+
- --inline-source
|
83
|
+
- --charset=UTF-8
|
84
|
+
require_paths:
|
85
|
+
- lib
|
86
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
87
|
+
requirements:
|
88
|
+
- - ">="
|
89
|
+
- !ruby/object:Gem::Version
|
90
|
+
version: "0"
|
91
|
+
version:
|
92
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
93
|
+
requirements:
|
94
|
+
- - ">="
|
95
|
+
- !ruby/object:Gem::Version
|
96
|
+
version: "0"
|
97
|
+
version:
|
98
|
+
requirements: []
|
99
|
+
|
100
|
+
rubyforge_project:
|
101
|
+
rubygems_version: 1.3.5
|
102
|
+
signing_key:
|
103
|
+
specification_version: 2
|
104
|
+
summary: Keep your ActionMailer emails from escaping into the wild during development.
|
105
|
+
test_files: []
|
106
|
+
|