Commit Graph

383 Commits

Author SHA1 Message Date
Rishabh Garg
e17f5004cc
🐛 Fixed unable to create new prices on switching Stripe account (#13013)
closes https://github.com/TryGhost/Team/issues/724
closes https://github.com/TryGhost/Team/issues/739

Currently, site owners are allowed to disconnect Stripe if they don't have any active subscriptions for a member. On disconnect, all stripe related data for the old account in DB should be cleared as using Stripe id for old account can cause weird failures due to incorrect Stripe key being used. This was also causing site owners to not be able to create new prices after connecting to new account as it ended up using old stripe product id which failed on Stripe request.
2021-06-08 21:28:16 +05:30
Rishabh
413c1cc4ce Handled empty stripe price object in API
no refs

In case of Stripe disconnect, its possible that the product table still contains reference to monthly/price id while the object itself isn't present in the DB. In this scenario the stripe price returned is empty object instead of `null` , which then passes down empty object in the API that causes clients to fail if they just check existence of stripe price. The fix returns `null` value for monthly/yearly price in case it has no reference and is empty object.
2021-06-08 20:59:39 +05:30
Fabien O'Carroll
76a54059b0 Fixed Product API handling of original options
no-issue

The default include values are empty arrays which are not falsy, so the
boolean OR operator would never use the second operand. Instead we
concatenate the options together so that the API can use all of them.
2021-06-08 11:41:00 +01:00
Fabien O'Carroll
09a817da16 Fixed Product serializer lookup of original include
no-issue

The Frame object colocates the query, params & options data under a
single options property, this is not the case for the "original" data
however, which means that we need to explicitly check individual
"original" properties. We do not expect the `include` option to be used
as a param so that has been left out for now.

This reverts commit ea9a83d444.
2021-06-08 11:27:16 +01:00
Naz
3f286e8eb4 Removed group/type mapping in v4/canary Settings API
refs https://github.com/TryGhost/Team/issues/757

- The "type" value in settings is meant to be representing the data type stored in the "value" field. It was an overlooked bug in v4 API adding a mapper to  group->type
2021-06-07 19:47:02 +04:00
Naz
cd35358fdb Added labs setting input validation
refs https://github.com/TryGhost/Team/issues/757

- To safeguard from mise of a very permissing "object" value of the "labs" setting this change introduces an "allowlist" approach to filtering unrecognized labs flags
- Should allow maintainers to have a clear view of which labs flags are currently in use and manage them accordingly
2021-06-08 02:18:17 +12:00
Naz
8ab43b84d5 Enabled 'labs' to be accepted as a value in Settings API
refs https://github.com/TryGhost/Team/issues/757

- As labs has been added back to the settings table the APIs are reverting back to accepting it as a value
2021-06-08 02:18:17 +12:00
Rishabh
ea9a83d444 Fixed product API removing included data
no refs

The product output serializer is removing the include data due to the includes being missing in frame options for some reason. This is a temporary fix that always allows the default includes as `monthly/yearly_price` to unblock the API, and we can revert it back to explicit request once fixed.
2021-06-04 12:28:56 +05:30
Fabien 'egg' O'Carroll
2a81d0a986
🐛 Fixed saving Members with Complimentary plans (#13008)
* 🐛 Fixed saving Members with Complimentary plans

refs https://github.com/TryGhost/Team/issues/758

Since 4.6 The Admin is using the comped flag again, rather than creating
subscriptions for zero-amount prices directly. With the `comped` flag
removed, the default state was for it to be falsy in the Admin, and when
saved would trigger the legacy comped flow, cancelling the subscription.

This reverts commit 57a176ff3d.
2021-06-03 18:28:14 +01:00
Fabien O'Carroll
a0df10f1b8 Fixed Products API removing included data
no-issue

The include data is stored under original.options rather than original.
2021-06-03 18:04:57 +01:00
Fabien O'Carroll
83a9a1d0a5 Supported monthly & yearly price in Products API
refs https://github.com/TryGhost/Team/issues/712

- Adds a Content API for products, which can be used by the theme-engine
  middleware to populate the products data.
- Removes Stripe ids from Content API so they cannot be used to
  initiate checkout sessions directly
- The monthly_price and yearly_price are used to create new prices, and
  to set them to the default monthly & yearly price for the product.
2021-06-03 17:08:02 +01:00
Naz
a7dec233ba Fixed error being saved in notification settings
refs https://github.com/TryGhost/Team/issues/754

- This is fixing the root cause of an error being saved in `settings` table under `notifications` key. There needs to be a follow up to this fixing any possible instances that might have been affected byt the bug
2021-06-03 12:54:09 +04:00
Kevin Ansfield
5fe9036ecf Added sentry_dsn and sentry_env properties to /canary/site/
refs https://github.com/TryGhost/Team/issues/723

- enables Admin to report unhandled exceptions and API errors when configured
2021-05-26 16:54:04 +01:00
Kevin Ansfield
3b366dc55d
Fixed max-api-complexity linting warnings for site and config APIs (#12982)
no issue

- moved `config` and `site` API output generation to a `public-config` service allowing all API versions to use `publicConfig.config` or `publicConfig.site` in their query methods
- updated `config` and `site` API output serializers to use an allow-list that limits the data returned for each API version
2021-05-26 12:10:19 +01:00
Fabien O'Carroll
f4017cc439 🐛 Fixed creating members linked to stripe customers
closes https://github.com/TryGhost/Ghost/issues/12942

The signature of the `linkStripeCustomer` method was updated and this
usage was missed.
2021-05-20 13:44:35 +01:00
Fabien O'Carroll
17a2083c05 Added precondition for Stripe Connect Admin API
refs https://github.com/TryGhost/Team/issues/598

Stripe Webhooks require SSL in production, and so we should not be
allowing connecting to Stripe in production mode unless the site is
running with SSL.
2021-05-20 12:08:45 +01:00
Fabien O'Carroll
57a176ff3d Removed comped flag from canary Members Admin API
refs https://github.com/TryGhost/Team/issues/693

Since we no longer have a concept of "comped" we're removing the flag
from the unstable canary api.
2021-05-19 18:49:18 +01:00
Rishabh
5cabc39124 Fixed products data in members api on changing comped status
refs a4c78dbf19

Updates member data on edit to include products data when comped status is changed, as by default we don't include products data when member goes from free to paid subscription due to comped being added.
2021-05-19 23:14:04 +05:30
Rishabh
a4c78dbf19 🐛 Fixed error on saving member with susbcriptions
closes https://github.com/TryGhost/Team/issues/699

With custom products, saving a member with subscriptions on member detail page in Admin throws errors on console, though the save is successful. This breaks the Admin as user needs to refresh the screen again to get rid of error. This change -

- updates the response on member save to return `price` object in subscription
- updates tests
2021-05-19 22:32:15 +05:30
Naz
ec01c4f004 Fixed typos 2021-05-12 17:06:10 +04:00
Kevin Ansfield
c36e749820
Added support for gating content by member labels and products (#12946)
refs https://github.com/TryGhost/Team/issues/581
closes https://github.com/TryGhost/Team/issues/582

Emails can now be sent to members with specific associated labels or products by specifying an NQL string. We want to bring the same members segment feature to content by allowing `visibility` to be an NQL filter string on top of the `public/members/paid` special-case strings.

As an example it's possible to set `posts.visibility` to `label:vip` to make a post available only to those members with the `vip` label.

- removed enum validations for `visibility` so it now accepts any string or `null`
    - bumped `@tryghost/admin-api-schema` for API-level validation changes
- added nql validation to API input validators by running the visibility query against the members model
- added transform of NQL to special-case visibility values when saving post model
    - ensures there's a single way of representing "members" and "paid" where NQL gives multiple ways of representing the same segment
    - useful for keeping theme-level checks such as `{{#has visibility="paid"}}` working as expected
- updated content-gating to parse nql from post's visibility and use it to query the currently logged in member to see if there's a match
    - bumped @tryghost/members-api to include label and product data when loading member
2021-05-10 19:32:11 +01:00
Rishabh
4d4286d255 Updated setup flow to rename default product
refs https://github.com/TryGhost/Team/issues/667

On clean and existing installs, the default product created should be named the same as the site title instead of the name in fixture. This change updates the default product's name to site title during the site setup. We use the Product name in Portal.
2021-05-10 13:59:00 +05:30
Kevin Ansfield
322664a145
Added ability to send a newsletter to members with a certain label or product (#12932)
refs https://github.com/TryGhost/Team/issues/581
refs https://github.com/TryGhost/Team/issues/582

When publishing a post via the API it was possible to send it using `?email_recipient_filter=all/free/paid` which allowed you to send to members only based on their payment status which is quite limiting for some sites.

This PR updates the `?email_recipient_filter` query param to support Ghost's `?filter` param syntax which enables more specific recipient lists, eg:

`?email_recipient_filter=status:free` = free members only
`?email_recipient_filter=status:paid` = paid members only
`?email_recipient_filter=label:vip` = members that have the `vip` label attached
`?email_recipient_filter=status:paid,label:vip` = paid members and members that have the `vip` label attached

The older `free/paid` values are still supported by the API for backwards compatibility.

- updates `Post` and `Email` models to transform legacy `free` and `paid` values to their NQL equivalents on read/write
  - lets us not worry about supporting legacy values elsewhere in the code
  - cleanup migration to transform all rows slated for 5.0
- removes schema and API `isIn` validations for recipient filters so allow free-form filters
- updates posts API input serializers to transform `free` and `paid` values in the `?email_recipient_filter` param to their NQL equivalents for backwards compatibility
- updates Post API controllers `edit` methods to run a query using the supplied filter to verify that it's valid
- updates `mega` service to use the filter directly when selecting recipients
2021-05-07 11:56:41 +01:00
Kevin Ansfield
b08b95085e
Added default email recipients settings (#12925)
refs https://github.com/TryGhost/Team/issues/496

We want to give more control over the default selection of email recipients when publishing a post, to do that we need somewhere to store those settings. These settings are site-wide and intended for use by admins to control the default editor behaviour for all staff users. They _do not_ control API behaviour, if you want to send email when publishing via the API it's still necessary to explicitly opt in to that using the `?email_recipients_filter=` query param.

- new `editor` settings group to indicate that these settings only affect the UI rather than the API
- `editor_default_email_recipients` controls overall behaviour, string/enum with these allowed values:
  - `'disabled'`: no option to send email is shown in the editor's publishing dropdown
  - `'visibility'`: (default) selected member segment is dynamic and matches the post visibility filter
  - `'filter'`: specific member filter defined in `editor_default_email_recipients_filter` setting
- `editor_default_email_recipients_filter` is an NQL string for selecting members, used when `editor_default_email_recipients` is set to `'filter'`
  - default value is `'all'`
  - the segment string can be any valid NQL filter with the additional special-case values of `'all'` and `'none'`
2021-05-07 09:30:57 +01:00
Fabien O'Carroll
da33a4ee65 Included description in Admin Products API output
refs https://github.com/TryGhost/Ghost/issues/12055
refs https://github.com/TryGhost/Ghost/commit/b4d9ee0b

Since we've added the description column to the products table we need
to include it in responses from the API
2021-05-04 13:42:35 +01:00
Hannah Wolfe
273e220327 Moved i18n to shared
refs 829e8ed010

- i18n is used everywhere but only requires shared or external packages, therefore it's a good candidate for living in shared
- this reduces invalid requires across frontend and server, and lets us use it everywhere until we come up with a better option
2021-05-04 13:03:38 +01:00
Hannah Wolfe
829e8ed010 Expanded requires of lib/common i18n and events
- Having these as destructured from the same package is hindering refactoring now
- Events should really only ever be used server-side
- i18n should be a shared module for now so it can be used everywhere until we figure out something better
- Having them seperate also allows us to lint them properly
2021-05-03 17:14:52 +01:00
Thibaut Patel
af35d5986a Exposed a read-only public oauth enabled/disabled configuration
issue https://github.com/TryGhost/Team/issues/614

The new flag is only appearing when oauth is configured.
2021-04-27 20:56:10 +02:00
Hannah Wolfe
bc75fab663 Moved theme service to core/server
refs: bf0823c9a2
refs: ae86254972

- continuing the work of splitting up the theme service into logical components

Themes Service
- The serverside theme service now serves just the API and boot
- It loads the theme and passes it to the theme-engine via the bridge

This achieves the bare minimum goal of removing all the cross requires between server and frontend around themes
There is still a lot more to do to achieve an ideal architecture here as laid out in ae86254972
2021-04-27 15:14:49 +01:00
Fabien 'egg' O'Carroll
33f26fbf32
Updated subscriptions for Members Admin API
refs https://github.com/TryGhost/Team/issues/616

We need a way to assign Products to Members via a Subscription, and we've
followed the same pattern as the editSubscription method for the Members API
controller, which acts upon Subscriptions as a nested resource.

Subscriptions now are linked to products, and we've included those links by
default in the Member Admin API as we already include subscriptions by
default, and Products are now a core part of the Members feature-set.
2021-04-26 17:14:34 +01:00
Fabien O'Carroll
050580e5ab Supported products include for Members Admin API
refs https://github.com/TryGhost/Team/issues/616

This allows us to check which products a Member has access to, without
having to check the subscriptions array.
2021-04-20 13:04:51 +01:00
Fabien O'Carroll
d7b6a48226 Added Products API to Admin API
refs https://github.com/TryGhost/Team/issues/616

This is a basic scaffold of the API to get things moving.

The input serializer is so that the controller logic does not need to
know about the json-api shape of the input data.

The output serializer is an adaptation of the members one.
2021-04-20 13:04:51 +01:00
Thibaut Patel
375c71fc6a 🔒 Added a way to hide the secret settings once they are set
issue https://github.com/TryGhost/Team/issues/621
2021-04-16 17:05:16 +02:00
naz
d964224312
Added settings keys to store OAuth related data (#12879)
refs https://github.com/TryGhost/Team/issues/618

- The `oauth_client_id` and `oauth_client_secret` are placeholders to store OAuths related data.
- The flag for `oauth_enabled` or anything along those lines was not added intentionally in favour of checking if the `oauth_client_id` & `oauth_client_secret` are null.
2021-04-16 10:02:21 +02:00
Thibaut Patel
44244871fe Added configurable limits to the theme management
issue https://github.com/TryGhost/Team/issues/590
2021-04-09 18:30:17 +02:00
Kevin Ansfield
bb19eddeae
Added DELETE /members/ to the Admin API for bulk member deletion (#12082)
refs https://github.com/TryGhost/Team/issues/585

- adds `DELETE /members/` route to the Admin API
- supports `?filter`, and `?search` query params to limit the members that are deleted
- `?all=true` is required if no other filter or query is provided
- uses `models.Member.bulkDestroy` which _will not_ cancel any Stripe subscriptions if members have them but _will_ clean up the Stripe relationship data in Ghost's database
2021-04-08 12:03:45 +01:00
Rishabh Garg
72e8894eac
Cleaned old members stats endpoint (#12821)
no refs

- Removes old `/members/stats` endpoint in favor of new `/members/stats/count` in canary/v4 which captures members counts using new events table
- Removes tests for old `/members/stats` endpoint
- Added test for new `/members/stats/count` endpoint
2021-03-29 13:07:01 +05:30
Naz
aaa54c603c Refactored exporter to use "allowlist" table filtering
refs https://github.com/TryGhost/Team/issues/555

- Previous blocklist approach was resulting in adding every single new table into an export automatically. Which creates possibility to leak sensitive data if not used porperly. Allowlist approach gives better control over what is exported, makes this information explicit, and version-control friendlier
2021-03-25 16:46:56 +13:00
Thibaut Patel
44035fd591 Added a better error when a user try to create an orphaned webhook
issue https://github.com/TryGhost/Team/issues/526
refs 70627d84a7 (r48575450)
2021-03-23 17:15:21 +01:00
Thibaut Patel
70627d84a7 Removed redundant code for handling orphaned webhooks
issue https://github.com/TryGhost/Team/issues/526
refs https://github.com/TryGhost/Team/issues/477
2021-03-22 15:48:51 +01:00
Kevin Ansfield
afbe0c27fb
🐛 Fixed __GHOST_URL__ appearing in sitemaps (#12787)
closes https://github.com/TryGhost/Team/issues/552

Refactors URL transforms so they take place at the model layer rather than the API serializer layer. Continuation of the pattern created for the settings model in https://github.com/TryGhost/Ghost/pull/12738

- Added checks to all front-end tests to ensure output does not contain the magic replacement string
  - includes failing acceptance test for `__GHOST_URL__` appearing in sitemaps
- Removed all transform-ready URL transforms from API serializers
  - input serializers transform image urls relative->absolute to keep absolute-urls as the consistent "outside of the database" format
  - output serializers should not need to perform any URL transforms as that will be done at the model layer
- Added url transforms to models layer
  - removes knowledge from the API serializers which shouldn't need to know how data is stored internally in the database
  - makes absolute urls the consistent "outside of the database" URL format
  - adds transform step to the sitemap generator because the data used for that is fetched directly via knex which will not run through the bookshelf `parse()` methods
2021-03-18 17:16:37 +00:00
Naz
b5de4f4cf5 Reverted dropped model usage in post serializer
refs 6b07d4b2a0

- The model is needed here, because it contains full set of fields. In some cases, like email-preview, the "plaintext" field is not present in "attrs" which causes the logic to fail.
- This should be sorted along with https://github.com/TryGhost/Ghost/issues/10396
2021-03-17 20:01:12 +13:00
Naz
6b07d4b2a0 🐛 Fixed __GHOST_URL__ appearing in generated excerpts
refs https://github.com/TryGhost/Team/issues/467
refs a6f5eb71be

- When a generated excerpt is calculated for posts/page resources it uses raw model! to get the data. Model contains untranformed __GHOST_URL__ markup which has to be additionally processed before extracint an excerpt or use the transformed `plaintext` from available attributes (chose the latter to decrease complexity)
- Removed model dependency as `attrs` at this point of serialization should always contain the `plaintext` field. It's ugly and has an unsolved bug report here - https://github.com/TryGhost/Ghost/issues/10396. The reliance should be solved at some point, but definitely not a part of this issue
2021-03-17 19:12:40 +13:00
Kevin Ansfield
021cfecb59
Fixed __GHOST_URL__ appearing in settings values after edit (#12738)
refs https://github.com/TryGhost/Ghost/pull/12736
refs https://github.com/TryGhost/Team/issues/467

knex's `parse()` method is only called on data when directly fetched from the db. This was causing problems when model instances are passed around via events for example because `.get('key')` will return data that was directly set on the model without having gone through the `parse()` transformations. The result of this inconsistency was settings appearing correct when Ghost started up but then being broken as soon as a setting was changed.

- moved absolute/relative->transform-ready URL transformations from the API input serializers to the model's `format()` method and replaced with a relative->absolute transform in API input serializers
    - results in consistency because `.get()` on a settings model will always return an URL
- removed transform-ready->absolute transforms from the API output serializers as that is now handled at the model-layer
2021-03-08 18:41:43 +00:00
Kevin Ansfield
a6f5eb71be
🏗 Changed internal URL storage format to use __GHOST_URL__ (#12731)
closes https://github.com/TryGhost/Team/issues/467

- switches to storing "transform-ready" URLs in the database
- transform-ready URLs contain a `__GHOST_URL__` placeholder that corresponds to the configured url that gives a few benefits
  - much faster and less memory intensive output transformations through not needing to parse html or markdown - the transform can be achieved using a straightforward regex find+replace
  - ability to change to/from or rename subdirectory without any manual updates to the database
- modified existing 4.0 url-transformation migration rather than adding another one and repeating the transformation on posts rows
2021-03-05 13:54:01 +00:00
Rish
6594741c11 Cleaned member stats endpoints response
refs https://github.com/TryGhost/Team/issues/469

- Cleans up response format for mrr and volume stats endpoint to more consistent pattern
- Removes `unit` attribute for now as its not used
2021-03-05 16:39:12 +05:30
Hannah Wolfe
6f579331e1 Changed Config API response structure
refs: https://github.com/TryGhost/Team/issues/510

- Changed to return the full hostSettings key, not just the billing URL
- We are introducing several more settings that are needed by Admin including limits
- Passing the whole object makes this much easier to reason about as Admin has the exact same config as the server
2021-03-04 21:16:20 +00:00
Hannah Wolfe
d51fcd072e Added new member limit & removed old
refs: https://github.com/TryGhost/Team/issues/510

- The current member limit was implemented as a member-specific concept
- The new limit service is much more generic, here we are swapping old for new
- The updated concept here is blocking all publishing, not just email sending, when a site is over its member limit
- To determine that we are publishing a post, we must be in the model layer. The code has been moved to the permissible function which makes sense as this is a permissions error that we are throwing
- I've left the extra check for email retries in, in case there is some loophole here (but we may wish to change it)
2021-03-04 18:16:34 +00:00
Hannah Wolfe
26f56626ce Updated host config to correctly use camelCase
refs https://github.com/TryGhost/Team/issues/510

- When the host config was introduced it was incorrectly introduced as host_settings instead of hostSettings
- All other Ghost config uses camelCase, so changing this now before it becomes a problem
- Note: Also removed some rogue return awaits that don't make sense. It's not possible to hit that case, but cleaning up anyway
2021-03-04 11:39:32 +00:00
Naz
9995ae3616 Added support for locale key in Admin Settings API
refs https://github.com/TryGhost/Team/issues/509

- Allows to update and read 'locale' key along with the deprecated 'lang'
- In Ghost v5 the 'lang' key will be dropped and the migration in settings table will clean up the key name to match the one exposed through the APIs
2021-03-04 21:20:46 +13:00