| @@ -12,10 +12,8 @@ | ||
| 12 | 12 | use Activitypub\Scheduler; |
| 13 | 13 | use Activitypub\Webfinger; |
| 14 | 14 | |
| 15 | 15 | use function Activitypub\add_to_outbox; |
| 16 | -use function Activitypub\object_to_uri; | |
| 17 | -use function Activitypub\user_can_act_as_blog; | |
| 18 | 16 | |
| 19 | 17 | /** |
| 20 | 18 | * ActivityPub Outbox Collection |
| 21 | 19 | * |
| @@ -39,16 +37,8 @@ | ||
| 39 | 37 | */ |
| 40 | 38 | const MAX_ITEMS = 5000; |
| 41 | 39 | |
| 42 | 40 | /** |
| 43 | - * Activity types included in the outbox collection listing. | |
| 44 | - * | |
| 45 | - * @var string[] | |
| 46 | - */ | |
| 47 | - const ACTIVITY_TYPES = array( 'Announce', 'Arrive', 'Create', 'Like', 'Update' ); | |
| 48 | - | |
| 49 | - | |
| 50 | - /** | |
| 51 | 41 | * Number of items to process per batch during purge. |
| 52 | 42 | * |
| 53 | 43 | * @var int |
| 54 | 44 | */ |
| @@ -71,24 +61,15 @@ | ||
| 71 | 61 | * @return false|int|\WP_Error The added item or an error. |
| 72 | 62 | */ |
| 73 | 63 | public static function add( Activity $activity, $user_id, $visibility = ACTIVITYPUB_CONTENT_VISIBILITY_PUBLIC ) { |
| 74 | 64 | $actor_type = Actors::get_type_by_id( $user_id ); |
| 65 | + $object_id = self::get_object_id( $activity ); | |
| 66 | + $title = self::get_object_title( $activity->get_object() ); | |
| 75 | 67 | |
| 76 | 68 | if ( ! $activity->get_actor() ) { |
| 77 | 69 | $activity->set_actor( Actors::get_by_id( $user_id )->get_id() ); |
| 78 | 70 | } |
| 79 | 71 | |
| 80 | - $object_id = object_to_uri( self::get_object_id( $activity ) ); | |
| 81 | - $title = self::get_object_title( $activity->get_object() ); | |
| 82 | - | |
| 83 | - if ( ! $object_id || ! \is_string( $object_id ) ) { | |
| 84 | - return new \WP_Error( | |
| 85 | - 'activitypub_outbox_invalid_object_id', | |
| 86 | - \__( 'Unable to determine an object ID for this activity.', 'activitypub' ), | |
| 87 | - array( 'status' => 400 ) | |
| 88 | - ); | |
| 89 | - } | |
| 90 | - | |
| 91 | 72 | if ( ! \filter_var( $object_id, FILTER_VALIDATE_URL ) ) { |
| 92 | 73 | $object_id = Webfinger::resolve( $object_id ); |
| 93 | 74 | } |
| 94 | 75 | |
| @@ -106,10 +87,9 @@ | ||
| 106 | 87 | __( '[%1$s] %2$s', 'activitypub' ), |
| 107 | 88 | $activity->get_type(), |
| 108 | 89 | \wp_trim_words( $title, 5 ) |
| 109 | 90 | ), |
| 110 | - // Persist the blind audience so later dispatch can compute recipients from `bto`/`bcc`. | |
| 111 | - 'post_content' => wp_slash( $activity->to_json( true, true ) ), | |
| 91 | + 'post_content' => wp_slash( $activity->to_json() ), | |
| 112 | 92 | // ensure that user ID is not below 0. |
| 113 | 93 | 'post_author' => \max( $user_id, 0 ), |
| 114 | 94 | 'post_status' => 'pending', |
| 115 | 95 | 'meta_input' => array( |
| @@ -136,9 +116,9 @@ | ||
| 136 | 116 | |
| 137 | 117 | \wp_update_post( |
| 138 | 118 | array( |
| 139 | 119 | 'ID' => $id, |
| 140 | - 'post_content' => \wp_slash( $activity->to_json( true, true ) ), | |
| 120 | + 'post_content' => \wp_slash( $activity->to_json() ), | |
| 141 | 121 | ) |
| 142 | 122 | ); |
| 143 | 123 | } |
| 144 | 124 | |
| @@ -249,39 +229,8 @@ | ||
| 249 | 229 | return add_to_outbox( $activity, $type, $outbox_item->post_author, $visibility ); |
| 250 | 230 | } |
| 251 | 231 | |
| 252 | 232 | /** |
| 253 | - * Get an outbox item by object ID and activity type. | |
| 254 | - * | |
| 255 | - * @param string $object_id The ActivityPub object ID. | |
| 256 | - * @param string $activity_type The activity type (Create, Update, etc.). | |
| 257 | - * | |
| 258 | - * @return \WP_Post|null The outbox item or null if not found. | |
| 259 | - */ | |
| 260 | - public static function get_by_object_id( $object_id, $activity_type ) { | |
| 261 | - $outbox_items = \get_posts( | |
| 262 | - array( | |
| 263 | - 'post_type' => self::POST_TYPE, | |
| 264 | - 'post_status' => 'any', | |
| 265 | - 'posts_per_page' => 1, | |
| 266 | - // phpcs:ignore WordPress.DB.SlowDBQuery.slow_db_query_meta_query | |
| 267 | - 'meta_query' => array( | |
| 268 | - array( | |
| 269 | - 'key' => '_activitypub_object_id', | |
| 270 | - 'value' => $object_id, | |
| 271 | - ), | |
| 272 | - array( | |
| 273 | - 'key' => '_activitypub_activity_type', | |
| 274 | - 'value' => $activity_type, | |
| 275 | - ), | |
| 276 | - ), | |
| 277 | - ) | |
| 278 | - ); | |
| 279 | - | |
| 280 | - return ! empty( $outbox_items ) ? $outbox_items[0] : null; | |
| 281 | - } | |
| 282 | - | |
| 283 | - /** | |
| 284 | 233 | * Get an outbox item by its GUID. |
| 285 | 234 | * |
| 286 | 235 | * @param string $guid The GUID of the outbox item. |
| 287 | 236 | * |
| @@ -337,16 +286,8 @@ | ||
| 337 | 286 | */ |
| 338 | 287 | public static function get_activity( $outbox_item ) { |
| 339 | 288 | $outbox_item = \get_post( $outbox_item ); |
| 340 | 289 | |
| 341 | - if ( ! $outbox_item ) { | |
| 342 | - return new \WP_Error( | |
| 343 | - 'activitypub_outbox_item_not_found', | |
| 344 | - \__( 'Outbox item not found.', 'activitypub' ), | |
| 345 | - array( 'status' => 404 ) | |
| 346 | - ); | |
| 347 | - } | |
| 348 | - | |
| 349 | 290 | $activity_object = \json_decode( $outbox_item->post_content, true ); |
| 350 | 291 | $type = \get_post_meta( $outbox_item->ID, '_activitypub_activity_type', true ); |
| 351 | 292 | |
| 352 | 293 | if ( $activity_object['type'] === $type ) { |
| @@ -426,34 +367,8 @@ | ||
| 426 | 367 | if ( 'ap_outbox' !== $outbox_item->post_type ) { |
| 427 | 368 | return new \WP_Error( 'invalid_outbox_item', 'Invalid Outbox item.' ); |
| 428 | 369 | } |
| 429 | 370 | |
| 430 | - // Authenticate via Bearer token for non-REST requests (e.g. permalink access). | |
| 431 | - if ( \get_option( 'activitypub_api', false ) && ! \is_user_logged_in() && ! \wp_is_serving_rest_request() ) { | |
| 432 | - \Activitypub\OAuth\Server::authenticate_oauth( null ); | |
| 433 | - } | |
| 434 | - | |
| 435 | - /* | |
| 436 | - * Allow the author to view their own outbox items regardless of visibility. | |
| 437 | - * The `is_user_logged_in()` guard prevents anonymous visitors from matching | |
| 438 | - * the blog actor's items (where both `get_current_user_id()` and `post_author` | |
| 439 | - * are `0`), which would otherwise expose private activities at their permalink. | |
| 440 | - * | |
| 441 | - * Users authorized to act as the blog actor are treated as the author of | |
| 442 | - * blog-actor items so they can read the same private outbox they can post to. | |
| 443 | - */ | |
| 444 | - if ( \is_user_logged_in() ) { | |
| 445 | - $author = (int) $outbox_item->post_author; | |
| 446 | - | |
| 447 | - if ( \get_current_user_id() === $author ) { | |
| 448 | - return self::get_activity( $outbox_item ); | |
| 449 | - } | |
| 450 | - | |
| 451 | - if ( Actors::BLOG_USER_ID === $author && user_can_act_as_blog() ) { | |
| 452 | - return self::get_activity( $outbox_item ); | |
| 453 | - } | |
| 454 | - } | |
| 455 | - | |
| 456 | 371 | // Check if Outbox Activity is public. |
| 457 | 372 | $visibility = \get_post_meta( $outbox_item->ID, 'activitypub_content_visibility', true ); |
| 458 | 373 | |
| 459 | 374 | if ( ! in_array( $visibility, array( ACTIVITYPUB_CONTENT_VISIBILITY_PUBLIC, ACTIVITYPUB_CONTENT_VISIBILITY_QUIET_PUBLIC ), true ) ) { |
| @@ -459,9 +374,9 @@ | ||
| 459 | 374 | if ( ! in_array( $visibility, array( ACTIVITYPUB_CONTENT_VISIBILITY_PUBLIC, ACTIVITYPUB_CONTENT_VISIBILITY_QUIET_PUBLIC ), true ) ) { |
| 460 | 375 | return new \WP_Error( 'private_outbox_item', 'Not a public Outbox item.' ); |
| 461 | 376 | } |
| 462 | 377 | |
| 463 | - $activity_types = \apply_filters( 'rest_activitypub_outbox_activity_types', self::ACTIVITY_TYPES ); | |
| 378 | + $activity_types = \apply_filters( 'rest_activitypub_outbox_activity_types', array( 'Announce', 'Create', 'Like', 'Update' ) ); | |
| 464 | 379 | $activity_type = \get_post_meta( $outbox_item->ID, '_activitypub_activity_type', true ); |
| 465 | 380 | |
| 466 | 381 | if ( ! in_array( $activity_type, $activity_types, true ) ) { |
| 467 | 382 | return new \WP_Error( 'private_outbox_item', 'Not public Outbox item type.' ); |
| @@ -474,9 +389,9 @@ | ||
| 474 | 389 | * Get the object ID of an activity. |
| 475 | 390 | * |
| 476 | 391 | * @param Activity|Base_Object|string $data The activity object. |
| 477 | 392 | * |
| 478 | - * @return string|null The object ID. | |
| 393 | + * @return string The object ID. | |
| 479 | 394 | */ |
| 480 | 395 | private static function get_object_id( $data ) { |
| 481 | 396 | $object = $data->get_object(); |
| 482 | 397 | |
| @@ -487,13 +402,9 @@ | ||
| 487 | 402 | if ( is_string( $object ) ) { |
| 488 | 403 | return $object; |
| 489 | 404 | } |
| 490 | 405 | |
| 491 | - if ( $data->get_id() ) { | |
| 492 | - return $data->get_id(); | |
| 493 | - } | |
| 494 | - | |
| 495 | - return object_to_uri( $data->get_actor() ); | |
| 406 | + return $data->get_id() ?? $data->get_actor(); | |
| 496 | 407 | } |
| 497 | 408 | |
| 498 | 409 | /** |
| 499 | 410 | * Get the title of an activity recursively. |