PluginProbe
ActivityPub / 8.0.2
ActivityPub v8.0.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 -220 8.3.08.0.2 View file →
@@ -10,11 +10,10 @@
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 17 use Activitypub\Tombstone;
19 18
20 19 use function Activitypub\count_followers;
@@ -60,11 +59,8 @@
60 59 \add_action( 'admin_action_activitypub_confirm_removal', array( self::class, 'handle_bulk_actor_delete_page' ) );
61 60
62 61 if ( user_can_activitypub( \get_current_user_id() ) ) {
63 62 \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 63 }
68 64
69 65 \add_filter( 'dashboard_glance_items', array( self::class, 'dashboard_glance_items' ) );
70 66 \add_filter( 'plugin_action_links_' . ACTIVITYPUB_PLUGIN_BASENAME, array( self::class, 'add_plugin_settings_link' ) );
@@ -74,19 +70,15 @@
74 70 \add_action( 'tool_box', array( self::class, 'tool_box' ) );
75 71 }
76 72
77 73 \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 74 \add_action( 'admin_print_scripts-settings_page_activitypub', array( self::class, 'enqueue_moderation_scripts' ) );
80 75 \add_action( 'admin_print_footer_scripts-settings_page_activitypub', array( self::class, 'open_help_tab' ) );
81 76
77 + \add_action( 'wp_dashboard_setup', array( self::class, 'add_dashboard_widgets' ) );
78 +
82 79 \add_action( 'wp_ajax_activitypub_moderation_settings', array( self::class, 'ajax_moderation_settings' ) );
83 80 \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 81 }
90 82
91 83 /**
92 84 * Display admin menu notices about configuration problems or conflicts.
@@ -259,10 +251,8 @@
259 251 'activitypub_hide_social_graph',
260 252 'activitypub_mailer_new_dm',
261 253 'activitypub_mailer_new_follower',
262 254 'activitypub_mailer_new_mention',
263 - 'activitypub_mailer_annual_report',
264 - 'activitypub_mailer_monthly_report',
265 255 );
266 256
267 257 foreach ( $required_user_options as $option ) {
268 258 \update_user_option( $user_id, $option, sanitize_text_field( wp_unslash( $_POST[ $option ] ?? 0 ) ) );
@@ -383,48 +373,8 @@
383 373 );
384 374 }
385 375
386 376 /**
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 377 * Hook into the edit_comment functionality.
428 378 *
429 379 * Disables the edit_comment capability for federated comments.
430 380 */
@@ -1004,8 +954,80 @@
1004 954 <?php
1005 955 }
1006 956
1007 957 /**
958 + * Add Dashboard widgets.
959 + */
960 + public static function add_dashboard_widgets() {
961 + \wp_add_dashboard_widget( 'activitypub_blog', \__( 'ActivityPub Plugin News', 'activitypub' ), array( self::class, 'blog_dashboard_widget' ) );
962 + if ( user_can_activitypub( \get_current_user_id() ) && ! is_user_type_disabled( 'user' ) ) {
963 + \wp_add_dashboard_widget( 'activitypub_profile', \__( 'ActivityPub Author profile', 'activitypub' ), array( self::class, 'profile_dashboard_widget' ) );
964 + }
965 + if ( ! is_user_type_disabled( 'blog' ) ) {
966 + \wp_add_dashboard_widget( 'activitypub_blog_profile', \__( 'ActivityPub Blog profile', 'activitypub' ), array( self::class, 'blogprofile_dashboard_widget' ) );
967 + }
968 + }
969 +
970 + /**
971 + * Add the `ActivityPub.blog` feed as a Dashboard widget.
972 + */
973 + public static function blog_dashboard_widget() {
974 + echo '<div class="rss-widget">';
975 + \wp_widget_rss_output(
976 + array(
977 + 'url' => 'https://activitypub.blog/feed/',
978 + 'items' => 3,
979 + 'show_summary' => 1,
980 + 'show_author' => 0,
981 + 'show_date' => 1,
982 + )
983 + );
984 + echo '</div>';
985 + }
986 +
987 + /**
988 + * Add the ActivityPub Author profile as a Dashboard widget.
989 + */
990 + public static function profile_dashboard_widget() {
991 + $user = Actors::get_by_id( \get_current_user_id() );
992 + ?>
993 + <p>
994 + <?php \esc_html_e( 'People can follow you by using your author name:', 'activitypub' ); ?>
995 + </p>
996 + <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>
997 + <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>
998 + <p>
999 + <?php \esc_html_e( 'Authors who can not access this settings page will find their username on the "Edit Profile" page.', 'activitypub' ); ?>
1000 + <a href="<?php echo \esc_url( \admin_url( '/profile.php#activitypub' ) ); ?>">
1001 + <?php \esc_html_e( 'Customize username on "Edit Profile" page.', 'activitypub' ); ?>
1002 + </a>
1003 + </p>
1004 + <?php
1005 + }
1006 +
1007 + /**
1008 + * Add the ActivityPub Blog profile as a Dashboard widget.
1009 + */
1010 + public static function blogprofile_dashboard_widget() {
1011 + $user = new Blog();
1012 + ?>
1013 + <p>
1014 + <?php \esc_html_e( 'People can follow your blog by using:', 'activitypub' ); ?>
1015 + </p>
1016 + <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>
1017 + <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>
1018 + <p>
1019 + <?php \esc_html_e( 'This blog profile will federate all posts written on your blog, regardless of the author who posted it.', 'activitypub' ); ?>
1020 + <?php if ( current_user_can( 'manage_options' ) ) : ?>
1021 + <a href="<?php echo \esc_url( \admin_url( '/options-general.php?page=activitypub&tab=blog-profile' ) ); ?>">
1022 + <?php \esc_html_e( 'Customize the blog profile.', 'activitypub' ); ?>
1023 + </a>
1024 + <?php endif; ?>
1025 + </p>
1026 + <?php
1027 + }
1028 +
1029 + /**
1008 1030 * AJAX handler for moderation settings (add/remove blocks).
1009 1031 */
1010 1032 public static function ajax_moderation_settings() {
1011 1033 $context = \sanitize_text_field( \wp_unslash( $_POST['context'] ?? '' ) );
@@ -1109,173 +1131,6 @@
1109 1131 \wp_send_json_success();
1110 1132 } else {
1111 1133 \wp_send_json_error( array( 'message' => \__( 'Failed to remove subscription.', 'activitypub' ) ) );
1112 1134 }
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 1135 }
1281 1136 }