action_mailbox_amazon_ingress 0.1.2 → 0.2.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.
- checksums.yaml +4 -4
- data/.github/workflows/ruby.yml +18 -0
- data/.rubocop.yml +4 -0
- data/.ruby-version +1 -1
- data/Gemfile +9 -0
- data/README.md +15 -8
- data/Rakefile +69 -0
- data/action_mailbox_amazon_ingress.gemspec +5 -16
- data/app/controllers/action_mailbox/ingresses/amazon/inbound_emails_controller.rb +11 -64
- data/lib/action_mailbox_amazon_ingress/rspec/email.rb +10 -5
- data/lib/action_mailbox_amazon_ingress/rspec.rb +10 -4
- data/lib/action_mailbox_amazon_ingress/sns_notification.rb +98 -0
- data/lib/action_mailbox_amazon_ingress/version.rb +1 -1
- metadata +18 -128
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 94d231867bda21e8d23375b26f34761b3b0125d6bad53e312cb37be1fc939788
|
4
|
+
data.tar.gz: 912a90256bf244ef73a41d8e3b19b2e2d052e5fd52a9dcfaff3c8fb9e8c21a85
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: e1cbfa0915941aefa5d14431eba979447c9dfb7a306b61aaa362dc469c7842cac91e1b1f30881a9982f5628d124e7ee2ac959646fc71c2c005e7bc317adab464
|
7
|
+
data.tar.gz: 0c1d0f82bf9c430be873a343a27b88999db24211cc5e25909956ad84ace4c374bea4dadcf4f515b8fc8d18bd21b8dc0caf0c73129b39acb39333fc8ede6a4284
|
@@ -0,0 +1,18 @@
|
|
1
|
+
name: 'CI'
|
2
|
+
on:
|
3
|
+
push:
|
4
|
+
branches: [ "master" ]
|
5
|
+
pull_request:
|
6
|
+
branches: [ "master" ]
|
7
|
+
jobs:
|
8
|
+
test:
|
9
|
+
runs-on: ubuntu-latest
|
10
|
+
steps:
|
11
|
+
- name: Checkout code
|
12
|
+
uses: actions/checkout@v4
|
13
|
+
- name: Install Ruby and gems
|
14
|
+
uses: ruby/setup-ruby@v1
|
15
|
+
with:
|
16
|
+
bundler-cache: true
|
17
|
+
- name: Run tests
|
18
|
+
run: make
|
data/.rubocop.yml
CHANGED
@@ -12,6 +12,7 @@ Metrics/BlockLength:
|
|
12
12
|
|
13
13
|
AllCops:
|
14
14
|
NewCops: enable
|
15
|
+
SuggestExtensions: false
|
15
16
|
Exclude:
|
16
17
|
- 'bin/**/*'
|
17
18
|
- 'db/migrate/**/*.rb'
|
@@ -32,3 +33,6 @@ Style/HashTransformKeys:
|
|
32
33
|
Enabled: true
|
33
34
|
Style/HashTransformValues:
|
34
35
|
Enabled: true
|
36
|
+
|
37
|
+
Style/HashSyntax:
|
38
|
+
Enabled: false
|
data/.ruby-version
CHANGED
@@ -1 +1 @@
|
|
1
|
-
2.
|
1
|
+
3.2.3
|
data/Gemfile
CHANGED
@@ -3,3 +3,12 @@
|
|
3
3
|
source 'https://rubygems.org'
|
4
4
|
git_source(:github) { |repo_name| "https://github.com/#{repo_name}" }
|
5
5
|
gemspec
|
6
|
+
|
7
|
+
gem 'devpack', '~> 0.3.3'
|
8
|
+
gem 'rake', '~> 13.0'
|
9
|
+
gem 'rspec-its', '~> 1.3'
|
10
|
+
gem 'rspec-rails', '~> 6.1'
|
11
|
+
gem 'rubocop', '~> 1.63'
|
12
|
+
gem 'sqlite3', '~> 1.4'
|
13
|
+
gem 'strong_versions', '~> 0.4.5'
|
14
|
+
gem 'webmock', '~> 3.8'
|
data/README.md
CHANGED
@@ -7,29 +7,27 @@ Provides _Amazon SES/SNS_ integration with [_Rails ActionMailbox_](https://guide
|
|
7
7
|
Add this line to your application's Gemfile:
|
8
8
|
|
9
9
|
```ruby
|
10
|
-
gem 'action_mailbox_amazon_ingress', '~> 0.1.
|
10
|
+
gem 'action_mailbox_amazon_ingress', '~> 0.1.3'
|
11
11
|
```
|
12
12
|
|
13
13
|
## Configuration
|
14
14
|
|
15
15
|
### Amazon SES/SNS
|
16
16
|
|
17
|
-
Configure
|
17
|
+
1. [Configure SES](https://docs.aws.amazon.com/ses/latest/DeveloperGuide/receiving-email-notifications.html) to (save emails to S3)(https://docs.aws.amazon.com/ses/latest/dg/receiving-email-action-s3.html) or to send them as raw messages.
|
18
18
|
|
19
|
-
|
20
|
-
|
21
|
-
https://example.com/rails/action_mailbox/amazon/inbound_emails
|
19
|
+
2. [Configure the SNS topic for SES or for the S3 action](https://docs.aws.amazon.com/ses/latest/DeveloperGuide/receiving-email-action-sns.html) to send notifications to +/rails/action_mailbox/amazon/inbound_emails+. For example, if your website is hosted at https://www.example.com then configure _SNS_ to publish the _SES_ notification topic to this _HTTP_ endpoint: https://example.com/rails/action_mailbox/amazon/inbound_emails
|
22
20
|
|
23
21
|
### Rails
|
24
22
|
|
25
|
-
Configure _ActionMailbox_ to accept emails from Amazon SES:
|
23
|
+
1. Configure _ActionMailbox_ to accept emails from Amazon SES:
|
26
24
|
|
27
25
|
```
|
28
26
|
# config/environments/production.rb
|
29
27
|
config.action_mailbox.ingress = :amazon
|
30
28
|
```
|
31
29
|
|
32
|
-
Configure which _SNS_ topics will be accepted:
|
30
|
+
2. Configure which _SNS_ topics will be accepted:
|
33
31
|
|
34
32
|
```
|
35
33
|
# config/environments/production.rb
|
@@ -39,7 +37,7 @@ config.action_mailbox.amazon.subscribed_topics = %w(
|
|
39
37
|
)
|
40
38
|
```
|
41
39
|
|
42
|
-
Subscriptions will now be auto-confirmed and messages will be
|
40
|
+
SNS Subscriptions will now be auto-confirmed and messages will be automatically handled via _ActionMailbox_.
|
43
41
|
|
44
42
|
Note that even if you manually confirm subscriptions you will still need to provide a list of subscribed topics; messages from unrecognized topics will be ignored.
|
45
43
|
|
@@ -99,11 +97,20 @@ You may also pass the following keyword arguments to both helpers:
|
|
99
97
|
|
100
98
|
## Development
|
101
99
|
|
100
|
+
### Setup
|
101
|
+
|
102
|
+
`bin/setup`
|
103
|
+
|
104
|
+
### Testing
|
105
|
+
|
102
106
|
Ensure _Rubocop_, _RSpec_, and _StrongVersions_ compliance by running `make`:
|
103
107
|
|
104
108
|
```
|
105
109
|
make
|
106
110
|
```
|
111
|
+
### Updating AWS Fixtures
|
112
|
+
|
113
|
+
`bundle exec rake sign_aws_fixtures`
|
107
114
|
|
108
115
|
## Contributing
|
109
116
|
|
data/Rakefile
CHANGED
@@ -6,3 +6,72 @@ require 'rspec/core/rake_task'
|
|
6
6
|
RSpec::Core::RakeTask.new(:spec)
|
7
7
|
|
8
8
|
task default: :spec
|
9
|
+
|
10
|
+
PRIVATE_KEY = 'spec/fixtures/pem/privatekey.pem'
|
11
|
+
CERTIFICATE = 'spec/fixtures/pem/certificate.pem'
|
12
|
+
AWS_FIXTURES = FileList['spec/fixtures/json/*.json'].exclude('**/*/invalid_signature.json')
|
13
|
+
SIGNABLE_KEYS = %w[
|
14
|
+
Message
|
15
|
+
MessageId
|
16
|
+
Subject
|
17
|
+
SubscribeURL
|
18
|
+
Timestamp
|
19
|
+
Token
|
20
|
+
TopicArn
|
21
|
+
Type
|
22
|
+
].freeze
|
23
|
+
|
24
|
+
file PRIVATE_KEY do |t|
|
25
|
+
require 'openssl'
|
26
|
+
key = OpenSSL::PKey::RSA.new 2048
|
27
|
+
File.write(t.name, key.to_pem)
|
28
|
+
end
|
29
|
+
|
30
|
+
file CERTIFICATE => PRIVATE_KEY do |t|
|
31
|
+
require 'openssl'
|
32
|
+
key = OpenSSL::PKey::RSA.new File.read(PRIVATE_KEY)
|
33
|
+
cert = OpenSSL::X509::Certificate.new
|
34
|
+
cert.version = 2
|
35
|
+
cert.serial = 2
|
36
|
+
cert.subject = OpenSSL::X509::Name.parse '/DC=org/DC=ruby-lang/CN=Ruby certificate'
|
37
|
+
cert.issuer = cert.subject # root CA is the issuer
|
38
|
+
cert.public_key = key.public_key
|
39
|
+
cert.not_before = Time.now
|
40
|
+
cert.not_after = cert.not_before + (1 * 365 * 24 * 60 * 60) # 10 years validity
|
41
|
+
ef = OpenSSL::X509::ExtensionFactory.new
|
42
|
+
ef.subject_certificate = cert
|
43
|
+
ef.issuer_certificate = cert
|
44
|
+
cert.add_extension(ef.create_extension('keyUsage', 'digitalSignature', true))
|
45
|
+
cert.add_extension(ef.create_extension('subjectKeyIdentifier', 'hash', false))
|
46
|
+
cert.sign(key, OpenSSL::Digest.new('SHA256'))
|
47
|
+
|
48
|
+
File.write(t.name, cert.to_pem)
|
49
|
+
end
|
50
|
+
task certificates: [PRIVATE_KEY, CERTIFICATE]
|
51
|
+
|
52
|
+
desc 'Sign AWS SES fixtures, must be called if fixtures are modified.'
|
53
|
+
task sign_aws_fixtures: :certificates do
|
54
|
+
require 'openssl'
|
55
|
+
require 'json'
|
56
|
+
require 'base64'
|
57
|
+
|
58
|
+
key = OpenSSL::PKey::RSA.new File.read(PRIVATE_KEY)
|
59
|
+
|
60
|
+
AWS_FIXTURES.each do |fixture|
|
61
|
+
data = JSON.parse File.read(fixture)
|
62
|
+
string = canonical_string(data)
|
63
|
+
signed_string = key.sign('SHA1', string)
|
64
|
+
data['Signature'] = Base64.encode64(signed_string)
|
65
|
+
File.write(fixture, JSON.pretty_generate(data))
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
def canonical_string(message)
|
70
|
+
parts = []
|
71
|
+
|
72
|
+
SIGNABLE_KEYS.each do |key|
|
73
|
+
value = message[key]
|
74
|
+
parts << "#{key}\n#{value}\n" unless value.nil? || value.empty?
|
75
|
+
end
|
76
|
+
parts.join
|
77
|
+
end
|
@@ -9,32 +9,21 @@ Gem::Specification.new do |spec|
|
|
9
9
|
spec.version = ActionMailboxAmazonIngress::VERSION
|
10
10
|
spec.authors = ['Bob Farrell']
|
11
11
|
spec.email = ['git@bob.frl']
|
12
|
-
spec.required_ruby_version = '>= 2
|
12
|
+
spec.required_ruby_version = '>= 3.2'
|
13
13
|
|
14
14
|
spec.summary = 'Amazon SES ingress for Rails ActionMailbox'
|
15
15
|
spec.description = 'Integrate Amazon SES with ActionMailbox'
|
16
16
|
spec.homepage = 'https://github.com/bobf/action_mailbox_amazon_ingress'
|
17
17
|
spec.license = 'MIT'
|
18
|
-
|
18
|
+
spec.metadata = { 'rubygems_mfa_required' => 'true' }
|
19
19
|
spec.files = Dir.chdir(File.expand_path(__dir__)) do
|
20
20
|
`git ls-files -z`.split("\x0").reject do |f|
|
21
21
|
f.match(%r{^(test|spec|features)/})
|
22
22
|
end
|
23
23
|
end
|
24
|
-
spec.bindir = 'bin'
|
25
|
-
spec.executables = []
|
26
24
|
spec.require_paths = ['lib']
|
27
25
|
|
28
|
-
spec.add_runtime_dependency 'aws-sdk-
|
29
|
-
spec.
|
30
|
-
|
31
|
-
spec.add_development_dependency 'betterp', '~> 0.1.3'
|
32
|
-
spec.add_development_dependency 'devpack', '~> 0.2.1'
|
33
|
-
spec.add_development_dependency 'rake', '~> 13.0'
|
34
|
-
spec.add_development_dependency 'rspec-its', '~> 1.3'
|
35
|
-
spec.add_development_dependency 'rspec-rails', '~> 4.0'
|
36
|
-
spec.add_development_dependency 'rubocop', '~> 0.90.0'
|
37
|
-
spec.add_development_dependency 'sqlite3', '~> 1.4'
|
38
|
-
spec.add_development_dependency 'strong_versions', '~> 0.4.5'
|
39
|
-
spec.add_development_dependency 'webmock', '~> 3.8'
|
26
|
+
spec.add_runtime_dependency 'aws-sdk-s3', '~> 1.151'
|
27
|
+
spec.add_runtime_dependency 'aws-sdk-sns', '~> 1.75'
|
28
|
+
spec.add_dependency 'actionmailbox', '~> 7.1'
|
40
29
|
end
|
@@ -1,5 +1,7 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
+
require 'action_mailbox_amazon_ingress/sns_notification'
|
4
|
+
|
3
5
|
module ActionMailbox
|
4
6
|
# Ingests inbound emails from Amazon SES/SNS and confirms subscriptions.
|
5
7
|
#
|
@@ -26,41 +28,16 @@ module ActionMailbox
|
|
26
28
|
# - <tt>401 Unauthorized</tt> if a request does not contain a valid signature
|
27
29
|
# - <tt>404 Not Found</tt> if the Amazon ingress has not been configured
|
28
30
|
# - <tt>422 Unprocessable Entity</tt> if a request provides invalid parameters
|
29
|
-
#
|
30
|
-
# == Usage
|
31
|
-
#
|
32
|
-
# 1. Tell Action Mailbox to accept emails from Amazon SES:
|
33
|
-
#
|
34
|
-
# # config/environments/production.rb
|
35
|
-
# config.action_mailbox.ingress = :amazon
|
36
|
-
#
|
37
|
-
# 2. Configure which SNS topics will be accepted:
|
38
|
-
#
|
39
|
-
# config.action_mailbox.amazon.subscribed_topics = %w(
|
40
|
-
# arn:aws:sns:eu-west-1:123456789001:example-topic-1
|
41
|
-
# arn:aws:sns:us-east-1:123456789002:example-topic-2
|
42
|
-
# )
|
43
|
-
#
|
44
|
-
# 3. {Configure SES}[https://docs.aws.amazon.com/ses/latest/DeveloperGuide/receiving-email-notifications.html]
|
45
|
-
# to route emails through SNS.
|
46
|
-
#
|
47
|
-
# Configure SNS to send emails to +/rails/action_mailbox/amazon/inbound_emails+.
|
48
|
-
#
|
49
|
-
# If your application is found at <tt>https://example.com</tt> you would
|
50
|
-
# specify the fully-qualified URL <tt>https://example.com/rails/action_mailbox/amazon/inbound_emails</tt>.
|
51
|
-
#
|
52
31
|
|
53
32
|
module Ingresses
|
54
33
|
module Amazon
|
55
34
|
class InboundEmailsController < ActionMailbox::BaseController
|
56
|
-
before_action :verify_authenticity
|
57
|
-
before_action :validate_topic
|
58
|
-
before_action :confirm_subscription
|
35
|
+
before_action :verify_authenticity, :validate_topic, :confirm_subscription
|
59
36
|
|
60
37
|
def create
|
61
|
-
head :bad_request unless
|
38
|
+
head :bad_request unless notification.message_content.present?
|
62
39
|
|
63
|
-
ActionMailbox::InboundEmail.create_and_extract_message_id!(
|
40
|
+
ActionMailbox::InboundEmail.create_and_extract_message_id!(notification.message_content)
|
64
41
|
head :no_content
|
65
42
|
end
|
66
43
|
|
@@ -68,60 +45,30 @@ module ActionMailbox
|
|
68
45
|
|
69
46
|
def verify_authenticity
|
70
47
|
head :bad_request unless notification.present?
|
71
|
-
head :unauthorized unless verified?
|
48
|
+
head :unauthorized unless notification.verified?
|
72
49
|
end
|
73
50
|
|
74
51
|
def confirm_subscription
|
75
|
-
return unless notification
|
76
|
-
return head :ok if
|
52
|
+
return unless notification.type == 'SubscriptionConfirmation'
|
53
|
+
return head :ok if notification.subscription_confirmed?
|
77
54
|
|
78
55
|
Rails.logger.error('SNS subscription confirmation request rejected.')
|
79
56
|
head :unprocessable_entity
|
80
57
|
end
|
81
58
|
|
82
59
|
def validate_topic
|
83
|
-
return if valid_topics.include?(topic)
|
60
|
+
return if valid_topics.include?(notification.topic)
|
84
61
|
|
85
62
|
Rails.logger.warn("Ignoring unknown topic: #{topic}")
|
86
63
|
head :unauthorized
|
87
64
|
end
|
88
65
|
|
89
|
-
def confirmation_response_code
|
90
|
-
@confirmation_response_code ||= begin
|
91
|
-
Net::HTTP.get_response(URI(notification['SubscribeURL'])).code
|
92
|
-
end
|
93
|
-
end
|
94
|
-
|
95
66
|
def notification
|
96
|
-
@notification ||=
|
97
|
-
rescue JSON::ParserError => e
|
98
|
-
Rails.logger.warn("Unable to parse SNS notification: #{e}")
|
99
|
-
nil
|
100
|
-
end
|
101
|
-
|
102
|
-
def verified?
|
103
|
-
verifier.authentic?(@notification.to_json)
|
104
|
-
end
|
105
|
-
|
106
|
-
def verifier
|
107
|
-
Aws::SNS::MessageVerifier.new
|
108
|
-
end
|
109
|
-
|
110
|
-
def message
|
111
|
-
@message ||= JSON.parse(notification['Message'])
|
112
|
-
end
|
113
|
-
|
114
|
-
def mail
|
115
|
-
return nil unless notification['Type'] == 'Notification'
|
116
|
-
return nil unless message['notificationType'] == 'Received'
|
117
|
-
|
118
|
-
message['content']
|
67
|
+
@notification ||= ActionMailboxAmazonIngress::SnsNotification.new(request.raw_post)
|
119
68
|
end
|
120
69
|
|
121
70
|
def topic
|
122
|
-
|
123
|
-
|
124
|
-
notification['TopicArn']
|
71
|
+
@topic ||= notification.topic
|
125
72
|
end
|
126
73
|
|
127
74
|
def valid_topics
|
@@ -3,10 +3,11 @@
|
|
3
3
|
module ActionMailboxAmazonIngress
|
4
4
|
module RSpec
|
5
5
|
class Email
|
6
|
-
def initialize(authentic: true, topic: 'topic:arn:default', mail: default_mail)
|
6
|
+
def initialize(authentic: true, topic: 'topic:arn:default', mail: default_mail, message_params: {})
|
7
7
|
@authentic = authentic
|
8
8
|
@topic = topic
|
9
9
|
@mail = mail
|
10
|
+
@message_params = message_params
|
10
11
|
end
|
11
12
|
|
12
13
|
def headers
|
@@ -21,13 +22,17 @@ module ActionMailboxAmazonIngress
|
|
21
22
|
{
|
22
23
|
'Type' => 'Notification',
|
23
24
|
'TopicArn' => @topic,
|
24
|
-
'Message' =>
|
25
|
-
'notificationType' => 'Received',
|
26
|
-
'content' => @mail.encoded
|
27
|
-
}.to_json
|
25
|
+
'Message' => message_json
|
28
26
|
}
|
29
27
|
end
|
30
28
|
|
29
|
+
def message_json
|
30
|
+
{
|
31
|
+
'notificationType' => 'Received',
|
32
|
+
'content' => @mail.encoded
|
33
|
+
}.merge(@message_params).to_json
|
34
|
+
end
|
35
|
+
|
31
36
|
def authentic?
|
32
37
|
@authentic
|
33
38
|
end
|
@@ -9,15 +9,21 @@ module ActionMailboxAmazonIngress
|
|
9
9
|
subscription_confirmation = SubscriptionConfirmation.new(**options)
|
10
10
|
stub_aws_sns_message_verifier(subscription_confirmation)
|
11
11
|
stub_aws_sns_subscription_request
|
12
|
-
|
13
|
-
|
12
|
+
|
13
|
+
post subscription_confirmation.url,
|
14
|
+
params: subscription_confirmation.params,
|
15
|
+
headers: subscription_confirmation.headers,
|
16
|
+
as: :json
|
14
17
|
end
|
15
18
|
|
16
19
|
def amazon_ingress_deliver_email(options = {})
|
17
20
|
email = Email.new(**options)
|
18
21
|
stub_aws_sns_message_verifier(email)
|
19
|
-
|
20
|
-
|
22
|
+
|
23
|
+
post email.url,
|
24
|
+
params: email.params,
|
25
|
+
headers: email.headers,
|
26
|
+
as: :json
|
21
27
|
end
|
22
28
|
|
23
29
|
private
|
@@ -0,0 +1,98 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'aws-sdk-sns'
|
4
|
+
|
5
|
+
module ActionMailboxAmazonIngress
|
6
|
+
class SnsNotification
|
7
|
+
class MessageContentError < StandardError; end
|
8
|
+
|
9
|
+
def initialize(request_body)
|
10
|
+
@request_body = request_body
|
11
|
+
end
|
12
|
+
|
13
|
+
def subscription_confirmed?
|
14
|
+
confirmation_response.code&.start_with?('2')
|
15
|
+
end
|
16
|
+
|
17
|
+
def verified?
|
18
|
+
Aws::SNS::MessageVerifier.new.authentic?(@request_body)
|
19
|
+
end
|
20
|
+
|
21
|
+
def topic
|
22
|
+
notification.fetch(:TopicArn)
|
23
|
+
end
|
24
|
+
|
25
|
+
def type
|
26
|
+
notification.fetch(:Type)
|
27
|
+
end
|
28
|
+
|
29
|
+
def message_content
|
30
|
+
raise MessageContentError, 'Incoming emails must have notificationType `Received`' unless receipt?
|
31
|
+
|
32
|
+
if content_in_s3?
|
33
|
+
s3_content
|
34
|
+
else
|
35
|
+
return message[:content] unless destination
|
36
|
+
|
37
|
+
"X-Original-To: #{destination}\n#{message[:content]}"
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
private
|
42
|
+
|
43
|
+
def notification
|
44
|
+
@notification ||= JSON.parse(@request_body, symbolize_names: true)
|
45
|
+
rescue JSON::ParserError => e
|
46
|
+
Rails.logger.warn("Unable to parse SNS notification: #{e}")
|
47
|
+
nil
|
48
|
+
end
|
49
|
+
|
50
|
+
def s3_content
|
51
|
+
require 'aws-sdk-s3'
|
52
|
+
|
53
|
+
Aws::S3::Client
|
54
|
+
.new(region: region)
|
55
|
+
.get_object(key: key, bucket: bucket)
|
56
|
+
.body
|
57
|
+
.string
|
58
|
+
end
|
59
|
+
|
60
|
+
def message
|
61
|
+
@message ||= JSON.parse(notification[:Message], symbolize_names: true)
|
62
|
+
end
|
63
|
+
|
64
|
+
def destination
|
65
|
+
message.dig(:mail, :destination)&.first
|
66
|
+
end
|
67
|
+
|
68
|
+
def action
|
69
|
+
return unless message[:receipt]
|
70
|
+
|
71
|
+
message.fetch(:receipt).fetch(:action)
|
72
|
+
end
|
73
|
+
|
74
|
+
def bucket
|
75
|
+
action.fetch(:bucketName)
|
76
|
+
end
|
77
|
+
|
78
|
+
def region
|
79
|
+
action.fetch(:topicArn).split(':')[3]
|
80
|
+
end
|
81
|
+
|
82
|
+
def key
|
83
|
+
action.fetch(:objectKey)
|
84
|
+
end
|
85
|
+
|
86
|
+
def content_in_s3?
|
87
|
+
action&.fetch(:type) == 'S3'
|
88
|
+
end
|
89
|
+
|
90
|
+
def receipt?
|
91
|
+
message.fetch(:notificationType) == 'Received'
|
92
|
+
end
|
93
|
+
|
94
|
+
def confirmation_response
|
95
|
+
@confirmation_response ||= Net::HTTP.get_response(URI(notification[:SubscribeURL]))
|
96
|
+
end
|
97
|
+
end
|
98
|
+
end
|
metadata
CHANGED
@@ -1,169 +1,57 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: action_mailbox_amazon_ingress
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.2.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Bob Farrell
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2024-06-19 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
|
-
name: aws-sdk-
|
14
|
+
name: aws-sdk-s3
|
15
15
|
requirement: !ruby/object:Gem::Requirement
|
16
16
|
requirements:
|
17
17
|
- - "~>"
|
18
18
|
- !ruby/object:Gem::Version
|
19
|
-
version: '1.
|
19
|
+
version: '1.151'
|
20
20
|
type: :runtime
|
21
21
|
prerelease: false
|
22
22
|
version_requirements: !ruby/object:Gem::Requirement
|
23
23
|
requirements:
|
24
24
|
- - "~>"
|
25
25
|
- !ruby/object:Gem::Version
|
26
|
-
version: '1.
|
26
|
+
version: '1.151'
|
27
27
|
- !ruby/object:Gem::Dependency
|
28
|
-
name:
|
28
|
+
name: aws-sdk-sns
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|
30
30
|
requirements:
|
31
31
|
- - "~>"
|
32
32
|
- !ruby/object:Gem::Version
|
33
|
-
version: '
|
33
|
+
version: '1.75'
|
34
34
|
type: :runtime
|
35
35
|
prerelease: false
|
36
36
|
version_requirements: !ruby/object:Gem::Requirement
|
37
37
|
requirements:
|
38
38
|
- - "~>"
|
39
39
|
- !ruby/object:Gem::Version
|
40
|
-
version: '
|
41
|
-
- !ruby/object:Gem::Dependency
|
42
|
-
name: betterp
|
43
|
-
requirement: !ruby/object:Gem::Requirement
|
44
|
-
requirements:
|
45
|
-
- - "~>"
|
46
|
-
- !ruby/object:Gem::Version
|
47
|
-
version: 0.1.3
|
48
|
-
type: :development
|
49
|
-
prerelease: false
|
50
|
-
version_requirements: !ruby/object:Gem::Requirement
|
51
|
-
requirements:
|
52
|
-
- - "~>"
|
53
|
-
- !ruby/object:Gem::Version
|
54
|
-
version: 0.1.3
|
55
|
-
- !ruby/object:Gem::Dependency
|
56
|
-
name: devpack
|
57
|
-
requirement: !ruby/object:Gem::Requirement
|
58
|
-
requirements:
|
59
|
-
- - "~>"
|
60
|
-
- !ruby/object:Gem::Version
|
61
|
-
version: 0.2.1
|
62
|
-
type: :development
|
63
|
-
prerelease: false
|
64
|
-
version_requirements: !ruby/object:Gem::Requirement
|
65
|
-
requirements:
|
66
|
-
- - "~>"
|
67
|
-
- !ruby/object:Gem::Version
|
68
|
-
version: 0.2.1
|
69
|
-
- !ruby/object:Gem::Dependency
|
70
|
-
name: rake
|
71
|
-
requirement: !ruby/object:Gem::Requirement
|
72
|
-
requirements:
|
73
|
-
- - "~>"
|
74
|
-
- !ruby/object:Gem::Version
|
75
|
-
version: '13.0'
|
76
|
-
type: :development
|
77
|
-
prerelease: false
|
78
|
-
version_requirements: !ruby/object:Gem::Requirement
|
79
|
-
requirements:
|
80
|
-
- - "~>"
|
81
|
-
- !ruby/object:Gem::Version
|
82
|
-
version: '13.0'
|
83
|
-
- !ruby/object:Gem::Dependency
|
84
|
-
name: rspec-its
|
85
|
-
requirement: !ruby/object:Gem::Requirement
|
86
|
-
requirements:
|
87
|
-
- - "~>"
|
88
|
-
- !ruby/object:Gem::Version
|
89
|
-
version: '1.3'
|
90
|
-
type: :development
|
91
|
-
prerelease: false
|
92
|
-
version_requirements: !ruby/object:Gem::Requirement
|
93
|
-
requirements:
|
94
|
-
- - "~>"
|
95
|
-
- !ruby/object:Gem::Version
|
96
|
-
version: '1.3'
|
40
|
+
version: '1.75'
|
97
41
|
- !ruby/object:Gem::Dependency
|
98
|
-
name:
|
42
|
+
name: actionmailbox
|
99
43
|
requirement: !ruby/object:Gem::Requirement
|
100
44
|
requirements:
|
101
45
|
- - "~>"
|
102
46
|
- !ruby/object:Gem::Version
|
103
|
-
version: '
|
104
|
-
type: :
|
105
|
-
prerelease: false
|
106
|
-
version_requirements: !ruby/object:Gem::Requirement
|
107
|
-
requirements:
|
108
|
-
- - "~>"
|
109
|
-
- !ruby/object:Gem::Version
|
110
|
-
version: '4.0'
|
111
|
-
- !ruby/object:Gem::Dependency
|
112
|
-
name: rubocop
|
113
|
-
requirement: !ruby/object:Gem::Requirement
|
114
|
-
requirements:
|
115
|
-
- - "~>"
|
116
|
-
- !ruby/object:Gem::Version
|
117
|
-
version: 0.90.0
|
118
|
-
type: :development
|
119
|
-
prerelease: false
|
120
|
-
version_requirements: !ruby/object:Gem::Requirement
|
121
|
-
requirements:
|
122
|
-
- - "~>"
|
123
|
-
- !ruby/object:Gem::Version
|
124
|
-
version: 0.90.0
|
125
|
-
- !ruby/object:Gem::Dependency
|
126
|
-
name: sqlite3
|
127
|
-
requirement: !ruby/object:Gem::Requirement
|
128
|
-
requirements:
|
129
|
-
- - "~>"
|
130
|
-
- !ruby/object:Gem::Version
|
131
|
-
version: '1.4'
|
132
|
-
type: :development
|
133
|
-
prerelease: false
|
134
|
-
version_requirements: !ruby/object:Gem::Requirement
|
135
|
-
requirements:
|
136
|
-
- - "~>"
|
137
|
-
- !ruby/object:Gem::Version
|
138
|
-
version: '1.4'
|
139
|
-
- !ruby/object:Gem::Dependency
|
140
|
-
name: strong_versions
|
141
|
-
requirement: !ruby/object:Gem::Requirement
|
142
|
-
requirements:
|
143
|
-
- - "~>"
|
144
|
-
- !ruby/object:Gem::Version
|
145
|
-
version: 0.4.5
|
146
|
-
type: :development
|
147
|
-
prerelease: false
|
148
|
-
version_requirements: !ruby/object:Gem::Requirement
|
149
|
-
requirements:
|
150
|
-
- - "~>"
|
151
|
-
- !ruby/object:Gem::Version
|
152
|
-
version: 0.4.5
|
153
|
-
- !ruby/object:Gem::Dependency
|
154
|
-
name: webmock
|
155
|
-
requirement: !ruby/object:Gem::Requirement
|
156
|
-
requirements:
|
157
|
-
- - "~>"
|
158
|
-
- !ruby/object:Gem::Version
|
159
|
-
version: '3.8'
|
160
|
-
type: :development
|
47
|
+
version: '7.1'
|
48
|
+
type: :runtime
|
161
49
|
prerelease: false
|
162
50
|
version_requirements: !ruby/object:Gem::Requirement
|
163
51
|
requirements:
|
164
52
|
- - "~>"
|
165
53
|
- !ruby/object:Gem::Version
|
166
|
-
version: '
|
54
|
+
version: '7.1'
|
167
55
|
description: Integrate Amazon SES with ActionMailbox
|
168
56
|
email:
|
169
57
|
- git@bob.frl
|
@@ -171,6 +59,7 @@ executables: []
|
|
171
59
|
extensions: []
|
172
60
|
extra_rdoc_files: []
|
173
61
|
files:
|
62
|
+
- ".github/workflows/ruby.yml"
|
174
63
|
- ".gitignore"
|
175
64
|
- ".rspec"
|
176
65
|
- ".rubocop.yml"
|
@@ -195,11 +84,13 @@ files:
|
|
195
84
|
- lib/action_mailbox_amazon_ingress/rspec.rb
|
196
85
|
- lib/action_mailbox_amazon_ingress/rspec/email.rb
|
197
86
|
- lib/action_mailbox_amazon_ingress/rspec/subscription_confirmation.rb
|
87
|
+
- lib/action_mailbox_amazon_ingress/sns_notification.rb
|
198
88
|
- lib/action_mailbox_amazon_ingress/version.rb
|
199
89
|
homepage: https://github.com/bobf/action_mailbox_amazon_ingress
|
200
90
|
licenses:
|
201
91
|
- MIT
|
202
|
-
metadata:
|
92
|
+
metadata:
|
93
|
+
rubygems_mfa_required: 'true'
|
203
94
|
post_install_message:
|
204
95
|
rdoc_options: []
|
205
96
|
require_paths:
|
@@ -208,15 +99,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
208
99
|
requirements:
|
209
100
|
- - ">="
|
210
101
|
- !ruby/object:Gem::Version
|
211
|
-
version: '2
|
102
|
+
version: '3.2'
|
212
103
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
213
104
|
requirements:
|
214
105
|
- - ">="
|
215
106
|
- !ruby/object:Gem::Version
|
216
107
|
version: '0'
|
217
108
|
requirements: []
|
218
|
-
|
219
|
-
rubygems_version: 2.7.6
|
109
|
+
rubygems_version: 3.4.19
|
220
110
|
signing_key:
|
221
111
|
specification_version: 4
|
222
112
|
summary: Amazon SES ingress for Rails ActionMailbox
|