diff --git a/phpcs.xml.dist b/phpcs.xml.dist
index d8c5651..99ba35a 100644
--- a/phpcs.xml.dist
+++ b/phpcs.xml.dist
@@ -6,7 +6,9 @@
-
+
+ tests/*
+
@@ -24,4 +26,4 @@
tests/*
-
\ No newline at end of file
+
diff --git a/tests/Constants.php b/tests/Constants.php
index 286a0f8..d767c6d 100644
--- a/tests/Constants.php
+++ b/tests/Constants.php
@@ -2,8 +2,6 @@
namespace Roots\PasswordBcrypt\Tests;
-// phpcs:disable PHPCompatibility.Classes.NewConstVisibility.Found
-
class Constants
{
/**
diff --git a/tests/TestCase.php b/tests/TestCase.php
index 23048b0..c4bde75 100644
--- a/tests/TestCase.php
+++ b/tests/TestCase.php
@@ -5,8 +5,6 @@
use Brain\Monkey;
use Mockery\Adapter\Phpunit\MockeryTestCase;
-// phpcs:disable PHPCompatibility.FunctionDeclarations.NewReturnTypeDeclarations.voidFound
-
class TestCase extends MockeryTestCase
{
use MocksWpdb;
diff --git a/tests/Unit/ApplicationPasswordTest.php b/tests/Unit/ApplicationPasswordTest.php
new file mode 100644
index 0000000..3c2d387
--- /dev/null
+++ b/tests/Unit/ApplicationPasswordTest.php
@@ -0,0 +1,73 @@
+andReturn(true);
+
+ $this
+ ->wpHasher()
+ ->shouldReceive('CheckPassword')
+ ->times(3)
+ ->andReturnValues([true, true, false]);
+
+ expect('update_user_meta')
+ ->once()
+ ->withArgs(function (...$args) {
+ [$userId, $metaKey, $passwords] = $args;
+
+ if ($userId != Constants::USER_ID) {
+ return false;
+ }
+
+ if ($metaKey != \WP_Application_Passwords::USERMETA_KEY_APPLICATION_PASSWORDS) {
+ return false;
+ }
+
+ if (count($passwords) != 3) {
+ return false;
+ }
+
+ if (!key_exists(0, $passwords)) {
+ return false;
+ }
+
+ $passwords = array_map((function ($item) {
+ return $item['password'];
+ }), $passwords);
+
+ [$pw1, $pw2, $pw3] = $passwords;
+
+ if (!password_verify(Constants::PASSWORD, $pw1)) {
+ return false;
+ }
+
+ if (!password_verify(Constants::PASSWORD, $pw2)) {
+ return false;
+ }
+
+ if (password_verify(Constants::PASSWORD, $pw3)) {
+ return false;
+ }
+
+ return true;
+ });
+
+ $hash = wp_set_password(Constants::PASSWORD, Constants::USER_ID);
+ }
+}
diff --git a/tests/WPApplicationPasswords.php b/tests/WPApplicationPasswords.php
new file mode 100644
index 0000000..cd7b3d9
--- /dev/null
+++ b/tests/WPApplicationPasswords.php
@@ -0,0 +1,25 @@
+ Constants::PHPPASS_HASH
+ ],
+ [
+ 'password' => Constants::BCRYPT_HASH
+ ],
+ [
+ 'password' => Constants::INVALID_HASH
+ ]
+ ];
+ }
+}
diff --git a/wp-password-bcrypt.php b/wp-password-bcrypt.php
index eef184a..1b92d2d 100644
--- a/wp-password-bcrypt.php
+++ b/wp-password-bcrypt.php
@@ -86,14 +86,52 @@ function wp_hash_password($password)
function wp_set_password($password, $user_id)
{
$hash = wp_hash_password($password);
- global $wpdb;
+ $is_api_request = apply_filters(
+ 'application_password_is_api_request',
+ (defined('XMLRPC_REQUEST') && XMLRPC_REQUEST) ||
+ (defined('REST_REQUEST') && REST_REQUEST)
+ );
+
+ if (! $is_api_request) {
+ global $wpdb;
+
+ $wpdb->update($wpdb->users, [
+ 'user_pass' => $hash,
+ 'user_activation_key' => ''
+ ], ['ID' => $user_id]);
+
+ clean_user_cache($user_id);
+
+ return $hash;
+ }
+
+ if (
+ ! class_exists('WP_Application_Passwords') ||
+ empty($passwords = WP_Application_Passwords::get_user_application_passwords($user_id))
+ ) {
+ return;
+ }
+
+ global $wp_hasher;
- $wpdb->update($wpdb->users, [
- 'user_pass' => $hash,
- 'user_activation_key' => ''
- ], ['ID' => $user_id]);
+ if (empty($wp_hasher)) {
+ require_once ABSPATH . WPINC . '/class-phpass.php';
+ $wp_hasher = new PasswordHash(8, true);
+ }
- clean_user_cache($user_id);
+ foreach ($passwords as $key => $value) {
+ if (! $wp_hasher->CheckPassword($password, $value['password'])) {
+ continue;
+ }
+
+ $passwords[$key]['password'] = $hash;
+ }
+
+ update_user_meta(
+ $user_id,
+ WP_Application_Passwords::USERMETA_KEY_APPLICATION_PASSWORDS,
+ $passwords
+ );
return $hash;
}