diff --git a/core/blocklist.go b/core/blocklist.go index 55a3b9c..4b66664 100644 --- a/core/blocklist.go +++ b/core/blocklist.go @@ -14,7 +14,7 @@ import ( ) type blockDoc struct { - Id primitive.ObjectID `bson:"_id,omitempty" json:"id"` + Id primitive.ObjectID `bson:"_id,omitempty" json:"_id"` From primitive.ObjectID `bson:"from,omitempty" json:"-"` To primitive.ObjectID `bson:"to,omitempty" json:"-"` ToAlias string `bson:"talias" json:"to"` @@ -53,13 +53,14 @@ func (bl *blocklist) Block(w http.ResponseWriter, r *http.Request) { return } + block.Timestamp = time.Now().UTC().Unix() _, newid, err := bl.mongoClient.Update(block_collection_name, bson.M{ "_id": combineObjectID(block.From, block.To), }, bson.M{ "$set": block, }, options.Update().SetUpsert(true)) - if err != nil || newid != block.Id { + if err != nil || newid == nil { // 이미 있다고 봐야지 w.WriteHeader(http.StatusBadRequest) return @@ -67,7 +68,7 @@ func (bl *blocklist) Block(w http.ResponseWriter, r *http.Request) { block.Id = newid.(primitive.ObjectID) bl.wsh.SendUpstreamMessage(&wshandler.UpstreamMessage{ - Target: block.To.Hex(), + Target: block.From.Hex(), Body: []blockDoc{block}, Tag: blocks_tag, }) @@ -92,9 +93,8 @@ func (bl *blocklist) Unblock(ctx wshandler.ApiCallContext) { if updated { bl.conns.writeMessage(ctx.CallBy.Accid, &wshandler.DownstreamMessage{ - Alias: ctx.CallBy.Alias, - Body: []blockDoc{{Id: id, Deleted: true, Timestamp: now}}, - Tag: blocks_tag, + Body: []blockDoc{{Id: id, Deleted: true, Timestamp: now}}, + Tag: blocks_tag, }) } } @@ -122,3 +122,23 @@ func (bl *blocklist) QueryBlock(w http.ResponseWriter, r *http.Request) { w.WriteHeader(http.StatusGone) } } + +func (bl *blocklist) QueryBlocks(ctx wshandler.ApiCallContext) { + queryfrom := int64(ctx.Arguments[0].(float64)) + + var myblocks []blockDoc + err := bl.mongoClient.FindAllAs(block_collection_name, bson.M{ + "from": ctx.CallBy.Accid, + "ts": bson.M{"$gt": queryfrom}, + }, &myblocks) + if err != nil { + logger.Println("QueryBlocks failed. FindAllAs err :", err) + } + + if len(myblocks) > 0 { + bl.conns.writeMessage(ctx.CallBy.Accid, &wshandler.DownstreamMessage{ + Body: myblocks, + Tag: blocks_tag, + }) + } +} diff --git a/core/common.go b/core/common.go index 11f8dbd..eac394f 100644 --- a/core/common.go +++ b/core/common.go @@ -1,6 +1,9 @@ package core -import "repositories.action2quare.com/ayo/gocommon" +import ( + "go.mongodb.org/mongo-driver/bson/primitive" + "repositories.action2quare.com/ayo/gocommon" +) const ( block_collection_name = gocommon.CollectionName("block") @@ -12,3 +15,11 @@ var friend_state_tag = []string{"social.FriendState"} var invitations_tag = []string{"social.Invitations"} var friends_tag = []string{"social.Friends"} var blocks_tag = []string{"social.Blocks"} + +func stringsToObjs(in []any) (out []primitive.ObjectID) { + for _, i := range in { + p, _ := primitive.ObjectIDFromHex(i.(string)) + out = append(out, p) + } + return +} diff --git a/core/friend.go b/core/friend.go index 023c621..4371e2f 100644 --- a/core/friend.go +++ b/core/friend.go @@ -299,6 +299,7 @@ func (fs *friends) DeleteFriend(ctx wshandler.ApiCallContext) { "ts": now, }, }, &yourdoc, options.FindOneAndUpdate().SetReturnDocument(options.After).SetUpsert(false)); err == nil { + logger.Println("delete friend your doc :", yourdoc) fs.wsh.SendUpstreamMessage(&wshandler.UpstreamMessage{ Target: fdoc.To.Hex(), Body: []friendDoc{yourdoc}, @@ -369,23 +370,14 @@ func (fs *friends) QueryFriends(ctx wshandler.ApiCallContext) { if len(myfriends) > 0 { fs.conns.writeMessage(ctx.CallBy.Accid, &wshandler.DownstreamMessage{ - Alias: ctx.CallBy.Alias, - Body: myfriends, - Tag: friends_tag, + Body: myfriends, + Tag: friends_tag, }) } } func (fs *friends) Trim(ctx wshandler.ApiCallContext) { - stringsTobjs := func(in []any) (out []primitive.ObjectID) { - for _, i := range in { - p, _ := primitive.ObjectIDFromHex(i.(string)) - out = append(out, p) - } - return - } - - ids := stringsTobjs(ctx.Arguments[2].([]any)) + ids := stringsToObjs(ctx.Arguments[1].([]any)) if len(ids) > 0 { if len(ids) == 1 { fs.mongoClient.Delete(friends_collection_name, bson.M{"_id": ids[0]}) diff --git a/core/invitation.go b/core/invitation.go index ae4b38b..3e9858c 100644 --- a/core/invitation.go +++ b/core/invitation.go @@ -28,7 +28,8 @@ type invitationDoc struct { FromAlias string `bson:"falias,omitempty" json:"from"` ToAlias string `bson:"talias,omitempty" json:"to"` Timestamp int64 `bson:"ts" json:"ts"` - Deleted bool `bson:"deleted,omitempty" json:"deleted,omitempty"` + Denied bool `bson:"denied,omitempty" json:"denied,omitempty"` + Canceled bool `bson:"canceled,omitempty" json:"canceled,omitempty"` Blocked bool `bson:"blocked,omitempty" json:"-"` // From은 To에 의해 차단된 상태를 표시 } @@ -45,7 +46,7 @@ func makeInvitation(ctx context.Context, s *Social, f *friends) (*invitation, er // 내가 받은거 if err := s.mongoClient.MakeIndices(invitation_collection_name, map[string]bson.D{ - "tots": {{Key: "to", Value: 1}, {Key: "ts", Value: -1}, {Key: "blocked", Value: 1}}, + "tots": {{Key: "to", Value: 1}, {Key: "ts", Value: -1}}, }); err != nil { return nil, err } @@ -67,15 +68,17 @@ func (iv *invitation) QueryInvitations(ctx wshandler.ApiCallContext) { if err := iv.mongoClient.FindAllAs(invitation_collection_name, bson.M{ "to": ctx.CallBy.Accid, "ts": bson.M{"$gt": queryfrom}, - "blocked": false, + "blocked": bson.M{"$exists": false}, + "denied": bson.M{"$exists": false}, }, &receives, options.Find().SetHint("tots")); err != nil { logger.Println("QueryInvitations failed. FindAllAs err :", err) } var sents []*invitationDoc if err := iv.mongoClient.FindAllAs(invitation_collection_name, bson.M{ - "from": ctx.CallBy.Accid, - "ts": bson.M{"$gt": queryfrom}, + "from": ctx.CallBy.Accid, + "ts": bson.M{"$gt": queryfrom}, + "canceled": bson.M{"$exists": false}, }, &sents, options.Find().SetHint("fromts")); err != nil { logger.Println("QueryInvitations failed. FindAllAs err :", err) } @@ -92,45 +95,37 @@ func (iv *invitation) QueryInvitations(ctx wshandler.ApiCallContext) { func (iv *invitation) CancelInvitation(ctx wshandler.ApiCallContext) { // ctx.CallBy.Accid - id, _ := primitive.ObjectIDFromHex(ctx.Arguments[0].(string)) + invId, _ := primitive.ObjectIDFromHex(ctx.Arguments[0].(string)) + now := time.Now().UTC().Unix() var ivdoc invitationDoc - if err := iv.mongoClient.FindOneAs(invitation_collection_name, bson.M{ - "_id": id, - }, &ivdoc); err != nil { - logger.Println("CancelInvitation failed:", err) - return - } - - if ivdoc.From != ctx.CallBy.Accid { - return - } - - ivdoc.Deleted = true - if _, _, err := iv.mongoClient.Update(invitation_collection_name, bson.M{ - "_id": id, + if err := iv.mongoClient.FindOneAndUpdateAs(invitation_collection_name, bson.M{ + "_id": invId, + "from": bson.M{"$eq": ctx.CallBy.Accid}, }, bson.M{ "$set": bson.M{ - "falias": "", - "deleted": true, - "ts": time.Now().UTC().Unix(), + "canceled": true, + "ts": now, }, - }); err != nil { - logger.Println("CancelInvitation failed:", err) + }, &ivdoc, options.FindOneAndUpdate().SetReturnDocument(options.After).SetUpsert(false)); err != nil { + logger.Println("CancelInvitation failed :", err) return } - iv.wsh.SendUpstreamMessage(&wshandler.UpstreamMessage{ - Target: ivdoc.To.Hex(), - Body: []invitationDoc{ivdoc}, - Tag: invitations_tag, - }) + if ivdoc.Id.IsZero() { + return + } - iv.wsh.SendUpstreamMessage(&wshandler.UpstreamMessage{ - Target: ivdoc.From.Hex(), - Body: []invitationDoc{ivdoc}, - Tag: invitations_tag, - }) + if ivdoc.Blocked { + // 차단된 초대다. 초대한 사람은 차단된 상태를 모르기 때문에 이 초대는 삭제하고, 초대받은 사람한테는 보내지 않는다. + iv.mongoClient.Delete(invitation_collection_name, bson.M{"_id": invId}) + } else { + iv.wsh.SendUpstreamMessage(&wshandler.UpstreamMessage{ + Target: ivdoc.To.Hex(), + Body: []invitationDoc{ivdoc}, + Tag: invitations_tag, + }) + } } func (iv *invitation) AcceptInvitation(ctx wshandler.ApiCallContext) { @@ -192,57 +187,31 @@ func (iv *invitation) AcceptInvitation(ctx wshandler.ApiCallContext) { return } - iv.mongoClient.Update(invitation_collection_name, bson.M{ - "_id": invId, - }, bson.M{ - "$set": bson.M{ - "deleted": true, - "ts": now, - }, - }, options.Update().SetUpsert(false)) + iv.mongoClient.Delete(invitation_collection_name, bson.M{"_id": invId}) } func (iv *invitation) DenyInvitation(ctx wshandler.ApiCallContext) { invId, _ := primitive.ObjectIDFromHex(ctx.Arguments[0].(string)) + now := time.Now().UTC().Unix() var ivdoc invitationDoc - if err := iv.mongoClient.FindOneAs(invitation_collection_name, bson.M{ - "_id": invId, - }, &ivdoc); err != nil { - logger.Println("AcceptInvitation failed:", err) - return - } - - if ivdoc.Id != invId { - // 초대가 없다 - return - } - - if ivdoc.To != ctx.CallBy.Accid { - // 내가 받은 초대가 아니네? - return - } - - now := time.Now().UTC().Unix() - ivdoc.Timestamp = now - ivdoc.Deleted = true - if _, _, err := iv.mongoClient.Update(invitation_collection_name, bson.M{ + if err := iv.mongoClient.FindOneAndUpdateAs(invitation_collection_name, bson.M{ "_id": invId, + "to": bson.M{"$eq": ctx.CallBy.Accid}, }, bson.M{ "$set": bson.M{ - "deleted": true, - "ts": now, + "denied": true, + "ts": now, }, - }, options.Update().SetUpsert(false)); err != nil { + }, &ivdoc, options.FindOneAndUpdate().SetReturnDocument(options.After).SetUpsert(false)); err != nil { logger.Println("DenyInvitation failed. addFriend(f2) err :", err) return } - iv.wsh.SendUpstreamMessage(&wshandler.UpstreamMessage{ - Target: ivdoc.To.Hex(), - Body: []invitationDoc{ivdoc}, - Tag: invitations_tag, - }) + if ivdoc.Id.IsZero() { + // 없다 + return + } iv.wsh.SendUpstreamMessage(&wshandler.UpstreamMessage{ Target: ivdoc.From.Hex(), @@ -252,23 +221,13 @@ func (iv *invitation) DenyInvitation(ctx wshandler.ApiCallContext) { } func (iv *invitation) Trim(ctx wshandler.ApiCallContext) { - stringsTobjs := func(in []any) (out []primitive.ObjectID) { - for _, i := range in { - p, _ := primitive.ObjectIDFromHex(i.(string)) - out = append(out, p) - } - return - } - - ids := stringsTobjs(ctx.Arguments[0].([]any)) - ids = append(ids, stringsTobjs(ctx.Arguments[1].([]any))...) + ids := stringsToObjs(ctx.Arguments[2].([]any)) if len(ids) > 0 { if len(ids) == 1 { - iv.mongoClient.Delete(invitation_collection_name, bson.M{"_id": ids[0], "deleted": true}) + iv.mongoClient.Delete(block_collection_name, bson.M{"_id": ids[0]}) } else { - iv.mongoClient.DeleteMany(invitation_collection_name, bson.D{ + iv.mongoClient.DeleteMany(block_collection_name, bson.D{ {Key: "_id", Value: bson.M{"$in": ids}}, - {Key: "deleted", Value: true}, }) } } @@ -353,7 +312,7 @@ func (iv *invitation) Block(w http.ResponseWriter, r *http.Request) { // 사실은 삭제가 아니지만 초대 삭제 알림. 나중에 쿼리해도 안나옴 iv.wsh.SendUpstreamMessage(&wshandler.UpstreamMessage{ Target: block.From.Hex(), - Body: []invitationDoc{{Id: id, Deleted: true, Timestamp: now}}, + Body: []invitationDoc{{Id: id, Canceled: true, Timestamp: now}}, Tag: invitations_tag, }) } @@ -376,6 +335,10 @@ func (iv *invitation) Unblock(ctx wshandler.ApiCallContext) { "$set": bson.M{ "ts": now, }, + "$unset": bson.M{ + "canceled": "", + "blocked": "", + }, }, &ivdoc, options.FindOneAndUpdate().SetUpsert(false).SetReturnDocument(options.After)) if err != nil { logger.Println("Block failed:", err) @@ -385,10 +348,10 @@ func (iv *invitation) Unblock(ctx wshandler.ApiCallContext) { if !ivdoc.Id.IsZero() { // 받은 초대가 있었다. // 나한테 알림 + ivdoc.Canceled = false iv.f.conns.writeMessage(ctx.CallBy.Accid, &wshandler.DownstreamMessage{ - Alias: ctx.CallBy.Alias, - Body: []invitationDoc{ivdoc}, - Tag: invitations_tag, + Body: []invitationDoc{ivdoc}, + Tag: invitations_tag, }) } }