PluginProbe
ActivityPub / 7.8.2
ActivityPub v7.8.2
9.3.1 9.3.0 9.2.2 9.2.1 9.2.0 9.1.0 9.0.2 9.0.1 9.0.0 8.3.0 8.2.1 8.2.0 8.1.1 1.0.5 1.0.6 1.0.7 1.0.8 1.0.9 1.1.0 1.2.0 1.3.0 2.0.0 2.0.1 2.1.0 2.1.1 All 160 releases
← All changes | includes/wp-admin/class-admin.php +75 -234 8.2.07.8.2 View file →
@@ -10,13 +10,11 @@
10 10 use Activitypub\Blocklist_Subscriptions;
11 11 use Activitypub\Collection\Actors;
12 12 use Activitypub\Collection\Extra_Fields;
13 13 use Activitypub\Comment;
14 +use Activitypub\Model\Blog;
14 15 use Activitypub\Moderation;
15 -use Activitypub\OAuth\Client;
16 -use Activitypub\OAuth\Token;
17 16 use Activitypub\Scheduler\Actor;
18 -use Activitypub\Tombstone;
19 17
20 18 use function Activitypub\count_followers;
21 19 use function Activitypub\get_content_visibility;
22 20 use function Activitypub\is_user_type_disabled;
@@ -60,11 +58,8 @@
60 58 \add_action( 'admin_action_activitypub_confirm_removal', array( self::class, 'handle_bulk_actor_delete_page' ) );
61 59
62 60 if ( user_can_activitypub( \get_current_user_id() ) ) {
63 61 \add_action( 'show_user_profile', array( self::class, 'add_profile' ) );
64 - if ( \get_option( 'activitypub_api', false ) ) {
65 - \add_action( 'show_user_profile', array( User_Settings_Fields::class, 'connected_apps_section' ) );
66 - }
67 62 }
68 63
69 64 \add_filter( 'dashboard_glance_items', array( self::class, 'dashboard_glance_items' ) );
70 65 \add_filter( 'plugin_action_links_' . ACTIVITYPUB_PLUGIN_BASENAME, array( self::class, 'add_plugin_settings_link' ) );
@@ -74,19 +69,15 @@
74 69 \add_action( 'tool_box', array( self::class, 'tool_box' ) );
75 70 }
76 71
77 72 \add_action( 'admin_print_scripts-profile.php', array( self::class, 'enqueue_moderation_scripts' ) );
78 - \add_action( 'admin_print_scripts-profile.php', array( self::class, 'enqueue_connected_apps_scripts' ) );
79 73 \add_action( 'admin_print_scripts-settings_page_activitypub', array( self::class, 'enqueue_moderation_scripts' ) );
80 74 \add_action( 'admin_print_footer_scripts-settings_page_activitypub', array( self::class, 'open_help_tab' ) );
81 75
76 + \add_action( 'wp_dashboard_setup', array( self::class, 'add_dashboard_widgets' ) );
77 +
82 78 \add_action( 'wp_ajax_activitypub_moderation_settings', array( self::class, 'ajax_moderation_settings' ) );
83 79 \add_action( 'wp_ajax_activitypub_blocklist_subscription', array( self::class, 'ajax_blocklist_subscription' ) );
84 - \add_action( 'wp_ajax_activitypub_register_oauth_client', array( self::class, 'ajax_register_oauth_client' ) );
85 - \add_action( 'wp_ajax_activitypub_delete_oauth_client', array( self::class, 'ajax_delete_oauth_client' ) );
86 - \add_action( 'wp_ajax_activitypub_delete_all_oauth_clients', array( self::class, 'ajax_delete_all_oauth_clients' ) );
87 - \add_action( 'wp_ajax_activitypub_revoke_oauth_token', array( self::class, 'ajax_revoke_oauth_token' ) );
88 - \add_action( 'wp_ajax_activitypub_revoke_all_oauth_tokens', array( self::class, 'ajax_revoke_all_oauth_tokens' ) );
89 80 }
90 81
91 82 /**
92 83 * Display admin menu notices about configuration problems or conflicts.
@@ -259,10 +250,8 @@
259 250 'activitypub_hide_social_graph',
260 251 'activitypub_mailer_new_dm',
261 252 'activitypub_mailer_new_follower',
262 253 'activitypub_mailer_new_mention',
263 - 'activitypub_mailer_annual_report',
264 - 'activitypub_mailer_monthly_report',
265 254 );
266 255
267 256 foreach ( $required_user_options as $option ) {
268 257 \update_user_option( $user_id, $option, sanitize_text_field( wp_unslash( $_POST[ $option ] ?? 0 ) ) );
@@ -345,15 +334,8 @@
345 334 array(),
346 335 ACTIVITYPUB_PLUGIN_VERSION
347 336 );
348 337 }
349 -
350 - if ( 'edit-comments.php' === $hook_suffix ) {
351 - \wp_add_inline_style(
352 - 'wp-emoji-styles',
353 - '.column-author img.emoji { float: none; }'
354 - );
355 - }
356 338 }
357 339
358 340 /**
359 341 * Enqueue moderation admin scripts.
@@ -383,48 +365,8 @@
383 365 );
384 366 }
385 367
386 368 /**
387 - * Enqueue connected apps admin scripts on the profile page.
388 - *
389 - * @since 8.1.0
390 - */
391 - public static function enqueue_connected_apps_scripts() {
392 - \wp_enqueue_script(
393 - 'activitypub-connected-apps',
394 - ACTIVITYPUB_PLUGIN_URL . 'assets/js/activitypub-connected-apps.js',
395 - array( 'jquery' ),
396 - ACTIVITYPUB_PLUGIN_VERSION,
397 - true
398 - );
399 -
400 - \wp_localize_script(
401 - 'activitypub-connected-apps',
402 - 'activitypubConnectedApps',
403 - array(
404 - 'ajaxUrl' => \admin_url( 'admin-ajax.php' ),
405 - 'nonce' => \wp_create_nonce( 'activitypub_connected_apps' ),
406 - 'confirm' => \__( 'Are you sure you want to revoke this application token? This action cannot be undone.', 'activitypub' ),
407 - 'confirmAll' => \__( 'Are you sure you want to revoke all connected applications? This action cannot be undone.', 'activitypub' ),
408 - 'confirmDelete' => \__( 'Are you sure you want to delete this application? This action cannot be undone.', 'activitypub' ),
409 - 'confirmDeleteAll' => \__( 'Are you sure you want to delete all registered applications? This action cannot be undone.', 'activitypub' ),
410 - 'registerError' => \__( 'Failed to register application.', 'activitypub' ),
411 - 'deleteLabel' => \__( 'Delete', 'activitypub' ),
412 - 'dismiss' => \__( 'Dismiss this notice.', 'activitypub' ),
413 - 'clientIdLabel' => \__( 'Your new Client ID:', 'activitypub' ),
414 - 'clientSecretLabel' => \__( 'Your new Client Secret:', 'activitypub' ),
415 - 'copy' => \__( 'Copy', 'activitypub' ),
416 - 'copied' => \__( 'Copied!', 'activitypub' ),
417 - 'saveWarning' => \__( 'Be sure to save this in a safe location. You will not be able to retrieve it.', 'activitypub' ),
418 - 'appRevoked' => \__( 'Application token revoked.', 'activitypub' ),
419 - 'allAppsRevoked' => \__( 'All application tokens revoked.', 'activitypub' ),
420 - 'appDeleted' => \__( 'Application deleted.', 'activitypub' ),
421 - 'allAppsDeleted' => \__( 'All registered applications deleted.', 'activitypub' ),
422 - )
423 - );
424 - }
425 -
426 - /**
427 369 * Hook into the edit_comment functionality.
428 370 *
429 371 * Disables the edit_comment capability for federated comments.
430 372 */
@@ -675,14 +617,8 @@
675 617 case 'add_activitypub_cap':
676 618 foreach ( $users as $user_id ) {
677 619 $user = new \WP_User( $user_id );
678 620 $user->add_cap( 'activitypub' );
679 -
680 - // Remove user from tombstone registry if they were previously buried.
681 - $actor = Actors::get_by_id( $user_id );
682 - if ( ! \is_wp_error( $actor ) ) {
683 - Tombstone::remove( $actor->get_id(), $actor->get_url() );
684 - }
685 621 }
686 622 return $send_back;
687 623 case 'remove_activitypub_cap':
688 624 $removed_count = 0;
@@ -1004,8 +940,80 @@
1004 940 <?php
1005 941 }
1006 942
1007 943 /**
944 + * Add Dashboard widgets.
945 + */
946 + public static function add_dashboard_widgets() {
947 + \wp_add_dashboard_widget( 'activitypub_blog', \__( 'ActivityPub Plugin News', 'activitypub' ), array( self::class, 'blog_dashboard_widget' ) );
948 + if ( user_can_activitypub( \get_current_user_id() ) && ! is_user_type_disabled( 'user' ) ) {
949 + \wp_add_dashboard_widget( 'activitypub_profile', \__( 'ActivityPub Author profile', 'activitypub' ), array( self::class, 'profile_dashboard_widget' ) );
950 + }
951 + if ( ! is_user_type_disabled( 'blog' ) ) {
952 + \wp_add_dashboard_widget( 'activitypub_blog_profile', \__( 'ActivityPub Blog profile', 'activitypub' ), array( self::class, 'blogprofile_dashboard_widget' ) );
953 + }
954 + }
955 +
956 + /**
957 + * Add the `ActivityPub.blog` feed as a Dashboard widget.
958 + */
959 + public static function blog_dashboard_widget() {
960 + echo '<div class="rss-widget">';
961 + \wp_widget_rss_output(
962 + array(
963 + 'url' => 'https://activitypub.blog/feed/',
964 + 'items' => 3,
965 + 'show_summary' => 1,
966 + 'show_author' => 0,
967 + 'show_date' => 1,
968 + )
969 + );
970 + echo '</div>';
971 + }
972 +
973 + /**
974 + * Add the ActivityPub Author profile as a Dashboard widget.
975 + */
976 + public static function profile_dashboard_widget() {
977 + $user = Actors::get_by_id( \get_current_user_id() );
978 + ?>
979 + <p>
980 + <?php \esc_html_e( 'People can follow you by using your author name:', 'activitypub' ); ?>
981 + </p>
982 + <p><label for="activitypub-user-identifier"><?php \esc_html_e( 'Username', 'activitypub' ); ?></label><input type="text" class="large-text code" id="activitypub-user-identifier" value="<?php echo \esc_attr( $user->get_webfinger() ); ?>" readonly /></p>
983 + <p><label for="activitypub-user-url"><?php \esc_html_e( 'Profile URL', 'activitypub' ); ?></label><input type="text" class="large-text code" id="activitypub-user-url" value="<?php echo \esc_attr( $user->get_url() ); ?>" readonly /></p>
984 + <p>
985 + <?php \esc_html_e( 'Authors who can not access this settings page will find their username on the "Edit Profile" page.', 'activitypub' ); ?>
986 + <a href="<?php echo \esc_url( \admin_url( '/profile.php#activitypub' ) ); ?>">
987 + <?php \esc_html_e( 'Customize username on "Edit Profile" page.', 'activitypub' ); ?>
988 + </a>
989 + </p>
990 + <?php
991 + }
992 +
993 + /**
994 + * Add the ActivityPub Blog profile as a Dashboard widget.
995 + */
996 + public static function blogprofile_dashboard_widget() {
997 + $user = new Blog();
998 + ?>
999 + <p>
1000 + <?php \esc_html_e( 'People can follow your blog by using:', 'activitypub' ); ?>
1001 + </p>
1002 + <p><label for="activitypub-user-identifier"><?php \esc_html_e( 'Username', 'activitypub' ); ?></label><input type="text" class="large-text code" id="activitypub-user-identifier" value="<?php echo \esc_attr( $user->get_webfinger() ); ?>" readonly /></p>
1003 + <p><label for="activitypub-user-url"><?php \esc_html_e( 'Profile URL', 'activitypub' ); ?></label><input type="text" class="large-text code" id="activitypub-user-url" value="<?php echo \esc_attr( $user->get_url() ); ?>" readonly /></p>
1004 + <p>
1005 + <?php \esc_html_e( 'This blog profile will federate all posts written on your blog, regardless of the author who posted it.', 'activitypub' ); ?>
1006 + <?php if ( current_user_can( 'manage_options' ) ) : ?>
1007 + <a href="<?php echo \esc_url( \admin_url( '/options-general.php?page=activitypub&tab=blog-profile' ) ); ?>">
1008 + <?php \esc_html_e( 'Customize the blog profile.', 'activitypub' ); ?>
1009 + </a>
1010 + <?php endif; ?>
1011 + </p>
1012 + <?php
1013 + }
1014 +
1015 + /**
1008 1016 * AJAX handler for moderation settings (add/remove blocks).
1009 1017 */
1010 1018 public static function ajax_moderation_settings() {
1011 1019 $context = \sanitize_text_field( \wp_unslash( $_POST['context'] ?? '' ) );
@@ -1109,173 +1117,6 @@
1109 1117 \wp_send_json_success();
1110 1118 } else {
1111 1119 \wp_send_json_error( array( 'message' => \__( 'Failed to remove subscription.', 'activitypub' ) ) );
1112 1120 }
1113 - }
1114 -
1115 - /**
1116 - * AJAX handler for registering a new OAuth client from the user profile.
1117 - *
1118 - * @since 8.1.0
1119 - */
1120 - public static function ajax_register_oauth_client() {
1121 - // Verify nonce.
1122 - if ( ! \wp_verify_nonce( \sanitize_text_field( \wp_unslash( $_POST['_wpnonce'] ?? '' ) ), 'activitypub_connected_apps' ) ) {
1123 - \wp_send_json_error( array( 'message' => \__( 'Invalid nonce.', 'activitypub' ) ) );
1124 - }
1125 -
1126 - if ( ! \current_user_can( 'manage_options' ) ) {
1127 - \wp_send_json_error( array( 'message' => \__( 'You do not have permission to perform this action.', 'activitypub' ) ) );
1128 - }
1129 -
1130 - $name = \sanitize_text_field( \wp_unslash( $_POST['name'] ?? '' ) );
1131 - $redirect_uri = \sanitize_url( \wp_unslash( $_POST['redirect_uri'] ?? '' ) );
1132 -
1133 - if ( empty( $name ) ) {
1134 - \wp_send_json_error( array( 'message' => \__( 'Application name is required.', 'activitypub' ) ) );
1135 - }
1136 -
1137 - if ( empty( $redirect_uri ) ) {
1138 - \wp_send_json_error( array( 'message' => \__( 'Redirect URI is required.', 'activitypub' ) ) );
1139 - }
1140 -
1141 - $result = Client::register(
1142 - array(
1143 - 'name' => $name,
1144 - 'redirect_uris' => array( $redirect_uri ),
1145 - 'is_public' => false,
1146 - )
1147 - );
1148 -
1149 - if ( \is_wp_error( $result ) ) {
1150 - \wp_send_json_error( array( 'message' => $result->get_error_message() ) );
1151 - }
1152 -
1153 - $data = array(
1154 - 'client_id' => $result['client_id'],
1155 - 'created' => \date_i18n( \get_option( 'date_format' ) ),
1156 - );
1157 -
1158 - if ( ! empty( $result['client_secret'] ) ) {
1159 - $data['client_secret'] = $result['client_secret'];
1160 - }
1161 -
1162 - \wp_send_json_success( $data );
1163 - }
1164 -
1165 - /**
1166 - * AJAX handler for deleting a registered OAuth client.
1167 - *
1168 - * @since 8.1.0
1169 - */
1170 - public static function ajax_delete_oauth_client() {
1171 - // Verify nonce.
1172 - if ( ! \wp_verify_nonce( \sanitize_text_field( \wp_unslash( $_POST['_wpnonce'] ?? '' ) ), 'activitypub_connected_apps' ) ) {
1173 - \wp_send_json_error( array( 'message' => \__( 'Invalid nonce.', 'activitypub' ) ) );
1174 - }
1175 -
1176 - if ( ! \current_user_can( 'manage_options' ) ) {
1177 - \wp_send_json_error( array( 'message' => \__( 'You do not have permission to perform this action.', 'activitypub' ) ) );
1178 - }
1179 -
1180 - $client_id = \sanitize_text_field( \wp_unslash( $_POST['client_id'] ?? '' ) );
1181 -
1182 - if ( empty( $client_id ) ) {
1183 - \wp_send_json_error( array( 'message' => \__( 'Invalid client ID.', 'activitypub' ) ) );
1184 - }
1185 -
1186 - $deleted = Client::delete( $client_id );
1187 -
1188 - if ( ! $deleted ) {
1189 - \wp_send_json_error( array( 'message' => \__( 'Failed to delete application.', 'activitypub' ) ) );
1190 - }
1191 -
1192 - \wp_send_json_success( array( 'deleted' => true ) );
1193 - }
1194 -
1195 - /**
1196 - * AJAX handler for deleting all manually registered OAuth clients.
1197 - *
1198 - * @since 8.1.0
1199 - */
1200 - public static function ajax_delete_all_oauth_clients() {
1201 - // Verify nonce.
1202 - if ( ! \wp_verify_nonce( \sanitize_text_field( \wp_unslash( $_POST['_wpnonce'] ?? '' ) ), 'activitypub_connected_apps' ) ) {
1203 - \wp_send_json_error( array( 'message' => \__( 'Invalid nonce.', 'activitypub' ) ) );
1204 - }
1205 -
1206 - if ( ! \current_user_can( 'manage_options' ) ) {
1207 - \wp_send_json_error( array( 'message' => \__( 'You do not have permission to perform this action.', 'activitypub' ) ) );
1208 - }
1209 -
1210 - $clients = Client::get_manually_registered();
1211 -
1212 - foreach ( $clients as $client ) {
1213 - Client::delete( $client->get_client_id() );
1214 - }
1215 -
1216 - \wp_send_json_success( array( 'deleted' => ! empty( $clients ) ) );
1217 - }
1218 -
1219 - /**
1220 - * AJAX handler for revoking an OAuth token from the user profile.
1221 - *
1222 - * Follows the WordPress core Application Passwords pattern.
1223 - *
1224 - * @since 8.1.0
1225 - */
1226 - public static function ajax_revoke_oauth_token() {
1227 - // Verify nonce.
1228 - if ( ! \wp_verify_nonce( \sanitize_text_field( \wp_unslash( $_POST['_wpnonce'] ?? '' ) ), 'activitypub_connected_apps' ) ) {
1229 - \wp_send_json_error( array( 'message' => \__( 'Invalid nonce.', 'activitypub' ) ) );
1230 - }
1231 -
1232 - if ( ! \current_user_can( 'read' ) ) {
1233 - \wp_send_json_error( array( 'message' => \__( 'You do not have permission to perform this action.', 'activitypub' ) ) );
1234 - }
1235 -
1236 - $meta_key = \sanitize_text_field( \wp_unslash( $_POST['meta_key'] ?? '' ) ); // phpcs:ignore WordPress.DB.SlowDBQuery.slow_db_query_meta_key -- Not a DB query parameter.
1237 -
1238 - // Verify the meta key belongs to our token prefix.
1239 - if ( 0 !== strpos( $meta_key, Token::META_PREFIX ) ) {
1240 - \wp_send_json_error( array( 'message' => \__( 'Invalid token.', 'activitypub' ) ) );
1241 - }
1242 -
1243 - $user_id = \get_current_user_id();
1244 - $token_data = \get_user_meta( $user_id, $meta_key, true );
1245 -
1246 - // Verify the token belongs to the current user.
1247 - if ( empty( $token_data ) || ! is_array( $token_data ) ) {
1248 - \wp_send_json_error( array( 'message' => \__( 'Token not found.', 'activitypub' ) ) );
1249 - }
1250 -
1251 - // Delete the token.
1252 - \delete_user_meta( $user_id, $meta_key );
1253 -
1254 - // Delete the associated refresh token index.
1255 - if ( ! empty( $token_data['refresh_token_hash'] ) ) {
1256 - \delete_user_meta( $user_id, Token::REFRESH_INDEX_PREFIX . $token_data['refresh_token_hash'] );
1257 - }
1258 -
1259 - \wp_send_json_success( array( 'deleted' => true ) );
1260 - }
1261 -
1262 - /**
1263 - * AJAX handler for revoking all OAuth tokens for the current user.
1264 - *
1265 - * @since 8.1.0
1266 - */
1267 - public static function ajax_revoke_all_oauth_tokens() {
1268 - // Verify nonce.
1269 - if ( ! \wp_verify_nonce( \sanitize_text_field( \wp_unslash( $_POST['_wpnonce'] ?? '' ) ), 'activitypub_connected_apps' ) ) {
1270 - \wp_send_json_error( array( 'message' => \__( 'Invalid nonce.', 'activitypub' ) ) );
1271 - }
1272 -
1273 - if ( ! \current_user_can( 'read' ) ) {
1274 - \wp_send_json_error( array( 'message' => \__( 'You do not have permission to perform this action.', 'activitypub' ) ) );
1275 - }
1276 -
1277 - $count = Token::revoke_all_for_user( \get_current_user_id() );
1278 -
1279 - \wp_send_json_success( array( 'deleted' => $count > 0 ) );
1280 1121 }
1281 1122 }