# 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