action_mailbox_amazon_ingress 0.1.3 → 0.2.0
Sign up to get free protection for your applications and to get access to all the features.
- 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 +14 -7
- data/Rakefile +69 -0
- data/action_mailbox_amazon_ingress.gemspec +5 -15
- 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 +19 -115
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
@@ -14,22 +14,20 @@ gem 'action_mailbox_amazon_ingress', '~> 0.1.3'
|
|
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,31 +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 'devpack', '~> 0.3.3'
|
32
|
-
spec.add_development_dependency 'rake', '~> 13.0'
|
33
|
-
spec.add_development_dependency 'rspec-its', '~> 1.3'
|
34
|
-
spec.add_development_dependency 'rspec-rails', '~> 4.0'
|
35
|
-
spec.add_development_dependency 'rubocop', '~> 0.90.0'
|
36
|
-
spec.add_development_dependency 'sqlite3', '~> 1.4'
|
37
|
-
spec.add_development_dependency 'strong_versions', '~> 0.4.5'
|
38
|
-
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'
|
39
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,155 +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.
|
27
|
-
- !ruby/object:Gem::Dependency
|
28
|
-
name: rails
|
29
|
-
requirement: !ruby/object:Gem::Requirement
|
30
|
-
requirements:
|
31
|
-
- - ">="
|
32
|
-
- !ruby/object:Gem::Version
|
33
|
-
version: '6.1'
|
34
|
-
type: :runtime
|
35
|
-
prerelease: false
|
36
|
-
version_requirements: !ruby/object:Gem::Requirement
|
37
|
-
requirements:
|
38
|
-
- - ">="
|
39
|
-
- !ruby/object:Gem::Version
|
40
|
-
version: '6.1'
|
26
|
+
version: '1.151'
|
41
27
|
- !ruby/object:Gem::Dependency
|
42
|
-
name:
|
43
|
-
requirement: !ruby/object:Gem::Requirement
|
44
|
-
requirements:
|
45
|
-
- - "~>"
|
46
|
-
- !ruby/object:Gem::Version
|
47
|
-
version: 0.3.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.3.3
|
55
|
-
- !ruby/object:Gem::Dependency
|
56
|
-
name: rake
|
57
|
-
requirement: !ruby/object:Gem::Requirement
|
58
|
-
requirements:
|
59
|
-
- - "~>"
|
60
|
-
- !ruby/object:Gem::Version
|
61
|
-
version: '13.0'
|
62
|
-
type: :development
|
63
|
-
prerelease: false
|
64
|
-
version_requirements: !ruby/object:Gem::Requirement
|
65
|
-
requirements:
|
66
|
-
- - "~>"
|
67
|
-
- !ruby/object:Gem::Version
|
68
|
-
version: '13.0'
|
69
|
-
- !ruby/object:Gem::Dependency
|
70
|
-
name: rspec-its
|
71
|
-
requirement: !ruby/object:Gem::Requirement
|
72
|
-
requirements:
|
73
|
-
- - "~>"
|
74
|
-
- !ruby/object:Gem::Version
|
75
|
-
version: '1.3'
|
76
|
-
type: :development
|
77
|
-
prerelease: false
|
78
|
-
version_requirements: !ruby/object:Gem::Requirement
|
79
|
-
requirements:
|
80
|
-
- - "~>"
|
81
|
-
- !ruby/object:Gem::Version
|
82
|
-
version: '1.3'
|
83
|
-
- !ruby/object:Gem::Dependency
|
84
|
-
name: rspec-rails
|
85
|
-
requirement: !ruby/object:Gem::Requirement
|
86
|
-
requirements:
|
87
|
-
- - "~>"
|
88
|
-
- !ruby/object:Gem::Version
|
89
|
-
version: '4.0'
|
90
|
-
type: :development
|
91
|
-
prerelease: false
|
92
|
-
version_requirements: !ruby/object:Gem::Requirement
|
93
|
-
requirements:
|
94
|
-
- - "~>"
|
95
|
-
- !ruby/object:Gem::Version
|
96
|
-
version: '4.0'
|
97
|
-
- !ruby/object:Gem::Dependency
|
98
|
-
name: rubocop
|
99
|
-
requirement: !ruby/object:Gem::Requirement
|
100
|
-
requirements:
|
101
|
-
- - "~>"
|
102
|
-
- !ruby/object:Gem::Version
|
103
|
-
version: 0.90.0
|
104
|
-
type: :development
|
105
|
-
prerelease: false
|
106
|
-
version_requirements: !ruby/object:Gem::Requirement
|
107
|
-
requirements:
|
108
|
-
- - "~>"
|
109
|
-
- !ruby/object:Gem::Version
|
110
|
-
version: 0.90.0
|
111
|
-
- !ruby/object:Gem::Dependency
|
112
|
-
name: sqlite3
|
113
|
-
requirement: !ruby/object:Gem::Requirement
|
114
|
-
requirements:
|
115
|
-
- - "~>"
|
116
|
-
- !ruby/object:Gem::Version
|
117
|
-
version: '1.4'
|
118
|
-
type: :development
|
119
|
-
prerelease: false
|
120
|
-
version_requirements: !ruby/object:Gem::Requirement
|
121
|
-
requirements:
|
122
|
-
- - "~>"
|
123
|
-
- !ruby/object:Gem::Version
|
124
|
-
version: '1.4'
|
125
|
-
- !ruby/object:Gem::Dependency
|
126
|
-
name: strong_versions
|
28
|
+
name: aws-sdk-sns
|
127
29
|
requirement: !ruby/object:Gem::Requirement
|
128
30
|
requirements:
|
129
31
|
- - "~>"
|
130
32
|
- !ruby/object:Gem::Version
|
131
|
-
version:
|
132
|
-
type: :
|
33
|
+
version: '1.75'
|
34
|
+
type: :runtime
|
133
35
|
prerelease: false
|
134
36
|
version_requirements: !ruby/object:Gem::Requirement
|
135
37
|
requirements:
|
136
38
|
- - "~>"
|
137
39
|
- !ruby/object:Gem::Version
|
138
|
-
version:
|
40
|
+
version: '1.75'
|
139
41
|
- !ruby/object:Gem::Dependency
|
140
|
-
name:
|
42
|
+
name: actionmailbox
|
141
43
|
requirement: !ruby/object:Gem::Requirement
|
142
44
|
requirements:
|
143
45
|
- - "~>"
|
144
46
|
- !ruby/object:Gem::Version
|
145
|
-
version: '
|
146
|
-
type: :
|
47
|
+
version: '7.1'
|
48
|
+
type: :runtime
|
147
49
|
prerelease: false
|
148
50
|
version_requirements: !ruby/object:Gem::Requirement
|
149
51
|
requirements:
|
150
52
|
- - "~>"
|
151
53
|
- !ruby/object:Gem::Version
|
152
|
-
version: '
|
54
|
+
version: '7.1'
|
153
55
|
description: Integrate Amazon SES with ActionMailbox
|
154
56
|
email:
|
155
57
|
- git@bob.frl
|
@@ -157,6 +59,7 @@ executables: []
|
|
157
59
|
extensions: []
|
158
60
|
extra_rdoc_files: []
|
159
61
|
files:
|
62
|
+
- ".github/workflows/ruby.yml"
|
160
63
|
- ".gitignore"
|
161
64
|
- ".rspec"
|
162
65
|
- ".rubocop.yml"
|
@@ -181,11 +84,13 @@ files:
|
|
181
84
|
- lib/action_mailbox_amazon_ingress/rspec.rb
|
182
85
|
- lib/action_mailbox_amazon_ingress/rspec/email.rb
|
183
86
|
- lib/action_mailbox_amazon_ingress/rspec/subscription_confirmation.rb
|
87
|
+
- lib/action_mailbox_amazon_ingress/sns_notification.rb
|
184
88
|
- lib/action_mailbox_amazon_ingress/version.rb
|
185
89
|
homepage: https://github.com/bobf/action_mailbox_amazon_ingress
|
186
90
|
licenses:
|
187
91
|
- MIT
|
188
|
-
metadata:
|
92
|
+
metadata:
|
93
|
+
rubygems_mfa_required: 'true'
|
189
94
|
post_install_message:
|
190
95
|
rdoc_options: []
|
191
96
|
require_paths:
|
@@ -194,15 +99,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
194
99
|
requirements:
|
195
100
|
- - ">="
|
196
101
|
- !ruby/object:Gem::Version
|
197
|
-
version: '2
|
102
|
+
version: '3.2'
|
198
103
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
199
104
|
requirements:
|
200
105
|
- - ">="
|
201
106
|
- !ruby/object:Gem::Version
|
202
107
|
version: '0'
|
203
108
|
requirements: []
|
204
|
-
|
205
|
-
rubygems_version: 2.7.6
|
109
|
+
rubygems_version: 3.4.19
|
206
110
|
signing_key:
|
207
111
|
specification_version: 4
|
208
112
|
summary: Amazon SES ingress for Rails ActionMailbox
|