feat(sharebymail): dispatch BeforeShare*MailSentEvent before each mail send#277
feat(sharebymail): dispatch BeforeShare*MailSentEvent before each mail send#277printminion-co wants to merge 21 commits into
Conversation
Signed-off-by: Your Name <you@example.com>
Signed-off-by: Benjamin Gaussorgues <benjamin.gaussorgues@nextcloud.com>
Signed-off-by: Benjamin Gaussorgues <benjamin.gaussorgues@nextcloud.com>
Signed-off-by: Carl Schwan <carlschwan@kde.org>
Signed-off-by: Peter Ringelmann <peter.ringelmann@nextcloud.com>
Signed-off-by: Peter Ringelmann <peter.ringelmann@nextcloud.com>
…sion before failing on increased permissions Signed-off-by: provokateurin <kate@provokateurin.de>
…ptimization feat: Fetch groups in batch in getUserGroups
Signed-off-by: Peter Ringelmann <peter.ringelmann@nextcloud.com>
…nteraction-file-delete-create-before-increase fix(files_sharing): Fail on sharing file with create or delete permission before failing on increased permissions
…x-shell feat(core): header-anchored combobox shell for unified search
…ngle event Signed-off-by: provokateurin <kate@provokateurin.de>
fix: webhook payload for system tag events
By default only 25 group objects are loaded. If a user is assigend to a group, that isn't loaded yet, we only show the gid instead of the displayname. Assisted-by: Copilot:gpt-5.4 Assisted-by: ClaudeCode:claude-sonnet-5 Signed-off-by: Daniel Kesselberg <mail@danielkesselberg.de>
Signed-off-by: Daniel Kesselberg <mail@danielkesselberg.de>
c09ac83 to
f2b7041
Compare
There was a problem hiding this comment.
Pull request overview
This PR adds PSR-14 events in apps/sharebymail that are dispatched immediately before each native mailer->send() call in ShareByMailProvider, allowing listeners to suppress/replace SMTP delivery for share-by-mail notifications (share link, password, and note mails).
Changes:
- Introduce
BeforeShare*MailSentEventclasses (with a shared abstract base) to carry the preparedIMessageand recipients and allow suppressing native sending viamarkMailHandled(). - Dispatch these events from
ShareByMailProvider::sendEmail(),sendPassword(),sendPasswordToOwner(), andsendNote(), skipping native send when handled. - Update unit tests and app-local composer autoload classmaps to include the new event classes.
Reviewed changes
Copilot reviewed 8 out of 8 changed files in this pull request and generated 3 comments.
Show a summary per file
| File | Description |
|---|---|
| apps/sharebymail/lib/ShareByMailProvider.php | Dispatch new events before each mail send and skip native send when handled; refactor template data arrays. |
| apps/sharebymail/tests/ShareByMailProviderTest.php | Extend tests to assert event dispatch and updated template data; add tests around “mail handled” behavior for password flows. |
| apps/sharebymail/lib/Event/AbstractBeforeShareMailSentEvent.php | Add common event base carrying share, recipients, and rendered message plus “handled” flag. |
| apps/sharebymail/lib/Event/BeforeShareMailSentEvent.php | Add event for share-link notification mails. |
| apps/sharebymail/lib/Event/BeforeSharePasswordMailSentEvent.php | Add event for password notification mails (recipient + owner cases). |
| apps/sharebymail/lib/Event/BeforeShareNoteMailSentEvent.php | Add event for note-update notification mails. |
| apps/sharebymail/composer/composer/autoload_static.php | Register new event classes in the app-local composer autoloader map. |
| apps/sharebymail/composer/composer/autoload_classmap.php | Register new event classes in the app-local composer classmap. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| /** | ||
| * @param string[] $resolvedEmails validated recipients | ||
| */ |
There was a problem hiding this comment.
Fixed in commit fix(sharebymail): fix docstring and add isMailHandled tests for sendEmail and sendNote. The @param docstring now reads "resolved recipient addresses (not guaranteed to be validated)" to accurately reflect that call sites like sendNote() and sendPasswordToOwner() do not validate addresses before dispatching.
| $event = new BeforeShareMailSentEvent($share, $emails, $message, $templateData); | ||
| $this->eventDispatcher->dispatchTyped($event); | ||
| if ($event->isMailHandled()) { | ||
| return; | ||
| } |
There was a problem hiding this comment.
Added testSendEmailDoesNotSendWhenMailHandledByListener in commit fix(sharebymail): fix docstring and add isMailHandled tests for sendEmail and sendNote. The test sets up a listener that calls markMailHandled() on the dispatched BeforeShareMailSentEvent and asserts mailer->send() is never called.
| $event = new BeforeShareNoteMailSentEvent($share, [$recipient], $message, $templateData); | ||
| $this->eventDispatcher->dispatchTyped($event); | ||
| if ($event->isMailHandled()) { | ||
| return; | ||
| } |
There was a problem hiding this comment.
Added testSendNoteDoesNotSendWhenMailHandledByListener in commit fix(sharebymail): fix docstring and add isMailHandled tests for sendEmail and sendNote. The test marks BeforeShareNoteMailSentEvent as handled via a listener and asserts mailer->send() is never invoked.
chore(jobs): write proper documentation for job:history
6274dc9 to
3391f42
Compare
3391f42 to
d928ae7
Compare
…n-users-list Show group display name when the group object is not loaded yet
…n/allow-multiple-resources-and-receivers refactor(Interaction): Allow multiple resources and receivers in a single event
Signed-off-by: Nextcloud bot <bot@nextcloud.com>
…ateData variables Extract the inline array literals passed to each createEMailTemplate() call into named $templateData variables. For sendNote(), which previously passed no data array, add a minimal array so all four send methods are consistent. Zero behaviour change — $templateData is passed straight through to createEMailTemplate() with identical contents. Signed-off-by: Misha M.-Kupriyanov <kupriyanov@strato.de>
…ch mail send
Dispatch a typed PSR-14 event immediately before every mailer->send() call
in ShareByMailProvider so that external listeners can intercept and replace
Nextcloud's native SMTP delivery.
Event hierarchy:
AbstractBeforeShareMailSentEvent (base: share, resolvedEmails, message,
markMailHandled / isMailHandled)
├── BeforeShareMailSentEvent – sendEmail()
├── BeforeSharePasswordMailSentEvent – sendPassword() + sendPasswordToOwner()
└── BeforeShareNoteMailSentEvent – sendNote()
Each concrete class holds its own typed $templateData (psalm array-shape)
and exposes named getters (getSenderUserId(), getFileName(), …) instead of
a generic getMailData(): array<string,mixed>. This avoids defensive
is_string() / null guards in listeners.
$templateData reuses the array already passed to createEMailTemplate(), with
one extra key added for sendEmail(): senderUserId (the raw user ID, distinct
from the display name stored under 'initiator').
The native mailer->send() is skipped when a listener calls markMailHandled().
If the listener's own send throws, the exception propagates and the native
send is also skipped — no silent SMTP fallback.
sendEmail() and sendPassword() are flattened from nested
if (!isMailHandled()) { ... } pyramids to early-return style.
createPasswordSendActivity() in sendPassword() and sendPasswordToOwner() now runs
only when the mail was actually sent: it moved inside the isMailHandled() early
return, so a listener that suppresses the SMTP send no longer produces a false
password-share activity entry.
Signed-off-by: Misha M.-Kupriyanov <kupriyanov@strato.de>
d928ae7 to
edc6c9c
Compare
Summary
Upstream-ready extract of IONOS PR #262, prepared for contribution to
nextcloud/server.Introduces a PSR-14 event dispatched immediately before every
mailer->send()inShareByMailProvider, so listeners can intercept/replace native SMTP delivery for share-by-mailnotifications.
apps/sharebymail/lib/Event/classes:AbstractBeforeShareMailSentEvent(base) +BeforeShareMailSentEvent,BeforeSharePasswordMailSentEvent,BeforeShareNoteMailSentEventsendEmail(),sendPassword(),sendPasswordToOwner(),sendNote();markMailHandled()skips native send (no silent fallback)$templateDatarefactor + fix socreatePasswordSendActivityno longer fires when a listenersuppresses the mail
Scope / cleanup vs PR #262
apps-custom/nc_ionos_processessubmodule bump and thehand-edited generated autoload noise. Diff is
apps/sharebymail/**only.IONOS(...)/HDNEXTmarkers); rebased onto currentmaster. Drift fixes: dropped an unused import; replacedwithConsecutive()(removed inPHPUnit 10) with a
willReturnCallbackidiom; autoload entries inksortorder.Verification (dev container)
./autotest.sh sqlite apps/sharebymail/tests/ShareByMailProviderTest.php→ OK (40 tests, 440 assertions)composer cs:checkclean on the changed filesFollow-ups
refactor(sharebymail)commit is missing aSigned-off-by— will be added + force-pushed.nextcloud/serverPR to be opened separately by the human contributor (AI policy).AI assistance
Branch prepared with AI assistance (cherry-pick, reword, drift-conflict resolution). Underlying
code is human-authored (PR #262).