The screen for inbuxa:ProtocolPolicy, the server-wide switch that closes
IMAP, POP3 and ManageSieve (legacy-protocols spec). Reached as
CustomComponent/LegacyProtocols, which the server's schema places under
Settings › Security; a server without that link never shows it.
- The selector lists every mail protocol, with what the switch does to
each and on which ports. SMTP and JMAP are shown locked, from the
server's lockedProtocols rather than a list carried here, so unlocking
later needs no admin release (LP-21).
- The statement is shown in full before the switch moves and while it is
off, with the listeners that close by name and port, and the note that
firewall rules and port-forwards are the operator's to reconcile
(LP-16, LP-20).
- Turning it off takes the typed phrase "turn off legacy mail", matched
exactly. Turning it back on is one click (LP-17).
- Listeners that could not be reopened stay listed, with a Try again
(LP-5).
- A banner on the Security settings and the dashboard while it is off
(LP-18). It stays silent on a server without the switch.
Visible to whoever may see listeners, changeable by whoever may update
them, matching the permissions the server checks.
Not here yet: the impact panel (LP-15), which needs the server to record
last use per protocol, and the tenant switch (LP-9 to LP-14).
INBUXA Admin built its own source into every deployment: the whole tree
packed as source.tar.gz next to the app, with an identity string shown
beside the link and in the version tooltip. The top bar menu and the
source link offered that download.
It answered the AGPL precisely -- the source of *this* build, uncommitted
work and all -- but it paid for that by carrying the tree into every
deployment, to a repository that is public and already has it. The
version shown beside the link already names the build, so the link and
the version together say what the archive said.
This is the same change already made to ihasmail-inbuxa, for the same
reason, and it leaves the two forks answering the offer the same way.
It is also what lets INBUXA Admin be built in an Alpine image: the
plugin shelled out to `tar --transform`, which BusyBox tar does not
have, so `npm run build` failed there and nowhere else.
Removed with it: source-archive.ts, the Vite plugin call, __SOURCE_ID__
and sourceDownloadUrl(). The build no longer shells out to git or tar,
and nothing is written next to the app.
The two strings that named the archive change with it: the link now
reads "Source code (<version>), AGPL-3.0" rather than naming a tree id,
and the version tooltip drops the id it appended.
Publishing the source is what asks for it: a modified version has to carry
prominent notices saying it was modified, with a date. These files already
added a Coffey Labs copyright line beside upstream's, which implies as much
without saying it; now they say it.
38 files, found by diffing against the merge base with upstream rather than
by guessing. Upstream's own notices are untouched. The build is unchanged.
The old web UI put everything in a sidebar, and a reskin of it would
still read as the old web UI. The modern shell splits navigation in two
instead: the layout switcher already in the top bar is tier one, and a
new bar under it carries that layout's own top-level items, each group
opening its children in a menu. Nothing on the left, so a queue table or
a dashboard gets the whole window.
- Management's nine entries and Account's eleven suit a menu bar; the
bar measures its items once per layout and folds whatever doesn't fit
into "More", recomputing on resize from the cached widths.
- Settings keeps the sidebar. Nineteen groups is a configuration browser,
not a set of destinations, and a menu bar stops helping however wide
the window; the threshold is on the count, not on the name, so a
changed schema can't strand anyone.
- Which shell to use is the reader's, beside the theme: user menu,
Layout, Modern or Legacy. Modern is the default, and the choice is
remembered in the browser rather than with the account — settings.json
is shared with the webmail, which has no notion of this.
- A phone is unchanged. The section bar is hidden below md and the
sidebar stays as the slide-over behind the hamburger.
- The tree walking both shells need moves to lib/navTree.ts, so the
sidebar and the section bar agree on what is visible, what is locked
and what is active.
A job that has a wizard now asks "Guide me / I'll do it myself" each time
it starts; nothing is remembered. The shared wizard shell gives every guide
a stepper, a side panel on what each step does and how to undo it, and the
way forward or back.
Automatic DNS, from a domain's DNS section:
- finds where the domain's DNS is hosted from its SOA and NS records, and
offers that host when the server can drive it;
- for the major hosts, steps to create the narrowest credential, and the
field named as the steps name it;
- records grouped by what they do, TLSA off unless the zone is signed;
- saves the provider and switches the domain over, removing the provider
again if the switch fails;
- watches the publishing task and public DNS, ticking each record green,
and boils a host's refusal down to its distinct messages;
- for hosts it can't drive, or domains not in DNS yet, every record laid
out for copying, with the same live checks.
The palette and light/dark choice now live in the account's JMAP Files
(ihasmail/settings.json), the same file and keys INBUXA webmail uses, so
the theme follows the user across devices and both apps. The admin
reads it at sign-in and writes only palette, mode and the derived
legacy theme, after a fresh read, keeping every other key. A palette
change keeps the stored mode. localStorage stays as the first-paint
cache.
Under the user menu, Theme offers ihasmail's palettes, in the same order and
under the same names. ihasmail is the default look, the colors the admin
already had, until someone picks another. The choice is remembered and
applied before the first paint, and dark mode still toggles on its own.
The other palettes' colors are ihasmail's, already contrast-checked, mapped
onto the admin's tokens by scripts/import-palettes.py; re-running it re-syncs
them. NOTICE carries the palettes' MIT notices and the fonts' OFL notices.
- The INBUXA palette on warm surfaces, softer cards, buttons and inputs, and
self-hosted Inter and Space Grotesk.
- Each section's icon sits on a colored tile, colored by what the section is
about.
- The sidebar gets a guide line for sub-pages and a labeled Management /
Settings / Account switch, and folds to a rail of tiles (remembered).
- Every page has a header with its section's tile.
- Fields and pages with no label of their own are spelled out in words
(defaultCertificateId becomes Default certificate ID).
- The dashboard greets you, and its stat cards wear colored tiles.
- Unavailable live numbers are a calm note, not an error.
- The cat appears in empty lists and while loading.
- Chart colors work again: they were hex values wrapped in hsl().
Every build writes the exact tree it was built from, uncommitted work
included, as source.tar.gz next to the app, and names that tree. The sidebar,
user menu, sign-in card and version tooltip link to it.
Coffey Labs' copyright line is added below Stalwart Labs' in every inherited
file changed, and the new files carry Coffey Labs' alone.
The upgrade prompt and its links are gone, the edition tooltip is neutral,
storage keys and the package description are INBUXA's own, and the README
states the lineage once, in the fine print.