refs https://github.com/TryGhost/Team/issues/982
These calls to the edit method were missing the transaction option from
the parent which meant that they ran outside of the transaction and
would cause the method to timeout.
no-issue
As subscriptions are a default relation, and we now require products to
populate subscriptions for comped members, we need to include products
by default when reading members.
refs https://github.com/TryGhost/Team/issues/986
The getMemberIdentityData is a relic of time past. Originally it was
used before we had anything like the member repository or bread
controller as a way for things inside of the Members ecosystem to get
access to member data.
This updates it to use the same interface as everything else for
fetching members so that we can rely on the shape of the data that we
consider a member.
This update will ensure that themes have access to the dummy
subscriptions created by the `read` method of the MemberBREADService.
refs https://github.com/TryGhost/Team/issues/979
This correctly handles updates to subscriptions so that if the product a
subscription is for has changed, we will remove the previous product, if
and only if there is not another subscription which gives access to it.
refs https://github.com/TryGhost/Team/issues/873
The `get` method of the member repository will return null when no
member is found - we must ensure that we don't attempt to call toJSON!
It is also possible for a member to not have any products, in which case
we should not attempt to iterate over them, and we can return early.
refs https://github.com/TryGhost/Team/issues/873
This is an unexpected state, but possible if the alpha version of tier
has been enabled previous to the events being added.
refs https://github.com/TryGhost/Team/issues/873
This adds a dummy subscription for each product that a member has
without an associated stripe subscription. It allows clients to deal
with things like a created date for comped members.
no-issue
The idea of this service is to sit infront of the repository and handle
application logic which does not belong at the data layer. The exact
naming and structure is TBC but this gives us a place to start pulling
logic out of the controllers, without having to mash it all into the
repository.
Also important to note is that is does not return instances of bookshelf
models, but a JSON representation of the model, this allows us to not
leak internal implementation to consumers.
refs https://github.com/TryGhost/Team/issues/873
This handles the creation of product events when a members access to
products is changed. This can happen on creation, update, and any
changes to stripe subscriptions.
We manually workout the difference between the current products and the
new products, and add the events accordingly.
no-issue
Calling ObjectId doesn't return a string a but an ObjectId object.
Whilst this object is cast to a string via the toJSON and toString
methods, this is not enough for MySQL. Instead we should explicitly cast
this to a string ourselves and the application level.
refs https://github.com/TryGhost/Team/issues/946
This adds the bulk edit method which handles bulk edit operations to members
to be used by the filtering feature. They have been combined into a single method
as that is how they are exposed to the API. This is definitely a candidate for a
refactor in the form of a service in front of the repository.
refs https://github.com/TryGhost/Ghost/commit/1dd52075
- Fixes bulkDestroy being passed the context
- Fixes passing options.search to the model layer
- Updates return value since the changes in referenced commit
no-issue
The logic for bulk destroy is currently incorrectly inside of the
members api controller in Ghost core. Moving it out to here allows us to
simplify the controller to rely on the service, rather than implement
the logic.
refs https://github.com/TryGhost/Team/issues/959
Because we were using the pre-existing products to determine a members
status, instead of the products _after_ we have handled the updates to
subscriptions, members with a paid subscription which was later canceled
were changed to 'comped' rather than 'free'. This adds a final check to
set a member to 'free' if their new set of products is empty.
refs https://github.com/TryGhost/Team/issues/909
The member identity data currently attaches several extra data points to member information which is not used/needed, and causes multiple DB queries on each page load when Portal requests for member via `/members/api/member` endpoint. This change removes all the unused data points on member - `labels`, `stripe_customer`, products`, `stripe_product` cutting DB queries in half.
refs https://github.com/TryGhost/Team/issues/919
As we pass the `benefits` to the Product model on creation, we do not
need to manually fetch them again. In fact doing so causes a strange SQL
error, where we attempt to run `SELECT undefined.*`.
refs https://github.com/TryGhost/Team/issues/664
The well known controller is designed to handle any requests to the
/.well-known endpoint where the members app is mounted. The first and
only requirement so far is that we expose a JSON Web Key Set so that
external services are able to validate Members JWT's
closes https://github.com/TryGhost/Team/issues/778
- cleans up the stripe migration to add default monthly/yearly prices for sites, which had a possibility of using complimentary (0 amount prices) in edge cases
- adds missing return in the same migration for an unlikely failure to parse stripe plans
refs https://github.com/TryGhost/Team/issues/542
Importing members with a created_at date will incorrectly create events
for the member for the date of the import. This updates our event
handling to use either the passed created_at date, or in the case of
subscriptions the start_date of the subscription. We're using start_date
for subscriptions rather than created, as this is more accurate because
start_date works correctly for backdated subscriptions in Stripe.
closes https://github.com/TryGhost/Team/issues/660
All subscriptions in Ghost are expected to have a corresponding price details in `stripe_price` table, which is used to determine the Stripe price a subscription is on. In some edge cases, specially before we started deleted old Stripe data during Stripe disconnect, it's possible that a subscription exists in DB without having a corresponding Stripe price in the DB. These subscriptions are not active for the connected Stripe account, and are save to remove. Going forward, all existing subscriptions with connected account will be removed when disconnecting stripe so we shouldn't have invalid subscriptions in DB in future.
The goal of this migration is to clean all such subscriptions from the DB to avoid any issues around missing price with invalid subscriptions.
refs https://github.com/TryGhost/Team/issues/858
Replacing the check for subscriptions with products ensures that Stripe
Checkout is not able to be opened by comped members.
refs https://github.com/TryGhost/Team/issues/790
We were missing a check for the existence of memberData.products before
attempting to read the length property from it, which can result in an
Uncaught TypeError
refs https://github.com/TryGhost/Team/issues/790
When linking a subscription to a member we must also update their
status. We could be in one of many states, so we start with the initial
values of either 'free' or 'comped' based on whether the member has any
products. We then make sure to updated the status to 'paid' if we find
any active subscriptions associated with the member, otherwise we leave
it as the initial value.
refs https://github.com/TryGhost/Team/issues/790
Both creating and updating members only ever need to explicitly set
either the 'comped' or 'free' status as these methods do not deal with
Stripe. When updating a member if the products are not changing, we do
not attempt to change the status either.
no issue
- we're killing off `ghost-ignition` in favor of explicit packages
containing its individual components
- this commit switches the Members repo to using the
`@tryghost/ignition-errors` and `@tryghost/debug` dependencies,
updates the code with relevant changes and removes the `ghost-ignition`
dependency
refs https://github.com/TryGhost/Team/issues/748
This ensures that you cannot add more than one product to a Member.
However it does allow a Member which already exists with more than one
Product to continue using the API. This is to account for edgecases such
as a Member going through the Stripe flow twice and ending up with
multiple subscriptions for multiple products
refs https://github.com/TryGhost/Team/issues/748
Previously when a change happened to a subscription the member's
products would be reset purely based on the subscriptions. Since we now
support setting products outside of subscriptions, we must make sure
than a change to a subscription will only affect the product for which
the subscription was for
refs https://github.com/TryGhost/Team/issues/775
Exposing this to the Admin API means that we want to be able to cancel
by id, not just email. The same pattern from editSubscription has been
used.
refs fd40e04105
The current implementation of setting legacy prices as inactive has a bug where it also sets the active price to inactive if only one of monthly/yearly price is edited while the other is not changed. This is a temporary reversal till we can narrow down the issue and fix to correctly set legacy plans to inactive.
closes https://github.com/TryGhost/Team/issues/753
Currently, the portal_plans setting is storing price ids for active monthly/yearly prices for the default product, which was done to allow multiple prices in Portal. Since we only want to limit the prices for a Product to monthly/yearly, we are reverting the earlier migration and only store the available prices as monthly / yearly in portal setting instead of ids. Its also in sync with the approach in theme/API where we use named prices for monthly/yearly instead of price id list.
refs https://github.com/TryGhost/Team/issues/711
As this migration relies on the settings being populated, it cannot be a
standard migration in Ghost core, as the settings are populated by these
code migrations.
refs https://github.com/TryGhost/Team/issues/704
Currently when attempting to create stripe_prices without a Stripe
connection, it will fail silently. This is an issue when initially
configuring Members as the Stripe connection can take some time to be
established. By erroring we allow the client to be notifed that the
connection does not yet exist, so that it can be retried later.
refs https://github.com/TryGhost/Team/issues/635
It's possible that we have subscriptions in the system which have been
created externally, and so using an interval of week or day. This change
ensures that we handle the mrr_delta for these subscriptions correctly.
refs https://github.com/TryGhost/Team/issues/657
Since we have removed the getPlan method we need to update the migration
which is the last piece of code which used it. Prices are backwards
compatible with Plans - so this will continue to work as expected.