From 0f4155ed0eab3c903447853628883195b5e016d3 Mon Sep 17 00:00:00 2001 From: Matthias Pfefferle Date: Thu, 10 Apr 2025 13:09:39 +0200 Subject: [PATCH 01/24] Comment: Send announce for all new comments Supersedes #1515 and fixes #1001 --- includes/class-comment.php | 34 ++++++++++++++++++++++ includes/collection/class-interactions.php | 5 ++-- 2 files changed, 37 insertions(+), 2 deletions(-) diff --git a/includes/class-comment.php b/includes/class-comment.php index 0f989376c6..aa9edd7a04 100644 --- a/includes/class-comment.php +++ b/includes/class-comment.php @@ -33,6 +33,8 @@ public static function init() { \add_action( 'update_option_activitypub_allow_likes', array( self::class, 'maybe_update_comment_counts' ), 10, 2 ); \add_action( 'update_option_activitypub_allow_reposts', array( self::class, 'maybe_update_comment_counts' ), 10, 2 ); \add_filter( 'pre_wp_update_comment_count_now', array( static::class, 'pre_wp_update_comment_count_now' ), 10, 3 ); + + \add_action( 'transition_comment_status', array( self::class, 'maybe_announce_interaction' ), 20, 3 ); } /** @@ -804,6 +806,38 @@ public static function pre_wp_update_comment_count_now( $new_count, $old_count, return $new_count; } + /** + * Announce an interaction. + * + * @param string $new_status The new comment status. + * @param string $old_status The old comment status. + * @param \WP_Comment $comment The comment object. + */ + public static function maybe_announce_interaction( $new_status, $old_status, $comment ) { + if ( defined( 'WP_IMPORTING' ) && WP_IMPORTING ) { + return; + } + + if ( 'approved' !== $new_status || 'approved' === $old_status ) { + return; + } + + $comment = \get_comment( $comment ); + + if ( ! self::was_received( $comment ) ) { + return; + } + + // get activity from comment meta + $activity = \get_comment_meta( $comment->comment_ID, '_activitypub_activity', true ); + + if ( ! $activity ) { + return; + } + + add_to_outbox( $activity, 'Announce', Actors::BLOG_USER_ID, ACTIVITYPUB_CONTENT_VISIBILITY_PUBLIC ); + } + /** * Check if a comment type is enabled. * diff --git a/includes/collection/class-interactions.php b/includes/collection/class-interactions.php index dc1f94170e..f40a9c7065 100644 --- a/includes/collection/class-interactions.php +++ b/includes/collection/class-interactions.php @@ -270,8 +270,9 @@ public static function activity_to_comment( $activity ) { 'comment_type' => 'comment', 'comment_author_email' => $webfinger, 'comment_meta' => array( - 'source_id' => \esc_url_raw( object_to_uri( $activity['object'] ) ), - 'protocol' => 'activitypub', + 'source_id' => \esc_url_raw( object_to_uri( $activity['object'] ) ), + 'protocol' => 'activitypub', + '_activitypub_activity' => $activity, ), ); From bb1ad46c9bd7c952c5f9bef8b5f6960d7b961b34 Mon Sep 17 00:00:00 2001 From: Automattic Bot Date: Thu, 10 Apr 2025 14:12:15 +0300 Subject: [PATCH 02/24] Add changelog --- .github/changelog/1562-from-description | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 .github/changelog/1562-from-description diff --git a/.github/changelog/1562-from-description b/.github/changelog/1562-from-description new file mode 100644 index 0000000000..acf5ca9479 --- /dev/null +++ b/.github/changelog/1562-from-description @@ -0,0 +1,4 @@ +Significance: minor +Type: added + +Incoming interactions create an Announce activity so other instances get notified about it. From adab3162dd7d8b877d1f870cb2eaf534afdcb6a7 Mon Sep 17 00:00:00 2001 From: Matthias Pfefferle Date: Thu, 10 Apr 2025 13:14:20 +0200 Subject: [PATCH 03/24] phpcs fix --- includes/class-comment.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/includes/class-comment.php b/includes/class-comment.php index aa9edd7a04..69c4584475 100644 --- a/includes/class-comment.php +++ b/includes/class-comment.php @@ -828,7 +828,7 @@ public static function maybe_announce_interaction( $new_status, $old_status, $co return; } - // get activity from comment meta + // Get activity from comment meta. $activity = \get_comment_meta( $comment->comment_ID, '_activitypub_activity', true ); if ( ! $activity ) { From c069473ebdedef7904503a0c031103f8fcf2b00c Mon Sep 17 00:00:00 2001 From: Matthias Pfefferle Date: Thu, 10 Apr 2025 13:32:49 +0200 Subject: [PATCH 04/24] activities are normally not in reply to --- includes/activity/class-activity.php | 4 ---- 1 file changed, 4 deletions(-) diff --git a/includes/activity/class-activity.php b/includes/activity/class-activity.php index f9da8b26fa..7eade851be 100644 --- a/includes/activity/class-activity.php +++ b/includes/activity/class-activity.php @@ -233,10 +233,6 @@ public function pre_fill_activity_from_object() { $this->set( 'actor', $object->get_attributed_to() ); } - if ( $object->get_in_reply_to() && ! $this->get_in_reply_to() ) { - $this->set( 'in_reply_to', $object->get_in_reply_to() ); - } - if ( $object->get_id() && ! $this->get_id() ) { $id = strtok( $object->get_id(), '#' ); if ( $object->get_updated() ) { From b1d461c7484fd088cf7583aaefbfa5fa12c4d4cd Mon Sep 17 00:00:00 2001 From: Matthias Pfefferle Date: Thu, 10 Apr 2025 13:36:52 +0200 Subject: [PATCH 05/24] Set Actor URL! --- includes/collection/class-outbox.php | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/includes/collection/class-outbox.php b/includes/collection/class-outbox.php index f610ea6b56..ba4c8076e7 100644 --- a/includes/collection/class-outbox.php +++ b/includes/collection/class-outbox.php @@ -36,6 +36,10 @@ public static function add( Activity $activity, $user_id, $visibility = ACTIVITY $object_id = self::get_object_id( $activity ); $title = self::get_object_title( $activity->get_object() ); + if ( ! $activity->get_actor() ) { + $activity->set_actor( Actors::get_by_id( $user_id )->get_id() ); + } + $outbox_item = array( 'post_type' => self::POST_TYPE, 'post_title' => sprintf( From 3fcdf0fed03e1439354a07c34c99e24eedf26e6c Mon Sep 17 00:00:00 2001 From: Matthias Pfefferle Date: Thu, 10 Apr 2025 13:38:37 +0200 Subject: [PATCH 06/24] backwards compatibility --- includes/collection/class-outbox.php | 3 +++ 1 file changed, 3 insertions(+) diff --git a/includes/collection/class-outbox.php b/includes/collection/class-outbox.php index ba4c8076e7..cf1dff89fd 100644 --- a/includes/collection/class-outbox.php +++ b/includes/collection/class-outbox.php @@ -217,6 +217,9 @@ public static function get_activity( $outbox_item ) { if ( $activity_object['type'] === $type ) { $activity = Activity::init_from_array( $activity_object ); + if ( ! $activity->get_actor() ) { + $activity->set_actor( $actor->get_id() ); + } } else { $activity = new Activity(); $activity->set_type( $type ); From ec02ba3b519a4a62d7f578c44b26643c296c8c31 Mon Sep 17 00:00:00 2001 From: Matthias Pfefferle Date: Thu, 10 Apr 2025 13:47:49 +0200 Subject: [PATCH 07/24] AI test fail --- tests/includes/collection/class-test-outbox.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/tests/includes/collection/class-test-outbox.php b/tests/includes/collection/class-test-outbox.php index fc4ee13354..e03117468e 100644 --- a/tests/includes/collection/class-test-outbox.php +++ b/tests/includes/collection/class-test-outbox.php @@ -115,7 +115,7 @@ public function activity_object_provider() { ), 'Create', 1, - '{"@context":["https:\/\/www.w3.org\/ns\/activitystreams",{"Hashtag":"as:Hashtag","sensitive":"as:sensitive"}],"id":"http:\/\/example.org\/?post_type=ap_outbox\u0026p=351","type":"Create","to":["https:\/\/www.w3.org\/ns\/activitystreams#Public"],"object":{"id":"https:\/\/example.com\/1","type":"Note","content":"\u003Cp\u003EThis is a note\u003C\/p\u003E","contentMap":{"en":"\u003Cp\u003EThis is a note\u003C\/p\u003E"},"to":["https:\/\/www.w3.org\/ns\/activitystreams#Public"],"mediaType":"text\/html"}}', + '{"@context":["https:\/\/www.w3.org\/ns\/activitystreams",{"Hashtag":"as:Hashtag","sensitive":"as:sensitive"}],"actor":"http:\/\/example.org\/?author=1","id":"http:\/\/example.org\/?post_type=ap_outbox\u0026p=351","type":"Create","to":["https:\/\/www.w3.org\/ns\/activitystreams#Public"],"object":{"id":"https:\/\/example.com\/1","type":"Note","content":"\u003Cp\u003EThis is a note\u003C\/p\u003E","contentMap":{"en":"\u003Cp\u003EThis is a note\u003C\/p\u003E"},"to":["https:\/\/www.w3.org\/ns\/activitystreams#Public"],"mediaType":"text\/html"}}', ), array( array( @@ -126,7 +126,7 @@ public function activity_object_provider() { ), 'Create', 2, - '{"@context":["https:\/\/www.w3.org\/ns\/activitystreams",{"Hashtag":"as:Hashtag","sensitive":"as:sensitive"}],"id":"http:\/\/example.org\/?post_type=ap_outbox\u0026p=352","type":"Create","to":["https:\/\/www.w3.org\/ns\/activitystreams#Public"],"object":{"id":"https:\/\/example.com\/2","type":"Note","content":"\u003Cp\u003EThis is another note\u003C\/p\u003E","contentMap":{"en":"\u003Cp\u003EThis is another note\u003C\/p\u003E"},"to":["https:\/\/www.w3.org\/ns\/activitystreams#Public"],"mediaType":"text\/html"}}', + '{"@context":["https:\/\/www.w3.org\/ns\/activitystreams",{"Hashtag":"as:Hashtag","sensitive":"as:sensitive"}],"actor":"http:\/\/example.org\/?author=0","id":"http:\/\/example.org\/?post_type=ap_outbox\u0026p=352","type":"Create","to":["https:\/\/www.w3.org\/ns\/activitystreams#Public"],"object":{"id":"https:\/\/example.com\/2","type":"Note","content":"\u003Cp\u003EThis is another note\u003C\/p\u003E","contentMap":{"en":"\u003Cp\u003EThis is another note\u003C\/p\u003E"},"to":["https:\/\/www.w3.org\/ns\/activitystreams#Public"],"mediaType":"text\/html"}}', ), array( Event::init_from_array( @@ -163,7 +163,7 @@ public function activity_object_provider() { ), 'Create', 1, - '{"@context":["https:\/\/schema.org\/","https:\/\/www.w3.org\/ns\/activitystreams",{"pt":"https:\/\/joinpeertube.org\/ns#","mz":"https:\/\/joinmobilizon.org\/ns#","status":"http:\/\/www.w3.org\/2002\/12\/cal\/ical#status","commentsEnabled":"pt:commentsEnabled","isOnline":"mz:isOnline","timezone":"mz:timezone","participantCount":"mz:participantCount","anonymousParticipationEnabled":"mz:anonymousParticipationEnabled","joinMode":{"@id":"mz:joinMode","@type":"mz:joinModeType"},"externalParticipationUrl":{"@id":"mz:externalParticipationUrl","@type":"schema:URL"},"repliesModerationOption":{"@id":"mz:repliesModerationOption","@type":"@vocab"},"contacts":{"@id":"mz:contacts","@type":"@id"}}],"id":"http:\/\/example.org\/?post_type=ap_outbox\u0026p=353","type":"Create","to":["https:\/\/www.w3.org\/ns\/activitystreams#Public"],"object":{"id":"https:\/\/example.com\/3","type":"Event","content":"\u003Cp\u003EYou should not miss this Event!\u003C\/p\u003E","contentMap":{"en":"\u003Cp\u003EYou should not miss this Event!\u003C\/p\u003E"},"name":"WP Test Event","nameMap":{"en":"WP Test Event"},"endTime":"2030-02-29T17:00:00+01:00","location":[{"id":"https:\/\/example.com\/place\/1","type":"Place","attributedTo":"https:\/\/wp-test.event-federation.eu\/@test","name":"Fediverse Place","address":{"type":"PostalAddress","addressCountry":"FediCountry","addressLocality":"FediTown","postalCode":"1337","streetAddress":"FediStreet"}},{"type":"VirtualLocation","url":"https:\/\/example.com\/VirtualMeetingRoom"}],"startTime":"2030-02-29T16:00:00+01:00","to":["https:\/\/www.w3.org\/ns\/activitystreams#Public"],"mediaType":"text\/html","timezone":"Europe\/Vienna","category":"MOVEMENTS_POLITICS","joinMode":"external"}}', + '{"@context":["https:\/\/schema.org\/","https:\/\/www.w3.org\/ns\/activitystreams",{"pt":"https:\/\/joinpeertube.org\/ns#","mz":"https:\/\/joinmobilizon.org\/ns#","status":"http:\/\/www.w3.org\/2002\/12\/cal\/ical#status","commentsEnabled":"pt:commentsEnabled","isOnline":"mz:isOnline","timezone":"mz:timezone","participantCount":"mz:participantCount","anonymousParticipationEnabled":"mz:anonymousParticipationEnabled","joinMode":{"@id":"mz:joinMode","@type":"mz:joinModeType"},"externalParticipationUrl":{"@id":"mz:externalParticipationUrl","@type":"schema:URL"},"repliesModerationOption":{"@id":"mz:repliesModerationOption","@type":"@vocab"},"contacts":{"@id":"mz:contacts","@type":"@id"}}],"actor":"http:\/\/example.org\/?author=1","id":"http:\/\/example.org\/?post_type=ap_outbox\u0026p=353","type":"Create","to":["https:\/\/www.w3.org\/ns\/activitystreams#Public"],"object":{"id":"https:\/\/example.com\/3","type":"Event","content":"\u003Cp\u003EYou should not miss this Event!\u003C\/p\u003E","contentMap":{"en":"\u003Cp\u003EYou should not miss this Event!\u003C\/p\u003E"},"name":"WP Test Event","nameMap":{"en":"WP Test Event"},"endTime":"2030-02-29T17:00:00+01:00","location":[{"id":"https:\/\/example.com\/place\/1","type":"Place","attributedTo":"https:\/\/wp-test.event-federation.eu\/@test","name":"Fediverse Place","address":{"type":"PostalAddress","addressCountry":"FediCountry","addressLocality":"FediTown","postalCode":"1337","streetAddress":"FediStreet"}},{"type":"VirtualLocation","url":"https:\/\/example.com\/VirtualMeetingRoom"}],"startTime":"2030-02-29T16:00:00+01:00","to":["https:\/\/www.w3.org\/ns\/activitystreams#Public"],"mediaType":"text\/html","timezone":"Europe\/Vienna","category":"MOVEMENTS_POLITICS","joinMode":"external"}}', ), ); } From 882157827abcbf1c3d6bffd1e8888acb620790af Mon Sep 17 00:00:00 2001 From: Matthias Pfefferle Date: Thu, 10 Apr 2025 14:00:12 +0200 Subject: [PATCH 08/24] lemmy sends 400 for "inbox_timeout" --- includes/class-dispatcher.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/includes/class-dispatcher.php b/includes/class-dispatcher.php index b76f00d1c5..4190c55256 100644 --- a/includes/class-dispatcher.php +++ b/includes/class-dispatcher.php @@ -40,7 +40,7 @@ class Dispatcher { * @see https://github.com/tfredrich/RestApiTutorial.com/blob/fd08b0f67f07450521d143b123cd6e1846cb2e3b/content/advanced/responses/retries.md * @var int[] */ - public static $retry_error_codes = array( 408, 429, 500, 502, 503, 504 ); + public static $retry_error_codes = array( 400, 408, 429, 500, 502, 503, 504 ); /** * Initialize the class, registering WordPress hooks. From ced037c9fdf4a28f8338c72baad4c19f459c4e2a Mon Sep 17 00:00:00 2001 From: Matthias Pfefferle Date: Fri, 11 Apr 2025 14:33:22 +0200 Subject: [PATCH 09/24] move function to scheduler class --- includes/class-comment.php | 34 ---------------------------- includes/scheduler/class-comment.php | 33 +++++++++++++++++++++++++-- 2 files changed, 31 insertions(+), 36 deletions(-) diff --git a/includes/class-comment.php b/includes/class-comment.php index 69c4584475..0f989376c6 100644 --- a/includes/class-comment.php +++ b/includes/class-comment.php @@ -33,8 +33,6 @@ public static function init() { \add_action( 'update_option_activitypub_allow_likes', array( self::class, 'maybe_update_comment_counts' ), 10, 2 ); \add_action( 'update_option_activitypub_allow_reposts', array( self::class, 'maybe_update_comment_counts' ), 10, 2 ); \add_filter( 'pre_wp_update_comment_count_now', array( static::class, 'pre_wp_update_comment_count_now' ), 10, 3 ); - - \add_action( 'transition_comment_status', array( self::class, 'maybe_announce_interaction' ), 20, 3 ); } /** @@ -806,38 +804,6 @@ public static function pre_wp_update_comment_count_now( $new_count, $old_count, return $new_count; } - /** - * Announce an interaction. - * - * @param string $new_status The new comment status. - * @param string $old_status The old comment status. - * @param \WP_Comment $comment The comment object. - */ - public static function maybe_announce_interaction( $new_status, $old_status, $comment ) { - if ( defined( 'WP_IMPORTING' ) && WP_IMPORTING ) { - return; - } - - if ( 'approved' !== $new_status || 'approved' === $old_status ) { - return; - } - - $comment = \get_comment( $comment ); - - if ( ! self::was_received( $comment ) ) { - return; - } - - // Get activity from comment meta. - $activity = \get_comment_meta( $comment->comment_ID, '_activitypub_activity', true ); - - if ( ! $activity ) { - return; - } - - add_to_outbox( $activity, 'Announce', Actors::BLOG_USER_ID, ACTIVITYPUB_CONTENT_VISIBILITY_PUBLIC ); - } - /** * Check if a comment type is enabled. * diff --git a/includes/scheduler/class-comment.php b/includes/scheduler/class-comment.php index 1d63f01e58..b6d4a10be4 100644 --- a/includes/scheduler/class-comment.php +++ b/includes/scheduler/class-comment.php @@ -42,9 +42,12 @@ public static function schedule_comment_activity( $new_status, $old_status, $com } $comment = get_comment( $comment ); + if ( ! $comment ) { + return; + } - // Federate only comments that are written by a registered user. - if ( ! $comment || ! $comment->user_id ) { + if ( ! $comment->user_id ) { + self::maybe_announce_interaction( $new_status, $old_status, $comment ); return; } @@ -77,6 +80,32 @@ public static function schedule_comment_activity( $new_status, $old_status, $com add_to_outbox( $comment, $type, $comment->user_id ); } + /** + * Announce an interaction. + * + * @param string $new_status The new comment status. + * @param string $old_status The old comment status. + * @param \WP_Comment $comment The comment object. + */ + public static function maybe_announce_interaction( $new_status, $old_status, $comment ) { + if ( 'approved' !== $new_status || 'approved' === $old_status ) { + return; + } + + if ( ! self::was_received( $comment ) ) { + return; + } + + // Get activity from comment meta. + $activity = \get_comment_meta( $comment->comment_ID, '_activitypub_activity', true ); + + if ( ! $activity ) { + return; + } + + add_to_outbox( $activity, 'Announce', Actors::BLOG_USER_ID, ACTIVITYPUB_CONTENT_VISIBILITY_PUBLIC ); + } + /** * Schedule Comment Activities on insert. * From c9bdb969b6807c8dfea74b904bf1a7821c5f5c42 Mon Sep 17 00:00:00 2001 From: Matthias Pfefferle Date: Fri, 11 Apr 2025 14:44:13 +0200 Subject: [PATCH 10/24] add blog user to audience --- includes/scheduler/class-comment.php | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/includes/scheduler/class-comment.php b/includes/scheduler/class-comment.php index b6d4a10be4..ef04bd1f40 100644 --- a/includes/scheduler/class-comment.php +++ b/includes/scheduler/class-comment.php @@ -88,6 +88,11 @@ public static function schedule_comment_activity( $new_status, $old_status, $com * @param \WP_Comment $comment The comment object. */ public static function maybe_announce_interaction( $new_status, $old_status, $comment ) { + // Only if we're in both Blog and User modes. + if ( ACTIVITYPUB_ACTOR_AND_BLOG_MODE !== \get_option( 'activitypub_actor_mode', ACTIVITYPUB_ACTOR_MODE ) ) { + return; + } + if ( 'approved' !== $new_status || 'approved' === $old_status ) { return; } @@ -103,7 +108,14 @@ public static function maybe_announce_interaction( $new_status, $old_status, $co return; } - add_to_outbox( $activity, 'Announce', Actors::BLOG_USER_ID, ACTIVITYPUB_CONTENT_VISIBILITY_PUBLIC ); + $activity['cc'][] = Actors::get_by_id( Actors::BLOG_USER_ID )->get_id(); + $activity['object']['cc'][] = Actors::get_by_id( Actors::BLOG_USER_ID )->get_id(); + + $announce = new Activity(); + $announce->set_type( 'Announce' ); + $announce->set_object( $activity ); + + add_to_outbox( $announce, null, Actors::BLOG_USER_ID, ACTIVITYPUB_CONTENT_VISIBILITY_PUBLIC ); } /** From fb8938d3f58a827033b1fb74e9945823bd8c6a03 Mon Sep 17 00:00:00 2001 From: Matthias Pfefferle Date: Fri, 11 Apr 2025 14:48:05 +0200 Subject: [PATCH 11/24] add missing namespaces --- includes/scheduler/class-comment.php | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/includes/scheduler/class-comment.php b/includes/scheduler/class-comment.php index ef04bd1f40..e9b95ff0c5 100644 --- a/includes/scheduler/class-comment.php +++ b/includes/scheduler/class-comment.php @@ -7,6 +7,10 @@ namespace Activitypub\Scheduler; +use Activitypub\Activity; +use Activitypub\Actors; +use Activitypub\Comments; + use function Activitypub\add_to_outbox; use function Activitypub\should_comment_be_federated; From 4a119b3b4facda3d72a91cc84a4b2bd5a461c10d Mon Sep 17 00:00:00 2001 From: Matthias Pfefferle Date: Fri, 11 Apr 2025 15:04:52 +0200 Subject: [PATCH 12/24] fix namespace issue --- includes/scheduler/class-comment.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/includes/scheduler/class-comment.php b/includes/scheduler/class-comment.php index e9b95ff0c5..a8b0fd41f4 100644 --- a/includes/scheduler/class-comment.php +++ b/includes/scheduler/class-comment.php @@ -9,7 +9,7 @@ use Activitypub\Activity; use Activitypub\Actors; -use Activitypub\Comments; +use Activitypub\Comment as Comment_Util; use function Activitypub\add_to_outbox; use function Activitypub\should_comment_be_federated; @@ -101,7 +101,7 @@ public static function maybe_announce_interaction( $new_status, $old_status, $co return; } - if ( ! self::was_received( $comment ) ) { + if ( ! Comment_Util::was_received( $comment ) ) { return; } From 4bd182a855798fa3b575bb38d20f38de6e9e5dcb Mon Sep 17 00:00:00 2001 From: Matthias Pfefferle Date: Fri, 11 Apr 2025 15:06:22 +0200 Subject: [PATCH 13/24] Fix namespaces --- includes/scheduler/class-comment.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/includes/scheduler/class-comment.php b/includes/scheduler/class-comment.php index a8b0fd41f4..b833ee36b4 100644 --- a/includes/scheduler/class-comment.php +++ b/includes/scheduler/class-comment.php @@ -8,7 +8,7 @@ namespace Activitypub\Scheduler; use Activitypub\Activity; -use Activitypub\Actors; +use Activitypub\Collection\Actors; use Activitypub\Comment as Comment_Util; use function Activitypub\add_to_outbox; From 3888f573a733264a006aa621abf0787b3b83e9e6 Mon Sep 17 00:00:00 2001 From: Matthias Pfefferle Date: Fri, 11 Apr 2025 15:29:30 +0200 Subject: [PATCH 14/24] fix namespace --- includes/scheduler/class-comment.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/includes/scheduler/class-comment.php b/includes/scheduler/class-comment.php index b833ee36b4..3ed9841252 100644 --- a/includes/scheduler/class-comment.php +++ b/includes/scheduler/class-comment.php @@ -7,7 +7,7 @@ namespace Activitypub\Scheduler; -use Activitypub\Activity; +use Activitypub\Activity\Activity; use Activitypub\Collection\Actors; use Activitypub\Comment as Comment_Util; From a5ceb574946e45f5c08fbd049a2e0e1e5a966539 Mon Sep 17 00:00:00 2001 From: Matthias Pfefferle Date: Wed, 30 Apr 2025 16:28:49 +0200 Subject: [PATCH 15/24] Add `to` --- includes/scheduler/class-comment.php | 2 ++ 1 file changed, 2 insertions(+) diff --git a/includes/scheduler/class-comment.php b/includes/scheduler/class-comment.php index 3ed9841252..6afaf5b1e5 100644 --- a/includes/scheduler/class-comment.php +++ b/includes/scheduler/class-comment.php @@ -113,7 +113,9 @@ public static function maybe_announce_interaction( $new_status, $old_status, $co } $activity['cc'][] = Actors::get_by_id( Actors::BLOG_USER_ID )->get_id(); + $activity['to'][] = Actors::get_by_id( Actors::BLOG_USER_ID )->get_id(); $activity['object']['cc'][] = Actors::get_by_id( Actors::BLOG_USER_ID )->get_id(); + $activity['object']['to'][] = Actors::get_by_id( Actors::BLOG_USER_ID )->get_id(); $announce = new Activity(); $announce->set_type( 'Announce' ); From f16bf041b4109835309264faf31562109688cac7 Mon Sep 17 00:00:00 2001 From: Matthias Pfefferle Date: Thu, 2 Oct 2025 15:15:18 +0200 Subject: [PATCH 16/24] Fix typo in Comment_Utils class reference Replaces incorrect 'Comment_Utils' with 'Comment_Util' in schedule_comment_delete_activity to ensure the correct utility class is used for checking if a comment was sent. --- includes/scheduler/class-comment.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/includes/scheduler/class-comment.php b/includes/scheduler/class-comment.php index d5b71581da..e60061e421 100644 --- a/includes/scheduler/class-comment.php +++ b/includes/scheduler/class-comment.php @@ -146,7 +146,7 @@ public static function schedule_comment_activity_on_insert( $comment_id, $commen */ public static function schedule_comment_delete_activity( $comment_id, $comment ) { // Only send Delete activities for comments that were previously federated. - if ( Comment_Utils::was_sent( $comment ) ) { + if ( Comment_Util::was_sent( $comment ) ) { self::schedule_comment_activity( 'delete', '', $comment ); } } From f90bdb0c66e8140a89a52521d8df3eefb80574d5 Mon Sep 17 00:00:00 2001 From: Matthias Pfefferle Date: Thu, 2 Oct 2025 15:16:17 +0200 Subject: [PATCH 17/24] Fix incorrect import and usage of Comment_Util class Replaces all instances of 'Comment_Util' with 'Comment_Utils' in class-comment.php to match the correct class name and prevent potential errors. --- includes/scheduler/class-comment.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/includes/scheduler/class-comment.php b/includes/scheduler/class-comment.php index e60061e421..905a90fd77 100644 --- a/includes/scheduler/class-comment.php +++ b/includes/scheduler/class-comment.php @@ -9,7 +9,7 @@ use Activitypub\Activity\Activity; use Activitypub\Collection\Actors; -use Activitypub\Comment as Comment_Util; +use Activitypub\Comment as Comment_Utils; use function Activitypub\add_to_outbox; use function Activitypub\should_comment_be_federated; @@ -103,7 +103,7 @@ public static function maybe_announce_interaction( $new_status, $old_status, $co return; } - if ( ! Comment_Util::was_received( $comment ) ) { + if ( ! Comment_Utils::was_received( $comment ) ) { return; } @@ -146,7 +146,7 @@ public static function schedule_comment_activity_on_insert( $comment_id, $commen */ public static function schedule_comment_delete_activity( $comment_id, $comment ) { // Only send Delete activities for comments that were previously federated. - if ( Comment_Util::was_sent( $comment ) ) { + if ( Comment_Utils::was_sent( $comment ) ) { self::schedule_comment_activity( 'delete', '', $comment ); } } From 11e098c54890ebc2f61edea176e214d329b4ae38 Mon Sep 17 00:00:00 2001 From: Matthias Pfefferle Date: Fri, 3 Oct 2025 07:56:35 +0200 Subject: [PATCH 18/24] Improve Undo handler object validation and defaults Adds a default value for the 'type' field in handle_undo to prevent undefined index errors. Updates object attribute validation to only check required fields if 'object' is an array, allowing string/URI objects. Adds a test case to ensure URI objects pass validation. --- includes/handler/class-undo.php | 25 +++++++++++----------- tests/includes/handler/class-test-undo.php | 10 +++++++++ 2 files changed, 22 insertions(+), 13 deletions(-) diff --git a/includes/handler/class-undo.php b/includes/handler/class-undo.php index 45433cc255..a1346ac119 100644 --- a/includes/handler/class-undo.php +++ b/includes/handler/class-undo.php @@ -33,7 +33,7 @@ public static function init() { * @param int|null $user_id The ID of the user who initiated the "Undo" activity. */ public static function handle_undo( $activity, $user_id ) { - $type = $activity['object']['type']; + $type = $activity['object']['type'] ?? 'Announce'; $success = false; $result = null; @@ -48,10 +48,7 @@ public static function handle_undo( $activity, $user_id ) { $success = Followers::remove( $post, $user_id ); } } - } - - // Handle "Undo" requests for "Like" and "Create" activities. - if ( in_array( $type, array( 'Like', 'Create', 'Announce' ), true ) ) { + } if ( in_array( $type, array( 'Like', 'Create', 'Announce' ), true ) ) { // Handle "Undo" requests for "Like" and "Create" activities. if ( ! ACTIVITYPUB_DISABLE_INCOMING_INTERACTIONS ) { $object_id = object_to_uri( $activity['object'] ); $result = Comment::object_id_to_comment( esc_url_raw( $object_id ) ); @@ -107,15 +104,17 @@ public static function validate_object( $valid, $param, $request ) { return false; } - $required_object_attributes = array( - 'id', - 'type', - 'actor', - 'object', - ); + if ( \is_array( $json_params['object'] ) ) { + $required_object_attributes = array( + 'id', + 'type', + 'actor', + 'object', + ); - if ( ! empty( \array_diff( $required_object_attributes, \array_keys( $json_params['object'] ) ) ) ) { - return false; + if ( ! empty( \array_diff( $required_object_attributes, \array_keys( $json_params['object'] ) ) ) ) { + return false; + } } return $valid; diff --git a/tests/includes/handler/class-test-undo.php b/tests/includes/handler/class-test-undo.php index b3e57e81c7..6a7dac049b 100644 --- a/tests/includes/handler/class-test-undo.php +++ b/tests/includes/handler/class-test-undo.php @@ -452,6 +452,16 @@ public function validate_object_provider() { false, 'Missing object.object should fail validation', ), + 'uri_object' => array( + array( + 'type' => 'Undo', + 'actor' => 'https://example.com/actor', + 'object' => 'https://example.com/activity/123', + ), + true, + true, + 'URI object should pass validation', + ), ); } From 8777641a398669ed3c3e728960d0358943d44303 Mon Sep 17 00:00:00 2001 From: Matthias Pfefferle Date: Fri, 3 Oct 2025 07:57:11 +0200 Subject: [PATCH 19/24] Revert "Improve Undo handler object validation and defaults" This reverts commit 11e098c54890ebc2f61edea176e214d329b4ae38. --- includes/handler/class-undo.php | 25 +++++++++++----------- tests/includes/handler/class-test-undo.php | 10 --------- 2 files changed, 13 insertions(+), 22 deletions(-) diff --git a/includes/handler/class-undo.php b/includes/handler/class-undo.php index a1346ac119..45433cc255 100644 --- a/includes/handler/class-undo.php +++ b/includes/handler/class-undo.php @@ -33,7 +33,7 @@ public static function init() { * @param int|null $user_id The ID of the user who initiated the "Undo" activity. */ public static function handle_undo( $activity, $user_id ) { - $type = $activity['object']['type'] ?? 'Announce'; + $type = $activity['object']['type']; $success = false; $result = null; @@ -48,7 +48,10 @@ public static function handle_undo( $activity, $user_id ) { $success = Followers::remove( $post, $user_id ); } } - } if ( in_array( $type, array( 'Like', 'Create', 'Announce' ), true ) ) { // Handle "Undo" requests for "Like" and "Create" activities. + } + + // Handle "Undo" requests for "Like" and "Create" activities. + if ( in_array( $type, array( 'Like', 'Create', 'Announce' ), true ) ) { if ( ! ACTIVITYPUB_DISABLE_INCOMING_INTERACTIONS ) { $object_id = object_to_uri( $activity['object'] ); $result = Comment::object_id_to_comment( esc_url_raw( $object_id ) ); @@ -104,17 +107,15 @@ public static function validate_object( $valid, $param, $request ) { return false; } - if ( \is_array( $json_params['object'] ) ) { - $required_object_attributes = array( - 'id', - 'type', - 'actor', - 'object', - ); + $required_object_attributes = array( + 'id', + 'type', + 'actor', + 'object', + ); - if ( ! empty( \array_diff( $required_object_attributes, \array_keys( $json_params['object'] ) ) ) ) { - return false; - } + if ( ! empty( \array_diff( $required_object_attributes, \array_keys( $json_params['object'] ) ) ) ) { + return false; } return $valid; diff --git a/tests/includes/handler/class-test-undo.php b/tests/includes/handler/class-test-undo.php index 6a7dac049b..b3e57e81c7 100644 --- a/tests/includes/handler/class-test-undo.php +++ b/tests/includes/handler/class-test-undo.php @@ -452,16 +452,6 @@ public function validate_object_provider() { false, 'Missing object.object should fail validation', ), - 'uri_object' => array( - array( - 'type' => 'Undo', - 'actor' => 'https://example.com/actor', - 'object' => 'https://example.com/activity/123', - ), - true, - true, - 'URI object should pass validation', - ), ); } From 0dfe418bb28463e4491ec5ef2a0186b945815902 Mon Sep 17 00:00:00 2001 From: Matthias Pfefferle Date: Thu, 23 Oct 2025 13:01:34 +0200 Subject: [PATCH 20/24] Improve Announce activity creation for received comments Adds stricter validation for ActivityPub activity data before creating Announce activities when comments are approved. Updates tests to cover cases where Announce should not be created, including missing, malformed, or non-received activity data and incorrect actor modes. --- includes/scheduler/class-comment.php | 28 +- .../includes/scheduler/class-test-comment.php | 247 ++++++++++++++++++ 2 files changed, 270 insertions(+), 5 deletions(-) diff --git a/includes/scheduler/class-comment.php b/includes/scheduler/class-comment.php index 905a90fd77..143c660c05 100644 --- a/includes/scheduler/class-comment.php +++ b/includes/scheduler/class-comment.php @@ -89,6 +89,10 @@ public static function schedule_comment_activity( $new_status, $old_status, $com /** * Announce an interaction. * + * When a comment is received from another ActivityPub instance and approved, + * this method creates an Announce activity so the blog's followers are notified + * about the interaction. + * * @param string $new_status The new comment status. * @param string $old_status The old comment status. * @param \WP_Comment $comment The comment object. @@ -110,19 +114,33 @@ public static function maybe_announce_interaction( $new_status, $old_status, $co // Get activity from comment meta. $activity = \get_comment_meta( $comment->comment_ID, '_activitypub_activity', true ); - if ( ! $activity ) { + // Validate activity structure. + if ( ! $activity || ! \is_array( $activity ) ) { + return; + } + + // Ensure object exists in the activity. + if ( empty( $activity['object'] ) || ! \is_array( $activity['object'] ) ) { + return; + } + + // Get the blog actor. + $blog_actor = Actors::get_by_id( Actors::BLOG_USER_ID ); + if ( ! $blog_actor || \is_wp_error( $blog_actor ) ) { return; } - $activity['cc'][] = Actors::get_by_id( Actors::BLOG_USER_ID )->get_id(); - $activity['to'][] = Actors::get_by_id( Actors::BLOG_USER_ID )->get_id(); - $activity['object']['cc'][] = Actors::get_by_id( Actors::BLOG_USER_ID )->get_id(); - $activity['object']['to'][] = Actors::get_by_id( Actors::BLOG_USER_ID )->get_id(); + $blog_actor_id = $blog_actor->get_id(); + // Create the Announce activity. $announce = new Activity(); $announce->set_type( 'Announce' ); + $announce->set_actor( $blog_actor_id ); $announce->set_object( $activity ); + $announce->set_to( array( $blog_actor_id ) ); + $announce->set_cc( array( $blog_actor_id ) ); + // Add to outbox with error handling. add_to_outbox( $announce, null, Actors::BLOG_USER_ID, ACTIVITYPUB_CONTENT_VISIBILITY_PUBLIC ); } diff --git a/tests/phpunit/tests/includes/scheduler/class-test-comment.php b/tests/phpunit/tests/includes/scheduler/class-test-comment.php index 2a204031f7..2d70e9d9a9 100644 --- a/tests/phpunit/tests/includes/scheduler/class-test-comment.php +++ b/tests/phpunit/tests/includes/scheduler/class-test-comment.php @@ -225,4 +225,251 @@ public function test_no_delete_activity_for_non_federated_comment() { $this->assertEmpty( $outbox_posts, 'Should not create Delete activity for non-federated comment deletion' ); } + + /** + * Test that no announce is created when not in Blog and User mode. + * + * @covers ::maybe_announce_interaction + */ + public function test_no_announce_when_not_in_blog_and_user_mode() { + $post_id = self::factory()->post->create( array( 'post_author' => self::$user_id ) ); + + // Set actor mode to User only mode. + \update_option( 'activitypub_actor_mode', ACTIVITYPUB_ACTOR_MODE ); + + $activity = array( + 'type' => 'Create', + 'actor' => 'https://example.com/users/testuser', + 'object' => array( + 'type' => 'Note', + 'content' => 'Test comment content', + ), + ); + + $comment_id = self::factory()->comment->create( + array( + 'comment_post_ID' => $post_id, + 'comment_approved' => 0, + 'comment_meta' => array( + 'protocol' => 'activitypub', + '_activitypub_activity' => $activity, + ), + ) + ); + + // Get count of Announce activities before approval. + $before_count = \count( + \get_posts( + array( + 'post_type' => Outbox::POST_TYPE, + 'numberposts' => -1, + 'meta_query' => array( // phpcs:ignore WordPress.DB.SlowDBQuery.slow_db_query_meta_query + array( + 'key' => '_activitypub_activity_type', + 'value' => 'Announce', + ), + ), + ) + ) + ); + + \wp_set_comment_status( $comment_id, 'approve' ); + + // Get count after approval. + $after_count = \count( + \get_posts( + array( + 'post_type' => Outbox::POST_TYPE, + 'numberposts' => -1, + 'meta_query' => array( // phpcs:ignore WordPress.DB.SlowDBQuery.slow_db_query_meta_query + array( + 'key' => '_activitypub_activity_type', + 'value' => 'Announce', + ), + ), + ) + ) + ); + + $this->assertEquals( $before_count, $after_count, 'Should not create Announce when not in Blog and User mode' ); + + \wp_delete_comment( $comment_id, true ); + } + + /** + * Test that no announce is created for non-received comments. + * + * @covers ::maybe_announce_interaction + */ + public function test_no_announce_for_non_received_comments() { + $post_id = self::factory()->post->create( array( 'post_author' => self::$user_id ) ); + + \update_option( 'activitypub_actor_mode', ACTIVITYPUB_ACTOR_AND_BLOG_MODE ); + + // Create a comment WITHOUT ActivityPub protocol meta (not received). + $comment_id = self::factory()->comment->create( + array( + 'comment_post_ID' => $post_id, + 'comment_approved' => 0, + ) + ); + + $before_count = \count( + \get_posts( + array( + 'post_type' => Outbox::POST_TYPE, + 'numberposts' => -1, + 'meta_query' => array( // phpcs:ignore WordPress.DB.SlowDBQuery.slow_db_query_meta_query + array( + 'key' => '_activitypub_activity_type', + 'value' => 'Announce', + ), + ), + ) + ) + ); + + \wp_set_comment_status( $comment_id, 'approve' ); + + $after_count = \count( + \get_posts( + array( + 'post_type' => Outbox::POST_TYPE, + 'numberposts' => -1, + 'meta_query' => array( // phpcs:ignore WordPress.DB.SlowDBQuery.slow_db_query_meta_query + array( + 'key' => '_activitypub_activity_type', + 'value' => 'Announce', + ), + ), + ) + ) + ); + + $this->assertEquals( $before_count, $after_count, 'Should not create Announce for non-received comments' ); + + \wp_delete_comment( $comment_id, true ); + } + + /** + * Test that no announce is created when activity data is missing. + * + * @covers ::maybe_announce_interaction + */ + public function test_no_announce_when_activity_data_missing() { + $post_id = self::factory()->post->create( array( 'post_author' => self::$user_id ) ); + + \update_option( 'activitypub_actor_mode', ACTIVITYPUB_ACTOR_AND_BLOG_MODE ); + + // Create a comment with protocol meta but no activity data. + $comment_id = self::factory()->comment->create( + array( + 'comment_post_ID' => $post_id, + 'comment_approved' => 0, + 'comment_meta' => array( + 'protocol' => 'activitypub', + ), + ) + ); + + $before_count = \count( + \get_posts( + array( + 'post_type' => Outbox::POST_TYPE, + 'numberposts' => -1, + 'meta_query' => array( // phpcs:ignore WordPress.DB.SlowDBQuery.slow_db_query_meta_query + array( + 'key' => '_activitypub_activity_type', + 'value' => 'Announce', + ), + ), + ) + ) + ); + + \wp_set_comment_status( $comment_id, 'approve' ); + + $after_count = \count( + \get_posts( + array( + 'post_type' => Outbox::POST_TYPE, + 'numberposts' => -1, + 'meta_query' => array( // phpcs:ignore WordPress.DB.SlowDBQuery.slow_db_query_meta_query + array( + 'key' => '_activitypub_activity_type', + 'value' => 'Announce', + ), + ), + ) + ) + ); + + $this->assertEquals( $before_count, $after_count, 'Should not create Announce when activity data is missing' ); + + \wp_delete_comment( $comment_id, true ); + } + + /** + * Test that no announce is created when activity is malformed. + * + * @covers ::maybe_announce_interaction + */ + public function test_no_announce_when_activity_malformed() { + $post_id = self::factory()->post->create( array( 'post_author' => self::$user_id ) ); + + \update_option( 'activitypub_actor_mode', ACTIVITYPUB_ACTOR_AND_BLOG_MODE ); + + // Create a comment with malformed activity (missing 'object' field). + $malformed_activity = array( + 'type' => 'Create', + 'actor' => 'https://example.com/users/testuser', + ); + + $comment_id = self::factory()->comment->create( + array( + 'comment_post_ID' => $post_id, + 'comment_approved' => 0, + 'comment_meta' => array( + 'protocol' => 'activitypub', + '_activitypub_activity' => $malformed_activity, + ), + ) + ); + + $before_count = \count( + \get_posts( + array( + 'post_type' => Outbox::POST_TYPE, + 'numberposts' => -1, + 'meta_query' => array( // phpcs:ignore WordPress.DB.SlowDBQuery.slow_db_query_meta_query + array( + 'key' => '_activitypub_activity_type', + 'value' => 'Announce', + ), + ), + ) + ) + ); + + \wp_set_comment_status( $comment_id, 'approve' ); + + $after_count = \count( + \get_posts( + array( + 'post_type' => Outbox::POST_TYPE, + 'numberposts' => -1, + 'meta_query' => array( // phpcs:ignore WordPress.DB.SlowDBQuery.slow_db_query_meta_query + array( + 'key' => '_activitypub_activity_type', + 'value' => 'Announce', + ), + ), + ) + ) + ); + + $this->assertEquals( $before_count, $after_count, 'Should not create Announce when activity is malformed' ); + + \wp_delete_comment( $comment_id, true ); + } } From 1c30a7cd3a95b372297588c22c0ef4b5391777e0 Mon Sep 17 00:00:00 2001 From: Matthias Pfefferle Date: Thu, 23 Oct 2025 13:07:22 +0200 Subject: [PATCH 21/24] Remove redundant recipient settings in announce activity Eliminated unnecessary set_to and set_cc calls for the announce activity in Comment scheduler. The recipients are now handled by add_to_outbox, simplifying the code. --- includes/scheduler/class-comment.php | 2 -- 1 file changed, 2 deletions(-) diff --git a/includes/scheduler/class-comment.php b/includes/scheduler/class-comment.php index 143c660c05..38408cf1ab 100644 --- a/includes/scheduler/class-comment.php +++ b/includes/scheduler/class-comment.php @@ -137,8 +137,6 @@ public static function maybe_announce_interaction( $new_status, $old_status, $co $announce->set_type( 'Announce' ); $announce->set_actor( $blog_actor_id ); $announce->set_object( $activity ); - $announce->set_to( array( $blog_actor_id ) ); - $announce->set_cc( array( $blog_actor_id ) ); // Add to outbox with error handling. add_to_outbox( $announce, null, Actors::BLOG_USER_ID, ACTIVITYPUB_CONTENT_VISIBILITY_PUBLIC ); From a046ba93e0ec767502c81816a355b2cd7c5e2027 Mon Sep 17 00:00:00 2001 From: Matthias Pfefferle Date: Thu, 23 Oct 2025 13:08:04 +0200 Subject: [PATCH 22/24] Simplify blog actor assignment in comment scheduler Replaces retrieval of the blog actor object with direct use of Actors::BLOG_USER_ID when setting the actor for Announce activities. This streamlines the code and removes unnecessary error handling for actor retrieval. --- includes/scheduler/class-comment.php | 10 +--------- 1 file changed, 1 insertion(+), 9 deletions(-) diff --git a/includes/scheduler/class-comment.php b/includes/scheduler/class-comment.php index 38408cf1ab..87d145d0d4 100644 --- a/includes/scheduler/class-comment.php +++ b/includes/scheduler/class-comment.php @@ -124,18 +124,10 @@ public static function maybe_announce_interaction( $new_status, $old_status, $co return; } - // Get the blog actor. - $blog_actor = Actors::get_by_id( Actors::BLOG_USER_ID ); - if ( ! $blog_actor || \is_wp_error( $blog_actor ) ) { - return; - } - - $blog_actor_id = $blog_actor->get_id(); - // Create the Announce activity. $announce = new Activity(); $announce->set_type( 'Announce' ); - $announce->set_actor( $blog_actor_id ); + $announce->set_actor( Actors::BLOG_USER_ID ); $announce->set_object( $activity ); // Add to outbox with error handling. From a861977371e4cd866c79228149d98c064b7401c7 Mon Sep 17 00:00:00 2001 From: Matthias Pfefferle Date: Thu, 23 Oct 2025 17:18:38 +0200 Subject: [PATCH 23/24] Update includes/class-dispatcher.php Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> --- includes/class-dispatcher.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/includes/class-dispatcher.php b/includes/class-dispatcher.php index a252ef8440..17ed0b6ae6 100644 --- a/includes/class-dispatcher.php +++ b/includes/class-dispatcher.php @@ -33,7 +33,7 @@ class Dispatcher { * @see https://github.com/tfredrich/RestApiTutorial.com/blob/fd08b0f67f07450521d143b123cd6e1846cb2e3b/content/advanced/responses/retries.md * @var int[] */ - public static $retry_error_codes = array( 400, 408, 429, 500, 502, 503, 504 ); + public static $retry_error_codes = array( 408, 429, 500, 502, 503, 504 ); /** * Initialize the class, registering WordPress hooks. From ab718f04f9848e7a500459ede3c1f048a7bbaa85 Mon Sep 17 00:00:00 2001 From: Automattic Bot Date: Thu, 30 Oct 2025 11:09:14 +0000 Subject: [PATCH 24/24] Prettify --- package-lock.json | 63 ++++++++++++++++++++++++++++++++++++----------- 1 file changed, 49 insertions(+), 14 deletions(-) diff --git a/package-lock.json b/package-lock.json index 50e2b659af..1fb208cb38 100644 --- a/package-lock.json +++ b/package-lock.json @@ -122,6 +122,7 @@ "integrity": "sha512-yJ474Zv3cwiSOO9nXJuqzvwEeM+chDuQ8GJirw+pZ91sCGCyOZ3dJkVE09fTV0VEVzXyLWhh3G/AolYTPX7Mow==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "@ampproject/remapping": "^2.2.0", "@babel/code-frame": "^7.25.7", @@ -2098,6 +2099,7 @@ "integrity": "sha512-h0Un1ieD+HUrzBH6dJXhod3ifSghk5Hw/2Y4/KHBziPlZecrFyE9YOTPU6eOs0V9pYl8gOs86fkr/KN8lUX39A==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "@keyv/serialize": "^1.1.1" } @@ -2138,6 +2140,7 @@ } ], "license": "MIT", + "peer": true, "engines": { "node": ">=18" }, @@ -2161,6 +2164,7 @@ } ], "license": "MIT", + "peer": true, "engines": { "node": ">=18" } @@ -2295,6 +2299,7 @@ "integrity": "sha512-O000MLDBDdk/EohJPFUqvnp4qnHeYkVP5B0xEG0D/L7cOKP9kefu2DXn8dj74cQfsEzUqh+sr1RzFqiL1o+PpA==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "@babel/runtime": "^7.18.3", "@emotion/babel-plugin": "^11.13.5", @@ -4050,6 +4055,7 @@ "integrity": "sha512-3giAOQvZiH5F9bMlMiv8+GSPMeqg0dbaeo58/0SlA9sxSqZhnUtxzX9/2FzyhS9sWQf5S0GJE0AKBrFqjpeYcg==", "dev": true, "license": "Apache-2.0", + "peer": true, "engines": { "node": ">=8.0.0" } @@ -4073,6 +4079,7 @@ "integrity": "sha512-s5vvxXPVdjqS3kTLKMeBMvop9hbWkwzBpu+mUO2M7sZtlkyDJGwFe33wRKnbaYDo8ExRVBIIdwIGrqpxHuKttA==", "dev": true, "license": "Apache-2.0", + "peer": true, "engines": { "node": ">=14" }, @@ -4086,6 +4093,7 @@ "integrity": "sha512-OOCM2C/QIURhJMuKaekP3TRBxBKxG/TWWA0TL2J6nXUtDnuCtccy49LUJF8xPFXMX+0LMcxFpCo8M9cGY1W6rQ==", "dev": true, "license": "Apache-2.0", + "peer": true, "dependencies": { "@opentelemetry/semantic-conventions": "1.28.0" }, @@ -4568,6 +4576,7 @@ "integrity": "sha512-5UxZqiAgLYGFjS4s9qm5mBVo433u+dSPUFWVWXmLAD4wB65oMCoXaJP1KJa9DIYYMeHu3z4BZcStG3LC593cWA==", "dev": true, "license": "Apache-2.0", + "peer": true, "dependencies": { "@opentelemetry/core": "1.30.1", "@opentelemetry/semantic-conventions": "1.28.0" @@ -4595,6 +4604,7 @@ "integrity": "sha512-jVPgBbH1gCy2Lb7X0AVQ8XAfgg0pJ4nvl8/IiQA6nxOsPvS+0zMJaFSs2ltXe0J6C8dqjcnpyqINDJmU30+uOg==", "dev": true, "license": "Apache-2.0", + "peer": true, "dependencies": { "@opentelemetry/core": "1.30.1", "@opentelemetry/resources": "1.30.1", @@ -4623,6 +4633,7 @@ "integrity": "sha512-JD6DerIKdJGmRp4jQyX5FlrQjA4tjOw1cvfsPAZXfOOEErMUHjPcPSICS+6WnM0nB0efSFARh0KAZss+bvExOA==", "dev": true, "license": "Apache-2.0", + "peer": true, "engines": { "node": ">=14" } @@ -4994,6 +5005,7 @@ "integrity": "sha512-vSMYtL/zOcFpvJCW71Q/OEGQb7KYBPAdKh35WNSkaZA75JlAO8ED8UN6GUNTm3drWomcbcqRPFqQbLae8yBTdg==", "dev": true, "license": "Apache-2.0", + "peer": true, "dependencies": { "playwright": "1.56.1" }, @@ -5941,6 +5953,7 @@ "integrity": "sha512-8QqtOQT5ACVlmsvKOJNEaWmRPmcojMOzCz4Hs2BGG/toAp/K38LcsMRyLp349glq5AzJbCEeimEoxaX6v/fLrA==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "@babel/core": "^7.21.3", "@svgr/babel-preset": "8.1.0", @@ -6193,8 +6206,7 @@ "resolved": "https://registry.npmjs.org/@types/aria-query/-/aria-query-5.0.4.tgz", "integrity": "sha512-rfT93uj5s0PRL7EzccGMs3brplhcrghnDoV26NqKhCAS1hVo+WdNsPvE/yb6ilfr5hi2MEk6d5EWJTKdxg8jVw==", "dev": true, - "license": "MIT", - "peer": true + "license": "MIT" }, "node_modules/@types/babel__core": { "version": "7.20.5", @@ -6302,6 +6314,7 @@ "integrity": "sha512-FXx2pKgId/WyYo2jXw63kk7/+TY7u7AziEJxJAnSFzHlqTAS3Ync6SvgYAN/k4/PQpnnVuzoMuVnByKK2qp0ag==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "@types/estree": "*", "@types/json-schema": "*" @@ -6648,6 +6661,7 @@ "integrity": "sha512-RFA/bURkcKzx/X9oumPG9Vp3D3JUgus/d0b67KB0t5S/raciymilkOa66olh78MUI92QLbEJevO7rvqU/kjwKA==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "@types/prop-types": "*", "csstype": "^3.0.2" @@ -6659,6 +6673,7 @@ "integrity": "sha512-MEe3UeoENYVFXzoXEWsvcpg6ZvlrFNlOQ7EOsvhI3CfAXwzPfO8Qwuxd40nepsYKqyyVQnTdEfv68q91yLcKrQ==", "dev": true, "license": "MIT", + "peer": true, "peerDependencies": { "@types/react": "^18.0.0" } @@ -6874,6 +6889,7 @@ "integrity": "sha512-tbsV1jPne5CkFQCgPBcDOt30ItF7aJoZL997JSF7MhGQqOeT3svWRYxiqlfA5RUdlHN6Fi+EI9bxqbdyAUZjYQ==", "dev": true, "license": "BSD-2-Clause", + "peer": true, "dependencies": { "@typescript-eslint/scope-manager": "6.21.0", "@typescript-eslint/types": "6.21.0", @@ -8269,6 +8285,7 @@ "integrity": "sha512-wPfA0BGnfyMLsiOhkxac2eNXTmcHH5r8nEnfSxf2bDQWRUcbQ2Laae53N0NplGmI79wsBSOXRfMCibM+gyq2rg==", "dev": true, "license": "GPL-2.0-or-later", + "peer": true, "dependencies": { "@inquirer/prompts": "^7.2.0", "chalk": "^4.0.0", @@ -9309,6 +9326,7 @@ "integrity": "sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg==", "dev": true, "license": "MIT", + "peer": true, "bin": { "acorn": "bin/acorn" }, @@ -9402,6 +9420,7 @@ "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "fast-deep-equal": "^3.1.1", "fast-json-stable-stringify": "^2.0.0", @@ -9619,7 +9638,6 @@ "integrity": "sha512-b0P0sZPKtyu8HkeRAfCq0IfURZK+SuwMjY1UXGBU27wpAiTwQAIlq56IbIO+ytk/JjS1fMR14ee5WBBfKi5J6A==", "dev": true, "license": "Apache-2.0", - "peer": true, "dependencies": { "dequal": "^2.0.3" } @@ -10464,6 +10482,7 @@ } ], "license": "MIT", + "peer": true, "dependencies": { "baseline-browser-mapping": "^2.8.9", "caniuse-lite": "^1.0.30001746", @@ -12261,7 +12280,6 @@ "integrity": "sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA==", "dev": true, "license": "MIT", - "peer": true, "engines": { "node": ">=6" } @@ -12320,7 +12338,8 @@ "resolved": "https://registry.npmjs.org/devtools-protocol/-/devtools-protocol-0.0.1507524.tgz", "integrity": "sha512-OjaNE7qpk6GRTXtqQjAE5bGx6+c4F1zZH0YXtpZQLM92HNXx4zMAaqlKhP4T52DosG6hDW8gPMNhGOF8xbwk/w==", "dev": true, - "license": "BSD-3-Clause" + "license": "BSD-3-Clause", + "peer": true }, "node_modules/diff": { "version": "4.0.2", @@ -12399,8 +12418,7 @@ "resolved": "https://registry.npmjs.org/dom-accessibility-api/-/dom-accessibility-api-0.5.16.tgz", "integrity": "sha512-X7BJ2yElsnOJ30pZF4uIIDfBEVgF4XEBxL9Bxhy6dnrm5hkzqmsWHGTiHqRiITNhMyFLyAiWndIJP7Z1NTteDg==", "dev": true, - "license": "MIT", - "peer": true + "license": "MIT" }, "node_modules/dom-serializer": { "version": "2.0.0", @@ -12983,6 +13001,7 @@ "deprecated": "This version is no longer supported. Please see https://eslint.org/version-support for other options.", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "@eslint-community/eslint-utils": "^4.2.0", "@eslint-community/regexpp": "^4.6.1", @@ -13039,6 +13058,7 @@ "integrity": "sha512-/IGJ6+Dka158JnP5n5YFMOszjDWrXggGz1LaK/guZq9vZTmniaKlHcsscvkAhn9y4U+BU3JuUdYvtAMcv30y4A==", "dev": true, "license": "MIT", + "peer": true, "bin": { "eslint-config-prettier": "bin/cli.js" }, @@ -16732,6 +16752,7 @@ "integrity": "sha512-NIy3oAFp9shda19hy4HK0HRTWKtPJmGdnvywu01nOqNC2vZg+Z+fvJDxpMQA88eb2I9EcafcdjYgsDthnYTvGw==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "@jest/core": "^29.7.0", "@jest/types": "^29.6.3", @@ -18432,7 +18453,8 @@ "resolved": "https://registry.npmjs.org/devtools-protocol/-/devtools-protocol-0.0.1508733.tgz", "integrity": "sha512-QJ1R5gtck6nDcdM+nlsaJXcelPEI7ZxSMw1ujHpO1c4+9l+Nue5qlebi9xO1Z2MGr92bFOQTW7/rrheh5hHxDg==", "dev": true, - "license": "BSD-3-Clause" + "license": "BSD-3-Clause", + "peer": true }, "node_modules/lighthouse/node_modules/puppeteer-core/node_modules/ws": { "version": "8.18.3", @@ -18722,7 +18744,6 @@ "integrity": "sha512-h5bgJWpxJNswbU7qCrV0tIKQCaS3blPDrqKWx+QxzuzL1zGUzij9XCWLrSLsJPu5t+eWA/ycetzYAO5IOMcWAQ==", "dev": true, "license": "MIT", - "peer": true, "bin": { "lz-string": "bin/bin.js" } @@ -19616,6 +19637,7 @@ "integrity": "sha512-cuXAJJB1Rdqz0UO6w524matlBqDBjcNt7Ru+RDIu4y6RI1gVqiWBnylrK8sPRk81gGBA0X8hJbDXolVOoTc+sA==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "ajv": "^6.12.6", "ajv-errors": "^1.0.1", @@ -20771,6 +20793,7 @@ } ], "license": "MIT", + "peer": true, "dependencies": { "nanoid": "^3.3.11", "picocolors": "^1.1.1", @@ -21547,6 +21570,7 @@ "integrity": "sha512-5SYSgFKSyhCbk6SrXyMpqjb5+MQBgfvEKE/OC+PujcY34sOpqtr+0AZQtPYx5IA6VxynQ7rUPCtKzyovpj9Bpg==", "dev": true, "license": "MIT", + "peer": true, "funding": { "type": "opencollective", "url": "https://opencollective.com/preact" @@ -21569,6 +21593,7 @@ "integrity": "sha512-X4UlrxDTH8oom9qXlcjnydsjAOD2BmB6yFmvS4Z2zdTzqqpRWb+fbqrH412+l+OUXmbzJlSXjlMFYPgYG12IAA==", "dev": true, "license": "MIT", + "peer": true, "bin": { "prettier": "bin/prettier.cjs" }, @@ -21598,7 +21623,6 @@ "integrity": "sha512-Qb1gy5OrP5+zDf2Bvnzdl3jsTf1qXVMazbvCoKhtKqVs4/YK4ozX4gKQJJVyNe+cajNPn0KoC0MC3FUmaHWEmQ==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "ansi-regex": "^5.0.1", "ansi-styles": "^5.0.0", @@ -21614,7 +21638,6 @@ "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", "dev": true, "license": "MIT", - "peer": true, "engines": { "node": ">=10" }, @@ -21627,8 +21650,7 @@ "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz", "integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==", "dev": true, - "license": "MIT", - "peer": true + "license": "MIT" }, "node_modules/process-nextick-args": { "version": "2.0.1", @@ -21991,6 +22013,7 @@ "integrity": "sha512-wS+hAgJShR0KhEvPJArfuPVN1+Hz1t0Y6n5jLrGQbkb4urgPE/0Rve+1kMB1v/oWgHgm4WIcV+i7F2pTVj+2iQ==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "loose-envify": "^1.1.0" }, @@ -22064,6 +22087,7 @@ "integrity": "sha512-5m4nQKp+rZRb09LNH59GM4BxTh9251/ylbKIbpe7TpGxfJ+9kv6BLkLBXIjjspbgbnIBNqlI23tRnTWT0snUIw==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "loose-envify": "^1.1.0", "scheduler": "^0.23.2" @@ -22100,6 +22124,7 @@ "integrity": "sha512-jCvmsr+1IUSMUyzOkRcvnVbX3ZYC6g9TDrDbFuFmRDq7PD4yaGbLKNQL6k2jnArV8hjYxh7hVhAZB6s9HDGpZA==", "dev": true, "license": "MIT", + "peer": true, "engines": { "node": ">=0.10.0" } @@ -22339,7 +22364,8 @@ "resolved": "https://registry.npmjs.org/redux/-/redux-5.0.1.tgz", "integrity": "sha512-M9/ELqF6fy8FwmkpnF0S3YKOqMyoWJ4+CS5Efg2ct3oY9daQvd/Pc71FpGZsVsbl3Cpb+IIcjBDUnnyBdQbq4w==", "dev": true, - "license": "MIT" + "license": "MIT", + "peer": true }, "node_modules/reflect.getprototypeof": { "version": "1.0.10", @@ -22922,6 +22948,7 @@ "integrity": "sha512-t+YPtOQHpGW1QWsh1CHQ5cPIr9lbbGZLZnbihP/D/qZj/yuV68m8qarcV17nvkOX81BCrvzAlq2klCQFZghyTg==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "chokidar": "^4.0.0", "immutable": "^5.0.2", @@ -23027,6 +23054,7 @@ "integrity": "sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "fast-deep-equal": "^3.1.3", "fast-uri": "^3.0.1", @@ -24563,6 +24591,7 @@ } ], "license": "MIT", + "peer": true, "dependencies": { "@csstools/css-parser-algorithms": "^3.0.5", "@csstools/css-tokenizer": "^3.0.4", @@ -24898,6 +24927,7 @@ "integrity": "sha512-8sLjZwK0R+JlxlYcTuVnyT2v+htpdrjDOKuMcOVdYjt52Lh8hWRYpxBPoKx/Zg+bcjc3wx6fmQevMmUztS/ccA==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "cssesc": "^3.0.0", "util-deprecate": "^1.0.2" @@ -25673,6 +25703,7 @@ "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", "dev": true, "license": "(MIT OR CC0-1.0)", + "peer": true, "engines": { "node": ">=10" }, @@ -26320,6 +26351,7 @@ "integrity": "sha512-7h/weGm9d/ywQ6qzJ+Xy+r9n/3qgp/thalBbpOi5i223dPXKi04IBtqPN9nTd+jBc7QKfvDbaBnFipYp4sJAUQ==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "@types/eslint-scope": "^3.7.7", "@types/estree": "^1.0.8", @@ -26428,6 +26460,7 @@ "integrity": "sha512-pIDJHIEI9LR0yxHXQ+Qh95k2EvXpWzZ5l+d+jIo+RdSm9MiHfzazIxwwni/p7+x4eJZuvG1AJwgC4TNQ7NRgsg==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "@discoveryjs/json-ext": "^0.5.0", "@webpack-cli/configtest": "^2.1.1", @@ -26508,6 +26541,7 @@ "integrity": "sha512-0XavAZbNJ5sDrCbkpWL8mia0o5WPOd2YGtxrEiZkBK9FjLppIUK2TgxK6qGD2P3hUXTJNNPVibrerKcx5WkR1g==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "@types/bonjour": "^3.5.9", "@types/connect-history-api-fallback": "^1.3.5", @@ -27194,6 +27228,7 @@ "integrity": "sha512-OIDwaflOaq4wC6YlPBy2L6ceKeKuF7DeTxx+jPzv1FHn9tCZ0ZwSRnUBxD05E3yed46fv/FWJbvR+Ud7x0L7zw==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "lib0": "^0.2.99" },