Repository navigation
Conversation
…bulwarkmail#124 Port of the webmail's Report phishing (lib/phishing-report*.ts, lib/phishing-links.ts). While the organisation policy sets organisation.phishingReport, the message's More menu and the list's selection bar offer "Report phishing…": after a confirm naming the address, each message goes to it as its own report (forwarded with the original attached as message/rfc822 by its blob, or as an ARF report, as the admin chose), with no copy kept. Each one reported is then filed in its own account's Junk with $junk, $phishing and $seen, with Undo. A message whose report fails stays where it is; nothing starts offline. A message carrying $phishing (or reported in this session) has its links turned off, with the webmail's banner, and shows no unsubscribe banner or structured-mail cards; files previewed from it have their links off too. The strings are the webmail's phishing_report block, in every locale.
wmcparla
marked this pull request as ready for review
November 13, 2026 19:45
|
I found nothing to flag in the send path.
The CI Bulwark Warden is an AI assistant and can be wrong. It answers from the docs, the code and earlier issues, and links its sources. |
Member
|
Thanks for the thorough port. Report phishing landed on main in 70b0d65 and e3a47be through the catch-up with the webmail before I got to this, so I'm closing this one as superseded. I took two of your additions into deca0bf: a reported message no longer shows its unsubscribe banner or structured-mail cards, and an .eml or HTML attachment previewed from it has its links off. Reporting several messages from the list's selection isn't on main yet; a separate PR on top of main's version is welcome. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
The app gets the webmail's "Report phishing" (#124). While the organisation policy sets
organisation.phishingReport, the message's More menu and the list's selection bar offer Report phishing…. After a confirm that names the address, each message goes to it as its own report, and is then filed in Junk with$phishing, with Undo. A reported message has its links turned off.It ports the webmail's
lib/phishing-report.ts,lib/phishing-report-flow.ts,lib/phishing-report-arf.ts,lib/phishing-links.tsandstores/phishing-report-store.ts, and follows them unless noted below.Changes
phishingReportSetup()readsorganisation.phishingReportfrom the policy the app already fetches (usePolicyStore().effective), and checks the address again because policy.json is written by hand.src/api/phishing-report.ts): one report per message, from the login's own address.message/rfc822by its blob id, copied withBlob/copyfirst when it is in a shared or group mailbox.maxSizeUploadis refused before the download.sendEmailgainsnoSentCopy(onSuccessDestroyEmailinstead of the move to Sent), so no copy stays in Sent or Drafts. A copy the server doesn't destroy is reported as a filing warning.fileReportedfiles each reported message in its own account's Junk, by account and id, through the existingfileAcrossAccounts. That gives one Undo for all, the offline queue and the cache updates as for Report spam.$junk,$phishingand$seen. Undo puts back each message's own keywords and folder, and shows the webmail's "Moved back. The report was already sent."api/markAsSpamtakes further keywords for$phishing. Plain Report spam is unchanged.usePhishingReportStore) as soon as its own report went out, so its links go off and it isn't offered again even if the move then fails.$phishing, or one reported in this session:turnOffLinksinemail-html.ts, through the tokenizer the sanitiser already uses), and the WebView refuses every navigation;.emlor HTML attachment previewed from it has its links off too.phishing_reportblock, copied into each vendoredlocales/<lang>/common.jsonas the webmail has it (translated in every language, nothing machine-made). A latersync-localeswrites the same text.Fish, as the webmail uses, added throughscripts/generate-icons.mjs(Tabler 3.50.0).Related issues
Closes #124
Type of change
Checklist
npm run typecheckand there are no errors (native has nolintscript)npm run buildin native; an x86_64 release APK,assembleGithubRelease -PallowDebugSignedRelease=true, builds and runs)locales/) if my changes affect user-facing text (the webmail's own translations;npm run i18n:checkpasses)Tests:
npx vitest run: 7143 passed, 163 skipped (the live Stalwart suites), 1 failed. The failure ispostal-mime-rn.test.ts, which fails the same on main in my checkout ("Creating blobs from 'ArrayBuffer' … are not supported"). The new tests cover:onSuccessDestroyEmail, the upload limit, a refused submission;turnOffLinkson HTML and plain-text bodies;fileReported: its own account's Junk while another account's folder is open, list removal, Undo;Tested on the Android 16 Pixel 9 emulator against a self-hosted Stalwart 1.1.0, with two test accounts:
Each case was predicted before the run. One account reports and the other is the report address; messages were seeded over JMAP and the server state read back over JMAP, not judged from the screen.
message/rfc822part byte-equal to the original; no copy in the reporter's Sent or Drafts; original in Junk with$junk,$phishing,$seen$junk/$phishingcleared,$seenas it was; one report; offered again$phishing; one Undo barmultipart/report; report-type=feedback-report,Feedback-Type: fraud, original byte for byte; no copy kept$junkonly, nothing sentNot tested: iOS (no Mac here). A real organisation policy on the device: the test accounts sign in without a webmail, so for the emulator build the address came from a local stand-in, and the policy reading is covered by unit tests only. Accounts signed in with a password get the webmail's public policy, which leaves out
organisation, so for them the action stays hidden, as for the app's other organisation rules.Screenshots / demo
Pixel 9 emulator. The boxes cover the test accounts' mail domain.
In the third, the link is drawn as plain dotted text and opens nothing.
Notes for reviewers
sendPhishingReportandfileReportedwould serve it here.🤖 Generated with Claude Code