1
0
مراية لـ https://github.com/postalserver/postal.git تم المزامنة 2026-03-05 07:14:04 +00:00

Compare commits

13 الالتزامات
2.1.6 ... 2.2.0

المؤلف SHA1 الرسالة التاريخ
github-actions[bot]
ff901e99f7 chore(main): release 2.2.0 (#2766)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2024-02-01 16:54:50 +00:00
Adam Cooke
ce19bf7988 fix: use utc timestamps when determining raw table names 2024-02-01 16:41:41 +00:00
Adam Cooke
8794a2f447 chore: add script to send html emails to a local SMTP server 2024-02-01 13:54:05 +00:00
Adam Cooke
6b2bf9062d fix: extract x-postal-tag before holding
closes #2684
2024-02-01 13:53:45 +00:00
Adam Cooke
49cceaa6ca fix: move tracking middleware before host authorization
closes #2415
2024-01-31 17:55:39 +00:00
Adam Cooke
71f51db3c2 fix: fixes error messages in web ui 2024-01-30 17:34:11 +00:00
Adam Cooke
4a46f690de feat: load signing key path from POSTAL_SIGNING_KEY_PATH 2024-01-30 14:13:19 +00:00
Adam Cooke
854aa5ebc8 feat: support for configuring postal with environment variables 2024-01-30 13:11:56 +00:00
Adam Cooke
990b575902 refactor: remove Postal::Job.perform method
this wasn't used
2024-01-30 11:06:39 +00:00
Adam Cooke
2bad645d98 fix: don't use indifferent access for job params
All jobs refer to parameters using string keys.

closes #2477
closes #2714
closes #2476
closes #2500
2024-01-30 11:06:22 +00:00
Adam Cooke
41f6cf4d90 chore: add binstubs for bundle and rspec 2024-01-30 10:19:40 +00:00
Adam Cooke
3fb40e4e24 fix: ignore message DB migrations in autoloader 2024-01-30 10:19:37 +00:00
Adam Cooke
0f9882f132 refactor: remove explicit autoload 2024-01-30 09:15:25 +00:00
20 ملفات معدلة مع 341 إضافات و196 حذوفات

عرض الملف

@@ -1,3 +1,3 @@
{ {
".": "2.1.6" ".": "2.2.0"
} }

عرض الملف

@@ -2,6 +2,36 @@
This file contains all the latest changes and updates to Postal. This file contains all the latest changes and updates to Postal.
## [2.2.0](https://github.com/postalserver/postal/compare/2.1.6...2.2.0) (2024-02-01)
### Features
* load signing key path from POSTAL_SIGNING_KEY_PATH ([4a46f69](https://github.com/postalserver/postal/commit/4a46f690de3010f1ae4d6c17739530a4eae35c09))
* support for configuring postal with environment variables ([854aa5e](https://github.com/postalserver/postal/commit/854aa5ebc87de692b4691d48759aefd6fae9d133))
### Bug Fixes
* don't use indifferent access for job params ([2bad645](https://github.com/postalserver/postal/commit/2bad645d980ad4b712a3c863b5350e4ee2895071)), closes [#2477](https://github.com/postalserver/postal/issues/2477) [#2714](https://github.com/postalserver/postal/issues/2714) [#2476](https://github.com/postalserver/postal/issues/2476) [#2500](https://github.com/postalserver/postal/issues/2500)
* extract x-postal-tag before holding ([6b2bf90](https://github.com/postalserver/postal/commit/6b2bf9062d662ede14617c4995ffaacca023a3b1)), closes [#2684](https://github.com/postalserver/postal/issues/2684)
* fixes error messages in web ui ([71f51db](https://github.com/postalserver/postal/commit/71f51db3c2515addaf8b280667555427d64796be))
* ignore message DB migrations in autoloader ([3fb40e4](https://github.com/postalserver/postal/commit/3fb40e4e247893b314e42affa4604a7a71a52c59))
* move tracking middleware before host authorization ([49cceaa](https://github.com/postalserver/postal/commit/49cceaa6ca862965448041279fc439ecba163ff8)), closes [#2415](https://github.com/postalserver/postal/issues/2415)
* use utc timestamps when determining raw table names ([ce19bf7](https://github.com/postalserver/postal/commit/ce19bf7988d522bf46aabf68090751427e286ffc))
### Miscellaneous Chores
* add binstubs for bundle and rspec ([41f6cf4](https://github.com/postalserver/postal/commit/41f6cf4d909518526af55ecb3fcccfa8fb8e1da2))
* add script to send html emails to a local SMTP server ([8794a2f](https://github.com/postalserver/postal/commit/8794a2f44783658a075a6f3985079ae4743412b1))
### Code Refactoring
* remove explicit autoload ([0f9882f](https://github.com/postalserver/postal/commit/0f9882f13204124df630606b1b9e36787c9c4011))
* remove Postal::Job.perform method ([990b575](https://github.com/postalserver/postal/commit/990b575902c45bb1678cc95f53ef3166c4b7092e))
## [2.1.6](https://github.com/postalserver/postal/compare/2.1.5...2.1.6) (2024-01-30) ## [2.1.6](https://github.com/postalserver/postal/compare/2.1.5...2.1.6) (2024-01-30)

عرض الملف

@@ -90,7 +90,7 @@ class ApplicationController < ActionController::Base
def render_form_errors(action_name, object) def render_form_errors(action_name, object)
respond_to do |wants| respond_to do |wants|
wants.html { render action_name } wants.html { render action_name }
wants.json { render json: { form_errors: object.errors.full_messages }, status: :unprocessable_entity } wants.json { render json: { form_errors: object.errors.map(&:full_message) }, status: :unprocessable_entity }
end end
end end

عرض الملف

@@ -292,6 +292,12 @@ class UnqueueMessageJob < Postal::Job
next next
end end
# Extract a tag and add it to the message if one doesn't exist
if queued_message.message.tag.nil? && tag = queued_message.message.headers["x-postal-tag"]
log "#{log_prefix} Added tag #{tag.last}"
queued_message.message.update(tag: tag.last)
end
# #
# If the credentials for this message is marked as holding and this isn't manual, hold it # If the credentials for this message is marked as holding and this isn't manual, hold it
# #
@@ -312,12 +318,6 @@ class UnqueueMessageJob < Postal::Job
next next
end end
# Extract a tag and add it to the message if one doesn't exist
if queued_message.message.tag.nil? && tag = queued_message.message.headers["x-postal-tag"]
log "#{log_prefix} Added tag #{tag.last}"
queued_message.message.update(tag: tag.last)
end
# Parse the content of the message as appropriate # Parse the content of the message as appropriate
if queued_message.message.should_parse? if queued_message.message.should_parse?
log "#{log_prefix} Parsing message content as it hasn't been parsed before" log "#{log_prefix} Parsing message content as it hasn't been parsed before"

عرض الملف

@@ -1,3 +1,109 @@
#!/usr/bin/env ruby #!/usr/bin/env ruby
ENV["BUNDLE_GEMFILE"] ||= File.expand_path("../Gemfile", __dir__) # frozen_string_literal: true
load Gem.bin_path("bundler", "bundle")
#
# This file was generated by Bundler.
#
# The application 'bundle' is installed as part of a gem, and
# this file is here to facilitate running it.
#
require "rubygems"
m = Module.new do
module_function
def invoked_as_script?
File.expand_path($0) == File.expand_path(__FILE__)
end
def env_var_version
ENV["BUNDLER_VERSION"]
end
def cli_arg_version
return unless invoked_as_script? # don't want to hijack other binstubs
return unless "update".start_with?(ARGV.first || " ") # must be running `bundle update`
bundler_version = nil
update_index = nil
ARGV.each_with_index do |a, i|
if update_index && update_index.succ == i && a =~ Gem::Version::ANCHORED_VERSION_PATTERN
bundler_version = a
end
next unless a =~ /\A--bundler(?:[= ](#{Gem::Version::VERSION_PATTERN}))?\z/
bundler_version = $1
update_index = i
end
bundler_version
end
def gemfile
gemfile = ENV["BUNDLE_GEMFILE"]
return gemfile if gemfile && !gemfile.empty?
File.expand_path("../Gemfile", __dir__)
end
def lockfile
lockfile =
case File.basename(gemfile)
when "gems.rb" then gemfile.sub(/\.rb$/, ".locked")
else "#{gemfile}.lock"
end
File.expand_path(lockfile)
end
def lockfile_version
return unless File.file?(lockfile)
lockfile_contents = File.read(lockfile)
return unless lockfile_contents =~ /\n\nBUNDLED WITH\n\s{2,}(#{Gem::Version::VERSION_PATTERN})\n/
Regexp.last_match(1)
end
def bundler_requirement
@bundler_requirement ||=
env_var_version ||
cli_arg_version ||
bundler_requirement_for(lockfile_version)
end
def bundler_requirement_for(version)
return "#{Gem::Requirement.default}.a" unless version
bundler_gem_version = Gem::Version.new(version)
bundler_gem_version.approximate_recommendation
end
def load_bundler!
ENV["BUNDLE_GEMFILE"] ||= gemfile
activate_bundler
end
def activate_bundler
gem_error = activation_error_handling do
gem "bundler", bundler_requirement
end
return if gem_error.nil?
require_error = activation_error_handling do
require "bundler/version"
end
return if require_error.nil? && Gem::Requirement.new(bundler_requirement).satisfied_by?(Gem::Version.new(Bundler::VERSION))
warn "Activating bundler (#{bundler_requirement}) failed:\n#{gem_error.message}\n\nTo install the version of bundler this project requires, run `gem install bundler -v '#{bundler_requirement}'`"
exit 42
end
def activation_error_handling
yield
nil
rescue StandardError, LoadError => e
e
end
end
m.load_bundler!
if m.invoked_as_script?
load Gem.bin_path("bundler", "bundle")
end

27
bin/rspec Executable file
عرض الملف

@@ -0,0 +1,27 @@
#!/usr/bin/env ruby
# frozen_string_literal: true
#
# This file was generated by Bundler.
#
# The application 'rspec' is installed as part of a gem, and
# this file is here to facilitate running it.
#
ENV["BUNDLE_GEMFILE"] ||= File.expand_path("../Gemfile", __dir__)
bundle_binstub = File.expand_path("bundle", __dir__)
if File.file?(bundle_binstub)
if File.read(bundle_binstub, 300).include?("This file was generated by Bundler")
load(bundle_binstub)
else
abort("Your `bin/bundle` was not generated by Bundler, so this binstub cannot run.
Replace `bin/bundle` by running `bundle binstubs bundler --force`, then run this command again.")
end
end
require "rubygems"
require "bundler/setup"
load Gem.bin_path("rspec-core", "rspec")

عرض الملف

@@ -27,14 +27,14 @@ module Postal
end end
# Include from lib # Include from lib
config.eager_load_namespaces << Postal config.eager_load_paths << Rails.root.join("lib")
# Disable field_with_errors # Disable field_with_errors
config.action_view.field_error_proc = proc { |t, i| t } config.action_view.field_error_proc = proc { |t, i| t }
# Load the tracking server middleware # Load the tracking server middleware
require "postal/tracking_middleware" require "postal/tracking_middleware"
config.middleware.use Postal::TrackingMiddleware config.middleware.insert_before ActionDispatch::HostAuthorization, Postal::TrackingMiddleware
config.logger = Postal.logger_for(:rails) config.logger = Postal.logger_for(:rails)

عرض الملف

@@ -12,13 +12,17 @@
# These inflection rules are supported but not enabled by default: # These inflection rules are supported but not enabled by default:
ActiveSupport::Inflector.inflections(:en) do |inflect| ActiveSupport::Inflector.inflections(:en) do |inflect|
inflect.acronym "API"
inflect.acronym "SMTP"
inflect.acronym "IP"
inflect.acronym "DNS"
inflect.acronym "UUID"
inflect.acronym "HTTP"
inflect.acronym "DB"
inflect.acronym "MX"
inflect.acronym "DKIM" inflect.acronym "DKIM"
inflect.acronym "HTTP"
inflect.acronym "SMTP"
inflect.acronym "UUID"
inflect.acronym "API"
inflect.acronym "DNS"
inflect.acronym "DB"
inflect.acronym "IP"
inflect.acronym "MQ"
inflect.acronym "MX"
end end

عرض الملف

@@ -0,0 +1,5 @@
Rails.autoloaders.each do |autoloader|
# Ignore the message DB migrations directory as it doesn't follow
# Zeitwerk's conventions and is always loaded and executed in order.
autoloader.ignore(Rails.root.join('lib/postal/message_db/migrations'))
end

عرض الملف

@@ -5,126 +5,122 @@
# You can refer to this for a complete listing all available configuration options. # You can refer to this for a complete listing all available configuration options.
web: web:
host: postal.example.com host: <%= ENV.fetch('POSTAL_HOST', 'postal.example.com') %>
protocol: https protocol: <%= ENV.fetch('POSTAL_PROTOCOL', 'https') %>
general: general:
use_ip_pools: false use_ip_pools: <%= ENV.fetch('POSTAL_USE_IP_POOLS', 'false') %>
exception_url: exception_url: <%= ENV.fetch('POSTAL_EXCEPTION_URL', '') %>
maximum_delivery_attempts: 18 maximum_delivery_attempts: <%= ENV.fetch('POSTAL_MAXIMUM_DELIVERY_ATTEMPTS', '18') %>
maximum_hold_expiry_days: 7 maximum_hold_expiry_days: <%= ENV.fetch('POSTAL_MAXIMUM_HOLD_EXPIRY_DAYS', '7') %>
suppression_list_removal_delay: 30 suppression_list_removal_delay: <%= ENV.fetch('POSTAL_SUPPRESSION_LIST_REMOVAL_DELAY', '30') %>
use_local_ns_for_domains: false use_local_ns_for_domains: <%= ENV.fetch('POSTAL_USE_LOCAL_NS_FOR_DOMAINS', 'false') %>
default_spam_threshold: 5.0 default_spam_threshold: <%= ENV.fetch('POSTAL_DEFAULT_SPAM_THRESHOLD', '5.0') %>
default_spam_failure_threshold: 20.0 default_spam_failure_threshold: <%= ENV.fetch('POSTAL_DEFAULT_SPAM_FAILURE_THRESHOLD', '20.0') %>
use_resent_sender_header: true use_resent_sender_header: <%= ENV.fetch('POSTAL_USE_RESENT_SENDER_HEADER', 'true') %>
web_server: web_server:
bind_address: 127.0.0.1 bind_address: <%= ENV.fetch('WEB_SERVER_BIND_ADDRESS', '0.0.0.0') %>
port: 5000 port: <%= ENV.fetch('WEB_SERVER_PORT', '5000') %>
max_threads: 5 max_threads: <%= ENV.fetch('WEB_SERVER_MAX_THREADS', '5') %>
main_db: main_db:
host: 127.0.0.1 host: <%= ENV.fetch('MAIN_DB_HOST', '127.0.0.1') %>
port: 3306 port: <%= ENV.fetch('MAIN_DB_PORT', '3306') %>
username: postal username: <%= ENV.fetch('MAIN_DB_USERNAME', 'postal') %>
password: password: <%= ENV.fetch('MAIN_DB_PASSWORD', '') %>
database: postal database: <%= ENV.fetch('MAIN_DB_DATABASE', 'postal') %>
pool_size: 5 pool_size: <%= ENV.fetch('MAIN_DB_POOL_SIZE', '5') %>
logging:
stdout: false
root: # Automatically determined based on config root
max_log_file_size: 20
max_log_files: 10
graylog:
host:
port: 12201
message_db: message_db:
host: 127.0.0.1 host: <%= ENV.fetch('MESSAGE_DB_HOST', '127.0.0.1') %>
port: 3306 port: <%= ENV.fetch('MESSAGE_DB_PORT', '3306') %>
username: postal username: <%= ENV.fetch('MESSAGE_DB_USERNAME', 'postal') %>
password: password: <%= ENV.fetch('MESSAGE_DB_PASSWORD', '') %>
prefix: postal prefix: <%= ENV.fetch('MESSAGE_DB_PREFIX', 'postal') %>
rabbitmq: rabbitmq:
host: 127.0.0.1 host: <%= ENV.fetch('RABBITMQ_HOST', '127.0.0.1') %>
port: 5672 port: <%= ENV.fetch('RABBITMQ_PORT', '5672') %>
tls: false username: <%= ENV.fetch('RABBITMQ_USERNAME', 'postal') %>
verify_peer: true password: <%= ENV.fetch('RABBITMQ_PASSWORD', '') %>
tls_ca_certificates: vhost: <%= ENV.fetch('RABBITMQ_VHOST', '/postal') %>
- /etc/ssl/certs/ca-certificates.crt tls: <%= ENV.fetch('RABBITMQ_TLS', 'false') %>
username: postal verify_peer: <%= ENV.fetch('RABBITMQ_VERIFY_PEER', 'true') %>
password: tls_ca_certificates: <%= ENV.fetch('RABBITMQ_TLS_CA_CERTIFICATES', '/etc/ssl/certs/ca-certificates.crt'.split(',').inspect) %>
vhost: /postal
logging:
stdout: <%= ENV.fetch('LOGGING_STDOUT', 'false') %>
root: <%= ENV.fetch('LOGGING_ROOT', '') %>
max_log_file_size: <%= ENV.fetch('LOGGING_MAX_LOG_FILES', '20') %>
max_log_files: <%= ENV.fetch('LOGGING_MAX_LOG_FILES', '10') %>
graylog:
host: <%= ENV.fetch('GRAYLOG_HOST', '') %>
port: <%= ENV.fetch('GRAYLOG_PORT', '12201') %>
workers: workers:
quantity: 1 threads: <%= ENV.fetch('WORKER_THREADS', '4') %>
threads: 4
smtp_server: smtp_server:
port: 25 port: <%= ENV.fetch('SMTP_SERVER_PORT', '25') %>
bind_address: '::' bind_address: "<%= ENV.fetch('SMTP_SERVER_BIND_ADDRESS', '::') %>"
tls_enabled: false tls_enabled: <%= ENV.fetch('SMTP_SERVER_TLS_ENABLED', 'false') %>
tls_certificate_path: # Defaults to config/smtp.cert tls_certificate_path: <%= ENV.fetch('SMTP_SERVER_TLS_CERTIFICATE_PATH', '') %> # Defaults to config/smtp.cert
tls_private_key_path: # Defaults to config/smtp.key tls_private_key_path: <%= ENV.fetch('SMTP_SERVER_TLS_PRIVATE_KEY_PATH', '') %> # Defaults to config/smtp.key
tls_ciphers: tls_ciphers: <%= ENV.fetch('SMTP_SERVER_TLS_CIPHERS', '') %>
ssl_version: SSLv23 ssl_version: <%= ENV.fetch('SMTP_SERVER_SSL_VERSION', 'SSLv23') %>
proxy_protocol: false proxy_protocol: <%= ENV.fetch('SMTP_SERVER_PROXY_PROTOCOL', 'false') %>
log_connect: true log_connect: <%= ENV.fetch('SMTP_SERVER_LOG_CONNECT', 'false') %>
strip_received_headers: false strip_received_headers: <%= ENV.fetch('SMTP_SERVER_STRIP_RECEIVED_HEADERS', 'false') %>
max_message_size: 14 # size in Megabytes max_message_size: <%= ENV.fetch('SMTP_SERVER_MAX_MESSAGE_SIZE', '14') %> # size in Megabytes
smtp_relays: smtp_relays:
- - hostname:
hostname:
port: 25 port: 25
ssl_mode: Auto ssl_mode: Auto
dns: dns:
mx_records: mx_records: <%= ENV.fetch('DNS_MX_RECORDS', 'mx.postal.example.com'.split(',').inspect) %>
- mx.postal.example.com smtp_server_hostname: <%= ENV.fetch('DNS_SMTP_SERVER_HOSTNAME', 'postal.example.com') %>
smtp_server_hostname: postal.example.com spf_include: <%= ENV.fetch('DNS_SPF_INCLUDE', 'spf.postal.example.com') %>
spf_include: spf.postal.example.com return_path: <%= ENV.fetch('DNS_RETURN_PATH', 'rp.postal.example.com') %>
return_path: rp.postal.example.com route_domain: <%= ENV.fetch('DNS_ROUTE_DOMAIN', 'routes.postal.example.com') %>
route_domain: routes.postal.example.com track_domain: <%= ENV.fetch('DNS_TRACK_DOMAIN', 'track.postal.example.com') %>
track_domain: track.postal.example.com helo_hostname: <%= ENV.fetch('DNS_HELO_HOSTNAME', '') %> # By default, this will be the same as the `smtp_server_hostname`
helo_hostname: # By default, this will be the same as the `smtp_server_hostname` dkim_identifier: <%= ENV.fetch('DNS_DKIM_IDENTIFIER', 'postal') %>
dkim_identifier: postal domain_verify_prefix: <%= ENV.fetch('DNS_DOMAIN_VERIFY_PREFIX', 'postal-verification') %>
domain_verify_prefix: postal-verification custom_return_path_prefix: <%= ENV.fetch('DNS_CUSTOM_RETURN_PATH_PREFIX', 'psrp') %>
custom_return_path_prefix: psrp
smtp: smtp:
host: 127.0.0.1 host: <%= ENV.fetch('SMTP_HOST', '127.0.0.1') %>
port: 25 port: <%= ENV.fetch('SMTP_PORT', '25') %>
username: # Complete when Postal is running and you can username: <%= ENV.fetch('SMTP_USERNAME', '') %> # Complete when Postal is running and you can
password: # generate the credentials within the interface. password: <%= ENV.fetch('SMTP_PASSWORD', '') %> # generate the credentials within the interface.
from_name: Postal from_name: <%= ENV.fetch('SMTP_FROM_NAME', 'Postal') %>
from_address: postal@yourdomain.com from_address: <%= ENV.fetch('SMTP_FROM_ADDRESS', 'postal@example.com') %>
rails: rails:
environment: production environment: <%= ENV.fetch('RAILS_ENV', 'production') %>
secret_key: secret_key: <%= ENV.fetch('RAILS_SECRET_KEY_BASE', '') %>
rspamd: rspamd:
enabled: false enabled: <%= ENV.fetch('RSPAMD_ENABLED', 'false') %>
host: 127.0.0.1 host: <%= ENV.fetch('RSPAMD_HOST', '127.0.0.1') %>
port: 11334 port: <%= ENV.fetch('RSPAMD_PORT', '11334') %>
ssl: false ssl: <%= ENV.fetch('RSPAMD_SSL', 'false') %>
password: null password: <%= ENV.fetch('RSPAMD_PASSWORD', '') %>
flags: null flags: <%= ENV.fetch('RSPAMD_FLAGS', '') %>
spamd: spamd:
enabled: false enabled: <%= ENV.fetch('SPAMD_ENABLED', 'false') %>
host: 127.0.0.1 host: <%= ENV.fetch('SPAMD_HOST', '127.0.0.1') %>
port: 783 port: <%= ENV.fetch('SPAMD_PORT', '783') %>
clamav: clamav:
enabled: false enabled: <%= ENV.fetch('CLAMAV_ENABLED', 'false') %>
host: 127.0.0.1 host: <%= ENV.fetch('CLAMAV_HOST', '127.0.0.1') %>
port: 2000 port: <%= ENV.fetch('CLAMAV_PORT', '2000') %>
smtp_client: smtp_client:
open_timeout: 30 open_timeout: <%= ENV.fetch('SMTP_CLIENT_OPEN_TIMEOUT', '30') %>
read_timeout: 60 read_timeout: <%= ENV.fetch('SMTP_CLIENT_READ_TIMEOUT', '60') %>

عرض الملف

@@ -1,45 +1,2 @@
module Postal module Postal
extend ActiveSupport::Autoload
eager_autoload do
autoload :AppLogger
autoload :BounceMessage
autoload :Config
autoload :Countries
autoload :DKIMHeader
autoload :Error
autoload :Helpers
autoload :HTTP
autoload :HTTPSender
autoload :Job
autoload :MessageDB
autoload :MessageInspection
autoload :MessageInspector
autoload :MessageInspectors
autoload :MessageParser
autoload :MessageRequeuer
autoload :MXLookup
autoload :QueryString
autoload :RabbitMQ
autoload :ReplySeparator
autoload :RspecHelpers
autoload :Sender
autoload :SendResult
autoload :SMTPSender
autoload :SMTPServer
autoload :SpamCheck
autoload :TrackingMiddleware
autoload :UserCreator
autoload :Version
autoload :Worker
end
def self.eager_load!
super
Postal::MessageDB.eager_load!
Postal::SMTPServer.eager_load!
Postal::MessageInspectors.eager_load!
end
end end

عرض الملف

@@ -1,3 +1,4 @@
require "erb"
require "yaml" require "yaml"
require "pathname" require "pathname"
require "cgi" require "cgi"
@@ -78,7 +79,11 @@ module Postal
end end
def self.defaults def self.defaults
@defaults ||= YAML.load_file(defaults_file_path) @defaults ||= begin
file = File.read(defaults_file_path)
yaml = ERB.new(file).result
YAML.safe_load(yaml)
end
end end
def self.database_url def self.database_url
@@ -152,7 +157,7 @@ module Postal
end end
def self.signing_key_path def self.signing_key_path
config_root.join("signing.key") ENV.fetch("POSTAL_SIGNING_KEY_PATH") { config_root.join("signing.key") }
end end
def self.signing_key def self.signing_key

عرض الملف

@@ -5,7 +5,7 @@ module Postal
def initialize(id, params = {}) def initialize(id, params = {})
@id = id @id = id
@params = params.with_indifferent_access @params = params
on_initialize on_initialize
end end
@@ -38,9 +38,5 @@ module Postal
job_id job_id
end end
def self.perform(params = {})
new(nil, params).perform
end
end end
end end

عرض الملف

@@ -1,20 +1,4 @@
module Postal module Postal
module MessageDB module MessageDB
extend ActiveSupport::Autoload
eager_autoload do
autoload :Click
autoload :Database
autoload :Delivery
autoload :LiveStats
autoload :Load
autoload :Message
autoload :Migration
autoload :Provisioner
autoload :Statistics
autoload :SuppressionList
autoload :Webhooks
end
end end
end end

عرض الملف

@@ -107,7 +107,7 @@ module Postal
# #
# Insert a new raw message into a table (creating it if needed) # Insert a new raw message into a table (creating it if needed)
# #
def insert_raw_message(data, date = Date.today) def insert_raw_message(data, date = Time.now.utc.to_date)
table_name = raw_table_name_for_date(date) table_name = raw_table_name_for_date(date)
begin begin
headers, body = data.split(/\r?\n\r?\n/, 2) headers, body = data.split(/\r?\n\r?\n/, 2)

عرض الملف

@@ -263,7 +263,7 @@ module Postal
return unless @pending_raw_message return unless @pending_raw_message
self.size = @pending_raw_message.bytesize self.size = @pending_raw_message.bytesize
date = Date.today date = Time.now.utc.to_date
table_name, headers_id, body_id = @database.insert_raw_message(@pending_raw_message, date) table_name, headers_id, body_id = @database.insert_raw_message(@pending_raw_message, date)
self.raw_table = table_name self.raw_table = table_name
self.raw_headers_id = headers_id self.raw_headers_id = headers_id

عرض الملف

@@ -94,7 +94,7 @@ module Postal
# Return a list of raw message tables that are older than the given date # Return a list of raw message tables that are older than the given date
# #
def raw_tables(max_age = 30) def raw_tables(max_age = 30)
earliest_date = max_age ? Date.today - max_age : nil earliest_date = max_age ? Time.now.utc.to_date - max_age : nil
[].tap do |tables| [].tap do |tables|
@database.query("SHOW TABLES FROM `#{@database.database_name}` LIKE 'raw-%'").each do |tbl| @database.query("SHOW TABLES FROM `#{@database.database_name}` LIKE 'raw-%'").each do |tbl|
tbl_name = tbl.to_a.first.last tbl_name = tbl.to_a.first.last
@@ -128,7 +128,7 @@ module Postal
#  Remove messages from the messages table that are too old to retain #  Remove messages from the messages table that are too old to retain
# #
def remove_messages(max_age = 60) def remove_messages(max_age = 60)
time = (Date.today - max_age.days).to_time.end_of_day time = (Time.now.utc.to_date - max_age.days).to_time.end_of_day
return unless newest_message_to_remove = @database.select(:messages, where: { timestamp: { less_than_or_equal_to: time.to_f } }, limit: 1, order: :id, direction: "DESC", fields: [:id]).first return unless newest_message_to_remove = @database.select(:messages, where: { timestamp: { less_than_or_equal_to: time.to_f } }, limit: 1, order: :id, direction: "DESC", fields: [:id]).first
id = newest_message_to_remove["id"] id = newest_message_to_remove["id"]

عرض الملف

@@ -1,12 +1,4 @@
module Postal module Postal
module MessageInspectors module MessageInspectors
extend ActiveSupport::Autoload
eager_autoload do
autoload :Clamav
autoload :Rspamd
autoload :SpamAssassin
end
end end
end end

عرض الملف

@@ -1,11 +1,4 @@
module Postal module Postal
module SMTPServer module SMTPServer
extend ActiveSupport::Autoload
eager_autoload do
autoload :Client
autoload :Server
end
end end
end end

50
script/send-html-email.rb Normal file
عرض الملف

@@ -0,0 +1,50 @@
# frozen_string_literal: true
# This script will automatically send an HTML email to the
# SMTP server given.
require 'mail'
require 'net/smtp'
from = ARGV[0]
to = ARGV[1]
if from.nil? || to.nil?
puts "Usage: ruby send-html-email.rb <from> <to>"
exit 1
end
mail = Mail.new
mail.to = to
mail.from = from
mail.subject = "A test email from #{Time.now.to_s}"
mail['X-Postal-Tag'] = 'send-html-email-script'
mail.text_part = Mail::Part.new do
body <<~BODY
Hello there.
This is an example. It doesn't do all that much.
Some other characters: őúéáűí
There is a link here through... https://postalserver.io/test-plain-text-link?foo=bar&baz=qux
BODY
end
mail.html_part = Mail::Part.new do
content_type 'text/html; charset=UTF-8'
body <<~BODY
<p>Hello there</p>
<p>This is an example email. It doesn't do all that much.</p>
<p>Some other characters: őúéáűí</p>
<p>There is a <a href='https://postalserver.io/test-plain-text-link?foo=bar&baz=qux'>link here</a> though...</p>
BODY
end
#puts mail.to_s
Net::SMTP.start('127.0.0.1', 2525) do |smtp|
smtp.send_message mail.to_s, mail.from.first, mail.to.first
end
puts "Sent"