5252import im .turms .service .domain .conversation .repository .PrivateConversationRepository ;
5353import im .turms .service .domain .group .service .GroupMemberService ;
5454import im .turms .service .domain .group .service .GroupService ;
55+ import im .turms .service .domain .message .service .MessageService ;
5556import im .turms .service .domain .user .service .UserRelationshipService ;
5657import im .turms .service .storage .mongo .OperationResultPublisherPool ;
5758
@@ -65,6 +66,7 @@ public class ConversationService {
6566 private final UserRelationshipService userRelationshipService ;
6667 private final GroupService groupService ;
6768 private final GroupMemberService groupMemberService ;
69+ private final MessageService messageService ;
6870
6971 private final GroupConversationRepository groupConversationRepository ;
7072 private final PrivateConversationRepository privateConversationRepository ;
@@ -84,11 +86,13 @@ public ConversationService(
8486 UserRelationshipService userRelationshipService ,
8587 @ Lazy GroupService groupService ,
8688 GroupMemberService groupMemberService ,
89+ @ Lazy MessageService messageService ,
8790 GroupConversationRepository groupConversationRepository ,
8891 PrivateConversationRepository privateConversationRepository ) {
8992 this .userRelationshipService = userRelationshipService ;
9093 this .groupService = groupService ;
9194 this .groupMemberService = groupMemberService ;
95+ this .messageService = messageService ;
9296 this .groupConversationRepository = groupConversationRepository ;
9397 this .privateConversationRepository = privateConversationRepository ;
9498
@@ -138,19 +142,31 @@ public Mono<Void> authAndUpsertGroupConversationReadDate(
138142 }));
139143 }
140144
141- // TODO: authenticate
142145 public Mono <Void > authAndUpsertPrivateConversationReadDate (
143146 @ NotNull Long ownerId ,
144147 @ NotNull Long targetId ,
145148 @ Nullable @ PastOrPresent Date readDate ) {
149+ try {
150+ Validator .notNull (ownerId , "ownerId" );
151+ Validator .notNull (targetId , "targetId" );
152+ } catch (ResponseException e ) {
153+ return Mono .error (e );
154+ }
146155 if (!isReadReceiptEnabled ) {
147156 return Mono .error (
148157 ResponseException .get (ResponseStatusCode .UPDATING_READ_DATE_IS_DISABLED ));
149158 }
150- if (useServerTime ) {
151- readDate = new Date ();
152- }
153- return upsertPrivateConversationReadDate (ownerId , targetId , readDate );
159+ return messageService .hasPrivateMessage (targetId , ownerId )
160+ // TODO: This is a simple authorization implementation,
161+ // we can throw different status codes for different reasons
162+ // to have a fine-grained control in the future.
163+ .flatMap (hasPrivateMessage -> hasPrivateMessage
164+ ? upsertPrivateConversationReadDate (ownerId ,
165+ targetId ,
166+ useServerTime
167+ ? new Date ()
168+ : readDate )
169+ : Mono .empty ());
154170 }
155171
156172 public Mono <Void > upsertGroupConversationReadDate (
0 commit comments