Skip to content

Add Junk Address Whitelisting and Basic Contacts UI#37

Merged
Sancus merged 6 commits into
mainfrom
junk-whitelist
Jun 16, 2026
Merged

Add Junk Address Whitelisting and Basic Contacts UI#37
Sancus merged 6 commits into
mainfrom
junk-whitelist

Conversation

@Sancus

@Sancus Sancus commented Jun 15, 2026

Copy link
Copy Markdown
Member

No description provided.

Sancus added 6 commits June 15, 2026 18:40
The message toolbar shows a Not-junk button when the open folder is Junk.
Clicking it queues a whitelistSender mutation that files the sender in a
Trusted senders address book via ContactCard/set (so Stalwart's contact
trust delivers future mail to the Inbox), removes $junk / adds $notjunk,
and moves the message to the Inbox, then shows a success toast.
Stalwart serves ContactCard objects in the RFC 9553 map shape
(`addressBookIds`, an `emails` keyed map, `name.full`, `organizations`),
but the sync parser expected the older single `addressBookId` / flat
`emails` array / `fullName` shape. Every real card failed the
addressbook lookup and was silently skipped, so synced contacts — and
the sender a Junk "Not junk" whitelist files into "Trusted senders" —
never appeared in the local cache. Requested property names were the
non-spec ones too.

Normalize each card (tolerating both shapes) and request the JSContact
property names, so contacts populate locally as expected.
…ple emails

Turn the read-only contacts view into a basic manager:

- Address-book folder rail with per-book counts and an "All contacts"
  entry; selecting a book filters the list and targets new contacts.
- Add, edit, and remove contacts over standard JMAP (ContactCard/set
  create/update/destroy) via new createContact / updateContact /
  deleteContact mutation types whose outbox handlers reconcile the
  local cache so changes appear immediately.
- Multiple emails per contact (add/remove rows in the same form).

Editing never silently drops data the form does not show: update
re-fetches the card and merges, so untouched email metadata, name
components, and other top-level properties (phones, organizations,
addressBookIds) are preserved — only fields the user actually edited or
removed change.
The repo had no automated browser coverage for these new features.
This spec drives the real UI against the local stack and verifies the
server side via JMAP: the Junk "Not junk" action whitelists the sender
(trusted ContactCard) and rescues the message to the Inbox, and the
contacts manager adds (multi-email), edits (rename + add email, merge
preserved), and removes a contact. Passes on Chromium and Firefox.
Run the whitelist trust write and only confirm success when it actually
applied. Share a queue-and-run helper so contact create/edit/delete treat
a run that attempted nothing as a failure, reuse the shared address
parser for the Junk sender, give the contact email-form rows stable keys,
clear the transient mail notice on reset, and add light types to the JMAP
contact helpers. Extend the e2e to assert the local cache via window.__repo
and the rescued $junk/$notjunk keywords server-side.
Replace the read-only contacts scope with create/edit/delete, the
address-book rail, and JSContact ingest requirements; add the Junk
"Not junk" triage requirement; and drop contact editing from the
non-goals.
@Sancus Sancus merged commit 6a4039f into main Jun 16, 2026
9 checks passed
@Sancus Sancus deleted the junk-whitelist branch June 16, 2026 03:43
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