jcoffey-dev 28c49b4056
ci / build (pull_request) Successful in 1m13s
ci / publish (pull_request) Skipped
Apply saved settings on the server after a save
A registry write is stored at once, but the running server only picks up
most settings when it rebuilds its configuration, which it does on a write
for directories and the default authentication alone. Everything else, a
delivery schedule for one, sat unapplied until someone ran Management >
Actions > Reload > Server settings by hand.

Every x:<Type>/set now goes past a listener in the JMAP client. A write that
changed a settings object queues the reload action it needs, and once no
write has been in flight for 600 ms the queued actions go out together in
one x:Action/set. A bulk edit or a page that saves several objects in a row
costs one reload, not one per object; a save still in flight holds the
reload back however long it takes.

Which action a type needs lives in lib/settingsApply.ts. Certificates, lookup
stores and blocked IPs have their own reload actions, and the full settings
reload doesn't rebuild them. Directories and authentication, data read live
or kept current by cache invalidation (accounts, domains, DKIM keys, tenants,
roles, lists and the like), operations and records, and stores, which a
reload never reopens, get none. A type the list doesn't know is reloaded: an
unneeded reload costs a second, a missing one leaves a setting unapplied. If
the server later applies these writes by itself, this becomes one extra,
harmless reload per burst of saves.

Applying straight after a save is safe because a reload is all or nothing:
the new configuration replaces the running one only when every settings
object builds. When one doesn't, the server keeps what it had and names the
object and the problem. That now shows as a banner above the page, "Saved,
but the server couldn't apply the settings: <reason>", naming the object with
a link to it, and an Apply now button. It stays until a reload succeeds or it
is dismissed. A failure that is already known is not retried on unrelated
saves, only on Apply now or a save that needs a reload.

On success a "Saved and applied" toast replaces the form's own "Saved
successfully" and "Created successfully" for settings objects, so a save
shows one message, not two.

New strings, in src/i18n/en.json (the only catalogue) under settingsApply:
applied, applyNow, dismiss, failed, failedObject, noAnswer, notConfirmed,
openObject, stillRunning.
2026-09-24 11:16:09 -07:00
2026-08-24 15:44:51 +02:00
2026-09-20 20:17:38 -07:00
2026-04-20 15:02:57 +02:00
2026-04-20 15:02:57 +02:00
2026-09-15 09:27:02 +02:00
2026-04-20 15:02:57 +02:00
2026-09-22 22:42:02 -07:00
2026-04-20 15:02:57 +02:00
2026-04-20 15:02:57 +02:00

inbuxa

INBUXA Admin

The administration interface for the INBUXA mail server: every server setting, first-boot setup, and recovery, in the browser.

It is schema-driven. After signing in it fetches the server's schema and builds every form, list and menu from it, so it covers every setting the server has without hardcoding any of them.

Design

  • One edition. Every feature the server has is available here, with nothing held back. See the INBUXA server's docs/spec/.
  • Runs anywhere, not on the mail server. INBUXA Admin is its own deployment, never installed onto the mail server. It's pointed at the server either at build time (VITE_API_BASE_URL) or at deploy time: <meta name="api-base-url" content="https://mail.example.com"> in index.html. Hosted like that, it signs in as the OAuth client inbuxa-admin, which the server registers when it's started with INBUXA_ADMIN_URL set to INBUXA Admin's address (for development, http://localhost:5173).
  • INBUXA's look: the logo and ihasmail's palette.
  • Two-factor setup names INBUXA as the issuer, and no longer makes authenticator apps fetch a logo from a third-party site.

Developing

npm ci
npm run dev          # http://localhost:5173, against VITE_API_BASE_URL in .env.development
npm run typecheck && npx eslint src/ && npx vitest run
npm run build

Keeping up with upstream

The upstream codebase's history contains no code under a proprietary license, so this is an ordinary git fork. upstream is a fetch-only remote:

git fetch upstream --tags
git merge v1.0.12        # the next release tag

Versions

INBUXA Admin has its own dated version (inbuxa-version.json), shown with the upstream release it's based on: INBUXA Admin 2026.9.18 (base 1.0.11). package.json keeps upstream's version, so upstream's bumps merge cleanly.

Source code

Every build carries its own source. The interface links to it (the user menu and the sign-in page), and the build writes it next to the app as source.tar.gz: the exact tree the running version was built from.

License and credits

Free software under the GNU Affero General Public License, version 3.

INBUXA Admin is forked from the upstream AGPL-3.0 web administration codebase originally developed by Stalwart Labs. Their copyright notices are kept on every file inherited from it, and INBUXA's own notice is added to the files it changes. Those files are offered upstream under the AGPL-3.0-only or a proprietary license. INBUXA uses them under the AGPL-3.0 only. INBUXA isn't affiliated with or endorsed by Stalwart Labs.

S
Description
Imported from github.com during the 2026-09-20 standup (local dir: inbuxa-admin)
Readme
1.7 MiB
2026-09-21 23:35:59 +00:00
Languages
TypeScript 97.5%
CSS 2%
Shell 0.2%
Dockerfile 0.2%