Commit Graph

1057 Commits

Author SHA1 Message Date
Steve Larson
f577aafa52
🐛 Fixed malformed unsubscribe_url in members api response (#21437)
no ref
2024-10-28 09:58:09 -05:00
Steve Larson
2e0293c99f
🐛 Fixed NQL filters for single letter slugs (#21340)
fixes https://github.com/TryGhost/Ghost/issues/20133
- includes fix to support single letter slugs
2024-10-17 15:35:26 +00:00
Steve Larson
63f25ece6d
Added unsubscribe_url to member api response (#21207)
ref https://linear.app/tryghost/issue/ONC-387/

With some recent changes, we added validation to unsubscribe URLs to verify the source, allowing us to cut down on spam and improving security, as the underlying key could be re-generated should the need arise. This had the side effect of making unsubscribe URLs difficult to reconstruct when using third-party/downstream integrations, such as ActiveCampaign, which fills a gap in the current Ghost feature set.

Now any authenticated query to `/api/members` will return an `unsubscribe_url` field that can be used directly.
2024-10-16 14:00:31 -05:00
Daniel Lockyer
de5dcb8189 Fixed treeshaking and require size for date-fns
- we don't need to require the entire package and this costs 5% of our
  boot time
- this commit bumps NQL to the latest version, which fixes the requires
  to help with treeshaking and loading less code
2024-10-09 17:03:04 +01:00
renovate[bot]
62d7b7ea52 Update dependency express to v4.21.1 2024-10-08 21:53:17 +01:00
Princi Vershwal
773f514ddb
🎨 Added a maximum limit of 100 for GET members admin endpoint (#20643)
Ref: https://linear.app/tryghost/issue/SLO-188/set-a-maximum-limit-for-get-members-api

Endpoint: ghost/api/admin/members/?limit=all

Change Overview: We are updating the GET ghost/api/admin/members/ endpoint to remove support for the limit=all parameter. Previously, a request like GET ghost/api/admin/members/?limit=all would return a list of all members. Going forward, any request with limit=all or a limit greater than 100 will only return up to 100 members per request.
This change aims to improve the performance and scalability of the API.

What changes for users? - They will have to implement pagination to retrieve the list of all members.
2024-09-18 11:17:56 +00:00
renovate[bot]
3d65690987 Update dependency jwk-to-pem to v2.0.6 2024-09-17 14:13:00 +02:00
Sag
430fbdb987
🐛 Fixed member filtering for "Unsubscribed from newsletter" filters (#20926)
ref https://linear.app/tryghost/issue/ENG-1466
ref https://linear.app/tryghost/issue/ENG-1484

- Previously, filtering members with multiple "Unsubscribed from
newsletter x" led to no filtering at all, all members were returned
- This was caused by a bug in NQL, that is fixed in version 0.12.5, cf.
[commit](dd18d1d6ca)
- We're also removing the safeguard in the product around bulk deletion
when multiple newsletter filters are in use, as the root problem has
been fixed
2024-09-16 11:16:49 +02:00
renovate[bot]
43a392d734 Update dependency express to v4.21.0 2024-09-12 07:37:27 +02:00
Sirichai Chulee
58ca6f3d95
Updated uuid to crypto.randomUUID() (#20821)
The uuid package README suggests using the node builtin `crypto` library if
we're only using uuid.v4, which we are.
2024-09-12 09:09:30 +07:00
renovate[bot]
979e704410 Update dependency express to v4.20.0 2024-09-11 08:21:15 +02:00
Princi Vershwal
b14b44faa4
ENG-1526 Added logs and sentry messages in Router Controller (#20955)
Ref:
https://linear.app/tryghost/issue/ENG-1526/errors-from-members-api-routercontroller-are-being-lost

The try/catch/re-throw pattern, that hides errors, is used throughout
the RouterController.js file.
I have not changed the try/catch/re-throw pattern because it helps in
sending clean messages to the users. We may not want to return internal
errors as API responses.
I have added logs and Sentry messages that will help us debug without
losing error messages.
2024-09-10 16:47:12 +05:30
renovate[bot]
d3cf1045f5 Update dependency body-parser to v1.20.3 2024-09-10 00:22:39 +00:00
Sam Lord
9ca513bfdd Added logging when honeypot field is hit
ref KTLO-1
2024-08-22 22:32:04 +01:00
Sam Lord
56a9fa34af Fixed names of tests for Portal honeypot field
ref KTLO-1
2024-08-22 22:32:04 +01:00
Sam Lord
0a9d2fadba Added honeypot field to prevent bot signup/signin
ref KTLO-1
Should prevent untargeted attacks using headless browser bots.
2024-08-22 22:32:04 +01:00
Princi Vershwal
f984fbd47e
🎨 Improved the performance of the /members/events/ aggregated_click_event endpoint (#20790)
Ref https://linear.app/tryghost/issue/ONC-216/improve-the-performance-of-the-membersevents-aggregated-click-event
2024-08-22 18:26:10 +05:30
Princi Vershwal
309cb37cc6
Updated nql package (#20811)
Ref [ONC-216](https://linear.app/tryghost/issue/ONC-216/improve-the-performance-of-the-membersevents-aggregated-click-event)

Needed changes in nql package for this task.
2024-08-22 07:55:14 +00:00
Steve Larson
9f4bc9c132
Added Sentry message logging for generating magic links (#20789)
ref https://linear.app/tryghost/issue/ONC-258
2024-08-19 21:28:15 +00:00
renovate[bot]
4b28812861 Update TryGhost packages 2024-08-05 12:12:34 +02:00
Princi Vershwal
086ed9e7a9
Optimising count query : Added option param to skip distinct from count query for members events API (#20700)
Ref:
https://linear.app/tryghost/issue/ENG-1470/improve-the-performance-of-the-membersevents-aggregated-click-event
2024-08-01 13:14:40 +05:30
Princi Vershwal
bb33a84058
Optimising count query : Added option param to skip distinct from count query for members events API
Ref https://linear.app/tryghost/issue/SLO-193/optimise-count-query-skip-distinct-from-count-query-for-members-events

The member events endpoint have many queries like:-

select count(distinct members_subscribe_events.id) as aggregate 
from `members_subscribe_events` 
where `members_subscribe_events`.`created_at` < '2024-07-30 11:30:39'

In these queries, distinct is not required as id is a primary key. Skipping distinct would improve the performance. 

This PR will changed the query to:-

select count(*) as aggregate 
from `members_subscribe_events` 
where `members_subscribe_events`.`created_at` < '2024-07-30 11:30:39'
2024-07-31 09:37:34 +05:30
Sag
e476eebd2d
🎨 Added staff notification when a sub is canceled due to failed payments (#20534)
ref https://linear.app/tryghost/issue/ENG-1254

- when a subscription is canceled automatically by Stripe (e.g. due to
multiple failed payments), we now send a staff notification
- logic before: if a member cancels a sub in Portal, then send a staff
notification
- logic now: if a subscription was active, but is now set to cancel
immediately or at the end of the billing period, then send a staff
notification.
- with that logic change, we now send a cancellation staff notification
when:
    1. A member cancels their sub in Portal (existing)
    2. A staff member cancels a member sub in Stripe (new)
    3. A staff member cancels a member sub in Admin (new)
    4. A sub is canceled automatically by Stripe because of multiple failed
payments (new)
- the copy of the staff notification email has also been updated to take
into account 1) manual vs automatic cancellations, and 2) immediate vs
end of billing period cancellations
2024-07-15 08:07:18 +02:00
Chris Raible
bf895e6e99
🐛 Fixed offer redemptions for free members redeeming an offer (#20571)
ref
https://linear.app/tryghost/issue/ENG-1251/support-escalation-re-offers-not-tracking

- Offer Redemptions were not being persisted in the database for
existing free members who upgrade to a paid plan with an offer, which
resulted in inaccurate offer redemption counts. This made it difficult
to assess the performance of an offer.
- Previously, Ghost recorded an offer redemption in the DB in response
to the `SubscriptionCreatedEvent`, under the assumption that the offer
details would be included in this event. This assumption was valid for
brand new members starting a subscription with an offer, but not for
existing free members upgrading to a paid plan with an offer.
- For existing free members, the subscription is first stored in Ghost
in response to the `customer.subscription.created` Stripe webhook. At
this point, the offer/discount is not attached to the subscription, so
the `SubscriptionCreatedEvent` triggers without the offer information,
and the offer redemption is not recorded. After the
`checkout.session.completed` webhook is received (which _does_ include
the offer details), the subscription is updated in Ghost, but the Offer
Redemption is not stored.
- For brand new members, the `customer.subscription.created` webhook
no-ops, because the member and Stripe Customer don't exist yet.
Therefore, the subscription is first created in Ghost in response to the
`checkout.session.completed` webhook, which _does_ include the offer
information, so the offer information is included in the
`SubscriptionCreatedEvent` and the offer redemption is recorded as
expected.
- This change adds a new `OfferRedemptionEvent`, which triggers
either: (1) when a new subscription is created with an offer (as in the
case of a brand new member), or (2) when an existing subscription is
first updated to include an offer (as in the case of an existing free
member upgrading with an offer). The Offer Redemption is then persisted
in the DB in response to the `OfferRedemptionEvent` rather than the
`SubscriptionCreatedEvent`.
2024-07-09 16:05:26 -07:00
Sag
6e0b009034
🎨 Added 'Payment failed' subscription cancellation reason (#20527)
ref https://linear.app/tryghost/issue/ENG-1254

- we currently only store a cancellation reason when a member cancels
manually in Portal
- we now also store "Payment failed" when the cancellation is automatic
due to several payment failures
2024-07-03 13:12:01 +02:00
Sag
7f963e9c2a
🎨 Added 'Changed email address' event to Member Activity (#20493)
fixes https://linear.app/tryghost/issue/ENG-1256

- when a member changes their email address, surface it in Member
Activity
2024-07-01 15:33:33 +00:00
Princi Vershwal
7bffe5b79a
Added option param to skip distinct from count query for members API
ref https://linear.app/tryghost/issue/SLO-173/removed-distinct-from-member-count-query

Performance of GET /members API can be improved by dropping the distinct from the total members count query.

select count(distinct members.id) as aggregate from `members`; // 275ms
select count(*) as aggregate from `members`; // 30ms

In this case we know that the result set will always be unique.
2024-06-27 17:35:19 +05:30
Sag
725ebc3e9f
Fixed invalid tierId handling during member paid checkout (#20455)
- fixes https://linear.app/tryghost/issue/SLO-90
2024-06-24 15:33:39 +00:00
Michael Barrett
7f92777f89
Added logging to track offer redemption (#20329)
refs
[ONC-56](https://linear.app/tryghost/issue/ONC-56/support-escalation-re-offers-not-tracking)

Added logging to track offer redemption logic to debug issue with offer
redemptions tracking incorrectly
2024-06-05 17:48:43 +01:00
Sag
d751d648c7
Fixed offer not found case during Stripe checkout (#20322)
fixes https://linear.app/tryghost/issue/SLO-135

- handles edge cases when an invalid `offerId` is provided during Stripe
checkout
2024-06-04 10:27:45 +00:00
renovate[bot]
3ebe206ea7 Update TryGhost packages 2024-05-27 16:58:32 +02:00
Steve Larson
842290cbef
Improved performance for filter strings with multiple neq statements (#20198)
ref https://linear.app/tryghost/issue/CFR-27
- updated packages to include performance improvement for NQL filter
strings including multiple neq filters for the same resource
- bumped `bookshelf-plugins`
- bumped NQL versions

We identified a performance fix that allows us to combine not equal
(neq) filters for the same resource in a logically-equivalent way that
also has far more performant resulting SQL.

We're effectively automatically combining strings like
'tag:-tag1+tag:-tag2` into 'tag:-[tag1,tag2]'.
2024-05-13 10:35:27 -05:00
Sag
cb8213e7d3
Fixed validation when tierId is missing during Stripe checkout (#20195)
refs https://linear.app/tryghost/issue/SLO-90
refs
https://www.notion.so/ghost/Decoupling-Members-from-Stripe-13b644d4dccb43ea83f683473c690b82

- the members API didn't support passing a Stripe Price ID directly
during checkout since end of 2022. However, we did not update the param
validation accordingly
2024-05-13 14:47:39 +02:00
Fabien 'egg' O'Carroll
56d984f05f
Used subscription currency for setup session (#19991)
ref https://linear.app/tryghost/issue/ENG-812
ref https://github.com/TryGhost/Ghost/commit/5b694761bc

We wanna use the currency of the subscription to avoid the edge-case where the 
subscription currency doesn't match the sites current tiers currency.
2024-05-09 13:03:11 +00:00
Sag
60ac3c735b
🐛 Fixed updating payment method when beta flag is on (#20171)
refs https://linear.app/tryghost/issue/ONC-20
refs https://linear.app/tryghost/issue/ENG-867

- when using dynamic payment methods in Stripe, we need to provide a
currency. Stripe uses that parameter to determine which payment methods
to render
- docs: https://docs.stripe.com/api/checkout/sessions/create
2024-05-08 20:56:17 +02:00
Daniel Lockyer
265a8dd16f Added function names to more middleware
refs 319f251ad2

- this helps debugging because all middleware in the stack will have a
  function name, so it'll show up instead of `<anonymous>`
2024-05-06 17:51:39 +02:00
Chris Raible
b9f7ea65e9
Revert "Added new member signup flow behind labs flag (#19986)" (#20130)
ref https://linear.app/tryghost/issue/KTLO-1/members-spam-signups

This reverts commit 01d0b2b304.

- Removed the new member signup flow because it didn't solve the
problems with spam signups
2024-05-02 13:02:32 -07:00
renovate[bot]
a33dccf8cd Update TryGhost packages 2024-05-01 17:01:41 +02:00
Daniel Lockyer
3f7a7fff44 Fixed HTTP 500 when adding unknown products to member
fix https://linear.app/tryghost/issue/SLO-89/cannot-read-properties-of-null-reading-get-an-unexpected-error

- if we pass an invalid ID when updating the products on a member, we
  throw a HTTP 500 error because `product` is `null`
- we can check for this and return a BadRequestError, because the user
  supplied an incorrect ID
2024-05-01 16:54:35 +02:00
Daniel Lockyer
31bdef94cd Handled invalid filters in members event repository
fix https://linear.app/tryghost/issue/SLO-82/query-error-unexpected-character-in-filter-at-char-1

- previously, we weren't handling a parsing error, and just bubbling it
  back up the chain
- this would result in an InternalServerError somewhere, which caused
  500s
- we can handle this, because it's just a bad filter
- this adds handling so we return a 422 upon receiving an invalid filter
2024-05-01 11:58:09 +02:00
renovate[bot]
60a3b5a913 Update TryGhost packages 2024-05-01 08:49:04 +02:00
renovate[bot]
8f839b34b1 Update Types packages 2024-04-30 22:00:55 +02:00
Chris Raible
01d0b2b304
Added new member signup flow behind labs flag (#19986)
ref https://linear.app/tryghost/issue/KTLO-1/members-spam-signups

- Some customers are seeing many spammy signups ("hundreds a day") — our
hypothesis is that bots and/or email link checkers are able to signup by
simply following the link in the email without even loading the page in
a browser.
- Currently new members signup by clicking a magic link in an email,
which is a simple GET request. When the user (or a bot) clicks that link, Ghost
creates the member and signs them in for the first time.
- This change, behind an alpha flag, requires a new member to click the
link in the email, which takes them to a new frontend route `/confirm_signup/`, then submit a form on the page which sends a POST request to the
server. If JavaScript is enabled, the form will be submitted
automatically so the only change to the user is an extra flash/redirect
before being signed in and redirected to the homepage.
- This change is behind the alpha flag `membersSpamPrevention` so we can
test it out on a few customer's sites and see if it helps reduce the
spam signups. With the flag off, the signup flow remains the same as
before.
2024-04-04 15:25:41 -07:00
renovate[bot]
dcbbfbba70 Update dependency express to v4.19.2 [SECURITY] 2024-03-27 11:18:44 +01:00
Simon Backx
3b8fb3cedf
Added support for ignoring migrated (duplicate) subscriptions (#19902)
refs KTLO-19

When we need to migrate subscriptions from a platform with platform
fees, we need to recreate the subscriptions. That can cause the same
subscription to be attached multiple times to the same member in Ghost.

This is a problem because all MRR, subscriptions and cancellations stats
are no longer correct. Ghost will add a MRR event for the duplicated
subscription from the start time, so there is a sudden peak in MRR and a
dip after the migration because all those duplicate subscriptions are
suddenly cancelled 'today'.

The migrator tool adds a ghost_migrated_to metadata field to the old
subscription. Ghost can use this to detect the old subscription and
delete the subscription and corresponding events.
2024-03-27 10:32:32 +01:00
Steve Larson
a1c4e64994
Added queueing middleware to handle high request volume (#19887)
ref https://linear.app/tryghost/issue/CFR-4/
- added request queueing middleware (express-queue) to handle high
request volume
- added new config option `optimization.requestQueue`
- added new config option `optimization.requestConcurrency`
- added logging of request queue depth - `req.queueDepth`

We've done a fair amount of investigation around improving Ghost's
resiliency to high request volume. While we believe this to be partly
due to database connection contention, it also seems Ghost gets
overwhelmed by the requests themselves. Implementing a simple queueing
system allows us a simple lever to change the volume of requests Ghost
is actually ingesting at any given time and gives us options besides
simply increasing database connection pool size.

---------

Co-authored-by: Michael Barrett <mike@ghost.org>
2024-03-21 09:25:07 -05:00
renovate[bot]
dfdd4e5cfa Update dependency express to v4.19.1 2024-03-21 11:50:48 +01:00
Daniel Lockyer
162f438c63 Updated @tryghost/errors dependency
- this version is written in TS, but was published a few months ago and
  needs to be bumped here
- also updates a previous deep include into the library, which was
  unnecessary anyway
2024-03-11 17:33:51 +01:00
renovate[bot]
3301332253 Update dependency express to v4.18.3 2024-03-07 13:42:27 +01:00
Ronald Langeveld
58c156001c
Added Newsletter Events Test to Members (#19653)
refs
https://linear.app/tryghost/issue/ENG-604/🐛-members-events-show-member-subscribed-to-archived-newsletter

- added a tests to avoid a potential regression
2024-02-05 13:54:10 +00:00