refs https://github.com/TryGhost/Product/issues/4053
This adds the feature flag. If enabled, the list-unsubscribe header
should be set. The value currently is only for testing purposes and
probably won't work yet.
no issue
- flag is no longer used in Admin so we can clean it up in Core too
- updated Post model to set blank document to `lexical` field rather than `mobiledoc` as a default value
- switched over to returning `mobiledoc,lexical` as default formats in Admin API
no issue
- updates `@tryghost/koenig-lexical` with indent improvements
- prevents indents on paragraphs/headings etc which are not supported when rendering for front-end display
- improves indent behaviour for lists so <kbd>Tab</kbd> can be pressed anywhere in a list item to indent rather than only at the beginning of the list
closes https://github.com/TryGhost/Product/issues/4037
- bumps `@tryghost/kg-html-to-lexical` that includes better node normalization to handle `<br>` in top-level text nodes and after a nested block-level element
- also includes fix for button hrefs having `about:blank` prefixed to hash URLs
refs https://github.com/TryGhost/Product/issues/3831
---
### <samp>🤖 Generated by Copilot at 539c2d3</samp>
This pull request updates and adds some test cases for the date picker
and newsletter features in the Ghost admin panel. It introduces a test
helper function for the date picker in `editor-test.js`, and removes a
redundant test case from `publish-flow-test.js`. It also adds two new
test cases in `publishing.spec.js` using the Playwright framework to
verify the timezone and recipient settings for publishing posts.
closes https://github.com/TryGhost/Ghost/issues/18448
- improved slash menu positioning when opening at the bottom of a post
- fixed backspace sometimes deleting a preceding card (e.g. backspace at end of link inside a paragraph preceded by a card)
- fixed `?source=html` issues
- images not rendering in front-end output after import
- images wrapped in links losing their link after import
- fixed inline styles in HTML card content not displaying in the editor
- fixed broken help link in the email card
no issue
- Casper and Source theme files were out of date — this commit updates the theme fixtures, and fixes up a few tests to pass with the updated themes
closesTryGhost/Product#4032
- the api flag ?convert_to_lexical converts a mobiledoc string to
lexical
- if run on a post/page with lexical content, would null it out
- this optimizes the number of `get` calls we need to do to the adapter
for settings cache
- for example, this prevents ~187 calls to the adapter during boot
- right now we use the in-memory adapter for settings, so there's probably
not much benefit, but if we ever switch to the Redis adapter, this will
help prevent a lot of extra Redis calls
no issue
Some flaky tests found, and it seems as though they're being caused by an invalid Stripe account id.
It's possible that by re-using the worker after a test which calls `setupStripe` could cause some Stripe functionality to not work.
refs: https://github.com/TryGhost/DevOps/issues/78
Re-introduce parallel browser tests
These were adding in a previous PR, but the difference between local
running tests and using CI introduced failures.
Added additional fixes to ensure the Stripe API key is used in the CLI when running in CI.
fixesTryGhost/Product#3792
- Previously, if you had a filter set in the members list (e.g. `status=paid`), then you searched for a member by email address, the original filter would be ignored, and any members matching the search would be returned, regardless of whether they matched the filters. Effectively, the logic was `member matches filters OR member matches search`. To make this worse, the UI still showed both the filters and the search query, leading to confusing results.
- This small change to the backend logic changes the behavior to only return members that match the filter AND the search query, so if you search for a member that does not meet the current filters, they will not be returned.
refs https://github.com/TryGhost/Product/issues/3831
---
<!-- Leave the line below if you'd like GitHub Copilot to generate a
summary from your commit -->
<!--
copilot:summary
-->
### <samp>🤖 Generated by Copilot at 5af23a9</samp>
This pull request updates and adds some test cases for the editor and
the publishing flow in Ghost. It uses a helper function to test the date
picker component in the editor, and removes a redundant test case from
the `publish-flow-test.js` file. It also adds two test cases to the
`publishing.spec.js` file, using the Playwright framework, to check the
publish time and the newsletter settings of a post.
no issue
Whilst debugging I discovered that the webhooks weren't being received by some tests, causing them to fail. I added log lines for the output from the webhook server to see if I could fix it, and the bug vanished. I narrowed it down to event listeners on the webhook server fixing it.
I'm not sure exactly how this fixes it, I'm guessing the extra events in the event queue have something to do with it.
refs: https://github.com/TryGhost/DevOps/issues/78
Some tests needed to disconnect Stripe + reconnect, so the code had to be changed to match the new Stripe Connect method.
Some tests in publishing.spec have been modified to work out-of-order, which will enable us to use fullyParallel in future (a change which brings test runs down from 85~ seconds to 50~ seconds).
refs: https://github.com/TryGhost/DevOps/issues/78
Instead of running a single instance of Ghost, we now run an instance of Ghost for each test worker.
This has the unfortunate effect that a test failing will close and restart a new instance of Ghost, but in general will be multiple times faster than sequential execution of tests.
closes https://github.com/TryGhost/Product/issues/4008
- bumps all Koenig packages
- `kg-default-nodes` contains a rendering fix that avoids creating invalid class attributes from bad `backgroundColor` values
- `kg-converters` contains an update to avoid copying over bad `backgroundColor` values when converting from mobiledoc to lexical
refs https://github.com/TryGhost/Product/issues/3832
---
<!-- Leave the line below if you'd like GitHub Copilot to generate a
summary from your commit -->
<!--
copilot:summary
-->
### <samp>🤖 Generated by Copilot at 8a40cbc</samp>
This pull request adds a feature to verify the sender email address for
a newsletter in the admin settings app. It implements a UI component, a
custom hook, and a server-side service to handle the verification
process. It also fixes a minor typo and a navigation issue in the
newsletters module.
closes https://github.com/TryGhost/Product/issues/4007
- bumps Koenig packages containing extended TextNode and HeadingNode with extra DOM parsing support for the non-semantic HTML generated by Word when copy/pasting
fixes https://github.com/TryGhost/Product/issues/4005
We no longer use the 'reason' of a recommendation, but allow a flexible
description instead. Because this is a breaking change in the API, we do
this before making this feature GA.
- Added new database utils for renaming a column
- Added new migration to rename the column
- Updated all references in code
no issue
- Removed redundant Admin X flags from the email service since we are preparing for release.
- updated snapshots
---
<!-- Leave the line below if you'd like GitHub Copilot to generate a
summary from your commit -->
<!--
copilot:summary
-->
### <samp>🤖 Generated by Copilot at fb0df07</samp>
Simplified staff URL generation for emails by removing unused feature
flag and code. This affects the `StaffServiceEmails.js` file and the
`adminXSettings` flag.
fixesTryGhost/Product#3970
- When saving a tier, it is impossible to change the capitalization of a
benefit
- The logic when saving a tier matches benefits by `name.toLowercase()`
and then overwrites the incoming change with the name from the previous
version of the benefit
- This changes the logic to match benefits the same way using
`name.toLowercase()`, but use the _incoming_ benefit's capitalization
rather than the old benefit's, to allow users to e.g. change 'TEst
benefit' to 'Test benefit'
refs https://github.com/TryGhost/Product/issues/3978
- added "GET /incoming_recommendations/" browse endpoint to the Admin
API - we store incoming recommendations as mentions in the database. The
new endpoint reuses the Mentions API underneath to fetch verified
mentions of type recommendation - recommendation-specific attributes are
returned by the new endpoint, including calculated fields such as the
"RecommendingBack" boolean
- show "Recommend back" option for sites recommending me, only if I
haven't recommended the site already
`generateOptionsData` was not taking into account the query params
`include`, `fields` and `format` could also be an array if included in
the request query like: `?fields[]=title&fields[]=slug` or
`?fields=title&fields=slug`
refs https://github.com/TryGhost/Ghost/pull/18422
- now that we're using the externally-loaded editor we need to wait for it to load and be ready before moving focus to it and starting to type
Promoted our beta editor to the default editor. Keep an eye on (or subscribe to) https://ghost.org/changelog/ for release announcements with full details.
- moved the beta editor (Lexical-based editor) to the default editor; all pages and posts will now use it
- all mobiledoc (previous editor) posts will remain mobiledoc until opened in the editor at which point will be converted to Lexical on the fly and open in the new editor
refs https://github.com/TryGhost/DevOps/issues/83
- this will now continue use the dev server assets if we tell it to,
or copy the dependency package files to the built folder otherwise
- removes `editor` from config API because it's no longer needed
- removes dependency on `editor.url` in tests, as this no longer exists
- edits dev script to pass dev server URL as env var
- adds `@tryghost/koenig-lexical` dependency to Admin
no issue
- After updating the default theme to be Source instead of Casper, the
browser tests broke because they depended on the class names in Casper,
which have changed
- This fixes that by updating the classes to be compatible with the
Source theme
refs TryGhost/Product#3510
- Added `TryGhost/Source` as a submodule in `ghost/core/content/themes` so `Source` will ship with Ghost (along with Casper)
- With this change, new installs will use `Source` as the default theme. Existing sites will have `Source` installed, but not activated, as this is a large change and we don't want to drastically change existing sites without warning. Users can upgrade to use `Source` simply by clicking 'Activate' in design settings.
- Updated protections to prevent users from uploading their own conflicting version of `Source`
refs https://github.com/TryGhost/Product/issues/3969
- this now allows themes to have up to 20 custom theme settings
- also bumps `@tryghost/zip` to try and ensure it uses the version
without fs-extra
refs https://github.com/TryGhost/Product/issues/3957
This changes how we fetch recommendations:
- Relations can be included in one query instead of extra queries
- Sorting is now possible by click or subscriber counts
refs https://github.com/TryGhost/Product/issues/3818
- added a check to compare hostname and pathnames of URLs. Different
subdomain or different pathname = different URLs, but protocol, www,
query parameters and hash fragments are ignored.
refs https://github.com/TryGhost/Product/issues/3832
---
<!-- Leave the line below if you'd like GitHub Copilot to generate a
summary from your commit -->
<!--
copilot:summary
-->
### <samp>🤖 Generated by Copilot at 1347a85</samp>
Added search functionality to the settings page using a custom hook and
a service. The `useSearch` hook uses the `useSearchService` function to
create a search service object that provides the filter and highlight
logic. The `highlightKeywords` function from the search service is
passed to the `SettingsGroupHeader` component to render the settings
with the matching keywords.
no issue
- bulk edit actions bypass the Bookshelf model hooks which meant our page reset behaviour in `onSaving` and `onDestroyed` was not being hit
- added overrides to `bulkEdit` and `bulkDestroy` to add the same page-reset behaviour any time we have a bulk edit or destroy
refs https://github.com/TryGhost/Product/issues/3938
- Updated "Recommendation received" email design
- Slightly improved how dark favicons show in dark mode
- Added TabView with counter variant to Storybook
refs https://github.com/TryGhost/Product/issues/3958
- Disabled automatic network retries for external site lookups (=> timed
out to 5s in every situation because it returned 404 when a site doesn't
implement the Ghost api)
- Disabled representing a modal when it is already present on hash
changes
- Added support for search params in modals
- Handle `?url` search param in the addRecommendationModal
refs https://github.com/TryGhost/Product/issues/3940
- the {{recommendation}} helper fetches recommendations from the Content
API and renders a HTML template with pre-defined CSS classes
- the HTML template can be overridden in themes, by uploading a file
under partials/recommendations.hbs
- the CSS classes are not pre-defined, they need to be defined in
individual themes
- if there are no recommendations, nothing is rendered
- the {{recommendations}} helper currently accepts "page", "limit",
"filter", and "order" as options
fixes https://github.com/TryGhost/Ghost/issues/17937
- We used a global Handlebars instance, which means it was reused across
Ghost
- Partials are different between parts of Ghost, that means the partials
were overwritten every time a normal Mailgun email was send
- All staff emails send after a normal newsletter would have invalid
styles because the partials for styles were overwritten
refs: https://github.com/TryGhost/Product/issues/3782
Latest version of request avoids using the OS-level name resolution system. This prevents long shutdowns from occuring where the OS is blocking the process from exiting cleanly.
The new version uses `got` 13, which has many breaking changes. Some of these are resolved within @tryghost/request (like response errors), but input parameters need to be changed.
no issue
- including a body snapshot for the pages API collection card tests causes issues because the generated HTML is dynamic and contains post creation times meaning the snapshot was unstable
- removed the body snapshot for the tests concerned for now as they are mostly there to catch saving issues rather than rendering issues
no issue
- added passthrough of `transaction` property when fetching post IDs otherwise SQLite will error with ` "Knex: Timeout acquiring a connection. The pool is probably full. Are you missing a .transacting(trx) call?"`
no issue
- act as regression tests for internal collection code changes
- useful to test as we've hit missing transaction passthrough for sqlite a couple of times that wasn't caught
fixes https://github.com/TryGhost/DevOps/issues/72
- in order to have greater control of labs flags outside of Ghost, this
commit allows Ghost to respect the value of `labs: { flagName: boolean }`
- this means we can hardcode a value to true or false, irrespective of
the value in the DB or GA flags array
- also adds tests to check functionality
refs https://github.com/TryGhost/Arch/issues/95
- We are releasing with a slight risk of failing over, so need a switch to allow disabling collections on hosted environment.
refs https://github.com/TryGhost/Arch/issues/95
refs 00e5f84d88
- Maintaining "latest" collection's static content is causing performance issues we are not able to overcome in a short period of time. Instead we leave it as a "dynamic" collection, which equals the contents of the Posts API. The "featured" collection will be saved in a "static" form as previously.
- This is roughly the same migration as in 5.64 version (see refed commit). It wipes out all of the stored collections data and only populates the featured collection.
refs https://github.com/TryGhost/Arch/issues/95
Rather than storing all of the relations between the latest collection and
posts, we know that it contains all posts. This means we don't have to keep the
collections posts in sync. Instead we can fetch them from the posts table. This
saves a lot of work during recalculation.
refs https://github.com/TryGhost/Arch/issues/95
Rather than a big nested loop to reconcile the in-memory vs. persisted
PostCollections we can instead use the events to know which rows we have to
delete and which we have to insert. This removes a tonne of work.
This implementation isn't perfect, and misses cases where the same post is
added and removed, our use-cases don't currently support that however.
no issue
Collection cards contain dynamic data that can change when there's any change to a published post but in Ghost all post/page content is rendered once on save and stored as a static string meaning we need a new approach for triggering a re-render of pages that plays well with caching.
- fixed typo in the relations/authors code that meant we weren't correctly calling the prototype method on the Post model inside the `onFetchedCollection` event handler
- updated Post model to clear the `html` field of all pages when saving or deleting a published post
- updated Post model to re-render `html` fields when fetching individual posts or a collection of posts
- modified `insertExtraPostsTags` fixture util to wrap it's concurrent post edits in a transaction otherwise MySQL errors because it hits a deadlock
refs https://ghost.slack.com/archives/C02G9E68C/p1695296293667689
- We block all outgoing networking by default in tests. When editing a
post/page, Ghost tries to send a webmention. Because of my earlier
changes
(1e3232cf82)
it tries 3 times - all network requests fail instantly when networking
is disabled - but it adds a delay in between those retries. So my change
disables retries during tests.
- Adds a warning when afterEach hook tooks longer than 2s due to
awaiting jobs/events
- We reduce the amount of webmentions that are send, by only sending
webmentions for added or removed urls, no longer when a post html is
changed (unless post is published/removed).
closes https://github.com/TryGhost/Product/issues/3818
- instead of fetching all recommendations and matching URLs on the frontend, we now query the database directly to find an existing Recommendation by URL. When comparing URLs, we don't take into account the protocol, www, query parameters nor hash fragments
fixes https://github.com/TryGhost/Product/issues/3911
For now we decided that we don't want to enable one-click-subscribe in
case a site has a required checkbox (which isn't shown during the
one-click-subscribe flow)
refs https://github.com/TryGhost/Product/issues/3850
- Added a recheck for recommendation related webmentions after boot (to
check missed webmentions during down time)
- Increased general timeouts to 15s for all webmention related HTTP
requests. Instead, increased retries to 3.
- Increased timeout for fetching webmention metadata from 2s to 15s
- Added more logging about verification and deletion status of
webmentions
refs https://ghost.slack.com/archives/C0568LN2CGJ/p1695149803260239
refs 290bc71d6a
- previous versions of `@tryghost/limit-service` did a full import of
lodash, which would bloat the bundle size, especially when we only use
a few of its functions
- I've since fixed that and this commit bumps Ghost to the smaller
version
This reverts commit 3e9da6df0c.
- changes introduced an error fetching `/admin/pages/` when using MySQL
- "The values in where clause must not be object or array"
no issue
Collection cards contain dynamic data that can change when there's any change to a published post but in Ghost all post/page content is rendered once on save and stored as a static string meaning we need a new approach for triggering a re-render of pages that plays well with caching.
- fixed typo in the relations/authors code that meant we weren't correctly calling the prototype method on the Post model inside the `onFetchedCollection` event handler
- updated Post model to clear the `html` field of all pages when saving or deleting a published post
- updated Post model to re-render `html` fields when fetching individual posts or a collection of posts
- modified `insertExtraPostsTags` fixture util to wrap it's concurrent post edits in a transaction otherwise MySQL errors because it hits a deadlock
fixes https://github.com/TryGhost/Product/issues/3830
This endpoint is required for recommendations to work: admin-x loads the incoming recommendations by querying the mentions endpoint. If the mentions flag was not enabled, this endpoint wasn't available.
closes https://github.com/TryGhost/Arch/issues/74
refs b5d1245be1
- We have turned off the collections feature flag after a unsuccessful attempt to make collections GA. With the flag turned off, collections_posts data has gone stale and needs repopulation to function properly again.
- This migration is meant to clear the data on collections_posts table and repopulated it again the same way initial migration did in 5.5/2023-07-10-05-16-55-add-built-in-collection-posts.js script.
refs https://github.com/TryGhost/Arch/issues/86
- Creating bookshelf models for each collection_post relation created a
massive overhead. On a dataset with 500k collections_posts records the
timing was roughly 7s comparing to 810ms after the optimization.
- Optimized memory and performance of collections fetching by querying post
ids only by default
refs https://github.com/TryGhost/DevOps/issues/80
- as part of moving Admin-X-Setting towards GA, we want to change it from
loading the settings externally via a CDN, to bundling it in with
Admin
- the bulk of the changes here are removing the config in Ghost, setting
up the copy to the Admin assets dir, and loading the new path in Admin
- several other changes have come along the way as I've cleaned up
unneeded code
refs https://github.com/TryGhost/Arch/issues/86
- Creating bookshelf models for each collection_post relation created a
massive overhead. On a dataset with 500k collections_posts records the
timing was roughly 7s comparing to 810ms after the optimization.
- Optimized memory and performance of collections fetching by querying post
ids only by default
refs https://github.com/TryGhost/Arch/issues/83
As we've only used the status and tiers in the cache key generation (as those
are currently the only ones that are present in DB's) we want to make sure that
content gating doesn't use any other properties, which means the cache behaviour
will match the content gating behaviour
refs https://github.com/TryGhost/Arch/issues/83
The options included are the only ones which have an effect on the response
data, as well as that we are using the properties of members which are used by
content-gating module. For the read operation we need to include the ID too.
refs https://github.com/TryGhost/Arch/issues/83
This allows endpoints to implement their own key generation, with access to the
frame object they can be smart about key generation and use only options and
context values that are appropriate.
closes https://github.com/TryGhost/Product/issues/3881
We observe the height of the recommendation table, and keep it fixed between pages — so that the UX is smoother when navigating between pages.
fixes https://github.com/TryGhost/Product/issues/3900
1. The service never returns a Recommendation Entity, but always plain
objects (which for now is the same as Recommendation without the
methods).
2. Updated the controller to be more readable and minimal (we keep this
controller, in addition to the existing endpoints and serializers)
- The controller does minimal validation and allows for type checking
(so we get compile time errors in case the service expects new fields)
- The controller uses the `UnsafeData` class to easily validate the
input from requests, and throws appropriate errors (with correct field
descriptions — "Expected a string at recommendations.0.title") without
too much boilerplate code. In addition the interface is typed, so we get
compile errors if there are breaking changes in the service.
- Removed `EntityWithIncludes`, since we now use plain objects, we
inject the relations directly into those plain objects (with some new
types that add type support)
- Added new tests to make sure that edits only affect the given fields,
and never undefined fields
- the schema.org data fo an author should primarily use the authors image as the image item instead of the cover image.
- otherwise the schema.org metadata will be invalid, since the image item is missing when no cover image has been uploaded.
closes https://github.com/TryGhost/Product/issues/3818
- in Admin, when adding a recommendation, the URL is compared against all existing ones. If the URL is already recommended, the publisher is shown an error: "A recommendation with this URL already exists.". Protocol, www, query parameters and hash fragments are ignored during the URL comparison.
- on the backend, there is another uniqueness validation for the recommendation URL. This check is redundant when adding a recommendation from Admin, but helps to keep data integrity when recommendations are added through other paths (e.g. via the API)
no issue
- added missing `context.public = true` option that tells our data fetching layer that this is a "Frontend/Content API" request and relevant filters should be applied
- adjusted require of posts service so it's only grabbed on the first render rather than every render
refs
https://www.notion.so/ghost/df5bdea8f7ea4aca9d25eceb6a1bf34c?v=be2f15b6b58b4c27a0e11374282bead0&p=163762d9513a4e6dbd60c28e19228fdc&pm=s
- Added a modal to confirm that the new support email has been verified.
- to achieve that a couple of adjustments had to be made
- Updated the RoutingProvider to handle routes with query params.
- Added a new useQueryParams hook to grab query params where needed.
- wired up the email verification api.
- added feature flags / labs logic to the core package with the new URL and updated test.
---
<!-- Leave the line below if you'd like GitHub Copilot to generate a
summary from your commit -->
<!--
copilot:summary
-->
### <samp>🤖 Generated by Copilot at 3ff8add</samp>
This pull request adds email verification functionality for the support
email address in the portal settings. It fixes a bug in the routing
provider, adds a new API function, a new custom hook, and a new modal
component to handle the verification process. It also updates the
settings query with the verified email address.
refs 488af56ef9
- The referenced commit introduced a postsService initializaiton at the top level of the module - causing cascading failure all the way down in the URL service, whe the ENV variables are not set.
- This fix is just a quick fix to unblock the main branch. A proper initialization of the service should be done ensuring we don't have to re-create a posts-service instance on each render method call.
refs TryGhost/Product#3883
- passes endpoint through to the lexical renderer for collections
rendering
- ghost still needs a `kg-default-nodes` and `kg-lexical-html-renderer`
update to support this completely
no issue
`PostsService` and `CollectionsService` were missing some passthroughs and had differing naming for a transaction instance on the `options` object which meant SQLite would hang if the Lexical renderer called out to `PostsService.browsePosts`
- added passthrough of `transacting` to the Lexical renderer ready for implementation of the collection-fetching function
- added rename of `options.transacting` to `options.transaction` and passthrough from `PostsService` to `CollectionsService` (passthrough from collections repository to bookshelf and required `transaction->transacting` was already in place)
refs https://github.com/TryGhost/Product/issues/3875
When a member had a comped subscription, the portal was showing an
incorrect expiry date. This was because the `expiry_date` was being set
to the `created_at` date of the subscription, rather than the
`expiry_date` of the comped subscription
https://github.com/TryGhost/Arch/issues/90
- When a post.deleted event is emitted the original 'data' object does not contain an 'id' property. The logic in collections service assumes the id would be present to update the collections efficiently.
refs https://github.com/TryGhost/Product/issues/3874
- the new collections card needs to access the Content API rather than the Admin API in order to show the card as it will appear on the front-end but we don't have a default integration that can be fetched via the Admin API for Admin to use when fetching from the Content API
- adds a new "Ghost Core Content API" integration with the `core` type so that it can be read via the `/admin/integrations/` endpoint and used in Admin to make Content API requests
refs https://github.com/TryGhost/Arch/issues/86
bookshelf-relations was generating tonnes of select queries from the
posts table in order to update the relations. We've instead implemented
this ourselves, so as to avoid the superfluous fetches. Working closer to
the db like this is nice, and makes you think more about performance.
This logic could be pulled out into a util (not bookshelf plugin) where
it could be used explicitly, but with the complexity hidden, we'll see ig.
refs https://github.com/TryGhost/Ghost/pull/18028
- The previous conditional meant that if the "host settings" collections enabled flag was set, we couldn't disable collections. The referenced pull request would also disable the collections across all of the hosted environment instances. The updated logic optionally takes into account the "labs" flag, as it should have from the very beginning.
refs https://github.com/TryGhost/Arch/issues/87
- The newsletters in members payload have leaked internal properties from Public Members API. The code skipped the output serialization step, which is now in place.
- The newsletter resource returned from the API consistently returns these properties:
id,
name,
description,
sort_order
refs https://github.com/TryGhost/Arch/issues/87
- There was no test whatsoever! Adding a super basic test to have some certainty the output doesn't change after a refactor
refs https://github.com/TryGhost/Arch/issues/87
- The Members Admin API and members.* webhooks were returning too many fields in the nested `newsletters` objects. There was no "allowlist" serializer for the newsletter object, which meant every time we add a new field to the database we would unintentionally return extra fields without a second thought.
- With this change only following fields will be returned with `members[x].newsletters[x]`:
'id',
'name',
'description',
'status'
refs https://github.com/TryGhost/Arch/issues/87
- Round 2 for the previous commit. Removes use of `anyArray` for all
- Using `anyArray` in snapshot test is an anti-pattern which leads to leaking output fields unintentionally when the API changes.
- Adding these fixes is fundamental work before changing the output of 'member.newsletters' property
refs https://github.com/TryGhost/Arch/issues/87
- Using `anyArray` in snapshot test is an anti-pattern which leads to leaking output fields unintentionally when the API changes.
- Adding these fixes is fundamental work before changing the output of 'member.newsletters' property
no issue
- Do not set ?ref in recommendations if analytics is disabled
- Do not send url_history if analytics is disabled
- Expose outboundLinkTagging as a public setting
fixes https://github.com/TryGhost/Product/issues/3851
- Order was not applied via the CRUD plugin
- Removed usage of CRUD findAll, and swapped to Bookshelf fetchAll
instead, to decrease dependencies of invisible Bookshelf plugins logic
- Reverted page and limit options possibility via findAll method
fixes https://github.com/TryGhost/Product/issues/3822
fixes https://github.com/TryGhost/Product/issues/3838
This PR became a bit big because it affected multiple parts of Ghost
that needed to be updated to prevent breaking anything.
### Backend
- Added pagination to the recommendations API's
- Updated BookshelfRepository template implementation to handle
pagination
- Allow to pass `page` and `limit` options to Models `findAll`, to allow
fetching a page without also fetching the count/metadata (=> in the
repository pattern we prefer to fetch the count explicitly if we need
pagination metadata)
- Added E2E tests for public recommendations API (content API)
- Extended E2E tests of admin recommendations API
### Portal
- Corrected recommendations always loaded in Portal. Instead they are
now only fetched when the recommendations page is opened.
### Admin-X
- Added `usePagination` hook: internally used in the new
`usePaginatedQuery` hook. This automatically adds working pagination to
a query that can be used to display in a table by passing the
`pagination` and `isLoading` results to the `<Table>`
- Added placeholder `<LoadingIndicator>` component
- Added a loading indicator to `<Table>`. This remembers the previous
height of the table, to avoid layout jumps when going to the next page.
closes https://github.com/TryGhost/Product/issues/3803
Previously when the beta editor was enabled, using `?source=html` to create posts via the API would create posts in the old editor rather than the beta. This change switches conversion over to the new editor format when the beta is enabled so the full flow can be tested.
- added `htmlToLexicalConverter` method to our lexical library
- updated post and page input serializers to add html-to-lexical conversion when the beta editor is enabled
- updated post model to handle the mobiledoc+lexical co-existing state
- this is a special case that is only valid for `?source=html` because providing both directly via the API is prohibited
- we need the extra check here because at the input serializer layer we don't have access to the model to check if we're updating a mobiledoc post or a lexical post so the serializer sets both formats on a `?source=html` request when the beta is enabled and lets the model handle choosing the correct one
fixes https://github.com/TryGhost/Product/issues/3820
- This adds a new public site endpoint in the members API to check if a
site can offer the one-click-subscribe feature
- This is implemented on the members API as a copy of the `site`
endpoint because the admin API site endpoint is protected by CORS and
mainly because it can be served on a different domain than the
recommended site and this is hard to detect reliably from the frontend
- Added a new calculated setting `allow_self_signup`, which can replace
the setting that is currently used in Portal (best to do this after a
release otherwise we risk creating issues if a patch release happens)
closes https://github.com/TryGhost/Product/issues/3799
- the recommendations_enabled setting is updated when a recommendation
is created or deleted. It's enabled as soon as there is at least one
recommendation in the database
- the recommendations_enabled setting exists to avoid fetching the
recommendation count from the database directly in themes. The setting
is cached and doesn't need a read every time from the database
closes https://github.com/TryGhost/Product/issues/3827
- links following a line break in the editor were being rendered before the line break when previewing/publishing
- bumps Koenig packages which includes relevant fix in `@tryghost/kg-lexical-html-renderer`
refs https://github.com/TryGhost/Ghost/issues/17932
- we were missing `chunk.208.dbf172ad32f72f21a5dc.js` from our published tarball
- turns out this is due to the lines in the `.npmignore` file to remove
.db files, which also matched this file
- we can make the regex more specific to avoid these cases
closes https://github.com/TryGhost/Product/issues/3675
refs c98bf80248
As part of our architecture guidelines Repository implementations should protect
against invalid or malformed data in persistence. We do not want read operations
of Entities to throw because of such data. For some fields that bad data can be
fixed or handled in the constructor or static create factory method and replaced
with valid data, others will cause the factory to throw.
This means that Repositories should catch these errors and exclude those
entities from their results. We log the errors in Sentry so that we have
visibility on the state of bad data in DBs
JSDoc has a problem with using values as types across repositories, rather than
getting `Offer` as the type we end up with `typeof Offer` as the type - which is
incorrect. Instead we use `import` syntax inside of JSDoc which resolves correctly
As per our architecture guidelines we want to keep bookshelf implementations of
Repositories in Ghost core, so that all the bookshelf code is kept together, and
the packages implementing business logic with entities and services require less
dependencies to test. This separation should also help us inadvertently add
business logic to repository implementations by having a more "physical"
boundary between them.
refs https://forum.ghost.org/t/anyone-else-seeing-page-too-wide-errors/40695
- google search console snapshots websites with their full height instead of scrolling
- that makes the value of vmax too much, especially when a page has lots of content
- this fixes the issue by adding max limit to the padding values with vmax
no issue
Previously the beta editor only worked for newly created posts/pages, any older content would open with the original editor. This change enables automatic conversion of old content to the new content format when a post/page is opened in the admin interface allowing new features like signup and advanced header cards to be used on existing content.
- removed `convertToLexical` feature flag
- where necessary switched to using just the `lexicalEditor` feature flag in its place
- moved the "L"/"M" indicators on the posts list to a new `lexicalIndicators` feature flag to make debugging/development easier
- added a redirect to the original editor route so that any route to opening the editor (such as the `/edit` front-end shortcut, or other areas of Admin) will open in the beta editor
- avoids confusing/inconsistent behavior
refs https://github.com/TryGhost/Arch/issues/80
refs 3960bfac1d
- The killswitch (a setting in host settings) is needed to control the feature on a hosted environment, so we can safely turn it off if it causes any major issues.
refs https://github.com/TryGhost/DevOps/issues/68
- without a name, tools such as New Relic report the function as
`<anonymous>`, which makes it incredible hard to follow the code flow
- this commit adds a function name to all middleware I can find that
doesn't already have one, which should fill in a lot of those gaps
refs https://github.com/TryGhost/DevOps/issues/68
- we want New Relic to be one of the first modules to load so it can
instrument the rest of our code
- previously this would not have been the case, and it would have missed
out on instrumenting the config and logging code
- this moves the require to be the first step in the process if the
PRO_ENV env var is set
closes https://github.com/TryGhost/Arch/issues/13
- Model to Domain event interceptor is a class that does not strictly belong to Collections. It's supposed to be used in any new code that depends on legacy bookshelf model events. Extracted it's initialization to it's own service for clarity and visibility.
The future work around collections requires the read only portions
of the Collections Admin API to be enabled without a flag.
The write endpoints are only for custom collections which aren't required.
refs https://github.com/TryGhost/Arch/issues/73
Since we've fixed the issues which were executing performance affecting DB
queries, we can enable the background syncing of collections again. This couple
with a new migration to populate the default collections will allow us to start
work on the collections card and will make rolling that card out to GA smoother
and easier as all the required data will be in place.
refs https://github.com/TryGhost/Arch/issues/73
This is just an initial stab at making sure we don't introduce extra DB
queries related to collections without being aware of it.
refs https://ghost.slack.com/archives/C02G9E68C/p1692816097875899
- With introduction of extra e2e test coverage for Collections some tests started to fail at random. The root issue here was the transaction processing collections was started before the original bulk action (bulk edit, bulk publish/unpublish, etc.) was fully committed. The full transaction commit happens with the bulkAction method return inside of `if (!options.transacting) {` block.
refs https://github.com/TryGhost/Product/issues/3504
- This adds support for translations, but doesn't yet translate every
possible string in the app.
- Only active if beta translations is enabled
refs https://github.com/TryGhost/Arch/issues/77
- We were missing e2e test coverage for when the tag used in collection filters was removed. This changeset improves the situation.
refs https://github.com/TryGhost/Arch/issues/77
- During initial development we have missed to support collections update when tags are added to posts in bulk. It's especially valid usecase since we can define automatic collection with a filter containing not yet existing tags.
refs https://github.com/TryGhost/Arch/issues/47
This ensures that we only have collections which have a valid filter in terms of
- Valid NQL string
- Uses only properties which are valid to filter on
- Only has an empty filter in the case of the "latest" collection
refs https://github.com/TryGhost/Arch/issues/47
This change allows us to throw errors when instantiating invalid entities,
whilst not breaking things when we have bad data in the database. What we can
do is act as if the bad rows are not present, whilst surfacing an error in
sentry to alert us to such cases.
refs https://github.com/TryGhost/Arch/issues/47
We've configured bookshelf to force empty strings to null, but this is
undesired behaviour here, so unfortunately we have to leak some business
logic into the repository.
This needs to be done to correctly support our filter validation logic.
fixes https://github.com/TryGhost/Product/issues/3752
- Added some extra tests for edge cases
- Updated handling of multiple subscriptions so they are handled better
- Canceling a subscription when the member still has other subscriptions will now get handled correctly where the status and products of the member stay intact
refs https://github.com/TryGhost/Arch/issues/71
- With describe/it block levels mixed on the top level of the test suite the order fo test execution was scattered around. Having "describe" groups for each of the BREAD methods makes things more organized and readable.
refs https://github.com/TryGhost/Arch/issues/73
With the latest version of bookshelf-relations we're able to define a model
specific hook which allows us to ignore sort_order updates on automatic
collections, which don't require their order to be persisted.
fixes https://github.com/TryGhost/Product/issues/3728
- When importing members from Stripe with an existing offer, that didn't
exist in Ghost, the offer never got linked with the imported
subscription because of a missing return statement.
- Fixes importing offers with duplicate names
- Added E2E tests for creating members from a Stripe Customer ID
closes https://github.com/TryGhost/Arch/issues/76
- The posts test suite was failing when run in isolation. This was due to "collections" labs flag not being turned on, the events were not going through to collections service correctly
fixes https://github.com/TryGhost/Product/issues/3723
This also fixes usage of localhost instead of 127.0.0.1 as a test URL
for playwright. This caused issues for cookies because the member
impersonation navigated to 127.0.0.1 instead of localhost, meaning that
the next page.goto call would go to localhost and lose the cookies.
closes https://github.com/TryGhost/Ghost/issues/17681
- updated `prepareContextResource()` to make sure `show_title_and_feature_image` is always removed from pages
- updated `formatResponse.entries()` to apply the same `@page` local behaviour when it's passed a `data.page` object to account for custom routed pages
no issue
- We were loading the Explore iframe together with all assets in Admin
- This change will avoid that and only start loading and rendering Explore, once it's clicked
refs https://github.com/TryGhost/Ghost/pull/17609
- The tests for content gating started to fail with introduction of the index on `published_at` data in for `posts` table. The reason for the failure was identical `published_at` date set during the fixture insertion, making the returned results change order non-deterministically. The problem is mostly in how the test is set up as it's quite unrealistic to have multiple posts in the system inserted at the same time down to millisecond. Maybe... by some coincidence, but thats not a problem we should care too much about imo.
refs https://github.com/TryGhost/Arch/issues/18
- The prev/next helpers are slow and are causing major performance issues. The helpers are using `posts.published_at` for comparisons extensively, which causes a full table scan - bad for query performance.
- We use published_at in other queries too (like default order for queries fetching all posts), so there might be a slight performance boost across the system with this new index.
closes https://github.com/TryGhost/Product/issues/3661
- until now, Portal was not loaded if members were disabled. With the
introduction of Tips & Donations, signed-off readers can also make
payments, using the Portal link /#/portal/support.
- now, Portal is loaded when Tips & Donations are enabled, even if
Memberships are disabled
- depending on the member signup access, the top bar / trigger button
Portal buttons are hidden as before (signup/subscribe hidden if access is set to none, subscribe hidden if
access is set to invite-only)
- for any other signup / signin Portal links (e.g., added by the theme,
or added via a Post/Page), a new popup informs the reader when
Memberships are disabled: "Memberships unavailable, contact the site
owner for access".
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 8367091</samp>
This pull request removes the `headerUpgrade` feature flag and enables
the new header card by default in the editor. It also hides the old
header card from the editor menu unless the `labs.headerV1` setting is
enabled.
closes https://github.com/TryGhost/Product/issues/3661
- until now, Portal was not loaded if members were disabled. With the
introduction of Tips & Donations, signed-off readers can also make
payments, using the Portal link /#/portal/support.
- now, Portal is loaded when Tips & Donations are enabled, even if
Memberships are disabled
- depending on the member signup access, the "sign in" / "subscribe"
Portal buttons are hidden (both hidden if none, signup hidden if
invite-only)
- for any other signup / signin Portal links (e.g., added by the theme,
or added via a Post/Page), a new popup informs the reader as such when
Memberships are disabled: "Memberships unavailable, contact the site owner for access".
refs: https://github.com/TryGhost/DevOps/issues/56
The new monobundle package now ignores any package directory if it doesn't contain a package.json. These non-packages are occasionally restored from cache when pulling dependencies.
refs TryGhost/Product#3638
- Added `convert_to_lexical` flag to the posts/pages edit endpoint
- Added 'convertToLexical' feature flag so we can enable/disable this
feature independently from the main lexical beta flag
- Modified admin posts/pages list to point to the lexical editor for
_all_ posts, regardless of mobiledoc vs lexical (if the flag is on)
- Added call to edit endpoint with `convert_to_lexical` in the lexical
editor admin route if the page/post is currently in mobiledoc and the
flag is enabled
fixes https://github.com/TryGhost/Product/issues/3687
After this change, relative URLs in emails will be replaced with
absolute URLs using the post URL. Making relative Portal URLs possible
etc.
Updates the test data generator to fix invalid URL encoding (somehow a
backslash + escaped double quote was added when it wasn't required).
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 2f86a35</samp>
Updated packages for rendering post and page content. This fixes some
bugs and improves the handling of HTML elements.
no issue
- some tweaks inside `kg-default-nodes`, requires an update in Ghost.
---
<!-- Leave the line below if you'd like GitHub Copilot to generate a
summary from your commit -->
copilot:summary
no issue
- made adjustment to `kg-default-nodes` that needs bumping on Ghost to
have those changes reflected.
---
<!-- Leave the line below if you'd like GitHub Copilot to generate a
summary from your commit -->
<!--
copilot:summary
-->
### <samp>🤖 Generated by Copilot at 77ea2d6</samp>
Updated Koenig Editor dependencies to fix bugs and enhance performance.
This affects the `@tryghost/kg-default-nodes` and
`@tryghost/kg-lexical-html-renderer` packages in
`ghost/core/package.json`.
By using the `collections_posts` table as a pivot table, I couldn't see
a way to get bookshelf to *not* load the Post models for the relation.
We don't actually need those Post models for our usescases, the the
queries were causing issues with our database servers! Here we've added
a new CollectionPost model which allows us to treat the
collections_posts table as a resource ratherthan pivot, and means we can
use the hasMany relation rather than belongsToMany relation. This
removes all queries to the posts table when fetching collections with
relations
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 ee5f8bf</samp>
Updated Koenig Editor dependencies in `package.json` to improve editor
performance and stability.
no issue
- Snapshot tests were incorrect but we weren't catching it because CI
was retrying them and yielding false passes
- This fix just fixes the broken tests, which will allow us to fix the
issue with CI yielding false passing results
closes https://github.com/TryGhost/Product/issues/3666
- added computed setting "donations_enabled"
- added logic to persist "donations_suggested_amount" and "donations_currency"
- used "donations_suggested_amount" and "donations_currency" when initiating a new Stripe Checkout for donations
- added copy functionality to "your link" in Tips & Donations settings
refs: https://github.com/TryGhost/DevOps/issues/11
This is a pretty huge commit, but the relevant points are:
* Each importer no longer needs to be passed a set of data, it just gets the data it needs
* Each importer specifies its dependencies, so that the order of import can be determined at runtime using a topological sort
* The main data generator function can just tell each importer to import the data it has
This makes working on the data generator much easier.
Some other benefits are:
* Batched importing, massively speeding up the whole process
* `--tables` to set the exact tables you want to import, and specify the quantity of each
We've been seeing an increased number of database queries, which are potentially
caused by the collections syncing logic. Whilst we haven't narrowed the cause
down precisely we want to disable this logic unless the flag is enabled.