updated plugin ActivityPub version 9.1.0

This commit is contained in:
2026-07-28 15:03:10 +00:00
committed by Gitium
parent bf428f0e45
commit ff806e1811
217 changed files with 6098 additions and 3025 deletions

View File

@ -7,6 +7,8 @@
namespace Activitypub\Rest;
use Activitypub\Signature;
/**
* ActivityPub Server REST-Class.
*
@ -19,6 +21,7 @@ class Server {
* Initialize the class, registering WordPress hooks.
*/
public static function init() {
\add_filter( 'rest_pre_dispatch', array( self::class, 'maybe_add_actor_from_signature' ), 10, 3 );
\add_filter( 'rest_request_before_callbacks', array( self::class, 'validate_requests' ), 9, 3 );
\add_filter( 'rest_request_parameter_order', array( self::class, 'request_parameter_order' ), 10, 2 );
@ -60,7 +63,7 @@ class Server {
if (
ACTIVITYPUB_DISABLE_INCOMING_INTERACTIONS &&
in_array( $params['type'], array( 'Create', 'Like', 'Announce' ), true )
\in_array( $params['type'], array( 'Create', 'Like', 'Announce' ), true )
) {
return new \WP_Error(
'activitypub_server_does_not_accept_incoming_interactions',
@ -104,6 +107,67 @@ class Server {
);
}
/**
* Backfill a missing `actor` on incoming FeatureRequest activities from the signature.
*
* Mastodon (FEP-7aa9) omits `actor` from the FeatureRequest body and conveys the
* requesting actor only through the HTTP signature keyId. Our inbox routes require
* `actor`, so such a request is rejected during parameter validation before it can
* reach the inbox or its handler, which is why no Accept is ever sent.
*
* Derive the actor from the keyId and add it as a request parameter. The actor is
* injected with `set_param()` rather than by rewriting the request body, so the raw
* body stays byte-identical and the signed `Digest` still verifies. Inbox POSTs read
* JSON parameters first (see `request_parameter_order()`), so the value is visible to
* both parameter validation and the handler via `get_json_params()`.
*
* Scoped to FeatureRequest, the only activity type known to address this way. Runs on
* `rest_pre_dispatch` because that is the only hook that fires before required-parameter
* validation. Signature verification still runs afterwards and remains authoritative:
* the injected actor is derived from the very keyId the signature is checked against, so
* it cannot be used to impersonate another actor.
*
* @since 9.0.0
*
* @param mixed $result Response to replace the request with, or null to continue.
* @param \WP_REST_Server $server Server instance.
* @param \WP_REST_Request $request The request object.
*
* @return mixed The unmodified `$result`.
*/
public static function maybe_add_actor_from_signature( $result, $server, $request ) {
// Respect an earlier short-circuit.
if ( null !== $result ) {
return $result;
}
if ( \WP_REST_Server::CREATABLE !== $request->get_method() ) {
return $result;
}
$route = $request->get_route();
if (
! \str_starts_with( $route, '/' . ACTIVITYPUB_REST_NAMESPACE ) ||
! \str_ends_with( $route, '/inbox' )
) {
return $result;
}
$json = $request->get_json_params();
if ( ! \is_array( $json ) || 'FeatureRequest' !== ( $json['type'] ?? '' ) || ! empty( $json['actor'] ) ) {
return $result;
}
$key_id = Signature::get_key_id( $request );
if ( ! $key_id ) {
return $result;
}
$request->set_param( 'actor', \strip_fragment_from_url( $key_id ) );
return $result;
}
/**
* Filters the REST API response to properly handle the ActivityPub error formatting.
*