Commit Graph

301 Commits

Author SHA1 Message Date
Daniel Lockyer
9a40440e82 Fixed handling SVG files with missing tag
fix https://linear.app/tryghost/issue/SLO-151/[ghost]-cannot-read-properties-of-null-reading-attributes-an

- in the event the file doesn't contain a tag, the code currently crashes
  because it tries to read `attributes from `undefined`
- we can fix that by checking the first element exists before reading
  from it
- also includes a breaking test
2024-06-18 14:41:11 +02:00
Steve Larson
3c247d93fe
Added posts.updated_at index to schema (#20357)
ref 6dbbdff
- added index to schema
2024-06-10 11:35:21 -05:00
Kevin Ansfield
9ca1f3ce24
Renamed subtitle to excerpt (#20334)
no issue

We've settled on using "excerpt" naming in place of "subtitle" to better reflect the underlying property name and tie in with themes and historical usage.

- added migration to rename the `show_subtitle` newsletter setting to `show_excerpt`
- renamed all places in the codebase that referenced subtitle
2024-06-05 17:59:30 +01:00
Michael Barrett
0f283da8eb
🐛 Fixed Slack integration using member content in excerpt (#20328)
- refs
[ONC-63](https://linear.app/tryghost/issue/ONC-63/discordslack-webhook-integration)
- fixes [#20304](https://github.com/TryGhost/Ghost/issues/20304)

When a post is published and sent to Slack via webhook, the excerpt
generated could contain member content. This change ensures that the
excerpt does not contain member content. This change also ensures that
the author for the post is correctly shown in Slack
2024-06-05 17:46:21 +01:00
Kevin Ansfield
b447a26832
Added custom excerpt to post revisions (#20323)
closes https://linear.app/tryghost/issue/MOM-170

When the subtitle field is included in the editor it creates a disconnect with post revisions if the underlying custom excerpt data is not included so we'd like to both preview and restore the subtitle when the in-editor subtitle field is enabled.

- added `post_revisions.custom_excerpt` column to schema
- added migration to add `post_revisions.custom_excerpt` to existing databases
- added migration to populate `post_revisions.custom_excerpt` with the current `post.custom_excerpt` value from the associated record
  - ensures no data is inadvertently lost when restoring an old version
- using current data matches what would have happened previously where custom_excerpt was never overwritten when restoring an old version
- updated post revisions handling to accept the `custom_excerpt` field
- updated Admin's revision preview and restoration to display and set the `custom_excerpt` field
2024-06-05 14:47:33 +01:00
Kevin Ansfield
952a89f673
Renamed show_subhead to show_subtitle (#20320)
closes https://linear.app/tryghost/issue/MOM-194

- whilst working on the feature our naming changed from "Subhead" to "Subtitle"
- this rename of the newsletter design setting column brings naming back into a consistent state before public release
2024-06-04 10:57:14 +00:00
Steve Larson
e6fcbf45a1
Added sanitization for svg uploads (#20264)
ref https://linear.app/tryghost/issue/ENG-856
- svgs were not previously sanitized and could contain scripts
2024-05-28 08:58:16 -05:00
Ronald Langeveld
d799f2ecb1
Added show_subhead column to newsletters table (#20268)
refs MOM-152

Adds `show_subhead` column to newsletter table. False by default.
2024-05-28 16:29:20 +07:00
Ronald Langeveld
4f3bfebfea
Revert "Added latest_event_timestamp to email table (#20118)" (#20149)
This reverts commit 3246a8d2c9.
2024-05-07 08:58:42 +00:00
Ronald Langeveld
3246a8d2c9
Added latest_event_timestamp to email table (#20118)
ref ENG-832

- Added migrations for `latest_event_timestamp` column in emails table.
- updated schema
- updated emails model
2024-05-07 16:12:51 +08:00
Chris Raible
dcd65bfa4f
Added caching to the LinkRedirectRepository (#20036)
ref
https://linear.app/tryghost/issue/ENG-851/implement-a-minimal-but-complete-version-of-redirect-caching-to
ref https://app.incident.io/ghost/incidents/55

Often immediately after sending an email, sites receive a large volume
of requests to LinkRedirect endpoints from members clicking on the links in
the email.

We currently don't cache any of these requests in our CDN, because we
also record click events, update the member's `last_seen_at` timestamp,
and send webhooks in response to these clicks, so Ghost needs to handle
each of these requests itself. This means that each of these LinkRedirect requests
hits Ghost, and currently all these requests hit the database to lookup
where to redirect the member to.

Each one of these requests can make up to 11 database queries, which can
quickly exhaust Ghost's database connection pool. Even though the
LinkRedirect lookup query is fairly cheap and quick, these queries aren't
prioritized over the "record" queries Ghost needs to handle, so they can
get stuck behind other queries in the queue and eventually timeout.

The result is that members are unable to actually reach the destination
of the link they clicked on, instead receiving a 500 error in Ghost, or
it can take a long time (60s+) for the redirect to happen.

This PR uses our existing `adapterManager` to cache the redirect lookups
either in-memory or in Redis (if configured — by default there is no caching). This only removes 1 out of
11 queries per redirect request, so it won't reduce the load on the DB
drastically, but it at least decouples the serving of the LinkRedirect from
the DB so the member can be redirected even if the DB is under heavy
load.

Local load testing results have shown a decrease in response times from
60 seconds to ~50ms for the redirect requests when handling 500 requests
per second, and reduced the 500 error rate to 0.
2024-04-25 19:17:25 -07:00
Daniel Lockyer
8e0ad1a6fb
Fixed test on Node 20
refs f39d1d3aa3

- similar to the commit above, the JSON parser changed between Node 18
  and Node 20, so the error message changed too
- we actually just want to check the error is forwarded to the user, so
  we can do that by getting the error message from JSON.parse and check
  against that
2024-04-18 13:17:16 +02:00
Nicholas Mizoguchi
d6b7ebb517
Enforced more Mocha lint rules (#19720)
ref https://github.com/TryGhost/Ghost/issues/11038

1. Enforced lint rule
**[ghost/mocha/no-identical-title](https://github.com/lo1tuma/eslint-plugin-mocha/blob/main/docs/rules/no-identical-title.md)**
- Fixed relevant tests
2. Enforced lint rule
**[ghost/mocha/max-top-level-suites](https://github.com/lo1tuma/eslint-plugin-mocha/blob/main/docs/rules/max-top-level-suites.md)**
- No required fixes, as tests are compliant already

#### Additional details
Specifically for `ghost/mocha/no-identical-title` most fixes were simple
test description updates. Added comments to aid the PR review for the
ones that had relevant changes, and might require more attention. They
are as follows:
*
[e2e-api/admin/invites.test.js](https://github.com/TryGhost/Ghost/pull/19720#discussion_r1496397548):
Removed duplicated test (exact same code on both);
*
[e2e-api/admin/members.test.js](https://github.com/TryGhost/Ghost/pull/19720#discussion_r1496399107):
From the[ PR this was
introduced](73466c1c40 (diff-4dbc7e96e356428561085147e00e9acb5c71b58d4c1bd3d9fc9ac30e77c45be0L236-L237))
seems like author based his test on an existing one but possibly forgot
to rename it;
*
[unit/api/canary/utils/serializers/input/pages.test.js](https://github.com/TryGhost/Ghost/pull/19720#discussion_r1496400143):
The [page filter](https://github.com/TryGhost/Ghost/pull/14829/files)
was removed, so changed the description accordingly;
*
[unit/api/canary/utils/serializers/input/posts.test.js](https://github.com/TryGhost/Ghost/pull/19720#discussion_r1496400329):
The [page filter](https://github.com/TryGhost/Ghost/pull/14829/files)
was removed, so changed the description accordingly;
*
[unit/frontend/services/rendering/templates.test.js](https://github.com/TryGhost/Ghost/pull/19720#discussion_r1496402430):
Removed duplicated test
*
[unit/server/models/post.test.js](https://github.com/TryGhost/Ghost/pull/19720#discussion_r1496403529):
the change in [this
PR](https://github.com/TryGhost/Ghost/pull/14586/files#diff-c351cb589adefbb886570cfadb33b33eb8fdc12bde1024d1188cd18c165fc5e8L1010)
made three tests here mostly the same. Deduplicated them and kept only
one.
2024-04-16 09:37:06 +02:00
Michael Barrett
9e78412268
Added queue depth to requests (#19987)
refs
[CFR-14](https://linear.app/tryghost/issue/CFR-14/ensure-queue-depth-is-always-set-on-req)

Added queue depth to any request that passes through the request queue
middleware instead of only adding it to the request if it is queued.
This makes it easier to report on the queue depth within Elastic.
2024-04-11 09:24:04 +01:00
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
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
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
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
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
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
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
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
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
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
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
500507ff21 Moved labs unit test to correct folder
refs https://github.com/TryGhost/DevOps/issues/72

- labs.js is in the shared folder, so I've moved it to the corresponding
  folder to make understanding the tests easier
2023-09-25 11:24:32 +02:00
Simon Backx
b82a93beac
Added recommendation_notifications column to users table (#18304)
fixes https://github.com/TryGhost/Product/issues/3939
2023-09-22 15:35:55 +00:00
Naz
1fd4861e97 Cleaned up fixtures from latest collections entry
refs https://github.com/TryGhost/Arch/issues/95
refs 45c1a82909

- Latest collection has become "dynamic" in the referenced commit, this means we don't need stored entries in the database.
2023-09-22 22:23:30 +08:00
Ronald Langeveld
851504030c
Added Support Email verification modals to Admin X (#18152)
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.
2023-09-15 16:00:24 +07:00
Kevin Ansfield
12621d8157
Added core content API integration fixture (#18114)
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
2023-09-13 17:04:49 +01:00
Simon Backx
e888a4e820
Added recommendation events tables (#18084)
fixes https://github.com/TryGhost/Product/issues/3852

Tech spec:
https://www.notion.so/ghost/Recommentions-Tech-Spec-598f09e4109f4eef8d9e32db7245a90c?pvs=4#d30e0081613a4f51860acd40169a4d68
2023-09-13 17:18:40 +02:00
Sag
f1cd6432a8
Added new setting to enable Recommendations (#17856)
closes https://github.com/TryGhost/Product/issues/3772

- Recommendations are disabled by default and will get enabled when a
first recommendation is added. The "recommendations_enabled" setting
will be not shown explicitly in Admin, it will rather be set implicitly
based on whether there is at least one recommendation
- The "recommendations_enabled" setting belongs to a new setting group
called "recommendations"

Tech Spec: https://www.notion.so/ghost/Recommentions-Tech-Spec-598f09e4109f4eef8d9e32db7245a90c?pvs=4
2023-08-30 08:56:21 +00:00