|
@@ -2663,6 +2663,97 @@ fail:
|
2663
|
2663
|
return false
|
2664
|
2664
|
}
|
2665
|
2665
|
|
|
2666
|
+// REDACT <target> <targetmsgid> [:<reason>]
|
|
2667
|
+func redactHandler(server *Server, client *Client, msg ircmsg.Message, rb *ResponseBuffer) bool {
|
|
2668
|
+ target := msg.Params[0]
|
|
2669
|
+ targetmsgid := msg.Params[1]
|
|
2670
|
+ //clientOnlyTags := msg.ClientOnlyTags()
|
|
2671
|
+ var reason string
|
|
2672
|
+ if len(msg.Params) > 2 {
|
|
2673
|
+ reason = msg.Params[2]
|
|
2674
|
+ }
|
|
2675
|
+ var members []*Client // members of a channel, or both parties of a PM
|
|
2676
|
+ var canDelete CanDelete
|
|
2677
|
+
|
|
2678
|
+ msgid := utils.GenerateSecretToken()
|
|
2679
|
+ time := time.Now().UTC().Round(0)
|
|
2680
|
+ details := client.Details()
|
|
2681
|
+ isBot := client.HasMode(modes.Bot)
|
|
2682
|
+
|
|
2683
|
+ if target[0] == '#' {
|
|
2684
|
+ channel := server.channels.Get(target)
|
|
2685
|
+ if channel == nil {
|
|
2686
|
+ rb.Add(nil, server.name, ERR_NOSUCHCHANNEL, client.Nick(), utils.SafeErrorParam(target), client.t("No such channel"))
|
|
2687
|
+ return false
|
|
2688
|
+ }
|
|
2689
|
+ members = channel.Members()
|
|
2690
|
+ canDelete = deletionPolicy(server, client, target)
|
|
2691
|
+ } else {
|
|
2692
|
+ targetClient := server.clients.Get(target)
|
|
2693
|
+ if targetClient == nil {
|
|
2694
|
+ rb.Add(nil, server.name, ERR_NOSUCHNICK, client.Nick(), target, "No such nick")
|
|
2695
|
+ return false
|
|
2696
|
+ }
|
|
2697
|
+ members = []*Client{client, targetClient}
|
|
2698
|
+ canDelete = canDeleteSelf
|
|
2699
|
+ }
|
|
2700
|
+
|
|
2701
|
+ if canDelete == canDeleteNone {
|
|
2702
|
+ rb.Add(nil, server.name, "FAIL", "REDACT", "REDACT_FORBIDDEN", utils.SafeErrorParam(target), utils.SafeErrorParam(targetmsgid), client.t("You are not authorized to delete messages"))
|
|
2703
|
+ return false
|
|
2704
|
+ }
|
|
2705
|
+ accountName := "*"
|
|
2706
|
+ if canDelete == canDeleteSelf {
|
|
2707
|
+ accountName = client.AccountName()
|
|
2708
|
+ if accountName == "*" {
|
|
2709
|
+ rb.Add(nil, server.name, "FAIL", "REDACT", "REDACT_FORBIDDEN", utils.SafeErrorParam(target), utils.SafeErrorParam(targetmsgid), client.t("You are not authorized to delete because you are logged out"))
|
|
2710
|
+ return false
|
|
2711
|
+ }
|
|
2712
|
+ }
|
|
2713
|
+
|
|
2714
|
+ err := server.DeleteMessage(target, targetmsgid, accountName)
|
|
2715
|
+ if err == errNoop {
|
|
2716
|
+ rb.Add(nil, server.name, "FAIL", "REDACT", "UNKNOWN_MSGID", utils.SafeErrorParam(target), utils.SafeErrorParam(targetmsgid), client.t("This message does not exist or is too old"))
|
|
2717
|
+ return false
|
|
2718
|
+ } else if err != nil {
|
|
2719
|
+ isOper := client.HasRoleCapabs("history")
|
|
2720
|
+ if isOper {
|
|
2721
|
+ rb.Add(nil, server.name, "FAIL", "REDACT", "REDACT_FORBIDDEN", utils.SafeErrorParam(target), utils.SafeErrorParam(targetmsgid), fmt.Sprintf(client.t("Error deleting message: %v"), err))
|
|
2722
|
+ } else {
|
|
2723
|
+ rb.Add(nil, server.name, "FAIL", "REDACT", "REDACT_FORBIDDEN", utils.SafeErrorParam(target), utils.SafeErrorParam(targetmsgid), client.t("Could not delete message"))
|
|
2724
|
+ }
|
|
2725
|
+ return false
|
|
2726
|
+ }
|
|
2727
|
+
|
|
2728
|
+ if target[0] != '#' {
|
|
2729
|
+ // If this is a PM, we just removed the message from the buffer of the other party;
|
|
2730
|
+ // now we have to remove it from the buffer of the client who sent the REDACT command
|
|
2731
|
+ err := server.DeleteMessage(client.Nick(), targetmsgid, accountName)
|
|
2732
|
+
|
|
2733
|
+ if err != nil {
|
|
2734
|
+ client.server.logger.Error("internal", fmt.Sprintf("Private message %s is not deletable by %s from their own buffer's even though we just deleted it from %s's. This is a bug, please report it in details.", targetmsgid, client.Nick(), target), client.Nick())
|
|
2735
|
+ isOper := client.HasRoleCapabs("history")
|
|
2736
|
+ if isOper {
|
|
2737
|
+ rb.Add(nil, server.name, "FAIL", "REDACT", "REDACT_FORBIDDEN", utils.SafeErrorParam(target), utils.SafeErrorParam(targetmsgid), fmt.Sprintf(client.t("Error deleting message: %v"), err))
|
|
2738
|
+ } else {
|
|
2739
|
+ rb.Add(nil, server.name, "FAIL", "REDACT", "REDACT_FORBIDDEN", utils.SafeErrorParam(target), utils.SafeErrorParam(targetmsgid), client.t("Error deleting message"))
|
|
2740
|
+ }
|
|
2741
|
+ }
|
|
2742
|
+ }
|
|
2743
|
+
|
|
2744
|
+ for _, member := range members {
|
|
2745
|
+ for _, session := range member.Sessions() {
|
|
2746
|
+ if session.capabilities.Has(caps.MessageRedaction) {
|
|
2747
|
+ session.sendFromClientInternal(false, time, msgid, details.nickMask, details.accountName, isBot, nil, "REDACT", target, targetmsgid, reason)
|
|
2748
|
+ } else {
|
|
2749
|
+ // If we wanted to send a fallback to clients which do not support
|
|
2750
|
+ // draft/message-redaction, we would do it from here.
|
|
2751
|
+ }
|
|
2752
|
+ }
|
|
2753
|
+ }
|
|
2754
|
+ return false
|
|
2755
|
+}
|
|
2756
|
+
|
2666
|
2757
|
func reportPersistenceStatus(client *Client, rb *ResponseBuffer, broadcast bool) {
|
2667
|
2758
|
settings := client.AccountSettings()
|
2668
|
2759
|
serverSetting := client.server.Config().Accounts.Multiclient.AlwaysOn
|