kanbanworkflowstimelinescrumrubyroadmapproject-planningproject-managementopenprojectangularissue-trackerifcgantt-chartganttbug-trackerboardsbcf
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.
210 lines
6.6 KiB
210 lines
6.6 KiB
#-- encoding: UTF-8
|
|
|
|
#-- copyright
|
|
# OpenProject is an open source project management software.
|
|
# Copyright (C) 2012-2021 the OpenProject GmbH
|
|
#
|
|
# This program is free software; you can redistribute it and/or
|
|
# modify it under the terms of the GNU General Public License version 3.
|
|
#
|
|
# OpenProject is a fork of ChiliProject, which is a fork of Redmine. The copyright follows:
|
|
# Copyright (C) 2006-2013 Jean-Philippe Lang
|
|
# Copyright (C) 2010-2013 the ChiliProject Team
|
|
#
|
|
# This program is free software; you can redistribute it and/or
|
|
# modify it under the terms of the GNU General Public License
|
|
# as published by the Free Software Foundation; either version 2
|
|
# of the License, or (at your option) any later version.
|
|
#
|
|
# This program is distributed in the hope that it will be useful,
|
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
# GNU General Public License for more details.
|
|
#
|
|
# You should have received a copy of the GNU General Public License
|
|
# along with this program; if not, write to the Free Software
|
|
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
|
#
|
|
# See COPYRIGHT and LICENSE files for more details.
|
|
#++
|
|
|
|
class ApplicationMailer < ActionMailer::Base
|
|
layout 'mailer'
|
|
|
|
helper :application, # for format_text
|
|
:work_packages, # for css classes
|
|
:custom_fields # for show_value
|
|
|
|
include OpenProject::LocaleHelper
|
|
|
|
# Send all delayed mails with the following job
|
|
self.delivery_job = ::Mails::MailerJob
|
|
|
|
# wrap in a lambda to allow changing at run-time
|
|
default from: Proc.new { Setting.mail_from }
|
|
|
|
class << self
|
|
# Activates/deactivates email deliveries during +block+
|
|
def with_deliveries(temporary_state = true, &_block)
|
|
old_state = ActionMailer::Base.perform_deliveries
|
|
ActionMailer::Base.perform_deliveries = temporary_state
|
|
yield
|
|
ensure
|
|
ActionMailer::Base.perform_deliveries = old_state
|
|
end
|
|
|
|
def host
|
|
if OpenProject::Configuration.rails_relative_url_root.blank?
|
|
Setting.host_name
|
|
else
|
|
Setting.host_name.to_s.gsub(%r{/.*\z}, '')
|
|
end
|
|
end
|
|
|
|
def protocol
|
|
Setting.protocol
|
|
end
|
|
|
|
def default_url_options
|
|
options = super.merge host: host, protocol: protocol
|
|
if OpenProject::Configuration.rails_relative_url_root.present?
|
|
options[:script_name] = OpenProject::Configuration.rails_relative_url_root
|
|
end
|
|
|
|
options
|
|
end
|
|
end
|
|
|
|
def mail(headers = {}, &block)
|
|
block ||= method(:default_formats_for_setting)
|
|
super(headers, &block)
|
|
end
|
|
|
|
# Sets a Message-ID header.
|
|
#
|
|
# While the value is set in here, email gateways such as postmark, unless instructed explicitly will assign
|
|
# their own message id overwriting the value calculated in here.
|
|
#
|
|
# Because of this, the message id and the value affected by it (In-Reply-To) is not relied upon when an email response
|
|
# is handled by OpenProject.
|
|
def message_id(object, user)
|
|
headers['Message-ID'] = "<#{message_id_value(object, user)}>"
|
|
end
|
|
|
|
# Sets a References header.
|
|
#
|
|
# The value is used within the MailHandler to find the appropriate objects for update
|
|
# when a mail has been received but should also allow mail clients to mails
|
|
# by the referenced entities. Because of this it might make sense to provide more than one object
|
|
# of reference. E.g. for a message, the message parent can also be provided.
|
|
def references(*objects)
|
|
refs = objects.map do |object|
|
|
if object.is_a?(Journal)
|
|
"<#{references_value(object.journable)}> <#{references_value(object)}>"
|
|
else
|
|
"<#{references_value(object)}>"
|
|
end
|
|
end
|
|
|
|
headers['References'] = refs.join(' ')
|
|
end
|
|
|
|
# Prepends given fields with 'X-OpenProject-' to save some duplication
|
|
def open_project_headers(hash)
|
|
hash.each { |key, value| headers["X-OpenProject-#{key}"] = value.to_s }
|
|
end
|
|
|
|
private
|
|
|
|
def default_formats_for_setting(format)
|
|
format.html unless Setting.plain_text_mail?
|
|
format.text
|
|
end
|
|
|
|
def send_mail(user, subject)
|
|
with_locale_for(user) do
|
|
mail to: user.mail, subject: subject
|
|
end
|
|
end
|
|
|
|
# Generates a unique value for the Message-ID header.
|
|
# Contains:
|
|
# * an 'op' prefix
|
|
# * an object id part that consists of the object's class name and the id unless that part is provided as a string
|
|
# * the current time
|
|
# * the recipient's id
|
|
#
|
|
# Note that this values, as opposed to the one from #references_value is unique.
|
|
def message_id_value(object, recipient)
|
|
object_reference = case object
|
|
when String
|
|
object
|
|
else
|
|
"#{object.class.name.demodulize.underscore}-#{object.id}"
|
|
end
|
|
hash = 'op'\
|
|
'.'\
|
|
"#{object_reference}"\
|
|
'.'\
|
|
"#{Time.current.strftime('%Y%m%d%H%M%S')}"\
|
|
'.'\
|
|
"#{recipient.id}"
|
|
|
|
"#{hash}@#{header_host_value}"
|
|
end
|
|
|
|
# Generates a value for the References header.
|
|
# Contains:
|
|
# * an 'op' prefix
|
|
# * an object id part that consists of the object's class name and the id
|
|
#
|
|
# Note that this values, as opposed to the one from #message_id_value is not unique.
|
|
# It in fact is aimed not not so that similar messages (i.e. those belonging to the same
|
|
# work package and journal) end up being grouped together.
|
|
def references_value(object)
|
|
hash = 'op'\
|
|
'.'\
|
|
"#{object.class.name.demodulize.underscore}-#{object.id}"
|
|
|
|
"#{hash}@#{header_host_value}"
|
|
end
|
|
|
|
def header_host_value
|
|
host = Setting.mail_from.to_s.gsub(%r{\A.*@}, '')
|
|
host = "#{::Socket.gethostname}.openproject" if host.empty?
|
|
host
|
|
end
|
|
end
|
|
|
|
##
|
|
# Interceptors
|
|
#
|
|
# These are registered in config/initializers/register_mail_interceptors.rb
|
|
#
|
|
# Unfortunately, this results in changes on the interceptor classes during development mode
|
|
# not being reflected until a server restart.
|
|
|
|
class DefaultHeadersInterceptor
|
|
def self.delivering_email(mail)
|
|
mail.headers(default_headers)
|
|
end
|
|
|
|
def self.default_headers
|
|
{
|
|
'X-Mailer' => 'OpenProject',
|
|
'X-OpenProject-Host' => Setting.host_name,
|
|
'X-OpenProject-Site' => Setting.app_title,
|
|
'Precedence' => 'bulk',
|
|
'Auto-Submitted' => 'auto-generated'
|
|
}
|
|
end
|
|
end
|
|
|
|
class DoNotSendMailsWithoutReceiverInterceptor
|
|
def self.delivering_email(mail)
|
|
receivers = [mail.to, mail.cc, mail.bcc]
|
|
# the above fields might be empty arrays (if entries have been removed
|
|
# by another interceptor) or nil, therefore checking for blank?
|
|
mail.perform_deliveries = false if receivers.all?(&:blank?)
|
|
end
|
|
end
|
|
|