Delete old messages on update - UUID changes

UUID now based on hash of ID. This allows them to be deleted when updated / undone, etc
main
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() {
global $body, $server, $username, $key_private, $directories;
// Get the message and type
// Get the message, type, and ID
$inbox_message = $body;
$inbox_type = $inbox_message["type"];
$inbox_id = $inbox_message["id"];
// If this is an Undo or Delete message, try to process it
if ( "Undo" == $inbox_type || "Delete" == $inbox_type ) {
// 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.
@ -293,7 +293,7 @@
if ( !verifyHTTPSignature() ) { die(); }
// If the message is valid, save the message in `/data/inbox/`
$uuid = uuid();
$uuid = uuid( $inbox_message );
$inbox_filename = $uuid . "." . urlencode( $inbox_type ) . ".json";
file_put_contents( $directories["inbox"] . "/{$inbox_filename}", json_encode( $inbox_message ) );
@ -345,14 +345,30 @@
// Every message sent should have a unique ID.
// This can be anything you like. Some servers use a random number.
// I prefer a date-sortable string.
function uuid() {
return sprintf( "%08x-%04x-%04x-%04x-%012x",
time(),
mt_rand(0, 0xffff),
mt_rand(0, 0xffff),
mt_rand(0, 0x3fff) | 0x8000,
mt_rand(0, 0xffffffffffff)
);
function uuid( $message = null) {
// UUIDs that this server *sends* will be [timestamp]-[random]
// 65e99ab4-5d43-f074-b43e-463f9c5cf05c
if ( is_null( $message ) ) {
return sprintf( "%08x-%04x-%04x-%04x-%012x",
time(),
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:
@ -1673,7 +1689,7 @@ HTML;
}
// Perform the Undo action requested
function undo( $message) {
function undo( $message ) {
global $server, $directories;
// Validate HTTP Message Signature
@ -1681,27 +1697,44 @@ HTML;
// Get some basic data
$type = $message["type"];
$id = $message["id"];
// The thing being undone
$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
$inbox_files = glob( $directories["inbox"] . "/*.json" );
foreach ( $inbox_files as $inbox_file ) {
// Load the contents
$inbox_item = json_decode( file_get_contents( $inbox_file ), true );
// Find the ID
if ( isset( $inbox_item["object"]["id"] ) ) {
$inbox_id = $inbox_item["object"]["id"];
} else if ( isset ($inbox_item["id"] )) {
$inbox_id = $inbox_item["id"];
// Filenames are `data/inbox/[date]-[SHA256 hash0].[Type].json
// Find the position of the first hyphen and the first dot
$hyphenPosition = strpos( $inbox_file, '-' );
$dotPosition = strpos( $inbox_file, '.' );
if ( $hyphenPosition !== false && $dotPosition !== false ) {
// Extract the text between the hyphen and the first dot
$file_id_hash = substr( $inbox_file, $hyphenPosition + 1, $dotPosition - $hyphenPosition - 1);
} else {
// Ignore the file and move to the next.
continue;
}
// If this has the same ID as the item being undone
if ( $inbox_id == $object_id ) {
// If this has the same hash as the item being undone
if ( $object_id_hash == $file_id_hash ) {
// Delete the file
unlink( $inbox_file );
@ -1716,14 +1749,12 @@ HTML;
}
}
// If the message is valid, save the message in `/data/inbox/`
$uuid = uuid();
$uuid = uuid( $message );
$filename = $uuid . "." . urlencode( $type ) . ".json";
file_put_contents( $directories["inbox"] . "/{$filename}", json_encode( $message ) );
}
// "One to stun, two to kill, three to make sure"
die();
die();