diff --git a/CHANGELOG.md b/CHANGELOG.md index ffe2d230b5c863acb3f76b3ff0649089511fb50b..058b57a5e091d47861df00f72de4693076347966 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -14,6 +14,7 @@ The format is based on [keep a changelog](http://keepachangelog.com) and this pr ### Fixed - Consistent validation of override operator in runtime leaderboard record writes. - Correctly filter open/closed groups in the listing API. +- Ensure direct message channel message listing is correctly scoped to participants only. ## [3.15.0] - 2023-01-04 ### Added diff --git a/server/api_channel.go b/server/api_channel.go index c671964d512d6bda9ee4b9c2a7665b4867fd7b00..ae5dfa207a0da93946993bd0ee7209669f5d54c6 100644 --- a/server/api_channel.go +++ b/server/api_channel.go @@ -16,10 +16,10 @@ package server import ( "context" - "github.com/heroiclabs/nakama-common/runtime" "github.com/gofrs/uuid" "github.com/heroiclabs/nakama-common/api" + "github.com/heroiclabs/nakama-common/runtime" "go.uber.org/zap" "google.golang.org/grpc/codes" "google.golang.org/grpc/status" @@ -78,6 +78,8 @@ func (s *ApiServer) ListChannelMessages(ctx context.Context, in *api.ListChannel return nil, status.Error(codes.InvalidArgument, "Cursor is invalid or expired.") } else if err == runtime.ErrChannelGroupNotFound { return nil, status.Error(codes.InvalidArgument, "Group not found.") + } else if err == runtime.ErrChannelIDInvalid { + return nil, status.Error(codes.InvalidArgument, "Channel not found.") } else if err != nil { return nil, status.Error(codes.Internal, "Error listing messages from channel.") } diff --git a/server/core_channel.go b/server/core_channel.go index 50409a0f79865f8429571da0f78d95595fc8868c..8cbc774d0556958bb2754a789c409317166b47b8 100644 --- a/server/core_channel.go +++ b/server/core_channel.go @@ -89,14 +89,27 @@ func ChannelMessagesList(ctx context.Context, logger *zap.Logger, db *sql.DB, ca } } - // If it's a group, check membership. - if caller != uuid.Nil && stream.Mode == StreamModeGroup { - allowed, err := groupCheckUserPermission(ctx, logger, db, stream.Subject, caller, 2) - if err != nil { - return nil, err - } - if !allowed { - return nil, runtime.ErrChannelGroupNotFound + // Check channel permissions for non-authoritative calls. + if caller != uuid.Nil { + switch stream.Mode { + case StreamModeGroup: + // If it's a group, check membership. + allowed, err := groupCheckUserPermission(ctx, logger, db, stream.Subject, caller, 2) + if err != nil { + return nil, err + } + if !allowed { + return nil, runtime.ErrChannelGroupNotFound + } + case StreamModeDM: + // If it's a DM chat, check that the user is one of the chat participants. + if stream.Subject != caller && stream.Subcontext != caller { + return nil, runtime.ErrChannelIDInvalid + } + case StreamModeChannel: + fallthrough + default: + // No } }