Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Jetpack: Account Protection #40925

Open
wants to merge 12 commits into
base: trunk
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
Significance: minor
Type: added

Adds Account Protection requests
10 changes: 10 additions & 0 deletions projects/js-packages/api/index.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -510,6 +510,16 @@ function JetpackRestApiClient( root, nonce ) {
getRequest( `${ wpcomOriginApiUrl }jetpack/v4/search/stats`, getParams )
.then( checkStatus )
.then( parseJsonResponse ),
fetchAccountProtectionSettings: () =>
getRequest( `${ apiRoot }jetpack/v4/account-protection`, getParams )
.then( checkStatus )
.then( parseJsonResponse ),
updateAccountProtectionSettings: newSettings =>
postRequest( `${ apiRoot }jetpack/v4/account-protection`, postParams, {
body: JSON.stringify( newSettings ),
} )
.then( checkStatus )
.then( parseJsonResponse ),
fetchWafSettings: () =>
getRequest( `${ apiRoot }jetpack/v4/waf`, getParams )
.then( checkStatus )
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
Significance: minor
Type: added

Adds handling for module activation and deactivation
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
Significance: minor
Type: added

Adds the password detection flow
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
Significance: minor
Type: changed

Moves get_settings method to primary class
4 changes: 3 additions & 1 deletion projects/packages/account-protection/composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,9 @@
"type": "jetpack-library",
"license": "GPL-2.0-or-later",
"require": {
"php": ">=7.2"
"php": ">=7.2",
"automattic/jetpack-connection": "@dev",
"automattic/jetpack-status": "@dev"
},
"require-dev": {
"yoast/phpunit-polyfills": "^1.1.1",
Expand Down
21 changes: 21 additions & 0 deletions projects/packages/account-protection/src/assets/jetpack-logo.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
197 changes: 193 additions & 4 deletions projects/packages/account-protection/src/class-account-protection.php
Original file line number Diff line number Diff line change
@@ -1,16 +1,205 @@
<?php
/**
* Package description here
* Class used to define Account Protection.
*
* @package automattic/jetpack-account-protection
*/

namespace Automattic\Jetpack;
namespace Automattic\Jetpack\Account_Protection;

use Automattic\Jetpack\Modules;

/**
* Class description.
* Class Account_Protection
*/
class Account_Protection {
const PACKAGE_VERSION = '0.1.0-alpha';
const ACCOUNT_PROTECTION_MODULE_NAME = 'account-protection';
const STRICT_MODE_OPTION_NAME = 'jetpack_account_protection_strict_mode';

/**
* Modules instance.
*
* @var Modules
*/
private $modules;

/**
* Password detection instance.
*
* @var Password_Detection
*/
private $password_detection;

/**
* Account_Protection constructor.
*
* @param ?Modules $modules Modules instance.
* @param ?Password_Detection $password_detection Password detection instance.
*/
public function __construct( ?Modules $modules = null, ?Password_Detection $password_detection = null ) {
$this->modules = $modules ?? new Modules();
$this->password_detection = $password_detection ?? new Password_Detection();
}

/**
* Initializes the configurations needed for the account protection module.
*/
public function init(): void {
$this->register_hooks();

if ( $this->is_enabled() ) {
$this->register_runtime_hooks();
}
}

/**
* Register hooks for module activation and environment validation.
*/
private function register_hooks(): void {
// Account protection activation/deactivation hooks
add_action( 'jetpack_activate_module_' . self::ACCOUNT_PROTECTION_MODULE_NAME, array( $this, 'on_account_protection_activation' ) );
add_action( 'jetpack_deactivate_module_' . self::ACCOUNT_PROTECTION_MODULE_NAME, array( $this, 'on_account_protection_deactivation' ) );

// Do not run in unsupported environments
add_action( 'jetpack_get_available_modules', array( $this, 'remove_module_on_unsupported_environments' ) );
add_action( 'jetpack_get_available_standalone_modules', array( $this, 'remove_standalone_module_on_unsupported_environments' ) );

// Register REST routes
add_action( 'rest_api_init', array( new REST_Controller(), 'register_rest_routes' ) );
}

/**
* Register hooks for runtime operations.
*/
private function register_runtime_hooks(): void {
// Validate password after successful login
add_action( 'wp_authenticate_user', array( $this->password_detection, 'login_form_password_detection' ), 10, 2 );

// Add password detection flow
add_action( 'login_form_password-detection', array( $this->password_detection, 'render_page' ), 10, 2 );

// Remove password detection usermeta after password reset and on profile password update
add_action( 'after_password_reset', array( $this->password_detection, 'delete_usermeta_after_password_reset' ), 10, 2 );
add_action( 'profile_update', array( $this->password_detection, 'delete_usermeta_on_profile_update' ), 10, 2 );

// Register AJAX resend password reset email action
add_action( 'wp_ajax_resend_password_reset', array( $this->password_detection, 'ajax_resend_password_reset_email' ) );
}

/**
* Activate the account protection on module activation.
*/
public function on_account_protection_activation(): void {
// Activation logic can be added here
}

/**
* Deactivate the account protection on module deactivation.
*/
public function on_account_protection_deactivation(): void {
// Remove password detection user meta on deactivation
// TODO: Run on Jetpack and Protect deactivation
$this->password_detection->delete_all_usermeta();
}

/**
* Determines if the account protection module is enabled on the site.
*
* @return bool
*/
public function is_enabled() {
return $this->modules->is_active( self::ACCOUNT_PROTECTION_MODULE_NAME );
}

/**
* Enables the account protection module.
*
* @return bool
*/
public function enable() {
// Return true if already enabled.
if ( $this->is_enabled() ) {
return true;
}
return $this->modules->activate( self::ACCOUNT_PROTECTION_MODULE_NAME, false, false );
}

/**
* Disables the account protection module.
*
* @return bool
*/
public function disable(): bool {
// Return true if already disabled.
if ( ! $this->is_enabled() ) {
return true;
}
return $this->modules->deactivate( self::ACCOUNT_PROTECTION_MODULE_NAME );
}

/**
* Determines if Account Protection is supported in the current environment.
*
* @return bool
*/
public function is_supported_environment(): bool {
// Do not run when killswitch is enabled
if ( defined( 'DISABLE_JETPACK_ACCOUNT_PROTECTION' ) && DISABLE_JETPACK_ACCOUNT_PROTECTION ) {
return false;
}

return true;
}

/**
* Disables the Account Protection module when on an unsupported platform in Jetpack.
*
* @param array $modules Filterable value for `jetpack_get_available_modules`.
*
* @return array Array of module slugs.
*/
public function remove_module_on_unsupported_environments( array $modules ): array {
if ( ! $this->is_supported_environment() ) {
// Account protection should never be available on unsupported platforms.
unset( $modules[ self::ACCOUNT_PROTECTION_MODULE_NAME ] );
}

return $modules;
}

/**
* Disables the Account Protection module when on an unsupported platform in a standalone plugin.
*
* @param array $modules Filterable value for `jetpack_get_available_standalone_modules`.
*
* @return array Array of module slugs.
*/
public function remove_standalone_module_on_unsupported_environments( array $modules ): array {
if ( ! $this->is_supported_environment() ) {
// Account Protection should never be available on unsupported platforms.
$modules = array_filter(
$modules,
function ( $module ) {
return $module !== self::ACCOUNT_PROTECTION_MODULE_NAME;
}
);

}

return $modules;
}

/**
* Get the account protection settings.
*
* @return array
*/
public function get_settings(): array {
$settings = array(
self::STRICT_MODE_OPTION_NAME => get_option( self::STRICT_MODE_OPTION_NAME, false ),
);

const PACKAGE_VERSION = '0.1.0-alpha';
return $settings;
}
}
Loading
Loading