Spec: two web front ends, ihasmail and INBUXA Admin (a fork of Stalwart WebUI)
Administration is no longer moving wholesale into ihasmail. INBUXA Admin, a fork of the schema-driven webui (no Enterprise-only code, ordinary fork), covers the whole server, setup and recovery from its own deployment. ihasmail keeps its account and tenant administration. Contract additions: the inbuxa-admin OAuth client, cross-origin access limited to the two front ends (the server currently allows every origin), and relative OAuth endpoints on servers with no public URL.
This commit is contained in:
+76
-38
@@ -7,18 +7,20 @@ remote, and nothing public before the cutover in §7.
|
|||||||
## 1. What this is
|
## 1. What this is
|
||||||
|
|
||||||
An AGPL-3.0-only fork of the Stalwart mail server that ships every feature
|
An AGPL-3.0-only fork of the Stalwart mail server that ships every feature
|
||||||
under the AGPL, with nothing held back for a paid edition. ihasmail is built
|
under the AGPL, with nothing held back for a paid edition. Two web front ends
|
||||||
in as the product's web front end: webmail, account self-service and
|
come with it, both separate from the mail host: ihasmail for webmail, account
|
||||||
administration. Stalwart's own web interface is dropped.
|
self-service and day-to-day account and tenant administration, and INBUXA
|
||||||
|
Admin, a fork of Stalwart's own web interface, for full server administration,
|
||||||
|
setup and recovery.
|
||||||
|
|
||||||
**Goals**
|
**Goals**
|
||||||
|
|
||||||
- Everything Stalwart's Enterprise Edition adds is available to everybody,
|
- Everything Stalwart's Enterprise Edition adds is available to everybody,
|
||||||
under the AGPL, rebuilt clean-room.
|
under the AGPL, rebuilt clean-room.
|
||||||
- One product: server, webmail and administration installed and versioned as
|
- One product: server, webmail and administration installed and versioned
|
||||||
a pair.
|
together.
|
||||||
- No web interface on the mail host. Administration happens over JMAP from
|
- No web interface on the mail host. Both front ends talk to the server over
|
||||||
ihasmail, which can run beside the server or on another machine.
|
JMAP and OAuth, and can run beside it or on another machine.
|
||||||
- Stay close enough to upstream that its releases can be taken quickly.
|
- Stay close enough to upstream that its releases can be taken quickly.
|
||||||
|
|
||||||
**Non-goals**
|
**Non-goals**
|
||||||
@@ -249,10 +251,36 @@ is written.
|
|||||||
| 8 | Scale-out storage | SQL read replicas; sharded blob and in-memory stores | For large installs only. |
|
| 8 | Scale-out storage | SQL read replicas; sharded blob and in-memory stores | For large installs only. |
|
||||||
| — | Seat limits, license keys | Nothing: there's no license | Removed, not rebuilt. |
|
| — | Seat limits, license keys | Nothing: there's no license | Removed, not rebuilt. |
|
||||||
|
|
||||||
## 5. ihasmail as the product's web front end
|
## 5. The web front ends
|
||||||
|
|
||||||
|
Decided 2026-09-18: two front ends, each with its own job.
|
||||||
|
|
||||||
|
- **ihasmail**: webmail, account self-service, and the day-to-day account and
|
||||||
|
tenant work done from inside the mail app by helpdesk staff and tenant
|
||||||
|
administrators. Its Administration stays as it is (accounts, domains, groups,
|
||||||
|
lists, roles, tenants, the dashboard), not grown to cover the whole server.
|
||||||
|
- **INBUXA Admin** (repository `inbuxa-admin`): full server administration,
|
||||||
|
first-boot setup and recovery-mode repair. It's a fork of Stalwart's own
|
||||||
|
web interface, `stalwartlabs/webui`, taken at `v1.0.11`.
|
||||||
|
|
||||||
|
Why fork `webui` rather than grow ihasmail: `webui` is entirely schema-driven,
|
||||||
|
building every form, list and menu from the schema the server serves, so it
|
||||||
|
already covers all ~125 setting types where ihasmail covers 18. It's the same
|
||||||
|
stack as ihasmail (React, Radix). And it contains no Enterprise-only code: all
|
||||||
|
111 files are dual-licensed AGPL, with no Enterprise-only files or snippets
|
||||||
|
anywhere in its 28-commit history. So it's an ordinary git fork with upstream's
|
||||||
|
history, needs no stripping and has no clean-room concerns. Its Enterprise
|
||||||
|
gating was client-side (hide or disable items when the server reports
|
||||||
|
`oss`/`community`), and the fork removes it at the one place the edition is
|
||||||
|
stored.
|
||||||
|
|
||||||
### 5.1 Shape
|
### 5.1 Shape
|
||||||
|
|
||||||
|
Both front ends run as their own containers, never installed onto the mail
|
||||||
|
server. INBUXA Admin is a static build. Its server address is set at build
|
||||||
|
time (`VITE_API_BASE_URL`) or deploy time (`<meta name="api-base-url">`), so
|
||||||
|
the same build can point at any server.
|
||||||
|
|
||||||
ihasmail stays a separate process: its Node server and its web app, run as a
|
ihasmail stays a separate process: its Node server and its web app, run as a
|
||||||
container. It can run:
|
container. It can run:
|
||||||
|
|
||||||
@@ -286,46 +314,55 @@ Versioned, and advertised in the JMAP session so either side can check it.
|
|||||||
- **Admin lane.** Administrative JMAP calls can be limited to ihasmail's
|
- **Admin lane.** Administrative JMAP calls can be limited to ihasmail's
|
||||||
address or network, so an admin credential is useless from anywhere else.
|
address or network, so an admin credential is useless from anywhere else.
|
||||||
- **Push.** Unchanged: JMAP push with VAPID, as ihasmail uses today.
|
- **Push.** Unchanged: JMAP push with VAPID, as ihasmail uses today.
|
||||||
|
- **INBUXA Admin's client.** INBUXA Admin signs in by OAuth (authorization
|
||||||
|
code with PKCE) as upstream's `webui` does, as client `stalwart-webui` for
|
||||||
|
now. The fork registers a first-party `inbuxa-admin` client with the
|
||||||
|
admin's own redirect URIs, and the admin switches to it (its
|
||||||
|
`<meta name="oauth-client-id">`).
|
||||||
|
- **Cross-origin access.** Verified 2026-09-18 against a separate
|
||||||
|
inbuxa-server: the whole admin flow works from another origin (sign-in, code
|
||||||
|
for the admin's redirect URI, token exchange, preflights, JMAP session,
|
||||||
|
`/api/schema`, admin calls). But the server answers
|
||||||
|
`Access-Control-Allow-Origin: *` on all of it. The fork restricts that to the
|
||||||
|
configured INBUXA Admin and ihasmail origins, since an admin API shouldn't be
|
||||||
|
callable from any web page.
|
||||||
|
- **A server without a public URL** returns relative OAuth endpoints (`/login`,
|
||||||
|
`/auth/token`) and an empty issuer. INBUXA Admin now resolves them against
|
||||||
|
the server's address. The installer sets the public URL (`INBUXA_PUBLIC_URL`)
|
||||||
|
so the server returns absolute ones.
|
||||||
|
|
||||||
### 5.3 Stalwart's web interface is removed
|
### 5.3 No web interface on the mail host
|
||||||
|
|
||||||
Upstream installs its web interface at first boot, serving `/admin` and
|
Upstream installs its web interface at first boot, serving `/admin` and
|
||||||
`/account`, by inserting a default web application that downloads a release
|
`/account` from the mail server itself, by inserting a default web application
|
||||||
of `stalwartlabs/webui`. The fork:
|
that downloads a release of `stalwartlabs/webui` from GitHub. The fork:
|
||||||
|
|
||||||
- inserts no default web application, and never fetches `webui`;
|
- inserts no default web application, and never fetches anything at boot;
|
||||||
- keeps the generic web-application mechanism for operators who want it,
|
- keeps the generic web-application mechanism for operators who want it,
|
||||||
documented as unsupported;
|
documented as unsupported.
|
||||||
- therefore carries no part of `webui`, which has its own Enterprise-only
|
|
||||||
parts.
|
|
||||||
|
|
||||||
What the web interface did moves to ihasmail:
|
Where each of the web interface's jobs goes:
|
||||||
|
|
||||||
| Was | Becomes |
|
| Was | Becomes |
|
||||||
|---|---|
|
|---|---|
|
||||||
| `/account`: password, app passwords, two-factor | ihasmail Settings: password and app passwords today; its two-factor work is written but backlogged |
|
| `/account`: password, app passwords, two-factor | ihasmail Settings: password and app passwords today; its two-factor work is written but backlogged |
|
||||||
| `/admin`: server administration | ihasmail Administration (§5.4) |
|
| `/admin`: server administration | INBUXA Admin, deployed separately (§5.4) |
|
||||||
| First-boot setup | the installer and a setup screen in ihasmail (§6) |
|
| First-boot setup | the installer, or INBUXA Admin's setup wizard against a server in bootstrap mode (§6) |
|
||||||
| Fixing a server the web front end can't reach | the host-side CLI (§6.3) |
|
| Fixing a server the web front end can't reach | INBUXA Admin in recovery mode, or the host-side CLI (§6.3) |
|
||||||
|
|
||||||
### 5.4 Administration at full coverage
|
### 5.4 Administration: who does what
|
||||||
|
|
||||||
The server's registry has about 125 object types. ihasmail Administration
|
- **INBUXA Admin** covers the whole server, every object type, generated from
|
||||||
uses 18 today: accounts, domains, groups, mailing lists, roles, tenants, the
|
the schema the server serves at `/api/schema`. New types upstream adds
|
||||||
dashboard, credentials and a few supporting types.
|
appear with no admin release. Hand-built screens stay where upstream has
|
||||||
|
them: dashboards, live tracing, the delivery tester, the Sieve editor.
|
||||||
- **Hand-built screens** for what operators change often: domains and DNS,
|
- **ihasmail Administration** keeps its scope: accounts, domains, groups,
|
||||||
DKIM, certificates and ACME, spam settings, the queue, tenants and quotas,
|
lists, roles, tenants and the dashboard, for people who work from the mail
|
||||||
reports.
|
app. Where an ihasmail screen stops short, it links to the matching INBUXA
|
||||||
- **Schema-generated forms** for the rest. Upstream already publishes a
|
Admin page instead of growing to match it.
|
||||||
complete UI schema, `resources/schema/schema.json.gz`, with objects, fields
|
- **Overlap is fine** where both need it (accounts and domains appear in
|
||||||
(with descriptions), forms, lists, enums, dashboards and layouts. It's what
|
both). Both are permission-gated by the server, so they can't disagree about
|
||||||
Stalwart's own web interface draws from, and it ships under the repository's
|
what anyone is allowed to do.
|
||||||
dual license, so the fork has it under the AGPL. The fork serves it over
|
|
||||||
JMAP, and ihasmail renders a correct, if plain, editor for any object type
|
|
||||||
from it. New types upstream
|
|
||||||
adds then appear without an ihasmail release.
|
|
||||||
- Everything stays permission-gated, as Administration is today.
|
|
||||||
|
|
||||||
## 6. First boot, setup and recovery
|
## 6. First boot, setup and recovery
|
||||||
|
|
||||||
@@ -393,8 +430,9 @@ Additions for the fork:
|
|||||||
that fails isn't retried on restart, some network settings need a restart,
|
that fails isn't retried on restart, some network settings need a restart,
|
||||||
and the default log path doesn't exist in the image. Each is a candidate for
|
and the default log path doesn't exist in the image. Each is a candidate for
|
||||||
fixing in the fork, and oneshot's workaround drops out once it is.
|
fixing in the fork, and oneshot's workaround drops out once it is.
|
||||||
- A setup screen in ihasmail for operators who install without the
|
- For operators who install without the installer, INBUXA Admin's setup
|
||||||
installer. It performs the same steps against a server in bootstrap mode.
|
wizard (upstream's bootstrap wizard, rebranded) performs the same steps
|
||||||
|
against a server in bootstrap mode.
|
||||||
|
|
||||||
### 6.3 Recovery without a web front end
|
### 6.3 Recovery without a web front end
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user