From 3fa95beb1fefdb8b2aabd1f9c3da4ef3eeb0bc51 Mon Sep 17 00:00:00 2001
From: Pascal Bleser
Date: Fri, 31 Oct 2025 17:32:19 +0100
Subject: [PATCH] groupware: return identities with accounts in the /accounts
endpoint
---
.../pkg/groupware/groupware_api_account.go | 35 +++++++++++++++++++
.../pkg/groupware/groupware_route.go | 2 +-
2 files changed, 36 insertions(+), 1 deletion(-)
diff --git a/services/groupware/pkg/groupware/groupware_api_account.go b/services/groupware/pkg/groupware/groupware_api_account.go
index 0448e89ce..d8f467498 100644
--- a/services/groupware/pkg/groupware/groupware_api_account.go
+++ b/services/groupware/pkg/groupware/groupware_api_account.go
@@ -6,6 +6,7 @@ import (
"strings"
"github.com/opencloud-eu/opencloud/pkg/jmap"
+ "github.com/opencloud-eu/opencloud/pkg/structs"
)
// When the request succeeds.
@@ -69,11 +70,45 @@ func (g *Groupware) GetAccounts(w http.ResponseWriter, r *http.Request) {
})
}
+func (g *Groupware) GetAccountsWithTheirIdentities(w http.ResponseWriter, r *http.Request) {
+ g.respond(w, r, func(req Request) Response {
+ uniqueAccountIds := structs.Uniq(structs.Keys(req.session.Accounts))
+ resp, sessionState, state, lang, err := g.jmap.GetIdentitiesForAllAccounts(uniqueAccountIds, req.session, req.ctx, req.logger, req.language())
+ if err != nil {
+ return req.errorResponseFromJmap(err)
+ }
+ list := make([]AccountWithIdAndIdentities, len(req.session.Accounts))
+ i := 0
+ for accountId, account := range req.session.Accounts {
+ identities, ok := resp.Identities[accountId]
+ if !ok {
+ identities = []jmap.Identity{}
+ }
+ slices.SortFunc(identities, func(a, b jmap.Identity) int { return strings.Compare(a.Id, b.Id) })
+ list[i] = AccountWithIdAndIdentities{
+ AccountId: accountId,
+ Account: account,
+ Identities: identities,
+ }
+ i++
+ }
+ // sort on accountId to have a stable order that remains the same with every query
+ slices.SortFunc(list, func(a, b AccountWithIdAndIdentities) int { return strings.Compare(a.AccountId, b.AccountId) })
+ return etagResponse(list, sessionState, state, lang)
+ })
+}
+
type AccountWithId struct {
AccountId string `json:"accountId,omitempty"`
jmap.Account
}
+type AccountWithIdAndIdentities struct {
+ AccountId string `json:"accountId,omitempty"`
+ jmap.Account
+ Identities []jmap.Identity `json:"identities,omitempty"`
+}
+
type AccountBootstrapResponse struct {
// The API version.
Version string `json:"version"`
diff --git a/services/groupware/pkg/groupware/groupware_route.go b/services/groupware/pkg/groupware/groupware_route.go
index c26db2b42..ffe49a63a 100644
--- a/services/groupware/pkg/groupware/groupware_route.go
+++ b/services/groupware/pkg/groupware/groupware_route.go
@@ -65,7 +65,7 @@ const (
func (g *Groupware) Route(r chi.Router) {
r.Get("/", g.Index)
r.Route("/accounts", func(r chi.Router) {
- r.Get("/", g.GetAccounts)
+ r.Get("/", g.GetAccountsWithTheirIdentities)
r.Route("/all", func(r chi.Router) {
r.Get("/", g.GetAccounts)
r.Route("/mailboxes", func(r chi.Router) {