feat(sharing): remove code redeem, unify Teilen button and team/user sharing across lists and notes
MindSift CI & Docker Release / Build, Test in Container & Push (push) Successful in 58s

This commit is contained in:
sandrodach committed 2026-10-25 13:51:42 +01:00
1 parent 20c50aa8d6
commit 7c47f245e2
6 files changed
+440 -226

No files matched your search

+59 -2
View File
@@ -921,18 +921,46 @@ func (s *Server) handleCreateDocShare(w http.ResponseWriter, r *http.Request) {
var req struct {
UserID string `json:"userId"`
Email string `json:"email"`
TeamID string `json:"teamId"`
Permission string `json:"permission"` // read | write
}
if err := json.NewDecoder(r.Body).Decode(&req); err != nil {
writeError(w, http.StatusBadRequest, "Ungültiges JSON")
return
}
if req.TeamID != "" {
members, err := s.store.GetTeamMembers(req.TeamID)
if err != nil {
writeError(w, http.StatusBadRequest, "Team nicht gefunden")
return
}
var lastShare *domain.DocShare
for _, tm := range members {
if tm.UserID == userID {
continue
}
share, err := s.store.CreateDocShare(userID, docID, tm.UserID, req.Permission)
if err == nil && share != nil {
lastShare = share
s.wsHub.BroadcastToUser(share.UserID, "DOC_SHARED", share)
s.wsHub.BroadcastDocEvent(docID, "DOC_SHARED", share)
}
}
if lastShare != nil {
writeJSON(w, http.StatusCreated, lastShare)
} else {
writeJSON(w, http.StatusOK, map[string]bool{"success": true})
}
return
}
target := req.UserID
if target == "" {
target = req.Email
}
if target == "" {
writeError(w, http.StatusBadRequest, "Benutzer-ID oder E-Mail erforderlich")
writeError(w, http.StatusBadRequest, "Benutzer-ID, E-Mail oder Team erforderlich")
return
}
@@ -1089,18 +1117,47 @@ func (s *Server) handleAddSpaceMember(w http.ResponseWriter, r *http.Request) {
var req struct {
UserID string `json:"userId"`
Email string `json:"email"`
TeamID string `json:"teamId"`
Role string `json:"role"`
}
if err := json.NewDecoder(r.Body).Decode(&req); err != nil {
writeError(w, http.StatusBadRequest, "Ungültiges JSON")
return
}
if req.Role != "owner" && req.Role != "editor" && req.Role != "viewer" {
req.Role = "editor"
}
if req.TeamID != "" {
members, err := s.store.GetTeamMembers(req.TeamID)
if err != nil {
writeError(w, http.StatusBadRequest, "Team nicht gefunden")
return
}
var lastMember *domain.SpaceMember
for _, tm := range members {
member, err := s.store.AddSpaceMember(currentUserID, spaceID, tm.UserID, req.Role)
if err == nil && member != nil {
lastMember = member
s.wsHub.BroadcastToUser(member.UserID, "SPACE_JOINED", map[string]interface{}{"spaceId": spaceID})
s.wsHub.Broadcast(spaceID, "", "MEMBER_ADDED", member)
}
}
if lastMember != nil {
writeJSON(w, http.StatusCreated, lastMember)
} else {
writeJSON(w, http.StatusOK, map[string]bool{"success": true})
}
return
}
target := req.UserID
if target == "" {
target = req.Email
}
if target == "" {
writeError(w, http.StatusBadRequest, "Benutzer-ID, Benutzername oder E-Mail erforderlich")
writeError(w, http.StatusBadRequest, "Benutzer-ID, Benutzername, E-Mail oder Team erforderlich")
return
}
+38
View File
@@ -618,6 +618,44 @@ func TestSpaceMembersDirectInvitationAPI(t *testing.T) {
if rec.Code != http.StatusOK {
t.Fatalf("expected 200 OK for remove member, got %d: %s", rec.Code, rec.Body.String())
}
// 5. Test adding a team to a space
team, err := store.CreateTeam("", "WG Team", "Haushalt")
if err != nil {
t.Fatalf("failed to create team: %v", err)
}
_ = store.AddTeamMember(team.ID, normalUser.ID, "member")
addTeamBody := []byte(`{"teamId":"` + team.ID + `","role":"editor"}`)
req = httptest.NewRequest(http.MethodPost, "/api/v1/spaces/"+createdSpace.ID+"/members", bytes.NewReader(addTeamBody))
req.Header.Set("Authorization", "Bearer "+adminToken)
req.Header.Set("Content-Type", "application/json")
rec = httptest.NewRecorder()
router.ServeHTTP(rec, req)
if rec.Code != http.StatusCreated && rec.Code != http.StatusOK {
t.Fatalf("expected 201 or 200 for add space team, got %d: %s", rec.Code, rec.Body.String())
}
// User should see the space again because their team was added
req = httptest.NewRequest(http.MethodGet, "/api/v1/spaces", nil)
req.Header.Set("Authorization", "Bearer "+userToken)
rec = httptest.NewRecorder()
router.ServeHTTP(rec, req)
if rec.Code != http.StatusOK {
t.Fatalf("expected 200 OK for user spaces after team add, got %d", rec.Code)
}
userSpaces = nil
_ = json.Unmarshal(rec.Body.Bytes(), &userSpaces)
found = false
for _, s := range userSpaces {
if s.ID == createdSpace.ID {
found = true
break
}
}
if !found {
t.Fatalf("expected space %s to be visible to user via team, got %+v", createdSpace.ID, userSpaces)
}
}
func TestWorkspaceTagsAPI(t *testing.T) {