diff --git a/argus-wordpress-defence.php b/argus-wordpress-defence.php
index 5afe57d..dc9e679 100644
--- a/argus-wordpress-defence.php
+++ b/argus-wordpress-defence.php
@@ -3,7 +3,7 @@
* Plugin Name: ARGUS WordPress Defence
* Plugin URI: https://git-cloud.weboria.eu/Weboria/argus-wp-defence
* Description: Standalone WordPress security: local WAF, malware & integrity scanning, vulnerability intelligence, and a deterministic ban/policy engine. Works fully offline; optionally connects to ARGUS Cloud for richer intelligence and cross-asset correlation.
- * Version: 7.23.1
+ * Version: 7.23.2
* Requires at least: 6.0
* Requires PHP: 7.4
* Author: ARGUS
@@ -28,7 +28,7 @@ if ( ! defined( 'ABSPATH' ) ) {
exit;
}
-define( 'ARGUS_WPD_VERSION', '7.23.1' );
+define( 'ARGUS_WPD_VERSION', '7.23.2' );
define( 'ARGUS_WPD_FILE', __FILE__ );
define( 'ARGUS_WPD_DIR', plugin_dir_path( __FILE__ ) );
define( 'ARGUS_WPD_URL', plugin_dir_url( __FILE__ ) );
diff --git a/bin/build-release.sh b/bin/build-release.sh
index dd41fbc..b348b36 100755
--- a/bin/build-release.sh
+++ b/bin/build-release.sh
@@ -46,24 +46,20 @@ rm -rf \
if [ "${CHANNEL}" = "wporg" ]; then
# A plugin hosted on WordPress.org must rely solely on WordPress.org's own
# update channel -- never a self-update-from-external-manifest mechanism,
- # even one that ships inert-by-default. class_exists( 'Argus_Update_Client' )
- # guards every reference to this class elsewhere in the codebase, so
- # removing the file here is sufficient; nothing else needs to change.
+ # even one that ships inert-by-default -- and must stay genuinely,
+ # permanently functional with no license/trial requirement (WordPress.org
+ # explicitly prohibits trialware). class_exists() guards every reference
+ # to both classes elsewhere in the codebase, so removing the files here is
+ # sufficient; nothing else needs to change per build.
echo "==> [wporg channel] Removing the self-update client (WordPress.org must be the only update channel)"
rm -f "${STAGE_DIR}/includes/class-argus-update-client.php"
+ echo "==> [wporg channel] Removing the license/trial system (WordPress.org prohibits trialware)"
+ rm -f "${STAGE_DIR}/includes/class-argus-license.php"
elif [ "${CHANNEL}" != "self" ]; then
echo "==> BUILD FAILED: unknown channel '${CHANNEL}' (expected 'self' or 'wporg')"
exit 1
fi
-# WordPress.org explicitly prohibits trialware -- a plugin submitted to the
-# directory must stay genuinely, permanently functional with no license
-# requirement. class_exists( 'Argus_License' ) guards every reference to
-# this class elsewhere, so removing the file here is sufficient; the free
-# build never has a trial timer at all.
-echo "==> Removing the license/trial system (WordPress.org prohibits trialware)"
-rm -f "${STAGE_DIR}/includes/class-argus-license.php"
-
echo "==> Allowlist audit -- fail closed on anything unexpected"
UNEXPECTED=0
while IFS= read -r -d '' item; do
diff --git a/includes/class-argus-license.php b/includes/class-argus-license.php
new file mode 100644
index 0000000..7130c3e
--- /dev/null
+++ b/includes/class-argus-license.php
@@ -0,0 +1,127 @@
+ unlicensed. Key present but no validation
+ // endpoint configured -> still unlicensed, not a silent green light.
+ public static function is_licensed() {
+ if ( '' === self::license_key() || '' === self::validation_endpoint() ) {
+ return false;
+ }
+ return 'valid' === get_option( self::LICENSE_STATUS_OPTION, '' );
+ }
+
+ public static function validate_now() {
+ $key = self::license_key();
+ $url = self::validation_endpoint();
+ if ( '' === $key ) {
+ return array( 'success' => false, 'message' => __( 'Enter a license key first.', 'argus-wordpress-defence' ) );
+ }
+ if ( '' === $url ) {
+ return array( 'success' => false, 'message' => __( 'No license validation server is configured for this deployment.', 'argus-wordpress-defence' ) );
+ }
+
+ $response = wp_remote_post(
+ $url,
+ array(
+ 'timeout' => 15,
+ 'headers' => array( 'Content-Type' => 'application/json' ),
+ 'body' => wp_json_encode( array( 'license_key' => $key, 'domain' => wp_parse_url( home_url(), PHP_URL_HOST ) ) ),
+ )
+ );
+
+ update_option( self::LICENSE_CHECKED_OPTION, current_time( 'mysql', true ), false );
+
+ if ( is_wp_error( $response ) || 200 !== (int) wp_remote_retrieve_response_code( $response ) ) {
+ update_option( self::LICENSE_STATUS_OPTION, 'error', false );
+ return array( 'success' => false, 'message' => __( 'Could not reach the license server. Try again shortly.', 'argus-wordpress-defence' ) );
+ }
+
+ $data = json_decode( wp_remote_retrieve_body( $response ), true );
+ $valid = is_array( $data ) && ! empty( $data['valid'] );
+ update_option( self::LICENSE_STATUS_OPTION, $valid ? 'valid' : 'invalid', false );
+
+ return array(
+ 'success' => $valid,
+ 'message' => $valid
+ ? __( 'License activated.', 'argus-wordpress-defence' )
+ : __( 'That license key is not valid or has expired.', 'argus-wordpress-defence' ),
+ );
+ }
+
+ public static function status() {
+ if ( self::is_licensed() ) {
+ return 'licensed';
+ }
+ return self::days_remaining() > 0 ? 'trial' : 'trial_expired';
+ }
+
+ public static function summary() {
+ return array(
+ 'status' => self::status(),
+ 'days_remaining' => self::days_remaining(),
+ 'trial_ends_at' => gmdate( 'Y-m-d H:i:s', self::trial_ends_at() ),
+ 'has_key' => '' !== self::license_key(),
+ 'purchase_url' => defined( 'ARGUS_WPD_LICENSE_PURCHASE_URL' ) ? ARGUS_WPD_LICENSE_PURCHASE_URL : '',
+ );
+ }
+}
diff --git a/readme.txt b/readme.txt
index 21147e1..151ac58 100644
--- a/readme.txt
+++ b/readme.txt
@@ -4,7 +4,7 @@ Tags: security, firewall, malware, vulnerability, backup
Requires at least: 6.0
Tested up to: 7.0
Requires PHP: 7.4
-Stable tag: 7.23.1
+Stable tag: 7.23.2
License: GPLv2 or later
License URI: https://www.gnu.org/licenses/gpl-2.0.html
@@ -53,6 +53,12 @@ dashboard whenever a new version is available, and you can update it in one clic
== Changelog ==
+= 7.23.2 =
+* Settings: added a License section -- a 30-day trial with everything active, then enter a
+ license key to keep Premium features. Protection never stops regardless of license status.
+* Intelligence page: rewrote descriptions in plain language focused on what's protecting your
+ site, not internal implementation details.
+
= 7.23.1 =
* Automatic updates: fixed a bug where a normal (non-critical) update would be detected and
shown as available, but never actually installed -- now any newer, compatible, verified