diff --git a/server/im_http.go b/server/im_http.go index 2bd0314..5fc9afc 100644 --- a/server/im_http.go +++ b/server/im_http.go @@ -5456,13 +5456,6 @@ func serveIMGroupInvitations(wrt http.ResponseWriter, req *http.Request, topic s results = append(results, item) continue } - invitationID := "ginv_" + store.Store.GetUidString() - idempotencyKey := strings.TrimSpace(req.Header.Get("Idempotency-Key")) - if idempotencyKey != "" { - idempotencyKey += ":" + uid.UserId() - } else { - idempotencyKey = invitationID - } targetRequiresApproval := settings != nil && settings.JoinApproval if !targetRequiresApproval && store.Profiles != nil { privacy, privacyErr := store.Profiles.GetPrivacy(principal.TenantID, uid) @@ -5480,9 +5473,35 @@ func serveIMGroupInvitations(wrt http.ResponseWriter, req *http.Request, topic s targetRequiresApproval = privacy != nil && privacy.GroupInviteVerification } joinRequestID := "" + invitationID := "" if targetRequiresApproval { + invitationID = "ginv_" + store.Store.GetUidString() joinRequestID = "gjr_" + store.Store.GetUidString() } + if !targetRequiresApproval { + joined, err := store.GroupBusiness.InviteMember(principal.TenantID, topic, principal.Uid, uid, + strings.TrimSpace(body.Message), strings.TrimSpace(req.Header.Get("Idempotency-Key")), + groupMemberPrivate("", false, false, 1, now), now) + if err != nil { + item["status"] = "failed" + item["reason"] = relationErrorReason(err) + results = append(results, item) + continue + } + if joined { + item["status"] = types.GroupInvitationStatusJoined + } else { + item["status"] = "already_member" + } + results = append(results, item) + continue + } + idempotencyKey := strings.TrimSpace(req.Header.Get("Idempotency-Key")) + if idempotencyKey != "" { + idempotencyKey += ":" + uid.UserId() + } else { + idempotencyKey = invitationID + } inv, err := store.GroupBusiness.CreateInvitation(principal.TenantID, &types.GroupInvitation{ InvitationID: invitationID, Topic: topic, diff --git a/server/im_http_test.go b/server/im_http_test.go index 1719290..b91fea5 100644 --- a/server/im_http_test.go +++ b/server/im_http_test.go @@ -4900,8 +4900,7 @@ func TestServeIMGroupLeave(t *testing.T) { func TestServeIMGroupInvitationAddsNonMember(t *testing.T) { ctrl := gomock.NewController(t) defer ctrl.Finish() - mockStore := expectIMBearer(t, ctrl, "token-1", 7, 42) - mockStore.EXPECT().GetUidString().Return("test") + expectIMBearer(t, ctrl, "token-1", 7, 42) oldSubs := store.Subs oldGroupBusiness := store.GroupBusiness oldSecurity := store.Security @@ -4935,21 +4934,15 @@ func TestServeIMGroupInvitationAddsNonMember(t *testing.T) { } data := decodeIMHTTPResponse(t, rec).Data.(map[string]any) items := data["items"].([]any) - if len(items) != 1 || items[0].(map[string]any)["status"] != types.GroupInvitationStatusPending { + if len(items) != 1 || items[0].(map[string]any)["status"] != types.GroupInvitationStatusJoined { t.Fatalf("unexpected invitation response: %#v", data) } - if len(groupStore.invitations) != 1 || groupStore.invitations[0].TargetUserID != target || groupStore.invitations[0].InvitationID != "ginv_test" { - t.Fatalf("invitation was not persisted: %#v", groupStore.invitations) + if len(groupStore.invitations) != 1 || groupStore.invitations[0].TargetUserID != target || + groupStore.invitations[0].Status != types.GroupInvitationStatusJoined { + t.Fatalf("member was not joined directly: %#v", groupStore.invitations) } - if len(securityStore.notifications) != 1 { - t.Fatalf("expected one target notification, got %#v", securityStore.notifications) - } - notification := securityStore.notifications[0] - if notification.UserID != target || notification.EventType != "group.invitation.created" { - t.Fatalf("unexpected notification target/type: %#v", notification) - } - if notification.Action["type"] != "group_invitation_accept" || notification.Action["invitation_id"] != "ginv_test" || notification.Action["topic"] != "grpAlpha" { - t.Fatalf("unexpected notification action: %#v", notification.Action) + if len(securityStore.notifications) != 0 { + t.Fatalf("direct invite should not create approval notification: %#v", securityStore.notifications) } }