Commit Graph
817 Commits
Author SHA1 Message Date
jcoffey-dev 22d891b1ed Merge pull request 'Seven app fixes from public ihasmail' (#25) from merge/public-app-fixes into main
ci / version (push) Skipped
ci / node (push) Successful in 2m30s
ci / publish (push) Skipped
ci / announce (push) Skipped
ci / docker-build (push) Successful in 1m56s
2026-09-27 23:32:21 +00:00
jcoffey-dev c64a23f9d9 List folders in sidebar order in the move-to picker
ci / version (pull_request) Skipped
ci / node (pull_request) Successful in 2m29s
ci / publish (pull_request) Skipped
ci / announce (pull_request) Skipped
ci / docker-build (pull_request) Successful in 1m23s
The picker sorted folders A-Z by path, with Inbox first, so a folder
dragged into place in the sidebar turned up somewhere else when moving
mail. It now walks the tree in compareFolders order, the sidebar's
order with every folder expanded: Inbox, then the saved order, then
the special folders, then A-Z, with subfolders under their parent.

treeOrder lives beside compareFolders. A folder the walk from the top
cannot reach is appended rather than dropped, so it stays pickable as
it was before.

Closes #1

(cherry picked from commit ea03406646062359f74e16ad8a8aed074b4dc409)
2026-09-27 16:27:24 -07:00
jcoffey fedc34698e The toolbar above an open message acts on that message (#414) (#417)
With conversation view off, marking a message unread from the list --
the hover button, the right-click menu -- marked that message. Opening
it and pressing Mark as unread in the toolbar above it marked every
message in its thread, and so did Move to, Report spam and Delete.

The setting already reaches all the way into the reading pane: the list
draws one row per message, and `visibleMessages` narrows the pane to the
one opened. The toolbar was half converted. Its labels were right --
Mark as unread against Mark as read, the star, the labels shown -- all
of those read `messages`, which is the narrowed set. Only `rowIds`, the
one thing actually handed to the action, still read `thread.emailIds`.
So the button said one message and did the whole conversation.

`rowIds` is now the same question `visibleMessages` answers for the
pane, asked of the same ids, with the same fallback: an id that names
nothing in the thread -- a link from somebody with conversation view on,
a stale `m` in the URL -- shows the conversation, so the toolbar takes
the conversation. Conversation view on is unchanged: nothing is singled
out, so the whole thread comes back as before.

No new strings.

(cherry picked from commit f627bfc1237d6e8bbc728147022f624c3834d648)
2026-09-27 16:27:24 -07:00
jcoffey 8bfc7a85a9 A reply to a self-addressed message follows its Reply-To (#415) (#416)
A website contact form mails the site's own address: From and To are
both info@thesite, and the person who filled the form in is in Reply-To.
Replying addressed the draft to info@thesite -- the site's own desk --
instead of to them.

The reply already knows two shapes. A message somebody sent me is
answered to its Reply-To, which is what that header is for. A message
*I* sent is answered to the people I wrote to, and deliberately not to
my own Reply-To, which is where answers to me belong and would send my
reply to myself. A contact form passes the test for the second: every
address in From is mine.

So it fell down the chain the second shape keeps for a message with
nobody obvious to answer -- To without me, then Cc, then, having run
out, every address on the message, which here was mine alone.

The Reply-To now goes in that chain, one step before the last: when no
recipient but me is left and the message names a Reply-To that is not
mine either, that address is who it is really from. Keeping it after the
Cc is what leaves a message I did send alone -- somebody I actually
wrote to still beats my own Reply-To, which is the case the existing
guard was built for and its test still holds.

No new strings.

(cherry picked from commit 01dc322aebcff0e8075c54f81eb7d171a32fb9e7)
2026-09-27 16:27:24 -07:00
jcoffey 2fffc9043d Quote images through the proxy, and unproxy them on the way out (#412) (#413)
Reading a message fetches its remote images through this server, so the
sender learns nothing about the reader. Quoting the same message into a
reply fetched them directly: same pixel, same reader, but the request
carried their IP and user agent -- exactly what the proxy withholds.

A quote now proxies them the way the message view does. That alone would
be wrong, because a proxied URL belongs to this deployment: sent
unchanged it would reach the recipient as images only this server can
serve, broken for them and a beacon back here. So buildEmailObject turns
them back into the addresses they came from, beside the pass that
restores images blocked under pr411 and the one that turns editor blob
URLs into cid: references.

Deployments with the proxy off are unaffected: the quote fetches
directly, as reading does there.

Three tests from pr411 asserted the address sat in src when images were
allowed, which was the old behaviour; they now ask whether the draft
fetches it at all, proxied or not.

No new strings.

(cherry picked from commit 23557a72a2a72088081792f8ea0cabedea4e7bcb)
2026-09-27 16:27:24 -07:00
jcoffey a94fd9cce3 Quoting follows the message's own image decision (#410) (#411)
Replying sanitized the quoted body with allowRemote: true, so quoting
fetched every remote image in the message whatever the reader had
decided about it. A tracking pixel in the quote then reported the
message read, and the address live, to whoever was counting -- the thing
leaving the images blocked was meant to prevent. Edit as new and opening
a draft that quotes a message did the same.

The decision now lives in one place, remoteImagesAllowed(), asked with
the same inputs the reader's answer used: the image policy, the trusted
senders, whether the sender is a contact, and whether Show images was
pressed on that message. The last of those was component state, so it
moves to the mail store, where the composer can see it.

Blocked images already keep their address in data-ihm-remote, so nothing
is lost by not fetching: it goes back on the way out, and the sent quote
is what its sender wrote. The recipient's client decides for itself, as
it would with any other client's reply.

Before pr408 this needed a rich-text default to reach; the format offer
made it reachable from plain text, which is how it was found.

No new strings.

(cherry picked from commit d329b33912921a851c548bffef5085e5fbf72bed)
2026-09-27 16:27:24 -07:00
jcoffey 9ba2c6e290 Switching format keeps the original quote, not a flattened copy (#409) (#409)
Switching a reply between plain text and rich text converted whatever
body the draft was showing. Going from plain text to rich, that meant
the quoted message came back as the "> " text quote run through a
converter -- the sender's formatting, images and links gone, even though
the original markup was sitting on the draft untouched.

Both forms of the quote are prepared when the reply opens, so keep them
on the draft and re-attach the right one when the format changes. Only
what the author typed above the quote is converted. Where the quote
can't be found any more -- edited by hand, or a draft that quotes
nothing -- the whole body is converted as before, which is what every
non-reply draft does.

No new strings.

(cherry picked from commit 88f9e6c50a04f8ffc4702d1d1e3cffa6a93e7690)
2026-09-27 16:27:24 -07:00
jcoffey 996aa66ef0 Offer the message's own format when replying (#407) (#408)
A reply opened in the format the settings ask for, whatever the message
being answered was written in, and the per-draft switch was buried in
the composer's ⋮ menu. Replying in plain text to a rich text message
throws away the formatting; replying in rich text to a plain-text one
overrides what the sender chose to write in.

When the two disagree the composer now says so above the editor -- "This
message is rich text", with a Switch button and a dismiss -- and the
draft still opens in the format the settings ask for. Switching converts
that draft only and leaves the setting alone; switching from the ⋮ menu
answers the offer too. Forwards get it as well, where the formatting
being passed on is somebody else's.

What counts as rich text is hasHtmlAlternative(), which reads the body
part's own type: `htmlBody` is derived (RFC 8621 4.1.4), so a plain-text
message has one too and its presence proves nothing.

The mock said otherwise -- it returned an empty `htmlBody` for a
plain-text message, where Stalwart 0.16.21 returns the text/plain part
in both lists. Both builders now answer as the server does, so the path
this feature depends on is exercised in development rather than only
against a real mailbox.

Two new strings, translated in all nine catalogs; the buttons reuse the
menu's existing "Switch to plain text" / "Switch to rich text". The
count falling back to English stays at 16 in every language.

Fixes #407

(cherry picked from commit d992442b8194be5e9c48204332c7243d9587b4ca)
2026-09-27 16:27:24 -07:00
jcoffey-dev d5c49c2962 Merge pull request 'Mark no interface language Beta' (#24) from i18n/no-beta-languages into main
ci / version (push) Skipped
ci / node (push) Successful in 2m33s
ci / publish (push) Skipped
ci / announce (push) Skipped
ci / docker-build (push) Successful in 15s
2026-09-27 23:05:17 +00:00
jcoffey-dev ee675004f2 Mark no interface language Beta
ci / version (pull_request) Skipped
ci / node (pull_request) Successful in 2m26s
ci / publish (pull_request) Skipped
ci / announce (pull_request) Skipped
ci / docker-build (pull_request) Successful in 32s
Every shipped language is offered without the Beta mark. The flag and
its settings note stay, so public ihasmail's changes to them still apply.
2026-09-27 16:01:58 -07:00
jcoffey-dev 2361caf2c7 Merge pull request 'Dutch out of Beta: the native speaker's final review, from public ihasmail' (#23) from i18n/dutch-native-review into main
ci / version (push) Skipped
ci / node (push) Successful in 2m37s
ci / publish (push) Skipped
ci / announce (push) Skipped
ci / docker-build (push) Successful in 16s
2026-09-27 23:01:42 +00:00
jcoffey-dev 2c4d6cdfae Link Michael's profile from the Dutch credits
ci / version (pull_request) Skipped
ci / node (pull_request) Successful in 2m40s
ci / publish (pull_request) Skipped
ci / announce (pull_request) Skipped
ci / docker-build (pull_request) Successful in 30s
(cherry picked from commit 9840a537834082bfd9a028a170ce2d6ac60ddf35)
2026-09-27 15:57:28 -07:00
jcoffey-dev f95072ab92 Credit Michael (mbjboon82) for the Dutch review
Name the reviewer in both Dutch catalogs, FEATURES and ROADMAP, under both of his handles, and record that his wording stands.

(cherry picked from commit aaa86e96d66e2431a8c98467712a977d4035bf76)
2026-09-27 15:57:28 -07:00
jcoffey-dev ab759143ab Take Dutch out of Beta with the native speaker's final review
Michael (mbjboon-netizen) sent the final corrections for nl.ts and the Dutch
permission labels and signed the language off, so Nederlands no longer
carries the Beta flag in the picker.

The main catalog changes 52 values, mostly "regels" -> "filterregels" and
"post" -> "e-mail(s)". The permission headings move from compound nouns
("Accountbeheer") to verb phrases ("Accounts beheren"), and the reviewer's
note on that is kept in the file. No keys were added or removed, and every
placeholder is intact.

One entry is kept as it was: "It {damage}, ..." stays "Het {damage}, ...".
{damage} is filled with a verb phrase ("stops in the middle of a line"), so
the added "is" would have doubled the verb.

README, FEATURES, ROADMAP and KNOWN-ISSUES now say Dutch has been reviewed
and the other eight have not.

(cherry picked from commit e30fd73d7dbb1463859efbc4048f680d21d64c56)
2026-09-27 15:57:23 -07:00
jcoffey-dev d0f7c6ed20 Merge pull request 'Open locked accounts handed to you, beside your own mail' (#22) from feature/delegated-accounts into main
ci / version (push) Skipped
ci / node (push) Successful in 2m45s
ci / publish (push) Skipped
ci / announce (push) Skipped
ci / docker-build (push) Successful in 15s
2026-09-27 22:55:38 +00:00
jcoffey-dev 4fcc8dd1b9 Show every folder of a locked account in view
ci / version (pull_request) Skipped
ci / node (pull_request) Successful in 2m25s
ci / publish (pull_request) Skipped
ci / announce (pull_request) Skipped
ci / docker-build (pull_request) Successful in 30s
Folder subscriptions are the reader's own and they have none in an
account handed to them, so only Inbox showed. Every folder shows while a
locked account is in view, and Hide from list is gone there.
2026-09-27 15:50:51 -07:00
jcoffey-dev 8674b70f62 Open locked accounts handed to you, beside your own mail
When the server hands a locked account to the reader (urn:inbuxa:jmap
delegation), the account popover offers it. Only mail follows the switch;
the reader's own settings, push and notifications stay theirs. A red bar,
a red wordmark with a padlock and the tab title say which account is in
view. Read delegates can't change anything, organize delegates can't
delete, and writing needs send-as. A delegation taken away drops back to
the reader's own mail.

14 new strings in all nine catalogs, unreviewed (inbuxa AL-7, AL-8).
2026-09-27 14:32:10 -07:00
jcoffey-dev ffe1a898f5 Merge pull request 'Version the brand images URLs' (#21) from brand/versioned-images into main
ci / version (push) Skipped
ci / node (push) Successful in 2m46s
ci / publish (push) Skipped
ci / announce (push) Skipped
ci / docker-build (push) Successful in 17s
2026-09-27 05:53:40 +00:00
jcoffey-dev 0adc402629 Version the brand images' URLs, so a new mark reaches returning visitors
ci / version (pull_request) Skipped
ci / node (pull_request) Successful in 2m25s
ci / publish (pull_request) Skipped
ci / announce (pull_request) Skipped
ci / docker-build (pull_request) Successful in 37s
The logo, favicons and app icons are served from public/img under fixed
names with a browser cache of hours, and the service worker fetches them
through that cache. After the mark changed on 2026-09-27, returning
visitors kept the old cat until their copies expired, and the favicon
and an installed app's icon hold on longer still.

Every URL that names one now carries ?v=BRAND_V (src/lib/brand.ts,
brandImage()): the header, sign-in, About, the mail empty state, the
notification icons, index.html's favicon links, the manifest's icons
and the service worker's shell and notification icons. Date-stamped,
never a counter, for the sites' ASSET_V reason; the three static files
carry the value written out, and the comment says to keep them in step.
2026-09-26 22:50:22 -07:00
jcoffey-dev 2a30a32c79 Merge pull request 'Brand: inbuxa own kitten replaces ihasmail cat' (#20) from brand/new-mark into main
ci / version (push) Skipped
ci / node (push) Successful in 2m29s
ci / publish (push) Skipped
ci / announce (push) Skipped
ci / docker-build (push) Successful in 3m19s
2026-09-27 05:12:38 +00:00
jcoffey-dev ee41846c2d Brand: inbuxa's own kitten replaces ihasmail's cat
ci / version (pull_request) Skipped
ci / node (pull_request) Successful in 2m43s
ci / publish (pull_request) Skipped
ci / announce (pull_request) Skipped
ci / docker-build (pull_request) Successful in 1m7s
The webmail showed ihasmail's cat-and-envelope as inbuxa's mark. The new
mark keeps the family's face, paws and colors, over a server with a bay
for each piece of the suite: the letter (webmail), a prompt (console),
status lights (server).

- img/inbuxa-mark.png (header, sign-in, About) and img/logo.png (the
  mail empty state and the custom-name fallback).
- favicon.ico, favicon-64, apple-touch-icon (opaque white, as before),
  icon-192/512, and icon-maskable, now on an opaque ground with the
  mark inside the safe circle.
- Login.tsx: 120x126, the new mark's proportions; 120x143 would have
  stretched it. Every other use sizes by one dimension.
- The service worker fetches images network-first, so installed copies
  pick the new ones up without a cache version bump.
2026-09-26 22:03:19 -07:00
jcoffey-dev 6cb3321022 Merge pull request 'Announce releases on the community forum' (#19) from announce-releases into main
ci / version (push) Skipped
ci / node (push) Successful in 2m6s
ci / publish (push) Skipped
ci / announce (push) Skipped
ci / docker-build (push) Successful in 13s
2026-09-27 02:37:12 +00:00
jcoffey-dev b407969849 Announce releases on the community forum
ci / version (pull_request) Skipped
ci / node (pull_request) Successful in 2m38s
ci / publish (pull_request) Skipped
ci / announce (pull_request) Skipped
ci / docker-build (pull_request) Successful in 2m22s
announce.yml runs coffey-labs/actions discourse-release on every published
release, posting it to this project's Announcements category on
community.coffeylabs.org. The release workflow also announces
from its own job, since a release made with the job token fires no
'on: release' workflow in Gitea.
2026-09-26 19:28:12 -07:00
jcoffey-dev 654d298a18 Merge pull request 'About: present inbuxa as the suite, not only the webmail' (#18) from fork/about-suite into main
ci / version (push) Successful in 26s
ci / node (push) Successful in 2m56s
ci / docker-build (push) Skipped
ci / publish (push) Successful in 3m41s
inbuxa-v2026.9.26-g654d298
2026-09-26 04:21:58 +00:00
jcoffey-dev dfbfc38258 About: present inbuxa as the suite, not only the webmail
ci / version (pull_request) Skipped
ci / node (pull_request) Successful in 2m25s
ci / publish (pull_request) Skipped
ci / docker-build (pull_request) Successful in 29s
The lead now says what inbuxa is: a mail server, its administration
console and this webmail, installed together under the AGPL, with the
name set apart in the brand teal. A new "The suite" table lists the
mail server, the console (linked, for sessions that may administer),
this webmail's version and inbuxa.org.

4 new strings in all 9 catalogues; the old webmail-only lead is dropped
from them, since nothing looks it up any more.
2026-09-25 21:18:13 -07:00
jcoffey-dev 8fef2c208d Merge pull request 'About: the mail node by hostname, found with resolvePtr' (#17) from fork/about-ptr-fix into main
ci / version (push) Skipped
ci / node (push) Successful in 2m25s
ci / publish (push) Skipped
ci / docker-build (push) Successful in 15s
2026-09-26 04:18:11 +00:00
jcoffey-dev 66673bc9d1 About: show the mail node's hostname, not its address
ci / docker-build (pull_request) Successful in 31s
ci / version (pull_request) Skipped
ci / node (pull_request) Successful in 2m28s
ci / publish (pull_request) Skipped
The address is only shown when the node has no PTR record.
2026-09-25 21:14:54 -07:00
jcoffey-dev 41fb7875d0 About: find the mail node's name with resolvePtr
ci / version (pull_request) Skipped
ci / node (pull_request) Canceled after 36s
ci / docker-build (pull_request) Canceled after 0s
ci / publish (pull_request) Canceled after 0s
dns.reverse came back empty inside the image while the resolver answered
the PTR, so About showed only the address. Ask for the PTR record of the
in-addr.arpa / ip6.arpa name directly.
2026-09-25 21:14:13 -07:00
jcoffey-dev 3507a21599 Merge pull request 'About: name the webmail node and the mail server node' (#16) from fork/about-node-identity into main
ci / version (push) Skipped
ci / node (push) Successful in 2m25s
ci / publish (push) Skipped
ci / docker-build (push) Successful in 15s
2026-09-26 04:05:46 +00:00
jcoffey-dev 6b44705bfd About: name the webmail node and the mail server node
ci / version (pull_request) Skipped
ci / node (pull_request) Successful in 2m26s
ci / publish (pull_request) Skipped
ci / docker-build (pull_request) Successful in 53s
Settings > About shows which webmail node answered (NODE_NAME, else the
container hostname) and which inbuxa node it talks to: the address the
server's name resolves to from the webmail, named by its PTR record. The
server only tells administrators its node name, so the webmail works it
out itself. Fetched from /api/about/nodes on every visit, cached for a
minute server-side, for troubleshooting a cluster.

Fork-only: upstream ihasmail runs one webmail against one server.
4 new strings, translated in all 9 catalogues.
2026-09-25 20:46:04 -07:00
jcoffey-dev 119548090e Merge pull request 'Show the language model's opinion on a message' (#15) from feature/llm-opinion into main
ci / version (push) Skipped
ci / node (push) Successful in 2m22s
ci / publish (push) Skipped
ci / docker-build (push) Successful in 2m43s
Reviewed-on: inbuxa/ihasmail-inbuxa#15
2026-09-23 05:39:19 +00:00
jcoffey-dev e4926cfa7d Show the language model's opinion on a message
ci / version (pull_request) Skipped
ci / node (pull_request) Successful in 2m23s
ci / publish (pull_request) Skipped
ci / docker-build (pull_request) Successful in 1m24s
When inbuxa-server's AI spam classification is on, it records the model's
answer in an X-Spam-LLM header: a tag (LLM_<category>[_<confidence>]) and,
in parentheses, the model's explanation. The full message now asks for it,
and where it's there:

- the message details show "Language model's opinion" beside the spam
  filter's own working, with category, confidence and explanation;
- a message in Junk carries a banner saying the same.

Both say it's one of several signals the spam filter weighed, never the
reason on its own, as the server's spec requires. The explanation is model
output and is only ever rendered as text. Nothing shows without the header,
so a server without the feature, or with it off, looks as before.

Translations: two new strings, "Language model's opinion" and "One of
several signals the spam filter weighed", in all eight catalogues (16
entries). Category and confidence come from the server and aren't
translated.
2026-09-22 22:03:29 -07:00
jcoffey-dev c0c892dd33 Merge pull request 'Use the server's renamed registry capability, urn:inbuxa:jmap:registry' (#14) from fork/rename-upstream-identifiers into main
ci / version (push) Skipped
ci / node (push) Successful in 1m25s
ci / publish (push) Skipped
ci / docker-build (push) Successful in 16s
Reviewed-on: inbuxa/ihasmail-inbuxa#14
2026-09-23 04:25:12 +00:00
jcoffey-dev f5dd4e5537 Use the server's renamed registry capability, urn:inbuxa:jmap:registry
ci / version (pull_request) Skipped
ci / node (pull_request) Successful in 2m47s
ci / publish (pull_request) Skipped
ci / docker-build (pull_request) Successful in 3m55s
inbuxa-server renames the identifiers that carried the upstream name (its
SPEC.md §2.4). Upstream's capability for the registry (x:) objects is now
urn:inbuxa:jmap:registry, beside the fork's own urn:inbuxa:jmap, which is
unchanged. There's no alias, so this lands with the server change and
deploys with it. The mock advertises the new name too. No user-visible
strings change.
2026-09-22 19:00:19 -07:00
jcoffey-dev e7ee09d228 Merge pull request 'Lowercase the name in the page title' (#13) from brand/lowercase-title into main
ci / version (push) Skipped
ci / node (push) Successful in 2m23s
ci / publish (push) Skipped
ci / docker-build (push) Successful in 1m17s
2026-09-23 00:16:23 +00:00
jcoffey-dev 1752276229 Lowercase the name in the page title
ci / version (pull_request) Skipped
ci / node (pull_request) Successful in 1m37s
ci / publish (pull_request) Skipped
ci / docker-build (pull_request) Successful in 40s
The browser tab, and anything that takes its name from the document title,
read INBUXA. The manifest, the server's app name and the sign-in card all
have it lowercase; the title was the one place left in caps.

Prod's APP_NAME override was set to inbuxa at the same time; the code
default already was.
2026-09-22 17:13:39 -07:00
jcoffey-dev acd9cff4ea Merge pull request 'Take the upstream name out of the mock's sample data' (#12) from mock/brand-sample-data into main
ci / version (push) Skipped
ci / node (push) Successful in 1m19s
ci / publish (push) Skipped
ci / docker-build (push) Successful in 15s
2026-09-22 23:06:53 +00:00
jcoffey-dev 413ece3bca Take the upstream name out of the mock's sample data
ci / version (pull_request) Skipped
ci / node (pull_request) Successful in 1m16s
ci / publish (pull_request) Skipped
ci / docker-build (pull_request) Successful in 33s
The mock inbox showed a sender called "Stalwart Labs" at [email protected],
a "Welcome to Stalwart!" subject, a link to stalw.art in the sample HTML
and a start-up banner tagged [mock-stalwart]. None of that belongs in this
fork, and it turns up in any screenshot taken from the mock.

Sample senders and subjects now name inbuxa, the sample link points at
inbuxa.org, and the banner says [mock-server].
2026-09-22 16:03:31 -07:00
jcoffey-dev 4bbfd7d455 Merge pull request 'Lowercase the tab title fallback' (#11) from fix/brand-lowercase-title into main
ci / version (push) Skipped
ci / node (push) Successful in 2m20s
ci / publish (push) Skipped
ci / docker-build (push) Successful in 17s
2026-09-22 22:24:12 +00:00
jcoffey-dev d0832013fe Lowercase the tab title's fallback name
ci / version (pull_request) Skipped
ci / node (pull_request) Successful in 1m46s
ci / publish (pull_request) Skipped
ci / docker-build (pull_request) Successful in 37s
The title the tab falls back to before the session names the app was the one
user-visible string the brand pass missed; setBaseTitle overwrites it as soon
as the session arrives, so it shows only for that first moment.
2026-09-22 15:21:35 -07:00
jcoffey-dev b79fdb8bab Merge pull request 'Write the name in lowercase where people see it' (#10) from fix/brand-lowercase into main
ci / version (push) Skipped
ci / node (push) Successful in 2m28s
ci / publish (push) Skipped
ci / docker-build (push) Successful in 16s
2026-09-22 22:18:06 +00:00
jcoffey-dev 8d717e0037 Write the name in lowercase where people see it
ci / version (pull_request) Skipped
ci / node (pull_request) Successful in 2m21s
ci / publish (pull_request) Skipped
ci / docker-build (pull_request) Successful in 1m10s
The brand is lowercase inbuxa. This changes what the app calls itself by
default, the wordmark's accessible name, the sign-in card's version line, the
installed app's name in the manifest, and the four translated strings that
name the console or the mail server.

Those four are source strings, so their catalog keys changed with them in all
nine languages; the translations keep their text with the name corrected. No
key was left behind, and no language falls back on more strings than before:
1643/1662 translated, 19 falling back, in each of the nine, unchanged.

Code identifiers, capability URNs, env var names and comments are untouched.
2026-09-22 15:13:53 -07:00
jcoffey-dev c2f13d6a1a Merge pull request 'ci: publish tagged releases as INBUXA's own image' (#9) from ci/inbuxa-release into main
ci / version (push) Successful in 1m24s
ci / node (push) Successful in 2m33s
ci / docker-build (push) Skipped
ci / publish (push) Successful in 5m41s
inbuxa-v2026.9.22-gc2f13d6
2026-09-22 16:58:24 +00:00
jcoffey-dev afb39fac20 ci: publish tagged releases as INBUXA's own image
ci / version (pull_request) Skipped
ci / node (pull_request) Successful in 1m15s
ci / publish (pull_request) Skipped
ci / docker-build (pull_request) Successful in 28s
A tag named inbuxa-v<version> (the tagged commit's own version from
scripts/version.mjs, '+' as '-') now builds a linux/amd64 + linux/arm64
image at <REGISTRY>/inbuxa/ihasmail-inbuxa, tagged with the version and
latest, links the package to the repository and creates the release.

The inbuxa- prefix keeps upstream ihasmail's v* tags, which this
repository carries on shared commits, from ever publishing under the
INBUXA name. The tag must name its commit's version and the commit must
be on main. No schedule yet: releases are cut by hand.
2026-09-22 09:56:09 -07:00
jcoffey-dev b514dab62a Merge pull request 'Point links at the new git host' (#8) from fix/links-after-move into main
ci / node (push) Successful in 3m15s
ci / docker-build (push) Successful in 58s
2026-09-22 16:09:58 +00:00
jcoffey-dev 2d7d8952ab Point links at the new git host
ci / docker-build (pull_request) Successful in 1m13s
ci / node (pull_request) Successful in 4m42s
GitHub went dark with the account suspension on 2026-09-20 and GitLab was
retired on 2026-09-22, so links to either no longer resolve. Repository,
file, release and download links now point at git.coffeylabs.org, images
at registry.coffeylabs.org, and old GitHub issue and pull request links at
coffey-labs/ihasmail-github-archive, whose numbers match GitHub's.
2026-09-22 09:03:00 -07:00
jcoffey-dev e752d08ebc Merge pull request 'ci: run socket-free jobs on the light label' (#7) from ci/light-runner into main
ci / node (push) Successful in 2m28s
ci / docker-build (push) Successful in 40s
2026-09-22 13:58:10 +00:00
jcoffey-dev dd955a939e ci: run socket-free jobs on the light label
ci / docker-build (pull_request) Successful in 1m31s
ci / node (pull_request) Successful in 2m28s
Both runners carry `light` (host1, and host2 over the wg-hosts link), so
these jobs run on whichever host is free. Jobs that mount the docker socket
keep `runs-on: docker`, which only host1 has.
2026-09-22 06:45:41 -07:00
jcoffey-dev 26cf45f502 Merge branch 'ci/gitea-actions' into 'main'
ci / node (push) Successful in 5m11s
ci / docker-build (push) Successful in 1m8s
ci: add Gitea Actions workflow

See merge request inbuxa/ihasmail-inbuxa!6
2026-09-22 00:03:04 -07:00
jcoffey-dev 7469598178 ci: add Gitea Actions workflows ported from .gitlab-ci.yml
ci / node (pull_request) Successful in 2m25s
ci / docker-build (pull_request) Successful in 3m28s
2026-09-21 22:49:35 -07:00