- Introduce a new API endpoint for counting subscribers matching a SQL snippet.
- Implement the HandleCountSQLSnippet function in the backend.
- Add frontend API call for counting SQL snippets with loading and error handling.
- Enhance SQL Snippets view with live validation and autocomplete for SQL snippets.
- Update navigation and UI elements for better user experience.
- Add SQL snippets table and migration
- Create CRUD operations for managing reusable SQL query fragments
- Add frontend UI for SQL snippets management
- Include query validation and syntax highlighting
- Add navigation menu integration
- Requires subscribers:sql_query permission
This is the first part of a larger feature split from dynamic segments.
This patch significantly cleans up clunky, repetitive, and pervasive
validation logic across HTTP handlers.
- Rather than dozens of handlers checking and using strconv to validate ID,
the handlers with `:id` are now wrapped in a `hasID()` middleware that does
the validation and sets an int `id` in the handler context that the wrapped
handlers can now access with `getID()`.
- Handlers that handled both single + multi resource requests
(eg: GET `/api/lists`) with single/multiple id checking conditions are all now
split into separate handlers, eg: `getList()`, `getLists()`.
- Attach all HTTP handlers to a new `Handlers{}` struct.
- Remove all `handle*` function prefixes.
- Remove awkward, repetitive `app = c.Get("app").(*App)` from all handlers
and instead, simply access it from `h.app` from `Handlers{}`
Originally proposed in #2292.
- Make the beginning of handlers consistent with uniform variable declaration
and grouping.
- Add missing comments.
- Fix staticcheck/vet warnings and idiom issues.
This patch introduces new `campaigns:get_all` and `campaigns:manage_all`
permissions which alter the behaviour of the the old `campaigns:get` and
`campaigns:manage` permissions. This is a subtle breaking behavioural change.
Old:
- `campaigns:get` -> View all campaigns irrespective of a user's list
permissions.
- `campaigns:manage` -> Manage all campaigns irrespective of a user's list
permissions.
New:
- `campaigns:get_all` -> View all campaigns irrespective of a user's list
permissions.
- `campaigns:manage_all` -> Manage all campaigns irrespective of a user's list
permissions.
- `campaigns:get` -> View only the campaigns that have at least one list to
which which a user has get or manage access.
- `campaigns:manage` -> Manage only the campaigns that have at list one list
to which a user has get or manage access.
In addition, this patch refactors and cleans up certain permission related
logic and functions.
This commit splits roles into two, user roles and list roles, both of which
are attached separately to a user.
List roles are collection of lists each with read|write permissions, while
user roles now have all permissions except for per-list ones.
This allows for easier management of roles, eliminating the need to clone and
create new roles just to adjust specific list permissions.
- `GET /api/events?type=error` opens a long-lived HTTP server side
event connection that streams error messages.
- async (typically SMTP) errors are now streamed to the frontend and
disaplyed as an error toast on the admin UI.
- 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>
- Add `/api/public/lists` that returns the list of public lists, same
information revealed on the `/subscription/form` page.
- Add `/api/public/subscription` that accepts a JSON POST for a
subscription signup same as `/subscription/form`.
Closes#910.
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.
This is a long pending refactor. All the DB, query, CRUD, and related
logic scattered across HTTP handlers are now moved into a central
`core` package with clean, abstracted methods, decoupling HTTP
handlers from executing direct DB queries and other business logic.
eg: `core.CreateList()`, `core.GetLists()` etc.
- Remove obsolete subscriber methods.
- Move optin hook queries to core.
- Move campaign methods to `core`.
- Move all campaign methods to `core`.
- Move public page functions to `core`.
- Move all template functions to `core`.
- Move media and settings function to `core`.
- Move handler middleware functions to `core`.
- Move all bounce functions to `core`.
- Move all dashboard functions to `core`.
- Fix GetLists() not honouring type
- Fix unwrapped JSON responses.
- Clean up obsolete pre-core util function.
- Replace SQL array null check with cardinality check.
- Fix missing validations in `core` queries.
- Remove superfluous deps on internal `subimporter`.
- Add dashboard functions to `core`.
- Fix broken domain ban check.
- Fix broken subscriber check middleware.
- Remove redundant error handling.
- Remove obsolete functions.
- Remove obsolete structs.
- Remove obsolete queries and DB functions.
- Document the `core` package.
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>
- echo is now on v4 with major changes including a few breaking changes
- bind() behaviour is now strict. JSON / form etc. unmarshalling of
request data need appropriate `json`, `form` tags. Missing tags for
the public subscription page is added in this commit.
- This also closes#602.
BasicAuth without an explicit landing page or a logout option has
sometimes been confusing to users. This commit adds a static
landing page on / with a login link and a logout option in the admin
that "logs out" BasicAuth session by posting invalid credentials to
the server to obtain a 401.
- Namespace all admin UI URLs behind `/admin/*`.
This breaks the current admin UI URLs.
- Make Vue output build assets to `frontend/dist/*` instead of
`frontend/dist/frontend`.
- Namespace Vue static assets to `/admin/static/*`.
This commit reduces the cofusing and convoluted Vue+WebPack build URI
and static path schemes. In addition, it removes ambiguity in URLs
where non-UI URLs like `/public`, `/api`, `/webhooks` etc. were in the
same name space as UI URLs like `/campaigns`, `/lists` etc. Now all UI
URLs are behind `/admin/`, also simplifying security rules for proxies.
- 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
- Adds `/health` as a public facing healthcheck endpoint.
- `/api/health` is meant for internal healthchecks. This endpoint in
future can serve sensitive information about Listmonk *or* can be
deprecated if there's not enough usecase.
Closes https://github.com/knadh/listmonk/issues/380
Previously, converting between formats simply copied over raw content.
This update does actual conversion between different formats. While
lossy, this seems to a good enough approximation for even reasonbly
rich HTML content. Closes#348.
- richtext, html => plain
Strips HTML and converts content to plain text.
- richtext, html => markdown
Uses turndown (JS) lib to convert HTML to Markdown.
- plain => richtext, html
Converts line breaks in plain text to HTML breaks.
- richtext => html
"Beautifies" the HTML generated by the WYSIWYG editor unlike the
earlier behaviour of dumping one long line of HTML.
- markdown => richtext, html
Makes an API call to the backend to use the Goldmark lib to convert
Markdown to HTML.