Skip to content

Added email notifications toggle for gift subscription events#27307

Open
mike182uk wants to merge 1 commit intomainfrom
BER-3523-add-settings-toggle
Open

Added email notifications toggle for gift subscription events#27307
mike182uk wants to merge 1 commit intomainfrom
BER-3523-add-settings-toggle

Conversation

@mike182uk
Copy link
Copy Markdown
Member

ref https://linear.app/ghost/issue/BER-3523

Added email notifications toggle for gift subscription events

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai bot commented Apr 9, 2026

Walkthrough

Adds two boolean user notification fields, gift_subscription_purchase_notification and gift_subscription_redemption_notification, to the exported User type. The admin settings UI conditionally shows two toggles for these fields when Stripe and the giftSubscriptions feature are enabled. Ghost core email alert handling now recognizes gift-subscription-purchased and gift-subscription-redeemed types and filters staff recipients accordingly. A staff email callsite and unit test were adjusted to the new alert key. The test user factory now defaults the two new fields to true.

🚥 Pre-merge checks | ✅ 3
✅ Passed checks (3 passed)
Check name Status Explanation
Title check ✅ Passed The title accurately describes the main change: adding email notification toggles for gift subscription events, which is reflected across multiple files including the UI component and backend models.
Description check ✅ Passed The description is related to the changeset, referencing the specific issue and stating the general purpose of adding email notifications toggle for gift subscription events.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch BER-3523-add-settings-toggle

Comment @coderabbitai help to get the list of available commands and usage tips.

@mike182uk mike182uk force-pushed the BER-3523-add-db-columns branch from f65d37e to 8b11f20 Compare April 9, 2026 14:04
@mike182uk mike182uk force-pushed the BER-3523-add-settings-toggle branch from 7ce4c34 to 54e8c1a Compare April 9, 2026 14:05
@mike182uk mike182uk force-pushed the BER-3523-add-db-columns branch from 8b11f20 to e8e31a8 Compare April 9, 2026 14:12
@mike182uk mike182uk force-pushed the BER-3523-add-settings-toggle branch from 54e8c1a to 032805e Compare April 9, 2026 14:13
@mike182uk mike182uk force-pushed the BER-3523-add-db-columns branch from e8e31a8 to cd3a9a2 Compare April 9, 2026 14:32
@mike182uk mike182uk force-pushed the BER-3523-add-settings-toggle branch from 032805e to 1093508 Compare April 9, 2026 14:34
@mike182uk mike182uk force-pushed the BER-3523-add-db-columns branch from cd3a9a2 to ff8dae9 Compare April 9, 2026 14:42
@mike182uk mike182uk force-pushed the BER-3523-add-db-columns branch from ff8dae9 to 49501b5 Compare April 9, 2026 15:57
@mike182uk mike182uk force-pushed the BER-3523-add-settings-toggle branch from 1093508 to 3109fd9 Compare April 9, 2026 15:59
Base automatically changed from BER-3523-add-db-columns to main April 9, 2026 16:27
@mike182uk mike182uk force-pushed the BER-3523-add-settings-toggle branch 2 times, most recently from 296b96f to e6c0203 Compare April 9, 2026 17:27
ref https://linear.app/ghost/issue/BER-3523

Added email notifications toggle for gift subscription events
@mike182uk mike182uk force-pushed the BER-3523-add-settings-toggle branch from e6c0203 to 88a4a35 Compare April 9, 2026 20:29
@sonarqubecloud
Copy link
Copy Markdown

sonarqubecloud bot commented Apr 9, 2026

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
ghost/core/core/server/models/user.js (1)

499-523: ⚠️ Potential issue | 🟠 Major

Fail closed for unknown email alert types.

getEmailAlertUsers currently falls back to status:active when type is unrecognized, which can notify all active owners/admins and bypass per-event opt-in flags. With the new gift keys, a typo/regression in a caller becomes an over-notification path.

Suggested fix
 getEmailAlertUsers(type, options) {
     options = options || {};
-
-    let filter = 'status:active';
-    if (type === 'free-signup') {
-        filter += '+free_member_signup_notification:true';
-    } else if (type === 'paid-started') {
-        filter += '+paid_subscription_started_notification:true';
-    } else if (type === 'paid-canceled') {
-        filter += '+paid_subscription_canceled_notification:true';
-    } else if (type === 'mention-received') {
-        filter += '+mention_notifications:true';
-    } else if (type === 'milestone-received') {
-        filter += '+milestone_notifications:true';
-    } else if (type === 'donation') {
-        filter += '+donation_notifications:true';
-    } else if (type === 'recommendation-received') {
-        filter += '+recommendation_notifications:true';
-    } else if (type === 'gift-subscription-purchased') {
-        filter += '+gift_subscription_purchase_notification:true';
-    } else if (type === 'gift-subscription-redeemed') {
-        filter += '+gift_subscription_redemption_notification:true';
-    }
+    const notificationFieldByType = {
+        'free-signup': 'free_member_signup_notification',
+        'paid-started': 'paid_subscription_started_notification',
+        'paid-canceled': 'paid_subscription_canceled_notification',
+        'mention-received': 'mention_notifications',
+        'milestone-received': 'milestone_notifications',
+        'donation': 'donation_notifications',
+        'recommendation-received': 'recommendation_notifications',
+        'gift-subscription-purchased': 'gift_subscription_purchase_notification',
+        'gift-subscription-redeemed': 'gift_subscription_redemption_notification'
+    };
+
+    const notificationField = notificationFieldByType[type];
+    if (!notificationField) {
+        return Promise.resolve([]);
+    }
+
+    const filter = `status:active+${notificationField}:true`;
     const updatedOptions = Object.assign({}, options, {filter, withRelated: ['roles']});
     return this.findAll(updatedOptions).then((users) => {
         return users.toJSON().filter((user) => {
             return user?.roles?.some((role) => {
                 return ['Owner', 'Administrator'].includes(role.name);
             });
         });
     });
 },
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@ghost/core/core/server/models/user.js` around lines 499 - 523,
getEmailAlertUsers currently defaults to 'status:active' for unknown types which
risks over-notifying; update the function to validate the incoming type against
the known set (e.g., free-signup, paid-started, paid-canceled, mention-received,
milestone-received, donation, recommendation-received,
gift-subscription-purchased, gift-subscription-redeemed) and fail closed for
anything unrecognized by returning an empty result (e.g., return
Promise.resolve([])) or applying a filter that matches no users before calling
findAll; adjust the code that builds filter (variable filter) and updatedOptions
so unknown types do not fall through to the active-owner path and optionally
emit a warning log instead of querying with 'status:active'.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Outside diff comments:
In `@ghost/core/core/server/models/user.js`:
- Around line 499-523: getEmailAlertUsers currently defaults to 'status:active'
for unknown types which risks over-notifying; update the function to validate
the incoming type against the known set (e.g., free-signup, paid-started,
paid-canceled, mention-received, milestone-received, donation,
recommendation-received, gift-subscription-purchased,
gift-subscription-redeemed) and fail closed for anything unrecognized by
returning an empty result (e.g., return Promise.resolve([])) or applying a
filter that matches no users before calling findAll; adjust the code that builds
filter (variable filter) and updatedOptions so unknown types do not fall through
to the active-owner path and optionally emit a warning log instead of querying
with 'status:active'.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 70dda4b7-9905-4500-8e72-42db2d671529

📥 Commits

Reviewing files that changed from the base of the PR and between e6c0203 and 88a4a35.

📒 Files selected for processing (6)
  • apps/admin-x-framework/src/api/users.ts
  • apps/admin-x-settings/src/components/settings/general/users/email-notifications-tab.tsx
  • apps/admin/test-utils/factories/user.ts
  • ghost/core/core/server/models/user.js
  • ghost/core/core/server/services/staff/staff-service-emails.js
  • ghost/core/test/unit/server/services/staff/staff-service.test.js
✅ Files skipped from review due to trivial changes (2)
  • ghost/core/test/unit/server/services/staff/staff-service.test.js
  • apps/admin/test-utils/factories/user.ts
🚧 Files skipped from review as they are similar to previous changes (2)
  • ghost/core/core/server/services/staff/staff-service-emails.js
  • apps/admin-x-framework/src/api/users.ts

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants