Commit Graph
38 Commits
Author SHA1 Message Date
kevinveenbirkenbach b1161f507a Merge remote-tracking branch 'origin/main' into review/dmarc-rua-1125 2026-10-29 08:14:29 +01:00
kevinveenbirkenbachandClaude Opus 5.5 a59275dd99 fix(web-app-stalwart): make the OAuth consent step optional in the native login spec
The image bump 9ed531a77e (#1254) put Stalwart v1.0.1 on main. v1.0.1
shows the password form right after the username, without the "Allow"
consent step that v1.0.0 asked for. test-login-native.js waited for that
button unconditionally, so "administrator: stalwart recovery admin
native login and logout" timed out after 60 s in every attempt
(locator.waitFor on getByRole('button', { name: /^allow$/i })).

The spec now waits for either the Allow button or the password field and
clicks Allow only when it is shown; the same check runs before the
dashboard assertion after sign-in. Both waits still fail when neither
element appears.

The change is identical to the one on feature/updater-lockdown-probe,
so the two lines do not conflict when they meet.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-29 08:10:28 +01:00
kevinveenbirkenbachandClaude Opus 5.5 191afe48b2 fix(mail): harden the DMARC rua checks after review
The Mailu assert accepted any non-empty forward on the rua user, so a
forward to a user without a mailbox let the deploy publish an rua address
whose alias delivers nowhere. A forward now satisfies the assert only when
its target carries a mailbox account.

production_facts.py let a later duplicate tag overwrite an earlier one, so
a record with two rua tags passed although receivers discard it (DKIM
tag-list rules, adopted by RFC 7489). dmarc_tags now raises on a duplicate
tag and check_dmarc reports the record as invalid. The rua comparison also
took the raw URI text, so a percent-encoded address or one followed by
mailto header fields never matched; the address is now cut at '?' and
percent-decoded after the size suffix is removed (RFC 6068).

Refs #1125

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-29 01:17:51 +01:00
kevinveenbirkenbachandClaude Opus 5.5 c4d0283300 feat(mail): publish a DMARC aggregate report address (rua)
Both mail providers published "v=DMARC1; p=reject; ruf=...; adkim=s;
aspf=s" without a rua tag, so the domain owner received no aggregate
reports and could not see who sends in the domain's name or whether
legitimate mail fails alignment.

services.<entity>.dmarc.rua_user in web-app-stalwart and web-app-mailu
now names the users-catalogue key whose mailbox receives the aggregate
reports. It is set to administrator, the one user every deployment
provisions with a mailbox (user-administrator), and an inventory may
name another key. The address is built as <username>@<mail domain>,
which is the exact account or alias the provider creates, so the record
never points at an address the server does not serve. An assert in the
DNS task fails the deploy before any record is written when the user
carries no mailbox account (Stalwart), or neither a mailbox account nor
a forward alias (Mailu), so reports cannot bounce. Mailu's DMARC_RUA
env, which only feeds the record its admin UI suggests, now carries the
same local part instead of the unprovisioned "admin".

production_facts.py takes a required --dmarc-rua. check_dmarc parses
the record's tags and fails unless rua names that mailbox (size
suffixes and several URIs are accepted). The policy check now reads the
p tag instead of matching the substring "p=", which "sp=" also matched.

Closes #1125

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-28 20:56:40 +01:00
kevinveenbirkenbachandClaude Opus 5.5 4d9c3c1cfc refactor(web-app-stalwart): group the store SQL files and use the vars SPOT constant
- test_prefix_grouped_files: files/sql/store_database.sql and
  store_layout.sql become files/sql/store/database.sql and layout.sql.
- test_file_spot: test_store_guard.py builds the vars path with
  ROLE_FILE_VARS_MAIN instead of a hard-coded "vars" / "main.yml" chain.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-28 03:46:55 +01:00
kevinveenbirkenbachandClaude Opus 5.5 47060a72d3 fix(web-app-stalwart): register the WebUI OAuth client and harden the 0.16 store guard
Follow-up to the v1.0.0 port, closing holes a review and a local run found:

- WebUI sign-in: WebUI v2 sends an http:// client-metadata-document id
  on the onion origin, which Stalwart v1.0.0 rejects (unknown http ids
  get no CIMD fallback, trusted hosts require TLS). The recovery admin
  under SSO hit the same wall with the bare id 'stalwart-webui'. Register
  a public first-party x:OAuthClient 'stalwart-webui' with the WebUI's
  callback and login URIs on the served origin, and always inject it as
  the Application's oauthClientId. Native sign-in now shows Stalwart's
  consent step; test-login-native.js clicks it and also runs under SSO.
- Store guard: the previous guard only checked a running 0.16 server; a
  local run showed v1 writing into a 0.16 store whose server was stopped.
  The guard now reads the store whenever one exists (shared: pg_database,
  dedicated: volume) and fails on the 0.16 bigint layout. A host marker
  written at the end of a successful v1 deploy lets restores and
  redeploys with a stopped dedicated database pass; without the marker,
  a stopped dedicated database fails with an explicit message instead of
  a masked psql error. Queries retry while the database recovers.
- README: WebUI sign-in, guard semantics, restore and redeploy.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-27 17:45:31 +01:00
kevinveenbirkenbachandClaude Opus 5.5 c75648ccdd fix(web-app-stalwart): port the role to server v1.0.0 and guard 0.16 stores
Stalwart v1.0.0 rejects unknown JMAP properties ("Invalid property" ->
notCreated/notUpdated), validates OIDC tokens more strictly and refuses to
open a data store from before 1.0. Port the role and protect existing
installs:

- Milter: hostname/timeoutConnect/timeoutCommand/timeoutData become
  host/connectTimeout/commandTimeout/dataTimeout; the existing milter is
  looked up by host.
- Onion relay route: address becomes host.
- OIDC directory: requireAudience is gone. Set skipAudienceValidation and
  unscopedTokens=interoperable on create and update, so Keycloak tokens
  (no Stalwart audience, no mail scope) keep working for the WebUI and
  Roundcube XOAUTH2.
- WebUI: send oauthClientId only with SSO enabled; without SSO the WebUI
  falls back to its own client metadata document.
- Store guard: before anything changes, a running Stalwart whose table u
  still has the 0.16 bigint layout stops the deploy and points to the
  stalwart-migrate steps, which the README now documents under
  "Upgrading from 0.16".
- Updater: pin the WebUI git_tags source to v2.* to match server 1.x.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-27 13:46:08 +01:00
kevinveenbirkenbachandClaude Opus 5.5 65a884beba test(web-app-stalwart): require the relay denial code in the CLI probe
The unauthenticated half of the relay probe passed on any 5xx answer.
A server that refused the recipient for another reason would have
counted as "relay denied". It now requires 550, the code Stalwart gives
for a denied relay.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-08 19:27:27 +02:00
kevinveenbirkenbachandClaude Opus 5.5 08ef66d8de fix(web-app-stalwart): authenticate bots with an app password under SSO
Under SSO the role tried to let applications relay without SMTP AUTH by
widening the relay rule to the private networks. The rule compared the
peer address to the text of a CIDR, which never matches, so an
application could reach local mailboxes but got "550 5.1.2 Relay not
allowed" for every external recipient. Repairing the comparison would
have opened a relay, because published ports, Tor and the swarm mesh all
hand outside clients an address inside those networks.

Stalwart checks app passwords before it asks the external directory, so
a bot can authenticate while the directory is OIDC. With SSO enabled the
role now creates one app password per bot, acting for that account as
the recovery admin, and stores it in the token store the SMTP password
is already read from. A bot gets a new one when its entry is deleted in
Stalwart or its token is removed.

The relay rule is back to authenticated sessions only. The lookup loses
its SSO relay branch and the role its submission_via_relay flag, so an
SSO deployment submits on 465 with AUTH like every other one.

The role's CLI test now fails when an unauthenticated session is given
an external recipient, or when the bot credential is refused one.

Closes #793

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-08 08:57:22 +02:00
Alejandro Roman 6144c85978 fix(stalwart): fixed secrets 2026-09-30 16:00:58 +04:00
Alejandro Roman 73b2593e47 fix(swarm-stalwart): mapache once and make fixes regarding comments 2026-09-29 18:31:02 +04:00
Alejandro Roman a390fea9e9 fix(swarm-stalwart): fix CI issues, cmments mapache 2026-09-28 18:23:16 +04:00
Alejandro Roman 570e06af99 fix(swarm-stalwart): mapache persona, playwrichts and issues fixed 2026-09-23 20:40:46 +04:00
Alejandro Roman 4287dee96b fix(swarm-stalwart): fix new issue on CI and allow videos on logic playwright 2026-09-09 22:45:08 +04:00
Alejandro Roman e6596d51f2 fix(stalwart): add the fix PR into main PR 2026-09-09 00:21:58 +04:00
Alejandro Roman ee6c555f88 fix(stalwart): fix mailu issues, add more playwrithg with full cehcks, fix lint issues 2026-09-04 15:45:16 +04:00
Alejandro Roman 1351c7ae96 fix(stalwart): fix mailu issues, add more playwrithg with full cehcks, fix some SPOT 2026-09-04 14:57:08 +04:00
Alejandro Roman f9d3a1345f fix(stalwart): fix TOr and testing properly, local pass 2026-09-04 02:43:39 +04:00
Alejandro Roman e809765e23 fix(stalwart): fix all comments, fix a tor issue fouind and fix all SPOT issues 2026-09-02 15:02:46 +04:00
Alejandro Roman e1bf6d775e feat(UI): fix lint issues 2026-09-01 13:15:33 +04:00
Alejandro Roman accc9e4c7c feat(UI): fix migration, errors happening in local deploy and swarm integraton issues, tor merged and implement stalwart with tor 2026-09-01 12:34:57 +04:00
Alejandro Roman 333079cc2a feat(UI): fix migration, errors happening in local deploy and swarm integraton + merged main 2026-08-30 21:39:52 +04:00
Alejandro Roman 026b28f9a7 fix(swar-stalwart): migration process 2026-08-30 14:43:00 +04:00
Alejandro Roman 3c7c3239be feat(swarm): fix CI and mirations issues 2026-08-21 00:25:38 +04:00
Alejandro Roman a67334dd30 feat(swarm): fix testing 2026-08-19 20:32:43 +04:00
Alejandro Roman ed1f35d6ae feat(swarm): add new test appraoch + fix swarm issues 2026-08-19 20:08:59 +04:00
Alejandro Roman 8a4f4142ff feat(swarm): Fix issues with mailu swarm 2026-08-19 14:32:56 +04:00
Alejandro Roman ac101d2efa Merge kevinveenbirkenbach/feature/swarm-nfs into stalwart integration branch 2026-07-21 10:00:17 +02:00
Alejandro Roman dc7081c917 feat(web-app-stalwart): Mailu→Stalwart data-migration script + standalone stump test 2026-07-18 21:04:27 +02:00
Alejandro Roman ab25684714 adrees all commens and fix CI usses on prev run 2026-07-16 19:19:23 +02:00
Alejandro Roman 889d3a370f fix SPot and issues found 2026-07-16 14:26:11 +02:00
Alejandro Roman 948b5f2f84 fix error in deploy 2026-07-03 06:58:17 +02:00
Alejandro Roman 500e5fef34 fix playwright tests 2026-07-02 23:08:03 +02:00
Alejandro Roman 564c0ab4df fix palywirght issues part 1 2026-07-01 22:33:20 +02:00
Alejandro Roman 9104b34795 add AV, Expose CalDAV/CardDAV/WebDAV and final testing refactoring 2026-07-01 13:04:15 +02:00
Alejandro Roman 233f15f3e0 fix OIDC and add more scenarios to tests 2026-07-01 11:19:49 +02:00
Alejandro Roman 9962429e59 Added playwright testing 2026-06-30 20:37:50 +02:00
Alejandro Roman 2f693f00e6 feat(stalwart):Created the role and the connection like mailu had it 2026-06-30 16:17:48 +02:00