Repository navigation
Releases: kubuno/mail
Release list
v0.1.8
Security
- HTML sanitiser updated to a patched release.
ammoniamoves from 4.1.2
to 4.2.0, closing two cross-site scripting holes in the sanitiser itself,
one through MathML and one through SVG animation tags (RUSTSEC-2026-0193,
RUSTSEC-2026-0213). - HTTP/2 layer updated to a patched release.
h2moves from 0.4.15 to
0.4.19, closing a denial of service through unbounded empty DATA frames
(RUSTSEC-2026-0258). - Error library updated to a patched release.
anyhowmoves from 1.0.102
to 1.0.104, closing an unsoundness inError::downcast_mut()
(RUSTSEC-2026-0190). - TLS library updated to a patched release. The pinned
rustlscarried
RUSTSEC-2026-0285 (medium). Every outbound HTTPS connection goes through it.
v0.1.7
Changed
- Typing
@in a recipient field reaches for a person. One letter after it
is now enough to be offered a list, instead of the usual two: the@has
already said you are naming somebody rather than typing an address. What
follows the@is what gets searched, and a half-typed@maris no longer
turned into a recipient of its own when you leave the field.
Added
-
A recipient pasted as a
Name <address>string is read as a name and an
address. It used to become a single unusable recipient carrying the whole
string. -
Writing to someone opens the composer, from anywhere in the instance. The
"write to them" action other modules offer beside a person — a guest on a
calendar event today — used to be amailto:handed to whatever the operating
system opens, which on an instance that has a mailbox is the wrong answer: it
loses the signature, the drafts and the sent copy. The composer already
floated above every module; it is now reachable by them, pre-filled with the
recipient, without leaving the page you were on. An instance without this
module keeps themailto:.
Added
-
"Directions" on an invitation. When the event carries a place and the Maps module is installed, the invitation card offers Directions beside the answers. It opens Maps in a new tab with the destination already filled in, so the invitation stays open behind it.
-
Guests can answer an invitation straight from the e-mail. The invitation now ends with a Répondre block offering Yes / No / Maybe; each button carries that guest's own link, so anyone can answer from any mail client without signing in to Kubuno. The buttons appear once an administrator has set the instance's public address in Calendar; without it the message explains that the answer is given from the recipient's own calendar, through the attached file.
-
Meeting invitation e-mails. When Calendar publishes an
invitation, Mail now sends the invitation e-mail on behalf of the organizer's
default account: a sober HTML body (event title, when, where, organizer, guest
list, description) plus a standards-compliantinvite.icsattachment
(text/calendar; method=REQUEST). A cancellation goes out the same way
(method=CANCEL), and a rescheduled event is flagged "Invitation mise à jour".
Recipients using any calendar client can accept, decline or answer "maybe"
straight from the message. -
RSVPs update the organizer's calendar automatically. When a guest replies
to an invitation (METHOD:REPLY) and the reply lands in the organizer's local
mailbox, Mail forwards the response to Calendar so the attendee's status
(accepted / declined / tentative) is reflected on the event without anyone
re-entering it. The same happens for a reply that syncs into an organizer's
external IMAP account (e.g. Gmail). -
Remote images from an unknown sender are held back, Gmail-style. A message
whose images would be fetched from outside the instance now shows a notice —
"External images are not displayed" — with Display images (this message) and
Always display images from (remembered). Nothing leaves the browser
until you ask: fetching a remote image tells its host the message was opened.
Inline (cid:), embedded (data:) and same-origin images are never touched,
and CSS backgrounds are neutralised too, not just<img>. -
Administrators define an instance-wide image allowlist (Mail → Filtering)
applying to every account on top of each user's own list, the way a Workspace
allowlist set at the top level applies to all organisations. It ships stocked
with major legitimate senders, accepts# commentsfor grouping, and an entry
only takes effect on a DMARC-authenticated message — nobody opted into it
individually, so a spoofed From must not be able to ride it. -
Notifications for calendar invitations. Receiving an invitation, a reply
to an invitation you sent (accepted / declined / maybe) or a cancellation now
raises its own notification, on top of the plain "new mail" one. Each is a
separate activity in Settings → Notifications. -
Declining an invitation can carry a reason, or propose another time.
Choosing "No" opens an optional panel: a note for the organizer (sent as the
iCalendar COMMENT) and an alternative slot. Filling the slot turns the answer
into an iTIP counter-proposal (METHOD:COUNTER) the organizer can accept. -
RSVP to calendar invitations, Gmail-style. An invitation card now offers
Yes / Maybe / No. Answering emails the organizer a proper iMIP reply
(text/calendar; method=REPLYwith the attendee's PARTSTAT), mirrors the
event into the calendar for Yes/Maybe (confirmed/tentative), and remembers the
answer so the chosen button stays selected on reload. -
Gmail-style rich cards for structured mail. Emails carrying schema.org
annotations (JSON-LD) or a calendar invitation (ICS) now show a card above the
body: calendar events/invitations, flight, hotel, train/bus, restaurant, car
rental, and order/parcel — with the key details laid out and, where relevant,
a check-in or tracking link. Event and invitation cards offer "Add to
calendar" (creates the event in the Calendar module) and a ".ics" download.
Extraction runs at delivery/sync time, so cards appear on mail received from
then on. -
Multiple sources and destinations in the search criteria. The "From"
field accepts several addresses, OR-combined (any of these senders); the "To"
field is a full AND/OR rule tree with nested groups — the same builder as the
"Additional filters" tab, its conditions locked onto:. "To" starts
compact like "From" — one input and a [+] — and switches to the multi-line
builder when a second condition is added, collapsing back at one. Both
round-trip with the bar's query text ((from:a OR from:b), parenthesized pure-to:
groups). -
Gmail-style contact suggestions in address fields of the search panel.
From/To criteria and builder rows whose operator takes an address (cc:,
bcc:,deliveredto:) suggest contacts as you type — avatar, display name
and address, merged from the contacts module and the mail address index. -
Logical repetitions are detected and removed when the search is
validated. Clicking "Search" simplifies the rule trees: duplicate
conditions collapse (label:x OR label:x→label:x), same-combinator
nesting flattens, single-child groups unwrap, and boolean absorption applies
(A OR (A AND B)→A); duplicate sources are deduplicated too. -
Search results always carry the filter-chip row — date, "Has attachment",
"To", "Exclude promotional offers" (new), "Unread" and the "Advanced search"
link. On a search view the chips refine the committed query (they append to
it and lift off it); folder views keep their scoped chip bar. -
Searching on senders features them above the results — avatar, display
name and the address as a mail link that opens the composer prefilled with
them. Multi-source queries ((from:a OR from:b)) show one card per sender,
flowing side by side on a single row; each card highlights on hover with a
plain rounded grey rectangle. -
The committed search lives in the URL —
#search/<encoded query>, Gmail
style: a search survives reloads, can be deep-linked and follows the browser's
back/forward. Clearing the search returns the hash to the folder. -
Condition rows can be reordered by drag and drop. Every condition and
group carries a grip; dropping between siblings shows a crisp insertion bar
(no translucent browser ghost), and dropping onto a group's header — which
highlights — moves the node into that group. Conditions and whole groups
move freely between root and any group; a group can never be dropped into its
own descendants. -
Uniform field typography in the advanced panel. The free-value inputs
render at the same 14px as every dropdown (the coarse-pointer 16px anti-zoom
guard was out-specifying the primitives' size on some devices). -
The search language accepts an explicit
AND.(-in:spam AND in:trash) OR is:subscriptionnow parses as intended:ANDis a combinator (juxtaposition
already meant AND), no longer a literal word to search for. -
The "Additional filters" tab is now a full recursive condition tree — the
standard query-builder model: every group carries one combinator ("all
conditions (AND)" / "any condition (OR)") and holds conditions, raw
expressions and nested groups, with "Condition" / "Group" buttons and per-node
deletion at every level. Any parenthesized AND/OR mix decomposes into editable
rows, and every edit rewrites the search bar live with correct parentheses.
Top-level OR chains are kept whole when pre-filling (sofrom:a OR from:bis
never silently split into a plain "From" field). -
A new search operator,
is:subscription. It matches messages that carry
aList-Unsubscribeheader — the same population the "Manage subscriptions"
view is built on. It combines with every other operator (from:,in:,
OR, negation, parentheses), and is suggested in the search bar.
Fixed
- Sent messages keep their formatting. Every outgoing message was cleaned with a policy that strips
styleoutright, so bold colours, spacing and alignment were lost the moment a message left — invitations arrived at their guests as an unstyled table. Sending now applies the module's own vetted policy, the same one the reader uses. - A conversation carrying an attachment now opens on a single click, wherever you click it. The attachment strip stretches across the whole row, and it swallowed clicks: the entire lower half of such a row opened nothing, so it often took a second click higher up. Clicking an attachment chip still previews that file instead of opening the conversation.
- **Sender, subject and date stay on the first line of a...
v0.1.6
Changed
- Theme tokens: two colours for navigation labels (
--color-text-nav,
--color-text-nav-active). Every module carries the same token sheet, so the
values must match across them — whichever bundle loads last would otherwise
win. No visible change inside this module. - The search bar follows the new default background (
#e9eef6). - Default application background token aligned with the core (
--body-bg#f8fafd). Only
visible when the module runs standalone: inside the shell the active theme sets it. - Search bar background now comes from the
--color-search-bgtoken (unified at#e9eef6)
rather than a hard-coded colour.