Commit graph

181 commits

Author SHA1 Message Date
Kailash Nadh
20e4b100ca Fix DB state issues in visual campaign cloning. 2025-04-20 20:48:51 +05:30
Kailash Nadh
f1fbadf6a6 Fix incorrect template states in DB in campaign creation and broken preview. 2025-04-20 20:48:51 +05:30
Kailash Nadh
c1f81cfadd Fix compatibility issues with master.
- Fix merge conflicts.
- Simply logic in campaign preview handler.
- Remove redundant `GetCampaignForPreviewWithTemplate()` and switch to the old
  query that optionally takes a template.
- Fix Vue linting issues.
2025-04-20 20:48:51 +05:30
Vivek R
4a524c9332 feat: Integrate media selector to visual editor and add minor fixes.
- Disable visual templates from being made default.
- Refactor visual template selection flow in campaigns.
- Hide scroll if templates modal is active. This is to make sure it doesn't
  flicker when adding blocks in visual-editor.
2025-04-20 20:48:51 +05:30
Vivek R
ae98280858 feat: Integrate email-builder on campaign/template editor UI and backend. 2025-04-20 20:48:51 +05:30
Kailash Nadh
4b805f885b Fix broken subscribers:sql_query permission.
This permission was never checked for and had an unintended consequence of
allowing a non-superadmin user to execute arbitrary queries (expected), but
getting a superadmin session by joining the `sessions` table.

This patch:
- Introduces a table allowlist that uses the Postgres query plan (JSON)
  and validate the referenced tables against the allowed ones on arbitrary
  queries issued to the various `/subscribers` APIs.
- Explicitly adds the missing `subscribers:sql_query` permission check to all
  handlers that accept `query`.
- Introduces a new `search` parameter on all handlers that accept `query`.
  This parameter is an interface over the default name/email substring search
  instead of relying on `query`.
2025-04-18 14:15:47 +05:30
Kailash Nadh
562e52cd22 Introduce LISTMONK_ADMIN_API_USER to --install. Closes #2314, #2322.
- During install, listmonk now accepts the env `LISTMONK_ADMIN_API_USER`
  and creates an API user (with username $LISTMONK_ADMIN_API_USER)
  with full superadmin permissions. This requires LISTMONK_ADMIN_USER and
  LISTMONK_ADMIN_API_PASSWORD to be set so that that there's always a superadmin
  user to avoid bad states, mainly: bot superadmin exists, but no admin user
  exists, leaving the installation perpetually open with the superadmin user
  creation UI on the first login.
  The API user's token is printed to stderr in the following format:
  `export LISTMONK_ADMIN_API_TOKEN="7I81VSd90UWhKDj5Kq9c6YopToRduyDF"`
  This can be redirected to a file with ./listmonk 2> /tmp/token or captured
  directly and then source()'d.
- Add new function `core.GetRole(id)`.
- Fix `at least one super admin` query in user deletion.
2025-04-10 13:06:04 +05:30
Kailash Nadh
a271bf54d5 Introduce per-campaign filter permissions. Closes #2325.
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.
2025-03-31 16:39:42 +05:30
Kailash Nadh
a5f8b28cb1 Fix inconsistent behaviour in campaign scheduling on the UI.
- Fix status/button state management issues when `Send at` was toggled
  under various scenarios.
- Allow paused campaigns to be edited and turned into scheduled campaigns.
- Add Cypress UI tests for unscheduling.
2025-03-31 13:00:51 +05:30
Kailash Nadh
e4a18dabc3 Remove forcing unique filename on all media uploads.
This patch removes the forced suffixing of all media upload filenames with
random strings. The upload handler now checks the `media` table to ensure that
the filename being uploaded doesn't exist before forcing a suffix.

Outright rejecting duplicate filenames cannot be done to maintain backwards
compatibility with the old behaviour.

Closes #2277.
2025-03-29 15:21:32 +05:30
Kailash Nadh
a9869612dc Disallow private list UUIDs on public sub endpoints. Closes #2296. 2025-03-12 22:00:35 +05:30
Kailash Nadh
5ba0adcb0b Automatically switch scheduled campaigns to draft when send_at date it removed. 2025-01-19 16:35:16 +05:30
Kailash Nadh
61c6b7e15a Add explicit Unschedule button on campaign UI. 2025-01-19 16:27:39 +05:30
Kailash Nadh
5c0de6ef0b Fix broken sorting lists by subscriber_count. Closes #2151. 2024-12-04 22:40:13 +05:30
Kailash Nadh
178fa94880 Update user login time on password login. 2024-10-26 23:56:12 +05:30
Kailash Nadh
1e4b3a26f2 Separate get individual user and get all users queries. 2024-10-26 17:03:02 +05:30
Kailash Nadh
887d5823f4 Fix get-users query to return all users when no ID param is given. 2024-10-21 23:20:07 +05:30
Kailash Nadh
1075485ca9 Merge branch 'fix-user-query' 2024-10-21 17:57:28 +05:30
Kailash Nadh
e7109daaf3 Fix missing email validation in OIDC exchange. 2024-10-21 17:54:58 +05:30
Kailash Nadh
7847167145 Fix incorrect id logic in user selection. 2024-10-20 23:50:06 +05:30
Kailash Nadh
cea65c009d Fix and refactor subscriber batch fetching in campaign processing.
This has been a hair-pulling rabbit hole of an issue. #1931 and others.
When the `next-campaign-subscribers` query that fetches $n subscribers
per batch for a campaign returns no results, the manager assumes
that the campaign is done and marks as finished.

Marathon debugging revealed fundamental flaws in qyery's logic that
would incorrectly return 0 rows under certain conditions.
- Based on the "layout" of subscribers for eg: a series of blocklisted
  subscribers between confirmed subscribers.
  A series of unconfirmed subscribers in a batch belonging to a double
  opt-in list.
- Bulk import blocklisting users, but not marking their subscriptions
  as 'unsubscribed'.
- Conditions spread across multiple CTEs resulted in returning an
  arbitrary number of rows and $N per batch as the selected $N rows
  would get filtered out elsewhere, possibly even becoming 0.

After fixing this and testing it on our prod instance that has
15 million subscribers and ~70 million subscriptions in the
`subscriber_lists` table, ended up discovered significant inefficiences
in Postgres query planning. When `subscriber_lists` and campaign list IDs
are joined dynamically (CTE or ANY() or any kind of JOIN that involves)
a query, the Postgres query planner is unable to use the right indexes.

After testing dozens of approaches, discovered that statically passing
the values to join on (hardcoding or passing via parametrized $1 vars),
the query uses the right indexes. The difference is staggering.
For the particular scenario on our large prod DB to pull a batch,
~15 seconds vs. ~50ms, a whopping 300x improvement!

This patch splits `next-campaign-subscribers` into two separate queries,
one which fetches campaign metadata and list_ids, whose values are then
passed statically to the next query to fetch subscribers by batch.

In addition, it fixes and refactors broken filtering and counting logic
in `create-campaign` and `next-campaign` queries.

Closes #1931, #1993, #1986.
2024-10-13 17:03:59 +05:30
Kailash Nadh
ee119b0088 Fix import not 'unsubscribing' list subs for already blacklisted subscribers. Ref #1931. 2024-10-13 17:03:59 +05:30
Kailash Nadh
0331e3ce4e Sory users by created_at always. 2024-10-13 17:03:59 +05:30
Kailash Nadh
eb47e80c35 Fix list auth by adding an explicit 'getAll' flag to query. 2024-10-13 17:03:59 +05:30
Kailash Nadh
ae2a386193 Add support for "list roles".
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.
2024-10-13 17:03:58 +05:30
Kailash Nadh
12a6451ed0 Add list permission check to subscriber calls. 2024-10-13 17:03:55 +05:30
Kailash Nadh
d74e067961 Add per-list permission to list management.
- Filter lists by permitted list IDs in DB get calls.
- Split getLists() handlers into two (one, all) for clarity.
- Introduce new `subscribers:get_by_list` permission.
- Tweak UI rendering to work with new per-list permssions.
2024-10-13 16:59:52 +05:30
Kailash Nadh
1649b3b135 Fix logic for preventing sole super admin from being wrongly updated/deleted. 2024-10-13 16:59:52 +05:30
Kailash Nadh
5024ded763 Add API user authentication to auth module with caching of creds on user CRUD. 2024-10-13 16:59:52 +05:30
Kailash Nadh
1e875afa67 Add OIDC auth hooks (init, callback, session) and finish OIDC support. 2024-10-13 16:59:52 +05:30
Kailash Nadh
17b5cc1774 Sort roles by created date. 2024-10-13 16:59:52 +05:30
Kailash Nadh
d52eac0948 Update user APIs and queries to embed role + list permissions. 2024-10-13 16:59:52 +05:30
Kailash Nadh
612c1d6eac Add per-list permission management to roles. 2024-10-13 16:59:52 +05:30
Kailash Nadh
dd9612b1ed Add user profile based permission check in auth middleware. 2024-10-13 16:59:52 +05:30
Kailash Nadh
32d5823dfe Refactor 'super' user type to a pre-defined super admin role. 2024-10-13 16:59:52 +05:30
Kailash Nadh
d4e4c5fa99 Add granular permissions and role management to backend and admin UI. 2024-10-13 16:59:51 +05:30
Kailash Nadh
4997c10b97 Add user profile APIs and update UI. 2024-10-13 16:59:51 +05:30
Kailash Nadh
57ac9dca4b Add public login page and auth middleware and handlers. 2024-10-13 16:59:51 +05:30
Kailash Nadh
1516bf216f Add api type user. 2024-10-13 16:59:51 +05:30
Kailash Nadh
bf0b500bb0 Add API token authentication. 2024-10-13 16:59:51 +05:30
Kailash Nadh
0968e58766 Add user/password login handler. 2024-10-13 16:59:51 +05:30
Kailash Nadh
435d6d5169 Add create/add/delete user management UI and database schema. 2024-10-13 16:59:51 +05:30
Bowrna
16f4dfd3e9
Fix incorrect bulk blocklisting behaviour (#2041). Fixes #1841 2024-09-19 10:56:56 +05:30
Kailash Nadh
51e3f1789b Fix pre-confirm status not working on subscriber update. Closes #1927. 2024-09-03 23:39:02 +05:30
Bowrna
ebac8b3b4c
Fix broken campaign clone with deleted lists (#1966)
Co-authored-by: Kailash Nadh <kailash@nadh.in>
2024-08-02 21:33:43 +05:30
Keshav Gupta
c334d2e6e1
fix #1950:Export of unsubscribed users exports all users (#1965)
Co-authored-by: keshav <keshav.gupta@jarvis.consulting>
2024-08-02 00:05:33 +05:30
Kailash Nadh
fedc51514d Fix incorrect count in subscriber query when there are no results. 2024-08-02 00:03:22 +05:30
zevszym
b38f1562ee
fix vanishing attachments in campaign in more the one campaigns setup (#1936) 2024-07-17 10:42:51 +05:30
Shivam Mishra
ec50bef292
fix: query campaign does not search numbers (#1758) 2024-03-08 09:48:34 +05:30
Kailash Nadh
284158666b Fix sorting in camapaign analytics view counts. 2024-01-28 10:59:51 +05:30