Commit Graph

291 Commits

Author SHA1 Message Date
Kevin Ansfield
9cbeb74db0
🐛 Fixed broken embeds cards when pasting links to Wordpress sites (#12262)
closes https://github.com/TryGhost/Ghost/issues/12260

- if a card type was not explicitly chosen (i.e. a url was pasted into the editor) then abort fetching the oembed endpoint if we detect it's a `wp-json` oembed and return a bookmark card payload instead
- cleaned up an unused argument in the internal `fetchBookmarkData()` method
2020-10-06 08:44:03 +01:00
Naz
39e403d176 🐛 Fixed meta attributes calculation on post preview
closes https://github.com/TryGhost/Ghost/issues/12247

- Internal preview controller was lacking "mapping" call to post object which handled not only missing meta attribute information but lots of other mappings (e.g. users, tags, etc.)
- Have added a regression test to catch issues like this in the future
2020-10-05 17:52:40 +13:00
naz
071bf8edb5
Extracted Admin API JSON schemas into @tryghost/admin-api-schema (#12237)
closes https://github.com/TryGhost/Ghost/issues/10628

- JSON Schemas were extracted into a separate module to allow other clients to reuse them (for example documentation). Having them in a separate package also slims down the amount of code needed to be maintained in the core.
- Updated canary API input validators to use admin-api-schema module
- Removed canary schemas that moved into admin-api-schema package
- Updated v2 API input validators to use admin-api-schema package
- Removed v2 schemas that moved into admin-api-schema package
- Updated tests to contain needed information in apiConfig to pick up correct validation
- Added @tryghost/admin-api-schema package dependency
2020-09-30 16:25:12 +13:00
Fabien 'egg' O'Carroll
854a41e556
🐛 Fixed CSV import json-schema email validation (#12239)
no-issue

By using the "email" validation, we were validating emails in CSV
imports using a different validator to the rest of the API. AJV's built
in email validation was failing on emails with "special" characters,
such as letters with an umlaut above them.

This commit brings the validation for CSV imports in line with the rest
of the API.
2020-09-29 12:51:35 +01:00
Kevin Ansfield
1dfaf8c5f8
Added migration to store from/reply-to values in email table (#12204)
no issue

The email table should be a reference for all data that was used when sending an email. From and Reply-to addresses can change over time and we don't have any other reference for their value at the time of sending an email so we should store them alongside the email content.

- schema updated with `from` and `reply_to` columns
- both are set to `nullable` because we don't have historic data (can be populated and changed in later migrations if needed)
- neither `from` or `reply_to` have `isEmail` validations because they can have name+email in an email-specific format
- will help keep concerns separated in the future. `mega` service can deal with all of the email contents/properties, and the `bulk-email` service's concerns are then only email sending and any provider-specific needs
2020-09-24 08:20:10 +01:00
Naz
43153ba31e Disabled changing webhook's integration_id through PUT API
refs #12033

- Allowing to change parent integration opens up possible security holes and has no clear usecase at the moment. After a webhook record is created it should not be possible to change parent integration.
- Had do partially duplicate JSON schema definition from webhooks definition as there is no proper composition technique available in current version of JSON Schema.
2020-09-24 16:24:02 +12:00
Naz
af516e130c Fixed error message checks in members regression test
refs 6f1abc610a

- Additional period `.` was introduced in referenced commit which broke these tests
- The period was added to follow general convention of ending error messages with a perio (in some situations validation message didn't make sense without proper punctuation)
2020-09-24 15:31:19 +12:00
Naz
6f1abc610a Added check for parent integration_id when creating a webhook
refs https://github.com/TryGhost/Ghost/issues/12033
refs https://github.com/TryGhost/Ghost/issues/10567

- Creating a webhook without valid parent integration leads to orphaned webhook records, which shoult not ever happen
- This scenario is only possible for non-integration authentication,
because in case of integration being authenticated it's id is
automatically assigned to creatd webhook
2020-09-24 15:09:51 +12:00
naz
bbcc83dadb
Added support for ordering Post API resources by fields coming form posts_meta table (#12226)
refs #11729

- When ordering is done by fields from a relation (like post's `meta_title` that comes form `posts_meta` table), Bookshelf does not include those relations in the original query which caused errors. To support this usecase added a mechanism to detect fields from a relation and load those relations into query. 
- Extended ordering to include table name in ordered field name.  The information about the table name is needed to avoid using `tableName` within pagination plugin and gives path to having other than original table ordering fields (e.g. order by posts_meta table fields)
- Added test case to check ordering on posts_meta fields
- Added support for "eager loading" relations. Allows to extend query builder object with joins to related tables,
which could be used in ordering (possibly in filtering later). Bookshelf does not support ordering/filtering by proprieties coming from relations, that's why this kind of plugin and query expansion is needed
- Added note about lack of support for child relations with same property names.
2020-09-24 13:32:40 +12:00
Kukhyeon Heo
635d26469f
Fixed settings reinit to only emit changed settings events (#12184)
closes #12038

Previously we were emitting changed events for _all_ settings which would
cause any listeners for those to be triggered, this ensures that listeners are
only triggered if the corresponding setting, _did_ in fact change.
2020-09-23 14:35:03 +01:00
Fabien O'Carroll
171908cefa Added support for filtering Members CSV exports
no-issue

Adding these options to the endpoint will pass them to the model layer,
allowing us to filter members CSV exports
2020-09-23 14:29:15 +01:00
Fabien O'Carroll
800ffc2e8f Improved Members CSV export acceptance tests
no-issue

This updates the test to check the parsed CSV contains all the expected rows
2020-09-23 14:29:15 +01:00
Nazar Gargol
5766b39be6 Fixed failing regression tests
refs 32b37d7ba8

- Some of the regression tests were broken after changes in referenced commit
2020-09-22 16:13:57 +12:00
Nazar Gargol
32b37d7ba8 Improved error messaging for password reset process
refs #11878

- When password reset link is invalid previous messaging left the user
without clear information about why the reset failed and what they could do about it.
- Updated messaging around password reset tokens including detection of
when password token has invalid structure, has expired or has already
been used
2020-09-22 15:45:19 +12:00
Fabien 'egg' O'Carroll
812e4b682f
Added SingleUseToken model (#12215)
no-issue

This is a model for the tokens table, which handles the single use
aspect by customising the `findOne` method to automatically destroy the
model after reading from it
2020-09-18 15:05:56 +01:00
Fabien O'Carroll
a862a58b5f Updated the tokens table to have 32 char tokens
no-issue

After discussion with Matt, we decided that 192 bits for the token is a
good number, as it has no padding when base64 encoded and is more secure
than 128 bits, whilst still a managable size.
2020-09-17 17:33:43 +01:00
Fabien O'Carroll
01e62e3d79 Added tokens table to the database
no-issue

This is a table to store single use tokens for use in magic links, the
columns are as simple as possible at the moment and are designed as:
id - standard ObjectID like all of our tables
token - 128bit base64 encoded string
data - arbitrary data to store against the token
created_at - timestamp to allow for expiry to be implemented for tokens
2020-09-17 16:08:35 +01:00
Rish
7a3839fb14 Added new portal config flag
no issue

- The new Portal config flag allows switching on Portal conditionally with config
- The dev experiment flag still works for enabling Portal
- The flag currently defaults to `false` as Portal is still a beta feature and switched off by default
- We expose it on the admin api config endpoint so that the Ghost-Admin client can use it to conditionally render Portal settings
2020-09-17 19:40:34 +05:30
Nazar Gargol
bd16c2216a Fixed acceptance tests for posts_meta refactor
refs d9dbcf6147
2020-09-17 21:19:26 +12:00
Nazar Gargol
d177852d1f Fixed posts_meta relation in test fixtures
refs d9dbcf6147

- Fixes broken commit
2020-09-17 20:46:45 +12:00
Nazar Gargol
d9dbcf6147 Corrected data generator fixture with posts_meta fields
refs https://github.com/TryGhost/Ghost/pull/11102

- When splitting out posts_meta table out of posts table, the fixtures were not corrected.
- There were no acceptance/regression tests which involved posts_meta fields which is why the error was not detected
2020-09-17 19:34:36 +12:00
Nazar Gargol
e9204c9168 Updated invitations test coverage with more specific checks
refs https://github.com/TryGhost/Ghost/issues/11878

- Updated test cases in preparation to improve messaging in referenced
issue.
2020-09-16 14:24:24 +12:00
Kevin Ansfield
76c1b60a4d
Added schema+migration for email_{batches,recipients} tables (#12192)
no issue

We want to store a list of recipients for each bulk email so that we have a consistent set of data that background processing/sending jobs can work from without worrying about moving large data sets around or member data changing mid-send.

- `email_batches` table acts as a join table with status for email<->email_recipient
  - stores a provider-specific ID that we get back when submitting a batch for sending to the bulk email provider
  - `status` allows for batch-specific status updates and picking up where we left off when submitting batches if needed
  - explicitly tying a list of email recipients to a batch allows for partial retries
- `email_recipients` table acts as a join table for email<->member
  - `member_id` does not have a foreign key constraint because members can be deleted but does have an index so that we can efficiently query which emails a member has received
  - stores static copies of the member info present at the time of sending an email for consistency in background jobs and auditing/historical data
2020-09-14 12:21:58 +01:00
naz
cbdc91ce48
Added Location header to API's POST request responses (#12186)
refs #2635

- Adds 'Location' header to endpoints which create new resources and have corresponding `GET` endpoint as speced in JSON API - https://jsonapi.org/format/#crud-creating-responses-201. Specifically:
    /posts/
    /pages/
    /integrations/
    /tags/
    /members/
    /labels/
    /notifications/
    /invites/

- Adding the header should allow for better resource discoverability and improved logging readability
- Added `url` property to the frame constructor. Data in `url` should give enough information  to later build up the `Location` header URL for created resource.
- Added Location header to headers handler. The Location value is built up from a combination of request URL and the id that is present in the response for the resource. The header is automatically added to requests coming to `add` controller methods which return `id` property in the frame result
- Excluded Webhooks API  as there is no "GET" endpoint available to fetch the resource
2020-09-14 22:33:37 +12:00
Talha
afa976066a
🐛 Fixed table constraint error when updating member's email with an already existing email (#12178)
closes #12045

- When member's email is updated to an already existing email of different member it caused table's unique constraint error, which was not handled properly. 
- Added handling for this error similar to one in members `add` method.
2020-09-10 16:03:57 +12:00
Nazar Gargol
453bc2c491 Fixed regression test for integrity check
refs 5582d030e3

- When not touching this area for longer time always forge following:  `routes.yaml` configuration file in /content/settings comes as a copy of `default-routes.yaml` file from frontend/services/settings/
- Always remember to clean up junk "default" files in the content/settings folder to make things less confusing!
2020-09-10 12:57:03 +12:00
Nazar Gargol
a8202eb80d Fixed regression test for integrity check
no issue

- The file that is better suited for integrity check is the `*-default.yaml` config because it's the one that gets copied through when there is none or configuration is broken
2020-09-10 11:20:38 +12:00
Nazar Gargol
5582d030e3 Added routes.yaml content checksum storage to the db
closes #11999

- When the routes.yaml file changes (manually or through API) we need
to store a checksum to be able to optimize routes reloads in the future
- Added mechanism to detect differences between stored and current routes.yaml hash value
- Added routes.yaml sync on server boot
- Added routes.yaml handling in controllers
- Added routes hash synchronization method in core settings. It lives in core settings
as it needs access to model layer. To avoid coupling with the frontend settings it accepts
a function which has to resolve to a routes hash
- Added note about settings validation side-effect. It mutates input!
- Added async check for currently loaded routes hash
- Extended frontend settings loader with async loader. The default behavior of the loader is
to load settings syncronously for reasons spelled in 0ac19dcf84
To avoid blocking the eventloop added async loading method
- Refactored frontend setting loader for reusability of  settings file path
- Added integrity check test for routes.yaml file
2020-09-10 10:54:57 +12:00
Talha
c8a6939b2e
🐛 Fixed error caused by accepting invitation with existing email (#12172)
closes #12060

- A 500 error what happening when invited user provided an email that is associated with an existing user
- Additional validation for existing email address was added to prevent invalid data hitting db constraint error
2020-09-09 11:58:53 +12:00
naz
fcc6401445
Added routes_hash setting (#12171)
refs #11999

- The `routes_hash` setting will be used during the boot process to update the hash
of currently loaded routes.yaml file in case it's different from last restart
2020-09-07 21:54:55 +12:00
Kevin Ansfield
936d7a315a 🐛 Fixed incorrect status used for trial subscription query
refs 96c18edc82

- replaced `trialed` with `trialing` to correctly match the status used in Stripe
2020-09-02 13:07:48 +01:00
Kevin Ansfield
96c18edc82 🐛 Fixed members with Stripe trials not receiving paid-members newsletters
no issue

- members who have trial subscriptions added directly via Stripe will have a status of `"trialed"` in their Ghost subscription
- the `paid: true` filter was not taking that into account meaning trial users were not receiving newsletters sent to paid members even though they have a "paid" subscription
2020-09-02 00:34:26 +01:00
Rishabh Garg
bc2f6eb8e9 Added migrations for support and reply email address setting (#12163)
no issue

- Added default settings for the two new setting fields - `members_support_address` and `members_reply_address`
- Added migrations for setting group for new email settings
- Migration sets current from address as new support address default
- Added migration to set new support address same as from address
- Updated tests for new settings
- `members_support_address` - How members can reach for help with their account, public setting
- `members_reply_address` - Where you receive responses to newsletters
2020-08-31 17:16:53 +05:30
Nazar Gargol
0f81e5e84a Fixed regression tests for Tags APIs
refs #12167

- The reason for failing tests was  https://github.com/TryGhost/Ghost/issues/6104 . As we already test for ordering elsewhere, didn't include more "if/else" logic in tests just for the sake of passing. Refactored them to be order-independent instead
2020-08-31 21:09:12 +12:00
Rish
8cf9dc05e3 Revert "Added migrations for support and reply email address setting (#12163)"
This reverts commit 2216019a86.
2020-08-31 14:25:29 +05:30
Nazar Gargol
eb8c0fcff9 🐛 Fixed Tags API v2 to return posts count
closes #12167

- Tags API v2 was ignoring `count.posts` include parameter.
- Regression was introduced with a3f693b472
- Introduced regression tests across all Content API versions to avoid similar bug in the future
2020-08-31 18:46:35 +12:00
Nazar Gargol
791bcc6adb Improved tests for "include=posts.count" query parameter
refs #12167

- Updated tests to check for concrete post counts numbers. This would allow catching more regression bugs in the future
- Made sure check is performed consistently in tests where posts.count
parameter is present
2020-08-31 17:30:21 +12:00
Rishabh Garg
2216019a86
Added migrations for support and reply email address setting (#12163)
no issue

- Added default settings for the two new setting fields - `members_support_address` and `members_reply_address`
- Added migrations for setting group for new email settings
- Migration sets current from address as new support address default
- Added migration to set new support address same as from address
- Updated tests for new settings
- `members_support_address` - How members can reach for help with their account
- `members_reply_address` - Where you receive responses to newsletters
2020-08-27 20:27:50 +05:30
Nazar Gargol
bcca59ffbe Fixed regression tests for members importer
refs 262d33b73c

- Added missing test changes from referenced commit
2020-08-27 19:28:18 +12:00
Kevin Ansfield
a995e9cc89 Allowed custom and search queries to be used with .findAll()
no issue

- extract filtering of an collection into a separate function
- use extracted function in `findAll()` so that it's query behaviour matches `findPage()`
2020-08-27 01:09:07 +01:00
Kevin Ansfield
5e64f113d5 Skipped separate count query in .findPage() for limit="all" requests
no issue

- for large result sets or complex queries the count query itself can be quite time consuming
- when `limit: 'all'` is passed as an option there's no need to perform a separate count query because we can determine the pagination data from the final result set
- skipped count query when `limit: 'all'` option is present
- re-ordered comments to be closer to the code they reference (ie, why we have our own count query instead of Bookshelf's `.count()`
2020-08-27 01:09:07 +01:00
Nazar Gargol
9d65de4b10 Removed created import labels when no records were imported
no issue

- When no members are succesfully imported through CSV import process the import label should not be created. Otherwise after multiple failed attempts to import there are orphaned labels in the system
2020-08-25 19:23:05 +12:00
Nazar Gargol
b8197023b3 🐛 Fixed ignored created_at and subscribed fields in Members API
closes #12156

- When adding new member through `POST /members` API or importing members with CSV importer `POST /members/upload` API created_at and subscribed were ignored
- Similar problem but only with `subscribed` field was present in `PUT /members/:id` API
- The regression was introduced with a bump of @tryghost/members-api to 0.26.0, specifically this change in upstream - a28bcc5b2a (diff-3daeef67d07a2a0f94c89a86cafcede9R44)
- Bumped @tryghost/members-api package to 0.28.2 fixing the underlying issue - 7b5f2e3cb7
2020-08-24 19:35:20 +12:00
naz
3a594ce22e
Improved error handling for batch inserted member records (#12146)
no issue

- When batch insert fails handling should be more granular and aim to retry and insert as many records from the batch as possible.  
- Added retry logic for failed member's batch inserts. It's a sequential insert for each record in the batch. This implementation was chosen to keep it as simple as possible
- Added filtering of "toCreate" records when member fails to insert. We should not try inserting related members_labels/members_stripe_customers/members_stripe_customer_subscriptions records because they would definitely fail insertion without associated member record
2020-08-20 17:41:47 +12:00
Nazar Gargol
6512b98049 Updated flaky member import tests
no issue

- Because there's concurrency involved during member import the order cannot be guaranteed.
2020-08-19 16:43:58 +12:00
Rishabh Garg
2bac2c67cc
Granted Admin users ability to impersonate member (#12132)
refs #12126

- Adds migration to add impersonation permission to administrators
- Adds default permission fixture to allow administrators to read member impersonation urls
- Allows administrators to create member impersonation magic links
2020-08-18 14:17:56 +05:30
naz
51c9a50c4f
Added validation layer to members import endpoint (#12131)
no issue

- Additional validation is needed for imported data because in case of bulk insertions (through knex) we bypass model layer validation - this could lead to invalid data in the database, which would be hard to fix.
- Chose validation method we use for other endpoints - through JSON Schema. It proved to be very performant (200ms overhead for 50k records). When comparing it with iterative method (validating each record separately) this was adding about 17s of overhead.
- Refactored returned values from "sanitizeInput" method to encapsulate more logic so that the caller doesn't have to calculate amount of invalid records and deal with error types
- Whole sanitizeInput method could now be easily extracted into separate module (somewhere close to members importer)
- Bumped members-csv package. It is meant to handle empty string values - '' and null, which should allow validating member records more consistently!
2020-08-17 23:28:57 +12:00
Nazar Gargol
ef41c57974 Added test coverage for invalid member import emails
no issue

- This test should serve as a control for new batched importer
2020-08-13 22:14:52 +12:00
Kevin Ansfield
c434666ba2 🐛 Removed [http://url/] output in member email preview text
no issue

- we output the post excerpt in a hidden div in the email template so that email clients pick it up as the "preview" text when listing emails
- when no custom excerpt is provided the preview text is grabbed from post.excerpt which is the first 500 chars of the post.plaintext value
- post.plaintext formats links as "Link [http://url/]" which is unwanted in html email previews

- add a basic replacement to the post email serializer to remove any `[http://url/]` occurrences from the post excerpt before rendering the email content
2020-08-12 20:14:06 +01:00
Kevin Ansfield
163092f377 🐛 Fixed apostrophes not displaying correctly in Outlook for member emails
refs https://github.com/TryGhost/Ghost/issues/11536

- Outlook supports `&#39;` as a special char for apostrophes but not `&#apos;` which is what cheerio/juiced render
- adds a basic string placement to the email serializer to switch to the older style of special char
2020-08-12 20:01:42 +01:00
Fabien 'egg' O'Carroll
1294e3f92c
Replaced all usage of member models with members-api (#12117)
no-issue

* Added stripeSubscriptions relation to member model

This allows us to fetch the subscriptions for a member via standard
model usage, e.g. `withRelated: ['stripeSubscriptions']` rather than
offloading to loops and `decorateWithSubscriptions` functions, this is
more performant and less non-standard than the existing method.

* Updated serialize methods to match existing format

The current usage of `decorateWithSubscriptions` and the usage of
members throughout the codebase has a subscriptions array on a stripe
object on the member, this ensures that when we serialize members to
JSON that we are using the same format.

There is definitely room to change this in future, but this is an
attempt to create as few breaking changes as possible.

* Installed @tryghost/members-api@0.26.0

This includes the required API changes so that everywhere can use
members-api directly rather than models and/or helper methods
2020-08-12 14:17:44 +01:00
Nazar Gargol
597bc12088 Fixed tests with members labels
refs 7d3f6e32ca

- Missed to commit fixture change
2020-08-12 17:02:08 +12:00
Nazar Gargol
7d3f6e32ca Addes sort order support for imported members
no issue

- Member's labels have to have sort_order assigned when added/edited. This was lacking from batched importer.
- Implementation is based on logic used in model's base - e484709e73/core/server/models/base/index.js (L81-L86)
2020-08-12 16:34:15 +12:00
Daniel Lockyer
5b471e1bbe Extracted promise libs and history into @tryghost/promise
- deleted files under `core/server/lib/promise` and related test files
- added `@tryghost/promise` as a dependency
- fixed all local requires to point to the new package
2020-08-11 18:44:21 +01:00
Daniel Lockyer
c9a5b28669 Extracted core/server/lib/security to @tryghost/security package
- code and tests were extracted out to this package
- deletes these files
- replaces all local requires, and adds it as a dependency
2020-08-11 14:06:50 +01:00
Daniel Lockyer
8799feb801 Replaced constants file with @tryghost/constants
- extracted constants file into a new package
- replaced all local requires of the file with new package
2020-08-11 12:51:16 +01:00
Hannah Wolfe
e84621d6ef 🐛 Readded missing server.start event
closes #12118

- server.start was mistakenly removed in 71f02d25e9
- it is used for loading themes (and other things) and is critical
- added tests to prevent this regressing again in future
2020-08-11 10:09:24 +01:00
Hannah Wolfe
71f02d25e9 Refactored server announce functions to be clearer
- the announce functions exist for the purpose of communicating with Ghost CLI
- the functions were called announceServerStart and announceServerStopped, which implies they tell Ghost CLI when the server starts and stops
- however, the true intention / purpose of these functions is to:
    - either tell Ghost CLI when Ghost has successfully booted (e.g. is ready to serve requests)
    - or tell Ghost CLI when the server failed to boot, and report the error so that Ghost CLI can communicate it to the user
- therefore, I've refactored the old functions into 1 function to make it clearer they do the same job, but with 2 different states
- also added some tests :D
2020-08-09 17:25:15 +01:00
Fabien 'egg' O'Carroll
d15446593a
Added support for ON DELETE CASCADE to the schema (#12105)
no-issue

We are in the process of creating migrations to add foreign key constraints
and cascading deletes to the members_stripe_* tables to make listing members
and deleting members faster. As well as the migrations we need to update the
database schema so that new installations have the correct indexes and constraints.

Co-authored-by: Kevin Ansfield <kevin@lookingsideways.co.uk>
2020-08-05 13:20:30 +02:00
Nazar Gargol
60ae9e82f9 Fixed integration_id assignment for webhook when creating through API key auth
refs 173e3292fa

- The bug was initially introduced in referenced commit. When request is done with `api_key` context, there should always be an `integration` object associated with it - 71c17539d8/core/server/services/permissions/parse-context.js (L36) . An `id` from `context.integration` not `context.api_key` has to be assigned to newly created webhook!
- The webhooks API is about to be declared stable in upcoming release, so no migration will be done
2020-08-04 16:43:24 +12:00
Nazar Gargol
1b449f4f53 🐛 Fixed 500 error in webhooks API when modifying non-existing webhooks
closes #12064

- Handled permission check bug by returning 404, same way it is returned in other permissions related places when handling non-existing resource. Example - 60907a7ae4/core/server/models/relations/authors.js (L355-L358)
2020-08-03 23:08:47 +12:00
Kevin Ansfield
0c5c7b32b8 Fixed members import regression tests
refs 14c6968388

- updates expected member labels length asserts to account for auto-generated import label being attached
2020-07-26 18:57:11 +01:00
Kevin Ansfield
14c6968388 Fixed auto-generated label not being attached to members during import
no issue

- label was being created and returned in the response OK but it was missing from the set of labels that get added to members during import
2020-07-26 18:30:58 +01:00
Fabien O'Carroll
c46475f5be Supported optionally cancelling subscriptions on delete
no-issue

This updates the Admin API Member resource to *not* cancel subscriptions
by default, and adds a `cancel` option. This can be used over HTTP by
including a `cancel=true` query parameter.
2020-07-24 16:01:06 +02:00
Fabien 'egg' O'Carroll
5144a0e09c
Updated Member model to cascade on destroy (#12077)
no-issue

Up until now we have left orphaned rows in members_stripe_* tables when
a member is deleted, this updates the destroy method so that we cascade
and remove any MemberStripeCustomer and StripeCustomerSubscription
models related to the Member.

This also adds regression tests for the new functionality as well as to
confirm the existing functionality of cascading to the members_labels
join table

This adds the relations of Subscription->Customer & Customer->Member
2020-07-23 18:21:10 +02:00
Kevin Ansfield
6504b0f6c3 Fixed settings unit tests
refs e04f55cce3

- added `tracker.uninstall()` so that previously set up `tracker.on()` listeners are not called by later tests
- fixed `emits edit events` test which was not correctly mocking the select and update queries
2020-07-22 22:12:00 +01:00
Kevin Ansfield
62c72cb58b Fixed oembed test
refs e04f55cce3

- added `nock.cleanAll()` so that there is no inter-test dependencies
- the failing test was successfully passing previously due to mocha's retry behaviour eventually exhausting nock request handlers that were set up in other tests and intended not to be called
2020-07-22 19:49:30 +01:00
Kevin Ansfield
8ceabbcfba Added automatic labelling of all members added during an import
no issue

Having all members created during an import labelled with a specific "import label" is useful for later operations such as bulk delete/edit or simply recording how and when a member was created.

- automatically create a label with the date/time the members CSV import occurred and assign it to all imported members
- return the import label data in the API response so that clients can react accordingly such as automatically filtering the members list by the label once an import finishes
2020-07-22 17:52:43 +01:00
Daniel Lockyer
415696a3f9 Replaced removed nock method
no issue
2020-07-21 20:25:06 +01:00
Hannah Wolfe
995a4eb46e 🐛 Fixed edit link for staff members
closes #12069

- the url in admin changed from team to staff, and wasn't updated in the frontend
2020-07-21 12:28:50 +01:00
Fabien 'egg' O'Carroll
6232981be7
🐛 Fixed importing Stripe Plans with amount 0 (#12062)
closes #12049

Stripe plans used to default to 0, and our new validation of plan
amounts were causing issues when importing from an older version of
Ghost, this updates the validation to be skipped when importing.

- Added regression test for importing plans
2020-07-20 14:59:23 +02:00
Nazar Gargol
a520cdad0b Added JSON Schema validations to Webhooks Admin API v3
closes #12033

- Added webhooks schemas and definitions.
- Added validation checking if integration_id is present when using session auth. This is needed to prevent orphan webhooks.
- Integrated webhook schemas into frame's validation layer.
- Added isLowerCase ajv keyword support. This is needed to be able to do isLowerCase validation using JSON Schema for webhooks.
2020-07-17 17:37:14 +12:00
Fabien 'egg' O'Carroll
8f660c3259
Improved settings validation (#12048)
closes #12001

* Moved settings validation to the model

This moves the settings validation out of the validation file and into
the model, as it is _only_ used there.

It also sets us up in the future for custom validators on individual
settings.

* Improved validation of stripe_plans setting

- Checks `interval` is a valid string
- Checks `name` & `currency` are strings

* Moved stripe key validation into model

The stripe key settings are all nullable and the regex validation fails
when the input is `null`. Rather than reworking the entirety of how we
validate with default-settings validation objects, this moves the
validation into methods on the Settings model.

* Added tests for new setting validations

Adds tests for both valid and invalid settings, as well as helpers
making future tests easier and less repetitive
2020-07-15 17:11:27 +02:00
Fabien O'Carroll
48eca5f618 Added amp_gtag_id setting migration & default
refs #11980

This lays the ground for the rest of the work surrounding Google
Analytics in AMP.
2020-07-15 13:43:25 +02:00
Nazar Gargol
ced3e28d60 🐛 Fixed cache invalidation for published posts with no content
closes #12015
refs 95880dddeb

- The bug was caused by falsy plaintext field assignment to empty string `''` when the html content was `null`. Because of the `setEmptyValuesToNull` function (referenced commit), there is no sense to assign empty string value to plaintext property, because it would still end up being `null`
- The `''` -> `null` conversion was confusing the model layer to think that some fields were changed, where in reality none did. This in turn lead to a bug with falsy cache invalidation
2020-07-15 17:41:24 +12:00
Nazar Gargol
a75e1e27db 🐛 Fixed cache invalidation when editing post_meta fields
closes #12016

- The change detection didn't work when editing post_meta fileds because we only check current model's `_changed` fields when performing `wasChanged()` check
- A solution was adding change tracking of post_meta relation to currently edited post model and overloading `wasChanged` method to check these fields as well
2020-07-14 23:48:36 +12:00
Fabien O'Carroll
06c7152f4b 🐛 Fixed Stripe webhooks for subdirectory setups
no-issue

- Added breaking test for webhook url including subdirectory

- Previously the webhook handler URL was generated incorrectly when
  running Ghost on a subdirectory, appending the path to the root of the
  host, this fix ensures that the subdirectory is included before the
  path.
2020-07-10 17:43:46 +02:00
Fabien 'egg' O'Carroll
20a95de8f7
Added new stripe webhook settings (#12028)
no-issue

They will be used to store webhook information so that we can persist it between
boots and simplify the creation process of webhooks in members
2020-07-10 16:26:06 +02:00
Rish
d6f4f01eff Added new settings integrity tests
refs https://github.com/TryGhost/Ghost/issues/12026

- We made changes to settings table structure in 3.22 which added new columns for `group` and `flags`
- Any new setting needs explicit group and flag migrations since or they fallback to default group value of `core`
- This tests ensures
  - hash is updated in DB integrity test anytime default-settings are changed
  - that a migration is present by maintaining a whitelist of allowed core settings and failing if new setting is added without correct group migration
2020-07-10 18:32:54 +05:30
Nazar Gargol
d6267340a1 Updated Content API resource ordering to be same as slugs in filter
closes #11994

- Adds support for ordering based on slug filter  that contains a slug-is-in filter. It is applied only to Content API's resources - post, page, tag, author. The order is applied in the same order in which slugs appear in the filter.
- For, example providing following  query parameter filter for any of the above resources: `?filter=slug:[kitchen-sink,bacon,chorizo]`, would filter them by these slugs and order in the same way defined in the filter
- Can be used in handlebars templates in following way: `{{#get "tags" filter="slug:[slugs,of,the,tags,in,order]"}}`
- The property conteining this new order is assigned to `autoOrder` instead of `rawOrder` intentionally. This explicit asstignment would allow distinguishing where the 'orderRaw' comes from the model or the API layer. Apart from  adding necessary context this separation makes it easier to refactor separately model layer and API specific ordering in the future
- This commit also fixes default filtering for `author` resource in Content API. The serializer was never used before as it was missing from `serializers/index.js` module.
2020-07-10 18:33:00 +12:00
Fabien O'Carroll
a607610c3a Added new meta columns to tags table
no-issue

This prepares the database for future work, allowing tags to store metadata
2020-07-08 11:49:22 +02:00
Nazar Gargol
173e3292fa Fixed integration_id handling in Webhooks Admin API
no issue

- Changes introduced to both API v3 and v2
- Makes sure to use the same integration_id as authenticated integration for the webhook's data.
-  Makde it is impossible to create orphaned webhooks using token authentication
- Allowed only parent integration to edit it's children webhooks. Throwing permission error otherwise
2020-07-08 16:54:31 +12:00
Nazar Gargol
3c21b45ad8 Fixed linting error
refs 256b407dd2
2020-07-07 21:07:16 +12:00
Nazar Gargol
256b407dd2 Refactored webhook acceptance test suite
no issue

- Refactored a test as it was using outdated `done()` convention instead of relying on promises
- Removed linting warnings for variable shadowing
- This is precursor work for webhook regression test updates needed in near future work
2020-07-07 21:02:11 +12:00
Rish
c0e3c8bcfe Added new settings for portal button customization
no issue

- Adds new portal settings - `portal_button_style`, `portal_button_icon` and `portal_button_signup_text`
- New settings allows customization of portal button
- Updates tests to include new settings
2020-07-07 14:06:04 +05:30
Hannah Wolfe
8c8af3b4ac Fixed additional bracket in fixture code example
closes #11908

- The post publishing-options shows a snippet of JSON-LD in a code block, that had an extra comma and curly bracket
2020-07-06 19:49:10 +01:00
John O'Nolan
70f16f3d97
🎨 New Google AMP template (#11986)
- Refreshed the design of the default Ghost AMP template
- Updated tests
2020-07-06 17:09:24 +01:00
Daniel Lockyer
8956a9df35 Merged 3.22.2 into master
* tag '3.22.2':
  v3.22.2
  Updated Ghost-Admin to v3.22.2
  Emitted all settings events on reinit of cache (#12012)
  🐛 Updated access to be true by default in v3 API
  Hardened members subscription migration against missing data (#12009)
2020-07-06 16:19:55 +01:00
Hannah Wolfe
289c1b3e8a 🐛 Updated access to be true by default in v3 API
closes #11990

- access should be a members feature, but it was already accidentally exposed to the theme layer
- it has now been added to the API even if members is disabled
- access defaults to true, unless members is enabled
- when members is enabled, access is set to the currently logged in members' access
2020-07-06 16:04:29 +01:00
Daniel Lockyer
f65c425786 🐛 Fixed searching for free/paid members
no issue

- when searching for paid/free members, the `members_stripe_customers`
  table would be joined into the query on `members`
- this table also has a `name` and `email` field, so both MySQL and
  SQLite would complain about ambiguous fields in the query
- the result of this would be a 500 error thrown inside Ghost, and no
  useful response to the user
- this commit explicitly chooses the `members` table to check against,
  and also adds a test for this
2020-07-06 09:09:08 +01:00
Fabien 'egg' O'Carroll
37d577fa90
Remove references to bulk email settings (#12000)
refs #10318

* Ignored bulk_email_settings when importing
* Removed custom handling for bulk_email_settings
* Removed bulk_email_settings from default-settings
* Ignored bulk_email_settings when editing settings
2020-07-03 16:30:54 +02:00
Fabien 'egg' O'Carroll
9df217b04e
Added mailgun_{domain,api_key,base_url} settings (#11992)
refs #10318

 - Adds new default settings
 - Adds migration for populating settings with bulk_email_settings data
 - Fixes regression tests
2020-07-03 11:00:20 +02:00
Kevin Ansfield
e9ae0d9baa 🐛 Fixed srcset and sizes attributes being rendered when image resizing unavailable
closes https://github.com/TryGhost/Ghost/issues/11944

- updates `@tryghost/image-transform` to version that exposes `canTransformFiles()` which checks for `sharp` availibility
- updates `@tryghost/kg-default-cards` to version that accepts a `canTransformImage()` method as an option
- updates our `mobiledoc` lib to pass a `canTransformImage()` function that returns false if sharp is unavailable, the image extension is not supported, or the storage engine in use does not support image transforms
- updates `populateImageSizes` to fetch image sizes when transforms are unavailable as the render/not-render is now handled in the renderer and we don't need to worry about adding size information to the mobiledoc source
2020-07-02 18:03:22 +01:00
Nazar Gargol
6902f86b40 Added field mapping support for members import CSVs
no issue

- This is a precursor work allowing client to send csv to JSON
field mapping hash as a `mapping` field parameter in the incoming
request.
2020-07-02 15:18:39 +12:00
Kevin Ansfield
ec6a46a183 Updated tests that were stubbing old ghost_head/ghost_foot settings keys
refs https://github.com/TryGhost/Ghost/issues/10318
refs 9d7665bb43

- broken helpers weren't picked up previously because the tests were stubbing the old keys
- once the helpers were fixed the tests started failing because they weren't stubbing the new key
2020-07-01 17:58:12 +01:00
Kevin Ansfield
fd4a011995
🐛 Fixed settings cache being out of sync after migrations (#11987)
refs https://github.com/TryGhost/Ghost/issues/10318

- re-initialize settings cache after migrations by shutting down to clean up event listeners then and calling `init` again
- important to ensure `db.ready` event is not emitted until settings have finished re-initializing to avoid problems with background processes using the db connection which is disconnected/re-connected or being kicked off with out-of-date settings
2020-07-01 17:16:57 +01:00
Nazar Gargol
0ee92639dd Fixed member import test
refs 05f6faf846

- The copy for these errors has changed, same should've been done in the tests.
2020-07-01 17:42:58 +12:00
Kevin Ansfield
9810c41dca 🐛 Fixed facebook/twitter images having relative URLS in API output
no issue

Output serializer's url util was expecting `og_image` and `twitter_image` to be top-level attributes in the `attrs` object but they are actually nested under `posts_meta`.

- updated the code to use lodash's `get/set()` so that we can work with paths for easier handling of nested objects
- fixed unit tests where the mocked data under test did not match real-world data
2020-06-30 16:40:34 +01:00
Jonas Fabisiak
58ac033b97
Updated head to only output custom favicons (#11949)
closes #11932

- as per the issue, there is no need to output a <link> tag if the favicon is the default /favicon.ico, as all browsers automatically check for this 
- instead the favicon <link> is only output if a custom favicon has been set, telling the browser to look somewhere different to its default location
- some of the tests expected 3 links in the html head, but through the favicon change there are often only 2.

Co-authored-by: RenCloud <rencloud@pop-os.localdomain>
2020-06-30 15:07:08 +01:00
Hannah Wolfe
fa91c6c954
🐛 Moved access to an API property (#11967)
closes #11574

- the current implementation of the access property has it frontend only, and wired up only in one place
- this leaves it only available in a handful of places, e.g. can't use it in a post loop or get helper
- the current implementation also fails logically if the html content of the post is blank

This fix moves the behaviour to the API

- this ensures the field is always available no matter what context you are in
- it also updates the logic to use the same membersHasAccess logic as is used to gate the post, so it's always correct

TODO: should reconsider the location of this code
2020-06-30 14:46:46 +01:00