fix: sync latest Android and langpack updates

This commit is contained in:
A 2026-07-02 14:09:24 +08:00
parent 20b388eeaa
commit 4570df5939
20 changed files with 12384 additions and 27 deletions

View file

@ -552,7 +552,8 @@ func adminRightsSubset(want, have domain.ChannelAdminRights) bool {
(!want.AddAdmins || have.AddAdmins) &&
(!want.ManageCall || have.ManageCall) &&
(!want.Anonymous || have.Anonymous) &&
(!want.ManageRanks || have.ManageRanks)
(!want.ManageRanks || have.ManageRanks) &&
(!want.ManageDirectMessages || have.ManageDirectMessages)
}
// checkEditMemberRank validates a rank-only (member tag) edit: creator edits

View file

@ -282,9 +282,6 @@ func (s *ChannelStore) EditChannelAdmin(_ context.Context, req domain.EditChanne
if !canAddChannelAdmins(actor) {
return domain.EditChannelAdminResult{}, domain.ErrChannelAdminRequired
}
if actor.Role != domain.ChannelRoleCreator && !adminRightsSubset(req.AdminRights, actor.AdminRights) {
return domain.EditChannelAdminResult{}, domain.ErrChannelRightForbidden
}
previous, ok := s.members[req.ChannelID][req.MemberID]
if !ok {
previous = domain.ChannelMember{
@ -300,7 +297,41 @@ func (s *ChannelStore) EditChannelAdmin(_ context.Context, req domain.EditChanne
}
}
if previous.Role == domain.ChannelRoleCreator {
return domain.EditChannelAdminResult{}, domain.ErrChannelUserCreator
if req.MemberID != req.UserID || channel.CreatorUserID != req.UserID || actor.Role != domain.ChannelRoleCreator {
return domain.EditChannelAdminResult{}, domain.ErrChannelUserCreator
}
member := previous
member.Status = domain.ChannelMemberActive
member.LeftAt = 0
member.AdminRights = domain.CreatorProjectionAdminRights(req.AdminRights)
if req.HasRank() {
member.Rank = req.Rank
}
s.members[req.ChannelID][req.MemberID] = member
s.appendChannelAdminLogLocked(domain.ChannelAdminLogEvent{
ChannelID: req.ChannelID,
UserID: req.UserID,
Date: req.Date,
Type: domain.ChannelAdminLogParticipantPromote,
PrevParticipant: ptrChannelMember(previous),
NewParticipant: ptrChannelMember(member),
})
s.refreshChannelCountsLocked(req.ChannelID)
channel = s.channels[req.ChannelID]
event := transientChannelParticipantEvent(channel.ID, req.UserID, previous, member, req.Date)
recipients := s.activeMemberIDsLocked(req.ChannelID, 0, 0)
recipients = append(recipients, req.MemberID)
return domain.EditChannelAdminResult{
Channel: channel,
Previous: previous,
Participant: member,
Event: event,
Recipients: recipients,
Date: req.Date,
}, nil
}
if actor.Role != domain.ChannelRoleCreator && !adminRightsSubset(req.AdminRights, actor.AdminRights) {
return domain.EditChannelAdminResult{}, domain.ErrChannelRightForbidden
}
member := previous
member.InviterUserID = req.UserID
@ -312,7 +343,9 @@ func (s *ChannelStore) EditChannelAdmin(_ context.Context, req domain.EditChanne
}
}
member.AdminRights = domain.NormalizeFullMegagroupAdminRights(channel, req.AdminRights)
member.Rank = req.Rank
if req.HasRank() {
member.Rank = req.Rank
}
if zeroChannelAdminRights(req.AdminRights) {
member.Role = domain.ChannelRoleMember
member.Rank = ""

View file

@ -173,6 +173,68 @@ func TestChannelCreatorLeaveTransfersOwner(t *testing.T) {
}
}
func TestChannelCreatorCanEditOwnAdminRights(t *testing.T) {
ctx := context.Background()
store := NewChannelStore()
created, err := store.CreateChannel(ctx, domain.CreateChannelRequest{
CreatorUserID: 1,
Title: "creator self admin",
Megagroup: true,
MemberUserIDs: []int64{2},
Date: 1_700_000_114,
})
if err != nil {
t.Fatalf("create channel: %v", err)
}
edited, err := store.EditChannelAdmin(ctx, domain.EditChannelAdminRequest{
UserID: 1,
ChannelID: created.Channel.ID,
MemberID: 1,
AdminRights: domain.ChannelAdminRights{
Anonymous: true,
},
Date: 1_700_000_115,
})
if err != nil {
t.Fatalf("creator edits own admin rights: %v", err)
}
if edited.Participant.Role != domain.ChannelRoleCreator || !edited.Participant.AdminRights.Anonymous || !edited.Participant.AdminRights.ChangeInfo || !edited.Participant.AdminRights.AddAdmins {
t.Fatalf("edited creator = %+v, want creator with anonymous plus full creator projection", edited.Participant)
}
persisted, err := store.GetParticipant(ctx, 1, created.Channel.ID, 1)
if err != nil {
t.Fatalf("get creator participant: %v", err)
}
if persisted.Role != domain.ChannelRoleCreator || !persisted.AdminRights.Anonymous || !persisted.AdminRights.ChangeInfo || !persisted.AdminRights.AddAdmins {
t.Fatalf("persisted creator = %+v, want creator with anonymous plus full creator projection", persisted)
}
if _, err := store.EditChannelAdmin(ctx, domain.EditChannelAdminRequest{
UserID: 1,
ChannelID: created.Channel.ID,
MemberID: 2,
AdminRights: domain.ChannelAdminRights{
ChangeInfo: true,
AddAdmins: true,
},
Date: 1_700_000_116,
}); err != nil {
t.Fatalf("promote admin: %v", err)
}
if _, err := store.EditChannelAdmin(ctx, domain.EditChannelAdminRequest{
UserID: 2,
ChannelID: created.Channel.ID,
MemberID: 1,
AdminRights: domain.ChannelAdminRights{
ChangeInfo: true,
},
Date: 1_700_000_117,
}); !errors.Is(err, domain.ErrChannelUserCreator) {
t.Fatalf("admin edits creator err = %v, want ErrChannelUserCreator", err)
}
}
func TestChannelAdminAndBanDoNotAdvanceChannelPts(t *testing.T) {
ctx := context.Background()
store := NewChannelStore()