You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
docuseal/app/jobs/cohort_admin_invitation_job.rb

60 lines
1.7 KiB

# frozen_string_literal: true
# CohortAdminInvitationJob
# Delivers invitation emails asynchronously
# Implements Winston's asynchronous security requirements
class CohortAdminInvitationJob
include Sidekiq::Job
sidekiq_options queue: :mailers, retry: 5
def perform(invitation_id)
invitation = CohortAdminInvitation.find_by(id: invitation_id)
# Check if invitation still valid
unless invitation && invitation.active? && !invitation.used?
Rails.logger.warn "Invitation #{invitation_id} no longer valid for email delivery"
return
end
# Send email
begin
CohortMailer.admin_invitation(invitation).deliver_now
# Update sent_at timestamp
invitation.update!(sent_at: Time.current)
# Log successful delivery
SecurityEvent.log(:email_sent, invitation.created_by, {
institution_id: invitation.institution_id,
email: invitation.email,
invitation_id: invitation.id
})
Rails.logger.info "Invitation email sent to #{invitation.email}"
rescue StandardError => e
# Log failure
SecurityEvent.log(:email_delivery_failure, invitation.created_by, {
institution_id: invitation.institution_id,
email: invitation.email,
invitation_id: invitation.id,
error: e.message
})
Rails.logger.error "Failed to send invitation email: #{e.message}"
raise # Re-raise to trigger retry
end
end
# Additional safety check
def self.perform_async_if_valid(invitation_id)
invitation = CohortAdminInvitation.find_by(id: invitation_id)
return false unless invitation
return false unless invitation.active?
return false if invitation.sent_at.present?
perform_async(invitation_id)
true
end
end