actionmailbox 6.0.0.beta1

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.
Files changed (55) hide show
  1. checksums.yaml +7 -0
  2. data/CHANGELOG.md +5 -0
  3. data/MIT-LICENSE +21 -0
  4. data/README.md +13 -0
  5. data/app/controllers/action_mailbox/base_controller.rb +38 -0
  6. data/app/controllers/action_mailbox/ingresses/amazon/inbound_emails_controller.rb +54 -0
  7. data/app/controllers/action_mailbox/ingresses/mailgun/inbound_emails_controller.rb +103 -0
  8. data/app/controllers/action_mailbox/ingresses/mandrill/inbound_emails_controller.rb +82 -0
  9. data/app/controllers/action_mailbox/ingresses/postmark/inbound_emails_controller.rb +62 -0
  10. data/app/controllers/action_mailbox/ingresses/relay/inbound_emails_controller.rb +65 -0
  11. data/app/controllers/action_mailbox/ingresses/sendgrid/inbound_emails_controller.rb +54 -0
  12. data/app/controllers/rails/conductor/action_mailbox/inbound_emails_controller.rb +34 -0
  13. data/app/controllers/rails/conductor/action_mailbox/reroutes_controller.rb +19 -0
  14. data/app/controllers/rails/conductor/base_controller.rb +14 -0
  15. data/app/jobs/action_mailbox/incineration_job.rb +22 -0
  16. data/app/jobs/action_mailbox/routing_job.rb +13 -0
  17. data/app/models/action_mailbox/inbound_email.rb +49 -0
  18. data/app/models/action_mailbox/inbound_email/incineratable.rb +20 -0
  19. data/app/models/action_mailbox/inbound_email/incineratable/incineration.rb +26 -0
  20. data/app/models/action_mailbox/inbound_email/message_id.rb +38 -0
  21. data/app/models/action_mailbox/inbound_email/routable.rb +24 -0
  22. data/app/views/layouts/rails/conductor.html.erb +7 -0
  23. data/app/views/rails/conductor/action_mailbox/inbound_emails/index.html.erb +15 -0
  24. data/app/views/rails/conductor/action_mailbox/inbound_emails/new.html.erb +47 -0
  25. data/app/views/rails/conductor/action_mailbox/inbound_emails/show.html.erb +15 -0
  26. data/config/routes.rb +20 -0
  27. data/db/migrate/20180917164000_create_action_mailbox_tables.rb +17 -0
  28. data/lib/action_mailbox.rb +16 -0
  29. data/lib/action_mailbox/base.rb +118 -0
  30. data/lib/action_mailbox/callbacks.rb +34 -0
  31. data/lib/action_mailbox/engine.rb +42 -0
  32. data/lib/action_mailbox/gem_version.rb +17 -0
  33. data/lib/action_mailbox/mail_ext.rb +6 -0
  34. data/lib/action_mailbox/mail_ext/address_equality.rb +9 -0
  35. data/lib/action_mailbox/mail_ext/address_wrapping.rb +9 -0
  36. data/lib/action_mailbox/mail_ext/addresses.rb +29 -0
  37. data/lib/action_mailbox/mail_ext/from_source.rb +7 -0
  38. data/lib/action_mailbox/mail_ext/recipients.rb +9 -0
  39. data/lib/action_mailbox/relayer.rb +75 -0
  40. data/lib/action_mailbox/router.rb +42 -0
  41. data/lib/action_mailbox/router/route.rb +42 -0
  42. data/lib/action_mailbox/routing.rb +22 -0
  43. data/lib/action_mailbox/test_case.rb +12 -0
  44. data/lib/action_mailbox/test_helper.rb +44 -0
  45. data/lib/action_mailbox/version.rb +10 -0
  46. data/lib/rails/generators/installer.rb +10 -0
  47. data/lib/rails/generators/mailbox/USAGE +12 -0
  48. data/lib/rails/generators/mailbox/mailbox_generator.rb +32 -0
  49. data/lib/rails/generators/mailbox/templates/application_mailbox.rb.tt +3 -0
  50. data/lib/rails/generators/mailbox/templates/mailbox.rb.tt +4 -0
  51. data/lib/rails/generators/test_unit/mailbox_generator.rb +20 -0
  52. data/lib/rails/generators/test_unit/templates/mailbox_test.rb.tt +13 -0
  53. data/lib/tasks/ingress.rake +72 -0
  54. data/lib/tasks/install.rake +20 -0
  55. metadata +184 -0
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: beb8145f8e8da8e158c0811ec7522495e294d13727c4960ec1810654d17c1299
4
+ data.tar.gz: f01ffcc7f94e19ffac7f01c4036886d6ad8ee9e57292e12920a1c98b954a7ce4
5
+ SHA512:
6
+ metadata.gz: 9219f0eb8d3f102068e9ea9b8c48e223e57ac79348d76c5418eb2e85ba797df68b3f8f8a0ee0f6881044c64ea38a3d0264d123550aef9aa5ac958e5f9d420d51
7
+ data.tar.gz: 32707b7b14716c46e76069a189275fd8f8ee064aa164cdbecccce869579719163a6e0ec33336dda9417363923a9e2d4958dffa916a0d9ad2e7ade9ae96e11c97
@@ -0,0 +1,5 @@
1
+ ## Rails 6.0.0.beta1 (January 18, 2019) ##
2
+
3
+ * Added to Rails.
4
+
5
+ *DHH*
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2019 Basecamp, LLC
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,13 @@
1
+ # Action Mailbox
2
+
3
+ Action Mailbox routes incoming emails to controller-like mailboxes for processing in Rails. It ships with ingresses for Amazon SES, Mailgun, Mandrill, Postmark, and SendGrid. You can also handle inbound mails directly via the built-in Exim, Postfix, and Qmail ingresses.
4
+
5
+ The inbound emails are turned into `InboundEmail` records using Active Record and feature lifecycle tracking, storage of the original email on cloud storage via Active Storage, and responsible data handling with on-by-default incineration.
6
+
7
+ These inbound emails are routed asynchronously using Active Job to one or several dedicated mailboxes, which are capable of interacting directly with the rest of your domain model.
8
+
9
+ You can read more about Action Mailbox in the [Action Mailbox Basics](https://edgeguides.rubyonrails.org/action_mailbox_basics.html) guide.
10
+
11
+ ## License
12
+
13
+ Action Mailbox is released under the [MIT License](https://opensource.org/licenses/MIT).
@@ -0,0 +1,38 @@
1
+ # frozen_string_literal: true
2
+
3
+ module ActionMailbox
4
+ # The base class for all Action Mailbox ingress controllers.
5
+ class BaseController < ActionController::Base
6
+ skip_forgery_protection
7
+
8
+ before_action :ensure_configured
9
+
10
+ def self.prepare
11
+ # Override in concrete controllers to run code on load.
12
+ end
13
+
14
+ private
15
+ def ensure_configured
16
+ unless ActionMailbox.ingress == ingress_name
17
+ head :not_found
18
+ end
19
+ end
20
+
21
+ def ingress_name
22
+ self.class.name.remove(/\AActionMailbox::Ingresses::/, /::InboundEmailsController\z/).underscore.to_sym
23
+ end
24
+
25
+
26
+ def authenticate_by_password
27
+ if password.present?
28
+ http_basic_authenticate_or_request_with name: "actionmailbox", password: password, realm: "Action Mailbox"
29
+ else
30
+ raise ArgumentError, "Missing required ingress credentials"
31
+ end
32
+ end
33
+
34
+ def password
35
+ Rails.application.credentials.dig(:action_mailbox, :ingress_password) || ENV["RAILS_INBOUND_EMAIL_PASSWORD"]
36
+ end
37
+ end
38
+ end
@@ -0,0 +1,54 @@
1
+ # frozen_string_literal: true
2
+
3
+ module ActionMailbox
4
+ # Ingests inbound emails from Amazon's Simple Email Service (SES).
5
+ #
6
+ # Requires the full RFC 822 message in the +content+ parameter. Authenticates requests by validating their signatures.
7
+ #
8
+ # Returns:
9
+ #
10
+ # - <tt>204 No Content</tt> if an inbound email is successfully recorded and enqueued for routing to the appropriate mailbox
11
+ # - <tt>401 Unauthorized</tt> if the request's signature could not be validated
12
+ # - <tt>404 Not Found</tt> if Action Mailbox is not configured to accept inbound emails from SES
13
+ # - <tt>422 Unprocessable Entity</tt> if the request is missing the required +content+ parameter
14
+ # - <tt>500 Server Error</tt> if one of the Active Record database, the Active Storage service, or
15
+ # the Active Job backend is misconfigured or unavailable
16
+ #
17
+ # == Usage
18
+ #
19
+ # 1. Install the {aws-sdk-sns}[https://rubygems.org/gems/aws-sdk-sns] gem:
20
+ #
21
+ # # Gemfile
22
+ # gem "aws-sdk-sns", ">= 1.9.0", require: false
23
+ #
24
+ # 2. Tell Action Mailbox to accept emails from SES:
25
+ #
26
+ # # config/environments/production.rb
27
+ # config.action_mailbox.ingress = :amazon
28
+ #
29
+ # 3. {Configure SES}[https://docs.aws.amazon.com/ses/latest/DeveloperGuide/receiving-email-notifications.html]
30
+ # to deliver emails to your application via POST requests to +/rails/action_mailbox/amazon/inbound_emails+.
31
+ # If your application lived at <tt>https://example.com</tt>, you would specify the fully-qualified URL
32
+ # <tt>https://example.com/rails/action_mailbox/amazon/inbound_emails</tt>.
33
+ class Ingresses::Amazon::InboundEmailsController < BaseController
34
+ before_action :authenticate
35
+
36
+ cattr_accessor :verifier
37
+
38
+ def self.prepare
39
+ self.verifier ||= begin
40
+ require "aws-sdk-sns"
41
+ Aws::SNS::MessageVerifier.new
42
+ end
43
+ end
44
+
45
+ def create
46
+ ActionMailbox::InboundEmail.create_and_extract_message_id! params.require(:content)
47
+ end
48
+
49
+ private
50
+ def authenticate
51
+ head :unauthorized unless verifier.authentic?(request.body)
52
+ end
53
+ end
54
+ end
@@ -0,0 +1,103 @@
1
+ # frozen_string_literal: true
2
+
3
+ module ActionMailbox
4
+ # Ingests inbound emails from Mailgun. Requires the following parameters:
5
+ #
6
+ # - +body-mime+: The full RFC 822 message
7
+ # - +timestamp+: The current time according to Mailgun as the number of seconds passed since the UNIX epoch
8
+ # - +token+: A randomly-generated, 50-character string
9
+ # - +signature+: A hexadecimal HMAC-SHA256 of the timestamp concatenated with the token, generated using the Mailgun API key
10
+ #
11
+ # Authenticates requests by validating their signatures.
12
+ #
13
+ # Returns:
14
+ #
15
+ # - <tt>204 No Content</tt> if an inbound email is successfully recorded and enqueued for routing to the appropriate mailbox
16
+ # - <tt>401 Unauthorized</tt> if the request's signature could not be validated, or if its timestamp is more than 2 minutes old
17
+ # - <tt>404 Not Found</tt> if Action Mailbox is not configured to accept inbound emails from Mailgun
18
+ # - <tt>422 Unprocessable Entity</tt> if the request is missing required parameters
19
+ # - <tt>500 Server Error</tt> if the Mailgun API key is missing, or one of the Active Record database,
20
+ # the Active Storage service, or the Active Job backend is misconfigured or unavailable
21
+ #
22
+ # == Usage
23
+ #
24
+ # 1. Give Action Mailbox your {Mailgun API key}[https://help.mailgun.com/hc/en-us/articles/203380100-Where-can-I-find-my-API-key-and-SMTP-credentials-]
25
+ # so it can authenticate requests to the Mailgun ingress.
26
+ #
27
+ # Use <tt>rails credentials:edit</tt> to add your API key to your application's encrypted credentials under
28
+ # +action_mailbox.mailgun_api_key+, where Action Mailbox will automatically find it:
29
+ #
30
+ # action_mailbox:
31
+ # mailgun_api_key: ...
32
+ #
33
+ # Alternatively, provide your API key in the +MAILGUN_INGRESS_API_KEY+ environment variable.
34
+ #
35
+ # 2. Tell Action Mailbox to accept emails from Mailgun:
36
+ #
37
+ # # config/environments/production.rb
38
+ # config.action_mailbox.ingress = :mailgun
39
+ #
40
+ # 3. {Configure Mailgun}[https://documentation.mailgun.com/en/latest/user_manual.html#receiving-forwarding-and-storing-messages]
41
+ # to forward inbound emails to +/rails/action_mailbox/mailgun/inbound_emails/mime+.
42
+ #
43
+ # If your application lived at <tt>https://example.com</tt>, you would specify the fully-qualified URL
44
+ # <tt>https://example.com/rails/action_mailbox/mailgun/inbound_emails/mime</tt>.
45
+ class Ingresses::Mailgun::InboundEmailsController < ActionMailbox::BaseController
46
+ before_action :authenticate
47
+
48
+ def create
49
+ ActionMailbox::InboundEmail.create_and_extract_message_id! params.require("body-mime")
50
+ end
51
+
52
+ private
53
+ def authenticate
54
+ head :unauthorized unless authenticated?
55
+ end
56
+
57
+ def authenticated?
58
+ if key.present?
59
+ Authenticator.new(
60
+ key: key,
61
+ timestamp: params.require(:timestamp),
62
+ token: params.require(:token),
63
+ signature: params.require(:signature)
64
+ ).authenticated?
65
+ else
66
+ raise ArgumentError, <<~MESSAGE.squish
67
+ Missing required Mailgun API key. Set action_mailbox.mailgun_api_key in your application's
68
+ encrypted credentials or provide the MAILGUN_INGRESS_API_KEY environment variable.
69
+ MESSAGE
70
+ end
71
+ end
72
+
73
+ def key
74
+ Rails.application.credentials.dig(:action_mailbox, :mailgun_api_key) || ENV["MAILGUN_INGRESS_API_KEY"]
75
+ end
76
+
77
+ class Authenticator
78
+ attr_reader :key, :timestamp, :token, :signature
79
+
80
+ def initialize(key:, timestamp:, token:, signature:)
81
+ @key, @timestamp, @token, @signature = key, Integer(timestamp), token, signature
82
+ end
83
+
84
+ def authenticated?
85
+ signed? && recent?
86
+ end
87
+
88
+ private
89
+ def signed?
90
+ ActiveSupport::SecurityUtils.secure_compare signature, expected_signature
91
+ end
92
+
93
+ # Allow for 2 minutes of drift between Mailgun time and local server time.
94
+ def recent?
95
+ Time.at(timestamp) >= 2.minutes.ago
96
+ end
97
+
98
+ def expected_signature
99
+ OpenSSL::HMAC.hexdigest OpenSSL::Digest::SHA256.new, key, "#{timestamp}#{token}"
100
+ end
101
+ end
102
+ end
103
+ end
@@ -0,0 +1,82 @@
1
+ # frozen_string_literal: true
2
+
3
+ module ActionMailbox
4
+ # Ingests inbound emails from Mandrill.
5
+ #
6
+ # Requires a +mandrill_events+ parameter containing a JSON array of Mandrill inbound email event objects.
7
+ # Each event is expected to have a +msg+ object containing a full RFC 822 message in its +raw_msg+ property.
8
+ #
9
+ # Returns:
10
+ #
11
+ # - <tt>204 No Content</tt> if an inbound email is successfully recorded and enqueued for routing to the appropriate mailbox
12
+ # - <tt>401 Unauthorized</tt> if the request's signature could not be validated
13
+ # - <tt>404 Not Found</tt> if Action Mailbox is not configured to accept inbound emails from Mandrill
14
+ # - <tt>422 Unprocessable Entity</tt> if the request is missing required parameters
15
+ # - <tt>500 Server Error</tt> if the Mandrill API key is missing, or one of the Active Record database,
16
+ # the Active Storage service, or the Active Job backend is misconfigured or unavailable
17
+ class Ingresses::Mandrill::InboundEmailsController < ActionMailbox::BaseController
18
+ before_action :authenticate
19
+
20
+ def create
21
+ raw_emails.each { |raw_email| ActionMailbox::InboundEmail.create_and_extract_message_id! raw_email }
22
+ head :ok
23
+ rescue JSON::ParserError => error
24
+ logger.error error.message
25
+ head :unprocessable_entity
26
+ end
27
+
28
+ private
29
+ def raw_emails
30
+ events.select { |event| event["event"] == "inbound" }.collect { |event| event.dig("msg", "raw_msg") }
31
+ end
32
+
33
+ def events
34
+ JSON.parse params.require(:mandrill_events)
35
+ end
36
+
37
+
38
+ def authenticate
39
+ head :unauthorized unless authenticated?
40
+ end
41
+
42
+ def authenticated?
43
+ if key.present?
44
+ Authenticator.new(request, key).authenticated?
45
+ else
46
+ raise ArgumentError, <<~MESSAGE.squish
47
+ Missing required Mandrill API key. Set action_mailbox.mandrill_api_key in your application's
48
+ encrypted credentials or provide the MANDRILL_INGRESS_API_KEY environment variable.
49
+ MESSAGE
50
+ end
51
+ end
52
+
53
+ def key
54
+ Rails.application.credentials.dig(:action_mailbox, :mandrill_api_key) || ENV["MANDRILL_INGRESS_API_KEY"]
55
+ end
56
+
57
+ class Authenticator
58
+ attr_reader :request, :key
59
+
60
+ def initialize(request, key)
61
+ @request, @key = request, key
62
+ end
63
+
64
+ def authenticated?
65
+ ActiveSupport::SecurityUtils.secure_compare given_signature, expected_signature
66
+ end
67
+
68
+ private
69
+ def given_signature
70
+ request.headers["X-Mandrill-Signature"]
71
+ end
72
+
73
+ def expected_signature
74
+ Base64.strict_encode64 OpenSSL::HMAC.digest(OpenSSL::Digest::SHA1.new, key, message)
75
+ end
76
+
77
+ def message
78
+ request.url + request.POST.sort.flatten.join
79
+ end
80
+ end
81
+ end
82
+ end
@@ -0,0 +1,62 @@
1
+ # frozen_string_literal: true
2
+
3
+ module ActionMailbox
4
+ # Ingests inbound emails from Postmark. Requires a +RawEmail+ parameter containing a full RFC 822 message.
5
+ #
6
+ # Authenticates requests using HTTP basic access authentication. The username is always +actionmailbox+, and the
7
+ # password is read from the application's encrypted credentials or an environment variable. See the Usage section below.
8
+ #
9
+ # Note that basic authentication is insecure over unencrypted HTTP. An attacker that intercepts cleartext requests to
10
+ # the Postmark ingress can learn its password. You should only use the Postmark ingress over HTTPS.
11
+ #
12
+ # Returns:
13
+ #
14
+ # - <tt>204 No Content</tt> if an inbound email is successfully recorded and enqueued for routing to the appropriate mailbox
15
+ # - <tt>401 Unauthorized</tt> if the request's signature could not be validated
16
+ # - <tt>404 Not Found</tt> if Action Mailbox is not configured to accept inbound emails from Postmark
17
+ # - <tt>422 Unprocessable Entity</tt> if the request is missing the required +RawEmail+ parameter
18
+ # - <tt>500 Server Error</tt> if the ingress password is not configured, or if one of the Active Record database,
19
+ # the Active Storage service, or the Active Job backend is misconfigured or unavailable
20
+ #
21
+ # == Usage
22
+ #
23
+ # 1. Tell Action Mailbox to accept emails from Postmark:
24
+ #
25
+ # # config/environments/production.rb
26
+ # config.action_mailbox.ingress = :postmark
27
+ #
28
+ # 2. Generate a strong password that Action Mailbox can use to authenticate requests to the Postmark ingress.
29
+ #
30
+ # Use <tt>rails credentials:edit</tt> to add the password to your application's encrypted credentials under
31
+ # +action_mailbox.ingress_password+, where Action Mailbox will automatically find it:
32
+ #
33
+ # action_mailbox:
34
+ # ingress_password: ...
35
+ #
36
+ # Alternatively, provide the password in the +RAILS_INBOUND_EMAIL_PASSWORD+ environment variable.
37
+ #
38
+ # 3. {Configure Postmark}[https://postmarkapp.com/manual#configure-your-inbound-webhook-url] to forward inbound emails
39
+ # to +/rails/action_mailbox/postmark/inbound_emails+ with the username +actionmailbox+ and the password you
40
+ # previously generated. If your application lived at <tt>https://example.com</tt>, you would configure your
41
+ # Postmark inbound webhook with the following fully-qualified URL:
42
+ #
43
+ # https://actionmailbox:PASSWORD@example.com/rails/action_mailbox/postmark/inbound_emails
44
+ #
45
+ # *NOTE:* When configuring your Postmark inbound webhook, be sure to check the box labeled *"Include raw email
46
+ # content in JSON payload"*. Action Mailbox needs the raw email content to work.
47
+ class Ingresses::Postmark::InboundEmailsController < ActionMailbox::BaseController
48
+ before_action :authenticate_by_password
49
+
50
+ def create
51
+ ActionMailbox::InboundEmail.create_and_extract_message_id! params.require("RawEmail")
52
+ rescue ActionController::ParameterMissing => error
53
+ logger.error <<~MESSAGE
54
+ #{error.message}
55
+
56
+ When configuring your Postmark inbound webhook, be sure to check the box
57
+ labeled "Include raw email content in JSON payload".
58
+ MESSAGE
59
+ head :unprocessable_entity
60
+ end
61
+ end
62
+ end
@@ -0,0 +1,65 @@
1
+ # frozen_string_literal: true
2
+
3
+ module ActionMailbox
4
+ # Ingests inbound emails relayed from an SMTP server.
5
+ #
6
+ # Authenticates requests using HTTP basic access authentication. The username is always +actionmailbox+, and the
7
+ # password is read from the application's encrypted credentials or an environment variable. See the Usage section below.
8
+ #
9
+ # Note that basic authentication is insecure over unencrypted HTTP. An attacker that intercepts cleartext requests to
10
+ # the ingress can learn its password. You should only use this ingress over HTTPS.
11
+ #
12
+ # Returns:
13
+ #
14
+ # - <tt>204 No Content</tt> if an inbound email is successfully recorded and enqueued for routing to the appropriate mailbox
15
+ # - <tt>401 Unauthorized</tt> if the request could not be authenticated
16
+ # - <tt>404 Not Found</tt> if Action Mailbox is not configured to accept inbound emails relayed from an SMTP server
17
+ # - <tt>415 Unsupported Media Type</tt> if the request does not contain an RFC 822 message
18
+ # - <tt>500 Server Error</tt> if the ingress password is not configured, or if one of the Active Record database,
19
+ # the Active Storage service, or the Active Job backend is misconfigured or unavailable
20
+ #
21
+ # == Usage
22
+ #
23
+ # 1. Tell Action Mailbox to accept emails from an SMTP relay:
24
+ #
25
+ # # config/environments/production.rb
26
+ # config.action_mailbox.ingress = :relay
27
+ #
28
+ # 2. Generate a strong password that Action Mailbox can use to authenticate requests to the ingress.
29
+ #
30
+ # Use <tt>rails credentials:edit</tt> to add the password to your application's encrypted credentials under
31
+ # +action_mailbox.ingress_password+, where Action Mailbox will automatically find it:
32
+ #
33
+ # action_mailbox:
34
+ # ingress_password: ...
35
+ #
36
+ # Alternatively, provide the password in the +RAILS_INBOUND_EMAIL_PASSWORD+ environment variable.
37
+ #
38
+ # 3. Configure your SMTP server to pipe inbound emails to the appropriate ingress command, providing the +URL+ of the
39
+ # relay ingress and the +INGRESS_PASSWORD+ you previously generated.
40
+ #
41
+ # If your application lives at <tt>https://example.com</tt>, you would configure the Postfix SMTP server to pipe
42
+ # inbound emails to the following command:
43
+ #
44
+ # bin/rails action_mailbox:ingress:postfix URL=https://example.com/rails/action_mailbox/postfix/inbound_emails INGRESS_PASSWORD=...
45
+ #
46
+ # Built-in ingress commands are available for these popular SMTP servers:
47
+ #
48
+ # - Exim (<tt>bin/rails action_mailbox:ingress:exim)
49
+ # - Postfix (<tt>bin/rails action_mailbox:ingress:postfix)
50
+ # - Qmail (<tt>bin/rails action_mailbox:ingress:qmail)
51
+ class Ingresses::Relay::InboundEmailsController < ActionMailbox::BaseController
52
+ before_action :authenticate_by_password, :require_valid_rfc822_message
53
+
54
+ def create
55
+ ActionMailbox::InboundEmail.create_and_extract_message_id! request.body.read
56
+ end
57
+
58
+ private
59
+ def require_valid_rfc822_message
60
+ unless request.content_type == "message/rfc822"
61
+ head :unsupported_media_type
62
+ end
63
+ end
64
+ end
65
+ end