sanitize_email 2.0.2 → 2.0.4
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 +4 -4
- checksums.yaml.gz.sig +3 -0
- data/CHANGELOG.md +82 -12
- data/CODE_OF_CONDUCT.md +84 -0
- data/CONTRIBUTING.md +47 -0
- data/{LICENSE → LICENSE.txt} +1 -1
- data/README.md +371 -58
- data/SECURITY.md +15 -0
- data/lib/sanitize_email/bleach.rb +13 -8
- data/lib/sanitize_email/config.rb +20 -20
- data/lib/sanitize_email/deprecation.rb +6 -6
- data/lib/sanitize_email/engine.rb +1 -1
- data/lib/sanitize_email/mail_ext.rb +2 -0
- data/lib/sanitize_email/mail_header_tools.rb +19 -15
- data/lib/sanitize_email/overridden_addresses.rb +77 -19
- data/lib/sanitize_email/railtie.rb +1 -1
- data/lib/sanitize_email/rspec_matchers.rb +55 -31
- data/lib/sanitize_email/test_helpers.rb +6 -6
- data/lib/sanitize_email/version.rb +4 -2
- data/lib/sanitize_email.rb +28 -18
- data.tar.gz.sig +0 -0
- metadata +70 -90
- metadata.gz.sig +0 -0
- data/.coveralls.yml +0 -1
- data/.gitignore +0 -12
- data/.pryrc +0 -11
- data/.reek +0 -9
- data/.rspec +0 -2
- data/.rubocop.yml +0 -73
- data/.rubocop_rspec.yml +0 -35
- data/.rubocop_todo.yml +0 -21
- data/.ruby-gemset +0 -1
- data/.ruby-version +0 -1
- data/.travis.yml +0 -71
- data/Appraisals +0 -29
- data/Gemfile +0 -22
- data/REEK +0 -2
- data/Rakefile +0 -52
- data/gemfiles/rails_4_2.gemfile +0 -17
- data/gemfiles/rails_5_0.gemfile +0 -17
- data/gemfiles/rails_5_1.gemfile +0 -17
- data/gemfiles/rails_5_2.gemfile +0 -17
- data/init.rb +0 -3
- data/sanitize_email.gemspec +0 -49
- data/spec/sanitize_email_spec.rb +0 -944
- data/spec/spec_helper.rb +0 -28
@@ -1,6 +1,6 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
# Copyright (c) 2008-
|
3
|
+
# Copyright (c) 2008 - 2018, 2020, 2022, 2024 Peter H. Boling of RailsBling.com
|
4
4
|
# Released under the MIT license
|
5
5
|
|
6
6
|
module SanitizeEmail
|
@@ -16,48 +16,48 @@ module SanitizeEmail
|
|
16
16
|
DEFAULTS = {
|
17
17
|
# Specify the BCC addresses for the messages
|
18
18
|
# that go out in "local" environments
|
19
|
-
:
|
19
|
+
sanitized_bcc: nil,
|
20
20
|
|
21
21
|
# Specify the CC addresses for the messages
|
22
22
|
# that go out in "local" environments
|
23
|
-
:
|
23
|
+
sanitized_cc: nil,
|
24
24
|
|
25
25
|
# The recipient addresses for the messages,
|
26
26
|
# either as a string (for a single address)
|
27
27
|
# or an array (for multiple addresses)
|
28
28
|
# that go out in "local" environments
|
29
|
-
:
|
29
|
+
sanitized_to: nil,
|
30
30
|
|
31
|
-
#
|
32
|
-
:
|
31
|
+
# an allow list
|
32
|
+
good_list: nil,
|
33
33
|
|
34
|
-
# a
|
35
|
-
:
|
34
|
+
# a block list
|
35
|
+
bad_list: nil,
|
36
36
|
|
37
|
-
:
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
37
|
+
environment: if defined?(Rails) && Rails.env.present?
|
38
|
+
"[#{Rails.env}]"
|
39
|
+
else
|
40
|
+
"[UNKNOWN ENVIRONMENT]"
|
41
|
+
end,
|
42
42
|
|
43
43
|
# Use the "real" email address as the username
|
44
44
|
# for the sanitized email address
|
45
45
|
# e.g. "real@example.com <sanitized@example.com>"
|
46
|
-
:
|
46
|
+
use_actual_email_as_sanitized_user_name: false,
|
47
47
|
|
48
48
|
# Prepend the "real" email address onto the Subject line of the message
|
49
49
|
# e.g. "real@example.com rest of subject"
|
50
|
-
:
|
50
|
+
use_actual_email_prepended_to_subject: false,
|
51
51
|
|
52
52
|
# Prepend the Rails environment onto the Subject line of the message
|
53
53
|
# e.g. "[development] rest of subject"
|
54
|
-
:
|
54
|
+
use_actual_environment_prepended_to_subject: false,
|
55
55
|
|
56
56
|
# True / False turns on or off sanitization,
|
57
57
|
# while nil ignores this setting and checks activation_proc
|
58
|
-
:
|
58
|
+
engage: nil,
|
59
59
|
|
60
|
-
:
|
60
|
+
activation_proc: proc { false },
|
61
61
|
}.freeze
|
62
62
|
|
63
63
|
@config ||= DEFAULTS.dup
|
@@ -83,9 +83,9 @@ module SanitizeEmail
|
|
83
83
|
end
|
84
84
|
|
85
85
|
def self.config_force_sanitize_deprecation_warning
|
86
|
-
return
|
86
|
+
return if @config[:force_sanitize].nil?
|
87
87
|
deprecation_warning_message(
|
88
|
-
<<-DEPRECATION
|
88
|
+
<<-DEPRECATION,
|
89
89
|
SanitizeEmail::Config.config[:force_sanitize] is deprecated.
|
90
90
|
Please use SanitizeEmail.force_sanitize or SanitizeEmail.sanitary instead.
|
91
91
|
Refer to https://github.com/pboling/sanitize_email/wiki for examples.
|
@@ -1,6 +1,6 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
# Copyright (c) 2008-
|
3
|
+
# Copyright (c) 2008 - 2018, 2020, 2022, 2024 Peter H. Boling of RailsBling.com
|
4
4
|
# Released under the MIT license
|
5
5
|
|
6
6
|
module SanitizeEmail
|
@@ -19,8 +19,8 @@ module SanitizeEmail
|
|
19
19
|
def deprecated_alias(name, replacement)
|
20
20
|
# Create a wrapped version
|
21
21
|
define_method(name) do |*args, &block|
|
22
|
-
warn
|
23
|
-
send
|
22
|
+
warn("SanitizeEmail: ##{name} deprecated (please use ##{replacement})") unless SanitizeEmail::Deprecation.deprecate_in_silence
|
23
|
+
send(replacement, *args, &block)
|
24
24
|
end
|
25
25
|
end
|
26
26
|
|
@@ -30,11 +30,11 @@ module SanitizeEmail
|
|
30
30
|
def deprecated(name, replacement = nil)
|
31
31
|
# Replace old method
|
32
32
|
old_name = :"#{name}_without_deprecation"
|
33
|
-
alias_method
|
33
|
+
alias_method(old_name, name)
|
34
34
|
# And replace it with a wrapped version
|
35
35
|
define_method(name) do |*args, &block|
|
36
36
|
deprecation(name, " (please use ##{replacement})")
|
37
|
-
send
|
37
|
+
send(old_name, *args, &block)
|
38
38
|
end
|
39
39
|
end
|
40
40
|
|
@@ -47,7 +47,7 @@ module SanitizeEmail
|
|
47
47
|
end
|
48
48
|
|
49
49
|
def deprecation_warning_message(message)
|
50
|
-
warn
|
50
|
+
warn(message) unless SanitizeEmail::Deprecation.deprecate_in_silence
|
51
51
|
end
|
52
52
|
end
|
53
53
|
end
|
@@ -1,6 +1,6 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
# Copyright (c) 2008-
|
3
|
+
# Copyright (c) 2008 - 2018, 2020, 2022, 2024 Peter H. Boling of RailsBling.com
|
4
4
|
# Released under the MIT license
|
5
5
|
|
6
6
|
module SanitizeEmail
|
@@ -9,20 +9,20 @@ module SanitizeEmail
|
|
9
9
|
def self.prepend_subject_array(message)
|
10
10
|
prepend = []
|
11
11
|
if SanitizeEmail.use_actual_email_prepended_to_subject
|
12
|
-
prepend << SanitizeEmail::MailHeaderTools
|
13
|
-
|
12
|
+
prepend << SanitizeEmail::MailHeaderTools
|
13
|
+
.prepend_email_to_subject(Array(message.to))
|
14
14
|
end
|
15
15
|
if SanitizeEmail.use_actual_environment_prepended_to_subject
|
16
|
-
prepend << SanitizeEmail::MailHeaderTools
|
17
|
-
|
16
|
+
prepend << SanitizeEmail::MailHeaderTools
|
17
|
+
.prepend_environment_to_subject
|
18
18
|
end
|
19
19
|
# this will force later joins to add an extra space
|
20
|
-
prepend <<
|
20
|
+
prepend << "" unless prepend.empty?
|
21
21
|
prepend
|
22
22
|
end
|
23
23
|
|
24
24
|
def self.custom_subject(message)
|
25
|
-
prepend_subject_array(message).join(
|
25
|
+
prepend_subject_array(message).join(" ")
|
26
26
|
end
|
27
27
|
|
28
28
|
def self.prepend_environment_to_subject
|
@@ -30,18 +30,22 @@ module SanitizeEmail
|
|
30
30
|
end
|
31
31
|
|
32
32
|
def self.prepend_email_to_subject(actual_addresses)
|
33
|
-
"(#{Array(actual_addresses).uniq.join(
|
34
|
-
gsub(/[<>]/,
|
33
|
+
"(#{Array(actual_addresses).uniq.join(",").gsub(/@/, " at ")
|
34
|
+
.gsub(/[<>]/, "~")})"
|
35
35
|
end
|
36
36
|
|
37
37
|
def self.add_original_addresses_as_headers(message)
|
38
38
|
# Add headers by string concat.
|
39
39
|
# Setting hash values on message.headers does nothing, strangely.
|
40
40
|
# See: http://goo.gl/v46GY
|
41
|
+
to_addrs = message[:to]&.addrs
|
42
|
+
cc_addrs = message[:cc]&.addrs
|
43
|
+
to_decoded = Array(to_addrs&.map(&:decoded))
|
44
|
+
cc_decoded = Array(cc_addrs&.map(&:decoded))
|
41
45
|
{
|
42
46
|
# can be an arrays, so casting it as arrays
|
43
|
-
|
44
|
-
|
47
|
+
"X-Sanitize-Email-To" => to_decoded,
|
48
|
+
"X-Sanitize-Email-Cc" => cc_decoded,
|
45
49
|
# Don't write out the BCC, as those addresses should not be visible
|
46
50
|
# in message headers for obvious reasons
|
47
51
|
}.each do |header_key, header_value|
|
@@ -49,13 +53,13 @@ module SanitizeEmail
|
|
49
53
|
SanitizeEmail::MailHeaderTools.update_header(
|
50
54
|
header_key,
|
51
55
|
header_value,
|
52
|
-
message
|
56
|
+
message,
|
53
57
|
)
|
54
58
|
end
|
55
59
|
end
|
56
60
|
|
57
61
|
def self.prepend_custom_subject(message)
|
58
|
-
message.subject =
|
62
|
+
message.subject = "" unless message.subject
|
59
63
|
custom_subject = SanitizeEmail::MailHeaderTools.custom_subject(message)
|
60
64
|
message.subject = custom_subject + message.subject
|
61
65
|
end
|
@@ -63,11 +67,11 @@ module SanitizeEmail
|
|
63
67
|
# According to https://github.com/mikel/mail
|
64
68
|
# this is the correct way to update headers.
|
65
69
|
def self.update_header(header_key, header_value, message)
|
66
|
-
return
|
70
|
+
return unless header_value
|
67
71
|
# For each address, as header_value can be an array of addresses
|
68
72
|
Array(header_value).each_with_index do |elem, index|
|
69
73
|
num = index + 1
|
70
|
-
new_header_key = num > 1 ? "#{header_key}-#{num}" : header_key
|
74
|
+
new_header_key = (num > 1) ? "#{header_key}-#{num}" : header_key
|
71
75
|
message.header[new_header_key] = elem.to_s
|
72
76
|
end
|
73
77
|
end
|
@@ -1,8 +1,11 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
# Copyright (c) 2008-
|
3
|
+
# Copyright (c) 2008 - 2018, 2020, 2022, 2024 Peter H. Boling of RailsBling.com
|
4
4
|
# Released under the MIT license
|
5
5
|
|
6
|
+
# External Libraries
|
7
|
+
require "mail"
|
8
|
+
|
6
9
|
module SanitizeEmail
|
7
10
|
# Tools for overriding addresses
|
8
11
|
class OverriddenAddresses
|
@@ -14,12 +17,18 @@ module SanitizeEmail
|
|
14
17
|
# recognized recipient types are: TO, CC, and BCC
|
15
18
|
class UnknownOverride < StandardError; end
|
16
19
|
|
17
|
-
REPLACE_AT = [/@/,
|
18
|
-
REPLACE_ALLIGATOR = [/[<>]/,
|
19
|
-
attr_accessor :
|
20
|
-
|
21
|
-
|
22
|
-
|
20
|
+
REPLACE_AT = [/@/, " at "].freeze
|
21
|
+
REPLACE_ALLIGATOR = [/[<>]/, "~"].freeze
|
22
|
+
attr_accessor :tempmail,
|
23
|
+
:overridden_to,
|
24
|
+
:overridden_cc,
|
25
|
+
:overridden_bcc,
|
26
|
+
:overridden_personalizations,
|
27
|
+
:good_list, # Allow-listed addresses will not be molested as to, cc, or bcc
|
28
|
+
:bad_list, # Block-listed addresses will be removed from to, cc and bcc when sanitization is engaged
|
29
|
+
:sanitized_to,
|
30
|
+
:sanitized_cc,
|
31
|
+
:sanitized_bcc # Replace non-allow-listed addresses with these sanitized addresses.
|
23
32
|
|
24
33
|
def initialize(message, **args)
|
25
34
|
# Not using extract_options! because non-rails compatibility is a goal
|
@@ -29,9 +38,23 @@ module SanitizeEmail
|
|
29
38
|
@sanitized_bcc = args[:sanitized_bcc]
|
30
39
|
@good_list = args[:good_list] || []
|
31
40
|
@bad_list = args[:bad_list] || []
|
32
|
-
|
33
|
-
@
|
34
|
-
|
41
|
+
# Mail will do the username parsing for us.
|
42
|
+
@tempmail = Mail.new
|
43
|
+
|
44
|
+
tempmail.to = to_override(message.to)
|
45
|
+
tempmail.cc = cc_override(message.cc)
|
46
|
+
tempmail.bcc = bcc_override(message.bcc)
|
47
|
+
|
48
|
+
remove_duplicates
|
49
|
+
|
50
|
+
@overridden_to = tempmail[:to].decoded
|
51
|
+
@overridden_cc = tempmail[:cc].decoded
|
52
|
+
@overridden_bcc = tempmail[:bcc].decoded
|
53
|
+
|
54
|
+
# remove addresses from :cc that are in :to
|
55
|
+
return if message["personalizations"].nil?
|
56
|
+
|
57
|
+
@overridden_personalizations = personalizations_override(message["personalizations"])
|
35
58
|
end
|
36
59
|
|
37
60
|
# Allow good listed email addresses, and then remove the bad listed addresses
|
@@ -44,15 +67,32 @@ module SanitizeEmail
|
|
44
67
|
def to_override(actual_addresses)
|
45
68
|
to = override_email(:to, actual_addresses)
|
46
69
|
raise MissingTo, "after overriding :to (#{actual_addresses}) there are no addresses to send in To: header." if to.empty?
|
47
|
-
|
70
|
+
|
71
|
+
to.join(",")
|
48
72
|
end
|
49
73
|
|
50
74
|
def cc_override(actual_addresses)
|
51
|
-
override_email(:cc, actual_addresses).join(
|
75
|
+
override_email(:cc, actual_addresses).join(",")
|
52
76
|
end
|
53
77
|
|
54
78
|
def bcc_override(actual_addresses)
|
55
|
-
override_email(:bcc, actual_addresses).join(
|
79
|
+
override_email(:bcc, actual_addresses).join(",")
|
80
|
+
end
|
81
|
+
|
82
|
+
def personalizations_override(actual_personalizations)
|
83
|
+
actual_personalizations.unparsed_value.map do |actual_personalization|
|
84
|
+
actual_personalization.merge(
|
85
|
+
to: actual_personalization[:to]&.map do |to|
|
86
|
+
to.merge(email: override_email(:to, to[:email]).join(","))
|
87
|
+
end,
|
88
|
+
cc: actual_personalization[:cc]&.map do |cc|
|
89
|
+
cc.merge(email: override_email(:cc, cc[:email]).join(","))
|
90
|
+
end,
|
91
|
+
bcc: actual_personalization[:bcc]&.map do |bcc|
|
92
|
+
bcc.merge(email: override_email(:bcc, bcc[:email]).join(","))
|
93
|
+
end,
|
94
|
+
)
|
95
|
+
end
|
56
96
|
end
|
57
97
|
|
58
98
|
def override_email(type, actual_addresses)
|
@@ -99,17 +139,19 @@ module SanitizeEmail
|
|
99
139
|
has_address ? address : nil
|
100
140
|
when :bad_list then
|
101
141
|
has_address ? nil : address
|
142
|
+
else
|
143
|
+
raise ArgumentError, "address_list_filter got unknown list_type: #{list_type}"
|
102
144
|
end
|
103
145
|
end
|
104
146
|
|
105
147
|
def inject_user_names(real_addresses, sanitized_addresses)
|
106
148
|
real_addresses.each_with_object([]) do |real_recipient, result|
|
107
149
|
new_recipient = if real_recipient.nil?
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
150
|
+
sanitized_addresses
|
151
|
+
else
|
152
|
+
# puts "SANITIZED: #{sanitized_addresses}"
|
153
|
+
sanitized_addresses.map { |sanitized| "#{real_recipient.gsub(REPLACE_AT[0], REPLACE_AT[1]).gsub(/[<>]/, "~")} <#{sanitized}>" }
|
154
|
+
end
|
113
155
|
result << new_recipient
|
114
156
|
end.flatten
|
115
157
|
end
|
@@ -131,7 +173,23 @@ module SanitizeEmail
|
|
131
173
|
when :bcc then
|
132
174
|
Array(sanitized_bcc)
|
133
175
|
else
|
134
|
-
raise UnknownOverride,
|
176
|
+
raise UnknownOverride, "unknown email override"
|
177
|
+
end
|
178
|
+
end
|
179
|
+
|
180
|
+
private
|
181
|
+
|
182
|
+
def remove_duplicates
|
183
|
+
dedup_addresses = tempmail[:to].addresses
|
184
|
+
|
185
|
+
tempmail[:cc].addrs.reject! do |addr|
|
186
|
+
# If this email address is already in the :to list, then remove
|
187
|
+
dedup_addresses.include?(addr.address)
|
188
|
+
end
|
189
|
+
dedup_addresses += tempmail[:cc].addresses
|
190
|
+
tempmail[:bcc].addrs.reject! do |addr|
|
191
|
+
# If this email address is already in the :to list, then remove
|
192
|
+
dedup_addresses.include?(addr.address)
|
135
193
|
end
|
136
194
|
end
|
137
195
|
end
|
@@ -1,92 +1,116 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
# Copyright (c) 2008-
|
3
|
+
# Copyright (c) 2008 - 2018, 2020, 2022, 2024 Peter H. Boling of RailsBling.com
|
4
4
|
# Released under the MIT license
|
5
5
|
# Note: the RspecMatchers are composed matchers:
|
6
6
|
# See: http://www.relishapp.com/rspec/rspec-expectations/v/3-5/docs/composing-matchers
|
7
7
|
|
8
|
-
require
|
8
|
+
require "sanitize_email/mail_ext"
|
9
9
|
|
10
10
|
module SanitizeEmail
|
11
11
|
# Provides matchers that can be used in
|
12
12
|
# Rspec tests to assert the behavior of email
|
13
13
|
module RspecMatchers
|
14
14
|
%i[from to cc bcc subject reply_to].each do |attribute|
|
15
|
-
RSpec::Matchers.define
|
15
|
+
RSpec::Matchers.define("have_#{attribute}") do |matcher|
|
16
16
|
match do |actual|
|
17
17
|
@actual = actual.send(attribute)
|
18
|
-
@actual = @actual.join(
|
19
|
-
expect(@actual).to
|
18
|
+
@actual = @actual.join(", ") if @actual.respond_to?(:join)
|
19
|
+
expect(@actual).to(match(matcher))
|
20
20
|
end
|
21
21
|
end
|
22
22
|
end
|
23
23
|
|
24
24
|
%i[from to cc bcc subject reply_to].each do |attribute|
|
25
|
-
RSpec::Matchers.define
|
25
|
+
RSpec::Matchers.define("match_#{attribute}") do |matcher|
|
26
26
|
match do |actual|
|
27
27
|
@actual = actual.send(attribute)
|
28
|
-
@actual = @actual.join(
|
29
|
-
expect(@actual).to
|
28
|
+
@actual = @actual.join(", ") if @actual.respond_to?(:join)
|
29
|
+
expect(@actual).to(match(matcher))
|
30
30
|
end
|
31
31
|
end
|
32
32
|
end
|
33
33
|
|
34
34
|
%i[from to cc bcc subject reply_to].each do |attribute|
|
35
|
-
RSpec::Matchers.define
|
35
|
+
RSpec::Matchers.define("be_#{attribute}") do |matcher|
|
36
36
|
match do |actual|
|
37
37
|
@actual = actual.send(attribute)
|
38
|
-
@actual = @actual.join(
|
39
|
-
expect(@actual).to
|
38
|
+
@actual = @actual.join(", ") if @actual.respond_to?(:join)
|
39
|
+
expect(@actual).to(be(matcher))
|
40
40
|
end
|
41
41
|
end
|
42
42
|
end
|
43
43
|
|
44
|
-
RSpec::Matchers.define
|
45
|
-
def
|
46
|
-
|
47
|
-
|
48
|
-
email_message.header.fields[3].value
|
44
|
+
RSpec::Matchers.define("have_to_username") do |matcher|
|
45
|
+
def get_to_usernames(email_message)
|
46
|
+
to_addrs = email_message[:to].addrs
|
47
|
+
to_addrs.map(&:name)
|
49
48
|
end
|
50
49
|
match do |actual|
|
51
|
-
@actual =
|
52
|
-
expect(@actual).to
|
50
|
+
@actual = get_to_usernames(actual)
|
51
|
+
expect(@actual).to(include(match(matcher)))
|
53
52
|
end
|
54
53
|
end
|
55
54
|
|
56
|
-
RSpec::Matchers.define
|
57
|
-
def
|
58
|
-
|
59
|
-
return
|
60
|
-
|
55
|
+
RSpec::Matchers.define("have_sanitized_to_header") do |matcher|
|
56
|
+
def get_sanitized_to_header(email_message)
|
57
|
+
sanitized_to_header = email_message.header["X-Sanitize-Email-To"]
|
58
|
+
return sanitized_to_header.value if sanitized_to_header.is_a?(Mail::Field)
|
59
|
+
|
60
|
+
"no header found at 'X-Sanitize-Email-To'"
|
61
|
+
end
|
62
|
+
match do |actual|
|
63
|
+
@actual = get_sanitized_to_header(actual)
|
64
|
+
expect(@actual).to(match(matcher))
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
RSpec::Matchers.define("have_cc_username") do |matcher|
|
69
|
+
def get_cc_usernames(email_message)
|
70
|
+
to_addrs = email_message[:cc].addrs
|
71
|
+
to_addrs.map(&:name)
|
72
|
+
end
|
73
|
+
match do |actual|
|
74
|
+
@actual = get_cc_usernames(actual)
|
75
|
+
expect(@actual).to(include(match(matcher)))
|
76
|
+
end
|
77
|
+
end
|
78
|
+
|
79
|
+
RSpec::Matchers.define("have_sanitized_cc_header") do |matcher|
|
80
|
+
def get_sanitized_cc_header(email_message)
|
81
|
+
sanitized_cc_header = email_message.header["X-Sanitize-Email-Cc"]
|
82
|
+
return sanitized_cc_header.value if sanitized_cc_header.is_a?(Mail::Field)
|
83
|
+
|
84
|
+
"no header found at 'X-Sanitize-Email-Cc'"
|
61
85
|
end
|
62
86
|
match do |actual|
|
63
|
-
@actual =
|
64
|
-
expect(@actual).to
|
87
|
+
@actual = get_sanitized_cc_header(actual)
|
88
|
+
expect(@actual).to(match(matcher))
|
65
89
|
end
|
66
90
|
end
|
67
91
|
|
68
92
|
# Cribbed from email_spec gem
|
69
|
-
RSpec::Matchers.define
|
93
|
+
RSpec::Matchers.define("have_body_text") do |matcher|
|
70
94
|
def get_fuzzy_body(email_message)
|
71
|
-
email_message.default_part_body.to_s.gsub(/\s+/,
|
95
|
+
email_message.default_part_body.to_s.gsub(/\s+/, " ")
|
72
96
|
end
|
73
97
|
|
74
98
|
def get_fuzzy_matcher(to_fuzz)
|
75
|
-
to_fuzz.gsub(/\s+/,
|
99
|
+
to_fuzz.gsub(/\s+/, " ")
|
76
100
|
end
|
77
101
|
match do |actual|
|
78
102
|
@actual = get_fuzzy_body(actual)
|
79
103
|
fuzzy_matcher = get_fuzzy_matcher(matcher)
|
80
|
-
expect(@actual).to
|
104
|
+
expect(@actual).to(match(fuzzy_matcher))
|
81
105
|
end
|
82
106
|
end
|
83
107
|
|
84
108
|
# Cribbed from email_spec gem
|
85
|
-
RSpec::Matchers.define
|
109
|
+
RSpec::Matchers.define("have_header") do |name, matcher|
|
86
110
|
match do |actual|
|
87
111
|
@actual = actual.header[name]
|
88
112
|
@actual = @actual.value unless @actual.nil?
|
89
|
-
expect(@actual).to
|
113
|
+
expect(@actual).to(match(matcher))
|
90
114
|
end
|
91
115
|
end
|
92
116
|
end
|
@@ -1,6 +1,6 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
# Copyright (c) 2008-
|
3
|
+
# Copyright (c) 2008 - 2018, 2020, 2022, 2024 Peter H. Boling of RailsBling.com
|
4
4
|
# Released under the MIT license
|
5
5
|
# Note: the RspecMatchers no longer use these methods. Instead they are composed matchers:
|
6
6
|
# See: http://www.relishapp.com/rspec/rspec-expectations/v/3-5/docs/composing-matchers
|
@@ -19,15 +19,15 @@ module SanitizeEmail
|
|
19
19
|
# Can we match a regex against it?
|
20
20
|
raise UnexpectedMailType, "Cannot match #{matcher} for #{part}" unless attribute.respond_to?(:=~)
|
21
21
|
attribute =~ if matcher.is_a?(Regexp)
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
22
|
+
matcher
|
23
|
+
else
|
24
|
+
Regexp.new(Regexp.escape(matcher))
|
25
|
+
end
|
26
26
|
end
|
27
27
|
|
28
28
|
# Normalize arrays to strings
|
29
29
|
def array_matching(matcher, part, attribute)
|
30
|
-
attribute = attribute.join(
|
30
|
+
attribute = attribute.join(", ") if attribute.respond_to?(:join)
|
31
31
|
string_matching(matcher, part, attribute)
|
32
32
|
end
|
33
33
|
|
@@ -1,8 +1,10 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
# Copyright (c) 2008-
|
3
|
+
# Copyright (c) 2008 - 2018, 2020, 2022, 2024 Peter H. Boling of RailsBling.com
|
4
4
|
# Released under the MIT license
|
5
5
|
|
6
6
|
module SanitizeEmail
|
7
|
-
|
7
|
+
module Version
|
8
|
+
VERSION = "2.0.4"
|
9
|
+
end
|
8
10
|
end
|