Skip to content

groupware: merge main, fix JMAP capabilities and upgrade Stalwart to 0.16.27 - #3803

Draft
tammi-23 wants to merge 894 commits into
groupwarefrom
chore/groupware-merge-main-stalwart
Draft

tammi-23 wants to merge 894 commits into
groupwarefrom
chore/groupware-merge-main-stalwart

Conversation

@tammi-23

@tammi-23 tammi-23 commented Oct 24, 2026 •

Copy link
Copy Markdown
Contributor

Description

Review hint: the PR diff contains everything from main. Please review it commit by commit: the conflict resolution of the merge can be shown with git show --remerge-diff 6114cdcbef, the actual changes are in the commits after the merge.

Brings the groupware branch up to date and upgrades Stalwart to the latest release:

  1. Merge main into groupware (groupware was 887 commits behind main). A merge instead of a rebase, so groupware doesn't need a force push.
    • Conflicts in opencloud/pkg/command/services.go, opencloud/pkg/init/structs.go, pkg/config/config.go and pkg/config/defaultconfig.go: both sides registered a new service at the same place (groupware/auth-api here, auth-guest on main), all are kept.
    • services/proxy/pkg/config/defaults/defaultconfig.go: the collaboration routes from main are kept (main restricted them in the meantime), the /groupware and /auth routes are added.
    • go.mod, go.sum, vendor: main plus the 13 modules the groupware branch requires, pinned to exactly the versions used on groupware (e.g. go-imap stays at v2.0.0-beta.5, gofakeit at v7.7.3), then go mod tidy and go mod vendor.
  2. Fix missing JMAP capabilities. Stalwart rejects these calls with unknownMethod, which breaks the account bootstrap (GET /groupware/accounts) and everything that uses address books:
    • Identity/* and EmailSubmission/* were sent without urn:ietf:params:jmap:submission (RFC 8621).
    • all AddressBook/* calls used MailboxType, so they were sent with the mail instead of the contacts capability.
    • creating, updating and deleting calendars used CalendarEventType (same capability, no change in behaviour, only for consistency).
    • New unit test TestObjectTypeNamespaces (fails without the fix).
  3. Upgrade Stalwart 0.16.12 → 0.16.27 and stalwart-cli 1.0.8 → 1.0.13 (jmaptest and opencloud_full):
    • Since 0.16.20 Stalwart only accepts BCP 47 locales: "en_US" → "en-US" in the configuration snapshots (idmldap.json, jmap_stalwart.go, DEVELOPER.md). With the old value the account import fails (Invalid value Str("en_US") for enum type EnUS).
    • TestGroupwareVacation: Stalwart 0.16.27 keeps isEnabled when other vacation properties change, the test asserted the old (buggy) behaviour.
    • TestWs: Stalwart may return a different but equivalent newState when nothing changed (e.g. sae for n, both lead to the same changes and the same next state), and announces new mail with EmailDelivery (since 0.16.16).
  4. TestPhone (pkg/jscontact): expect the RFC 9553 phone feature mobile instead of the vCard type cell (was failing on groupware before).
  5. Build on 32-bit platforms (was failing on groupware before, the release pipeline also builds linux/386): relatedEmailsFilter compared a uint with math.MaxInt64, and the Stalwart test users had a 20 GB quota as int. The days are now also capped so that the time.Duration can't overflow.
  6. Skip the groupware integration tests without Docker (TestGroupwareIndex, TestGroupwareVacation), using the same jmaptest.Skip conditions as the JMAP integration tests. In the CI they failed with rootless Docker not found and a nil pointer panic in the cleanup.
  7. Stable header order in the HTTP dumps (pkg/http): the headers were written in map iteration order, so TestDumpHttpResponse/TestDumpHttpRequest failed randomly (failed in the CI once). They are written sorted by name now (go test ./pkg/http/ -count=50 passes).

Related Issue

Motivation and Context

groupware was based on main from July and pinned to Stalwart 0.16.12. Newer Stalwart releases contain fixes the groupware apps need (sharing, vacation, Identity/get, address books), but they reject requests without the required capabilities and the old locale format, so upgrading needs the fixes above.

How Has This Been Tested?

  • test environment: macOS, Go 1.26.4, Docker Desktop
  • test case 1: go build ./...
  • test case 2: full unit test suite USE_TESTCONTAINERS=false go test ./..., compared with main: no new failures. Failing on both: pkg/log (TestDeprecation) and services/search/pkg/opensearch (needs OpenSearch).
  • test case 3: Stalwart integration tests against 0.16.27 (go test -p 1 ./pkg/jmaptest/... ./services/groupware/...): all pass (TestAddressBooks, TestCalendars, TestContacts, TestEmails, TestEvents, TestSendingEmails, TestWs, TestGroupwareIndex, TestGroupwareVacation), TestWs 3 out of 3 runs. Note: the integration test packages have to run with -p 1, otherwise both start a container named stalwart at the same time.
  • test case 4: opencloud_full snapshot (idmldap.json) applied with stalwart-cli 1.0.13 to a fresh Stalwart 0.16.27: 17 created, 0 failed (the unchanged snapshot fails on the account locale).
  • test case 5: end-to-end with an OpenCloud image built from this branch, Stalwart 0.16.27 and the built-in IDM LDAP (isolated Docker Compose stack, basic auth with the demo users), using the same requests as the web apps:
    • GET /groupware/ and GET /groupware/accounts (identities, including the shared programmers@example.org group account) for alan and mary
    • mailboxes, identities, creating a draft, sending it with identity, move-from and move-to, mary receives it, markAsSeen, keywords
    • address books: list, create; contacts: create, get, list in the address book
    • calendars: list, create, update, delete
    • vacation response: enabling it, then changing the dates keeps it enabled
  • test case 6: GOOS=linux GOARCH=386|arm|amd64|arm64 go build ./...
  • test case 7: CI=woodpecker go test ./services/groupware/... skips the integration tests, with Docker they pass
  • test case 8: golangci-lint 2.13.2 with --new-from-rev=origin/groupware on pkg/jmap, pkg/jmaptest and services/groupware: only the existing missing doc comment hints (revive) on the changed NS_*/StalwartVersion lines, like all other NS_* variables.

Not part of this PR / known: updating and deleting address books and contacts still fails with no supplier supports that id, because the JMAP suppliers (JmapAddressBookSupplier, JmapContactCardSupplier) don't implement update and delete yet. This was the same before this PR and is listed in the backend dependencies of opencloud-eu/web#3844.

Screenshots (if appropriate):

n/a

Types of changes

  • Bug fix (non-breaking change which fixes an issue)
  • New feature (non-breaking change which adds functionality)
  • Breaking change (fix or feature that would cause existing functionality to change)
  • Technical debt
  • Tests only (no source changes)

Checklist:

  • Code changes
  • Unit tests added
  • Acceptance tests added
  • Documentation added

maki5 and others added 30 commits October 6, 2026 08:07
…pired and shareRemoved events, common config loading fix
feat(guestlinks)!: auth-guest service
This starts the guestlinks authprovider as part of the auth-guest
service and wires it into the authregistry.
Replace the boolean authenticator result with a typed AuthenticationResult
containing AuthenticationState (NotApplicable, Failed, Succeeded, Error)
to distinguish between non-applicability, rejected credentials, and
dependency failures.

All existing authentication behavior remains observably unchanged.
guestlinks: implement auth-middleware for Guestlink cookies
Bumps [github.com/open-policy-agent/opa](https://github.com/open-policy-agent/opa) from 1.19.1 to 1.21.1.
- [Release notes](https://github.com/open-policy-agent/opa/releases)
- [Changelog](https://github.com/open-policy-agent/opa/blob/main/CHANGELOG.md)
- [Commits](open-policy-agent/opa@v1.19.1...v1.21.1)

---
updated-dependencies:
- dependency-name: github.com/open-policy-agent/opa
  dependency-version: 1.20.2
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Replace AUTH_GUEST_SESSION_JWT_SECRET with a key derived via
HMAC-SHA256 from the reva JWT secret. Guest session tokens and reva
access tokens remain unforgeable across each other without a second
secret to configure.
…ub.com/open-policy-agent/opa-1.20.2

build(deps): bump github.com/open-policy-agent/opa from 1.19.1 to 1.21.1
Bumps [github.com/onsi/ginkgo/v2](https://github.com/onsi/ginkgo) from 2.32.1 to 2.33.0.
- [Release notes](https://github.com/onsi/ginkgo/releases)
- [Changelog](https://github.com/onsi/ginkgo/blob/master/CHANGELOG.md)
- [Commits](onsi/ginkgo@v2.32.1...v2.33.0)

---
updated-dependencies:
- dependency-name: github.com/onsi/ginkgo/v2
  dependency-version: 2.33.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
…ub.com/onsi/ginkgo/v2-2.33.0

build(deps): bump github.com/onsi/ginkgo/v2 from 2.32.1 to 2.33.0
* api-test: extend search tests

* adjust tets
dschmidt and others added 21 commits October 21, 2026 14:54
They are merged onto the built-in defaults, the way the proxy's additional_policies and OC_ADD_RUN_SERVICES are, so the name says it: env variable, yaml key and field all carry the prefix. The two that take key:value entries are named in the plural like the other map-shaped settings in this repo, and the README says which of the three takes bare mime types.
Push based thumbnailer architecture
…p_events

Feat/guestlinks spaceshare cleanup events
* tests: add acceptance tests for renewing guest links

Cover renewing a guest link with and without a session, the PIN, rate limiting and the expiry of the session and the PIN.

* tests: replay used PIN with its nonce in PIN-once scenario
feat(search): configurable query filter, leaves the personal space root and .space out by default
Conflicts:
- opencloud/pkg/command/services.go, opencloud/pkg/init/structs.go,
  pkg/config/config.go, pkg/config/defaultconfig.go: keep the groupware
  and auth-api services next to auth-guest from main
- services/proxy/pkg/config/defaults/defaultconfig.go: keep the
  collaboration routes from main and add the groupware and auth routes
- go.mod, go.sum, vendor: use main and keep the module versions the
  groupware branch requires, then go mod tidy and go mod vendor
…ubmission and address book calls

Identity/get and EmailSubmission were sent without
urn:ietf:params:jmap:submission, and all address book calls were sent with
the mail instead of the contacts capability. Stalwart rejects such calls
with unknownMethod since 0.16.x, which breaks the account bootstrap
(GET /groupware/accounts) and the address books.

Also use the calendar type for creating, updating and deleting calendars
(same capability, no change in behaviour).
…to 1.0.13

- jmaptest and opencloud_full: use Stalwart 0.16.27 and stalwart-cli 1.0.13
- use the BCP 47 locale "en-US" in the Stalwart configuration snapshots,
  Stalwart rejects "en_US" since 0.16.20
- TestGroupwareVacation: Stalwart 0.16.27 keeps isEnabled when other
  vacation properties change, expect true now
- TestWs: Stalwart may return a different but equivalent newState when
  nothing changed, and announces new mail with EmailDelivery (since 0.16.16)
@codacy-production

Copy link
Copy Markdown

Up to standards ✅

🟢 Issues 0 issues

Results:
0 new issues

View in Codacy

NEW Get contextual insights on your PRs based on Codacy's metrics, along with PR and Jira context, without leaving GitHub. Enable AI reviewer
TIP This summary will be updated as you push new changes.

The release pipeline also builds linux/386, where uint and int are 32 bits
wide: comparing the days of the related emails filter with math.MaxInt64
and the 20 GB disk quota of the Stalwart test users didn't compile there.

Also cap the days so that the time.Duration can't overflow.
The headers were written in map iteration order, which made the HTTP dump
tests flaky and the trace logs harder to compare.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Status:In-Progress Type:Bug Type:Maintenance E.g. technical debt, packaging, etc.

Projects

None yet

Development

Successfully merging this pull request may close these issues.