'GET', 'callback' => [ $this, 'get_info' ], 'permission_callback' => static function () { return current_user_can( 'manage_options' ); }, ] ); register_rest_route( 'shiftora/v1', '/connection/reset-key', [ 'methods' => 'POST', 'callback' => [ $this, 'reset_key' ], 'permission_callback' => static function () { return current_user_can( 'manage_options' ); }, ] ); register_rest_route( 'shiftora/v1', '/connection/settings', [ 'methods' => 'PATCH', 'callback' => [ $this, 'update_settings' ], 'permission_callback' => static function () { return current_user_can( 'manage_options' ); }, 'args' => [ 'allow_pull' => [ 'required' => false, 'type' => 'boolean' ], ], ] ); } public function get_info( WP_REST_Request $request ): WP_REST_Response { $key = get_option( 'shiftora_secret_key', '' ); // Created lazily for a plugin activated before a key existed. if ( empty( $key ) ) { $key = TokenGenerator::generate_secret(); update_option( 'shiftora_secret_key', $key, false ); } return new WP_REST_Response( [ 'site_url' => esc_url_raw( get_site_url() ), 'secret_key' => $key, 'allow_pull' => (bool) get_option( 'shiftora_allow_pull', true ), ], 200 ); } public function update_settings( WP_REST_Request $request ): WP_REST_Response { $nonce_check = $this->require_rest_nonce( $request ); if ( is_wp_error( $nonce_check ) ) { return new WP_REST_Response( [ 'code' => $nonce_check->get_error_code(), 'message' => $nonce_check->get_error_message() ], (int) ( $nonce_check->get_error_data()['status'] ?? 403 ) ); } if ( $request->has_param( 'allow_pull' ) ) { update_option( 'shiftora_allow_pull', (bool) $request->get_param( 'allow_pull' ), false ); } return new WP_REST_Response( [ 'success' => true, 'allow_pull' => (bool) get_option( 'shiftora_allow_pull', true ), ], 200 ); } public function reset_key( WP_REST_Request $request ): WP_REST_Response { $nonce_check = $this->require_rest_nonce( $request ); if ( is_wp_error( $nonce_check ) ) { return new WP_REST_Response( [ 'code' => $nonce_check->get_error_code(), 'message' => $nonce_check->get_error_message() ], (int) ( $nonce_check->get_error_data()['status'] ?? 403 ) ); } $key = TokenGenerator::generate_secret(); update_option( 'shiftora_secret_key', $key, false ); return new WP_REST_Response( [ 'success' => true, 'secret_key' => $key, ], 200 ); } private function require_rest_nonce( WP_REST_Request $request ): bool|WP_Error { $nonce = (string) ( $request->get_header( 'X-WP-Nonce' ) ?: $request->get_param( '_wpnonce' ) ); if ( '' !== $nonce && wp_verify_nonce( sanitize_text_field( wp_unslash( $nonce ) ), 'wp_rest' ) ) { return true; } return new WP_Error( 'shiftora_invalid_nonce', __( 'Security check failed. Please refresh the page and try again.', 'shiftora' ), [ 'status' => 403 ] ); } }