Merge pull request #180 from pfefferle/feature-guidance

add some guidance
This commit is contained in:
Matthias Pfefferle 2022-12-09 09:06:50 +01:00 committed by GitHub
commit 58c19de374
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
24 changed files with 558 additions and 125 deletions

View file

@ -10,7 +10,7 @@ jobs:
steps:
- uses: actions/checkout@master
- name: WordPress Plugin Deploy
uses: 10up/action-wordpress-plugin-deploy@master
uses: 10up/action-wordpress-plugin-deploy@stable
env:
SVN_PASSWORD: ${{ secrets.SVN_PASSWORD }}
SVN_USERNAME: ${{ secrets.SVN_USERNAME }}

View file

@ -1,5 +1,5 @@
name: Unit Testing
on:
on:
push:
pull_request:
jobs:
@ -15,7 +15,7 @@ jobs:
options: --health-cmd="mysqladmin ping" --health-interval=10s --health-timeout=10s --health-retries=10
strategy:
matrix:
php-versions: ['5.6', '7.2', '7.3', '7.4', '8.0', '8.1']
php-versions: ['5.6', '7.2', '7.3', '7.4', '8.0', '8.1', '8.2']
steps:
- name: Checkout
uses: actions/checkout@v2
@ -24,7 +24,7 @@ jobs:
with:
php-version: ${{ matrix.php-versions }}
coverage: none
tools: composer, phpunit-polyfills
tools: composer, phpunit-polyfills
extensions: mysql
- name: Install Composer dependencies for PHP
uses: "ramsey/composer-install@v1"

View file

@ -10,7 +10,7 @@ jobs:
steps:
- uses: actions/checkout@master
- name: WordPress.org plugin asset/readme update
uses: 10up/action-wordpress-plugin-asset-update@master
uses: 10up/action-wordpress-plugin-asset-update@stable
env:
SVN_PASSWORD: ${{ secrets.SVN_PASSWORD }}
SVN_USERNAME: ${{ secrets.SVN_USERNAME }}

2
.gitignore vendored
View file

@ -5,5 +5,5 @@ composer.lock
.DS_Store
.idea/
.php_cs.cache
.vscode/settings.json
.phpunit.result.cache

View file

@ -1,5 +1,5 @@
# ActivityPub #
**Contributors:** [pfefferle](https://profiles.wordpress.org/pfefferle), [mediaformat](https://profiles.wordpress.org/mediaformat)
**Contributors:** [pfefferle](https://profiles.wordpress.org/pfefferle/), [mediaformat](https://profiles.wordpress.org/mediaformat/)
**Donate link:** https://notiz.blog/donate/
**Tags:** OStatus, fediverse, activitypub, activitystream
**Requires at least:** 4.7

View file

@ -22,9 +22,13 @@ function init() {
\defined( 'ACTIVITYPUB_HASHTAGS_REGEXP' ) || \define( 'ACTIVITYPUB_HASHTAGS_REGEXP', '(?:(?<=\s)|(?<=<p>)|(?<=<br>)|^)#([A-Za-z0-9_]+)(?:(?=\s|[[:punct:]]|$))' );
\defined( 'ACTIVITYPUB_ALLOWED_HTML' ) || \define( 'ACTIVITYPUB_ALLOWED_HTML', '<strong><a><p><ul><ol><li><code><blockquote><pre><img>' );
\defined( 'ACTIVITYPUB_CUSTOM_POST_CONTENT' ) || \define( 'ACTIVITYPUB_CUSTOM_POST_CONTENT', "<p><strong>%title%</strong></p>\n\n%content%\n\n<p>%hashtags%</p>\n\n<p>%shortlink%</p>" );
\define( 'ACTIVITYPUB_PLUGIN_DIR', plugin_dir_path( __FILE__ ) );
\define( 'ACTIVITYPUB_PLUGIN_BASENAME', plugin_basename( __FILE__ ) );
\define( 'ACTIVITYPUB_PLUGIN_FILE', plugin_dir_path( __FILE__ ) . '/' . basename( __FILE__ ) );
require_once \dirname( __FILE__ ) . '/includes/table/followers-list.php';
require_once \dirname( __FILE__ ) . '/includes/class-signature.php';
require_once \dirname( __FILE__ ) . '/includes/class-webfinger.php';
require_once \dirname( __FILE__ ) . '/includes/peer/class-followers.php';
require_once \dirname( __FILE__ ) . '/includes/functions.php';
@ -107,7 +111,7 @@ function add_rewrite_rules() {
\add_rewrite_rule( '^.well-known/webfinger', 'index.php?rest_route=/activitypub/1.0/webfinger', 'top' );
}
if ( ! \class_exists( 'Nodeinfo' ) ) {
if ( ! \class_exists( 'Nodeinfo' ) || ! (bool) \get_option( 'blog_public', 1 ) ) {
\add_rewrite_rule( '^.well-known/nodeinfo', 'index.php?rest_route=/activitypub/1.0/nodeinfo/discovery', 'top' );
\add_rewrite_rule( '^.well-known/x-nodeinfo2', 'index.php?rest_route=/activitypub/1.0/nodeinfo2', 'top' );
}

View file

@ -0,0 +1,140 @@
.settings_page_activitypub .notice {
max-width: 800px;
margin: 0 auto;
}
.activitypub-settings-header {
text-align: center;
margin: 0 0 1rem;
background: #fff;
border-bottom: 1px solid #dcdcde;
}
.activitypub-settings-title-section {
display: flex;
align-items: center;
justify-content: center;
clear: both;
padding-top: 8px;
}
.settings_page_activitypub #wpcontent {
padding-left: 0;
}
.activitypub-settings-tabs-wrapper {
display: -ms-inline-grid;
-ms-grid-columns: 1fr 1fr;
vertical-align: top;
display: inline-grid;
grid-template-columns: 1fr 1fr;
}
.activitypub-settings-tab.active {
box-shadow: inset 0 -3px #3582c4;
font-weight: 600;
}
.activitypub-settings-tab {
display: block;
text-decoration: none;
color: inherit;
padding: .5rem 1rem 1rem;
margin: 0 1rem;
transition: box-shadow .5s ease-in-out;
}
.wp-header-end {
visibility: hidden;
margin: -2px 0 0;
}
summary {
cursor: pointer;
text-decoration: underline;
color: #2271b1;
}
.activitypub-settings-accordion {
border: 1px solid #c3c4c7;
}
.activitypub-settings-accordion-heading {
margin: 0;
border-top: 1px solid #c3c4c7;
font-size: inherit;
line-height: inherit;
font-weight: 600;
color: inherit;
}
.activitypub-settings-accordion-heading:first-child {
border-top: none;
}
.activitypub-settings-accordion-panel {
margin: 0;
padding: 1em 1.5em;
background: #fff;
}
.activitypub-settings-accordion-trigger {
background: #fff;
border: 0;
color: #2c3338;
cursor: pointer;
display: flex;
font-weight: 400;
margin: 0;
padding: 1em 3.5em 1em 1.5em;
min-height: 46px;
position: relative;
text-align: left;
width: 100%;
align-items: center;
justify-content: space-between;
-webkit-user-select: auto;
user-select: auto;
}
.activitypub-settings-accordion-trigger {
color: #2c3338;
cursor: pointer;
font-weight: 400;
text-align: left;
}
.activitypub-settings-accordion-trigger .title {
pointer-events: none;
font-weight: 600;
flex-grow: 1;
}
.activitypub-settings-accordion-trigger .icon, .activitypub-settings-accordion-viewed .icon {
border: solid #50575e medium;
border-width: 0 2px 2px 0;
height: .5rem;
pointer-events: none;
position: absolute;
right: 1.5em;
top: 50%;
transform: translateY(-70%) rotate(45deg);
width: .5rem;
}
.activitypub-settings-accordion-trigger[aria-expanded="true"] .icon {
transform: translateY(-30%) rotate(-135deg);
}
.activitypub-settings-accordion-trigger:active, .activitypub-settings-accordion-trigger:hover {
background: #f6f7f7;
}
.activitypub-settings-accordion-trigger:focus {
color: #1d2327;
border: none;
box-shadow: none;
outline-offset: -1px;
outline: 2px solid #2271b1;
background-color: #f6f7f7;
}

View file

@ -0,0 +1,20 @@
jQuery( function( $ ) {
// Accordion handling in various areas.
$( '.activitypub-settings-accordion' ).on( 'click', '.activitypub-settings-accordion-trigger', function() {
var isExpanded = ( 'true' === $( this ).attr( 'aria-expanded' ) );
if ( isExpanded ) {
$( this ).attr( 'aria-expanded', 'false' );
$( '#' + $( this ).attr( 'aria-controls' ) ).attr( 'hidden', true );
} else {
$( this ).attr( 'aria-expanded', 'true' );
$( '#' + $( this ).attr( 'aria-controls' ) ).attr( 'hidden', false );
}
} );
$(document).on( 'wp-plugin-install-success', function( event, response ) {
setTimeout( function() {
$( '.activate-now' ).removeClass( 'thickbox open-plugin-details-modal' );
}, 1200 );
} );
} );

View file

@ -14,6 +14,7 @@ class Admin {
\add_action( 'admin_menu', array( '\Activitypub\Admin', 'admin_menu' ) );
\add_action( 'admin_init', array( '\Activitypub\Admin', 'register_settings' ) );
\add_action( 'show_user_profile', array( '\Activitypub\Admin', 'add_fediverse_profile' ) );
\add_action( 'admin_enqueue_scripts', array( '\Activitypub\Admin', 'enqueue_scripts' ) );
}
/**
@ -21,7 +22,7 @@ class Admin {
*/
public static function admin_menu() {
$settings_page = \add_options_page(
'ActivityPub',
'Welcome',
'ActivityPub',
'manage_options',
'activitypub',
@ -39,7 +40,27 @@ class Admin {
* Load settings page
*/
public static function settings_page() {
\load_template( \dirname( __FILE__ ) . '/../templates/settings.php' );
// phpcs:ignore WordPress.Security.NonceVerification.Recommended
if ( empty( $_GET['tab'] ) ) {
$tab = 'welcome';
} else {
// phpcs:ignore WordPress.Security.NonceVerification.Recommended
$tab = sanitize_key( $_GET['tab'] );
}
switch ( $tab ) {
case 'settings':
\load_template( \dirname( __FILE__ ) . '/../templates/settings.php' );
break;
case 'welcome':
default:
wp_enqueue_script( 'plugin-install' );
add_thickbox();
wp_enqueue_script( 'updates' );
\load_template( \dirname( __FILE__ ) . '/../templates/welcome.php' );
break;
}
}
/**
@ -122,23 +143,7 @@ class Admin {
}
public static function add_settings_help_tab() {
\get_current_screen()->add_help_tab(
array(
'id' => 'overview',
'title' => \__( 'Overview', 'activitypub' ),
'content' =>
'<p>' . \__( 'ActivityPub is a decentralized social networking protocol based on the ActivityStreams 2.0 data format. ActivityPub is an official W3C recommended standard published by the W3C Social Web Working Group. It provides a client to server API for creating, updating and deleting content, as well as a federated server to server API for delivering notifications and subscribing to content.', 'activitypub' ) . '</p>',
)
);
\get_current_screen()->set_help_sidebar(
'<p><strong>' . \__( 'For more information:', 'activitypub' ) . '</strong></p>' .
'<p>' . \__( '<a href="https://activitypub.rocks/">Test Suite</a>', 'activitypub' ) . '</p>' .
'<p>' . \__( '<a href="https://www.w3.org/TR/activitypub/">W3C Spec</a>', 'activitypub' ) . '</p>' .
'<p>' . \__( '<a href="https://github.com/pfefferle/wordpress-activitypub/issues">Give us feedback</a>', 'activitypub' ) . '</p>' .
'<hr />' .
'<p>' . \__( '<a href="https://notiz.blog/donate">Donate</a>', 'activitypub' ) . '</p>'
);
require_once \dirname( __FILE__ ) . '/help.php';
}
public static function add_followers_list_help_tab() {
@ -147,8 +152,15 @@ class Admin {
public static function add_fediverse_profile( $user ) {
?>
<h2><?php \esc_html_e( 'Fediverse', 'activitypub' ); ?></h2>
<h2 id="activitypub"><?php \esc_html_e( 'ActivityPub', 'activitypub' ); ?></h2>
<?php
\Activitypub\get_identifier_settings( $user->ID );
}
public static function enqueue_scripts( $hook_suffix ) {
if ( false !== strpos( $hook_suffix, 'activitypub' ) ) {
wp_enqueue_style( 'activitypub-admin-styles', plugins_url( 'assets/css/activitypub-admin.css', ACTIVITYPUB_PLUGIN_FILE ), array(), '1.0.0' );
wp_enqueue_script( 'activitypub-admin-styles', plugins_url( 'assets/js/activitypub-admin.js', ACTIVITYPUB_PLUGIN_FILE ), array( 'jquery' ), '1.0.0', false );
}
}
}

View file

@ -17,13 +17,16 @@ class Debug {
}
public static function log_remote_post_responses( $response, $url, $body, $user_id ) {
// phpcs:ignore WordPress.PHP.DevelopmentFunctions.error_log_error_log, WordPress.PHP.DevelopmentFunctions.error_log_print_r
\error_log( "Request to: {$url} with response: " . \print_r( $response, true ) );
}
public static function write_log( $log ) {
if ( \is_array( $log ) || \is_object( $log ) ) {
// phpcs:ignore WordPress.PHP.DevelopmentFunctions.error_log_error_log, WordPress.PHP.DevelopmentFunctions.error_log_print_r
\error_log( \print_r( $log, true ) );
} else {
// phpcs:ignore WordPress.PHP.DevelopmentFunctions.error_log_error_log
\error_log( $log );
}
}

View file

@ -1,8 +1,6 @@
<?php
namespace Activitypub;
use Activitypub\Rest\Webfinger;
/**
* ActivityPub Health_Check Class
*
@ -17,6 +15,7 @@ class Health_Check {
*/
public static function init() {
\add_filter( 'site_status_tests', array( '\Activitypub\Health_Check', 'add_tests' ) );
\add_filter( 'debug_information', array( '\Activitypub\Health_Check', 'debug_information' ) );
}
public static function add_tests( $tests ) {
@ -203,7 +202,7 @@ class Health_Check {
$user = \wp_get_current_user();
$account = \Activitypub\get_webfinger_resource( $user->ID );
$url = Webfinger::resolve( $account );
$url = \Activitypub\Webfinger::resolve( $account );
if ( \is_wp_error( $url ) ) {
$health_messages = array(
'webfinger_url_not_accessible' => \sprintf(
@ -268,4 +267,30 @@ class Health_Check {
return $link;
}
/**
* Static function for generating site debug data when required.
*
* @param array $info The debug information to be added to the core information page.
* @return array The filtered informations
*/
public static function debug_information( $info ) {
$info['activitypub'] = array(
'label' => __( 'ActivityPub', 'activitypub' ),
'fields' => array(
'webfinger' => array(
'label' => __( 'WebFinger Resource', 'activitypub' ),
'value' => \Activitypub\Webfinger::get_user_resource( wp_get_current_user()->ID ),
'private' => true,
),
'author_url' => array(
'label' => __( 'Author URL', 'activitypub' ),
'value' => get_author_posts_url( wp_get_current_user()->ID ),
'private' => true,
),
),
);
return $info;
}
}

View file

@ -0,0 +1,69 @@
<?php
namespace Activitypub;
/**
* ActivityPub WebFinger Class
*
* @author Matthias Pfefferle
*
* @see https://webfinger.net/
*/
class Webfinger {
/**
* Returns a users WebFinger "resource"
*
* @param int $user_id
*
* @return string The user-resource
*/
public static function get_user_resource( $user_id ) {
// use WebFinger plugin if installed
if ( \function_exists( '\get_webfinger_resource' ) ) {
return \get_webfinger_resource( $user_id, false );
}
$user = \get_user_by( 'id', $user_id );
return $user->user_login . '@' . \wp_parse_url( \home_url(), \PHP_URL_HOST );
}
public static function resolve( $account ) {
if ( ! preg_match( '/^@?[^@]+@((?:[a-z0-9-]+\.)+[a-z]+)$/i', $account, $m ) ) {
return null;
}
$url = \add_query_arg( 'resource', 'acct:' . ltrim( $account, '@' ), 'https://' . $m[1] . '/.well-known/webfinger' );
if ( ! \wp_http_validate_url( $url ) ) {
return new \WP_Error( 'invalid_webfinger_url', null, $url );
}
// try to access author URL
$response = \wp_remote_get(
$url,
array(
'headers' => array( 'Accept' => 'application/activity+json' ),
'redirection' => 0,
)
);
if ( \is_wp_error( $response ) ) {
return new \WP_Error( 'webfinger_url_not_accessible', null, $url );
}
$response_code = \wp_remote_retrieve_response_code( $response );
$body = \wp_remote_retrieve_body( $response );
$body = \json_decode( $body, true );
if ( ! isset( $body['links'] ) ) {
return new \WP_Error( 'webfinger_url_invalid_response', null, $url );
}
foreach ( $body['links'] as $link ) {
if ( 'self' === $link['rel'] && 'application/activity+json' === $link['type'] ) {
return $link['href'];
}
}
return new \WP_Error( 'webfinger_url_no_activity_pub', null, $body );
}
}

View file

@ -95,14 +95,7 @@ function safe_remote_get( $url, $user_id ) {
* @return string The user-resource
*/
function get_webfinger_resource( $user_id ) {
// use WebFinger plugin if installed
if ( \function_exists( '\get_webfinger_resource' ) ) {
return \get_webfinger_resource( $user_id, false );
}
$user = \get_user_by( 'id', $user_id );
return $user->user_login . '@' . \wp_parse_url( \home_url(), \PHP_URL_HOST );
return \Activitypub\Webfinger::get_user_resource( $user_id );
}
/**
@ -118,7 +111,7 @@ function get_remote_metadata_by_actor( $actor ) {
return $pre;
}
if ( preg_match( '/^@?[^@]+@((?:[a-z0-9-]+\.)+[a-z]+)$/i', $actor ) ) {
$actor = Rest\Webfinger::resolve( $actor );
$actor = \Acivitypub\Webfinger::resolve( $actor );
}
if ( ! $actor ) {
@ -243,7 +236,7 @@ function get_identifier_settings( $user_id ) {
<td>
<p><code><?php echo \esc_html( \Activitypub\get_webfinger_resource( $user_id ) ); ?></code> or <code><?php echo \esc_url( \get_author_posts_url( $user_id ) ); ?></code></p>
<?php // translators: the webfinger resource ?>
<p class="description"><?php \printf( \esc_html__( 'Try to follow "@%s" in the Mastodon/Friendica search field.', 'activitypub' ), \esc_html( \Activitypub\get_webfinger_resource( $user_id ) ) ); ?></p>
<p class="description"><?php \printf( \esc_html__( 'Try to follow "@%s" by searching for it on Mastodon,Friendica & Co.', 'activitypub' ), \esc_html( \Activitypub\get_webfinger_resource( $user_id ) ) ); ?></p>
</td>
</tr>
</tbody>

55
includes/help.php Normal file
View file

@ -0,0 +1,55 @@
<?php
\get_current_screen()->add_help_tab(
array(
'id' => 'fediverse',
'title' => \__( 'Fediverse', 'activitypub' ),
'content' =>
'<p><strong>' . \__( 'What is the Fediverse?', 'activitypub' ) . '</strong></p>' .
'<p>' . \__( 'The Fediverse is a new word made of two words: "federation" + "universe"', 'activitypub' ) . '</p>' .
'<p>' . \__( 'It is a federated social network running on free open software on a myriad of computers across the globe. Many independent servers are interconnected and allow people to interact with one another. There\'s no one central site: you choose a server to register. This ensures some decentralization and sovereignty of data. Fediverse (also called Fedi) has no built-in advertisements, no tricky algorithms, no one big corporation dictating the rules. Instead we have small cozy communities of like-minded people. Welcome!', 'activitypub' ) . '</p>' .
'<p>' . \__( 'For more informations please visit <a href="https://fediverse.party/" target="_blank">fediverse.party</a>', 'activitypub' ) . '</p>',
)
);
\get_current_screen()->add_help_tab(
array(
'id' => 'activitypub',
'title' => \__( 'ActivityPub', 'activitypub' ),
'content' =>
'<p><strong>' . \__( 'What is ActivityPub?', 'activitypub' ) . '</strong></p>' .
'<p>' . \__( 'ActivityPub is a decentralized social networking protocol based on the ActivityStreams 2.0 data format. ActivityPub is an official W3C recommended standard published by the W3C Social Web Working Group. It provides a client to server API for creating, updating and deleting content, as well as a federated server to server API for delivering notifications and subscribing to content.', 'activitypub' ) . '</p>',
)
);
\get_current_screen()->add_help_tab(
array(
'id' => 'webfinger',
'title' => \__( 'WebFinger', 'activitypub' ),
'content' =>
'<p><strong>' . \__( 'What is WebFinger?', 'activitypub' ) . '</strong></p>' .
'<p>' . \__( 'WebFinger is used to discover information about people or other entities on the Internet that are identified by a URI using standard Hypertext Transfer Protocol (HTTP) methods over a secure transport. A WebFinger resource returns a JavaScript Object Notation (JSON) object describing the entity that is queried. The JSON object is referred to as the JSON Resource Descriptor (JRD).', 'activitypub' ) . '</p>' .
'<p>' . \__( 'For a person, the type of information that might be discoverable via WebFinger includes a personal profile address, identity service, telephone number, or preferred avatar. For other entities on the Internet, a WebFinger resource might return JRDs containing link relations that enable a client to discover, for example, that a printer can print in color on A4 paper, the physical location of a server, or other static information.', 'activitypub' ) . '</p>' .
'<p>' . \__( 'On Mastodon [and other Plattforms], user profiles can be hosted either locally on the same website as yours, or remotely on a completely different website. The same username may be used on a different domain. Therefore, a Mastodon user\'s full mention consists of both the username and the domain, in the form <code>@username@domain</code>. In practical terms, <code>@user@example.com</code> is not the same as <code>@user@example.org</code>. If the domain is not included, Mastodon will try to find a local user named <code>@username</code>. However, in order to deliver to someone over ActivityPub, the <code>@username@domain</code> mention is not enough mentions must be translated to an HTTPS URI first, so that the remote actor\'s inbox and outbox can be found. (This paragraph is copied from the <a href="https://docs.joinmastodon.org/spec/webfinger/" target="_blank">Mastodon Documentation</a>)', 'activitypub' ) . '</p>' .
'<p>' . \__( 'For more informations please visit <a href="https://webfinger.net/" target="_blank">webfinger.net</a>', 'activitypub' ) . '</p>',
)
);
\get_current_screen()->add_help_tab(
array(
'id' => 'nodeinfo',
'title' => \__( 'NodeInfo', 'activitypub' ),
'content' =>
'<p><strong>' . \__( 'What is NodeInfo?', 'activitypub' ) . '</strong></p>' .
'<p>' . \__( 'NodeInfo is an effort to create a standardized way of exposing metadata about a server running one of the distributed social networks. The two key goals are being able to get better insights into the user base of distributed social networking and the ability to build tools that allow users to choose the best fitting software and server for their needs.', 'activitypub' ) . '</p>' .
'<p>' . \__( 'For more informations please visit <a href="http://nodeinfo.diaspora.software/" target="_blank">nodeinfo.diaspora.software</a>', 'activitypub' ) . '</p>',
)
);
\get_current_screen()->set_help_sidebar(
'<p><strong>' . \__( 'For more information:', 'activitypub' ) . '</strong></p>' .
'<p>' . \__( '<a href="https://wordpress.org/support/plugin/activitypub/">Get support</a>', 'activitypub' ) . '</p>' .
'<p>' . \__( '<a href="https://github.com/pfefferle/wordpress-activitypub/issues">Report an issue</a>', 'activitypub' ) . '</p>' .
'<hr />' .
'<p>' . \__( '<a href="https://notiz.blog/donate">Donate</a>', 'activitypub' ) . '</p>'
);

View file

@ -73,9 +73,11 @@ class Outbox {
$json->actor = \get_author_posts_url( $user_id );
$json->type = 'OrderedCollectionPage';
$json->partOf = \get_rest_url( null, "/activitypub/1.0/users/$user_id/outbox" ); // phpcs:ignore
$json->totalItems = 0; // phpcs:ignore
// phpcs:ignore
$json->totalItems = 0;
foreach ( $post_types as $post_type ) {
$count_posts = \wp_count_posts( $post_type );
$json->totalItems += \intval( $count_posts->publish ); // phpcs:ignore

View file

@ -120,44 +120,4 @@ class Webfinger {
return $array;
}
public static function resolve( $account ) {
if ( ! preg_match( '/^@?[^@]+@((?:[a-z0-9-]+\.)+[a-z]+)$/i', $account, $m ) ) {
return null;
}
$url = \add_query_arg( 'resource', 'acct:' . ltrim( $account, '@' ), 'https://' . $m[1] . '/.well-known/webfinger' );
if ( ! \wp_http_validate_url( $url ) ) {
return new \WP_Error( 'invalid_webfinger_url', null, $url );
}
// try to access author URL
$response = \wp_remote_get(
$url,
array(
'headers' => array( 'Accept' => 'application/activity+json' ),
'redirection' => 0,
)
);
if ( \is_wp_error( $response ) ) {
return new \WP_Error( 'webfinger_url_not_accessible', null, $url );
}
$response_code = \wp_remote_retrieve_response_code( $response );
$body = \wp_remote_retrieve_body( $response );
$body = \json_decode( $body, true );
if ( ! isset( $body['links'] ) ) {
return new \WP_Error( 'webfinger_url_invalid_response', null, $url );
}
foreach ( $body['links'] as $link ) {
if ( 'self' === $link['rel'] && 'application/activity+json' === $link['type'] ) {
return $link['href'];
}
}
return new \WP_Error( 'webfinger_url_no_activity_pub', null, $body );
}
}

View file

@ -95,7 +95,7 @@ class Friends_Feed_Parser_ActivityPub extends \Friends\Feed_Parser {
*/
public function friends_rewrite_incoming_url( $url, $incoming_url ) {
if ( preg_match( '/^@?[^@]+@((?:[a-z0-9-]+\.)+[a-z]+)$/i', $incoming_url ) ) {
$resolved_url = \Activitypub\Rest\Webfinger::resolve( $incoming_url );
$resolved_url = \Activitypub\Webfinger::resolve( $incoming_url );
if ( ! is_wp_error( $resolved_url ) ) {
return $resolved_url;
}

View file

@ -0,0 +1,16 @@
<div class="activitypub-settings-header">
<div class="activitypub-settings-title-section">
<h1><?php \esc_html_e( 'ActivityPub', 'activitypub' ); ?></h1>
</div>
<nav class="activitypub-settings-tabs-wrapper hide-if-no-js" aria-label="<?php \esc_attr_e( 'Secondary menu', 'activitypub' ); ?>">
<a href="<?php echo \esc_url_raw( admin_url( 'options-general.php?page=activitypub' ) ); ?>" class="activitypub-settings-tab <?php echo \esc_attr( $args['welcome'] ); ?>">
<?php \esc_html_e( 'Welcome', 'activitypub' ); ?>
</a>
<a href="<?php echo \esc_url_raw( admin_url( 'options-general.php?page=activitypub&tab=settings' ) ); ?>" class="activitypub-settings-tab <?php echo \esc_attr( $args['settings'] ); ?>">
<?php \esc_html_e( 'Settings', 'activitypub' ); ?>
</a>
</nav>
</div>
<hr class="wp-header-end">

View file

@ -75,12 +75,6 @@ if ( \get_the_author_meta( 'user_url', $author_id ) ) {
);
}
/*
$json->endpoints = array(
'sharedInbox' => \get_rest_url( null, '/activitypub/1.0/inbox' ),
);
*/
// filter output
$json = \apply_filters( 'activitypub_json_author_array', $json, $author_id );

View file

@ -27,10 +27,10 @@ if ( \has_header_image() ) {
);
}
$json->inbox = \get_rest_url( null, "/activitypub/1.0/blog/inbox" );
$json->outbox = \get_rest_url( null, "/activitypub/1.0/blog/outbox" );
$json->followers = \get_rest_url( null, "/activitypub/1.0/blog/followers" );
$json->following = \get_rest_url( null, "/activitypub/1.0/blog/following" );
$json->inbox = \get_rest_url( null, '/activitypub/1.0/blog/inbox' );
$json->outbox = \get_rest_url( null, '/activitypub/1.0/blog/outbox' );
$json->followers = \get_rest_url( null, '/activitypub/1.0/blog/followers' );
$json->following = \get_rest_url( null, '/activitypub/1.0/blog/following' );
$json->manuallyApprovesFollowers = \apply_filters( 'activitypub_json_manually_approves_followers', \__return_false() ); // phpcs:ignore
@ -54,12 +54,6 @@ $json->attachment[] = array(
),
);
/*
$json->endpoints = array(
'sharedInbox' => \get_rest_url( null, '/activitypub/1.0/inbox' ),
);
*/
// filter output
$json = \apply_filters( 'activitypub_json_blog_array', $json );

View file

@ -1,7 +1,8 @@
<div class="wrap">
<h1><?php \esc_html_e( 'Followers (Fediverse)', 'activitypub' ); ?></h1>
<p><?php \printf( \__( 'You currently have %s followers.', 'activitypub' ), \esc_attr( \Activitypub\Peer\Followers::count_followers( \get_current_user_id() ) ) ); ?></p>
<?php // translators: ?>
<p><?php \printf( \esc_html__( 'You currently have %s followers.', 'activitypub' ), \esc_attr( \Activitypub\Peer\Followers::count_followers( \get_current_user_id() ) ) ); ?></p>
<?php $token_table = new \Activitypub\Table\Followers_List(); ?>

View file

@ -1,4 +1,5 @@
<?php
// phpcs:ignore WordPress.WP.GlobalVariablesOverride.Prohibited
$post = \get_post();
$activitypub_post = new \Activitypub\Model\Post( $post );

View file

@ -1,12 +1,36 @@
<div class="wrap">
<h1><?php \esc_html_e( 'ActivityPub Settings', 'activitypub' ); ?></h1>
<?php
\load_template(
\dirname( __FILE__ ) . '/admin-header.php',
true,
array(
'settings' => 'active',
'welcome' => '',
)
);
?>
<p><?php \esc_html_e( 'ActivityPub turns your blog into a federated social network. This means you can share and talk to everyone using the ActivityPub protocol, including users of Friendica, Pleroma and Mastodon.', 'activitypub' ); ?></p>
<div class="privacy-settings-body hide-if-no-js">
<div class="notice notice-info">
<p>
<?php
echo \wp_kses(
\sprintf(
// translators:
\__( 'If you have problems using this plugin, please check the <a href="%s">Site Health</a> to ensure that your site is compatible and/or use the "Help" tab (in the top right of the settings pages).', 'activitypub' ),
\esc_url_raw( \admin_url( 'site-health.php' ) )
),
'default'
);
?>
</p>
</div>
<p><?php \esc_html_e( 'Customize your ActivityPub settings to suit your needs.', 'activitypub' ); ?></p>
<form method="post" action="options.php">
<?php \settings_fields( 'activitypub' ); ?>
<h2><?php \esc_html_e( 'Activities', 'activitypub' ); ?></h2>
<h3><?php \esc_html_e( 'Activities', 'activitypub' ); ?></h3>
<p><?php \esc_html_e( 'All activity related settings.', 'activitypub' ); ?></p>
@ -30,19 +54,24 @@
<label><input type="radio" name="activitypub_post_content_type" id="activitypub_post_content_type_custom" value="custom" <?php echo \checked( 'custom', \get_option( 'activitypub_post_content_type', 'content' ) ); ?> /> <?php \esc_html_e( 'Custom', 'activitypub' ); ?></label> - <span class="description"><?php \esc_html_e( 'Use the text-area below, to customize your activities.', 'activitypub' ); ?></span>
</p>
<p>
<textarea name="activitypub_custom_post_content" id="activitypub_custom_post_content" rows="10" cols="50" class="large-text" placeholder="<?php echo ACTIVITYPUB_CUSTOM_POST_CONTENT; ?>"><?php echo \get_option( 'activitypub_custom_post_content', ACTIVITYPUB_CUSTOM_POST_CONTENT ); ?></textarea>
<div class="description">
<ul>
<li><code>%title%</code> - <?php \esc_html_e( 'The Post-Title.', 'activitypub' ); ?></li>
<li><code>%content%</code> - <?php \esc_html_e( 'The Post-Content.', 'activitypub' ); ?></li>
<li><code>%excerpt%</code> - <?php \esc_html_e( 'The Post-Excerpt (default 400 Chars).', 'activitypub' ); ?></li>
<li><code>%permalink%</code> - <?php \esc_html_e( 'The Post-Permalink.', 'activitypub' ); ?></li>
<li><code>%shortlink%</code> - <?php \printf( \esc_html( 'The Post-Shortlink. I can recommend %sHum%s, to prettify the Shortlinks', 'activitypub' ), '<a href="https://wordpress.org/plugins/hum/" target="_blank">', '</a>' ); ?></li>
<li><code>%hashtags%</code> - <?php \esc_html_e( 'The Tags as Hashtags.', 'activitypub' ); ?></li>
</ul>
<?php \printf( \__( '%sLet me know%s if you miss a template placeholder.', 'activitypub' ), '<a href="https://github.com/pfefferle/wordpress-activitypub/issues/new" target="_blank">', '</a>' ); ?>
</div>
<textarea name="activitypub_custom_post_content" id="activitypub_custom_post_content" rows="10" cols="50" class="large-text" placeholder="<?php echo wp_kses( ACTIVITYPUB_CUSTOM_POST_CONTENT, 'post' ); ?>"><?php echo wp_kses( \get_option( 'activitypub_custom_post_content', ACTIVITYPUB_CUSTOM_POST_CONTENT ), 'post' ); ?></textarea>
<details>
<summary><?php esc_html_e( 'See the complete list of template patterns.', 'activitypub' ); ?></summary>
<div class="description">
<ul>
<li><code>%title%</code> - <?php \esc_html_e( 'The Post-Title.', 'activitypub' ); ?></li>
<li><code>%content%</code> - <?php \esc_html_e( 'The Post-Content.', 'activitypub' ); ?></li>
<li><code>%excerpt%</code> - <?php \esc_html_e( 'The Post-Excerpt (default 400 Chars).', 'activitypub' ); ?></li>
<li><code>%permalink%</code> - <?php \esc_html_e( 'The Post-Permalink.', 'activitypub' ); ?></li>
<?php // translators: ?>
<li><code>%shortlink%</code> - <?php echo \wp_kses( \__( 'The Post-Shortlink. I can recommend <a href="https://wordpress.org/plugins/hum/" target="_blank">Hum</a>, to prettify the Shortlinks', 'activitypub' ), 'default' ); ?></li>
<li><code>%hashtags%</code> - <?php \esc_html_e( 'The Tags as Hashtags.', 'activitypub' ); ?></li>
</ul>
</div>
</details>
</p>
<?php // translators: ?>
<p><?php echo \wp_kses( \__( '<a href="https://github.com/pfefferle/wordpress-activitypub/issues/new" target="_blank">Let me know</a> if you miss a template pattern.', 'activitypub' ), 'default' ); ?></p>
</td>
</tr>
<tr>
@ -70,6 +99,7 @@
<?php $post_types = \get_post_types( array( 'public' => true ), 'objects' ); ?>
<?php $support_post_types = \get_option( 'activitypub_support_post_types', array( 'post', 'page' ) ) ? \get_option( 'activitypub_support_post_types', array( 'post', 'page' ) ) : array(); ?>
<ul>
<?php // phpcs:ignore WordPress.WP.GlobalVariablesOverride.Prohibited ?>
<?php foreach ( $post_types as $post_type ) { ?>
<li>
<input type="checkbox" id="activitypub_support_post_types" name="activitypub_support_post_types[]" value="<?php echo \esc_attr( $post_type->name ); ?>" <?php echo \checked( true, \in_array( $post_type->name, $support_post_types, true ) ); ?> />
@ -86,17 +116,28 @@
</th>
<td>
<p>
<label><input type="checkbox" name="activitypub_use_hashtags" id="activitypub_use_hashtags" value="1" <?php echo \checked( '1', \get_option( 'activitypub_use_hashtags', '1' ) ); ?> /> <?php \_e( 'Add hashtags in the content as native tags and replace the <code>#tag</code> with the tag-link.', 'activitypub' ); ?></label>
<label><input type="checkbox" name="activitypub_use_hashtags" id="activitypub_use_hashtags" value="1" <?php echo \checked( '1', \get_option( 'activitypub_use_hashtags', '1' ) ); ?> /> <?php echo wp_kses( \__( 'Add hashtags in the content as native tags and replace the <code>#tag</code> with the tag-link.', 'activitypub' ), 'default' ); ?></label>
</p>
</td>
</tr>
<tr>
<th scope="row">
<?php \esc_html_e( 'HTML Whitelist', 'activitypub' ); ?>
<?php \esc_html_e( 'HTML Allowlist', 'activitypub' ); ?>
</th>
<td>
<textarea name="activitypub_allowed_html" id="activitypub_allowed_html" rows="3" cols="50" class="large-text"><?php echo \get_option( 'activitypub_allowed_html', ACTIVITYPUB_ALLOWED_HTML ); ?></textarea>
<p class="description"><?php \_e( \sprintf( 'A list of HTML elements, you want to whitelist for your activities. <strong>Leave list empty to support all HTML elements.</strong> Default: <code>%s</code>.', \esc_html( ACTIVITYPUB_ALLOWED_HTML ) ), 'activitypub' ); ?></p>
<textarea name="activitypub_allowed_html" id="activitypub_allowed_html" rows="3" cols="50" class="large-text"><?php echo esc_html( \get_option( 'activitypub_allowed_html', ACTIVITYPUB_ALLOWED_HTML ) ); ?></textarea>
<p class="description">
<?php
echo \wp_kses(
\sprintf(
// translators:
\__( 'A list of HTML elements, you want to allowlist for your activities. <strong>Leave list empty to support all HTML elements</strong>. Default: <code>%s</code>', 'activitypub' ),
\esc_html( ACTIVITYPUB_ALLOWED_HTML )
),
'default'
);
?>
</p>
</td>
</tr>
</tbody>
@ -104,7 +145,7 @@
<?php \do_settings_fields( 'activitypub', 'activity' ); ?>
<h2><?php \esc_html_e( 'Server', 'activitypub' ); ?></h2>
<h3><?php \esc_html_e( 'Server', 'activitypub' ); ?></h3>
<p><?php \esc_html_e( 'Server related settings.', 'activitypub' ); ?></p>
@ -115,7 +156,18 @@
<?php \esc_html_e( 'Blocklist', 'activitypub' ); ?>
</th>
<td>
<p class="description"><?php \printf( \__( 'To block servers, add the host of the server to the "<a href="%s">Disallowed Comment Keys</a>" list.', 'activitypub' ), admin_url( 'options-discussion.php#disallowed_keys' ) ); ?></p>
<p class="description">
<?php
echo \wp_kses(
\sprintf(
// translators: %s is a URL.
\__( 'To block servers, add the host of the server to the "<a href="%s">Disallowed Comment Keys</a>" list.', 'activitypub' ),
\esc_attr( \admin_url( 'options-discussion.php#disallowed_keys' ) )
),
'default'
);
?>
</p>
</td>
</tr>
</tbody>
@ -127,8 +179,4 @@
<?php \submit_button(); ?>
</form>
<p>
<small><?php \_e( 'If you like this plugin, what about a small <a href="https://notiz.blog/donate">donation</a>?', 'activitypub' ); ?></small>
</p>
</div>

96
templates/welcome.php Normal file
View file

@ -0,0 +1,96 @@
<?php
\load_template(
\dirname( __FILE__ ) . '/admin-header.php',
true,
array(
'settings' => '',
'welcome' => 'active',
)
);
?>
<div class="privacy-settings-body hide-if-no-js">
<h2><?php \esc_html_e( 'Welcome', 'activitypub' ); ?></h2>
<p><?php \esc_html_e( 'With ActivityPub your blog becomes part of a federated social network. This means you can share and talk to everyone using the ActivityPub protocol, including users of Friendica, Pleroma and Mastodon.', 'activitypub' ); ?></p>
<p>
<?php
echo wp_kses(
\sprintf(
// translators:
\__(
'People can follow you by using the username <code>%1$s</code> or the URL <code>%2$s</code>. Users who can not access this settings page will find their username on the <a href="%3$s">Edit Profile</a> page.',
'activitypub'
),
\esc_attr( \Activitypub\get_webfinger_resource( wp_get_current_user()->ID ) ),
\esc_url_raw( \get_author_posts_url( wp_get_current_user()->ID ) ),
\esc_url_raw( \admin_url( 'profile.php#activitypub' ) )
),
'default'
);
?>
</p>
<p>
<?php
echo wp_kses(
\sprintf(
// translators:
\__( 'If you have problems using this plugin, please check the <a href="%s">Site Health</a> to ensure that your site is compatible and/or use the "Help" tab (in the top right of the settings pages).', 'activitypub' ),
\esc_url_raw( admin_url( 'site-health.php' ) )
),
'default'
);
?>
</p>
<hr />
<h3><?php \esc_html_e( 'Recommended Plugins', 'activitypub' ); ?></h3>
<p><?php \esc_html_e( 'ActivityPub works as is and there is no need for you to install additional plugins, nevertheless there are some plugins that extends the functionality of ActivityPub.', 'activitypub' ); ?></p>
<div class="activitypub-settings-accordion">
<h4 class="activitypub-settings-accordion-heading">
<button aria-expanded="true" class="activitypub-settings-accordion-trigger" aria-controls="activitypub-settings-accordion-block-friends-plugin" type="button">
<span class="title"><?php \esc_html_e( 'Following Others', 'activitypub' ); ?></span>
<span class="icon"></span>
</button>
</h4>
<div id="activitypub-settings-accordion-block-friends-plugin" class="activitypub-settings-accordion-panel plugin-card-friends">
<p><?php \esc_html_e( 'To follow people on Mastodon or similar platforms using your own WordPress, you can use the Friends Plugin for WordPress which uses this plugin to receive posts and display them on your own WordPress, thus making your own WordPress a Fediverse instance of its own.', 'activitypub' ); ?></p>
<p><a href="<?php echo \esc_url_raw( \admin_url( 'plugin-install.php?tab=plugin-information&plugin=friends&TB_iframe=true' ) ); ?>" class="thickbox open-plugin-details-modal button install-now" target="_blank"><?php \esc_html_e( 'Install the Friends Plugin for WordPress', 'activitypub' ); ?></a></p>
</div>
<h4 class="activitypub-settings-accordion-heading">
<button aria-expanded="false" class="activitypub-settings-accordion-trigger" aria-controls="activitypub-settings-accordion-block-activitypub-hum-plugin" type="button">
<span class="title"><?php \esc_html_e( 'Add a URL Shortener', 'activitypub' ); ?></span>
<span class="icon"></span>
</button>
</h4>
<div id="activitypub-settings-accordion-block-activitypub-hum-plugin" class="activitypub-settings-accordion-panel plugin-card-hum" hidden="hidden">
<p><?php \esc_html_e( 'Hum is a personal URL shortener for WordPress, designed to provide short URLs to your personal content, both hosted on WordPress and elsewhere.', 'activitypub' ); ?></p>
<p><a href="<?php echo \esc_url_raw( \admin_url( 'plugin-install.php?tab=plugin-information&plugin=hum&TB_iframe=true' ) ); ?>" class="thickbox open-plugin-details-modal button install-now" target="_blank"><?php \esc_html_e( 'Install Hum Plugin for WordPress', 'activitypub' ); ?></a></p>
</div>
<h4 class="activitypub-settings-accordion-heading">
<button aria-expanded="false" class="activitypub-settings-accordion-trigger" aria-controls="activitypub-settings-accordion-block-activitypub-webfinger-plugin" type="button">
<span class="title"><?php \esc_html_e( 'Advanced WebFinger Support', 'activitypub' ); ?></span>
<span class="icon"></span>
</button>
</h4>
<div id="activitypub-settings-accordion-block-activitypub-webfinger-plugin" class="activitypub-settings-accordion-panel plugin-card-webfinger" hidden="hidden">
<p><?php \esc_html_e( 'WebFinger is a protocol that allows for discovery of information about people and things identified by a URI. Information about a person might be discovered via an "acct:" URI, for example, which is a URI that looks like an email address.', 'activitypub' ); ?></p>
<p><?php \esc_html_e( 'The ActivityPub plugin comes with basic WebFinger support, if you need more configuration options and compatibility with other Fediverse/IndieWeb plugins, please install the WebFinger plugin.', 'activitypub' ); ?></p>
<p><a href="<?php echo \esc_url_raw( \admin_url( 'plugin-install.php?tab=plugin-information&plugin=webfinger&TB_iframe=true' ) ); ?>" class="thickbox open-plugin-details-modal button install-now" target="_blank"><?php \esc_html_e( 'Install WebFinger Plugin for WordPress', 'activitypub' ); ?></a></p>
</div>
<h4 class="activitypub-settings-accordion-heading">
<button aria-expanded="false" class="activitypub-settings-accordion-trigger" aria-controls="activitypub-settings-accordion-block-activitypub-nodeinfo-plugin" type="button">
<span class="title"><?php \esc_html_e( 'Provide Enhanced Information about Your Blog', 'activitypub' ); ?></span>
<span class="icon"></span>
</button>
</h4>
<div id="activitypub-settings-accordion-block-activitypub-nodeinfo-plugin" class="activitypub-settings-accordion-panel plugin-card-nodeinfo" hidden="hidden">
<p><?php \esc_html_e( 'NodeInfo is an effort to create a standardized way of exposing metadata about a server running one of the distributed social networks. The two key goals are being able to get better insights into the user base of distributed social networking and the ability to build tools that allow users to choose the best fitting software and server for their needs.', 'activitypub' ); ?></p>
<p><?php \esc_html_e( 'The ActivityPub plugin comes with a simple NodeInfo endpoint. If you need more configuration options and compatibility with other Fediverse plugins, please install the NodeInfo plugin.', 'activitypub' ); ?></p>
<p><a href="<?php echo \esc_url_raw( \admin_url( 'plugin-install.php?tab=plugin-information&plugin=nodeinfo&TB_iframe=true' ) ); ?>" class="thickbox open-plugin-details-modal button install-now" target="_blank"><?php \esc_html_e( 'Install NodeInfo Plugin for WordPress', 'activitypub' ); ?></a></p>
</div>
</div>
</div>