fix(server): удаление и пины сообщений попадают в аудит сервера
AGENT.md 7.10 требует, чтобы действия с сообщениями были в журнале сервера, а §11.5 перечисляет удаление и закрепление как действия инстанс-админа на чужом сервере. Обе ручки рассылали только события Gateway, записей в аудите не было. `message.edit` намеренно не пишется: история правок не хранится (7.6), а правка своего сообщения — не модерационное действие и не входит в §11.5. Личные беседы в аудит не попадают: у них нет сервера, а журнал ведётся по серверам (7.10). Тест: internal/server/audit_messages_test.go — удаление, pin и unpin чужого сообщения инстанс-админом помечены `actor_instance_admin`, действие владельца в журнале есть, но без флага; личные сообщения в аудит не пишутся.
This commit is contained in:
@@ -375,7 +375,7 @@ func (s *Server) registerMessageRoutes(api huma.API) {
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
channelID, resolved, _, err := s.requireChannelPermission(ctx, input.ChannelID, user, permissions.ViewChannel)
|
||||
channelID, resolved, channel, err := s.requireChannelPermission(ctx, input.ChannelID, user, permissions.ViewChannel)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -389,6 +389,7 @@ func (s *Server) registerMessageRoutes(api huma.API) {
|
||||
if err := s.store.DeleteMessage(ctx, message.ID); err != nil {
|
||||
return nil, humaError(err)
|
||||
}
|
||||
s.recordMessageAudit(ctx, user, channel, "message.delete", message.ID)
|
||||
s.dispatchChannelEvent(ctx, channelID, "MESSAGE_DELETE", map[string]any{
|
||||
"id": formatSnowflake(message.ID),
|
||||
"channel_id": formatSnowflake(channelID),
|
||||
@@ -754,6 +755,15 @@ func (s *Server) requireMessageAuthor(user *store.User, resolved permissions.Res
|
||||
return humaErrorStatus(http.StatusForbidden, "perm.denied", "permission denied")
|
||||
}
|
||||
|
||||
// recordMessageAudit пишет действие с сообщением в аудит сервера (AGENT.md 7.10).
|
||||
// Личные беседы серверу не принадлежат — в журнал они не попадают.
|
||||
func (s *Server) recordMessageAudit(ctx context.Context, actor *store.User, channel *store.Channel, action string, messageID uint64) {
|
||||
if channel.GuildID == nil {
|
||||
return
|
||||
}
|
||||
s.recordAudit(ctx, actor, *channel.GuildID, action, "message", &messageID, "")
|
||||
}
|
||||
|
||||
// changeReaction ставит или снимает реакцию и рассылает событие.
|
||||
func (s *Server) changeReaction(ctx context.Context, rawChannelID, rawMessageID, emoji string, add bool) (*okOutput, error) {
|
||||
user, _, err := requireUser(ctx)
|
||||
@@ -835,7 +845,7 @@ func (s *Server) changePin(ctx context.Context, rawChannelID, rawMessageID strin
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
channelID, _, _, err := s.requireChannelPermission(ctx, rawChannelID, user, permissions.ManageMessages)
|
||||
channelID, _, channel, err := s.requireChannelPermission(ctx, rawChannelID, user, permissions.ManageMessages)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -856,6 +866,11 @@ func (s *Server) changePin(ctx context.Context, rawChannelID, rawMessageID strin
|
||||
if err := s.store.SetMessagePinned(ctx, message.ID, pinned); err != nil {
|
||||
return nil, humaError(err)
|
||||
}
|
||||
action := "message.unpin"
|
||||
if pinned {
|
||||
action = "message.pin"
|
||||
}
|
||||
s.recordMessageAudit(ctx, user, channel, action, message.ID)
|
||||
s.dispatchChannelEvent(ctx, channelID, "CHANNEL_PINS_UPDATE", map[string]any{
|
||||
"channel_id": formatSnowflake(channelID),
|
||||
"message_id": formatSnowflake(message.ID),
|
||||
|
||||
Reference in New Issue
Block a user