You've already forked wc-licensed-product
Compare commits
4 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 548b2ae8af | |||
| e0001c3f4e | |||
| a879be989c | |||
| 40c08bf474 |
19
CHANGELOG.md
19
CHANGELOG.md
@@ -7,6 +7,25 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
||||
|
||||
## [Unreleased]
|
||||
|
||||
## [0.7.3] - 2026-02-01
|
||||
|
||||
### Fixed
|
||||
|
||||
- **Docker Environment Support:** API Verification Secret now visible on customer licenses page in Docker environments
|
||||
- Added `ResponseSigner::getServerSecret()` method to check multiple sources for server secret
|
||||
- Checks PHP constant, `getenv()`, `$_ENV`, and `$_SERVER` in priority order
|
||||
- Maintains full backward compatibility with standard WordPress installations
|
||||
|
||||
### Changed
|
||||
|
||||
- Updated `Plugin.php` to use `ResponseSigner::isSigningEnabled()` instead of direct constant check
|
||||
|
||||
### Technical Details
|
||||
|
||||
- Root cause: Docker WordPress setups using `wp-config-docker.php` with `getenv_docker()` don't always define PHP constants
|
||||
- The environment variable was accessible but the constant wasn't being created
|
||||
- New `getServerSecret()` method centralizes all server secret retrieval logic
|
||||
|
||||
## [0.7.2] - 2026-01-29
|
||||
|
||||
### Added
|
||||
|
||||
47
CLAUDE.md
47
CLAUDE.md
@@ -32,7 +32,9 @@ This project is proudly **"vibe-coded"** using Claude.AI - the entire codebase w
|
||||
|
||||
**Note for AI Assistants:** Clean this section after the specific features are done or new releases are made. Effective changes are tracked in `CHANGELOG.md`. Do not add completed versions here - document them in the Session History section at the end of this file.
|
||||
|
||||
No pending roadmap items.
|
||||
### Known Bugs
|
||||
|
||||
None currently tracked.
|
||||
|
||||
## Technical Stack
|
||||
|
||||
@@ -1945,3 +1947,46 @@ composer install
|
||||
- Automatically created by Gitea Actions CI/CD pipeline
|
||||
- Release package: 881 KiB with SHA256 checksum
|
||||
- First automated release - all future releases will use this workflow
|
||||
|
||||
**Additional fixes (same session):**
|
||||
|
||||
- Updated README.md with Auto-Updates section and Development section
|
||||
- Fixed CI/CD workflow to handle existing releases (delete before recreate)
|
||||
- When updating a tag, the workflow now checks for existing releases and deletes them first
|
||||
|
||||
**Lessons learned:**
|
||||
|
||||
- Gitea releases persist even when their tag is deleted - must delete release via API
|
||||
- Composer `symlink: false` doesn't always work - CI must manually replace symlinks with `cp -r`
|
||||
- Never create zip archives locally on this machine (fills up RAM indefinitely)
|
||||
- Gitea API endpoint for releases by tag: `GET /api/v1/repos/{owner}/{repo}/releases/tags/{tag}`
|
||||
|
||||
### 2026-02-01 - Bug Fix: API Verification Secret Not Visible
|
||||
|
||||
**Overview:**
|
||||
|
||||
Fixed the "API Verification Secret" (customer secret) not appearing on the customer account licenses page in Docker environments.
|
||||
|
||||
**Root Cause:**
|
||||
|
||||
The `WC_LICENSE_SERVER_SECRET` constant was not being defined even though the environment variable was set. In Docker WordPress setups using `wp-config-docker.php`, the `getenv_docker()` function retrieves values from environment variables, but the constant wasn't being created properly. The plugin was only checking for the PHP constant, not the environment variable directly.
|
||||
|
||||
**Fix:**
|
||||
|
||||
Added `ResponseSigner::getServerSecret()` static method that checks multiple sources for the server secret:
|
||||
|
||||
1. `WC_LICENSE_SERVER_SECRET` constant (standard WordPress configuration)
|
||||
2. `getenv('WC_LICENSE_SERVER_SECRET')` (Docker environments)
|
||||
3. `$_ENV['WC_LICENSE_SERVER_SECRET']` (some PHP configurations)
|
||||
4. `$_SERVER['WC_LICENSE_SERVER_SECRET']` (fallback)
|
||||
|
||||
**Modified files:**
|
||||
|
||||
- `src/Api/ResponseSigner.php` - Added `getServerSecret()` method, updated `isSigningEnabled()` and `getCustomerSecretForLicense()` to use it
|
||||
- `src/Plugin.php` - Updated to use `ResponseSigner::isSigningEnabled()` instead of direct constant check
|
||||
|
||||
**Technical notes:**
|
||||
|
||||
- The fix maintains backward compatibility with standard WordPress installations using constants
|
||||
- Docker environments can now use environment variables directly without needing the constant to be defined
|
||||
- All three methods (`isSigningEnabled()`, `getCustomerSecretForLicense()`, and constructor) now use the centralized `getServerSecret()` method
|
||||
|
||||
@@ -26,9 +26,7 @@ final class ResponseSigner
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
$this->serverSecret = defined('WC_LICENSE_SERVER_SECRET')
|
||||
? WC_LICENSE_SERVER_SECRET
|
||||
: '';
|
||||
$this->serverSecret = self::getServerSecret();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -185,7 +183,7 @@ final class ResponseSigner
|
||||
*/
|
||||
public static function getCustomerSecretForLicense(string $licenseKey): ?string
|
||||
{
|
||||
$serverSecret = defined('WC_LICENSE_SERVER_SECRET') ? WC_LICENSE_SERVER_SECRET : '';
|
||||
$serverSecret = self::getServerSecret();
|
||||
|
||||
if (empty($serverSecret)) {
|
||||
return null;
|
||||
@@ -201,6 +199,40 @@ final class ResponseSigner
|
||||
*/
|
||||
public static function isSigningEnabled(): bool
|
||||
{
|
||||
return defined('WC_LICENSE_SERVER_SECRET') && !empty(WC_LICENSE_SERVER_SECRET);
|
||||
return !empty(self::getServerSecret());
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the server secret from constant or environment variable
|
||||
*
|
||||
* Checks in order:
|
||||
* 1. WC_LICENSE_SERVER_SECRET constant (preferred)
|
||||
* 2. WC_LICENSE_SERVER_SECRET environment variable (Docker fallback)
|
||||
*
|
||||
* @return string The server secret, or empty string if not configured
|
||||
*/
|
||||
public static function getServerSecret(): string
|
||||
{
|
||||
// First check the constant (standard WordPress configuration)
|
||||
if (defined('WC_LICENSE_SERVER_SECRET') && !empty(WC_LICENSE_SERVER_SECRET)) {
|
||||
return WC_LICENSE_SERVER_SECRET;
|
||||
}
|
||||
|
||||
// Fallback to environment variable (Docker environments)
|
||||
$envSecret = getenv('WC_LICENSE_SERVER_SECRET');
|
||||
if ($envSecret !== false && !empty($envSecret)) {
|
||||
return $envSecret;
|
||||
}
|
||||
|
||||
// Also check $_ENV and $_SERVER (some PHP configurations)
|
||||
if (!empty($_ENV['WC_LICENSE_SERVER_SECRET'])) {
|
||||
return $_ENV['WC_LICENSE_SERVER_SECRET'];
|
||||
}
|
||||
|
||||
if (!empty($_SERVER['WC_LICENSE_SERVER_SECRET'])) {
|
||||
return $_SERVER['WC_LICENSE_SERVER_SECRET'];
|
||||
}
|
||||
|
||||
return '';
|
||||
}
|
||||
}
|
||||
|
||||
@@ -147,7 +147,7 @@ final class Plugin
|
||||
new LicenseEmailController($this->licenseManager);
|
||||
|
||||
// Initialize response signing if server secret is configured
|
||||
if (defined('WC_LICENSE_SERVER_SECRET') && WC_LICENSE_SERVER_SECRET !== '') {
|
||||
if (ResponseSigner::isSigningEnabled()) {
|
||||
(new ResponseSigner())->register();
|
||||
}
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
* Plugin Name: WooCommerce Licensed Product
|
||||
* Plugin URI: https://src.bundespruefstelle.ch/magdev/wc-licensed-product
|
||||
* Description: WooCommerce plugin to sell software products using license keys with domain-based validation.
|
||||
* Version: 0.7.2
|
||||
* Version: 0.7.3
|
||||
* Author: Marco Graetsch
|
||||
* Author URI: https://src.bundespruefstelle.ch/magdev
|
||||
* License: GPL-2.0-or-later
|
||||
@@ -28,7 +28,7 @@ if (!defined('ABSPATH')) {
|
||||
}
|
||||
|
||||
// Plugin constants
|
||||
define('WC_LICENSED_PRODUCT_VERSION', '0.7.2');
|
||||
define('WC_LICENSED_PRODUCT_VERSION', '0.7.3');
|
||||
define('WC_LICENSED_PRODUCT_PLUGIN_FILE', __FILE__);
|
||||
define('WC_LICENSED_PRODUCT_PLUGIN_DIR', plugin_dir_path(__FILE__));
|
||||
define('WC_LICENSED_PRODUCT_PLUGIN_URL', plugin_dir_url(__FILE__));
|
||||
|
||||
Reference in New Issue
Block a user