refs: 23b383bedf
- @tryghost/error constructors take an object, not a string - the expectation is that message, context & help should all be set
- This does the bare minimum and just ensures message is set correctly
refs: 3a1c51672c
- @babel/eslint-parser was added to enable support for static members on classes but this causes other problems as it fails on eslint ugprades etc
- a better solution is to set ecmaVersion to 2022, as our default is 2018 which does not support static, yet 2022 does
no-issue
The new tests added do not meet the default minimum of 90% and we do not
want to dedicate more time to writing tests for this package right now.
refs https://github.com/TryGhost/Team/issues/1322
We no longer restart the Members service based on the Stripe service
being updated, which meant that if it was initially configured with
missing URL's and later Stripe connected, it would not get the new
config until a server restart. This moves the last of Stripe config into
the Stripe service, so that all things concerning Stripe can be handled
in one place and updated together.
refs https://github.com/TryGhost/Team/issues/1319
Rather than allowing our code to attempt to speak with Stripe and error
there, we opt to fail fast and throw validation errors so that our API
will respond with a 422, the existing pattern for validation errors.
refs: https://github.com/TryGhost/Toolbox/issues/203
- Without the all flag only files touched by tests are counted
- This shows our unit-testing picture more clearly
- Will get this change rolled out across all repos and packages ASAP, but for now this one seemed most important
no-issue
There is a bug in the event repository code where filters are not
correctly applied, this results in the api verification being extremely
trigger happy. For now we're removing the logic, with the plan to revert
this commit once the event repository is fixed.
no-issue
We were incorrectly mixing transactional and non-transactional
operations. An e2e test in Ghost will be merged shortly which caught
this problem.
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/Toolbox/issues/166
New package handles the email verification workflow to prevent spammers. It currently handles MembersSubscribeEvent to detect potential abuse of the API to add members, and exposes methods for checking the threshold / starting the verification process for use by other areas of the code (at the moment - just member imports).
The import package no longer needs to handle anything related to verification since it can be handled in the wrapper function in Ghost, and the API package doesn't need to do anything other than dispatch the new event.
refs https://github.com/TryGhost/Team/issues/1277
- When a user signs-up, two events are created, the code was only keeping one of these events.
- This was introduce in commit 58c9c1c649 when the only usage of the function was to extract the 5 most recent events. Any duplication was creating too much noise.
- This was creating issues now that we introduce event filtering. Some `newsletter_event` events would appear from nowhere we we were filtering-out `signup_event` events.
- We removed the deduplication when the `membersActivityFeed` flag is enabled.
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
refs https://github.com/TryGhost/Team/issues/1252
Although we filter out archived tiers from being shown in Portal - we
must also persist this information, so that when they are unarchived,
they continue to not be shown in Portal.
Unfortunately this information is stored in a setting, rather than on
the Tier object itself, two things to consider for the future are:
1. Representing the display value on the Tier object in the API
2. Updating the DB tables to allow storing the display value on the Tier
refs https://github.com/TryGhost/Team/issues/1277
- Doing a filtered DB query wasn't a good solution because we query several tables with different shapes.
- Filtering in memory is done with the NQL library
- Removed the side-effect of changing options.filter for each query, now that options.filter will already contain NQL
- The filtering is done in the reduce function to avoid looping one more time over the in-memory events
refs https://github.com/TryGhost/Team/issues/1277
- Added the pre-existing framework filters to each event query.
- Made sure we aren't modifying the original `options.filter` to avoid side-effects between event queries.
refs https://github.com/TryGhost/Team/issues/1252
This will be used to archive and unarchive Tiers. There is a restriction
on archiving "free" Tiers because our current system expects only one,
and it should always be active.
no-issue
The `opts` parameter is optional but there was no default defined, this
was causing errors when trying to read the forceCreate property if opts
was not passed.
refs https://github.com/TryGhost/Team/issues/1277
- The members weren't included in the serialized version of the new events
- Some properties weren't using the bookshelf `get` method as they should have
refs https://github.com/TryGhost/Team/issues/1277
- Adds 3 new requests to the `email_recipients` table in the `getEventTimeline` method
- This allows to extract new member events from the table: `email_delivered_event`, `email_opened_event`, `email_failed_event`
no-issue
This module is going to encapsulate all of the Stripe related logic, so
I'm renaming this file to be a little more specific about what it
relates to. Essentially this module will export a Stripe Service, and
this file is just one part of that.
no-issue
We are already in the Members repository so there's no need for members
in the directory name. The NPM package name however is unchanged and
still requires specificity as it is scoped to @tryghost as a whole
rather than the Members feature.
refs https://github.com/TryGhost/Team/issues/1037
Tiers have a new `type` column to differentiate between `free` and `paid` tiers. This change -
- sets type as paid for all new tiers created, as `free` tier is created by default
- excludes any price/stripe data change for free tier
- updates all usages of default product to fetch the first paid product from the products list in DB instead of just the first product it finds.
refs https://github.com/TryGhost/Team/issues/1275
We want to be able to track where member subscriptions came from, so
that we can use the information to reduce spam imports of members.
We were missing information when members were uploaded via the Admin
API, and setting the source to 'member' be default - this fixes that
both when creating members and when updating their subscription status.
no-issue
We have a special mapping for subscribed_to_emails -> subscribed in the
parse method, but were not mapping it in the unparse method, which meant
we were losing information during CSV imports.
no-issue
Running these in a transaction ensures that they do not partially execute or run
into race conditions with simultaneous operations via the API.
refs https://github.com/TryGhost/Team/issues/1257
This gets us closer to not having to reload the MembersAPI when config
is changed which will help stop bugs arising from multiple instances of
the MembersAPI being created.
refs https://github.com/TryGhost/Team/issues/1259
These errors are thrown by nodemailer and can occur when an invalid
email address is used. Without special handling these cause a 500 error.
refs https://github.com/TryGhost/Team/issues/789
We are still having issues with duplicate subscriptions being inserted,
despite running our code in transactions. For now we will catch these
errors and response ot Stripe with a 409 so that it'll retry later - and
it stops us from throwing 500's
refs https://github.com/TryGhost/Team/issues/1202
When importing we were transforming the CSV and add missing columns to
it before storing it in preparation to perform the import. This resulted
in the missing columns being updated for existing members with blank
data.
We've updated the Members CSV parsing library to take an options list of
columns to include, which then allows imports to not include all of the
default columns.
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
refs https://github.com/TryGhost/Team/issues/1067
This decouples the contents/type of email from the webhooks service,
allowing us to easily make changes to the type of email sent, without
having to make changes to the webhooks service.
refs https://github.com/TryGhost/Team/issues/1243
It's possible to get into strange states where a subscription in Ghost
doesn't have an associated Price. This then has knock on effects because
we're dealing with data in an undefined state. Rather than add guards
against this throughout the entire stack, we stop returning it from the
BREAD API. It might be worth considering removing these subscriptions
from the response of the repository, but for now this is the most
minimal change that fixes the problem.
refs https://github.com/TryGhost/Toolbox/issues/139
- The DynamicRedirectManager was initialized witht the same set of parameters throughout the test suite, so it made sense to initialize it once for all the tests. The sibiling describe block will have a similar setup for a redirects manager that has a subdirectory configured
refs https://github.com/TryGhost/Toolbox/issues/139
- As few more tests have been added a clearer pattern of reusable variable has emerged. Have extracted common bits into "beforeEach" block to keep the declarative part of the test to the minimum
refs https://github.com/TryGhost/Team/issues/1236
We want to be able to use the OfferName as the name property for a
Stripe Coupon - which has a maximum character length of 40.
refs https://github.com/TryGhost/Team/issues/1092
refs https://github.com/TryGhost/Team/issues/1135
This was missed in the initial due to the issue tracking the task being
superceded, and the task not being copied across to the superceding
issue.
A new method to remove coupons has been added, as opposed to updating
the existing change subscription price method, because the removal of a
coupon is not the concern of an auxillary stripe service, but a busines
concern that should be explicit in the members-api codebase.