From 195be1afead7f04dff83aa8287ea2a0750dbd80b Mon Sep 17 00:00:00 2001 From: Terence Eden Date: Mon, 26 Feb 2024 19:56:55 +0000 Subject: [PATCH] General tidy up --- index.php | 96 +++++++++++++++++++++++++++++-------------------------- 1 file changed, 51 insertions(+), 45 deletions(-) diff --git a/index.php b/index.php index db7e929..1ba614a 100644 --- a/index.php +++ b/index.php @@ -18,7 +18,9 @@ */ // Preamble: Set your details here - // This is where you set up your account's name and bio. You also need to provide a public/private keypair. The posting page is protected with a password that also needs to be set here. + // This is where you set up your account's name and bio. + // You also need to provide a public/private keypair. + // The posting page is protected with a password that also needs to be set here. // Set up the Actor's information // Edit these: @@ -48,17 +50,19 @@ $getData = print_r( $_GET, true ); $filesData = print_r( $_FILES, true ); $input = file_get_contents( "php://input" ); - $body = json_decode( $input, true ); + $body = json_decode( $input,true ); $bodyData = print_r( $body, true ); $requestData = print_r( $_REQUEST, true ); $serverData = print_r( $_SERVER, true ); + !empty( $_GET["path"] ) ? $path = $_GET["path"] : $path = "/"; // Get the type of request - used in the log filename if ( isset( $body["type"] ) ) { - // Sanitise type to only include letter - $type = " " . preg_replace( '/[^a-zA-Z]/', '', $body["type"] ); + // Sanitise before using it in a filename + $type = " " . urlencode( $body["type"] ); } else { - $type = ""; + // Sanitise the path requested + $type = " " . urlencode( $path ); } // Create a timestamp for the filename @@ -85,7 +89,6 @@ // Routing: // The .htaccess changes /whatever to /?path=whatever // This runs the function of the path requested. - !empty( $_GET["path"] ) ? $path = $_GET["path"] : home(); switch ($path) { case ".well-known/webfinger": webfinger(); // Mandatory. Static. @@ -94,20 +97,22 @@ case "following": following(); // Mandatory. Static case "followers": - followers(); // Mandatory. Could be dynamic + followers(); // Mandatory. Can be dynamic case "inbox": inbox(); // Mandatory. Only accepts follow requests. case "write": write(); // User interface for writing posts - case "send": // API for posting content to the Fediverse - send(); - case "outbox": // Optional. Dynamic. - outbox(); + case "send": + send(); // API for posting content to the Fediverse + case "outbox": + outbox(); // Optional. Dynamic. + case "/": + home(); // Optional. Can be dynamic default: die(); } - // The [WebFinger Protocol](https://docs.joinmastodon.org/spec/webfinger/) is used to identify accounts. + // The WebFinger Protocol is used to identify accounts. // It is requested with `example.com/.well-known/webfinger?resource=acct:username@example.com` // This server only has one user, so it ignores the query string and always returns the same details. function webfinger() { @@ -150,7 +155,7 @@ "url" => "https://{$server}/{$username}", "manuallyApprovesFollowers" => true, "discoverable" => true, - "published" => "2024-02-12T11:51:00Z", + "published" => "2024-02-29T12:34:00Z", "icon" => [ "type" => "Image", "mediaType" => "image/png", @@ -210,8 +215,7 @@ // The `/inbox` is the main server. It receives all requests. // This server only responds to "Follow" requests. // A remote server sends a follow request which is a JSON file saying who they are. - // This code does not cryptographically validate the headers of the received message. - // The name of the remote user's server is saved to a file so that future messages can be delivered to it. + // 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. function inbox() { global $body, $server, $username, $key_private; @@ -228,8 +232,8 @@ if ( "Follow" != $inbox_type ) { die(); } // Get the parameters - $follower_id = $inbox_message["id"]; - $follower_actor = $inbox_message["actor"]; + $follower_id = $inbox_message["id"]; // E.g. https://mastodon.social/(unique id) + $follower_actor = $inbox_message["actor"]; // E.g. https://mastodon.social/users/Edent $follower_host = parse_url( $follower_actor, PHP_URL_HOST ); $follower_path = parse_url( $follower_actor, PHP_URL_PATH ); @@ -242,7 +246,7 @@ // Request the JSON representation of the the user $ch = curl_init( $follower_actor ); - // Get the signed headers + // Generate signed headers for this request $headers = generate_signed_headers( null, $follower_host, $follower_path, "GET" ); // Set cURL options @@ -302,7 +306,7 @@ $ch = curl_init( $follower_inbox ); curl_setopt( $ch, CURLOPT_RETURNTRANSFER, true ); curl_setopt( $ch, CURLOPT_CUSTOMREQUEST, "POST" ); - curl_setopt( $ch, CURLOPT_POSTFIELDS, json_encode($message) ); + curl_setopt( $ch, CURLOPT_POSTFIELDS, json_encode( $message ) ); curl_setopt( $ch, CURLOPT_HTTPHEADER, $headers ); curl_exec( $ch ); @@ -330,7 +334,8 @@ // Headers: // Every message that your server sends needs to be cryptographically signed with your Private Key. - // This is a complicated process. Please read https://blog.joinmastodon.org/2018/07/how-to-make-friends-and-verify-requests/ for more information. + // This is a complicated process. + // Please read https://blog.joinmastodon.org/2018/07/how-to-make-friends-and-verify-requests/ for more information. function generate_signed_headers( $message, $host, $path, $method ) { global $server, $username, $key_private; @@ -344,7 +349,6 @@ $date = date( "D, d M Y H:i:s \G\M\T" ); // There are subtly different signing requirements for POST and GET - // GET does not require a digest if ( "POST" == $method ) { // Encode the message object to JSON $message_json = json_encode( $message ); @@ -369,14 +373,14 @@ // Full signature header $signature_header = 'keyId="' . $keyId . '",algorithm="rsa-sha256",headers="(request-target) host date digest",signature="' . $signature_b64 . '"'; - // Header for POST reply + // Header for POST request $headers = array( - "Host: {$host}", - "Date: {$date}", - "Digest: SHA-256={$digest}", - "Signature: {$signature_header}", + "Host: {$host}", + "Date: {$date}", + "Digest: SHA-256={$digest}", + "Signature: {$signature_header}", "Content-Type: application/activity+json", - "Accept: application/activity+json", + "Accept: application/activity+json", ); } else if ( "GET" == $method ) { // Sign the path, host, date - NO DIGEST @@ -396,7 +400,7 @@ // Full signature header $signature_header = 'keyId="' . $keyId . '",algorithm="rsa-sha256",headers="(request-target) host date",signature="' . $signature_b64 . '"'; - // Header for POST reply + // Header for GET request $headers = array( "Host: {$host}", "Date: {$date}", @@ -435,8 +439,10 @@ echo <<< HTML

This site is a basic ActivityPub server designed to be a lightweight educational tool.