refs https://github.com/TryGhost/Toolbox/issues/345
- this commit bumps `eslint-plugin-ghost`, which bumps compatiblity to
2022
- this also removes a lot of the manually-added
`parserOptions.ecmaVersion` that we had in imported packages, in favor
of the value set in `eslint-plugin-ghost`
refs https://github.com/TryGhost/Team/issues/1141
- when a member had canceled subscriptions the check we have to match products to subscriptions to determine whether to insert the hardcoded complimentary subscription was incorrectly matching against the canceled subscriptions
- updated to match only active subscriptions
refs https://github.com/TryGhost/Team/issues/1299
- Convert `created_at` to the right column in each function query
- Renamed the misspelled `getEmailDeliveredEvents` function
- Updated existing unit tests to cover the order
refs https://github.com/TryGhost/Team/issues/1277
- In `getEventTimeline` we filter to only perform the relevant queries, passing to each query function the filters (subset of NQL)
- In each query function, we rewrite the filters to adapt them to the internal data shape.
- We need to do this rewrite to allow API consumers to create filters based on the output on the API instead of the internal data structure.
- Added partial unit tests as there is a lot of repetition between the query functions.
refs https://github.com/TryGhost/Team/issues/1277
- This will allow to filter events within `getEventTimeline`
- The subset of NQL has the following rules:
- Only one level of filters, now parenthesis allowed
- Only three filter keys allowed
- No `or` allowed outside of the bracket notation (this is allowed: `type:-[email_opened_event,email_failed_event]` but this isn't: `type:1,data.created_at:1`)
- The return is an object with a NQL filter by allowed filter key
closes https://github.com/TryGhost/Team/issues/1238
- previously returned 500 errors when a subscription had multiple prices due to external tampering on Stripe directly
- instead now returns 400 Bad Request error when subscriptions don't have right number of prices
no-issue
Since we do not necessarily have a single stripe product anymore, we
should be checking if an invoice webhook is for a stripe product which
we know about. We use the Products repository to search our database for
one.
refs https://github.com/TryGhost/Team/issues/637
All the APIs that currently work with price names needs to be updated to work with price ids instead to work with custom prices/products. This change updates APIs to work with Price IDs in `checkout` , `updateSubscription` and other APIs/methods.
refs https://github.com/TryGhost/Team/issues/530
The RouterController was a grab bag of all controller methods, making it
difficult to mock & test. This adds a MemberController with a smaller
API - making it easier to test.
no-issue
1. We do not want to store payment events for payments of 0 value
2. Stripe webhooks can arrive and be processed "out of order", which can
result in us attempting to add a payment event for a member which
does not yet exist. The change here will 404 in such (edge) cases, so
that Stripe will retry the webhook at a later point, when the Member
has been created, allowing us to store the payment event.
no-issue
This refactors the members-api module so that it is easier to test going forward,
as well as easier to understand & navigate. The Stripe API no longer contains
storage code, this is all handled via the member repository. And we have dedicated
services for webhooks, and stripe plans initialisation.
requires f38d490886
- adds `lib/geolocation.js` with `getGeolocationFromIP()` function which uses https://geojs.io to lookup geolocation data from an IPv4 or IPv6 address
- updates `create/updateMember()` functions to work with a `geolocation` property in the passed in object
- if `geolocation` is `undefined` when updating a member do not reset any existing property
- updates `sendMagicLink` middleware to extract the IP address from the request and stores it as part of the token payload
- updates `getMemberDataFromMagicLinkToken()` method to extract the IP address from the token payload and perform a geolocation lookup if we have an IP address and a matching member does not already have geolocation data