# frozen_string_literal: true
require 'aws/rails/action_mailbox/sns_notification'
module ActionMailbox
module Ingresses
module Ses
# Ingests inbound emails from Amazon SES/SNS and confirms subscriptions.
#
# Subscription requests must provide the following parameters in a JSON body:
# - +Message+: Notification content
# - +MessagId+: Notification unique identifier
# - +Timestamp+: iso8601 timestamp
# - +TopicArn+: Topic identifier
# - +Type+: Type of event ("Subscription")
#
# Inbound email events must provide the following parameters in a JSON body:
# - +Message+: Notification content
# - +MessagId+: Notification unique identifier
# - +Timestamp+: iso8601 timestamp
# - +SubscribeURL+: Topic identifier
# - +TopicArn+: Topic identifier
# - +Type+: Type of event ("SubscriptionConfirmation")
#
# All requests are authenticated by validating the provided AWS signature.
#
# Returns:
#
# - 204 No Content if a request is successfully processed
# - 401 Unauthorized if a request does not contain a valid signature
# - 404 Not Found if the Amazon ingress has not been configured
# - 422 Unprocessable Entity if a request provides invalid parameters
class InboundEmailsController < ActionMailbox::BaseController
before_action :verify_authenticity, :validate_topic, :confirm_subscription
def create
head :bad_request unless notification.message_content.present?
ActionMailbox::InboundEmail.create_and_extract_message_id!(notification.message_content)
head :no_content
end
private
def verify_authenticity
head :bad_request unless notification.present?
head :unauthorized unless notification.verified?
end
def confirm_subscription
return unless notification.type == 'SubscriptionConfirmation'
return head :ok if notification.subscription_confirmed?
Rails.logger.error('SNS subscription confirmation request rejected.')
head :unprocessable_entity
end
def validate_topic
return if valid_topic == notification.topic
Rails.logger.warn("Ignoring unknown topic: #{topic}")
head :unauthorized
end
def notification
@notification ||= Aws::Rails::ActionMailbox::SnsNotification.new(request.raw_post)
end
def topic
@topic ||= notification.topic
end
def valid_topic
::Rails.configuration.action_mailbox.ses.subscribed_topic
end
end
end
end
end