diff --git a/.dockerignore b/.dockerignore index 22fe334..2f3a0c4 100644 --- a/.dockerignore +++ b/.dockerignore @@ -3,10 +3,7 @@ config/postal.yml config/smtp.cert config/smtp.key -config/lets_encrypt.pem config/signing.key -config/fast_server.cert -config/fast_server.key public/assets vendor/bundle Procfile.local diff --git a/.gitignore b/.gitignore index 7ac6cff..c4484f5 100644 --- a/.gitignore +++ b/.gitignore @@ -19,10 +19,7 @@ config/postal.yml config/smtp.cert config/smtp.key -config/lets_encrypt.pem config/signing.key -config/fast_server.cert -config/fast_server.key config/postal/**/* spec/config/postal.local.yml diff --git a/Gemfile b/Gemfile index 36242cb..66fc285 100644 --- a/Gemfile +++ b/Gemfile @@ -27,7 +27,6 @@ gem 'sentry-raven' gem 'gelf' gem 'moonrope' gem 'jwt' -gem 'acme-client' gem 'highline', :require => false gem 'resolv', '~> 0.2.1' diff --git a/Gemfile.lock b/Gemfile.lock index 69765ab..ebb12f9 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -9,8 +9,6 @@ GIT GEM remote: https://rubygems.org/ specs: - acme-client (2.0.0) - faraday (~> 0.9, >= 0.9.1) actioncable (5.2.6) actionpack (= 5.2.6) nio4r (~> 2.0) @@ -249,7 +247,6 @@ PLATFORMS ruby DEPENDENCIES - acme-client annotate authie (~> 3.0) autoprefixer-rails diff --git a/Procfile b/Procfile index 7d9514d..9f0e14a 100644 --- a/Procfile +++ b/Procfile @@ -1,5 +1,4 @@ web: bundle exec puma -C config/puma.rb -fast: bundle exec rake postal:fast_server worker: bundle exec ruby script/worker.rb cron: bundle exec rake postal:cron smtp: bundle exec rake postal:smtp_server diff --git a/app/jobs/renew_track_certificates_job.rb b/app/jobs/renew_track_certificates_job.rb deleted file mode 100644 index 67b071d..0000000 --- a/app/jobs/renew_track_certificates_job.rb +++ /dev/null @@ -1,15 +0,0 @@ -class RenewTrackCertificatesJob < Postal::Job - - def perform - TrackCertificate.where("renew_after IS NULL OR renew_after <= ?", Time.now).each do |certificate| - log "Renewing certificate for track domain ##{certificate.id} (#{certificate.domain})" - if certificate.get - log "Successfully renewed" - else - certificate.update(:renew_after => 1.day.from_now) - log "Could not be renewed" - end - end - end - -end diff --git a/app/models/track_certificate.rb b/app/models/track_certificate.rb deleted file mode 100644 index d9fa259..0000000 --- a/app/models/track_certificate.rb +++ /dev/null @@ -1,108 +0,0 @@ -# == Schema Information -# -# Table name: track_certificates -# -# id :integer not null, primary key -# domain :string(255) -# certificate :text(65535) -# intermediaries :text(65535) -# key :text(65535) -# expires_at :datetime -# renew_after :datetime -# verification_path :string(255) -# verification_string :string(255) -# created_at :datetime not null -# updated_at :datetime not null -# -# Indexes -# -# index_track_certificates_on_domain (domain) -# - -class TrackCertificate < ApplicationRecord - - validates :domain, :presence => true, :uniqueness => true - - default_value :key, -> { OpenSSL::PKey::RSA.new(2048).to_s } - - scope :active, -> { where("certificate IS NOT NULL AND expires_at > ?", Time.now) } - - def active? - certificate.present? - end - - def get - order = Postal::LetsEncrypt.client.new_order(identifiers: [self.domain]) - authorization = order.authorizations.first - challenge = authorization.http - self.verification_path = challenge.filename - self.verification_string = challenge.file_content - self.save! - logger.info "Attempting verification of #{self.domain}" - challenge.request_validation - checks = 0 - until challenge.status != "pending" - checks += 1 - if checks > 30 - logger.info "Status remained at pending for 30 checks" - return false - end - sleep 1 - challenge.reload - end - - unless challenge.status == "valid" - logger.info "Status was not valid (was: #{challenge.status})" - return false - end - - csr = OpenSSL::X509::Request.new - csr.subject = OpenSSL::X509::Name.new([['CN', self.domain, OpenSSL::ASN1::UTF8STRING]]) - private_key = OpenSSL::PKey::RSA.new(self.key) - csr.public_key = private_key.public_key - csr.sign(private_key, OpenSSL::Digest::SHA256.new) - logger.info "Getting certificate for #{self.domain}" - order.finalize(:csr => csr) - - sleep(1) while order.status == 'processing' - https_cert = order.certificate # => PEM-formatted certificate - cert, chain = https_cert.split(/\r?\n\r?\n/, 2) - - self.certificate = cert - self.intermediaries = chain - self.expires_at = certificate_object.not_after - self.renew_after = (self.expires_at - 1.month) + rand(10).days - self.save! - logger.info "Certificate issued (expires on #{self.expires_at}, will renew after #{self.renew_after})" - return true - - rescue Acme::Client::Error => e - @retries = 0 - if e.is_a?(Acme::Client::Error::BadNonce) && @retries < 5 - @retries += 1 - logger.info "Bad nounce encountered. Retrying (#{@retries} of 5 attempts)" - sleep 1 - verify - else - logger.info "Error: #{e.class} (#{e.message})" - return false - end - end - - def certificate_object - OpenSSL::X509::Certificate.new(self.certificate) - end - - def intermediaries_array - self.intermediaries.to_s.scan(/-----BEGIN CERTIFICATE-----.+?-----END CERTIFICATE-----/m).map{|c| OpenSSL::X509::Certificate.new(c)} - end - - def key_object - OpenSSL::PKey::RSA.new(self.key) - end - - def logger - Postal::LetsEncrypt.logger - end - -end diff --git a/app/models/track_domain.rb b/app/models/track_domain.rb index 793b11a..0ab8328 100644 --- a/app/models/track_domain.rb +++ b/app/models/track_domain.rb @@ -34,8 +34,6 @@ class TrackDomain < ApplicationRecord scope :ok, -> { where(:dns_status => 'OK')} after_create :check_dns, :unless => :dns_status - after_create :create_ssl_certificate_if_missing - after_destroy :delete_ssl_certificate_when_not_in_use before_validation do self.server = self.domain.server if self.domain && self.server.nil? @@ -73,16 +71,8 @@ class TrackDomain < ApplicationRecord dns_ok? end - def has_ssl? - ssl_certificate && ssl_certificate.active? - end - def use_ssl? - ssl_enabled? && has_ssl? - end - - def ssl_certificate - @ssl_certificate ||= TrackCertificate.where(:domain => self.full_name).first + ssl_enabled? end def validate_domain_belongs_to_server @@ -91,17 +81,4 @@ class TrackDomain < ApplicationRecord end end - def create_ssl_certificate_if_missing - unless TrackCertificate.where(:domain => self.full_name).exists? - TrackCertificate.create!(:domain => self.full_name) - end - end - - def delete_ssl_certificate_when_not_in_use - others = TrackDomain.includes(:domain).where(:name => self.name, :domains => {:name => self.domain.name}) - if others.empty? - TrackCertificate.where(:domain => self.full_name).destroy_all - end - end - end diff --git a/app/views/domains/_nav.html.haml b/app/views/domains/_nav.html.haml index 1fb3076..0323a53 100644 --- a/app/views/domains/_nav.html.haml +++ b/app/views/domains/_nav.html.haml @@ -1,5 +1,4 @@ .navBar.navBar--secondary %ul %li.navBar__item= link_to "Domains", organization_server_domains_path(organization, @server), :class => ['navBar__link', active_nav == :domains ? 'is-active' : ''] - - if Postal.tracking_available? - %li.navBar__item= link_to "Tracking Domains", organization_server_track_domains_path(organization, @server), :class => ['navBar__link', active_nav == :track_domains ? 'is-active' : ''] + %li.navBar__item= link_to "Tracking Domains", organization_server_track_domains_path(organization, @server), :class => ['navBar__link', active_nav == :track_domains ? 'is-active' : ''] diff --git a/app/views/track_domains/index.html.haml b/app/views/track_domains/index.html.haml index 81d0f3c..c138b25 100644 --- a/app/views/track_domains/index.html.haml +++ b/app/views/track_domains/index.html.haml @@ -31,10 +31,7 @@ %li.domainList__check.domainList__check--warning{:title => track_domain.dns_error} CNAME not configured correctly - if track_domain.ssl_enabled? - - if track_domain.has_ssl? - %li.domainList__check.domainList__check--ok= link_to "SSL enabled", [:toggle_ssl, organization, @server, track_domain], :remote => true, :method => :post - - else - %li.domainList__check.domainList__check--neutral= link_to "SSL setup in progress", [:toggle_ssl, organization, @server, track_domain], :remote => true, :method => :post + %li.domainList__check.domainList__check--neutral= link_to "SSL enabled", [:toggle_ssl, organization, @server, track_domain], :remote => true, :method => :post - else %li.domainList__check.domainList__check--neutral-cross= link_to "SSL disabled", [:toggle_ssl, organization, @server, track_domain], :remote => true, :method => :post diff --git a/bin/postal b/bin/postal index e87e6ec..ae9e124 100755 --- a/bin/postal +++ b/bin/postal @@ -84,10 +84,6 @@ case "$1" in run "bundle exec ruby script/default_dkim_record.rb" ;; - register-lets-encrypt) - run "bundle exec ruby script/register_lets_encrypt.rb $2" - ;; - auto-upgrade) run "ruby script/auto_upgrade.rb $@" ;; diff --git a/config/application.rb b/config/application.rb index dc53555..db3b574 100644 --- a/config/application.rb +++ b/config/application.rb @@ -28,5 +28,9 @@ module Postal # Disable field_with_errors config.action_view.field_error_proc = Proc.new { |t, i| t } + + # Load the tracking server middleware + require 'postal/tracking_middleware' + config.middleware.use Postal::TrackingMiddleware end end diff --git a/config/cron.rb b/config/cron.rb index f0d4884..c89c62b 100644 --- a/config/cron.rb +++ b/config/cron.rb @@ -10,10 +10,6 @@ module Clockwork SendNotificationsJob.queue(:main) end - every 15.minutes, 'every-15-minutes', :at => ['**:00', '**:15', '**:30', '**:45'] do - RenewTrackCertificatesJob.queue(:main) - end - every 1.hour, 'every-hour', :at => ['**:15'] do CheckAllDNSJob.queue(:main) ExpireHeldMessagesJob.queue(:main) diff --git a/config/postal.defaults.yml b/config/postal.defaults.yml index 2e01be3..ee9d313 100644 --- a/config/postal.defaults.yml +++ b/config/postal.defaults.yml @@ -21,20 +21,6 @@ web_server: port: 5000 max_threads: 5 -fast_server: - enabled: false - bind_address: - # Set appropriate IP addresses to listen on. These should be dedicated IP - # addresses just used for this server. You should list IPv4 and IPv6 addresses - # as appropriate. - # - 1.2.3.4 - # - abcd:a:b:c:d::1 - port: 80 - ssl_port: 443 - proxy_protocol: false - default_private_key_path: # Defaults to config/fast_server.key - default_tls_certificate_path: # Defaults to config/fast_server.cert - main_db: host: 127.0.0.1 port: 3306 diff --git a/config/puma.fast.rb b/config/puma.fast.rb deleted file mode 100644 index 4eb3fdf..0000000 --- a/config/puma.fast.rb +++ /dev/null @@ -1,17 +0,0 @@ -require_relative '../lib/postal/config' -threads_count = Postal.config.fast_server&.max_threads&.to_i || 5 -threads threads_count, threads_count -bind_address = Postal.config.fast_server&.bind_address || '127.0.0.1' -bind_port = Postal.config.fast_server&.port&.to_i || 5010 -bind "tcp://#{bind_address}:#{bind_port}" -environment Postal.config.rails&.environment || 'development' -prune_bundler -quiet false -rackup File.expand_path('../../lib/postal/fast_server/config.ru', __FILE__) -unless ENV['LOG_TO_STDOUT'] - stdout_redirect Postal.app_root.join('log', 'puma.fast.log'), Postal.app_root.join('log', 'puma.fast.log'), true -end - -if ENV['APP_ROOT'] - directory ENV['APP_ROOT'] -end diff --git a/docker/ci-config/fast_server.cert b/docker/ci-config/fast_server.cert deleted file mode 100644 index 3e6064c..0000000 --- a/docker/ci-config/fast_server.cert +++ /dev/null @@ -1,19 +0,0 @@ ------BEGIN CERTIFICATE----- -MIIDBTCCAe2gAwIBAgIUexj/Ul7/jvs4L6q6H3MSYsW4FbkwDQYJKoZIhvcNAQEL -BQAwEjEQMA4GA1UEAwwHZGVmYXVsdDAeFw0yMTA3MjYxNjQwNTRaFw0zMTA3MjQx -NjQwNTRaMBIxEDAOBgNVBAMMB2RlZmF1bHQwggEiMA0GCSqGSIb3DQEBAQUAA4IB -DwAwggEKAoIBAQDRNaLmKp75o6I37JCpO2e8IIWBqLTpYGomvAWgKdB8v0AyWMcy -kE5IWZcFICBTJBpRTTHdCfrDnnqvS0AhMqpB3xPw0/DOCDhAxri6Cg4yxecXkFZP -Ckx1ga1sUb9ej8fYBWx9/g6j7waRSGtRB0zwS94tJdJa9XAVj3e97f3CEAr9wPQG -oCC/HQfSgZTho3RPik0x3Wi3Kf9JMHRbBZFDW/a/Z0KjmtFFebJNXBOH7r0Itq82 -DY14UqHtG6omZUrGu/Dsx8++USaV03rOq2fSKuol4lEqBWfqI2tzal5hE/46Glbn -ukM+/Iq4+t4ydNsYrhxetsNl3mTWiDkcmYV/AgMBAAGjUzBRMB0GA1UdDgQWBBS+ -6ok381yre3ATn7f5cx6VrBg9+jAfBgNVHSMEGDAWgBS+6ok381yre3ATn7f5cx6V -rBg9+jAPBgNVHRMBAf8EBTADAQH/MA0GCSqGSIb3DQEBCwUAA4IBAQAQPFR90MKT -LiwMCCRjpTfMtKYF9rkNTIptCSResfeiwQ3KboBeE/jZzVzk1Pmy5Cvsy/i8zCfz -DcQbxKG82rmUwoPcS/Q0TKjmNcmwiLVvAuR8M8JJnZQiXux+Hb7yKgF/35U6FBuE -jqkWNpuTh5dVEC71hfl6JDuAFrQo+KguppMrbGyT5/yzU99YJR0wI0jjQlBvM9BC -JMf/IA5Q0XZFPpqFSDIud3xqrzbhBgdkBO1MRs/6NAY+pGDxQ5hWlVcn+f/spQZc -03PD+xZjtauUBfsrwk5PpOyGKL4bxgbt2S1aoIgLOjRZwpWFKQwuEcJNi9mDTU6j -mEYzeueHq+7M ------END CERTIFICATE----- diff --git a/docker/ci-config/fast_server.key b/docker/ci-config/fast_server.key deleted file mode 100644 index 30796d1..0000000 --- a/docker/ci-config/fast_server.key +++ /dev/null @@ -1,28 +0,0 @@ ------BEGIN PRIVATE KEY----- -MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQDRNaLmKp75o6I3 -7JCpO2e8IIWBqLTpYGomvAWgKdB8v0AyWMcykE5IWZcFICBTJBpRTTHdCfrDnnqv -S0AhMqpB3xPw0/DOCDhAxri6Cg4yxecXkFZPCkx1ga1sUb9ej8fYBWx9/g6j7waR -SGtRB0zwS94tJdJa9XAVj3e97f3CEAr9wPQGoCC/HQfSgZTho3RPik0x3Wi3Kf9J -MHRbBZFDW/a/Z0KjmtFFebJNXBOH7r0Itq82DY14UqHtG6omZUrGu/Dsx8++USaV -03rOq2fSKuol4lEqBWfqI2tzal5hE/46GlbnukM+/Iq4+t4ydNsYrhxetsNl3mTW -iDkcmYV/AgMBAAECggEBALGFK7bWj5MQsIN3rsCK8dkGV4LP3sLw1uILRVLEaG6R -8i1Ge7CCFor5ylXFDui9h79ZG2iOIUSAY2X/GmmRDjtayRbfIEQTYXhFp1XlVmrq -1s594V6sRHipErkJHLNmmZLJ92dpfo7IMfBxXO6inTyBhAMXRsl73iHNXTPCkEJr -xbrnQPw5g1f7amGS09Iz4CEwVs7PABA7V1uhGRyCESp9nUrdQpHKPfjAIi+KMNZw -0Eb/Bj4NSHNokmbp2TUJ1lRAsFmunjHpgdZ18CR1G8naSjhtd11/HrQ5b0LWVdsE -0Igq1/i0Os75lFi2d8ZSPrxIp9FQd61wrujPXiOFqeECgYEA6z+VulbI1D/CTkft -nvc46xsop+j+N0BYLUzorstA2INCoORHM8rZseJ4QDJcou4gXg6NfdIkoncnTDaa -p0xZfNsP3o3lQHRiDDrzRfrTt8XogYA4MQQzHsEHarwHlRd4Ftsu43rCuLZX7g9r -BE0OsjsY3Wy9qW9UxKGA50XG0EkCgYEA46oJsayy+rIgm9EPn09j9ezGz9o5KOe6 -Pjo5CYLKVuVkkQugAozwvf/+SumxVdepA9aUQ635Euw/Dpm/2SPaiBN4H4tLhRNp -YchpiOwWg9ThC26w7jRk0rdBWUIzisZvIeBo1w5ye/HB3Ztl2MAz6Yv3SAOj0mNv -ogXzuQ3yN4cCgYAq8RlowUy5icXzOigC+4fVSsjaFarJ9SHjawWSWqHEo/k2m1Tv -/FhOo1NmDItiZmtcH/XuAL0VNwDiZZlHbqVrKCW2b1posJXxO5WKsaWSBztQ4FHh -iK24MG4lKpuLuJQAQBRIC/GdfBOC7iePym0jVaxNRvs8AYmMtxprnQ4UmQKBgQDQ -p8oktnR/QfyS8oPP7fJetbjtTUMwE1nlqHUYG3AZPjrymOX5EHWgndvRiueGFpcI -NoVCllN+nVmZpx5nA+5I4xcoSgFYIRdnkEfxPvfPsa7kTHoKh6iUW3KgPQWCPiYi -tUtBNzOEF2ooEkHA6z9o4Ggt73AY5hutMqlSxM5nRwKBgBP0OqiyHeLbORHwOZeE -459uSE7UmoJINKgRWqdGprmfQZZvzoI0jvAvRvGIt0DYyS5o25AEAO6Y84DkkXGf -8yNHXJf6F6VPt40S5XOyJ8wikmSlsfLtRWkMsdSXZtsF7zOtE6kTCewxEwrypuzs -jNrQgpSolNPcLy6+2hgbiyu5 ------END PRIVATE KEY----- diff --git a/docker/ci-config/lets_encrypt.pem b/docker/ci-config/lets_encrypt.pem deleted file mode 100644 index c872ac4..0000000 --- a/docker/ci-config/lets_encrypt.pem +++ /dev/null @@ -1,27 +0,0 @@ ------BEGIN RSA PRIVATE KEY----- -MIIEowIBAAKCAQEApj2HYkdZsxxHpaUZV3beSn7p1DeVueDcGTT17Gf/PpV+SHXI -lC1AplNcQPI5iPmg7Fyk2KedlaQQJe8BrCrtBm5X5xNbGDuN5s4N8fZ/AJZ+YZOi -fTEzixYUjuQtJ0KcdofOMBqr4F4DVIG6ZWGoEbEIdNzDCLUeFv5xBmKGRDKmtEDC -SnYcEEFR9ewEHU7KYZbiaGexX0mskKGHMQLiM+xFp6qxsx8isVn+SBo3h94TFdRH -wanFg7ZOUo7Vm1gQkclz7+KpKeWjAsBfuFisrl1cGpN0zODltGGiOQVOymccv93k -7Dw01OAmr5JCfm5Ch9V9pVGlkSykAG93UrfhVwIDAQABAoIBACe+7ECGGJ8nMsYa -3B06UVl0UImppIWliloIfIfCMZeP/HpslsE+tIdPxO3OPA1QybXZTJx0LswZRrcb -FsZIGRWBiki4Kv53Nq0pNNJWAfVtBdhkiOPvwIgPhmjHizgox+na/GQp7FAfiiJJ -Rfx5Rcq9De2K3qKVUxViTjmdksZ5Bw4RzLNAa4QEUw8oZ0QTELvBISo2m6IlLWQq -YRyA2X2bbOjIRbvGfouFLuzqqrtqy76jyamTlTGP3BV7PcJlS+HRhpgXRX1GDANz -MGijGkk+g8umTdj2CIuUbfC6DvYv1XiskPWsMw+1Vel/pKdSbT8trCluG5AGcPeB -08wViSkCgYEA099Nr/fXDqqjulG5uIO624kE5ED3AbsShsCJHQMDjX79xzljjXXm -C5nydj9xRiWB9xt8ptL4ZDOm/EyzFYJmkRWe0eMHU6vUZpbRBRMSHPQhVs4PMDtB -OJ2+sZL/vIaqF6W8VYzohEGVoN34sNDh7MRX283V2XSAgi7PEWdzVpUCgYEAyN0z -2wBftrd85harUfryZwPNh53HrA0Xku3AqKymb5ukS2uQFQ904cvxlIOxEZGVlW1r -HWwEgvd1QkiovT6FExSgQoMMShiRJDeJJVqaR0/UD7hHyvX5P8LKUosQaJUWrA09 -Y777tskJX34WWyzJgvHTnQ2TA4MQAaJEHb08+TsCgYEAzbx+PMymuWg72tY3SRQp -o7qW1Gq9MKIOqGlX+6MMlR7mocl5gUkmHMfd6LNMdHhBjsnTLk+YwfxiP4bfM5jP -rjzXXypc2AP4GbKDv7C4GwN5SEiJ+STg/XA4V0jOKqx9iL74df6BXsQs3uwM7O25 -JOe4BQoIicOWclOv4U+acU0CgYAr8ckghqpqDSa0KA1/OAnEY96ZZvmCOLMJoB5g -SLV5AXImVfgFw4XsyHOn7E/W6iTxtiiTHUi3ZnAu+jqAfKccj4yoQId1xn4qkEPe -+j16kIpyjfyW+M15F6KwAGCsoMF/Dr55jhT/3mfAjpNRizDjBwkm+QtK32enE9sX -LomidQKBgBxdncRWWwCKtD8MCW/fkK/jGFVhy4dxzgAJCGy1ThuAylkHRscTmszt -Pgp1Layd2fGWM+ohTrzPZAkoa7UqTvDxGe50ODdY4nw01/s4RGVBDbnLOBJ8yUMO -SwAgEqOjEWEyHl4tkcBWcNzu0QWPd7NPmXuh/7dAyIJ66fL3R6y1 ------END RSA PRIVATE KEY----- diff --git a/docker/ci-config/postal.yml b/docker/ci-config/postal.yml index fb03db4..982fcec 100644 --- a/docker/ci-config/postal.yml +++ b/docker/ci-config/postal.yml @@ -5,9 +5,6 @@ web_server: bind_address: 127.0.0.1 port: 5000 -fast_server: - enabled: true - smtp_server: port: 2525 diff --git a/lib/postal.rb b/lib/postal.rb index 06a04d8..c1da40c 100644 --- a/lib/postal.rb +++ b/lib/postal.rb @@ -9,7 +9,6 @@ module Postal autoload :Countries autoload :DKIMHeader autoload :Error - autoload :FastServer autoload :Helpers autoload :HTTP autoload :HTTPSender @@ -29,6 +28,7 @@ module Postal autoload :SMTPSender autoload :SMTPServer autoload :SpamCheck + autoload :TrackingMiddleware autoload :UserCreator autoload :Version autoload :Worker @@ -37,7 +37,6 @@ module Postal def self.eager_load! super Postal::MessageDB.eager_load! - Postal::FastServer.eager_load! Postal::SMTPServer.eager_load! end diff --git a/lib/postal/config.rb b/lib/postal/config.rb index 335374b..ee6d0d8 100644 --- a/lib/postal/config.rb +++ b/lib/postal/config.rb @@ -151,35 +151,6 @@ module Postal end end - def self.fast_server_default_private_key_path - config.fast_server.default_private_key_path || config_root.join('fast_server.key') - end - - def self.fast_server_default_private_key - @fast_server_default_private_key ||= OpenSSL::PKey::RSA.new(File.read(fast_server_default_private_key_path)) - end - - def self.fast_server_default_certificate_path - config.fast_server.default_tls_certificate_path || config_root.join('fast_server.cert') - end - - def self.fast_server_default_certificate_data - @fast_server_default_certificate_data ||= File.read(fast_server_default_certificate_path) - end - - def self.fast_server_default_certificates - @fast_server_default_certificates ||= begin - certs = self.fast_server_default_certificate_data.scan(/-----BEGIN CERTIFICATE-----.+?-----END CERTIFICATE-----/m) - certs.map do |c| - OpenSSL::X509::Certificate.new(c) - end.freeze - end - end - - def self.lets_encrypt_private_key_path - @lets_encrypt_private_key_path ||= Postal.config_root.join('lets_encrypt.pem') - end - def self.signing_key_path config_root.join('signing.key') end @@ -203,19 +174,11 @@ module Postal raise ConfigError, "No config found at #{self.config_file_path}" end - unless File.exists?(self.lets_encrypt_private_key_path) - raise ConfigError, "No Let's Encrypt private key found at #{self.lets_encrypt_private_key_path}" - end - unless File.exists?(self.signing_key_path) raise ConfigError, "No signing key found at #{self.signing_key_path}" end end - def self.tracking_available? - self.config.fast_server.enabled? - end - def self.ip_pools? self.config.general.use_ip_pools? end diff --git a/lib/postal/fast_server.rb b/lib/postal/fast_server.rb deleted file mode 100644 index e4c63bc..0000000 --- a/lib/postal/fast_server.rb +++ /dev/null @@ -1,12 +0,0 @@ -module Postal - module FastServer - extend ActiveSupport::Autoload - eager_autoload do - autoload :Client - autoload :HTTPHeader - autoload :HTTPHeaderSet - autoload :Interface - autoload :Server - end - end -end diff --git a/lib/postal/fast_server/client.rb b/lib/postal/fast_server/client.rb deleted file mode 100644 index 25d6f12..0000000 --- a/lib/postal/fast_server/client.rb +++ /dev/null @@ -1,172 +0,0 @@ -require 'stringio' - -module Postal - module FastServer - class Client - class ClientWentAway < StandardError; end - class BadRequest < StandardError; end - - def initialize(socket, options) - @raw_socket = socket - @options = options - end - - def run - Timeout.timeout(15) do - if Postal.config.fast_server.proxy_protocol - - # gets without readahead - line = "" - char = nil - while(char != "\n") - char = @raw_socket.read(1) - line << char - end - line.chomp! - - if m = line.match(/\APROXY (.+) (.+) (.+) (.+) (.+)\z/) - @remote_ip = m[2] - else - return false - end - end - - if self.ssl? - @socket = OpenSSL::SSL::SSLSocket.new(@raw_socket, self.class.ssl_context) - @socket.accept - else - @socket = @raw_socket - end - - Timeout::timeout(20) do - # Read the request line - request = @socket.gets.to_s.chomp - # Split the request into its 3 parts - method, path, protocol = request.split(' ', 3) - - raise BadRequest unless method && path && protocol - - # Create an empty header set - header_set = HTTPHeaderSet.new - # Read each header and populate the header set - loop do - header = @socket.gets - if header.nil? - raise ClientWentAway - elsif header.chomp == "" - break - else - header_set << HTTPHeader.from_string(header.chomp) - end - end - - # At this point, one might want to read the request body, but I don't think we need it. - - # Build rack request - server_name, server_port = header_set['Host'].try(:value).to_s.split(":", 2) - request = { - "REQUEST_METHOD" => method, - "SCRIPT_NAME" => "", - "PATH_INFO" => path.split('?', 2)[0], - "QUERY_STRING" => path.split('?', 2)[1], - "SERVER_NAME" => server_name || "", - "SERVER_PORT" => server_name || "", - "rack.version" => [1, 3], - "rack.url_scheme" => ssl? ? "https" : "http", - "rack.input" => StringIO.new(""), - "rack.errors" => STDERR, - "rack.multithread" => true, - "rack.multiprocess" => true, - "rack.run_once" => false, - "rack.hijack" => false, - "rack.hijack_io" => false, - "REMOTE_ADDR" => remote_ip, - } - - # Add request headers to rack hash - header_set.headers.each do |header| - request["HTTP_" + header.key.gsub('-', '_').upcase] = header.value - end - - # Call the rack app and process the result - code, headers, body = Interface.new.call(request) - response = "HTTP/1.1 #{code} #{Rack::Utils::HTTP_STATUS_CODES[code]}\r\n" - headers.each do |k,v| - response << "#{k}:#{v}\r\n" - end - response << "\r\n" - body.each do |data| - response << data - end - @socket.write(response) - end - end - rescue ClientWentAway, Timeout::Error, Errno::ECONNRESET - # We don't really care if a client has disapeared, close the sockets and carry on. - rescue OpenSSL::SSL::SSLError - # Don't worry about SSL negotiation failures, disconnect and carry on - rescue BadRequest - # We couldn't read a proper HTTP request, disconnect the client - rescue => e - if defined?(Raven) - Raven.capture_exception(e) - end - ensure - @socket.close rescue nil - @raw_socket.close rescue nil - end - - def ssl? - !!@options[:ssl] - end - - def remote_ip - @remote_ip || @raw_socket.peeraddr[3].sub('::ffff:', '') - end - - def self.ssl_context(domain_name = nil) - @ssl_certificates ||= {} - unless @ssl_certificates_refreshed && @ssl_certificates_refreshed > Time.now.utc.beginning_of_day - @ssl_certificates_refreshed = Time.now.utc - @ssl_certificates = {} - end - @ssl_certificates[domain_name] ||= OpenSSL::SSL::SSLContext.new.tap do |ssl_context| - if domain_name - if domain = TrackCertificate.active.where(:domain => domain_name).first - ssl_context.cert = domain.certificate_object - ssl_context.extra_chain_cert = domain.intermediaries_array - ssl_context.key = domain.key_object - end - end - - if ssl_context.cert.nil? - ssl_context.cert = Postal.fast_server_default_certificates[0] - ssl_context.extra_chain_cert = Postal.fast_server_default_certificates[1..-1] - ssl_context.key = Postal.fast_server_default_private_key - end - - ssl_context.ssl_version = "SSLv23" - ssl_context.ciphers = 'EECDH+ECDSA+AESGCM EECDH+aRSA+AESGCM EECDH+ECDSA+SHA384 EECDH+ECDSA+SHA256 EECDH+aRSA+SHA384 EECDH+aRSA+SHA256 EECDH+aRSA+RC4 EECDH EDH+aRSA !aNULL !eNULL !LOW !3DES !MD5 !EXP !PSK !SRP !DSS !RC4 !DH' - ssl_context.options = OpenSSL::SSL::SSLContext::DEFAULT_PARAMS[:options] | - OpenSSL::SSL::OP_NO_SSLv2 | - OpenSSL::SSL::OP_NO_SSLv3 | - OpenSSL::SSL::OP_NO_COMPRESSION | - OpenSSL::SSL::OP_CIPHER_SERVER_PREFERENCE - - if ssl_context.respond_to?('tmp_ecdh_callback=') - ssl_context.tmp_ecdh_callback = Proc.new do |*a| - OpenSSL::PKey::EC.new("prime256v1") - end - end - - unless domain_name - ssl_context.servername_cb = Proc.new do |ctx, hostname| - self.ssl_context(hostname) - end - end - end - end - - end - end -end diff --git a/lib/postal/fast_server/http_header.rb b/lib/postal/fast_server/http_header.rb deleted file mode 100644 index c2d086f..0000000 --- a/lib/postal/fast_server/http_header.rb +++ /dev/null @@ -1,21 +0,0 @@ -module Postal - module FastServer - class HTTPHeader - attr_accessor :key, :value - def self.from_string(string) - k, v = string.to_s.split(/\:\s*/, 2) - self.new(k.to_s, v.to_s) - end - - def initialize(k, v) - @key = k - @value = v - end - - def to_s - @key + ": " + @value - end - end - - end -end diff --git a/lib/postal/fast_server/http_header_set.rb b/lib/postal/fast_server/http_header_set.rb deleted file mode 100644 index cb3e1a8..0000000 --- a/lib/postal/fast_server/http_header_set.rb +++ /dev/null @@ -1,37 +0,0 @@ -module Postal - module FastServer - class HTTPHeaderSet - attr_accessor :headers - def initialize - @headers = [] - end - - def self.from_string_array(array) - header_set = self.new - header_set.headers = array.map{|h|HTTPHeader.from_string(h)} - header_set - end - - def select(key) - @headers.select{|h|h.key.downcase == key.downcase} - end - - def [](key) - @headers.find{|h|h.key.downcase == key.downcase} - end - - def []=(key, value) - self.delete(key) - @headers << HTTPHeader.new(key, value) - end - - def delete(key) - @headers.delete_if{|h|h.key.downcase == key.downcase} - end - - def <<(header) - @headers << header - end - end - end -end diff --git a/lib/postal/fast_server/interface.rb b/lib/postal/fast_server/interface.rb deleted file mode 100644 index cb17f8b..0000000 --- a/lib/postal/fast_server/interface.rb +++ /dev/null @@ -1,96 +0,0 @@ -module Postal - module FastServer - class Interface - - # TODO: Make this multithreaded? Thread-safe? - - TRACKING_PIXEL = File.read(Rails.root.join('app', 'assets', 'images', 'tracking_pixel.png')) - - def get_message_db_from_server_token(token) - if server = ::Server.find_by_token(token) - server.message_db - else - nil - end - end - - def call(env) - request = Rack::Request.new(env) - - if request.path =~ /\A\/(\.well-known\/.*)/ - if certificate = ::TrackCertificate.find_by_verification_path($1) - return [200, {'Content-Length' => certificate.verification_string.bytesize.to_s}, [certificate.verification_string]] - else - return [404, {}, ["Verification not found"]] - end - - elsif request.path =~ /\A\/img\/([a-z0-9\-]+)\/([a-z0-9\-]+)/i - server_token = $1 - message_token = $2 - - if message_db = get_message_db_from_server_token(server_token) - begin - message = message_db.message(:token => message_token) - message.create_load(request) - rescue Postal::MessageDB::Message::NotFound - # This message has been removed, we'll just continue to serve the image - rescue => e - # Somethign else went wrong. We don't want to stop the image loading though because - # this is our problem. Log this exception though. - if defined?(Raven) - Raven.capture_exception(e) - end - end - source_image = request.params['src'] - if source_image.nil? - headers = {} - headers['Content-Type'] = "image/png" - headers['Content-Length'] = TRACKING_PIXEL.bytesize.to_s - return [200, headers, [TRACKING_PIXEL]] - elsif source_image =~ /\Ahttps?\:\/\// - response = Postal::HTTP.get(source_image, :timeout => 3) - if response[:code] == 200 - headers = {} - headers['Content-Type'] = response[:headers]['content-type']&.first - headers['Last-Modified'] = response[:headers]['last-modified']&.first - headers['Cache-Control'] = response[:headers]['cache-control']&.first - headers['Etag'] = response[:headers]['etag']&.first - headers['Content-Length'] = response[:body].bytesize.to_s - return [200, headers, [response[:body]]] - else - return [404, {}, ['Not found']] - end - else - return [400, {}, ['Invalid/missing source image']] - end - else - return [404, {}, ['Invalid Server Token']] - end - end - - if request.path =~ /\A\/([a-z0-9\-]+)\/([a-z0-9\-]+)/i - server_token = $1 - link_token = $2 - if message_db = get_message_db_from_server_token(server_token) - if link = message_db.select(:links, :where => {:token => link_token}, :limit => 1).first - time = Time.now.to_f - if link['message_id'] - message_db.update(:messages, {:clicked => time}, :where => {:id => link['message_id']}) - message_db.insert(:clicks, {:message_id => link['message_id'], :link_id => link['id'], :ip_address => request.ip, :user_agent => request.user_agent, :timestamp => time}) - SendWebhookJob.queue(:main, :server_id => message_db.server_id, :event => 'MessageLinkClicked', :payload => {:_message => link['message_id'], :url => link['url'], :token => link['token'], :ip_address => request.ip, :user_agent => request.user_agent}) - end - return [307, {'Location' => link['url']}, ["Redirected to: #{link['url']}"]] - else - return [404, {}, ['Link not found']] - end - else - return [404, {}, ['Invalid Server Token']] - end - end - - [200, {}, ["Hello."]] - end - - end - end -end diff --git a/lib/postal/fast_server/server.rb b/lib/postal/fast_server/server.rb deleted file mode 100644 index 3ed8861..0000000 --- a/lib/postal/fast_server/server.rb +++ /dev/null @@ -1,49 +0,0 @@ -require 'socket' -require 'openssl' - -module Postal - module FastServer - class Server - - def run - if Postal.config.fast_server.bind_address.blank? - Postal.logger_for(:fast_server).info "Cannot start fast server because no bind address has been specified" - exit 1 - end - - Thread.abort_on_exception = true - TrackCertificate - - bind_addresses = Postal.config.fast_server.bind_address - bind_addresses = [bind_addresses] unless bind_addresses.is_a?(Array) - - server_sockets = bind_addresses.each_with_object({}) do |bind_addr, sockets| - sockets[TCPServer.new(bind_addr, Postal.config.fast_server.port)] = {:ssl => false} - sockets[TCPServer.new(bind_addr, Postal.config.fast_server.ssl_port)] = {:ssl => true} - Postal.logger_for(:fast_server).info("Fast server started listening on HTTP (#{bind_addr}:#{Postal.config.fast_server.port})") - Postal.logger_for(:fast_server).info("Fast server started listening on HTTPS port (#{bind_addr}:#{Postal.config.fast_server.ssl_port})") - end - - loop do - client = nil - ios = select(server_sockets.keys, nil, nil, 1) - if ios && server_io = ios[0][0] - begin - client_io = server_io.accept_nonblock - client = Client.new(client_io, server_sockets[server_io]) - Thread.new(client) { |t_client| t_client.run } - rescue IO::WaitReadable, Errno::EINTR - # Never mind, guess the client went away - rescue => e - if defined?(Raven) - Raven.capture_exception(e) - end - client_io.close rescue nil - end - end - end - end - - end - end -end diff --git a/lib/postal/lets_encrypt.rb b/lib/postal/lets_encrypt.rb deleted file mode 100644 index 6cfbfec..0000000 --- a/lib/postal/lets_encrypt.rb +++ /dev/null @@ -1,29 +0,0 @@ -require 'acme-client' - -module Postal - module LetsEncrypt - - def self.client - @client ||= Acme::Client.new(:private_key => private_key, :directory => directory) - end - - def self.private_key - @private_key ||= OpenSSL::PKey::RSA.new(File.open(Postal.lets_encrypt_private_key_path)) - end - - def self.directory - @directory ||= Rails.env.development? ? "https://acme-staging-v02.api.letsencrypt.org/directory" : "https://acme-v02.api.letsencrypt.org/directory" - end - - def self.register_private_key(email_address) - registration = client.new_account(:contact => "mailto:#{email_address}", :terms_of_service_agreed => true) - logger.info "Successfully registered private key with address #{email_address}" - true - end - - def self.logger - Postal.logger_for(:lets_encrypt) - end - - end -end diff --git a/lib/postal/message_parser.rb b/lib/postal/message_parser.rb index f9c3a9a..5a14fdc 100644 --- a/lib/postal/message_parser.rb +++ b/lib/postal/message_parser.rb @@ -80,11 +80,11 @@ module Postal end def parse(part, type = nil) - if Postal.tracking_available? && @domain.track_clicks? + if @domain.track_clicks? part = insert_links(part, type) end - if Postal.tracking_available? && @domain.track_loads? && type == :html + if @domain.track_loads? && type == :html part = insert_tracking_image(part) end diff --git a/lib/postal/tracking_middleware.rb b/lib/postal/tracking_middleware.rb new file mode 100644 index 0000000..90c3cac --- /dev/null +++ b/lib/postal/tracking_middleware.rb @@ -0,0 +1,105 @@ +module Postal + class TrackingMiddleware + + TRACKING_PIXEL = File.read(Rails.root.join('app', 'assets', 'images', 'tracking_pixel.png')) + + def initialize(app = nil) + @app = app + end + + def call(env) + unless env['HTTP_X_POSTAL_TRACK_HOST'].to_i == 1 + return @app.call(env) + end + + request = Rack::Request.new(env) + + case request.path + when /\A\/img\/([a-z0-9\-]+)\/([a-z0-9\-]+)/i + server_token = $1 + message_token = $2 + dispatch_image_request(request, server_token, message_token) + when /\A\/([a-z0-9\-]+)\/([a-z0-9\-]+)/i + server_token = $1 + link_token = $2 + dispatch_redirect_request(request, server_token, link_token) + else + [200, {}, ["Hello."]] + end + end + + private + + def dispatch_image_request(request, server_token, message_token) + message_db = get_message_db_from_server_token(server_token) + if message_db.nil? + return [404, {}, ['Invalid Server Token']] + end + + begin + message = message_db.message(:token => message_token) + message.create_load(request) + rescue Postal::MessageDB::Message::NotFound + # This message has been removed, we'll just continue to serve the image + rescue => e + # Somethign else went wrong. We don't want to stop the image loading though because + # this is our problem. Log this exception though. + Raven.capture_exception(e) if defined?(Raven) + end + + source_image = request.params['src'] + case source_image + when nil + headers = {} + headers['Content-Type'] = "image/png" + headers['Content-Length'] = TRACKING_PIXEL.bytesize.to_s + return [200, headers, [TRACKING_PIXEL]] + when /\Ahttps?\:\/\// + response = Postal::HTTP.get(source_image, :timeout => 3) + if response[:code] == 200 + headers = {} + headers['Content-Type'] = response[:headers]['content-type']&.first + headers['Last-Modified'] = response[:headers]['last-modified']&.first + headers['Cache-Control'] = response[:headers]['cache-control']&.first + headers['Etag'] = response[:headers]['etag']&.first + headers['Content-Length'] = response[:body].bytesize.to_s + return [200, headers, [response[:body]]] + else + return [404, {}, ['Not found']] + end + else + return [400, {}, ['Invalid/missing source image']] + end + end + + def dispatch_redirect_request(request, server_token, link_token) + message_db = get_message_db_from_server_token(server_token) + if message_db.nil? + return [404, {}, ['Invalid Server Token']] + end + + link = message_db.select(:links, :where => {:token => link_token}, :limit => 1).first + if link.nil? + return [404, {}, ['Link not found']] + end + + time = Time.now.to_f + if link['message_id'] + message_db.update(:messages, {:clicked => time}, :where => {:id => link['message_id']}) + message_db.insert(:clicks, {:message_id => link['message_id'], :link_id => link['id'], :ip_address => request.ip, :user_agent => request.user_agent, :timestamp => time}) + SendWebhookJob.queue(:main, :server_id => message_db.server_id, :event => 'MessageLinkClicked', :payload => {:_message => link['message_id'], :url => link['url'], :token => link['token'], :ip_address => request.ip, :user_agent => request.user_agent}) + end + + return [307, {'Location' => link['url']}, ["Redirected to: #{link['url']}"]] + end + + def get_message_db_from_server_token(token) + if server = ::Server.find_by_token(token) + server.message_db + else + nil + end + end + + end +end diff --git a/lib/tasks/postal.rake b/lib/tasks/postal.rake index aa54967..f7e5373 100644 --- a/lib/tasks/postal.rake +++ b/lib/tasks/postal.rake @@ -28,11 +28,6 @@ namespace :postal do end end - desc 'Start the fast server'# - task :fast_server => :environment do - Postal::FastServer::Server.new.run - end - end Rake::Task['db:migrate'].enhance do diff --git a/script/generate_initial_config.rb b/script/generate_initial_config.rb index f255116..64c3c7d 100755 --- a/script/generate_initial_config.rb +++ b/script/generate_initial_config.rb @@ -15,33 +15,9 @@ unless File.exist?(Postal.config_file_path) puts "Created example config file at #{Postal.config_file_path}" end -unless File.exists?(Postal.lets_encrypt_private_key_path) - key = OpenSSL::PKey::RSA.new(2048).to_s - File.open(Postal.lets_encrypt_private_key_path, 'w') { |f| f.write(key) } - puts "Created new private key for Let's Encrypt" -end - unless File.exists?(Postal.signing_key_path) key = OpenSSL::PKey::RSA.new(1024).to_s File.open(Postal.signing_key_path, 'w') { |f| f.write(key) } puts "Created new signing key for DKIM & HTTP requests" end -unless File.exists?(Postal.fast_server_default_private_key_path) - key = OpenSSL::PKey::RSA.new(2048).to_s - File.open(Postal.fast_server_default_private_key_path, 'w') { |f| f.write(key) } - puts "Created new private key for default fast server TLS connections" -end - -unless File.exist?(Postal.fast_server_default_certificate_path) - cert = OpenSSL::X509::Certificate.new - cert.subject = cert.issuer = OpenSSL::X509::Name.parse("/C=GB/O=Default/OU=Default/CN=default") - cert.not_before = Time.now - cert.not_after = Time.now + (365 * 24 * 60 * 60) * 10 - cert.public_key = Postal.fast_server_default_private_key.public_key - cert.serial = 0x0 - cert.version = 2 - cert.sign Postal.fast_server_default_private_key, OpenSSL::Digest::SHA256.new - File.open(Postal.fast_server_default_certificate_path, 'w') { |f| f.write(cert.to_pem) } - puts "Created new self signed certificate for default fast server TLS connections" -end diff --git a/script/register_lets_encrypt.rb b/script/register_lets_encrypt.rb deleted file mode 100644 index c5214e1..0000000 --- a/script/register_lets_encrypt.rb +++ /dev/null @@ -1,15 +0,0 @@ -require_relative '../config/application' -require 'postal/lets_encrypt' - -if ARGV[0].nil? - puts "e-mail address missing" - exit 1 -end - -begin - Postal::LetsEncrypt.register_private_key(ARGV[0]) - puts "Done" -rescue => e - puts "#{e.class}: #{e.message}" - exit 1 -end diff --git a/spec/config/fast_server.cert b/spec/config/fast_server.cert deleted file mode 100644 index dd04406..0000000 --- a/spec/config/fast_server.cert +++ /dev/null @@ -1,19 +0,0 @@ ------BEGIN CERTIFICATE----- -MIIC/zCCAeegAwIBAgIBADANBgkqhkiG9w0BAQsFADBDMQswCQYDVQQGEwJHQjEQ -MA4GA1UECgwHRGVmYXVsdDEQMA4GA1UECwwHRGVmYXVsdDEQMA4GA1UEAwwHZGVm -YXVsdDAeFw0xNzA1MDgxMzM2MDBaFw0yNzA1MDYxMzM2MDBaMEMxCzAJBgNVBAYT -AkdCMRAwDgYDVQQKDAdEZWZhdWx0MRAwDgYDVQQLDAdEZWZhdWx0MRAwDgYDVQQD -DAdkZWZhdWx0MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA18zeoKrM -m9dlvu5l3k57ocbtB5PKm1fWcUg6XSl4Wtk+Tf9TQx8wuwjEwRvqGdgP9KWtazdW -2eN9z9lmHd3GnC3inmw7UcSkGkeEUQrwbkjihoKAgEpLBNmJoaMWatbdvcgkBvKs -WUg8J4g7yRdX5jWGa0f9Ok0jfYYNQwPZ1iugD9ayBcovvvCX3Xm2oeKCjBeqjejS -wlv1KdYmHQ2AduIx/s9+vxdWtnllqbJ+v60+WqVzwxxJWE4P+kJb+vNbgZ01xFGX -vljT/DzosDVR4OYBI5IumOYwuDz91FY/K9Yi+7QKfI7tq7y9ZKYJQSqZxpnOw2gn -qZuC/ReCBw/wlwIDAQABMA0GCSqGSIb3DQEBCwUAA4IBAQDHEE35sCpFivcVFoVC -Y7q7u2PhHofjhi1pqPRnZOtiVIYr9xXAe+pTlcv+K9Kc0IenaADEnra0wM0i5imp -b3ObQ0CyRCyKKVbU8t74RYo6K3klZnru61YWte0MdsBFYwYTSAZzK9l+5EICyX1l -KYcXIGgdZJddU7GQ4EASh1BTB7qDQ7GOQRlY1uTyVd+74WdfUez8A6FgRGnx/RRD -0u/l+K8+JIaqgSU1+ZlxPw+KpHUPJhoTikZapyKgaINBoLfyuVd4svf4HsJzjwcj -w8CL5sPAdN8iLeDVkHemX/Tcl4CdWVBodb3Wiqcq7DgTVY2alDNMjCo9YvzuAPVL -99W3 ------END CERTIFICATE----- diff --git a/spec/config/fast_server.key b/spec/config/fast_server.key deleted file mode 100644 index c9f1691..0000000 --- a/spec/config/fast_server.key +++ /dev/null @@ -1,27 +0,0 @@ ------BEGIN RSA PRIVATE KEY----- -MIIEogIBAAKCAQEA18zeoKrMm9dlvu5l3k57ocbtB5PKm1fWcUg6XSl4Wtk+Tf9T -Qx8wuwjEwRvqGdgP9KWtazdW2eN9z9lmHd3GnC3inmw7UcSkGkeEUQrwbkjihoKA -gEpLBNmJoaMWatbdvcgkBvKsWUg8J4g7yRdX5jWGa0f9Ok0jfYYNQwPZ1iugD9ay -BcovvvCX3Xm2oeKCjBeqjejSwlv1KdYmHQ2AduIx/s9+vxdWtnllqbJ+v60+WqVz -wxxJWE4P+kJb+vNbgZ01xFGXvljT/DzosDVR4OYBI5IumOYwuDz91FY/K9Yi+7QK -fI7tq7y9ZKYJQSqZxpnOw2gnqZuC/ReCBw/wlwIDAQABAoIBADj2T/GTBA1Czw2V -+fezObkbPCfa4AkfJ3Chgx5iOu2oGGUYN08pZYCJMP5UMvf9a0DFlsANTHSZMvVx -Sh4qEynYhtAQe5v6zuJM7GVEAPDrdjfRLMAwXBr8nPK4jMtIyiE1OiVHWyz5/z7k -G/vZmI8go8mfp/0CrZKNluSQmKiKQPS1rkDXiVBkF7ifFO6j34IjnihgWsc2W/CL -Wvehfe6RmCK+KfEDREpTSw2/VFuqn4j2FYK8PpweAAJwVWtGGuDB9QSPkKT8WSgK -yZFVW3d+aouBfduHKcja/ccmrGhmBhni80lTjUxakzK7Hw4SKmNTV1FPNfJsE1ez -zPqs8tkCgYEA/a0yBSFuwaLGuwpmchjH32bcq+TR7qNaCAfv07pL7aQXd7nSjDuU -Lz/ohveubizhdsl32kJQBuPNuYeLXxhsulxCumS3tfN31/J4IYU2BXNB20mhKSkP -APneQfc5SS2T3cOdd5hUgsFlSAU2KtWC/qSrXSpR0kEyCGLbOrctJnUCgYEA2cbd -R8QOFzMBpz5Dl3DtFc3qzAyw2lS1m6Nlus3zMxNwX0Diaw9eyiZKOxjNBwN8uQa6 -hOf944go2MmEmdRILWiV7lXt1ML5/fD/Kf2n15TI+xl4maETNGtxPMlZs158xsRR -g4qUvRufZp03V3Cu1e9HrypElw9D6K1lv7DvkVsCgYAvxM53gt0tX26WyBWUhLAW -lHMXd2ZEzsPkYUI7F4i2vkChDf/k4k88OoeZ6sgQ/SiTyspj8jrJoVobBrgq9xl6 -WmdCXDbv72Hw6zrN7RzIF/Udyxaq/o1RvLuqplhGPGvsxapAXBIF8U8WKc0ScdRS -CUYvrAluU1KNm7f2rYm2BQKBgEEliUqPrrtn6cWzDZs/D91m9SdHYJxfnNhLQAJq -26ba2NHV4iWuumd0nt4g5CyF8YiUJ7XchInNUJLRbdZqt5DF6ZwbnoL4NLqvnlVc -aRpHivv6uaYTlmAnB//sJ+ZNjLwVPGFCUo5jtgKHY2fH8LVU2DfhSBV8Xo87V+XJ -M1FjAoGAEIkg3M/rRku0SMaT0LofchABhW1RXYwBUqUsb4TUF2fdm5iESRg1wP2g -kvMe6394KFseK4/OG2SZf69bMeUbdwi+LA8krIKj4CFhgjdG0Xs4j/POWqCExNDC -pAwJbJcn3o/RSGwIl4fO0o0JwJe8//269pklRQ5CrZt3+LSxy/E= ------END RSA PRIVATE KEY----- diff --git a/spec/config/lets_encrypt.pem b/spec/config/lets_encrypt.pem deleted file mode 100644 index a356326..0000000 --- a/spec/config/lets_encrypt.pem +++ /dev/null @@ -1,27 +0,0 @@ ------BEGIN RSA PRIVATE KEY----- -MIIEpAIBAAKCAQEAvbtEZ/TZPqMZmbNJH8trasoYkuzkLSsiGBAmKWDw/V3xVkMX -JSY+MYRv6NlKKXZg6SYoZVU8DvxCvUQstJDU+CYHUfQtBthQaWGzh5XdAmjTtb+6 -UTyI5UtrwbzWHPgUrwHtN/QpBGsan6A2ASbP5R+HxuUTjzvkMc6otyvdjO+86jSt -mFxGoJXmQSyyGATjMBnhTCPUNjqOI13qgwWgh0beCY2+m78URbJ60NHg+UOBOIUx -Z1e0jY0YCRxb+CuTiBgbBCS3JNlze7JTwLXDgXunV2OPUBA5qd2+4eGsaSzeGxMi -HZaat/Pcn11PEZBEYMuEr2bGb9ANxSzzN4+NKwIDAQABAoIBAQCTH1qdDfVDp++b -CrZCTFfgOBQ0IjORfufyJtugrIZSwfz5Og8BhJUnip3Ivm3Olvfw8uDSKvTmXeBW -qT3NSp2KStrURvZ/X0+DV/qBwcjeLHE2dxTAF6PDwecuFQMm9Yv8ZQ8Qm2kO/wpn -CzG1VOZSsk90AIBZSkTaBnk3iHFE7e66Ru3AVNdFOkn45W459IeZRsh7FnrLG4r4 -3ko/07+e1Eb82mgnan3iyMrHYW+PACzcP/GjIJ2Xh3e39IexXeEsp8qkAbUsv0xx -lt1QL22Xi6gRc2GMv+GNIi84FfnJ6P/ju3dVuHiShFncM2zM5cc9snOHaayePyT6 -HVVySp0JAoGBAPDJmdd/01W91KcmzZ59N7+uhSMhfvxvZE/fpq1dEwtTIREUW6sL -J7yfJA9KSm+SsOpy6NOG/caWACz+lPZX67Ju4eIO6aiIV5Tj3g8SvdMNvj4a6gfz -lMg7eDtiuk4AeFQroPqmo+IPMd2ia4N6OOIOt5XzaoTHl7wdIrMTFbb/AoGBAMm3 -6E7DMR/dcUpe9bOrOtPA8MtGVxhMhR6AR7fpQtFRcjmpOnQnio5EASvOM4tAN/H0 -DB5tyuQ9JzHmvH5tENdwXZLnPBvnKl4OobZqaX7SWQA1inb71fr1pjp8rzceABjZ -pFJ3/esN5VJw+f3DTjw8HbBkHZBtvbNNPin/5LXVAoGBAKq698dSjoHcQR1oKSG4 -vb+/Og3H4WeSgDkWZvPD7A36mpamrbzhAwL+gC4LSi5EgActBSN/MxANKgC9Xtgx -TSFO+AE2+7yRODCNRdXAPzKYKw2UPd73esZjTIQnI9zM/oUIDnPLlqZiicQSN1OZ -ZR38u3WqjBur/k3XBtScsqf3AoGAGA3VJudByWH3q32tYPJvPmcIj8Tgh+ZADYYQ -h07Kh/llXJjgfo9kh1h2p0mcfeN3iGOoukwvYI4mSV4RZiYNVxNwJR9r3IvxUmv+ -Pqlr0RK2SD8aNtwLBTUb0Gej4TeznUL+xFLItanfibgtJ2SNxMMKa0lU+S8M6v+w -BQQdus0CgYBu+21HRlcgTr47TtNlCUP1fCPgkpJXj72P8WBVvJnVi8JjIX++PtcR -QwxJpPxX9MsQiD/2oziEb/pXDrNytuezDwGsNrRmrVpgorL3lXaLi571AjY7urrq -/0ZT4OPIP+Em1F9ugh+u/XxOedLwmcwzz3VmKCYfSJzcQQ3jU8njjA== ------END RSA PRIVATE KEY----- diff --git a/spec/config/postal.yml b/spec/config/postal.yml index ec06fbf..5adc051 100644 --- a/spec/config/postal.yml +++ b/spec/config/postal.yml @@ -2,12 +2,6 @@ web: host: postal.example.com protocol: https -fast_server: - enabled: true - bind_address: 0.0.0.0 - port: 5010 - ssl_port: 5011 - general: use_ip_pools: false diff --git a/spec/lib/postal/message_parser_spec.rb b/spec/lib/postal/message_parser_spec.rb index b3bb557..e1b8bd9 100644 --- a/spec/lib/postal/message_parser_spec.rb +++ b/spec/lib/postal/message_parser_spec.rb @@ -19,7 +19,7 @@ describe Postal::MessageParser do track_domain = 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(/\AHello world! http:\/\/click\.#{message.domain.name}/) + expect(parser.new_body).to match(/\AHello world! https:\/\/click\.#{message.domain.name}/) expect(parser.tracked_links).to eq 1 end end