Commit Graph

390 Commits

Author SHA1 Message Date
Kevin Ansfield
d5a9731845
Fixed email_recipients indexes to match query usage (#19918)
closes https://linear.app/tryghost/issue/ENG-791/migration-to-fix-email-recipients-indexes

Our indexes over single columns (`delivered_at`, `opened_at`, `failed_at`) were ineffective because the only time we query those is alongside `email_id` meaning we were frequently performing full table scans on very large tables during our email analytics jobs.

- added migration to add new indexes covering `email_id` and the respective columns
- added migration to drop the old indexes that weren't being used in any query plans

Local runtime with ~2M email_recipient rows:
- before: 1.7s
- after: 99ms

Explain output...

before:
```
+----+-------------+------------------+------------+-------+----------------------------------------------------------------------------------+----------------------------------------------+---------+-------+--------+----------+------------------------------------+
| id | select_type | table            | partitions | type  | possible_keys                                                                    | key                                          | key_len | ref   | rows   | filtered | Extra                              |
+----+-------------+------------------+------------+-------+----------------------------------------------------------------------------------+----------------------------------------------+---------+-------+--------+----------+------------------------------------+
|  1 | UPDATE      | emails           | NULL       | index | NULL                                                                             | PRIMARY                                      | 98      | NULL  |      1 |   100.00 | Using where                        |
|  4 | SUBQUERY    | email_recipients | NULL       | range | email_recipients_email_id_member_email_index,email_recipients_failed_at_index    | email_recipients_failed_at_index             | 6       | NULL  |   2343 |     7.76 | Using index condition; Using where |
|  3 | SUBQUERY    | email_recipients | NULL       | ref   | email_recipients_email_id_member_email_index,email_recipients_opened_at_index    | email_recipients_email_id_member_email_index | 98      | const | 159126 |    50.00 | Using where                        |
|  2 | SUBQUERY    | email_recipients | NULL       | ref   | email_recipients_email_id_member_email_index,email_recipients_delivered_at_index | email_recipients_email_id_member_email_index | 98      | const | 159126 |    50.00 | Using where                        |
+----+-------------+------------------+------------+-------+----------------------------------------------------------------------------------+----------------------------------------------+---------+-------+--------+----------+------------------------------------+
```

after:
```
+----+-------------+------------------+------------+-------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+----------------------------------------------+---------+------+--------+----------+--------------------------+
| id | select_type | table            | partitions | type  | possible_keys                                                                                                                                                                 | key                                          | key_len | ref  | rows   | filtered | Extra                    |
+----+-------------+------------------+------------+-------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+----------------------------------------------+---------+------+--------+----------+--------------------------+
|  1 | UPDATE      | emails           | NULL       | index | NULL                                                                                                                                                                          | PRIMARY                                      | 98      | NULL |      1 |   100.00 | Using where;             |
|  4 | SUBQUERY    | email_recipients | NULL       | range | email_recipients_email_id_member_email_index,email_recipients_email_id_delivered_at_index,email_recipients_email_id_opened_at_index,email_recipients_email_id_failed_at_index | email_recipients_email_id_failed_at_index    | 104     | NULL |     60 |   100.00 | Using where; Using index |
|  3 | SUBQUERY    | email_recipients | NULL       | range | email_recipients_email_id_member_email_index,email_recipients_email_id_delivered_at_index,email_recipients_email_id_opened_at_index,email_recipients_email_id_failed_at_index | email_recipients_email_id_opened_at_index    | 104     | NULL | 119496 |   100.00 | Using where; Using index |
|  2 | SUBQUERY    | email_recipients | NULL       | range | email_recipients_email_id_member_email_index,email_recipients_email_id_delivered_at_index,email_recipients_email_id_opened_at_index,email_recipients_email_id_failed_at_index | email_recipients_email_id_delivered_at_index | 104     | NULL | 146030 |   100.00 | Using where; Using index |
+----+-------------+------------------+------------+-------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+----------------------------------------------+---------+------+--------+----------+--------------------------+
```
2024-04-03 17:52:52 +01:00
Fabien 'egg' O'Carroll
3d3b3ff701
Fixed Editors being able to invite Editors (#19904)
ref ENG-774
ref https://linear.app/tryghost/issue/ENG-774

Staff Tokens will have both a `user` and an `apiKey` present on the
`loadedPermissions`.

The check here for `apiKey` was written when we could assume that an
`apiKey` was an Admin Integration - so it completely overwrote the
previous `allowed` list. When we added the concept of Staff Tokens -
this resulted in a privilege escalation.

This is a good lesson in not using proxies or indicators for data, as
changes elsewhere can invalidate them - if we had been specific and
checked the role of the current actor we wouldn't've had this bug!
2024-03-26 00:45:08 +07:00
Steve Larson
a1c4e64994
Added queueing middleware to handle high request volume (#19887)
ref https://linear.app/tryghost/issue/CFR-4/
- added request queueing middleware (express-queue) to handle high
request volume
- added new config option `optimization.requestQueue`
- added new config option `optimization.requestConcurrency`
- added logging of request queue depth - `req.queueDepth`

We've done a fair amount of investigation around improving Ghost's
resiliency to high request volume. While we believe this to be partly
due to database connection contention, it also seems Ghost gets
overwhelmed by the requests themselves. Implementing a simple queueing
system allows us a simple lever to change the volume of requests Ghost
is actually ingesting at any given time and gives us options besides
simply increasing database connection pool size.

---------

Co-authored-by: Michael Barrett <mike@ghost.org>
2024-03-21 09:25:07 -05:00
Fabien O'Carroll
cb72835af1 Removed support for id specific permissions
ref ENG-728
ref https://linear.app/tryghost/issue/ENG-728

This is not used anywhere, and makes the code more complicated, it's a good
step toward simplifying permissions and pulling them out of the database.
2024-03-21 00:21:40 +07:00
Fabien 'egg' O'Carroll
7cc65c18cc
Added missing permissions to Contributor & Editor (#19881)
ref ENG-728
ref https://linear.app/tryghost/issue/ENG-728

This is NOT a functionality change. The Post#permissible method unit
tests have been updated to pass `true` as `hasUserPermission` and we can
see that the permission functionality remains the same.

The permissible method of the post model is responsible for removing
permission based on the data that is being modified, but the permissions
module is setup to allow the permissible method to grant permission -
this means that we call permissible, even if the current actor doesn't
have permission, this results in code that is hard to understand and
manage.

We are going to be instead returning early if an actor does not have
permission, this will allow permissible method signatures to be greatly
simplified (removing the need for hasUserPermission, hasApiKeyPermission
& hasMemberPermission arguments).
2024-03-20 20:36:07 +07:00
Daniel Lockyer
134c33cef5
🐛 Fixed missing source + resized images producing rendered 404 (#19869)
fixes https://linear.app/tryghost/issue/ENG-746/http-500-responses-when-handle-image-sizes-middleware-hits-missing

- in the event a request comes in for a resized image, but the source
image does not exist, we return a rendered 404 page
- we do this because we pass the NotFoundError to `next`, which skips
over the static asset code where we return a plaintext 404
- also included a breaking test that ensure we go to the next middleware
without an error
2024-03-18 18:32:10 +01:00
Fabien 'egg' O'Carroll
6a35f6e4cc
Fixed get helper cache optimizations (#19865)
ref [ENG-747](https://linear.app/tryghost/issue/ENG-747/)
ref https://linear.app/tryghost/issue/ENG-747

H'okay - so what we're trying to do here is make get helper queries more
cacheable. The way we're doing that is by modifying the filter used when
we're trying to remove a single post from the query.

The idea is that we can remove that restriction on the filter, increase
the number of posts fetched by 1 and then filter the fetched posts back
down, this means that the same query, but filtering different posts,
will be updated to make _exactly_ the same query, and so share a cache!

We've been purposefully restrictive in the types of filters we
manipulate, so that we only deal with the simplest cases and the code is
easier to understand.
2024-03-15 00:18:15 +07:00
Aileen Booker
f16d9802d0 Added ability to pass minThreshold for Milestone Slack notifications
closes ENG-632

- This listens to a new property in the `milestones` config to set a minimum value of Milestones we wanna use the Slack notification service for
2024-03-14 12:06:43 -04:00
Daniel Lockyer
360ecf15ae 🐛 Fixed HTTP 500 error when given incorrect Range header
ref ENG-729
ref https://linear.app/tryghost/issue/ENG-729/incorrect-range-header-leads-to-http-500-errors

- we didn't have handling here for the `RangeNotSatisfiableError` that
  can come from express/serve-static/send
- as a result, passing an invalid range would cause a 500 error
- this prevents that and adds a breaking test
2024-03-11 19:14:30 +01:00
Fabien 'egg' O'Carroll
7f392c305b
Added output to the get helper when the timeout is exceeded (#19761)
refs https://linear.app/tryghost/issue/ENG-670

We keep running into issues with a sites content not being correct,
and slow get helpers being the suspect - but it's difficult to prove.
The idea behind this it to give us concrete evidence, which will allow
us to diagnose the problem faster.
2024-02-28 07:35:16 +07:00
Steve Larson
2c166582fd
Added config option to disable db backups (#19614)
refs https://linear.app/tryghost/issue/ENG-600
- users need an option so they can perform actions like delete users
without blowing up Ghost as large dbs can OOM node
2024-02-01 12:09:41 -06:00
Aileen Booker
c4912665e5 Removed DomainEventsAnalytics
closes CA-11

- Segment events in Ghost core are not used currently
2024-01-30 13:58:22 -04:00
Simon Backx
7d0be3f1a9
Improved sending email addresses for self-hosters (#19617)
ref https://github.com/TryGhost/Ghost/issues/12802
fixes DMA-27

- You can choose any support and newsletter email address in the UI
without verification (as long as your SMTP-server / Mailgun can send
from it)
- All emails will use the mail.from config as the from address as a
default:
- Staff notification emails no longer use the made up ghost@domain email
address
    - Newsletters no longer default to 'noreply@domain' 
- Member related emails (signin/signup/comment notifications...) will
continue to be send from the chosen support address (Portal settings →
Account page), but will now default to the mail.from config instead of
noreply@domain if no support address is set.
2024-01-30 11:21:08 +01:00
Chris Raible
975bb6849f
Renamed performanceMonitoring config to telemetry (#19613)
no issue

- Renaming the configuration parameter created in this commit:
e0dae46dfc
- No functional difference, this change just makes the configuration a
bit more succinct
2024-01-29 11:56:17 -08:00
Chris Raible
e0dae46dfc
Added basic instrumentation to the database connection pool (#19589)
no issue

- To help debug potential causes of slow/aborted get helpers, it would
be cool to get more visibility into how Ghost handles database
connections, particularly if it has to spend a long time waiting to
acquire a new connection from the pool.
- Under the hood, knex uses a package called tarn
(https://github.com/Vincit/tarn.js/tree/3.0.2) to manage the connection
pool. Tarn provides some hooks for instrumentation, so we can use those
to get some basic visibility into the connection pool.
- This PR adds handling for creating, acquiring and releasing
connections from Tarn's connection pool which logs some basic metrics,
particularly the queue length and time it takes to acquire a connection.
2024-01-29 10:25:35 -08:00
Chris Raible
794ef85968
Added Sentry instrumentation for get helpers (#19576)
no issue

- To help debug ABORTED_GET_HELPER errors, this PR adds Sentry
instrumentation to the get helpers
- It also adds the homepage, any pages/posts, the tag page, and the
author page to the list of transactions that will send to Sentry
2024-01-24 18:50:48 -08:00
Simon Backx
eb063f7a40
Fixed clearing invalid sender_email when changing newsletter sender_reply_to (#19555)
fixes PROD-102

When a newsletter has a sender_email stored in the database that Ghost
is not allowed to send from, we no longer return it as sender_email in
the API. Instead we return it as the sender_reply_to. That way the
expected behaviour is shown correctly in the frontend and the API result
also makes more sense.

In addition to that, when a change is made to a newsletters reply_to
address we'll clear any invalid sender_email values in that newsletter.
That makes sure we can clear the sender_reply_to value instead of
keeping the current fallback to sender_email if that one is stored.

On top of that, this change correclty updates the browse endpoint to use
the newsletter service instead of directly using the model.
2024-01-23 16:10:11 +01:00
Michael Barrett
57810cd34e
Added allowlist for Sentry transactions (#19538)
refs
[ARCH-41](https://linear.app/tryghost/issue/ARCH-41/add-allowlist-for-sentry-transactions)

Added allowlist for Sentry transactions so that we can better control
the data we are putting into Sentry
2024-01-23 08:22:57 +00:00
Aileen Booker
75874151fd Removed ModelEventsAnalytics
refs https://linear.app/tryghost/issue/BIZ-6/[wip]-update-segment-events

- With the removal of the `integration.added` event, we have no more model events remaining to listen to for our analytics
- Removal of the function entirely seems the easier and more straightforward way
2024-01-18 10:29:56 -04:00
Aileen Booker
e4b9305e2a Removed unneeded analytics for model events
refs https://linear.app/tryghost/issue/BIZ-6/[wip]-update-segment-events

- Removed model events to listen to: `post.published`, `page.published`, and `theme.uploaded` in segment service,  as we're not actively using those.
- Updated tests to reflect the changes (from 4 events to 1 model event)
2024-01-18 10:29:56 -04:00
Kevin Ansfield
f88fdfe363
Increased test timeout for HTML transform unit tests (#19490)
closes https://github.com/TryGhost/Product/issues/4086

- JSDOM require on CI has been found to occasionally be very slow causing random timeouts
- doubled test time to eliminate the noise
2024-01-16 11:16:46 +00:00
Michael Barrett
1263cf148e
Updated Sentry env to use PRO_ENV when available (#19441)
refs
[ARCH-33](https://linear.app/tryghost/issue/ARCH-33/fix-sentry-environment)

To ensure that we are correctly identifying the environment that data is
being sent to Sentry from, we can use the `PRO_ENV` environment variable
if it is available. This will be set to `production` in production and
`staging` in staging. If `PRO_ENV` is not available, we will fall back
to retrieving the environment from config (`env`)
2024-01-05 12:10:39 +00:00
Simon Backx
3f6ea04c43
Added portal default plan setting (#19238)
fixes PROD-61

This adds a new default plan setting. It defaults to yearly, which is
the current default selected interval in Portal.

Behind the new portal improvements feature flag, the default plan can be
changed. It will also change automatically if the available intervals
are changed.

This PR also wires up passing the new setting to the Portal preview.
2023-12-06 11:39:58 +01:00
Simon Backx
3687feca07
Updated support email address verification for DMARC changes (#19147)
fixes GRO-71

- Current flow: unchanged
- New managed flow: verification required
- New managed flow with custom sending domain: only verification
required for different domains
- Self hosters (feature flag): no verification required
2023-11-28 15:06:58 +01:00
Fabien 'egg' O'Carroll
616247b6d5
Indexed over members_newsletters(newsletter_id, member_id) (#19156)
refs https://github.com/TryGhost/Product/issues/4181

We were seeing slow queries when joining on this table, and the index
speeds them up. The down migration is tricky because when we add the
index MySQL can optimise away some `KEY` indexes on the `newsletter_id`
column. When we then go to remove the newly created index, there is no
index for the FK! 

We also remove the use of `force index` as 1. the index we're forcing is
optimised away and 2. we don't need it anymore!


Co-authored-by: Daniel Lockyer <hi@daniellockyer.com>
2023-11-28 12:20:14 +00:00
Simon Backx
17ec1e8937
Added email address alignment protections (#19094)
ref GRO-54
fixes GRO-63
fixes GRO-62
fixes GRO-69

When the config `hostSettings:managedEmail:enabled` is enabled, or the
new flag (`newEmailAddresses`) is enabled for self-hosters, we'll start
to check the from addresses of all outgoing emails more strictly.

- Current flow: nothing changes if the managedEmail config is not set or
the `newEmailAddresses` feature flag is not set
- When managedEmail is enabled: never allow to send an email from any
chosen email. We always use `mail.from` for all outgoing emails. Custom
addresses should be set as replyTo instead. Changing the newsletter
sender_email is not allowed anymore (and ignored if it is set).
- When managedEmail is enabled with a custom sending domain: if a from
address doesn't match the sending domain, we'll default to mail.from and
use the original as a replyTo if appropriate and only when no other
replyTo was set. A newsletter sender email addresss can only be set to
an email address on this domain.
- When `newEmailAddresses` is enabled: self hosters are free to set all
email addresses to whatever they want, without verification. In addition
to that, we stop making up our own email addresses and send from
`mail.from` by default instead of generating a `noreply`+ `@` +
`sitedomain.com` address

A more in depth example of all cases can be seen in
`ghost/core/test/integration/services/email-addresses.test.js`

Includes lots of new E2E tests for most new situations. Apart from that,
all email snapshots are changed because the from and replyTo addresses
are now included in snapshots (so we can see unexpected changes in the
future).

Dropped test coverage requirement, because tests were failing coverage
locally, but not in CI

Fixed settings test that set the site title to an array - bug tracked in
GRO-68
2023-11-23 10:25:30 +01:00
Chris Raible
a97e2b823e
Added error handling to Sentry's beforeSend (#19109)
refs TryGhost/Product#4175

- Added error handling to Sentry's beforeSend function in both Admin and
Core, so if there is any error in beforeSend, we will still send the
unmodified event to Sentry
- This is in response to an incident yesterday wherein the beforeSend
function threw an error due to an unexpected missing value in the
exception. The event sent to Sentry was the error in the beforeSend
function, and the original error never reached Sentry.
- If the original event had reached Sentry, even if unmodified by the
logic in beforeSend, we could have been alerted to the issue sooner and
more easily identified all affected sites.
- Also added defensive logic to protect for certain values in the
exception passed to beforeSend not existing and added unit tests for the
beforeSend function in admin and core
2023-11-23 02:46:50 +00:00
Kevin Ansfield
1be490ae9e
Reduced size of social metadata images (#19048)
refs https://github.com/TryGhost/Product/issues/4140

- added `social-image` image size to our `internalImagesSizes` list with a max-width of 1200
- extracted image utils from `{{img_url}}` helper to a utils file for re-use
- updated `getImageDimensions` method that reads image dimensions and modifies the finalised `metaData` object before use to adjust dimensions and associated URLs to match max width of 1200px
2023-11-20 12:39:51 +00:00
Simon Backx
75bb53f065
🔒 Added support for logging out members on all devices (#18935)
fixes https://github.com/TryGhost/Product/issues/3738
https://www.notion.so/ghost/Member-Session-Invalidation-13254316f2244c34bcbc65c101eb5cc4

- Adds the transient_id column to the members table. This defaults to
email, to keep it backwards compatible (not logging out all existing
sessions)
- Instead of using the email in the cookies, we now use the transient_id
- Updating the transient_id means invalidating all sessions of a member
- Adds an endpoint to the admin api to log out a member from all devices
- Added the `all` body property to the DELETE session endpoint in the
members API. Setting it to true will sign a member out from all devices.
- Adds a UI button in Admin to sign a member out from all devices
- Portal 'sign out of all devices' will not be added for now

Related changes (added because these areas were affected by the code
changes):
- Adds a serializer to member events / activity feed endpoints - all
member fields were returned here, so the transient_id would also be
returned - which is not needed and bloats the API response size
(`transient_id` is not a secret because the cookies are signed)
- Removed `loadMemberSession` from public settings browse (not used
anymore + bad pattern)

Performance tests on site with 50.000 members (on Macbook M1 Pro):
- Migrate: 6s (adding column 4s, setting to email is 1s, dropping
nullable: 1s)
- Rollback: 2s
2023-11-15 17:10:28 +01:00
Simon Backx
986296cac9 🐛 Fixed unsubscribe button requiring manual action + wrong confirmation
fixes https://github.com/TryGhost/Product/issues/4118

The newsletter uuids were not passed when fetching all the members current newsletters. Therefore, Portals logic broke to remove all newsletters that matched the uuid that was passed to the unsubscribe link. No newsletters were removed, still the notification toast said that the member was unsubscribed from the newsletter.
2023-11-08 15:05:47 +01:00
Daniel Lockyer
9c6dc044b3 Skipped random flaky HTML -> Lexical test
refs https://github.com/TryGhost/Product/issues/4086

- this test is randomly timing out so we're disabling it until we figure out
  the cause
2023-11-07 09:50:53 +01:00
Michael Barrett
213e54aa71
Fixed error caused by uploading empty redirects YAML file (#18820)
no refs

Fixed error caused by uploading empty redirects YAML file:

```
Cannot read properties of undefined (reading '302')
```

This error was occurring due to `yaml.load` returning `undefined` when
the provided yaml file was empty. I've made the check on the return
value of `yaml.load` stricter (i.e we only want an `object`) to prevent
this error from occurring.
2023-11-02 08:17:52 +00:00
Simon Backx
97d0cddb50
Added indexes to members_created_events and members_subscription_created_events (#18805)
fixes https://github.com/TryGhost/Product/issues/4085

Increases the performance for the post analytics export by adding new
indexes. These indexes are used when counting the amount of (paid)
subscribers that were attributed to a given post. With the indexes, the
time required to export 700 posts with 300k members decreases from 40s
to 0.6s.

Tests show that adding these indexes should be very fast (< 1 s) if the
tables contain up to 300k rows.
2023-10-31 15:11:24 +00:00
Hannah Wolfe
0049b74a2d Added well-known assetlinks.json to allowed files
refs: https://github.com/google/digitalassetlinks/blob/master/well-known/specification.md
refs: https://github.com/google/digitalassetlinks/blob/master/well-known/details.md

- allow themes to include assetlinks.json files to comply with the Google digital asset links spec
2023-10-31 15:10:58 +00:00
Sag
6db0deb58e
Fixed missing favicon layout in the Recommendations template (#18766)
refs https://github.com/TryGhost/Product/issues/3940
- when a favicon url is null, don't render the img element at all
- when a favicon fails to load, hide the img element from the DOM
2023-10-25 19:13:37 +00:00
Daniel Lockyer
96b7ba4755 Fixed minor Node deprecation warning
- resolves `DeprecationWarning: In future versions of Node.js, fs.rmdir(path, { recursive: true }) will be removed. Use fs.rm(path, { recursive: true }) instead` in tests
2023-10-25 18:06:44 +02:00
Kevin Ansfield
9b1f79f601
Cleaned up lexicalEditor labs flag, switched Post model to lexical-by-default (#18607)
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
2023-10-23 17:51:34 +01:00
Fabien "egg" O'Carroll
edcd6caf2b Removed post_revisions default include
Having this as a default means that API responses are HUGE!

Co-authored-by: Daniel Lockyer <hi@daniellockyer.com>
2023-10-12 13:10:05 +02:00
Sag
5bcc7f9a7a
Updated recommendations helper template (#18574)
refs https://github.com/TryGhost/Product/issues/3940
2023-10-11 12:33:46 +00:00
Sag
3cc60bc7ea
Added {{readable_url}} helper (#18564)
refs https://github.com/TryGhost/Product/issues/4021

- used in the recommendations template to display urls in a short
readable way, e.g. google.com instead of
https://www.google.com?query=1#section
2023-10-10 18:56:59 +00:00
Jono M
81d2fa09da
Redesigned Admin settings (#18545)
refs https://github.com/TryGhost/Product/issues/3832

Last piece of cleanup, removing the old feature flag. See
https://github.com/TryGhost/Ghost/pull/18360 for the commit that
actually switched over the routes.
2023-10-10 07:37:01 +01:00
Steve Larson
dcb9bfa7fc
Support twitter embeds using x as host (#18550)
closes TryGhost/Product#4017
- fixed users reporting x.com not creating twitter embed
2023-10-09 15:55:26 -05:00
Simon Backx
9abd466397
Renamed reason to description in recommendations table (#18527)
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
2023-10-09 11:19:44 -03:00
Simon Backx
1882b7048d
Added click tracking for recommendations helper (#18496)
fixes https://github.com/TryGhost/Product/issues/4001
2023-10-05 11:37:02 +02:00
Sag
0c8218b8f6
Removed wrapper in the Recommendation helper template (#18488)
no issue
2023-10-04 22:11:25 +00:00
Chris Raible
80a6fe17d0 Added Source as the new default 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`
2023-10-03 14:02:08 +02:00
Sag
d24c7c5fa6
Added {{recommendations}} theme helper (#18340)
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
2023-09-26 17:15:17 +02:00
Sam Lord
fd7ead6ce6 Upgraded to latest version of @tryghost/request
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.
2023-09-26 12:45:14 +01:00
Daniel Lockyer
49d36fc1a1 Allowed config to override labs flags
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
2023-09-25 11:24:32 +02:00
Daniel Lockyer
1432c6f311 Rewritten labs unit test to use assert over should
refs https://github.com/TryGhost/DevOps/issues/72

- assert is the way we're going with assertion libraries and makes the
  code a little clearer
2023-09-25 11:24:32 +02:00