Skip to content

Enable test email buttons on the permissions a test needs - #506

Merged
pierre-b merged 4 commits into
devfrom
fix/test-email-button-permissions
Nov 10, 2026
Merged

pierre-b merged 4 commits into
devfrom
fix/test-email-button-permissions

Conversation

@pierre-b

@pierre-b pierre-b commented Nov 10, 2026 •

Copy link
Copy Markdown
Contributor

Follow-up to #503 (known, not handled there).

What changes

POST /api/transactional.testTemplate checks Transactional write. It then reads the template with the member's own permissions, so Templates read is needed too. The contact upsert runs system-scoped, so no contacts permission is needed. Before this PR the console's Send Test Email buttons did not match:

Page Before Now
Templates, Broadcasts Templates read + Contacts write: an enabled button could 403, and a disabled one could have sent Templates read + Transactional write, with a tooltip naming them
Transactional notifications Transactional write only: a 403 without Templates read Transactional write + Templates read
  • New canSendTestEmail predicate in services/api/permissions.ts, and a shared SendTestEmailButton replacing the two copies of the tooltip and button.
  • Test dialog: a required canReadContacts prop. CC and BCC are shown, and sent, only with Contacts read, which the server requires for them.
  • Permissions matrix: lists the test email under Templates read. It also lists transactional.create, and transactional.update when the body carries channels (every console edit does), since both read the template with the member's context. The Transactional write lines say what also needs Templates read.
  • i18n: 8 catalogues updated. Shipped strings are kept as obsolete entries; strings that were never released are removed.
  • CHANGELOG: a Fix line under 43.1.

No backend change, no migration, no environment variable.

Plan: plans/fix-test-email-button-permissions-plan.md. Docs: Notifuse/docs#28.

Tests

  • Integration (TestTransactionalHandler/Template Testing Permissions):
    • Transactional write without Templates read → 403 templates/read.
    • Templates read + Transactional write, no contacts permission → 200 with success: true.
  • Console:
    • canSendTestEmail cases.
    • Catalogue entries.
    • SendTestEmailButton: enabled, disabled, tooltip.
    • Transactional notifications page: test button with and without Templates read.
    • Test dialog: CC/BCC hidden or shown, and a cc and a bcc typed before Contacts read goes are not sent.
    • Mutation-checked where cheap.
  • Commands run:
    • Integration test above, and the full npx vitest run (2107 tests at the first commit).
    • Targeted vitest after the review fixes, npx tsc -b, npx eslint . (warnings unchanged from dev) and npm run build.

Known, not handled

  • Whether a test should need Templates read at all is a permission change, left out. The backend could read the template system-scoped instead.
  • The transactional notifications page offers Create and Edit on Transactional write alone, while both also need Templates read. Only the matrix is corrected here.
  • The page also hides its test button without a hint, as it does Edit and Delete.
  • broadcasts.sendToIndividual also reads the template with the member's context and is not listed under Templates read. No screen calls it.
  • SendTemplateModal's withCCAndBCC prop is still unused.

A test email needs Transactional write and Templates read, since the
template is read with the member's own permissions, and no contacts
permission. The templates and broadcasts pages asked for Templates read
and Contacts write, and the transactional notifications page did not
ask for Templates read. Gate all three on the same predicate, show cc
and bcc in the test dialog only with Contacts read, and list the
transactional endpoints that read a template under Templates read.
Make canReadContacts required on the test dialog so a page cannot drop
it, pin that a cc typed before the permission goes is not sent, say in
the matrix that creating a transactional notification or changing its
template needs Templates read, and tidy the translations.
transactional.update reads the template whenever the body carries
channels, which every console edit sends. Also pin that a bcc typed
before Contacts read goes is not sent, and refresh catalogue references.
@codecov

codecov Bot commented Nov 10, 2026 •

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 88.76%. Comparing base (dfa4a6d) to head (0f99162).

Additional details and impacted files
@@            Coverage Diff             @@
##              dev     #506      +/-   ##
==========================================
- Coverage   88.77%   88.76%   -0.01%     
==========================================
  Files         366      366              
  Lines       71512    71512              
==========================================
- Hits        63483    63480       -3     
- Misses       5398     5400       +2     
- Partials     2631     2632       +1     
Flag Coverage Δ
unit 88.76% <ø> (-0.01%) ⬇️

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

Move the Fix line to the open 43.2 version and refresh catalogue
references.
@pierre-b
pierre-b merged commit ff1ed69 into dev Nov 10, 2026
5 checks passed
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.

1 participant