diff --git a/.distignore b/.distignore index 4df6c478..ffb1e0e4 100644 --- a/.distignore +++ b/.distignore @@ -2,7 +2,6 @@ /node_modules/ /tests/ /vendor/ -/wordpress/ # Files .* diff --git a/.github/workflows/deploy.yml b/.github/workflows/deploy.yml index ca224545..7f964c13 100644 --- a/.github/workflows/deploy.yml +++ b/.github/workflows/deploy.yml @@ -31,6 +31,7 @@ jobs: - name: Build plugin run: npm run build + - name: WordPress Plugin Deploy id: deploy uses: 10up/action-wordpress-plugin-deploy@stable diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index b4ea2a9d..c20d222e 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -2,47 +2,142 @@ name: Test on: [push, pull_request] +# Cancels all previous workflow runs for pull requests that have not completed. +concurrency: + # The concurrency group contains the workflow name and the branch name for pull requests + # or the commit hash for any other events. + group: ${{ github.workflow }}-${{ github.event_name == 'pull_request' && github.head_ref || github.sha }} + cancel-in-progress: true + jobs: + lint-js-css: + name: Lint JS & CSS + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Setup Node + uses: actions/setup-node@v4 + with: + cache: 'npm' + node-version-file: '.nvmrc' + + - name: Install NPM dependencies + run: npm install + + - name: Lint JS + run: npm run lint:js + + - name: Lint CSS + run: npm run lint:css + + lint-php-and-compatibility: + name: Lint PHP & PHP Compatibility checks. + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Setup PHP and Composer + uses: shivammathur/setup-php@v2 + with: + php-version: '8.2' + + - name: Setup Node + uses: actions/setup-node@v4 + with: + cache: 'npm' + node-version-file: '.nvmrc' + + - name: Install NPM dependencies + run: npm install + + - name: Lint PHP + run: npm run lint:php || true # Ignore for now. + + - name: Lint PHP Compatibility + run: composer lint-compat + + test-php: + name: Test PHP ${{ matrix.php }} ${{ matrix.wp != '' && format( ' (WP {0}) ', matrix.wp ) || '' }} + runs-on: ubuntu-latest + strategy: + matrix: + php: + - '8.3' + - '8.2' + - '8.1' + - '8.0' + - '7.4' + - '7.3' + - '7.2' + wp: + - latest + - trunk + - '6.3' + env: + WP_ENV_PHP_VERSION: ${{ matrix.php }} + WP_ENV_CORE: ${{ matrix.wp == 'trunk' && 'WordPress/WordPress' || format( 'https://wordpress.org/wordpress-{0}.zip', matrix.wp ) }} + + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Setup PHP + uses: shivammathur/setup-php@v2 + with: + php-version: '8.2' - lint: - name: Lint and Test - runs-on: ubuntu-20.04 - steps: - - name: Checkout - uses: actions/checkout@v3 + - name: Setup Node + uses: actions/setup-node@v4 + with: + cache: 'npm' + node-version-file: '.nvmrc' - - name: Setup Node - uses: actions/setup-node@v3 - with: - cache: 'npm' - node-version-file: '.nvmrc' + - name: Install NPM dependencies + run: npm install - - name: Setup PHP and Composer - uses: shivammathur/setup-php@v2 - with: - php-version: '7.4' - tools: composer:v2 + - name: Start the Docker testing environment + uses: nick-fields/retry@v3 + with: + timeout_minutes: 10 + max_attempts: 3 + command: npm run env start - - name: Install NPM dependencies - run: npm install + - name: Composer install + run: | + rm composer.lock || true # We need to install fresh. + npm run composer install - - name: Lint JS - run: npm run lint:js + - name: Versions + run: | + npm run env run cli php -- -v + npm run env run cli wp core version - - name: Lint CSS - run: npm run lint:css + - name: Test + run: npm run test - - name: Lint PHP - run: npm run lint:php || true # Ignore for now. + build: + name: Build + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v4 - - name: Lint PHP8 - run: composer lint-php8 + - name: Setup PHP + uses: shivammathur/setup-php@v2 + with: + php-version: '8.2' - - name: Start the Docker testing environment - run: npm run env start --xdebug=coverage + - name: Setup Node + uses: actions/setup-node@v4 + with: + cache: 'npm' + node-version-file: '.nvmrc' - - name: Test - run: npm run test + - name: Install NPM dependencies + run: npm install - - name: Build - run: npm run build + - name: Build + run: npm run build diff --git a/.gitignore b/.gitignore index 9d288c60..6430f0ee 100644 --- a/.gitignore +++ b/.gitignore @@ -3,6 +3,5 @@ /npm-debug.log /vendor/ /dist/ -/tests/.phpunit.result.cache /tests/logs/ -/wordpress/ +.phpunit.result.cache diff --git a/.nvmrc b/.nvmrc index b6a7d89c..209e3ef4 100644 --- a/.nvmrc +++ b/.nvmrc @@ -1 +1 @@ -16 +20 diff --git a/.wp-env.json b/.wp-env.json index 0ee66b30..8e06478a 100644 --- a/.wp-env.json +++ b/.wp-env.json @@ -1,5 +1,15 @@ { - "core": "./wordpress", "phpVersion": "7.4", - "plugins": [ "." ] + "plugins": [ "." ], + "env": { + "tests": { + "config": { + "WP_DEBUG": true, + "WP_TESTS_EMAIL": "admin@example.org", + "WP_TESTS_DOMAIN": "example.org", + "WP_SITEURL": "https://example.org", + "WP_HOME": "https://example.org" + } + } + } } diff --git a/Gruntfile.js b/Gruntfile.js index e60363bf..9a58b436 100644 --- a/Gruntfile.js +++ b/Gruntfile.js @@ -11,16 +11,6 @@ module.exports = function( grunt ) { invert: true, } ); - /** - * Check if CLI input appears to indicate a truthy value. - * - * @param {string} input Value to check. - * @return {boolean} If value appears to be truthy. - */ - function isTruthy( input ) { - return ( '1' === input || 'true' === input ); - } - grunt.initConfig( { pkg: grunt.file.readJSON( 'package.json' ), @@ -47,23 +37,6 @@ module.exports = function( grunt ) { ], }, }, - - wp_deploy: { - options: { - plugin_slug: 'two-factor', - build_dir: '<%= dist_dir %>', - assets_dir: 'assets', - }, - wporg: { - options: { - skip_confirmation: isTruthy( process.env.DEPLOY_SKIP_CONFIRMATION ), - svn_user: process.env.DEPLOY_SVN_USERNAME, - deploy_tag: isTruthy( process.env.DEPLOY_TAG ), - deploy_trunk: isTruthy( process.env.DEPLOY_TRUNK ), - assets_dir: ( isTruthy( process.env.DEPLOY_TAG ) || isTruthy( process.env.DEPLOY_TRUNK ) ) ? 'assets' : null, - }, - }, - }, } ); grunt.registerTask( @@ -72,11 +45,4 @@ module.exports = function( grunt ) { 'copy', ] ); - - grunt.registerTask( - 'deploy', [ - 'build', - 'wp_deploy', - ] - ); }; diff --git a/class-two-factor-core.php b/class-two-factor-core.php index f3d532ce..d7b5ef1b 100644 --- a/class-two-factor-core.php +++ b/class-two-factor-core.php @@ -57,7 +57,7 @@ class Two_Factor_Core { const USER_PASSWORD_WAS_RESET_KEY = '_two_factor_password_was_reset'; /** - * URL query paramater used for our custom actions. + * URL query parameter used for our custom actions. * * @var string */ @@ -93,7 +93,6 @@ class Two_Factor_Core { * @since 0.1-dev */ public static function add_hooks( $compat ) { - add_action( 'plugins_loaded', array( __CLASS__, 'load_textdomain' ) ); add_action( 'init', array( __CLASS__, 'get_providers' ) ); add_action( 'wp_login', array( __CLASS__, 'wp_login' ), 10, 2 ); add_filter( 'wp_login_errors', array( __CLASS__, 'maybe_show_reset_password_notice' ) ); @@ -125,22 +124,13 @@ public static function add_hooks( $compat ) { add_filter( 'authenticate', array( __CLASS__, 'filter_authenticate_block_cookies' ), PHP_INT_MAX ); add_filter( 'attach_session_information', array( __CLASS__, 'filter_session_information' ), 10, 2 ); - + add_action( 'admin_init', array( __CLASS__, 'trigger_user_settings_action' ) ); add_filter( 'two_factor_providers', array( __CLASS__, 'enable_dummy_method_for_debug' ) ); $compat->init(); } - /** - * Loads the plugin's text domain. - * - * Sites on WordPress 4.6+ benefit from just-in-time loading of translations. - */ - public static function load_textdomain() { - load_plugin_textdomain( 'two-factor' ); - } - /** * For each provider, include it and then instantiate it. * @@ -184,7 +174,7 @@ public static function get_providers() { * For each filtered provider, */ foreach ( $providers as $provider_key => $path ) { - include_once $path; + require_once $path; $class = $provider_key; @@ -399,7 +389,7 @@ public static function fetch_user( $user = null ) { /** * Get all Two-Factor Auth providers that are enabled for the specified|current user. * - * @param int|WP_User $user Optonal. User ID, or WP_User object of the the user. Defaults to current user. + * @param int|WP_User $user Optional. User ID, or WP_User object of the the user. Defaults to current user. * @return array */ public static function get_enabled_providers_for_user( $user = null ) { @@ -427,7 +417,7 @@ public static function get_enabled_providers_for_user( $user = null ) { /** * Get all Two-Factor Auth providers that are both enabled and configured for the specified|current user. * - * @param int|WP_User $user Optonal. User ID, or WP_User object of the the user. Defaults to current user. + * @param int|WP_User $user Optional. User ID, or WP_User object of the the user. Defaults to current user. * @return array|WP_Error */ public static function get_available_providers_for_user( $user = null ) { @@ -477,7 +467,7 @@ public static function get_available_providers_for_user( $user = null ) { /** * Fetch the provider for the request based on the user preferences. * - * @param int|WP_User $user Optonal. User ID, or WP_User object of the the user. Defaults to current user. + * @param int|WP_User $user Optional. User ID, or WP_User object of the the user. Defaults to current user. * @param null|string|object $preferred_provider Optional. The name of the provider, the provider, or empty. * @return null|object The provider */ @@ -515,7 +505,7 @@ public static function get_provider_for_user( $user = null, $preferred_provider * * @since 0.1-dev * - * @param int|WP_User $user Optonal. User ID, or WP_User object of the the user. Defaults to current user. + * @param int|WP_User $user Optional. User ID, or WP_User object of the the user. Defaults to current user. * @return object|null */ public static function get_primary_provider_for_user( $user = null ) { @@ -564,7 +554,7 @@ public static function get_primary_provider_for_user( $user = null ) { * * @since 0.1-dev * - * @param int|WP_User $user Optonal. User ID, or WP_User object of the the user. Defaults to current user. + * @param int|WP_User $user Optional. User ID, or WP_User object of the the user. Defaults to current user. * @return bool */ public static function is_user_using_two_factor( $user = null ) { @@ -721,8 +711,8 @@ public static function maybe_show_last_login_failure_notice( $user ) { echo '