Skip to content

[pull] main from TryGhost:main#893

Merged
pull[bot] merged 9 commits intocode:mainfrom
TryGhost:main
Feb 3, 2026
Merged

[pull] main from TryGhost:main#893
pull[bot] merged 9 commits intocode:mainfrom
TryGhost:main

Conversation

@pull
Copy link

@pull pull bot commented Feb 3, 2026

See Commits and Changes for more details.


Created by pull[bot] (v2.0.0-alpha.4)

Can you help keep this open source service alive? 💖 Please sponsor : )

rob-ghost and others added 9 commits February 3, 2026 16:35
ref https://linear.app/ghost/issue/BER-3184

Adds a checkbox to the disable commenting dialog that allows hiding
all previous comments from a member when disabling their commenting.
Moved this rule from the shared renovate-config to be Ghost-specific,
so it no longer affects all repos using the shared config.
closes [GVA-645](https://linear.app/ghost/issue/GVA-645/add-suppression-re-enable-button-in-ghost-admin)

Please take a minute to explain the change you're making:
- **Why are you making it?**
This change introduces the ability for publishers to re-enable a
member's email directly from Ghost Admin when it has been disabled
(e.g., due to bounces or spam complaints). This streamlines the process
of managing email suppressions without needing to leave the admin
interface, improving workflow efficiency for publishers.
- **What does it do?**
A "Re-enable email" button is added to the member's newsletter
subscription settings in Ghost Admin, appearing when their email is in a
disabled state. Clicking this button calls a new API endpoint to remove
the email from the suppression list and updates the member's
`email_disabled` status to `false`, subsequently refreshing the UI to
show active newsletter settings.
- **Why is this something Ghost users or developers need?**
Publishers gain a direct and convenient tool within Ghost Admin to
manage member email deliverability, which is essential for reactivating
members whose emails were temporarily disabled. This enhances
administrative control over member engagement.

Please check your PR against these items:

- [ ] I've read and followed the [Contributor
Guide](https://github.com/TryGhost/Ghost/blob/main/.github/CONTRIBUTING.md)
- [ ] I've explained my change
- [ ] I've written an automated test to prove my change works

We appreciate your contribution! 🙏

---
Linear Issue:
[GVA-645](https://linear.app/ghost/issue/GVA-645/add-suppression-re-enable-button-in-ghost-admin)

<a
href="https://cursor.com/background-agent?bcId=bc-edf898b1-a4ca-4989-9e52-0ac43ba9148c"><picture><source
media="(prefers-color-scheme: dark)"
srcset="https://cursor.com/open-in-cursor-dark.svg"><source
media="(prefers-color-scheme: light)"
srcset="https://cursor.com/open-in-cursor-light.svg"><img alt="Open in
Cursor"
src="https://cursor.com/open-in-cursor.svg"></picture></a>&nbsp;<a
href="https://cursor.com/agents?id=bc-edf898b1-a4ca-4989-9e52-0ac43ba9148c"><picture><source
media="(prefers-color-scheme: dark)"
srcset="https://cursor.com/open-in-web-dark.svg"><source
media="(prefers-color-scheme: light)"
srcset="https://cursor.com/open-in-web-light.svg"><img alt="Open in Web"
src="https://cursor.com/open-in-web.svg"></picture></a>

<!-- CURSOR_SUMMARY -->
---

> [!NOTE]
> **Medium Risk**
> Adds a new authenticated admin write endpoint that alters suppression
state and `email_disabled`, so regressions could incorrectly re-enable
sending or fail to clear suppressions.
> 
> **Overview**
> Adds a **“Re-enable email”** button to the member newsletter
preferences UI when a member is email-suppressed, including
loading/disabled state and a small layout tweak.
> 
> Introduces a new Admin API endpoint `DELETE /members/:id/suppression`
that removes the member’s email from the suppression list and flips
`email_disabled` back to `false`, plus e2e tests/snapshots covering
success, missing member (404), and suppression removal failure (500).
> 
> <sup>Written by [Cursor
Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit
71fc112. This will update automatically
on new commits. Configure
[here](https://cursor.com/dashboard?tab=bugbot).</sup>
<!-- /CURSOR_SUMMARY -->

<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->

## Summary by CodeRabbit

## Release Notes

* **New Features**
* Added "Re-enable email" button to member newsletter preferences,
enabling administrators to restore email communications for members with
suppressed email addresses.

* **Style**
* Improved spacing in newsletter no-data state for better visual
presentation.

* **Tests**
* Added comprehensive test coverage for email suppression removal
including success and error scenarios.

<!-- end of auto-generated comment: release notes by coderabbit.ai -->

---------

Co-authored-by: Cursor Agent <cursoragent@cursor.com>
Co-authored-by: peter <peter@ghost.org>
Co-authored-by: Sam Lord <hello@samlord.me>
ref
ae95876

The ref'd commit seems to have a stale lock file.
no ref

When committing translations, if the context file was not updated it
would never fail on CI, propagating the change down the line a future PR
that is making changes to translations, as well as missing out on the
context being part of the original commit.

This change causes CI to fail on changes to context.json rather than
silently letting it pass by.

the context file is provided to give context along with new strings, and
we do not currently require this to be filled in, although that is
something we should look at separately.

<!-- CURSOR_SUMMARY -->
---

> [!NOTE]
> **Low Risk**
> Low risk: adds a CI-only guardrail around translation metadata
generation and updates the generated `context.json` entries; no runtime
product logic is affected.
> 
> **Overview**
> Prevents stale translation context from silently landing by updating
`generate-context.js` to compare the newly generated `context.json`
against the committed file and **fail in CI** with a clear error when
they differ.
> 
> Updates `locales/context.json` with newly generated keys (e.g.
additional "Open <provider> Mail" strings and "View in admin"), ensuring
the context file stays in sync with extracted English strings.
> 
> <sup>Written by [Cursor
Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit
e8cc533. This will update automatically
on new commits. Configure
[here](https://cursor.com/dashboard?tab=bugbot).</sup>
<!-- /CURSOR_SUMMARY -->
This test-only change should have no user impact.
no issue

- by default 3% of comments will get a single report
- if a quantity is given then the specified number of reports will be spread across all comments
ref [GVA-647](https://linear.app/ghost/issue/GVA-647/member-email-enumeration-during-signin)

So the changes here:
* If you're registering to a site: No change (this already automatically
sends a sign-in email if you have an account)
* If you're signing into a site and do have account: No change
* If you're signing in to a site, but don't have an account, and the
site is private: You'll get an email explaining that you don't have an
account and the site is private
* If you're signing into a site, but don't have an account, and the site
is public: You'll get a sign-up email with magic link

This also meant adding the blocked domains feature to the sign-in
endpoint, but only when it's being used to create an account.

<img width="1180" height="649" alt="Screenshot 2026-01-27 at 15 58 19"
src="https://github.com/user-attachments/assets/75d0465f-8648-4d68-be50-1e6ff00af749"
/>

This is the attempted sign-in email.

<!-- CURSOR_SUMMARY -->
---

> [!NOTE]
> **Medium Risk**
> Changes authentication-adjacent magic-link behavior and email sending,
which could impact signup/signin flows and rate-limiting/blocked-domain
edge cases if misconfigured.
> 
> **Overview**
> Prevents member email enumeration during `send-magic-link` sign-in by
**no longer returning a 400 when the email doesn’t exist**. Instead,
when self-signup is enabled the API sends a *signup* magic-link email
(without OTC) and returns an empty `201`, while invite-only sites
silently return an empty `201` with no email.
> 
> Adds blocked-domain handling to this “signin-but-create-account” path
(silently drops blocked domains), updates Portal copy to show a
non-revealing invite-only message, and standardizes “e-mail” → “email”
strings across errors/tests/locales.
> 
> <sup>Written by [Cursor
Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit
b175ec7. This will update automatically
on new commits. Configure
[here](https://cursor.com/dashboard?tab=bugbot).</sup>
<!-- /CURSOR_SUMMARY -->

<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit

* **New Features**
* Sends signup magic-link emails for unknown addresses when self-signup
is enabled; invite-only sites remain silent.
* Portal shows quick "open email"/provider links and new sign-in
informational copy.

* **Bug Fixes**
  * Prevents account enumeration in sign-in/sign-up flows.
* Enforces blocked email-domain handling and consistent OTC behavior for
non-existent members.

* **Documentation & Localization**
* Standardized "e-mail" → "email" across portal translations; added new
sign-in message.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
This test-only change should have no user impact.
@pull pull bot locked and limited conversation to collaborators Feb 3, 2026
@pull pull bot added the ⤵️ pull label Feb 3, 2026
@pull pull bot merged commit 24ef18d into code:main Feb 3, 2026
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

7 participants