Backend: Fix organization API endpoints and RBAC

- Fix member list API response format to match frontend expectations
- Fix join requests API response format
- Add proper JSON tags to Invitation struct
- Grant OrgManage permission to admin role for proper RBAC

These changes ensure frontend-backend API contracts are aligned and admins can manage organizations.
This commit is contained in:
Leon Bösche
2026-01-23 23:48:10 +01:00
parent bfe2d1d521
commit e10e499b6c
4 changed files with 72 additions and 11 deletions

Binary file not shown.

View File

@@ -117,14 +117,14 @@ type Membership struct {
}
type Invitation struct {
ID uuid.UUID
OrgID uuid.UUID
InvitedBy uuid.UUID
Username string
Role string
CreatedAt time.Time
ExpiresAt time.Time
AcceptedAt *time.Time
ID uuid.UUID `json:"id"`
OrgID uuid.UUID `json:"orgId"`
InvitedBy uuid.UUID `json:"invitedBy"`
Username string `json:"username"`
Role string `json:"role"`
CreatedAt time.Time `json:"createdAt"`
ExpiresAt time.Time `json:"expiresAt"`
AcceptedAt *time.Time `json:"acceptedAt"`
}
type JoinRequest struct {

View File

@@ -888,6 +888,21 @@ func activityHandler(w http.ResponseWriter, r *http.Request, db *database.DB) {
json.NewEncoder(w).Encode(activities)
}
type memberResponse struct {
UserID string `json:"userId"`
OrgID string `json:"orgId"`
Role string `json:"role"`
CreatedAt time.Time `json:"createdAt"`
User userInfo `json:"user"`
}
type userInfo struct {
ID string `json:"id"`
Username string `json:"username"`
DisplayName string `json:"displayName"`
Email string `json:"email"`
}
func listMembersHandler(w http.ResponseWriter, r *http.Request, db *database.DB) {
orgID := r.Context().Value(middleware.OrgKey).(uuid.UUID)
@@ -898,8 +913,25 @@ func listMembersHandler(w http.ResponseWriter, r *http.Request, db *database.DB)
return
}
// Convert to proper response format
var response []memberResponse
for _, m := range members {
response = append(response, memberResponse{
UserID: m.Membership.UserID.String(),
OrgID: m.Membership.OrgID.String(),
Role: m.Membership.Role,
CreatedAt: m.Membership.CreatedAt,
User: userInfo{
ID: m.User.ID.String(),
Username: m.User.Username,
DisplayName: m.User.DisplayName,
Email: m.User.Email,
},
})
}
w.Header().Set("Content-Type", "application/json")
json.NewEncoder(w).Encode(members)
json.NewEncoder(w).Encode(response)
}
func updateMemberRoleHandler(w http.ResponseWriter, r *http.Request, db *database.DB, auditLogger *audit.Logger) {
@@ -1126,6 +1158,16 @@ func createJoinRequestHandler(w http.ResponseWriter, r *http.Request, db *databa
json.NewEncoder(w).Encode(joinRequest)
}
type joinRequestResponse struct {
ID string `json:"id"`
OrgID string `json:"orgId"`
UserID string `json:"userId"`
InviteToken *string `json:"inviteToken"`
RequestedAt time.Time `json:"requestedAt"`
Status string `json:"status"`
User userInfo `json:"user"`
}
func listJoinRequestsHandler(w http.ResponseWriter, r *http.Request, db *database.DB) {
orgID := r.Context().Value(middleware.OrgKey).(uuid.UUID)
@@ -1136,8 +1178,27 @@ func listJoinRequestsHandler(w http.ResponseWriter, r *http.Request, db *databas
return
}
// Convert to proper response format
var response []joinRequestResponse
for _, req := range requests {
response = append(response, joinRequestResponse{
ID: req.JoinRequest.ID.String(),
OrgID: req.JoinRequest.OrgID.String(),
UserID: req.JoinRequest.UserID.String(),
InviteToken: req.JoinRequest.InviteToken,
RequestedAt: req.JoinRequest.RequestedAt,
Status: req.JoinRequest.Status,
User: userInfo{
ID: req.User.ID.String(),
Username: req.User.Username,
DisplayName: req.User.DisplayName,
Email: req.User.Email,
},
})
}
w.Header().Set("Content-Type", "application/json")
json.NewEncoder(w).Encode(requests)
json.NewEncoder(w).Encode(response)
}
func acceptJoinRequestHandler(w http.ResponseWriter, r *http.Request, db *database.DB, auditLogger *audit.Logger) {

View File

@@ -22,7 +22,7 @@ const (
var rolePermissions = map[string][]Permission{
"owner": {FileRead, FileWrite, FileDelete, DocumentView, DocumentEdit, OrgManage},
"admin": {FileRead, FileWrite, FileDelete, DocumentView, DocumentEdit},
"admin": {FileRead, FileWrite, FileDelete, DocumentView, DocumentEdit, OrgManage},
"member": {FileRead, DocumentView},
}