Delete old messages on update - UUID changes

UUID now based on hash of ID. This allows them to be deleted when updated / undone, etc
merge-requests/5/head
Terence Eden 2024-03-08 11:44:40 +00:00
rodzic 3231a4fc52
commit 2e3968c8f0
1 zmienionych plików z 59 dodań i 28 usunięć

Wyświetl plik

@ -244,17 +244,17 @@
function inbox() { function inbox() {
global $body, $server, $username, $key_private, $directories; global $body, $server, $username, $key_private, $directories;
// Get the message and type // Get the message, type, and ID
$inbox_message = $body; $inbox_message = $body;
$inbox_type = $inbox_message["type"]; $inbox_type = $inbox_message["type"];
$inbox_id = $inbox_message["id"];
// If this is an Undo or Delete message, try to process it // If this is an Undo, Delete, or Update message, try to process it
if ( "Undo" == $inbox_type || "Delete" == $inbox_type ) { if ( "Undo" == $inbox_type || "Delete" == $inbox_type || "Update" == $inbox_type ) {
undo( $inbox_message ); undo( $inbox_message );
die(); die();
} }
// Messages to ignore. // Messages to ignore.
// Some servers are very chatty. They send lots of irrelevant messages. // Some servers are very chatty. They send lots of irrelevant messages.
// Before even bothering to validate them, we can delete them. // Before even bothering to validate them, we can delete them.
@ -293,7 +293,7 @@
if ( !verifyHTTPSignature() ) { die(); } if ( !verifyHTTPSignature() ) { die(); }
// If the message is valid, save the message in `/data/inbox/` // If the message is valid, save the message in `/data/inbox/`
$uuid = uuid(); $uuid = uuid( $inbox_message );
$inbox_filename = $uuid . "." . urlencode( $inbox_type ) . ".json"; $inbox_filename = $uuid . "." . urlencode( $inbox_type ) . ".json";
file_put_contents( $directories["inbox"] . "/{$inbox_filename}", json_encode( $inbox_message ) ); file_put_contents( $directories["inbox"] . "/{$inbox_filename}", json_encode( $inbox_message ) );
@ -345,14 +345,30 @@
// Every message sent should have a unique ID. // Every message sent should have a unique ID.
// This can be anything you like. Some servers use a random number. // This can be anything you like. Some servers use a random number.
// I prefer a date-sortable string. // I prefer a date-sortable string.
function uuid() { function uuid( $message = null) {
return sprintf( "%08x-%04x-%04x-%04x-%012x", // UUIDs that this server *sends* will be [timestamp]-[random]
time(), // 65e99ab4-5d43-f074-b43e-463f9c5cf05c
mt_rand(0, 0xffff), if ( is_null( $message ) ) {
mt_rand(0, 0xffff), return sprintf( "%08x-%04x-%04x-%04x-%012x",
mt_rand(0, 0x3fff) | 0x8000, time(),
mt_rand(0, 0xffffffffffff) mt_rand(0, 0xffff),
); mt_rand(0, 0xffff),
mt_rand(0, 0x3fff) | 0x8000,
mt_rand(0, 0xffffffffffff)
);
} else {
// UUIDs that this server *saves* will be [timestamp]-[hash of message ID]
// 65eadace-8f434346648f6b96df89dda901c5176b10a6d83961dd3c1ac88b59b2dc327aa4
// The message might have its own object
if ( isset( $message["object"]["id"] ) ) {
$id = $message["object"]["id"];
} else {
$id = $message["id"];
}
return sprintf( "%08x", time() ) . "-" . hash( "sha256", $id );
}
} }
// Headers: // Headers:
@ -1673,7 +1689,7 @@ HTML;
} }
// Perform the Undo action requested // Perform the Undo action requested
function undo( $message) { function undo( $message ) {
global $server, $directories; global $server, $directories;
// Validate HTTP Message Signature // Validate HTTP Message Signature
@ -1681,27 +1697,44 @@ HTML;
// Get some basic data // Get some basic data
$type = $message["type"]; $type = $message["type"];
$id = $message["id"];
// The thing being undone // The thing being undone
$object = $message["object"]; $object = $message["object"];
$object_id = $object["id"];
$object_type = $object["type"]; // Does the thing being undone have its own ID or Type?
if ( isset( $object["id"] ) ) {
$object_id = $object["id"];
} else {
$object_id = $id;
}
if ( isset( $object["type"] ) ) {
$object_type = $object["type"];
} else {
$object_type = $type;
}
// Inbox items are stored as the hash of the original ID
$object_id_hash = hash( "sha256", $object_id );
// Find all the inbox messages which have that ID // Find all the inbox messages which have that ID
$inbox_files = glob( $directories["inbox"] . "/*.json" ); $inbox_files = glob( $directories["inbox"] . "/*.json" );
foreach ( $inbox_files as $inbox_file ) { foreach ( $inbox_files as $inbox_file ) {
// Load the contents // Filenames are `data/inbox/[date]-[SHA256 hash0].[Type].json
$inbox_item = json_decode( file_get_contents( $inbox_file ), true ); // Find the position of the first hyphen and the first dot
// Find the ID $hyphenPosition = strpos( $inbox_file, '-' );
if ( isset( $inbox_item["object"]["id"] ) ) { $dotPosition = strpos( $inbox_file, '.' );
$inbox_id = $inbox_item["object"]["id"];
} else if ( isset ($inbox_item["id"] )) { if ( $hyphenPosition !== false && $dotPosition !== false ) {
$inbox_id = $inbox_item["id"]; // Extract the text between the hyphen and the first dot
$file_id_hash = substr( $inbox_file, $hyphenPosition + 1, $dotPosition - $hyphenPosition - 1);
} else { } else {
// Ignore the file and move to the next.
continue; continue;
} }
// If this has the same ID as the item being undone // If this has the same hash as the item being undone
if ( $inbox_id == $object_id ) { if ( $object_id_hash == $file_id_hash ) {
// Delete the file // Delete the file
unlink( $inbox_file ); unlink( $inbox_file );
@ -1716,14 +1749,12 @@ HTML;
} }
} }
// If the message is valid, save the message in `/data/inbox/` // If the message is valid, save the message in `/data/inbox/`
$uuid = uuid(); $uuid = uuid( $message );
$filename = $uuid . "." . urlencode( $type ) . ".json"; $filename = $uuid . "." . urlencode( $type ) . ".json";
file_put_contents( $directories["inbox"] . "/{$filename}", json_encode( $message ) ); file_put_contents( $directories["inbox"] . "/{$filename}", json_encode( $message ) );
} }
// "One to stun, two to kill, three to make sure" // "One to stun, two to kill, three to make sure"
die(); die();
die(); die();