Skip to content

Instantly share code, notes, and snippets.

@DanielOaks
Last active April 9, 2020 17:16
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save DanielOaks/eb88a1a9652f7fd3bbdeebac630ad1c9 to your computer and use it in GitHub Desktop.
Save DanielOaks/eb88a1a9652f7fd3bbdeebac630ad1c9 to your computer and use it in GitHub Desktop.
IRCv3 message modification very drafty proposal
title layout work-in-progress copyrights
IRCv3 Message Modification
spec
true
name email period
Daniel Oakley
daniel@danieloaks.net
2017

Notes for implementing work-in-progress version

This is a work-in-progress specification.

Software implementing this work-in-progress specification MUST NOT use the unprefixed +edit or +delete tag names. Instead, implementations SHOULD use the +draft/edit and +draft/delete tag names to be interoperable with other software implementing a compatible work-in-progress version.

The final version of the specification will use unprefixed tag names.

Introduction

Most text-based chat systems today allow both editing and deleting messages. This allows people to correct typos, remove messages that were accidentally sent, and fix similar issues that regularly occur while typing.

Architecture

Dependencies

Clients wishing to use these features MUST negotiate the draft/message-tags and account-tag capabilities with the server, and SHOULD negotiate the chghost extension. Additionally, these features rely on messages being sent with the draft/msgid tag.

Client Tags

+draft/delete tag

The +draft/delete client tag allows clients to delete their own messages, and channel operators to delete messages in their channel. Its value references the server-provided ID of another message (specifically, the message the sending client wishes to delete).

For instance, the tag +draft/delete=abcd123 indicates that the client wishes to delete the message with the ID abcd123.

Deleting messages can be done by either the original sender of the message, or by a channel operator if the message was posted in their channel.

When checking the original sender, clients MUST check the message author using the techniques in the "Validating Message Authors" section below. To be precise, if the same account tag is included on both the original message and the message with the +draft/delete tag, that's also confirmation of the same user deleting their message.

For channel operators, the check is relatively simple. If the user sending the delete message is at least a channel operator, and has a higher channel privilege than that of the user who originally posted the message, they can delete the message.

Clients SHOULD NOT allow their users to 'delete' messages in their UI if they do not have the privileges to do so. This is to avoid confusion when other users do not see their message deletion (as it would be rejected and ignored by those other clients).

If a +draft/delete client tag is received but the message cannot be deleted for any reason, it MUST be ignored.

+draft/edit tag

The +draft/edit client tag allows clients to edit their own messages. It does NOT allow channel operators to edit others' messages. Its value references the server-provided ID of another message (specifically, the message the sending client wishes to edit).

For instance, the tag +draft/edit=abcd1234 indicates that the client wishes to delete the message with the ID abcd1234.

Editing messages can only be done by the original sender of that message, and by nobody else.

When checking the original sender, clients MUST check the message author using the techniques in the "Validating Message Authors" section below. To be precise, if the same account tag is included on both the original message and the message with the +draft/edit tag, that's also confirmation of the same user deleting their message.

Clients SHOULD NOT allow their users to 'edit' messages in their UI if they do not have the privileges to do so. This is to avoid confusion when other users do not see their message edit (as it would be rejected and ignored by those other clients).

+draft/edit tag MUST be sent with the PRIVMSG command. When a client receives a PRIVMSG with the +draft/edit client tag, and the client has permission to edit the original message, they MUST replace the content of the original message with the content of the new private message that has just been received.

This tag is always sent as a PRIVMSG to avoid unduly notifying clients that do not support client tags, and will simply receive the edited message in whole instead.

Validating Message Authors

This section describes how users validate the original authors of messages.

Clients implementing this specification MUST implement the account-tag specification, and SHOULD implement the chghost extension.

For each channel a client is joined to, the client MUST remember which user and account posted each of the last 20 messages in that channel. Clients MAY remember more history than the last 20 messages if desired.

When remembering which user posted a channel, clients MUST track users across nickname changes, and username and hostname changes if the chghost extension is negotiated. It must track this while it shares a common channel with each user. If the client no longer shares a common channel with a user, all tracking information with regards to which messages a user has posted, aside from identical nickmask comparison (nickname!username@hostname) and account comparison MUST no longer be used for validation.

Example

dan posts a message, changes nickname, and the other clients in the channel must validate.

C: (dan)     PRIVMSG #chan1 :So as we were discussing, #chan5's based on X, Y, and Z
S: (#chan1)  @draft/msgid=123 :dan!~d@localhost #chan1 :So as we were discussing, #chan5's based on X, Y, and Z
C: (dan)     NICK coolguy
S: (#chan1)  :dan!~d@localhost NICK coolguy

Clients in #chan1 MUST be able to tell that the user currently with the nick coolguy originally posted message 123.

Examples

+draft/delete Examples

Client deleting their own message after posting it.

C: (dan)     PRIVMSG #chan1 :So as we were discussing, #chan5's based on X, Y, and Z
S: (#chan1)  @draft/msgid=123 :dan!~d@localhost #chan1 :So as we were discussing, #chan5's based on X, Y, and Z
C: (dan)     @+draft/delete=123 TAGMSG #chan1
S: (#chan1)  @+draft/delete=123 :dan!~d@localhost TAGMSG #chan1

Clients in #chan1 see that dan is deleting his own message and processes it.


Channel operator @eve deleting dan's message.

C: (dan)     PRIVMSG #chan1 :SPAM SPAM SPAM SPAM LOOK AT ALL THIS SPAM SPAM SPAM SPAM
S: (#chan1)  @draft/msgid=543 :dan!~d@localhost #chan1 :SPAM SPAM SPAM SPAM LOOK AT ALL THIS SPAM SPAM SPAM SPAM
C: (eve)     @+draft/delete=543 TAGMSG #chan1
S: (#chan1)  @+draft/delete=543 :eve!e@local.host2 TAGMSG #chan1

Clients in #chan1 see that @eve, a chanop, is removing dan's message and processes it.


Client deleting their own message with different clients dan and coolg.

C: (dan)     PRIVMSG #chan1 :So as we were discussing, #chan5's based on X, Y, and Z
S: (#chan1)  @account=coolguy;draft/msgid=123 :dan!~d@localhost #chan1 :So as we were discussing, #chan5's based on X, Y, and Z
C: (coolg)   @+draft/delete=123 TAGMSG #chan1
S: (#chan1)  @account=coolguy;+draft/delete=123 :coolg!uy@localhost TAGMSG #chan1

Clients in #chan1 should see that the same account that created the message sent the deletion request, and processes it.

+draft/edit Examples

Client editing their own message after posting it.

C: (dan)     PRIVMSG #chan1 :So as we were discussing, #chan1's based on X, Y, and Z
S: (#chan1)  @draft/msgid=123 :dan!~d@localhost #chan1 :So as we were discussing, #chan1's based on X, Y, and Z
C: (dan)     @+draft/edit=123 PRIVMSG #chan1 :So as we were discussing, #chan1's based on X and Y
S: (#chan1)  @+draft/edit=123 :dan!~d@localhost PRIVMSG #chan1 :So as we were discussing, #chan1's based on X and Y

Clients in #chan1 see that dan is editing his own message and processes it.


Channel operator @eve attempting to edit dan's message.

C: (dan)     PRIVMSG #chan1 :So as we were discussing, #chan1's based on X, Y, and Z
S: (#chan1)  @draft/msgid=543 :dan!~d@localhost #chan1 :So as we were discussing, #chan1's based on X, Y, and Z
C: (eve)     @+draft/edit=123 PRIVMSG #chan1 :So as we were discussing, #chan1's based on A, B, and C
S: (#chan1)  @+draft/edit=123 :eve!e@local.host2 PRIVMSG #chan1 :So as we were discussing, #chan1's based on A, B, and C

Clients in #chan1 see that @eve is not dan, and did not author dan's message. Clients reject and do not display the edit.


Client editing their own message with different clients dan and coolg.

C: (dan)     PRIVMSG #chan1 :So as we were discussing, #chan5's based on X, Y, and Z
S: (#chan1)  @account=coolguy;draft/msgid=123 :dan!~d@localhost #chan1 :So as we were discussing, #chan5's based on X, Y, and Z
C: (coolg)   @+draft/edit=123 PRIVMSG #chan1 :So as we were discussing, #chan1's based on X and Y
S: (#chan1)  @+draft/edit=123 :coolg!uy@localhost PRIVMSG #chan1 :So as we were discussing, #chan1's based on X and Y

Clients in #chan1 should see that the same account that created the message sent the edit request, and processes it.

Implementation Considerations

This section is non-normative.

Clients may wish to only allow message edits for a certain length of time after the original message is posted. Or may only allow editing/deleting messages for the last X number of messages in their channel, depending on how message IDs and how related message attributes such as accounts are stored.

Similarly, particularly long-running clients may wish to disable editing or deleting messages in their GUI after a certain amount of time has passed. If they do, the developers of those clients should stay aware of the time or message-count-based limits of message modification, and tune the timings used by their own clients to be similar.

Clients should make an effort to allow a reasonably long amount of message deletion, particularly within channels, to match the asynchronous nature of IRC communications.

Clients should be aware that not all clients may see the modifications they make after posting messages.

Alternatives

Alternatives that have been discussed include making edit and delete tags that are validated by the server before being passed along. I have not done this here, since this requires servers to store fairly in-depth message history, for at least as long as clients want to edit messages.

For the edit tag, it's been suggested to put the new replacement message text in as a separate edit-text tag instead. I have not done this here as making it a PRIVMSG forces backwards compatibility, in that clients will be able to see the new, edited messages (which can in some cases completely change the context or content of a previously-sent message). In my experience, resending messages to fix edits is already common enough that doing so here shouldn't cause a big fuss.

As well, adding the text as an edit-text tag rather than using the body of a PRIVMSG causes issues as we allow the maximum length of tags and of the rest of the message to differ (or may in the future, see #281 for context). Doing message editing in the way specified here bypasses any possible complications or issues caused by that in the future.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment