refs https://github.com/TryGhost/Product/issues/3648
- Refactored Members API RouterController.createCheckoutSession: Split the method into smaller parts so we can reuse individual parts for the upcoming donation checkout session.
- Wired up donation checkout creation
- Added donation events
no issue
- We made some styling changes in the rendering nodes for the new header
card.
- This bumps the affected packages.
---
<!-- Leave the line below if you'd like GitHub Copilot to generate a
summary from your commit -->
<!--
copilot:summary
-->
### <samp>🤖 Generated by Copilot at 655e595</samp>
Updated content rendering packages to fix bugs and improve output. This
affects how Ghost converts markdown to `HTML`, `AMP`, or `email`
formats.
refs https://github.com/TryGhost/Product/issues/3651
- This is a security fix that addresses an issue causing malicious users
to abuse the test / preview email API endpoint.
- We have multiple procedures in place now to limit such users.
- First, we now only allow one email address to be passed into the
`sendTestEmail` method. This method only have one purpose, which is to
compliment the test email functionality within the Editor in Admin and
therefore have no reason to send to more than one email address at a
time.
- We then add an additional rate limiter to prevent a user from making
multiple requests, eg via a script.
- The new imposed limit is 10 test emails per hour.
refs https://github.com/TryGhost/Product/issues/3651
- This is a security fix that addresses an issue causing malicious users
to abuse the test / preview email API endpoint.
- We have multiple procedures in place now to limit such users.
- First, we now only allow one email address to be passed into the
`sendTestEmail` method. This method only have one purpose, which is to
compliment the test email functionality within the Editor in Admin and
therefore have no reason to send to more than one email address at a
time.
- We then add an additional rate limiter to prevent a user from making
multiple requests, eg via a script.
- The new imposed limit is 10 test emails per hour.
closes https://github.com/TryGhost/Arch/issues/58
- Following assumptions were broken:
- Posts Admin API should include posts of all statuses when filtering by collection
- Posts Content API should not include any unpublished posts
- Updated the "status" filter which fixes the problem. We still disallow any custom filters to be applied on top of collections filter.
no issues
- using .kg-v2 as an indicator to add the v2-specific styles
- .kg-header-card and .kg-header-card-button are the class names that confict with the existing Header card, so only using .kg-v2 to style those elements
refs https://github.com/TryGhost/Product/issues/3561
- Added a static section to Membership settings with a button to copy
the Tips & donations Stripe link
- Added a `tipsAndDonations` feature flag
This ensures that collections are updated in the background regardless of
whether or not the labs flag is enabled, which is important for the stability
of the collections database tables. In order to make sure we don't add a tonne
of event listeners during the tests we have to add a flag to make sure that the
service is treated as a singleton and only instanciated once. This should only
affect code running in tests, as we don't initialise services multiple times
Unfortuantely our framework is bookshelf centric so we have to refer to the
`withRelated` property rather than a more generic `include` property.
The collection entity already contains the list of post ids, so we can just
return the length of that array.
The test was addign an extra collection, but not cleaning it up - which makes it
hard to reason about other tests, especially when running them in isolation and
the state is different. This just cleans up the test and updates the browse test
to match the right snapshot.
The only usecases we need to support at the moment are reading individual
collections by ID and by Slug. We can extend this API as we get more usescases
in future.
The correct mechanism for fetching posts from a collection is via the Posts API.
This removes all functionality of getting posts from the Collections API.
Co-authored-by: Naz <hi@nazavo.com>
refs https://github.com/TryGhost/Arch/issues/46
- Similarly to post filters, collection filters now support both 'tag' and 'tags' nql filter keys when defining a filter for related tag slugs. For example, both `tag:avocado` and `tags:avocado` would both be valid collection filters that would filter by the same 'slug' property of the tags assigned to a post.
- Along with these changes had to rework the tags property of the collection posts to match the shape used in post resources. Moved from:
`tags: ['bacon', 'broc']`
to
`tags:[{slug: 'bacon'}, {slug: 'broc'}]`
no issues
- some themes have global styles applied to inputs and it breaks the card input layout because of the style conflict
- this adds some default margin values to fix the issue
closes https://github.com/TryGhost/Arch/issues/45
- This endpoint is here to keep the convention of being able to fetch the resource by it's slug through a `GET /{resource_name}/slug/:slug`. It has identical output as the `GET /collections/:id` endpoint
- The alternative would be having an alias and try fetching by :id and then by slug if the result for id was null, but that would be a completely new pattern we have not used anywhere else yet.
We were not passing the `slug` to the `apiOptions` so the posts were not
correctly filtered, and on top of that the `collection` option had not been
added to the allow list of the Posts Content API. With these two fixes the
collection helper works as expected.
refs https://github.com/TryGhost/Arch/issues/16
- We made a decision to limit the API for fetching posts belonging to a certain collection to only the Posts API. The endpoint on the collections was an experiment that only brings unnecessary maintenance at this point of time.
refs https://github.com/TryGhost/Arch/issues/16
- Using the API directly on the repository level prevented us from ensuring collection consistency through transactions.
- This change migrates the PostsRepository to use Bookshelf model layer directly, which also allows to put queries into transactions.
- Additional optimization here was removing the `getAllPosts` method from CollectionService. This is an attempt to reduce the API surface of the of the service before calling it a GA.
refs https://github.com/TryGhost/Arch/issues/16
- Having transactional collection post updates makes sure there are no race conditions when updating collection_posts relations. Without the transactions collection was prone to update relations based on a stale state causing problems like described in the linked issue
refs https://github.com/TryGhost/DevOps/issues/48
- due to changes in the build workflow, we no longer depended on
`ghost`'s own `build` before producing the tarball
- as a result, the minified css was not produced and private pages were
unstyled
- this adds our own `build` step to the list of dependencies for
`archive`
no issue
---
<!-- Leave the line below if you'd like GitHub Copilot to generate a
summary from your commit -->
<!--
copilot:summary
-->
### <samp>🤖 Generated by Copilot at bfc259e</samp>
Updated content rendering packages to fix bugs and improve performance.
This affects how Ghost outputs HTML and AMP pages from the
`@tryghost/kg-default-nodes` and `@tryghost/kg-lexical-html-renderer`
modules.
refs https://github.com/TryGhost/Arch/issues/41
- When an new collection is created the relational "tags" filter is now picked up properly and appropriate posts matching the tag filter are assigned and stored in the collection. Example collection filter that is now supported: `tags:['bacon']`
- Additionally cleaned up returned collection post DTOs, so we return as little data as possible and add only the fields that are needed
no issue
- bumps `@tryghost/kg-lexical-html-renderer` which includes a change to drastically reduce the number of `jsdom` instantiations made when rendering text content
no issue
- bumps `@tryghost/kg-lexical-html-renderer` which includes a change to drastically reduce the number of `jsdom` instantiations made when rendering text content
refs https://github.com/TryGhost/Arch/issues/16
- There's a race condition happening when processing multiple collection updates at the same time. It causes the state to be inconsistent between the runs.
- Once the event handling is improved these tests should be put back into action
refs https://github.com/TryGhost/Product/issues/3508
- copied over styles from the signup card, which is what the new header
card is loosely based on.
- this is meant to be hacked till we have the new header card look
pretty.
---
<!-- Leave the line below if you'd like GitHub Copilot to generate a
summary from your commit -->
<!--
copilot:summary
-->
### <samp>🤖 Generated by Copilot at 150aa92</samp>
This change introduces a new header card v2 component that allows users
to create custom headers for their Ghost site. It adds a new CSS file
`header_v2.css` that defines the styles and responsive behavior for the
component. The file uses modern CSS features to achieve a flexible and
consistent design. The file is part of the frontend module of the Ghost
core repository.
refs https://github.com/TryGhost/Arch/issues/25
- When run against different DB Engines the returned order of collections belonging to a post is not consistent (SQLite vs MySQL). Having a primitive ordering by slug allows to keep the order compatible
refs https://github.com/TryGhost/Ghost/pull/17247
- When the instance is started the posts_collections records should be pre-filled for built-in collections. This is to avoid expensive processing during every instance startup.
https://github.com/TryGhost/Arch/issues/25
- This naming matches how the collection will be visible in the cards and how it's marketed. Naming it "index" even for internal purposes will get confusing.
refs https://github.com/TryGhost/Arch/issues/25
- The instance should have two built-in collections "latest" (prviously known as "index") and "featured". These have been filled through in-memory tricks before, now they should come pre-populated through fixtures mechanism.
This is an initial implementation which uses the Posts Content API rather than
the Collections Content API, this is because we haven't added the Collections
Content API yet, but we can added it later when necessary.
We want to keep the differences between the Content & Admin API's in the API
layer, rather than at the service layer. The caching functionality hasn't been
moved yet though, and can be handled separately.
no issue
- Tests were failing for me locally because the snapshot for testing
page event payloads didn't include the new
`show_title_and_feature_image` property
- Updated snapshot to include this property, which also changed a few content lengths and `x-cache-invalidate` headers as a side effect
- this switches us to using Nx for `ghost:dev`, which means we can
configure its dependencies and ensure that the TS projects are built
beforehand
- also switches to Nx for `ghost:archive` so we don't need to run
`build:ts` for all `yarn` commands
no issue
- These repositories were leftover from first phases of collections development. Not needed any longer as we have more specialized bookshelf repositories in the core code
no issue
- updated frontend's `formatResponse` method to add `@page` to the local template data
- added here because it's the first place we have both context and page data available
- makes the property available outside of the page context so it can be used to modify layouts
- updated `prepareContextResource()` to delete `show_title_and_feature_image`
- ensures `@page.show_title_and_feature_image` is the only way of accessing that property
- method is used when rendering multiple entries so it also prevents differences in context data between looped pages and single pages
refs https://github.com/TryGhost/DevOps/issues/45
- this switches the monorepo over to using Nx instead of Lerna, because
we don't currently need the versioning+publishing capabilities
- this also adds an `nx.json`, which allows us to enable task caching
- also adds `build:ts` to the TS projects, which is cached for fast execution
- how these interact with the dev.js script will hopefully soon be
reworked to be a better experience
closes https://github.com/TryGhost/Arch/issues/27
- We need a more convenient method of fetching posts belonging to a collection than by collection's "id". This change adds an alias to the existing endpoint `GET /collections/:id/posts/`. A non-valid ObjectID in the parameter is treated as a slug.
refs https://github.com/TryGhost/Product/issues/3508
- added a feature flag for Header Cards that's being upgraded.
---
<!-- Leave the line below if you'd like GitHub Copilot to generate a
summary from your commit -->
<!--
copilot:summary
-->
### <samp>🤖 Generated by Copilot at 10ac1e4</samp>
This pull request adds a new feature flag `headerUpgrade` to the server
and the admin settings, which allows the user to opt-in to a new header
design. The feature flag is only available if the labs toggle is
enabled.
- due to schema changes between versions, we need to completely nuke the
DB between these tests
- this is definitely not the best way to do it but I'll fix properly next week
no issue
`show_title_and_feature_image` leads to more intuitive logic in themes and we can use `posts` rather than `posts_meta` as there are no longer row-length issues with MySQL 8.
- removed original add-column migration that was never in a release
- added new add-column migration that puts
`show_title_and_feature_image` column with a default of `true` on the `posts` table
- renamed property and default value everywhere
- bumped `@tryghost/admin-api-schema` to allow the new property through at the API level
refs @TryGhost/Product#3551
- PostsImporter would convert the HTML from the import file into
Mobiledoc, even if the post was written in Lexical
- As a result, the imported posts would have both mobiledoc & lexical
fields populated, which prevents the post from being updated in the
Lexical editor
- Added a check to see if the post was written in Lexical, and if so,
skip the HTML > Mobiledoc conversion
closes https://github.com/TryGhost/Product/issues/3557
- bumped `@tryghost/admin-api-schema` to allow passthrough of the new property in API requests
- updated output mapper to ensure property always returns a boolean rather than `null` in the case where `posts_meta` doesn't exist for a page
- updated `PostsService.copyPost()` to include the new property when copying
- updated `checkResponse` test util and snapshots to expect `hide_title_and_feature_image` property in page API responses
- fixed pages e2e test so it doesn't inadvertently modify the match object breaking later tests
closes https://github.com/TryGhost/Team/issues/3550
We want to allow an option to hide the title and feature image on a
per-page basis, to do that we need somewhere to store the setting value.
The existing `posts_meta` table is the simplest candidate, especially as
this is a single setting and we don't have a desire to introduce many
such settings.
- added migration that adds the `hide_title_and_feature_image` column to
the `posts_meta` table with a `boolean` data type and a default value of
`false` (matches behaviour of all existing pages)
- updated schema file for initial database creation
- removed property from API output via serializers to keep migration PR
minimal
refs https://github.com/TryGhost/DevOps/issues/39
- up until now, we've had a CI job which does a really basic test for
migrations, but it barely functions and misses bugs all the time
- this commit removes that and switches to an actual test suite for our
migrations, so we can ensure they function as expected
- also removes the env var hack I came up with for those migrations
tests
- this should lead to safer migrations and faster tests
refs https://github.com/TryGhost/Team/issues/3544
- Bumps required packages to fix an issue on posts that still contains base64 images.
<!-- Leave the line below if you'd like GitHub Copilot to generate a
summary from your commit -->
<!--
copilot:summary
-->
### <samp>🤖 Generated by Copilot at 5fb728e</samp>
Updated `@tryghost/helpers` dependency to fix some helper issues. This
improved the accuracy and security of the `{{reading_time}}` and
`{{encode}}` helpers in Ghost themes.
refs https://github.com/TryGhost/Team/issues/3544
- Bumps required packages to fix an issue on posts that still contains base64 images.
<!-- Leave the line below if you'd like GitHub Copilot to generate a
summary from your commit -->
<!--
copilot:summary
-->
### <samp>🤖 Generated by Copilot at 5fb728e</samp>
Updated `@tryghost/helpers` dependency to fix some helper issues. This
improved the accuracy and security of the `{{reading_time}}` and
`{{encode}}` helpers in Ghost themes.
fixes https://github.com/TryGhost/Team/issues/2937
Bumps juice to 9.1.0:
- Support for 'auto' width and height attributes
- Fixed a bug with counter-reset styles
- Dependencies updates
refs https://github.com/TryGhost/Ghost/pull/17065
- This is a follow up cleanup work after introducing even mapper when working on collections refresh mechanism.
- This module manages interception of the Model events and maps/dispatches Domain events that could later be used in different libraries.
fixes https://github.com/TryGhost/Team/issues/3541
The email preheader, which is only present in the html version of an
email, is also included in the plaintext version of all emails. This
results in all text being duplicated twice in plaintext emails.
We setup the relations and NQL expansions/replacements here rather than in the
repository, we want to keep all the bookshelf code together in one place.
When we end up wiring this to the database, this generator will also ensure
uniqueness by appending/incrementing a number on the end of the slug. Long term
it would be good to offload this to a shared slug service, this could also
ensure that slugs are unique globally or between multiple tables, if desired
This follows our existing patterns and protects us from th eslint max line rule
when wiring up dependencies. The rule is designed to keep logic out of glue
code, and this file won't have logic, just lots of deps.
refs https://github.com/TryGhost/Team/issues/3169
- The "current" part of the payload should always have the "id" included to make the data structure easier to use for the event consumer
refs https://github.com/TryGhost/Team/issues/3169
- With the new architecture all possible dependencies should be injected rather than required directly - this applies to the DomainEvents module as well.
refs https://github.com/TryGhost/Team/issues/3169
- When a not yet mapped event is produced by Ghost model the posts belonging to a collection are recalculated in a brute-force way. This causes a lot of strain on the database and times out some of the tests. Right now we only care about a handful of events, so limited the ones we listen to and will be uncommenting the rest when we have an optimal mapping/handling for them.
refs https://github.com/TryGhost/Team/issues/3169
- To be able to apply NQL filtering on Collection Posts the dates should be serialized to be ISO Date Strings instead of raw Dates. Otherwise, NQL filtering fails to compare Date with a Date String.
refs https://github.com/TryGhost/Team/issues/3169
- When handling a single generic event the code becomes riddled with if statements to detect correct "data" that is being passed with the event. Switching to have a domain event per model event helps solving this problem and makes code more readable.
refs https://github.com/TryGhost/Team/issues/3169
- To make the coupling to Ghost's model events as loose as possible added a bridge that maps model events to domain events. These domain events it what the collections module can subscribe to to make necessary updates.
refs https://github.com/TryGhost/Team/issues/3169
- Ghost model events should not be crossing emitted to outside libraries. The wrapper code is a "glue code" that can still listen to model events but transforms them to specific format that is useful for the collections module
- This hooks up the Ghost model events and transforms them into a "CollectionEvent" format.
refs https://github.com/TryGhost/Toolbox/issues/602
- the new regex allows for the filename to contain seconds, which would have
helped prevent a bug we had with migrations being in the wrong order
- mentioned filename ordering in the migration review comment to bring
that to the forefront of the mind
refs https://github.com/TryGhost/Ghost/issues/15725
This pull request adds a new configuration option for the Mailgun email
provider that allows the user to set the maximum number of recipients
per email batch via a new config option `bulkEmail.batchSize`
fixes https://github.com/TryGhost/Ghost/issues/17125
- both collections migrations have the same timestamp so they're ordered
based upon their slug name, and the one that creates
`collections_posts` is ordered before the one that created
`collections`
- as a result, the migration fails because the table does not exist
- this commit pushes the `collections_posts` migration after the other
one by bumping the timestamp
no issue
Keep an eye on Ghost's changelog (https://ghost.org/changelog/) for the
full feature announcement.
<!-- Leave the line below if you'd like GitHub Copilot to generate a
summary from your commit -->
<!--
copilot:summary
-->
### <samp>🤖 Generated by Copilot at ee03e4d</samp>
This pull request removes the `signupCard` feature flag and enables the
signup card for all users in the Lexical editor. This is part of the
Lexical editor beta release, which is a new editor for Ghost that
provides a better writing experience and more features for content
creators.
fixes https://github.com/TryGhost/Ghost/issues/16120
- if you set `sodoSearch.url` to `false` in config, it'll currently
crash because we're not correctly handling the types correctly
- the first part of the fix is ensuring the value is a string so we can
call `.includes` on it
- second, the `false` value is passed into the output as a string, so we
should detect if we passed a false value and early return with an
empty string if so
- credits to https://github.com/ltoinel for the fix inspiration
- in the migration tests we need to boot Ghost and then kill it
afterwards
- because there was no easy way to do this, the workflow waits for 20s
and then kills the last process ID
- aside from being a terrible idea, it means we're also just arbitrarily
waiting for 20s, which burns time when it takes shorter to boot Ghost
- this commit implements an environment variable that will kill the
server once it has run the whole boot process, and then fixes the
workflow to use that
refs https://github.com/TryGhost/Team/issues/3504
- Sentry was never setup and we don't use it
- Styles have been moved to inline JS styles (no separate css file generated)
- App version was never used
- Improved current script tag detection
closes https://github.com/TryGhost/Team/issues/3493
- Fixed pages not saving on force revision. As a side effect, it broke
admin navigation as it doesn't manage to create a new revision upon going back to the pages list.
- This was simply caused by a missing option in the API endpoint config.
---
<!-- Leave the line below if you'd like GitHub Copilot to generate a
summary from your commit -->
<!--
copilot:summary
-->
### <samp>🤖 Generated by Copilot at b646916</samp>
This change enables the `pages` endpoint to handle page revisions by
adding the `save_revision` permission. This is part of a pull request
that adds page versioning and restoring functionality to Ghost.
refs: https://github.com/TryGhost/Toolbox/issues/595
We're rolling out new rules around the node assert library, the first of which is enforcing the use of assert/strict. This means we don't need to use the strict version of methods, as the standard version will work that way by default.
This caught some gotchas in our existing usage of assert where the lack of strict mode had unexpected results:
- Url matching needs to be done on `url.href` see aa58b354a4
- Null and undefined are not the same thing, there were a few cases of this being confused
- Particularly questionable changes in [PostExporter tests](c1a468744b) tracked [here](https://github.com/TryGhost/Team/issues/3505).
- A typo see eaac9c293a
Moving forward, using assert strict should help us to catch unexpected behaviour, particularly around nulls and undefineds during implementation.
refs TryGhost/Ghost#3494
- By default, the post scheduler runs as user_id = 1, which is the
original owner of the site
- If ownership has been transferred to a different user, it's possible
that there is no user with id = 1
- In this case, the scheduler would fail to publish a post, because
updating the post using user_id = 1 failed a foreign key constraint in
the post_revisions table
- This commit fixes the issue by checking if the contextUser exists, and
if not, replacing it with the current owner of the site
closes https://github.com/TryGhost/Team/issues/3499
- bumps `@tryghost/kg-default-nodes` and `@tryghost/kg-lexical-html-renderer` to fix missing `kg-image` class on the `<img>` element of rendered image cards
refs https://github.com/TryGhost/Toolbox/issues/592
- it turns out that `TRUNCATE` in CI takes ~300ms for all tables, but
`DELETE FROM` takes ~30ms
- whilst truncating is generally known to be faster, I believe it's only
faster on large tables
- this saves 90% of the time it takes to reset the DB in MySQL
closes https://github.com/TryGhost/Team/issues/3423
- For convenience we need a way to fetch posts that belong to a certain collection. This change adds support for `collection` query parameter: `/?collection=` which can be either an id or slug of the collections we are trying to fetch.
- When posts are fetched by collection we ignore any filters passed along in query parameters as collection is a "filter" by it's very nature.
no issue
This was a bit of an oversight from our feature built at the retreat. We
didn't take revisions into account for pages at all, but luckily it made
revisions without issues regardless.
It just wasn't accessible and users weren't able to restore via ADMIN
because the API didn't serve them at all.
This wires up the revisions relation to be served by the API so we can
retrieve it in Admin.