diff --git a/feps/fep-5624.md b/feps/fep-5624.md index 1421905..7051c47 100644 --- a/feps/fep-5624.md +++ b/feps/fep-5624.md @@ -62,44 +62,60 @@ After locally verifying that the replier should be allowed to reply, the replier When receiving a reply to an object with a `canReply` property, the authority decides whether the reply is acceptable. -If the reply is considered acceptable, the authority MUST reply with an `Accept` activity with the `object` property set to the `id` of the reply object, and its `inReplyTo` property set to the object it is in reply to. +If the reply is considered acceptable, the authority MUST reply with an `ApproveReply` (`http://joinmastodon.org/ns#ApproveReply`) activity with the `object` property set to the `id` of the reply object, and its `inReplyTo` property set to the object it is in reply to. -That `Accept` activity SHOULD be publicly dereferenceable and MUST be dereferenceable by all parties allowed to see the original post. It MUST NOT embed its `object` nor its `inReplyTo` as to avoid possible information leaks. +That `ApproveReply` activity SHOULD be publicly dereferenceable and MUST be dereferenceable by all parties allowed to see the original post. It MUST NOT embed its `object` nor its `inReplyTo` as to avoid possible information leaks. -If the reply is considered unacceptable, the authority SHOULD reply with a `Reject` activity. This activity MAY be publicly accessible, but this is not a requirement. +Additionally, the authority MAY forward an accepted reply according to its own rules. -### Example `Accept` activity +If the reply is considered unacceptable, the authority SHOULD reply with a `RejectReply` (`http://joinmastodon.org/ns#RejectReply`) activity. This activity MAY be publicly accessible, but this is not a requirement. + +The reason for using the new activity types `ApproveReply` and `RejectReply` is to be explicit about the purpose of the approval, as one could imagine other kinds of approvals, and remaining implicit may cause ambiguities with other potential extensions. + +### Example `ApproveReply` activity ``` { - "@context": "https://www.w3.org/ns/activitystreams", + "@context": [ + "https://www.w3.org/ns/activitystreams", + { + "toot": "http://joinmastodon.org/ns#", + "ApproveReply": "toot:ApproveReply" + } + ], "actor": "https://example.com/users/1", "id": "https://example.com/reply_approvals/1", - "type": "Accept", + "type": "ApproveReply", "object": "https://example.org/users/bob/statuses/3", "inReplyTo": "https://example.com/users/1/statuses/1" } ``` -### Example `Reject` activity +### Example `RejectReply` activity ``` { - "@context": "https://www.w3.org/ns/activitystreams", + "@context": [ + "https://www.w3.org/ns/activitystreams", + { + "toot": "http://joinmastodon.org/ns#", + "RejectReply": "toot:RejectReply" + } + ], "actor": "https://example.com/users/1", "id": "https://example.com/reply_approvals/1", - "type": "Reject", + "type": "RejectReply", "object": "https://example.org/users/bob/statuses/3" } ``` ## Receiving approval and distributing the reply -After sending the initial `Create`, the replier SHOULD wait for an `Accept` activity such as described above. +After sending the initial `Create`, the replier SHOULD wait for an `ApproveReply` activity such as described above. -Once the `Accept` has been received, the replier SHOULD add a `replyApproval` (`http://joinmastodon.org/ns#replyApproval`) property to their reply object pointing to the `Accept` activity they received, and then MAY send a `Create` activity with the modified object to its intended audience. +Once the `ApproveReply` has been received, the replier SHOULD add a `replyApproval` (`http://joinmastodon.org/ns#replyApproval`) property to their reply object pointing to the `ApproveReply` activity they received, and then MAY send a `Create` activity with the modified object to its intended audience. -If it instead receives a `Reject`, the reply SHOULD be immediately deleted and the replier MAY be notified. +If it instead receives a `RejectReply`, the reply SHOULD be immediately deleted and the replier MAY be notified. ### Example reply object with `replyApproval` @@ -131,11 +147,12 @@ If it instead receives a `Reject`, the reply SHOULD be immediately deleted and t When processing a reply from a remote actor to a remote authority, a recipient SHOULD discard any reply that does not match any of the following conditions: - the object it is in reply to does not set a `canReply` property +- the object has been received through the remote authority - the object it is in reply to has a `canReply` containing the `as:Public` collection - the author of the reply appears in a `Mention` object in the `tag` property of the object it is in reply to -- the object it is in reply to sets a non-empty `canReply`, and `replyApproval` can be dereferenced and is a valid `Accept` activity +- the object it is in reply to sets a non-empty `canReply`, and `replyApproval` can be dereferenced and is a valid `ApproveReply` activity -To be considered valid, the `Accept` activity referenced in `replyApproval` MUST satisfy the following properties: +To be considered valid, the `ApproveReply` activity referenced in `replyApproval` MUST satisfy the following properties: - its `actor` property is the authority - its authenticity can be asserted - its `object` property is the reply under consideration @@ -147,15 +164,15 @@ In addition, if the reply is considered valid, but has no valid `replyApproval` The authority may want to perform /a posteriori/ moderation of their replies. -To do this, the authority SHOULD send a `Reject` activity to the sender and the reply's audience, with the reply URI as the `object` property. The `object` property MUST NOT be embedded, as to avoid possible information leaks. +To do this, the authority SHOULD send a `RejectReply` activity to the sender and the reply's audience, with the reply URI as the `object` property. The `object` property MUST NOT be embedded, as to avoid possible information leaks. -The URI at which the previously-offered `Accept` was available should return HTTP 404 or redirect to the newly-issued `Reject` activity. +The URI at which the previously-offered `ApproveReply` was available should return HTTP 404 or redirect to the newly-issued `RejectReply` activity. ## Handling a revocation -Upon receiving a `Reject` activity for a previously-accepted reply, third-parties SHOULD check that the `Reject` is valid and SHOULD delete or hide the revoked reply if it is. +Upon receiving a `RejectReply` activity for a previously-accepted reply, third-parties SHOULD check that the `RejectReply` is valid and SHOULD delete or hide the revoked reply if it is. -To be considered valid, the `Reject` activity MUST satisfy the following properties: +To be considered valid, the `RejectReply` activity MUST satisfy the following properties: - its `actor` property is the authority - its authenticity can be asserted - its `object` property is the reply under consideration @@ -166,11 +183,11 @@ Because it is unrealistic to expect all implementations and deployments to imple ## Security considerations -By not adding a hash or copy of the reply in the `Accept` activity, malicious actors could exploit this in a split horizon setting, sending different versions of the same activity to different actors. This is, however, already a concern in pretty much all contexts in ActivityPub, and enshrining that information in the `Accept` activity would have many drawbacks: +By not adding a hash or copy of the reply in the `ApproveReply` activity, malicious actors could exploit this in a split horizon setting, sending different versions of the same activity to different actors. This is, however, already a concern in pretty much all contexts in ActivityPub, and enshrining that information in the `ApproveReply` activity would have many drawbacks: - significantly more complex implementation - inability to change the JSON-LD representation after the fact -- possibly leaking private information if the `Accept` activity is publicly dereferenceable +- possibly leaking private information if the `ApproveReply` activity is publicly dereferenceable ## Implementations