diff --git a/001-core/privacy.php b/001-core/privacy.php index 213088e678..ea7e47fb5e 100644 --- a/001-core/privacy.php +++ b/001-core/privacy.php @@ -457,3 +457,22 @@ function delete_old_export_files() { } } } + +/** + * Disable crawling for go-vip.co and go-vip.net domains. + * + * @param string $output The robots.txt content. + * @return string The modified robots.txt content. + */ +function vip_convenience_domain_robots_txt( $output ) { + $host = strtolower( $_SERVER['HTTP_HOST'] ?? '' ); // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized + if ( false !== strpos( $host, '.go-vip.co' ) || false !== strpos( $host, '.go-vip.net' ) ) { + $output = "# Crawling is blocked for go-vip.co and go-vip.net domains\n"; + $output .= "User-agent: *\n"; + $output .= "Disallow: /\n"; + } + + return $output; +} +// phpcs:ignore WordPressVIPMinimum.Hooks.RestrictedHooks.robots_txt +add_filter( 'robots_txt', __NAMESPACE__ . '\vip_convenience_domain_robots_txt' ); diff --git a/__tests__/e2e/package-lock.json b/__tests__/e2e/package-lock.json index 98171ad3df..cc53f3c719 100644 --- a/__tests__/e2e/package-lock.json +++ b/__tests__/e2e/package-lock.json @@ -13,7 +13,7 @@ "@playwright/test": "^1.39.0", "asana-phrase": "^0.0.8", "eslint": "^8.51.0", - "eslint-plugin-playwright": "^0.20.0", + "eslint-plugin-playwright": "^0.21.0", "playwright": "^1.39.0", "typescript": "^5.2.2" } @@ -2175,9 +2175,9 @@ } }, "node_modules/eslint-plugin-playwright": { - "version": "0.20.0", - "resolved": "https://registry.npmjs.org/eslint-plugin-playwright/-/eslint-plugin-playwright-0.20.0.tgz", - "integrity": "sha512-JWTSwUyPPipSOm6AK8z78bQXtKRCykvhSGUewcmZuxstSZ5oGsykW2JaRXJQ2IIfzKJToCBeKD2ISc8Li8qVEQ==", + "version": "0.21.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-playwright/-/eslint-plugin-playwright-0.21.0.tgz", + "integrity": "sha512-Y6qwguE9L6LB1JCsnPKaHbo+Z4X8/MngD82N0NkwiZ0ch0UVc4Oc2ZqmxanFxftIddnvwtNNlzUezglLlzUzKA==", "dev": true, "dependencies": { "globals": "^13.23.0" diff --git a/__tests__/e2e/package.json b/__tests__/e2e/package.json index a39aa0cfd5..5909db6c4d 100644 --- a/__tests__/e2e/package.json +++ b/__tests__/e2e/package.json @@ -16,7 +16,7 @@ "@playwright/test": "^1.39.0", "asana-phrase": "^0.0.8", "eslint": "^8.51.0", - "eslint-plugin-playwright": "^0.20.0", + "eslint-plugin-playwright": "^0.21.0", "playwright": "^1.39.0", "typescript": "^5.2.2" } diff --git a/files/class-vip-filesystem.php b/files/class-vip-filesystem.php index bc4e58484a..ac51a04b76 100644 --- a/files/class-vip-filesystem.php +++ b/files/class-vip-filesystem.php @@ -178,13 +178,14 @@ public function filter_validate_file( $file ) { $upload_path = trailingslashit( $this->get_upload_path() ); $file_path = $upload_path . $file_name; - // TODO: run through unique filename? - - $check_type = $this->validate_file_type( $file_path ); - if ( is_wp_error( $check_type ) ) { - $file['error'] = $check_type->get_error_message(); + $check_file_name = $this->validate_file_name( $file_path ); + if ( is_wp_error( $check_file_name ) ) { + $file['error'] = $check_file_name->get_error_message(); return $file; + } elseif ( $check_file_name !== $file_name ) { + $file['name'] = $check_file_name; + $file_path = $upload_path . $check_file_name; } $check_length = $this->validate_file_path_length( $file_path ); @@ -221,9 +222,9 @@ protected function validate_file_path_length( $file_path ) { * * @param string $file_path Path starting with /wp-content/uploads * - * @return WP_Error|bool True if filetype is supported. Else WP_Error. + * @return WP_Error|string Unique Filename string if filetype is supported. Else WP_Error. */ - protected function validate_file_type( $file_path ) { + protected function validate_file_name( $file_path ) { $result = $this->stream_wrapper->client->get_unique_filename( $file_path ); if ( is_wp_error( $result ) ) { @@ -235,10 +236,9 @@ protected function validate_file_type( $file_path ) { E_USER_WARNING ); } - return $result; } - return true; + return $result; } /** diff --git a/package-lock.json b/package-lock.json index 85428048ea..28b3930de9 100644 --- a/package-lock.json +++ b/package-lock.json @@ -8364,9 +8364,9 @@ "dev": true }, "node_modules/classnames": { - "version": "2.5.0", - "resolved": "https://registry.npmjs.org/classnames/-/classnames-2.5.0.tgz", - "integrity": "sha512-FQuRlyKinxrb5gwJlfVASbSrDlikDJ07426TrfPsdGLvtochowmkbnSFdQGJ2aoXrSetq5KqGV9emvWpy+91xA==", + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/classnames/-/classnames-2.5.1.tgz", + "integrity": "sha512-saHYOzhIQs6wy2sVxTM6bUDsQO4F50V9RQ22qBpEdCW+I+/Wmke2HOl6lS6dTpdxVhb88/I6+Hs+438c3lfUow==", "dev": true }, "node_modules/clean-css": { diff --git a/search/elasticpress-next b/search/elasticpress-next index 0b1336931a..445401e47e 160000 --- a/search/elasticpress-next +++ b/search/elasticpress-next @@ -1 +1 @@ -Subproject commit 0b1336931a69dde98cb203a8a08630800002ff48 +Subproject commit 445401e47eb6d1781a116302e91bc15ffb261948 diff --git a/search/includes/classes/class-search.php b/search/includes/classes/class-search.php index 64ffb5735d..bd9552c6f7 100644 --- a/search/includes/classes/class-search.php +++ b/search/includes/classes/class-search.php @@ -675,7 +675,8 @@ protected function load_commands() { WP_CLI::add_command( 'vip-search queue', __NAMESPACE__ . '\Commands\QueueCommand' ); WP_CLI::add_command( 'vip-search index-versions', __NAMESPACE__ . '\Commands\VersionCommand' ); WP_CLI::add_command( 'vip-search documents', __NAMESPACE__ . '\Commands\DocumentCommand' ); - WP_CLI::add_command( 'vip-search', __NAMESPACE__ . '\Commands\CoreCommand' ); + $vip_search_core_command = new \Automattic\VIP\Search\Commands\CoreCommand( new \ElasticPress\Command() ); + WP_CLI::add_command( 'vip-search', $vip_search_core_command ); } } diff --git a/search/includes/classes/commands/class-corecommand.php b/search/includes/classes/commands/class-corecommand.php index 7ec81ad2c4..b9b613e6b9 100644 --- a/search/includes/classes/commands/class-corecommand.php +++ b/search/includes/classes/commands/class-corecommand.php @@ -6,14 +6,18 @@ use WP_CLI\Utils; use ElasticPress\Elasticsearch; -use function Automattic\VIP\Logstash\log2logstash; - /** * Core commands for interacting with VIP Search * * @package Automattic\VIP\Search */ -class CoreCommand extends \ElasticPress\Command { +class CoreCommand { + private $ep_command; + + public function __construct( \ElasticPress\Command $ep_command ) { + $this->ep_command = $ep_command; + } + private function verify_arguments_compatibility( $assoc_args ) { if ( array_key_exists( 'version', $assoc_args ) && array_key_exists( 'using-versions', $assoc_args ) ) { WP_CLI::error( 'The --version argument is not allowed when specifying --using-versions' ); @@ -221,9 +225,6 @@ protected function maybe_setup_index_version( $assoc_args ) { * @param array $assoc_args Associative CLI args. */ public function index( $args, $assoc_args ) { - if ( isset( $assoc_args['setup'] ) && $assoc_args['setup'] ) { - self::confirm_destructive_operation( $assoc_args ); - } $this->verify_arguments_compatibility( $assoc_args ); $using_versions = $assoc_args['using-versions'] ?? false; @@ -294,6 +295,10 @@ public function index( $args, $assoc_args ) { WP_CLI::line( WP_CLI::colorize( '%CRun took: ' . ( round( microtime( true ) - $start, 3 ) ) . '%n' ) ); } else { + if ( isset( $assoc_args['setup'] ) && $assoc_args['setup'] ) { + self::confirm_destructive_operation( $assoc_args ); + } + // Unset our arguments since they don't exist in ElasticPress and causes // an error for indexing operations exclusively for some reason. unset( $assoc_args['version'] ); @@ -337,7 +342,7 @@ public function index( $args, $assoc_args ) { */ public function put_mapping( $args, $assoc_args ) { self::confirm_destructive_operation( $assoc_args ); - parent::put_mapping( $args, $assoc_args ); + $this->ep_command->put_mapping( $args, $assoc_args ); } /** @@ -383,11 +388,11 @@ public function get_index_settings( $args, $assoc_args ) { * Throw error when delete-index command is attempted to be used. * * @subcommand delete-index - * + * * @param array $args Positional CLI args. * @param array $assoc_args Associative CLI args. */ - public function delete_index( $args, $assoc_args ) { + public function delete_index( $args, $assoc_args ) { // phpcs:ignore Generic.CodeAnalysis.UnusedFunctionParameter.FoundAfterLastUsed WP_CLI::error( 'Please use index versioning to manage your indices: https://docs.wpvip.com/how-tos/vip-search/version-with-enterprise-search/' ); } @@ -411,12 +416,8 @@ public static function confirm_destructive_operation( array $assoc_args ) { * Return all index names as a JSON object. * * @subcommand get-indexes - * - * @param array $args Positional CLI args. - * @param array $assoc_args Associative CLI args. */ - public function get_indexes( $args, $assoc_args ) { - + public function get_indexes( $args, $assoc_args ) { // phpcs:ignore Generic.CodeAnalysis.UnusedFunctionParameter.FoundAfterLastUsed $indexes = $this->list_indexes(); if ( is_wp_error( $indexes ) ) { @@ -434,7 +435,7 @@ public function get_indexes( $args, $assoc_args ) { * @param array $args Positional CLI args. * @param array $assoc_args Associative CLI args. */ - public function get_mapping( $args, $assoc_args ) { + public function get_mapping( $args, $assoc_args ) { // phpcs:ignore Generic.CodeAnalysis.UnusedFunctionParameter.FoundAfterLastUsed $index_names = (array) ( isset( $assoc_args['index-name'] ) ? $assoc_args['index-name'] : $this->list_indexes() ); $path = join( ',', $index_names ) . '/_mapping'; @@ -464,8 +465,7 @@ public function activate_feature( $args, $assoc_args ) { WP_CLI::error( "The feature {$args[0]} is not currently supported." ); } - array_unshift( $args, 'elasticpress', 'activate-feature' ); - WP_CLI::run_command( $args, $assoc_args ); + $this->ep_command->activate_feature( $args, $assoc_args ); } /** @@ -500,19 +500,15 @@ public function deactivate_feature( $args, $assoc_args ) { WP_CLI::confirm( "Are you sure you want to deactivate $args[0]? This will break all search-related functionality!" ); } - array_unshift( $args, 'elasticpress', 'deactivate-feature' ); - WP_CLI::run_command( $args, $assoc_args ); + $this->ep_command->deactivate_feature( $args, $assoc_args ); } /** * Get the last indexed post ID on an incomplete indexing operation. * * @subcommand get-last-indexed-post-id - * - * @param array $args Positional CLI args. - * @param array $assoc_args Associative CLI args. */ - public function get_last_indexed_post_id( $args, $assoc_args ) { + public function get_last_indexed_post_id( $args, $assoc_args ) { // phpcs:ignore Generic.CodeAnalysis.UnusedFunctionParameter.FoundAfterLastUsed $search = \Automattic\VIP\Search\Search::instance(); $last_id = get_option( $search::LAST_INDEXED_POST_ID_OPTION ); @@ -528,11 +524,8 @@ public function get_last_indexed_post_id( $args, $assoc_args ) { * Clean the ep_feature_settings individual blog option if it exists for sites with EP_IS_NETWORK. * * @subcommand clean-ep-feature-settings - * - * @param array $args Positional CLI args. - * @param array $assoc_args Associative CLI args. */ - public function clean_ep_feature_settings( $args, $assoc_args ) { + public function clean_ep_feature_settings( $args, $assoc_args ) { // phpcs:ignore Generic.CodeAnalysis.UnusedFunctionParameter.FoundAfterLastUsed if ( is_multisite() && defined( 'EP_IS_NETWORK' ) && true === constant( 'EP_IS_NETWORK' ) ) { $delete_option = delete_option( 'ep_feature_settings' ); if ( $delete_option ) { @@ -544,4 +537,119 @@ public function clean_ep_feature_settings( $args, $assoc_args ) { WP_CLI::error( 'Not a multisite or EP_IS_NETWORK is not enabled!' ); } } + + /** + * Stop the current indexing operation. + * + * @subcommand stop-indexing + * + * @param array $args Positional CLI args. + * @param array $assoc_args Associative CLI args. + */ + public function stop_indexing( $args, $assoc_args ) { + $this->ep_command->stop_indexing( $args, $assoc_args ); + } + + /** + * List features (either active or all). + * + * ## OPTIONS + * + * [--all] + * : Show all registered features + * + * @subcommand list-features + * @param array $args Positional CLI args. + * @param array $assoc_args Associative CLI args. + */ + public function list_features( $args, $assoc_args ) { + $this->ep_command->list_features( $args, $assoc_args ); + } + + /** + * Recreates the alias index which points to every index in the network. + * + * Map network alias to every index in the network for every non-global indexable + * + * @subcommand recreate-network-alias + * @param array $args Positional CLI args. + * @param array $assoc_args Associative CLI args. + */ + public function recreate_network_alias( $args, $assoc_args ) { + $this->ep_command->recreate_network_alias( $args, $assoc_args ); + } + + /** + * Clear a sync/index process. + * + * If an index was stopped prematurely and won't start again, this will clear this cached data such that a new index can start. + * + * @subcommand clear-index + * @alias delete-transient + */ + public function clear_index( $args, $assoc_args ) { + $this->ep_command->clear_index( $args, $assoc_args ); + } + + /** + * Returns the status of an ongoing index operation in JSON array. + * + * Returns the status of an ongoing index operation in JSON array with the following fields: + * indexing | boolean | True if index operation is ongoing or false + * items_indexed | integer | Total number of items indexed + * total_items | integer | Total number of items indexed or -1 if not yet determined + * + * ## OPTIONS + * + * [--pretty] + * : Use this flag to render a pretty-printed version of the JSON response. + * + * @subcommand get-indexing-status + * @param array $args Positional CLI args. + * @param array $assoc_args Associative CLI args. + */ + public function get_indexing_status( $args, $assoc_args ) { + $this->ep_command->get_indexing_status( $args, $assoc_args ); + } + + /** + * Returns a JSON array with the results of the last CLI index (if present) or an empty array. + * + * ## OPTIONS + * + * [--clear] + * : Clear the `ep_last_cli_index` option. + * + * [--pretty] + * : Use this flag to render a pretty-printed version of the JSON response. + * + * @subcommand get-last-index + * @param array $args Positional CLI args. + * @param array $assoc_args Associative CLI args. + */ + public function get_last_index( $args, $assoc_args ) { + $this->ep_command->get_last_cli_index( $args, $assoc_args ); + } + + /** + * Get the algorithm version. + * + * Get the value of the `ep_search_algorithm_version` option, or + * `default` if empty. + * + * @subcommand get-algorithm-version + */ + public function get_algorithm_version( $args, $assoc_args ) { // phpcs:ignore Generic.CodeAnalysis.UnusedFunctionParameter.FoundAfterLastUsed + $version = apply_filters( 'ep_search_algorithm_version', get_option( 'ep_search_algorithm_version', '3.5' ) ); + WP_CLI::line( $version ); + } + + /** + * Get stats on the current index. + * + * @subcommand stats + */ + public function get_stats( $args, $assoc_args ) { // phpcs:ignore Generic.CodeAnalysis.UnusedFunctionParameter.FoundAfterLastUsed + $this->ep_command->stats(); + } } diff --git a/search/search-dev-tools/package-lock.json b/search/search-dev-tools/package-lock.json index 1e07b88f32..09ff0fdc16 100644 --- a/search/search-dev-tools/package-lock.json +++ b/search/search-dev-tools/package-lock.json @@ -121,9 +121,9 @@ } }, "node_modules/@babel/core": { - "version": "7.23.6", - "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.23.6.tgz", - "integrity": "sha512-FxpRyGjrMJXh7X3wGLGhNDCRiwpWEF74sKjTLDJSG5Kyvow3QZaG0Adbqzi9ZrVjTWpsX+2cxWXD71NMg93kdw==", + "version": "7.23.7", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.23.7.tgz", + "integrity": "sha512-+UpDgowcmqe36d4NwqvKsyPMlOLNGMsfMmQ5WGCu+siCe3t3dfe9njrzGfdN4qq+bcNUt0+Vw6haRxBOycs4dw==", "dev": true, "dependencies": { "@ampproject/remapping": "^2.2.0", @@ -131,10 +131,10 @@ "@babel/generator": "^7.23.6", "@babel/helper-compilation-targets": "^7.23.6", "@babel/helper-module-transforms": "^7.23.3", - "@babel/helpers": "^7.23.6", + "@babel/helpers": "^7.23.7", "@babel/parser": "^7.23.6", "@babel/template": "^7.22.15", - "@babel/traverse": "^7.23.6", + "@babel/traverse": "^7.23.7", "@babel/types": "^7.23.6", "convert-source-map": "^2.0.0", "debug": "^4.1.0", @@ -264,9 +264,9 @@ } }, "node_modules/@babel/helper-define-polyfill-provider": { - "version": "0.4.3", - "resolved": "https://registry.npmjs.org/@babel/helper-define-polyfill-provider/-/helper-define-polyfill-provider-0.4.3.tgz", - "integrity": "sha512-WBrLmuPP47n7PNwsZ57pqam6G/RGo1vw/87b0Blc53tZNGZ4x7YvZ6HgQe2vo1W/FR20OgjeZuGXzudPiXHFug==", + "version": "0.4.4", + "resolved": "https://registry.npmjs.org/@babel/helper-define-polyfill-provider/-/helper-define-polyfill-provider-0.4.4.tgz", + "integrity": "sha512-QcJMILQCu2jm5TFPGA3lCpJJTeEP+mqeXooG/NZbg/h5FTFi6V0+99ahlRsW8/kRLyb24LZVCCiclDedhLKcBA==", "dev": true, "dependencies": { "@babel/helper-compilation-targets": "^7.22.6", @@ -489,13 +489,13 @@ } }, "node_modules/@babel/helpers": { - "version": "7.23.6", - "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.23.6.tgz", - "integrity": "sha512-wCfsbN4nBidDRhpDhvcKlzHWCTlgJYUUdSJfzXb2NuBssDSIjc3xcb+znA7l+zYsFljAcGM0aFkN40cR3lXiGA==", + "version": "7.23.7", + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.23.7.tgz", + "integrity": "sha512-6AMnjCoC8wjqBzDHkuqpa7jAKwvMo4dC+lr/TFBz+ucfulO1XMpDnwWPGBNwClOKZ8h6xn5N81W/R5OrcKtCbQ==", "dev": true, "dependencies": { "@babel/template": "^7.22.15", - "@babel/traverse": "^7.23.6", + "@babel/traverse": "^7.23.7", "@babel/types": "^7.23.6" }, "engines": { @@ -561,9 +561,9 @@ } }, "node_modules/@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly": { - "version": "7.23.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly/-/plugin-bugfix-v8-static-class-fields-redefine-readonly-7.23.3.tgz", - "integrity": "sha512-XaJak1qcityzrX0/IU5nKHb34VaibwP3saKqG6a/tppelgllOH13LUann4ZCIBcVOeE6H18K4Vx9QKkVww3z/w==", + "version": "7.23.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly/-/plugin-bugfix-v8-static-class-fields-redefine-readonly-7.23.7.tgz", + "integrity": "sha512-LlRT7HgaifEpQA1ZgLVOIJZZFVPWN5iReq/7/JixwBtwcoeVGDBD53ZV28rrsLYOZs1Y/EHhA8N/Z6aazHR8cw==", "dev": true, "dependencies": { "@babel/helper-environment-visitor": "^7.22.20", @@ -869,9 +869,9 @@ } }, "node_modules/@babel/plugin-transform-async-generator-functions": { - "version": "7.23.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-async-generator-functions/-/plugin-transform-async-generator-functions-7.23.4.tgz", - "integrity": "sha512-efdkfPhHYTtn0G6n2ddrESE91fgXxjlqLsnUtPWnJs4a4mZIbUaK7ffqKIIUKXSHwcDvaCVX6GXkaJJFqtX7jw==", + "version": "7.23.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-async-generator-functions/-/plugin-transform-async-generator-functions-7.23.7.tgz", + "integrity": "sha512-PdxEpL71bJp1byMG0va5gwQcXHxuEYC/BgI/e88mGTtohbZN28O5Yit0Plkkm/dBzCF/BxmbNcses1RH1T+urA==", "dev": true, "dependencies": { "@babel/helper-environment-visitor": "^7.22.20", @@ -967,16 +967,15 @@ } }, "node_modules/@babel/plugin-transform-classes": { - "version": "7.23.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-classes/-/plugin-transform-classes-7.23.5.tgz", - "integrity": "sha512-jvOTR4nicqYC9yzOHIhXG5emiFEOpappSJAl73SDSEDcybD+Puuze8Tnpb9p9qEyYup24tq891gkaygIFvWDqg==", + "version": "7.23.8", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-classes/-/plugin-transform-classes-7.23.8.tgz", + "integrity": "sha512-yAYslGsY1bX6Knmg46RjiCiNSwJKv2IUC8qOdYKqMMr0491SXFhcHqOdRDeCRohOOIzwN/90C6mQ9qAKgrP7dg==", "dev": true, "dependencies": { "@babel/helper-annotate-as-pure": "^7.22.5", - "@babel/helper-compilation-targets": "^7.22.15", + "@babel/helper-compilation-targets": "^7.23.6", "@babel/helper-environment-visitor": "^7.22.20", "@babel/helper-function-name": "^7.23.0", - "@babel/helper-optimise-call-expression": "^7.22.5", "@babel/helper-plugin-utils": "^7.22.5", "@babel/helper-replace-supers": "^7.22.20", "@babel/helper-split-export-declaration": "^7.22.6", @@ -1670,9 +1669,9 @@ } }, "node_modules/@babel/preset-env": { - "version": "7.23.6", - "resolved": "https://registry.npmjs.org/@babel/preset-env/-/preset-env-7.23.6.tgz", - "integrity": "sha512-2XPn/BqKkZCpzYhUUNZ1ssXw7DcXfKQEjv/uXZUXgaebCMYmkEsfZ2yY+vv+xtXv50WmL5SGhyB6/xsWxIvvOQ==", + "version": "7.23.8", + "resolved": "https://registry.npmjs.org/@babel/preset-env/-/preset-env-7.23.8.tgz", + "integrity": "sha512-lFlpmkApLkEP6woIKprO6DO60RImpatTQKtz4sUcDjVcK8M8mQ4sZsuxaTMNOZf0sqAq/ReYW1ZBHnOQwKpLWA==", "dev": true, "dependencies": { "@babel/compat-data": "^7.23.5", @@ -1681,7 +1680,7 @@ "@babel/helper-validator-option": "^7.23.5", "@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression": "^7.23.3", "@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": "^7.23.3", - "@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly": "^7.23.3", + "@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly": "^7.23.7", "@babel/plugin-proposal-private-property-in-object": "7.21.0-placeholder-for-preset-env.2", "@babel/plugin-syntax-async-generators": "^7.8.4", "@babel/plugin-syntax-class-properties": "^7.12.13", @@ -1702,13 +1701,13 @@ "@babel/plugin-syntax-top-level-await": "^7.14.5", "@babel/plugin-syntax-unicode-sets-regex": "^7.18.6", "@babel/plugin-transform-arrow-functions": "^7.23.3", - "@babel/plugin-transform-async-generator-functions": "^7.23.4", + "@babel/plugin-transform-async-generator-functions": "^7.23.7", "@babel/plugin-transform-async-to-generator": "^7.23.3", "@babel/plugin-transform-block-scoped-functions": "^7.23.3", "@babel/plugin-transform-block-scoping": "^7.23.4", "@babel/plugin-transform-class-properties": "^7.23.3", "@babel/plugin-transform-class-static-block": "^7.23.4", - "@babel/plugin-transform-classes": "^7.23.5", + "@babel/plugin-transform-classes": "^7.23.8", "@babel/plugin-transform-computed-properties": "^7.23.3", "@babel/plugin-transform-destructuring": "^7.23.3", "@babel/plugin-transform-dotall-regex": "^7.23.3", @@ -1750,9 +1749,9 @@ "@babel/plugin-transform-unicode-regex": "^7.23.3", "@babel/plugin-transform-unicode-sets-regex": "^7.23.3", "@babel/preset-modules": "0.1.6-no-external-plugins", - "babel-plugin-polyfill-corejs2": "^0.4.6", - "babel-plugin-polyfill-corejs3": "^0.8.5", - "babel-plugin-polyfill-regenerator": "^0.5.3", + "babel-plugin-polyfill-corejs2": "^0.4.7", + "babel-plugin-polyfill-corejs3": "^0.8.7", + "babel-plugin-polyfill-regenerator": "^0.5.4", "core-js-compat": "^3.31.0", "semver": "^6.3.1" }, @@ -1810,9 +1809,9 @@ } }, "node_modules/@babel/traverse": { - "version": "7.23.6", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.23.6.tgz", - "integrity": "sha512-czastdK1e8YByZqezMPFiZ8ahwVMh/ESl9vPgvgdB9AmFMGP5jfpFax74AQgl5zj4XHzqeYAg2l8PuUeRS1MgQ==", + "version": "7.23.7", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.23.7.tgz", + "integrity": "sha512-tY3mM8rH9jM0YHFGyfC0/xf+SB5eKUu7HPj7/k3fpi9dAlsMc5YbQvDi0Sh2QTPXqMhyaAtzAr807TIyfQrmyg==", "dev": true, "dependencies": { "@babel/code-frame": "^7.23.5", @@ -3160,9 +3159,9 @@ } }, "node_modules/acorn": { - "version": "8.11.2", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.11.2.tgz", - "integrity": "sha512-nc0Axzp/0FILLEVsm4fNwLCwMttvhEI263QtVPQcbpfZZ3ts0hLsZGOpE6czNlid7CJ9MlyH8reXkpsf3YUY4w==", + "version": "8.11.3", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.11.3.tgz", + "integrity": "sha512-Y9rRfJG5jcKOE0CLisYbojUjIrIEE7AGMzA/Sm4BslANhbS+cDMpgBdcPT91oJ7OuJ9hYJBx59RjbhxVnrF8Xg==", "dev": true, "bin": { "acorn": "bin/acorn" @@ -3577,13 +3576,13 @@ } }, "node_modules/babel-plugin-polyfill-corejs2": { - "version": "0.4.6", - "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs2/-/babel-plugin-polyfill-corejs2-0.4.6.tgz", - "integrity": "sha512-jhHiWVZIlnPbEUKSSNb9YoWcQGdlTLq7z1GHL4AjFxaoOUMuuEVJ+Y4pAaQUGOGk93YsVCKPbqbfw3m0SM6H8Q==", + "version": "0.4.7", + "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs2/-/babel-plugin-polyfill-corejs2-0.4.7.tgz", + "integrity": "sha512-LidDk/tEGDfuHW2DWh/Hgo4rmnw3cduK6ZkOI1NPFceSK3n/yAGeOsNT7FLnSGHkXj3RHGSEVkN3FsCTY6w2CQ==", "dev": true, "dependencies": { "@babel/compat-data": "^7.22.6", - "@babel/helper-define-polyfill-provider": "^0.4.3", + "@babel/helper-define-polyfill-provider": "^0.4.4", "semver": "^6.3.1" }, "peerDependencies": { @@ -3591,25 +3590,25 @@ } }, "node_modules/babel-plugin-polyfill-corejs3": { - "version": "0.8.5", - "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs3/-/babel-plugin-polyfill-corejs3-0.8.5.tgz", - "integrity": "sha512-Q6CdATeAvbScWPNLB8lzSO7fgUVBkQt6zLgNlfyeCr/EQaEQR+bWiBYYPYAFyE528BMjRhL+1QBMOI4jc/c5TA==", + "version": "0.8.7", + "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs3/-/babel-plugin-polyfill-corejs3-0.8.7.tgz", + "integrity": "sha512-KyDvZYxAzkC0Aj2dAPyDzi2Ym15e5JKZSK+maI7NAwSqofvuFglbSsxE7wUOvTg9oFVnHMzVzBKcqEb4PJgtOA==", "dev": true, "dependencies": { - "@babel/helper-define-polyfill-provider": "^0.4.3", - "core-js-compat": "^3.32.2" + "@babel/helper-define-polyfill-provider": "^0.4.4", + "core-js-compat": "^3.33.1" }, "peerDependencies": { "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0" } }, "node_modules/babel-plugin-polyfill-regenerator": { - "version": "0.5.3", - "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-regenerator/-/babel-plugin-polyfill-regenerator-0.5.3.tgz", - "integrity": "sha512-8sHeDOmXC8csczMrYEOf0UTNa4yE2SxV5JGeT/LP1n0OYVDUUFPxG9vdk2AlDlIit4t+Kf0xCtpgXPBwnn/9pw==", + "version": "0.5.4", + "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-regenerator/-/babel-plugin-polyfill-regenerator-0.5.4.tgz", + "integrity": "sha512-S/x2iOCvDaCASLYsOOgWOq4bCfKYVqvO/uxjkaYyZ3rVsVE3CeAI/c84NpyuBBymEgNvHgjEot3a9/Z/kXvqsg==", "dev": true, "dependencies": { - "@babel/helper-define-polyfill-provider": "^0.4.3" + "@babel/helper-define-polyfill-provider": "^0.4.4" }, "peerDependencies": { "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0" @@ -3934,9 +3933,9 @@ } }, "node_modules/classnames": { - "version": "2.5.0", - "resolved": "https://registry.npmjs.org/classnames/-/classnames-2.5.0.tgz", - "integrity": "sha512-FQuRlyKinxrb5gwJlfVASbSrDlikDJ07426TrfPsdGLvtochowmkbnSFdQGJ2aoXrSetq5KqGV9emvWpy+91xA==" + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/classnames/-/classnames-2.5.1.tgz", + "integrity": "sha512-saHYOzhIQs6wy2sVxTM6bUDsQO4F50V9RQ22qBpEdCW+I+/Wmke2HOl6lS6dTpdxVhb88/I6+Hs+438c3lfUow==" }, "node_modules/clean-css": { "version": "5.3.2", @@ -4149,12 +4148,12 @@ "dev": true }, "node_modules/core-js-compat": { - "version": "3.33.0", - "resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.33.0.tgz", - "integrity": "sha512-0w4LcLXsVEuNkIqwjjf9rjCoPhK8uqA4tMRh4Ge26vfLtUutshn+aRJU21I9LCJlh2QQHfisNToLjw1XEJLTWw==", + "version": "3.35.0", + "resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.35.0.tgz", + "integrity": "sha512-5blwFAddknKeNgsjBzilkdQ0+YK8L1PfqPYq40NOYMYFSS38qj+hpTcLLWwpIwA2A5bje/x5jmVn2tzUMg9IVw==", "dev": true, "dependencies": { - "browserslist": "^4.22.1" + "browserslist": "^4.22.2" }, "funding": { "type": "opencollective", @@ -10145,9 +10144,9 @@ "dev": true }, "node_modules/sass": { - "version": "1.69.5", - "resolved": "https://registry.npmjs.org/sass/-/sass-1.69.5.tgz", - "integrity": "sha512-qg2+UCJibLr2LCVOt3OlPhr/dqVHWOa9XtZf2OjbLs/T4VPSJ00udtgJxH3neXZm+QqX8B+3cU7RaLqp1iVfcQ==", + "version": "1.69.7", + "resolved": "https://registry.npmjs.org/sass/-/sass-1.69.7.tgz", + "integrity": "sha512-rzj2soDeZ8wtE2egyLXgOOHQvaC2iosZrkF6v3EUG+tBwEvhqUCzm0VP3k9gHF9LXbSrRhT5SksoI56Iw8NPnQ==", "dev": true, "dependencies": { "chokidar": ">=3.0.0 <4.0.0", diff --git a/tests/files/test-vip-filesystem.php b/tests/files/test-vip-filesystem.php index 6c630dca26..fe0250b45f 100644 --- a/tests/files/test-vip-filesystem.php +++ b/tests/files/test-vip-filesystem.php @@ -266,13 +266,13 @@ public function test__filter_validate_file__valid_file() { $basepath = $this->get_upload_path(); $stub = $this->getMockBuilder( VIP_Filesystem::class ) - ->setMethods( [ 'validate_file_type' ] ) + ->setMethods( [ 'validate_file_name' ] ) ->getMock(); $stub->expects( $this->once() ) - ->method( 'validate_file_type' ) + ->method( 'validate_file_name' ) ->with( $basepath . '/' . $file['name'] ) - ->will( $this->returnValue( true ) ); + ->will( $this->returnValue( $file['name'] ) ); $actual = $stub->filter_validate_file( $file ); @@ -280,17 +280,42 @@ public function test__filter_validate_file__valid_file() { $this->assertArrayNotHasKey( 'error', $actual ); } + public function test__filter_validate_file__unique_file() { + $file = [ + 'name' => 'testfile.txt', + ]; + $unique_file_name = 'testfile_8hj30h.txt'; + $basepath = $this->get_upload_path(); + + $stub = $this->getMockBuilder( VIP_Filesystem::class ) + ->setMethods( [ 'validate_file_name' ] ) + ->getMock(); + + $stub->expects( $this->once() ) + ->method( 'validate_file_name' ) + ->with( $basepath . '/' . $file['name'] ) + ->will( $this->returnValue( $unique_file_name ) ); + + $actual = $stub->filter_validate_file( $file ); + + $this->assertEquals( $unique_file_name, $actual['name'] ); + $this->assertArrayNotHasKey( 'error', $actual ); + } + public function test__filter_validate_file__invalid_file_length() { - $file = [ + $file = [ 'name' => 'abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz.txt', ]; + $basepath = $this->get_upload_path(); $stub = $this->getMockBuilder( VIP_Filesystem::class ) - ->setMethods( [ 'validate_file_type' ] ) + ->setMethods( [ 'validate_file_name' ] ) ->getMock(); $stub->expects( $this->once() ) - ->method( 'validate_file_type' ); + ->method( 'validate_file_name' ) + ->with( $basepath . '/' . $file['name'] ) + ->will( $this->returnValue( $file['name'] ) ); $actual = $stub->filter_validate_file( $file ); @@ -308,11 +333,11 @@ public function test__filter_validate_file__invalid_file_type() { $basepath = $this->get_upload_path(); $stub = $this->getMockBuilder( VIP_Filesystem::class ) - ->setMethods( [ 'validate_file_type' ] ) + ->setMethods( [ 'validate_file_name' ] ) ->getMock(); $stub->expects( $this->once() ) - ->method( 'validate_file_type' ) + ->method( 'validate_file_name' ) ->with( $basepath . '/' . $file['name'] ) ->will( $this->returnValue( new WP_Error( 'invalid-file-type', 'Failed to generate new unique file name `testfile.exe` (response code: 400)' ) ) ); diff --git a/tests/search/e2e/integration/wp-cli.spec.js b/tests/search/e2e/integration/wp-cli.spec.js index 4d517719de..0784fe7280 100644 --- a/tests/search/e2e/integration/wp-cli.spec.js +++ b/tests/search/e2e/integration/wp-cli.spec.js @@ -126,14 +126,14 @@ describe('WP-CLI Commands', () => { ); }); - it('Can return a string indicating with the appropriate fields if user runs wp vip-search get-last-cli-index command', () => { + it('Can return a string indicating with the appropriate fields if user runs wp vip-search get-last-index command', () => { cy.wpCli('wp vip-search index'); - cy.wpCli('wp vip-search get-last-cli-index') + cy.wpCli('wp vip-search get-last-index') .its('stdout') .should('contain', '"total":'); - cy.wpCli('wp vip-search get-last-cli-index --clear') + cy.wpCli('wp vip-search get-last-index --clear') .its('stdout') .should('contain', '[]'); }); @@ -176,34 +176,10 @@ describe('WP-CLI Commands', () => { }); }); - it('Can set the algorithm version', () => { - cy.wpCli('wp vip-search set-algorithm-version --default') - .its('stdout') - .should('contain', 'Done'); - - cy.wpCli('wp vip-search get-algorithm-version') - .its('stdout') - .should('contain', 'default'); - - cy.wpCli('wp vip-search set-algorithm-version --version=1.0.0') - .its('stdout') - .should('contain', 'Done'); - - cy.wpCli('wp vip-search get-algorithm-version').its('stdout').should('contain', '1.0.0'); - - cy.wpCli('wp vip-search set-algorithm-version', true) - .its('stderr') - .should('contain', 'This command expects a version number or the --default flag'); - }); - it('Can get the mapping information', () => { cy.wpCli('wp vip-search get-mapping').its('stdout').should('contain', 'mapping_version'); }); - it('Can get the cluster indexes information', () => { - cy.wpCli('wp vip-search get-cluster-indexes').its('stdout').should('contain', 'health'); - }); - it('Can get the indexes names', () => { cy.wpCli('wp vip-search get-indexes').its('code').should('equal', 0); diff --git a/two-factor.php b/two-factor.php index 6d4f658586..eda89493a9 100644 --- a/two-factor.php +++ b/two-factor.php @@ -248,7 +248,7 @@ function wpcom_vip_two_factor_admin_notice() {

- Two Factor Authentication is required to edit content on this site. + Your account requires two-factor authentication to be enabled.

For the safety and security of this site, your account access has been downgraded. Please enable two-factor authentication to restore your access.

diff --git a/vip-helpers/vip-utils.php b/vip-helpers/vip-utils.php index c464969ca2..f63a09b641 100644 --- a/vip-helpers/vip-utils.php +++ b/vip-helpers/vip-utils.php @@ -1640,3 +1640,16 @@ function vip_get_hyper_servers( $hyperdb, $operation = 'all', $dataset = 'global return $hyperdb->hyper_servers[ $dataset ]; } + +/** + * Checks if a given string looks like a VIP convenience domain. + * + * Examples of a VIP convenience domain are `example.go-vip.co` and `example.go-vip.net`. + * + * @param string $domain Domain to check. + * @return bool True if the domain is a convenience domain. + */ +function is_vip_convenience_domain( string $domain ): bool { + $domain = strtolower( $domain ); + return str_ends_with( $domain, '.go-vip.co' ) || str_ends_with( $domain, '.go-vip.net' ); +}