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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: b26f2cfe0ca42ab7c2db9987a82c666a6f7445fc7389c7085f79c707a76d5899
4
- data.tar.gz: a8fe61d7f510e118805f199cfde57d0907db72b8bf1ffe47ebf6ea998f206a01
3
+ metadata.gz: 94d231867bda21e8d23375b26f34761b3b0125d6bad53e312cb37be1fc939788
4
+ data.tar.gz: 912a90256bf244ef73a41d8e3b19b2e2d052e5fd52a9dcfaff3c8fb9e8c21a85
5
5
  SHA512:
6
- metadata.gz: 56389ac398f5fdf2bffa59827383ed915d600a9667e2a5d092ba1874c51edf4fc3896d8ddac26bbde7359f7ae5ad330603059c8f62bcd5ff571a49de4ce0e027
7
- data.tar.gz: 6bd724fef91f51ea927f91fd95106dd4a42901aa857154ec4d8fbc087d6f99773f735c05b4af59bd38db708593714f1c4822f81a18f53f014791e53888bb2029
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.5.3
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.2'
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 _SES_ to [route emails through SNS](https://docs.aws.amazon.com/ses/latest/DeveloperGuide/configure-sns-notifications.html).
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
- If your website is hosted at https://www.example.com then configure _SNS_ to publish the _SES_ notification topic to this _HTTP_ endpoint:
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 delivered via _ActionMailbox_.
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.5'
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-sns', '~> 1.23'
29
- spec.add_dependency 'rails', '~> 6'
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 mail.present?
38
+ head :bad_request unless notification.message_content.present?
62
39
 
63
- ActionMailbox::InboundEmail.create_and_extract_message_id!(mail)
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['Type'] == 'SubscriptionConfirmation'
76
- return head :ok if confirmation_response_code&.start_with?('2')
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 ||= JSON.parse(request.body.read)
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
- return nil unless notification.present?
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
- post subscription_confirmation.url, params: subscription_confirmation.params.to_json,
13
- headers: subscription_confirmation.headers
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
- post email.url, params: email.params.to_json,
20
- headers: email.headers
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
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module ActionMailboxAmazonIngress
4
- VERSION = '0.1.2'
4
+ VERSION = '0.2.0'
5
5
  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.1.2
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: 2021-12-15 00:00:00.000000000 Z
11
+ date: 2024-06-19 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
- name: aws-sdk-sns
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.23'
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.23'
26
+ version: '1.151'
27
27
  - !ruby/object:Gem::Dependency
28
- name: rails
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: '6'
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: '6'
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: rspec-rails
42
+ name: actionmailbox
99
43
  requirement: !ruby/object:Gem::Requirement
100
44
  requirements:
101
45
  - - "~>"
102
46
  - !ruby/object:Gem::Version
103
- version: '4.0'
104
- type: :development
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: '3.8'
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.5'
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
- rubyforge_project:
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