diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 6a78088f..7aa350ce 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -47,15 +47,17 @@ jobs: - uses: actions/checkout@v4 with: fetch-depth: 0 + - uses: docker/setup-qemu-action@v3 + - uses: docker/setup-buildx-action@v2 - uses: docker/login-action@v2 with: registry: ghcr.io username: ${{ github.actor }} password: ${{ secrets.GITHUB_TOKEN }} - - run: docker-compose pull + - run: docker compose pull env: POSTAL_IMAGE: ghcr.io/buttondown/postal:ci-${{ github.sha }} - - run: docker-compose run postal sh -c 'bundle exec rspec' + - run: docker compose run postal sh -c 'bundle exec rspec' env: POSTAL_IMAGE: ghcr.io/buttondown/postal:ci-${{ github.sha }} diff --git a/config/examples/test.yml b/config/examples/test.yml index e47f3abe..0d0e6e5a 100644 --- a/config/examples/test.yml +++ b/config/examples/test.yml @@ -1,4 +1,4 @@ -# This is an example Postal configuration file for use in +# This is an example Postal configuration file for use in # test environments. For a production example, see # the https://github.com/postalserver/install repository. @@ -7,14 +7,14 @@ version: 2 main_db: host: 127.0.0.1 username: root - password: + password: database: postal-test message_db: host: 127.0.0.1 username: root - password: - prefix: postal-test + password: + prefix: postal logging: enabled: false diff --git a/lib/postal/message_db/message.rb b/lib/postal/message_db/message.rb index 4f29a6f1..10f16767 100644 --- a/lib/postal/message_db/message.rb +++ b/lib/postal/message_db/message.rb @@ -310,7 +310,7 @@ def html_body end # - # Return the HTML body with any tracking links + # Return the HTML body with the tracking image removed. # def html_body_without_tracking_image html_body.gsub(/<p class=['"]ampimg['"].*?<\/p>/, "") @@ -573,8 +573,15 @@ def parsed? # Should this message be parsed? # def should_parse? - # Header values are always arrays, so we check for `['skip']` instead of `'skip'` - parsed? == false && headers["x-amp"] != ["skip"] + parsed? == false + end + + def track_clicks? + headers["x-track-clicks"] != ["no"] + end + + def track_loads? + headers["x-track-opens"] != ["no"] end private diff --git a/lib/postal/message_parser.rb b/lib/postal/message_parser.rb index b4f24ba8..996cce46 100644 --- a/lib/postal/message_parser.rb +++ b/lib/postal/message_parser.rb @@ -85,11 +85,11 @@ def parse_parts(parts) end def parse(part, type = nil) - if @domain.track_clicks? + if @domain.track_clicks? && @message.track_clicks? part = insert_links(part, type) end - if @domain.track_loads? && type == :html + if @domain.track_loads? && @message.track_loads? && type == :html part = insert_tracking_image(part) end diff --git a/spec/helpers/general_helpers.rb b/spec/helpers/general_helpers.rb index 0b982f5f..249dce44 100644 --- a/spec/helpers/general_helpers.rb +++ b/spec/helpers/general_helpers.rb @@ -12,4 +12,13 @@ def create_plain_text_message(server, text, to = "test@example.com", override_at server.message_db.message(result[:id]) end + def create_html_message(server, html, to = "test@example.com", override_attributes = {}) + domain = create(:domain, owner: server) + attributes = { from: "test@#{domain.name}", subject: "Test HTML Message" }.merge(override_attributes) + attributes[:to] = to + attributes[:html_body] = html + message = OutgoingMessagePrototype.new(server, "127.0.0.1", "testsuite", attributes) + result = message.create_message(to) + server.message_db.message(result[:id]) + end end diff --git a/spec/lib/postal/message_parser_spec.rb b/spec/lib/postal/message_parser_spec.rb index 6eb645ab..3a03af1c 100644 --- a/spec/lib/postal/message_parser_spec.rb +++ b/spec/lib/postal/message_parser_spec.rb @@ -22,4 +22,31 @@ expect(parser.new_body).to match(/^Hello world! https:\/\/click\.#{message.domain.name}/) expect(parser.tracked_links).to eq 1 end + + it "should not replace links in messages if the header is set to no" do + message = create_plain_text_message(server, "Hello world! http://github.com/atech/postal", "test@example.com", { custom_headers: { "x-track-clicks" => "no" } }) + create(:track_domain, server: server, domain: message.domain) + parser = Postal::MessageParser.new(message) + expect(parser.actioned?).to be false + expect(parser.new_body).to include("Hello world! http://github.com/atech/postal") + expect(parser.tracked_links).to eq 0 + end + + it "should insert tracking pixels in messages" do + message = create_html_message(server, "<p>Hello world! <a href='http://github.com/atech/postal'>Github</a></p>", "test@example.com") + create(:track_domain, server: server, domain: message.domain) + parser = Postal::MessageParser.new(message) + expect(parser.actioned?).to be true + expect(parser.new_body).to match(/<p class='ampimg' style='display:none;visibility:none;margin:0;padding:0;line-height:0;'><img src='https:\/\/click\.#{message.domain.name}/) + expect(parser.tracked_images).to eq 1 + end + + it "should not insert tracking pixels in messages if the header is set to no" do + message = create_html_message(server, "<p>Hello world! <a href='http://github.com/atech/postal'>Github</a></p>", "test@example.com", { custom_headers: { "x-track-opens" => "no" } }) + create(:track_domain, server: server, domain: message.domain) + parser = Postal::MessageParser.new(message) + expect(parser.actioned?).to be true + expect(parser.new_body).to_not include("<p class='ampimg' style='display:none;visibility:none;margin:0;padding:0;line-height:0;'><img src='https:\/\/click\.#{message.domain.name}") + expect(parser.tracked_images).to eq 0 + end end