diff --git a/doc/administration/incoming_email.md b/doc/administration/incoming_email.md index 674be5d7e114f0cdd3bc1c32453d760f443c5b49..d23f96681938fd6b1bc6a0c84b9ac6dee7153671 100644 --- a/doc/administration/incoming_email.md +++ b/doc/administration/incoming_email.md @@ -74,6 +74,7 @@ this method only supports replies, and not the other features of [incoming email > - Accepting `Cc` headers [introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/348572) in GitLab 16.5. > - Accepting `X-Original-To` headers [introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/149874) in GitLab 17.0. +> - Accepting `X-Forwarded-To` headers [introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/168716) in GitLab 17.6. Email is processed correctly when a configured email address is present in one of the following headers (sorted in the order they are checked): @@ -83,6 +84,7 @@ Email is processed correctly when a configured email address is present in one o - `Envelope-To` or `X-Envelope-To` - `Received` - `X-Original-To` +- `X-Forwarded-To` - `Cc` The `References` header is also accepted, however it is used specifically to relate email responses to existing discussion threads. It is not used for creating issues by email. diff --git a/lib/gitlab/email/receiver.rb b/lib/gitlab/email/receiver.rb index ccaf45ed6ff167e8d023501bd9b2f07cc0a11cb1..af6d8e85b980983af2aee2304b8b07109c0cf7f6 100644 --- a/lib/gitlab/email/receiver.rb +++ b/lib/gitlab/email/receiver.rb @@ -49,6 +49,7 @@ def mail_metadata envelope_to: envelope_to.map(&:value), x_envelope_to: x_envelope_to.map(&:value), x_original_to: x_original_to.map(&:value), + x_forwarded_to: x_forwarded_to.map(&:value), cc_address: cc, # reduced down to what looks like an email in the received headers received_recipients: recipients_from_received_headers, @@ -112,6 +113,7 @@ def key_from_additional_headers find_first_key_from(x_envelope_to) || find_first_key_from(recipients_from_received_headers) || find_first_key_from(x_original_to) || + find_first_key_from(x_forwarded_to) || find_first_key_from(cc) end @@ -167,6 +169,10 @@ def x_original_to Array(mail[:x_original_to]) end + def x_forwarded_to + Array(mail[:x_forwarded_to]) + end + def recipients_from_received_headers received.filter_map { |header| header.value[RECEIVED_HEADER_REGEX, 1] } end diff --git a/spec/lib/gitlab/email/receiver_spec.rb b/spec/lib/gitlab/email/receiver_spec.rb index b8da127afb4ed34cd32a22c460a1a6144e3fcf68..8a09258a60c88416c09ca6de4825a847b44c1d9e 100644 --- a/spec/lib/gitlab/email/receiver_spec.rb +++ b/spec/lib/gitlab/email/receiver_spec.rb @@ -34,7 +34,7 @@ metadata = receiver.mail_metadata - expect(metadata.keys).to match_array(%i[mail_uid from_address to_address mail_key references delivered_to envelope_to x_envelope_to meta received_recipients cc_address x_original_to]) + expect(metadata.keys).to match_array(%i[mail_uid from_address to_address mail_key references delivered_to envelope_to x_envelope_to meta received_recipients cc_address x_original_to x_forwarded_to]) expect(metadata[:meta]).to include(client_id: client_id, project: project.full_path) expect(metadata[meta_key]).to eq(meta_value) end @@ -151,6 +151,23 @@ it_behaves_like 'successful receive' end + context 'when in a X-Forwarded-To header' do + let(:email_raw) do + <<~EMAIL + From: jake@example.com + To: to@example.com + X-Forwarded-To: #{incoming_email} + Subject: Issue titile + + Issue description + EMAIL + end + + let(:meta_key) { :x_forwarded_to } + + it_behaves_like 'successful receive' + end + context 'for Service Desk custom email' do let_it_be_with_refind(:setting) { create(:service_desk_setting, project: project, add_external_participants_from_cc: true) } diff --git a/spec/lib/gitlab/email/service_desk_receiver_spec.rb b/spec/lib/gitlab/email/service_desk_receiver_spec.rb index 18243ef2a0e5155d87456847aa0f67f37b060fe9..3844231d79e89563ac7f91488905eff2039923c2 100644 --- a/spec/lib/gitlab/email/service_desk_receiver_spec.rb +++ b/spec/lib/gitlab/email/service_desk_receiver_spec.rb @@ -66,6 +66,21 @@ it_behaves_like 'received successfully' end + context 'when in a X-Forwarded-To header' do + let(:email) do + <<~EMAIL + From: from@example.com + To: to@example.com + X-Forwarded-To: #{service_desk_email} + Subject: Issue titile + + Issue description + EMAIL + end + + it_behaves_like 'received successfully' + end + context 'when in a Cc header' do let(:email) do <<~EMAIL