- Add materialized views for list -> subscriber counts, dashboard chart,
and dashboard aggregate stats that slow down significantly on large
databases (with millions or tens of millions of subscribers). These
slow queries involve full table scan COUNTS().
- Add a toggle to enable caching slow results in Settings -> Performance.
- Add support for setting a cron string that crons and periodically
refreshes aggregated stats in materialized views.
Closes#1019.
- Add new 'Subscriptions' table on the subscriber list form that shows subs,
IP, and other data.
- Add new `meta` JSONB field to `subscriber_lsts` table.
Closes#1329.
- Change tiled UI to table UI.
- Add support for search and pagination.
- Important: This breaks the `GET /api/media` API to introduce pagination
fields. Media items are now moved into `{ data: results[] }`.
- Adds support for arbitrary file uploads with an admin setting to select allowed file extensions.
- Adds support for attaching media (files) to campaigns.
- Add support for `complaint` to the SES bounce processor.
- Add support for `hard/soft` to Sendgrid bounce processor.
- Add new bounce actions `None` and `Unsubscribe`.
- Add per type (`soft/hard/complaint`) bounce rule configuration to
admin settings UI.
- Refactor Cypress bounce tests.
- Introduces a new option on the settings UI to optionally publish the full campaign body in
public archive RSS feeds.
Closes#1033
Co-authored-by: Kailash Nadh <kailash@nadh.in>
Bots easily bypass the simple `nonce` hack. This commit adds support
for the hcaptcha.com widget.
- New `Security` tab in the admin settings UI.
- Enable/disable CAPTCHA.
- Render CAPTCHA on the public subscription form.
Closes#1116.
This commit adds a new API `POST /api/tx` that sends an ad-hoc message
to a subscriber based on a pre-defined transactional template. This is
a large commit that adds the following:
- New campaign / tx template types on the UI. tx templates have an
additional subject field.
- New fields `type` and `subject` to the templates table.
- Refactor template CRUD operations and models.
- Refactor template func assignment in manager.
- Add pre-compiled template caching to manager runtime.
- Pre-compile all tx templates into memory on program boot to avoid
expensive template compilation on ad-hoc tx messages.
- Add new `headers[]` column to the campain table.
- Add new headers box to the campaign UI that takes a JSON array of
custom headers like the headers on the SMTP settings UI.
- Headers are added to e-mails and messenger postback webhooks.
- Add cypress tests.
Closes#514.
- Add support for TLS in `smtppool` (v0.4.0) and upgrade the lib.
- Change `tls_enabled: bool` in the settings table to string
`tls_type: STARTTLS|TLS|none` and on the settings UI.
- Add DB migrations and schema changes to apply the field change.
Closes#504.
This feature was originally authored by @sweetppro in PR #438.
However, since the PR ended up in an unclean state with
multiple master merges (instead of rebase) from the upstream, there are
several commits that are out of order and can can no longer be be
squashed for a clean feature merge.
This commit aggregates the changes from the original PR and applies the
following fixes on top of it.
- Add custom admin JS box to appearance UI.
- Refactor i18n language strings.
- Add handlers and migrations for the new `appearance.admin.custom_js`
field.
- Fix migration version to `v2.1.0`
- Load custom appearance CSS/JS bytes into global constants during boot
instead of making a DB call on every request.
- Fix and canonicalize URIs from `/api/custom*` to `/public/*.css`
and `/admin/*.css`. Add proxy paths to yarn proxy config.
- Remove redundant HTTP handlers for different custom appearance files
and refactor into a single handler `serveCustomApperance()`
- Fix content-type and UTF8 encoding headers for different file types.
- Fix incorrect registration of public facing custom CSS/JS handlers
in the authenticated admin URI group.
- Fix merge conflicts in `Settings.vue`.
- Minor HTML and style fixes.
- Remove the `AppearanceEditor` component and use the existing
`HTMLEditor` component instead.
- Add `language` prop to the `HTMLEditor` component.
Co-authored-by: SweetPPro <sweetppro@users.noreply.github.com>
E-mails in the domain blocklist are disallowed on the admin UI, public
subscription forms, API, and in the bulk importer.
- Add blocklist setting that takes a list of multi-line domains on the
Settings -> Privacy UI.
- Refactor e-mail validation in subimporter to add blocklist checking
centrally.
- Add Cypress testr testing domain blocklist behaviour on admin
and non-admin views.
Closes#336.
- Add indexes.
- Refactor dashboard charts and view/click count queries.
(~10x speed bump on a setup of 7mn subscribers and 80mn views)
- Refactor get subscriber queries.
(~10x speed bump on 7mn subscribers)
- Make subscriber UI issue an equality query for email seach strings.
- Introduce a new S3 backend URL on the settings UI
- Add DB migration to populate S3 URL for existing S3 settings
- Refactor and fix URL formatting
Closes#139
- Blocklist or unsubscribe subscribers based on a bounce threshold
- Add /bounces UI for viewing bounces and in the subscriber view
- Add settings UI for managing bounce settings
- Add support for scanning POP3 bounce mailboxes
- Add a generic webhook for posting custom bounces at /webhooks/bounce
- Add SES bounce webhook support at /webhooks/services/ses
- Add Sendgrid bounce webhook support at /webhooks/services/sendgrid
In addition to generating HTML forms for selected public lists,
the form page now shows a URL (/subscription/form) that can be
publicly shared to solicit subscriptions. The page lists all
public lists in the database. This page can be disabled on the
Settings UI.
This commit removes the Go html2text lib that would automatically
convert all HTML messages to plaintext and add them as the alt
text body to outgoing e-mails. This lib also had memory leak
issues with certain kinds of HTML templates.
A new UI field for optionally adding an alt plaintext body to
a campaign is added. On enabling, it converts the HTML message in
the campaign editor into plaintext (using the textversionjs lib).
This introduces breaking changes in the campaigns table schema,
model, and template compilation.
Certain SMTP hosts limit the total number of messages that can be
sent within a window, for instance, X / 24 hours. The concurrency
and message rate controls can only limit that to a max of
1 messages / second, without a global cap.
This commit introduces a simple sliding window rate limit feature
that counts the number of messages sent in a specific window, and
upon reaching that limit, waits for the window to reset before
any more messages are pushed out globally across any number of
campaigns.
Context: https://github.com/knadh/listmonk/issues/119
The link_clicks.link_id table was NULLable incorrectly. Links that
do not exist should not register a tracking entry. Fix the query
and also update the schema + migration (breaking table change).
A new toggle switch in Settings -> Privacy, which is off by
default, allows campaign views (pixel) and link clicks to function
without registering the subscriber ID against view and click
events, anonymising tracking. When off, the subscriber UUIDs in
view and link tracking URLs are removed, anonymising subscriber
information from HTTP logs as well.
- On boot, the app now checks if the DB version matches its
expected version and refuses to start if there are pending
migrations to be run.
- The new `--upgrade` flag runs data migrations from the last
recorded migration (in the settings table) to the latest one
in the binary.
- Migrations are DB/arbitrary logic functions in .go files in
internal/migrations.
- All migration functions are idempotent.