Files
wc-licensed-product/CHANGELOG.md
magdev a93381dce6 Bump version to 0.3.8
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-24 15:34:38 +01:00

22 KiB

Changelog

All notable changes to this project will be documented in this file.

The format is based on Keep a Changelog, and this project adheres to Semantic Versioning.

Unreleased

[0.3.8] - 2026-01-24

Fixed

  • Fixed duplicate German translation string causing ArgumentCountError in settings page
  • The notification settings description had duplicated text with two %s placeholders

Changed

  • Updated magdev/wc-licensed-product-client to latest version (64d215c)

[0.3.7] - 2026-01-24

Added

  • Download counter for licensed product versions (tracked per version)
  • Download Statistics admin dashboard widget showing total downloads, top products, and top versions
  • New DownloadWidgetController class for download statistics widget
  • New incrementDownloadCount(), getTotalDownloadCount(), and getDownloadStatistics() methods in VersionManager
  • New download_count column in product versions database table

Fixed

  • Dashboard widget "View All Licenses" link now uses correct page slug (wc-licenses)
  • Download links in customer account page no longer result in 404 errors (added query var registration)
  • Added license-download endpoint registration during plugin activation

Changed

  • Removed redundant "Status Breakdown" section from dashboard widget (info already shown in stat cards)
  • License Types section in dashboard widget now uses card style matching the stats row above
  • Improved dashboard widget visual consistency

Technical Details

  • Added addDownloadQueryVar() method to DownloadController for proper endpoint registration
  • Updated Installer::activate() to register license-download endpoint before flushing rewrite rules
  • Updated translations (356 strings)

[0.3.6] - 2026-01-23

Security

  • Added CSRF protection (nonce verification) to CSV export functionality
  • Fixed IP header spoofing vulnerability in rate limiting - now requires explicit trusted proxy configuration
  • Enabled explicit Twig autoescape for XSS protection
  • Fixed unescaped status values in CSS classes in Twig templates

Fixed

  • Fixed response signing to use recursive key sorting for client compatibility
  • ResponseSigner now recursively sorts nested array keys alphabetically as required by client implementation

Changed

  • Rate limiting now only trusts proxy headers when WC_LICENSE_TRUSTED_PROXIES constant is defined
  • Added Cloudflare IP range support via WC_LICENSE_TRUSTED_PROXIES = 'CLOUDFLARE' configuration
  • Improved IP detection with CIDR notation support for trusted proxy ranges

Technical Details

  • Added recursiveKeySort() method to ResponseSigner for proper response signing
  • Added isTrustedProxy(), isCloudflareIp(), and ipMatchesCidr() methods to RestApiController
  • Twig environment now explicitly sets autoescape => 'html'
  • Export CSV link now includes nonce via wp_nonce_url()
  • Added export_csv_url() Twig function for generating export URL with nonce

[0.3.5] - 2026-01-23

Added

  • Admin dashboard widget showing license statistics on WordPress dashboard
  • Automatic license expiration via daily wp-cron job
  • License expired email notification sent when license auto-expires
  • New LicenseExpiredEmail WooCommerce email class (configurable via WooCommerce > Settings > Emails)

Changed

  • Improved download list layout in customer account licenses page
  • Downloads now displayed in two-row format: file link on first row, metadata on second row
  • Better visual separation between download link and version/date/checksum information

Technical Details

  • New DashboardWidgetController class in src/Admin/ for WordPress dashboard widget
  • Widget displays: total licenses, active, expiring soon, expired counts, status breakdown, license types
  • New LicenseExpiredEmail class in src/Email/ for expired license notifications
  • Added getExpiredActiveLicenses() and autoExpireLicense() methods to LicenseManager
  • Daily cron now auto-expires licenses with past expiration date and sends notification emails
  • Updated templates/frontend/licenses.html.twig with new two-row structure
  • Added .download-item, .download-row-file, .download-row-meta CSS classes
  • Improved responsive behavior for download metadata

[0.3.4] - 2026-01-23

Added

  • Current version display on single product pages for licensed products
  • Version number shown directly under the product title
  • Frontend CSS styling for version badge with monospace font

Technical Details

  • Added displayCurrentVersion() method to LicensedProductType class
  • Hooked to woocommerce_single_product_summary at priority 6 (after title)
  • Added enqueueFrontendStyles() to load CSS on product pages
  • Uses LicensedProduct::get_current_version() to fetch latest version

0.3.3 - 2026-01-22

Fixed

  • Fixed version deactivation button not working in admin product versions table
  • Corrected parameter order in updateVersion() call - isActive was being passed to attachmentId parameter

Technical Details

  • Bug in VersionAdminController::ajaxToggleVersion() - parameters were in wrong order
  • Changed from updateVersion($versionId, null, null, !$currentlyActive) to updateVersion($versionId, null, !$currentlyActive, null)

0.3.2 - 2026-01-22

Changed

  • Updated OpenAPI specification to version 0.3.2
  • Added documentation for response signing headers (X-License-Signature, X-License-Timestamp)
  • Enhanced API description with response signing security information

Technical Details

  • OpenAPI spec now documents optional response signature headers
  • Added header component definitions for X-License-Signature and X-License-Timestamp
  • All endpoint 200 responses now reference signature headers
  • Improved API documentation describing SecureLicenseClient usage

0.3.1 - 2026-01-22

Changed

  • Settings page reorganized with sub-tab navigation similar to WooCommerce Advanced tab
  • Settings split into three sections: Plugin License, Default Settings, Notifications
  • Improved settings UI with WooCommerce-style section navigation

Technical Details

  • SettingsController refactored with getSections() and outputSections() methods
  • Section-specific settings methods using PHP 8 match expression
  • Hooks updated to use woocommerce_sections_licensed_product for sub-navigation

0.3.0 - 2026-01-22

Added

  • Self-licensing functionality: Plugin validates its own license against a remote server
  • Plugin license settings in WooCommerce > Settings > Licensed Products tab
  • License Server URL, License Key, and optional Server Secret configuration
  • License status display in settings with verify button
  • Localhost bypass: All features work without license when running on localhost
  • Admin notice when plugin license is not configured or invalid

Changed

  • Frontend features now require a valid plugin license to function
  • Disabled features without license: Checkout domain field, customer licenses page, downloads, license generation

Technical Details

  • New PluginLicenseChecker singleton class for license validation
  • Integration with magdev/wc-licensed-product-client Composer package
  • Caching: 1 hour for valid license, 5 minutes for errors
  • Localhost detection supports: localhost, 127.0.0.1, ::1, and .localhost/.local subdomains

0.2.2 - 2026-01-22

Added

  • SHA256 checksum column in admin product versions table
  • File hash display in customer account downloads section
  • Visual indicators for file integrity verification

Changed

  • Checksum file upload field now styled consistently with package upload field
  • Download list items now show truncated hash with full hash on hover

Technical Details

  • ProductVersion getFileHash() method now exposed in admin and frontend views
  • Frontend CSS extended with .download-hash styles
  • Admin CSS extended with .file-hash styles

0.2.1 - 2026-01-22

Changed

  • SHA256 hash input changed from text field to file upload field
  • Checksum files (.sha256 or .txt) can now be uploaded directly
  • Improved user experience for version integrity verification

Technical Details

  • Added readChecksumFile() JavaScript function using FileReader API with Promise support
  • Checksum file format supports both "hash filename" and plain "hash" formats
  • Added localized error messages for checksum file validation

0.2.0 - 2026-01-22

Added

  • Response signing for REST API using HMAC-SHA256
  • SHA256 hash field for product version uploads with checksum validation
  • File integrity verification before storing uploaded version files
  • New ResponseSigner class for automatic API response signing
  • Database column file_hash in versions table for storing checksums

Changed

  • Version uploads now require file attachments (external URL option removed)
  • API responses now include X-License-Signature and X-License-Timestamp headers when WC_LICENSE_SERVER_SECRET is configured

Removed

  • External download URL field from product version form
  • Direct URL support in version uploads (use Media Library uploads only)

Security

  • API response signing prevents tampering and replay attacks
  • Per-license key derivation using HKDF-like approach
  • SHA256 checksum validation ensures file integrity

Technical Details

  • New class: ResponseSigner for HMAC-SHA256 response signing
  • VersionManager extended with $fileHash parameter and validation
  • ProductVersion model extended with fileHash property
  • Signature algorithm: HMAC-SHA256(derived_key, timestamp + ':' + canonical_json)
  • Key derivation: HMAC-SHA256(HMAC-SHA256(license_key, server_secret) + "\x01", server_secret)
  • Compatible with magdev/wc-licensed-product-client SecureLicenseClient

Configuration

To enable response signing, add to wp-config.php:

define('WC_LICENSE_SERVER_SECRET', 'your-secure-random-string-min-32-chars');

0.1.0 - 2026-01-22

Added

  • First stable minor release
  • Comprehensive code review for WordPress/WooCommerce best practices
  • Security audit completed

Changed

  • Improved input sanitization for admin page context checks
  • Fixed VersionManager null format handling for attachment updates

Technical Details

  • All code reviewed for OWASP Top 10 security vulnerabilities
  • Verified proper nonce verification, capability checks, and input sanitization
  • SQL injection prevention confirmed using $wpdb->prepare() throughout
  • XSS prevention confirmed with proper output escaping
  • Rate limiting verified on REST API endpoints
  • README.md updated with full feature documentation

0.0.11 - 2026-01-22

Added

  • Created date column in admin license overview

Technical Details

  • Added "Created" column to licenses table in admin (Twig template and PHP fallback)
  • Shows when each license was generated

0.0.10 - 2026-01-21

Added

  • License meta box on WooCommerce order edit pages
  • Editable order domain field with AJAX save
  • Editable license domains directly from order page
  • View licenses table showing all licenses for an order
  • Link to full licenses management page from order view
  • Support for both classic orders and HPOS (High-Performance Order Storage)
  • Inline editing for license fields (status, expiry date, domain) in admin
  • Copy license key button in admin licenses overview
  • Live search for licenses in admin overview
  • Settings link in plugin actions

Fixed

  • Fixed 404 error on licenses menu item
  • Fixed Twig template cache issues with auto_reload

Technical Details

  • New OrderLicenseController class for order page integration
  • New getLicensesByOrder() method in LicenseManager
  • New updateLicenseExpiry() method in LicenseManager
  • JavaScript file order-licenses.js for inline domain editing
  • JavaScript file admin-licenses.js for live search and inline editing
  • AJAX handlers for updating order domain and license domains
  • AJAX handlers for inline editing (status, expiry, domain updates)

0.0.9 - 2026-01-21

Added

  • API client examples for multiple programming languages
  • cURL command examples (docs/client-examples/curl.sh)
  • PHP client class (docs/client-examples/php-client.php)
  • Python client class (docs/client-examples/python-client.py)
  • JavaScript/Node.js client (docs/client-examples/javascript-client.js)
  • C# client class (docs/client-examples/csharp-client.cs)
  • Client examples documentation (docs/client-examples/README.md)

Technical Details

  • All clients include rate limiting handling (HTTP 429)
  • Examples demonstrate validate, status, and activate endpoints
  • JavaScript client works in both browser and Node.js environments
  • Python client uses dataclasses for type-safe responses
  • C# client uses async/await patterns

0.0.8 - 2026-01-21

Changed

  • Current version now automatically derived from latest product version
  • Email system refactored to use WooCommerce transactional emails
  • License expiration warning email now configurable via WooCommerce email settings

Removed

  • "Current Version" field from product license settings panel

Technical Details

  • New LicenseExpirationEmail class extends WC_Email
  • LicensedProduct's get_current_version() queries VersionManager
  • Uses WooCommerce email header/footer templates
  • Warning days configurable in plugin settings

0.0.7 - 2026-01-21

Added

  • License Dashboard moved to WooCommerce Reports section (Reports > Licenses)
  • License search and filtering in admin (by license key, domain, status, product)
  • Customer-facing license transfer request with AJAX-based modal
  • Email notifications for license expiration warnings (7 days and 1 day before)
  • Bulk import licenses from CSV functionality
  • Import page with detailed format instructions
  • Scheduled cron job for daily expiration checks

Changed

  • Dashboard now accessible via WooCommerce > Reports > Licenses tab
  • License list page includes search box and filter dropdowns
  • Pagination preserves filter state
  • Import CSV button added to licenses page header

Technical Details

  • AccountController extended with customer transfer AJAX handler and domain normalization
  • LicenseEmailController extended with expiration warning scheduling and email templates
  • LicenseManager extended with getLicensesExpiringSoon(), markExpirationNotified(), wasExpirationNotified(), importLicense() methods
  • AdminController extended with CSV import handling and import page rendering
  • Installer clears cron events on plugin deactivation
  • Frontend JavaScript extended for transfer modal handling
  • Frontend CSS extended with modal and transfer button styles

0.0.6 - 2026-01-21

Added

  • License usage statistics/analytics dashboard (WooCommerce > License Dashboard)
  • License transfer functionality to change domain from admin
  • Export licenses to CSV functionality
  • OpenAPI 3.1 specification for REST API documentation (openapi.json)
  • Monthly license creation chart on dashboard
  • Top products and top domains statistics
  • Expiring soon alerts on dashboard

Removed

  • API endpoint /deactivate removed (license deactivation is now admin-only)

Changed

  • Licenses admin page header now includes Export CSV button
  • Actions column widened to accommodate Transfer link
  • Dashboard link added to licenses page

Technical Details

  • New admin page: License Dashboard with statistics overview
  • LicenseManager extended with transferLicense(), getStatistics(), exportLicensesForCsv() methods
  • AdminController extended with dashboard rendering, CSV export, and transfer handling
  • Transfer modal with form for domain change
  • REST API now only has three endpoints: /validate, /status, /activate
  • OpenAPI 3.1 specification documents all API endpoints with examples

0.0.5 - 2026-01-21

Added

  • Bulk license operations in admin (activate, deactivate, revoke, extend, delete)
  • License renewal/extension functionality (extend by 30/90/365 days)
  • Set license to lifetime (remove expiration)
  • Quick action buttons per license row (+30d, ∞, Revoke, Delete)
  • Checkbox selection for bulk operations with select-all functionality
  • Improved admin notices for bulk operation results

Changed

  • Licenses admin page redesigned with WordPress list table styling
  • License actions use row-actions pattern for cleaner UI
  • Bulk action dropdowns at top and bottom of table (synchronized)

Technical Details

  • LicenseManager extended with extendLicense(), setLicenseLifetime(), bulkUpdateStatus(), bulkDelete(), bulkExtend() methods
  • AdminController extended with bulk action handling and extend/lifetime actions
  • Twig template functions for generating action URLs with nonces
  • JavaScript for checkbox sync and bulk action handling

0.0.4 - 2026-01-21

Added

  • WooCommerce settings tab "Licensed Products" for default license settings
  • Default settings for Max Activations, License Validity, and Bind to Major Version
  • Per-product settings now override global defaults (empty = use default)
  • Settings link in product edit page pointing to WooCommerce settings

Changed

  • Product license settings now show placeholder with default values
  • LicensedProduct class now falls back to global defaults when product settings are empty

Technical Details

  • New class: SettingsController for WooCommerce settings integration
  • LicensedProduct model extended with has_custom_* methods for checking overrides
  • Settings stored using WooCommerce options API

0.0.3 - 2026-01-21

Added

  • File attachment support for product versions (WordPress Media Library integration)
  • Version auto-detection from uploaded filenames (e.g., plugin-v1.2.3.zip)
  • Customer download page for purchased licenses with secure authenticated downloads
  • License key copy-to-clipboard functionality on account page and emails
  • New card-based UI for customer licenses page with download section
  • DownloadController for secure file delivery with hash-based URL verification

Changed

  • Product versions meta box now hidden for non-licensed product types (dynamic show/hide)
  • Redesigned customer licenses page with modern card layout
  • Frontend JavaScript and CSS enhancements for better UX

Technical Details

  • New class: DownloadController for secure file downloads
  • Database schema updated: attachment_id column added to versions table
  • ProductVersion model extended with getEffectiveDownloadUrl() and getDownloadFilename()
  • Secure download URLs use hash verification (license_id-version_id-hash format)

0.0.2 - 2026-01-21

Added

  • Product version management UI in admin (meta box on product edit page)
  • AJAX-based version CRUD operations (add, delete, toggle active status)
  • ProductVersion model and VersionManager for version data handling
  • Email notifications with license keys on order completion
  • License information included in WooCommerce order completed emails
  • Rate limiting for REST API endpoints (30 requests/minute per IP)
  • Cloudflare and proxy-aware IP detection for rate limiting
  • JavaScript for version management interactions

Changed

  • Declared WooCommerce HPOS and cart/checkout blocks compatibility
  • Plugin name changed from "WC Licensed Product" to "WooCommerce Licensed Product"

Technical Details

  • New classes: ProductVersion, VersionManager, VersionAdminController, LicenseEmailController
  • Rate limiting uses WordPress transients for request counting
  • HTTP 429 response with Retry-After header when rate limited

0.0.1 - 2026-01-21

Added

  • Initial plugin structure with WordPress Plugin API integration
  • New WooCommerce product type "Licensed Product" for selling software licenses
  • License key generation with format XXXX-XXXX-XXXX-XXXX on order completion
  • Domain-based license validation (licenses bound to specific domains)
  • REST API endpoints for license management:
    • POST /wp-json/wc-licensed-product/v1/validate - Validate license for domain
    • POST /wp-json/wc-licensed-product/v1/status - Check license status
    • POST /wp-json/wc-licensed-product/v1/activate - Activate license on domain
  • Checkout domain field for licensed products
  • Customer account page "Licenses" to view purchased licenses
  • Admin interface for license management (WooCommerce > Licenses)
  • License settings per product:
    • Maximum activations per license
    • License validity period (days or lifetime)
    • Optional binding to major software version
    • Current version tracking
  • Custom database tables for licenses and product versions
  • Twig template engine integration for views
  • Full internationalization support (i18n)
  • German (Switzerland, formal) translation (de_CH)
  • WooCommerce HPOS compatibility
  • Responsive frontend license table

Technical

  • PHP 8.3+ required
  • WooCommerce 10.0+ required
  • PSR-4 autoloading via Composer
  • Twig 3.0 template engine
  • WordPress REST API integration
  • Custom WooCommerce product type extending WC_Product