From ccdcca3dae5303ad02240e1f5d698234e078ed29 Mon Sep 17 00:00:00 2001 From: Terence Eden Date: Thu, 14 Mar 2024 22:08:16 +0000 Subject: [PATCH] Better logic for ignoring spurious posts --- index.php | 176 +++++++++++++++++++++++++++++------------------------- 1 file changed, 96 insertions(+), 80 deletions(-) diff --git a/index.php b/index.php index f3ad441..e278efd 100644 --- a/index.php +++ b/index.php @@ -247,97 +247,113 @@ // Get the message, type, and ID $inbox_message = $body; $inbox_type = $inbox_message["type"]; - $inbox_id = $inbox_message["id"]; - - // If this is an Undo, Delete, or Update message, try to process it - if ( "Undo" == $inbox_type || "Delete" == $inbox_type || "Update" == $inbox_type ) { - undo( $inbox_message ); - die(); - } - - // Messages to ignore. - // Some servers are very chatty. They send lots of irrelevant messages. - // Before even bothering to validate them, we can delete them. - - // Messages from accounts which aren't being followed. - // Some servers send delete messages about users we don't follow. - // Lemmy sends messages even after unfollowing or blocking a channel - - // Get a list of every account we follow - // Get all the files - $following_files = glob( $directories["following"] . "/*.json"); - - // Create a list of all accounts being followed - $following_ids = array(); - foreach ( $following_files as $following_file ) { - $following = json_decode( file_get_contents( $following_file ), true ); - $following_ids[] = $following["id"]; - } - - // Is this from someone we follow? - in_array( $inbox_message["actor"], $following_ids ) ? $from_following = true: $from_following = false; - - // Has the user has been specifically CC'd? - if ( isset( $inbox_message["cc"] ) ) { - $reply = in_array( "https://{$server}/{$username}", $inbox_message["cc"] ); - } else { - $reply = false; - } - - if ( !$reply && !$from_following ) { - // Don't bother processing it at all. - die(); - } - - // Validate HTTP Message Signature - if ( !verifyHTTPSignature() ) { die(); } - - // If the message is valid, save the message in `/data/inbox/` - $uuid = uuid( $inbox_message ); - $inbox_filename = $uuid . "." . urlencode( $inbox_type ) . ".json"; - file_put_contents( $directories["inbox"] . "/{$inbox_filename}", json_encode( $inbox_message ) ); // This inbox only sends responses to follow requests. // A remote server sends the inbox a follow request which is a JSON file saying who they are. // The details of the remote user's server is saved to a file so that future messages can be delivered to the follower. // An accept request is cryptographically signed and POST'd back to the remote server. - if ( "Follow" != $inbox_type ) { die(); } + if ( "Follow" == $inbox_type ) { + // Validate HTTP Message Signature + if ( !verifyHTTPSignature() ) { die(); } - // Get the parameters - $follower_id = $inbox_message["id"]; // E.g. https://mastodon.social/(unique id) - $follower_actor = $inbox_message["actor"]; // E.g. https://mastodon.social/users/Edent - - // Get the actor's profile as JSON - $follower_actor_details = getDataFromURl( $follower_actor ); + // Get the parameters + $follower_id = $inbox_message["id"]; // E.g. https://mastodon.social/(unique id) + $follower_actor = $inbox_message["actor"]; // E.g. https://mastodon.social/users/Edent + + // Get the actor's profile as JSON + $follower_actor_details = getDataFromURl( $follower_actor ); - // Save the actor's data in `/data/followers/` - $follower_filename = urlencode( $follower_actor ); - file_put_contents( $directories["followers"] . "/{$follower_filename}.json", json_encode( $follower_actor_details ) ); - - // Get the new follower's Inbox - $follower_inbox = $follower_actor_details["inbox"]; + // Save the actor's data in `/data/followers/` + $follower_filename = urlencode( $follower_actor ); + file_put_contents( $directories["followers"] . "/{$follower_filename}.json", json_encode( $follower_actor_details ) ); + + // Get the new follower's Inbox + $follower_inbox = $follower_actor_details["inbox"]; - // Response Message ID - // This isn't used for anything important so could just be a random number - $guid = uuid(); + // Response Message ID + // This isn't used for anything important so could just be a random number + $guid = uuid(); - // Create the Accept message to the new follower - $message = [ - "@context" => "https://www.w3.org/ns/activitystreams", - "id" => "https://{$server}/{$guid}", - "type" => "Accept", - "actor" => "https://{$server}/{$username}", - "object" => [ + // Create the Accept message to the new follower + $message = [ "@context" => "https://www.w3.org/ns/activitystreams", - "id" => $follower_id, - "type" => $inbox_type, - "actor" => $follower_actor, - "object" => "https://{$server}/{$username}", - ] - ]; + "id" => "https://{$server}/{$guid}", + "type" => "Accept", + "actor" => "https://{$server}/{$username}", + "object" => [ + "@context" => "https://www.w3.org/ns/activitystreams", + "id" => $follower_id, + "type" => $inbox_type, + "actor" => $follower_actor, + "object" => "https://{$server}/{$username}", + ] + ]; + + // The Accept is POSTed to the inbox on the server of the user who requested the follow + sendMessageToSingle( $follower_inbox, $message ); + } else { + // Messages to ignore. + // Some servers are very chatty. They send lots of irrelevant messages. + // Before even bothering to validate them, we can delete them. + + // Messages from accounts which aren't being followed. + // Some servers send delete messages about users we don't follow. + // Lemmy sends messages even after unfollowing or blocking a channel + + // Get a list of every account we follow + // Get all the files + $following_files = glob( $directories["following"] . "/*.json"); + + // Create a list of all accounts being followed + $following_ids = array(); + foreach ( $following_files as $following_file ) { + $following = json_decode( file_get_contents( $following_file ), true ); + $following_ids[] = $following["id"]; + } + + // Is this from someone we follow? + in_array( $inbox_message["actor"], $following_ids ) ? $from_following = true: $from_following = false; + + // Get a list of every account following us + // Get all the files + $followers_files = glob( $directories["followers"] . "/*.json"); + + // Create a list of all accounts being followed + $followers_ids = array(); + foreach ( $followers_files as $follower_file ) { + $follower = json_decode( file_get_contents( $follower_file ), true ); + $followers_ids[] = $follower["id"]; + } + + // Is this from someone following us? + in_array( $inbox_message["actor"], $followers_ids ) ? $from_follower = true: $from_follower = false; + + // Has the user has been specifically CC'd? + if ( isset( $inbox_message["cc"] ) ) { + $reply = in_array( "https://{$server}/{$username}", $inbox_message["cc"] ); + } else { + $reply = false; + } + + if ( !$reply && !$from_following && !$from_follower ) { + // Don't bother processing it at all. + die(); + } + + // If this is an Undo, Delete, or Update message, try to process it + if ( "Undo" == $inbox_type || "Delete" == $inbox_type || "Update" == $inbox_type ) { + undo( $inbox_message ); + } + + // Validate HTTP Message Signature + if ( !verifyHTTPSignature() ) { die(); } + } + + // If the message is valid, save the message in `/data/inbox/` + $uuid = uuid( $inbox_message ); + $inbox_filename = $uuid . "." . urlencode( $inbox_type ) . ".json"; + file_put_contents( $directories["inbox"] . "/{$inbox_filename}", json_encode( $inbox_message ) ); - // The Accept is POSTed to the inbox on the server of the user who requested the follow - sendMessageToSingle( $follower_inbox, $message ); die(); }