5 Commits

Author SHA1 Message Date
5834e067f4 Change license client to use git repository instead of local path
- Updated composer.json repository from local path to git URL
- Package magdev/wc-licensed-product-client now fetched from:
  https://src.bundespruefstelle.ch/magdev/wc-licensed-product-client.git
- Fixes symlink issues in release packages

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-22 19:19:44 +01:00
79417e4971 Update translations for v0.3.2
- Regenerated POT template with updated version
- Updated German (de_CH) translation
- Compiled .mo file

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-22 19:14:24 +01:00
304eb16e2e Update README with response signing documentation
- Added Response Signing section explaining X-License-Signature and X-License-Timestamp headers
- Added wp-config.php configuration example for WC_LICENSE_SERVER_SECRET
- Updated client section to recommend official magdev/wc-licensed-product-client Composer package
- Documented LicenseClient and SecureLicenseClient classes

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-22 19:12:58 +01:00
df4cfc7e84 Update OpenAPI specification for v0.3.2
- Updated OpenAPI version from 0.0.7 to 0.3.2
- Added documentation for response signing headers (X-License-Signature, X-License-Timestamp)
- Enhanced API description with security information about signature verification
- Added header component definitions to OpenAPI spec
- All endpoint 200 responses now reference optional signature headers

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-22 19:11:11 +01:00
812beb2a02 Update CLAUDE.md with v0.3.1 release information
- Added release package details for v0.3.1
- SHA256: 55468275522590cd68924bdf97cfcba8aa9e6ba11e2111d0234e16a1936b8adf

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-22 19:04:10 +01:00
9 changed files with 495 additions and 379 deletions

View File

@@ -7,6 +7,21 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
## [Unreleased] ## [Unreleased]
## [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 ## [0.3.1] - 2026-01-22
### Changed ### Changed
@@ -410,7 +425,8 @@ define('WC_LICENSE_SERVER_SECRET', 'your-secure-random-string-min-32-chars');
- WordPress REST API integration - WordPress REST API integration
- Custom WooCommerce product type extending WC_Product - Custom WooCommerce product type extending WC_Product
[Unreleased]: https://src.bundespruefstelle.ch/magdev/wc-licensed-product/compare/v0.3.1...HEAD [Unreleased]: https://src.bundespruefstelle.ch/magdev/wc-licensed-product/compare/v0.3.2...HEAD
[0.3.2]: https://src.bundespruefstelle.ch/magdev/wc-licensed-product/compare/v0.3.1...v0.3.2
[0.3.1]: https://src.bundespruefstelle.ch/magdev/wc-licensed-product/compare/v0.3.0...v0.3.1 [0.3.1]: https://src.bundespruefstelle.ch/magdev/wc-licensed-product/compare/v0.3.0...v0.3.1
[0.3.0]: https://src.bundespruefstelle.ch/magdev/wc-licensed-product/compare/v0.2.2...v0.3.0 [0.3.0]: https://src.bundespruefstelle.ch/magdev/wc-licensed-product/compare/v0.2.2...v0.3.0
[0.2.2]: https://src.bundespruefstelle.ch/magdev/wc-licensed-product/compare/v0.2.1...v0.2.2 [0.2.2]: https://src.bundespruefstelle.ch/magdev/wc-licensed-product/compare/v0.2.1...v0.2.2

View File

@@ -840,3 +840,32 @@ Reorganized the settings page with WooCommerce-style sub-tab navigation for bett
- Added `outputSections()` for WooCommerce-style navigation rendering - Added `outputSections()` for WooCommerce-style navigation rendering
- Split `getSettingsFields()` into section-specific methods using PHP 8 match expression - Split `getSettingsFields()` into section-specific methods using PHP 8 match expression
- Hooks: `woocommerce_sections_licensed_product` for sub-navigation - Hooks: `woocommerce_sections_licensed_product` for sub-navigation
**Release v0.3.1:**
- Created release package: `releases/wc-licensed-product-0.3.1.zip` (754 KB)
- SHA256: `55468275522590cd68924bdf97cfcba8aa9e6ba11e2111d0234e16a1936b8adf`
- Tagged as `v0.3.1` and pushed to `main` branch
### 2026-01-22 - Version 0.3.2 - OpenAPI Update
**Overview:**
Updated OpenAPI specification to document response signing feature added in v0.2.0.
**Implemented:**
- Updated OpenAPI version from 0.0.7 to 0.3.2
- Added documentation for X-License-Signature and X-License-Timestamp headers
- Enhanced API description with response signing security information
- Added header component definitions in OpenAPI spec
**Modified files:**
- `openapi.json` - Updated version and added signature header documentation
**Technical notes:**
- All endpoint 200 responses now reference optional signature headers
- Header definitions added to components section
- API description explains SecureLicenseClient usage for signature verification

View File

@@ -107,12 +107,42 @@ When a customer purchases a licensed product, they must enter the domain where t
Full API documentation available in `openapi.json` (OpenAPI 3.1 specification). Full API documentation available in `openapi.json` (OpenAPI 3.1 specification).
### Client Examples ### Response Signing (Optional)
Ready-to-use API client examples are available in `docs/client-examples/`: When the server is configured with a shared secret, all API responses include cryptographic signatures for tamper protection:
**Configuration (wp-config.php):**
```php
define('WC_LICENSE_SERVER_SECRET', 'your-secure-random-string-min-32-chars');
```
**Response Headers:**
| Header | Description |
| ------ | ----------- |
| `X-License-Signature` | HMAC-SHA256 signature of the response body |
| `X-License-Timestamp` | Unix timestamp when the response was generated |
The signature prevents man-in-the-middle attacks and ensures response integrity. Use the `magdev/wc-licensed-product-client` Composer package with the `SecureLicenseClient` class to automatically verify signatures.
### Client Libraries & Examples
**PHP (Recommended):** Install the official client library via Composer:
```bash
composer require magdev/wc-licensed-product-client
```
The library provides:
- `LicenseClient` - Standard client for API calls
- `SecureLicenseClient` - Client with automatic response signature verification
**Example clients** for other languages are available in `docs/client-examples/`:
- **cURL** - Shell script examples ([curl.sh](docs/client-examples/curl.sh)) - **cURL** - Shell script examples ([curl.sh](docs/client-examples/curl.sh))
- **PHP** - Client class with examples ([php-client.php](docs/client-examples/php-client.php)) - **PHP** - Standalone client example ([php-client.php](docs/client-examples/php-client.php))
- **Python** - Client class with dataclasses ([python-client.py](docs/client-examples/python-client.py)) - **Python** - Client class with dataclasses ([python-client.py](docs/client-examples/python-client.py))
- **JavaScript** - Browser and Node.js client ([javascript-client.js](docs/client-examples/javascript-client.js)) - **JavaScript** - Browser and Node.js client ([javascript-client.js](docs/client-examples/javascript-client.js))
- **C#** - Async client with System.Text.Json ([csharp-client.cs](docs/client-examples/csharp-client.cs)) - **C#** - Async client with System.Text.Json ([csharp-client.cs](docs/client-examples/csharp-client.cs))

View File

@@ -12,8 +12,8 @@
], ],
"repositories": [ "repositories": [
{ {
"type": "path", "type": "vcs",
"url": "/home/magdev/workspaces/php/wc-licensed-product-client" "url": "https://src.bundespruefstelle.ch/magdev/wc-licensed-product-client.git"
} }
], ],
"require": { "require": {

13
composer.lock generated
View File

@@ -4,14 +4,14 @@
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
"This file is @generated automatically" "This file is @generated automatically"
], ],
"content-hash": "0387e179142771dbc12a8dba42895bd0", "content-hash": "05af8ab515abe7e689c610724b54e27a",
"packages": [ "packages": [
{ {
"name": "magdev/wc-licensed-product-client", "name": "magdev/wc-licensed-product-client",
"version": "dev-main", "version": "dev-main",
"dist": { "source": {
"type": "path", "type": "git",
"url": "/home/magdev/workspaces/php/wc-licensed-product-client", "url": "https://src.bundespruefstelle.ch/magdev/wc-licensed-product-client.git",
"reference": "83037ea0c2d9e365cf9ec0ad50251d3ebc7e4782" "reference": "83037ea0c2d9e365cf9ec0ad50251d3ebc7e4782"
}, },
"require": { "require": {
@@ -24,6 +24,7 @@
"require-dev": { "require-dev": {
"phpunit/phpunit": "^11.0" "phpunit/phpunit": "^11.0"
}, },
"default-branch": true,
"type": "library", "type": "library",
"autoload": { "autoload": {
"psr-4": { "psr-4": {
@@ -51,9 +52,7 @@
"issues": "https://src.bundespruefstelle.ch/magdev/wc-licensed-product-client/issues", "issues": "https://src.bundespruefstelle.ch/magdev/wc-licensed-product-client/issues",
"source": "https://src.bundespruefstelle.ch/magdev/wc-licensed-product-client" "source": "https://src.bundespruefstelle.ch/magdev/wc-licensed-product-client"
}, },
"transport-options": { "time": "2026-01-22T15:24:57+00:00"
"relative": false
}
}, },
{ {
"name": "psr/cache", "name": "psr/cache",

View File

@@ -5,7 +5,7 @@ msgid ""
msgstr "" msgstr ""
"Project-Id-Version: WC Licensed Product 0.3.1\n" "Project-Id-Version: WC Licensed Product 0.3.1\n"
"Report-Msgid-Bugs-To: magdev3.0@gmail.com\n" "Report-Msgid-Bugs-To: magdev3.0@gmail.com\n"
"POT-Creation-Date: 2026-01-22 18:30+0100\n" "POT-Creation-Date: 2026-01-22 19:11+0100\n"
"PO-Revision-Date: 2026-01-22T17:15:00+00:00\n" "PO-Revision-Date: 2026-01-22T17:15:00+00:00\n"
"Last-Translator: Marco Graetsch <magdev3.0@gmail.com>\n" "Last-Translator: Marco Graetsch <magdev3.0@gmail.com>\n"
"Language-Team: German (Switzerland) <de_CH@li.org>\n" "Language-Team: German (Switzerland) <de_CH@li.org>\n"
@@ -15,193 +15,6 @@ msgstr ""
"Content-Transfer-Encoding: 8bit\n" "Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n" "Plural-Forms: nplurals=2; plural=(n != 1);\n"
#: src/Admin/SettingsController.php:54
msgid "Licensed Products"
msgstr "Lizensierte Produkte"
#: src/Admin/SettingsController.php:64 src/Admin/SettingsController.php:128
msgid "Plugin License"
msgstr "Plugin-Lizenz"
#: src/Admin/SettingsController.php:65
msgid "Default Settings"
msgstr "Standardeinstellungen"
#: src/Admin/SettingsController.php:66
msgid "Notifications"
msgstr "Benachrichtigungen"
#: src/Admin/SettingsController.php:130
msgid ""
"Configure the license for this plugin. A valid license is required for "
"frontend features to work."
msgstr ""
"Konfigurieren Sie die Lizenz für dieses Plugin. Eine gültige Lizenz ist "
"erforderlich, damit die Frontend-Funktionen funktionieren."
#: src/Admin/SettingsController.php:134
msgid "License Server URL"
msgstr "Lizenzserver-URL"
#: src/Admin/SettingsController.php:136
msgid "The URL of the license server (e.g., https://shop.example.com)."
msgstr "Die URL des Lizenzservers (z.B. https://shop.example.com)."
#: src/Admin/SettingsController.php:142
#: src/Admin/OrderLicenseController.php:144 src/Admin/AdminController.php:1253
#: src/Admin/AdminController.php:1391 src/Email/LicenseEmailController.php:230
msgid "License Key"
msgstr "Lizenzschlüssel"
#: src/Admin/SettingsController.php:144
msgid "Your license key in XXXX-XXXX-XXXX-XXXX format."
msgstr "Ihr Lizenzschlüssel im Format XXXX-XXXX-XXXX-XXXX."
#: src/Admin/SettingsController.php:150
msgid "Server Secret (Optional)"
msgstr "Server-Secret (Optional)"
#: src/Admin/SettingsController.php:152
msgid ""
"If the license server uses signed responses, enter the shared secret here "
"for enhanced security."
msgstr ""
"Falls der Lizenzserver signierte Antworten verwendet, geben Sie hier das "
"gemeinsame Secret für erhöhte Sicherheit ein."
#: src/Admin/SettingsController.php:170
msgid "Default License Settings"
msgstr "Standard Lizenz-Einstellungen"
#: src/Admin/SettingsController.php:172
msgid ""
"These settings serve as defaults for new licensed products. Individual "
"product settings override these defaults."
msgstr ""
"Diese Einstellungen dienen als Standard für neue lizensierte Produkte. "
"Individuelle Produkteinstellungen überschreiben diese Standards."
#: src/Admin/SettingsController.php:176
msgid "Default Max Activations"
msgstr "Standard Max. Aktivierungen"
#: src/Admin/SettingsController.php:178
msgid "Default maximum number of domain activations per license."
msgstr "Standard maximale Anzahl der Domain-Aktivierungen pro Lizenz."
#: src/Admin/SettingsController.php:187
msgid "Default License Validity (Days)"
msgstr "Standard Lizenz-Gültigkeit (Tage)"
#: src/Admin/SettingsController.php:189
msgid ""
"Default number of days a license is valid. Leave empty or set to 0 for "
"lifetime licenses."
msgstr ""
"Standard Anzahl Tage, die eine Lizenz gültig ist. Leer lassen oder auf 0 "
"setzen für lebenslange Lizenzen."
#: src/Admin/SettingsController.php:192
#: src/Admin/OrderLicenseController.php:201 src/Admin/AdminController.php:148
#: src/Admin/AdminController.php:263 src/Admin/AdminController.php:1335
#: src/Product/LicensedProductType.php:104
#: src/Product/LicensedProductType.php:152
msgid "Lifetime"
msgstr "Lebenslang"
#: src/Admin/SettingsController.php:199
msgid "Default Bind to Major Version"
msgstr "Standard An Hauptversion binden"
#: src/Admin/SettingsController.php:201
msgid ""
"If enabled, licenses are bound to the major version at purchase time by "
"default."
msgstr ""
"Falls aktiviert, werden Lizenzen standardmässig an die Hauptversion zum "
"Kaufzeitpunkt gebunden."
#: src/Admin/SettingsController.php:219
msgid "Expiration Warning Schedule"
msgstr "Ablaufwarnung Zeitplan"
#: src/Admin/SettingsController.php:223
#, php-format
msgid ""
"Configure when expiration warning emails are sent. To customize the email "
"template, enable/disable, or change the subject, go to %s."
msgstr ""
"Konfigurieren Sie, wann Ablaufwarnungs-E-Mails gesendet werden. Um die E-"
"Mail-Vorlage anzupassen, zu aktivieren/deaktivieren oder den Betreff zu "
"ändern, gehen Sie zu %s."
#: src/Admin/SettingsController.php:225
msgid "WooCommerce > Settings > Emails > License Expiration Warning"
msgstr "WooCommerce > Einstellungen > E-Mails > Lizenzablauf-Warnung"
#: src/Admin/SettingsController.php:230
msgid "First Warning (Days Before)"
msgstr "Erste Warnung (Tage vorher)"
#: src/Admin/SettingsController.php:232
msgid "Days before expiration to send the first warning email."
msgstr "Tage vor Ablauf, um die erste Warn-E-Mail zu senden."
#: src/Admin/SettingsController.php:241
msgid "Second Warning (Days Before)"
msgstr "Zweite Warnung (Tage vorher)"
#: src/Admin/SettingsController.php:243
msgid ""
"Days before expiration to send the second warning email. Set to 0 to disable."
msgstr ""
"Tage vor Ablauf, um die zweite Warn-E-Mail zu senden. Setzen Sie auf 0, um "
"sie zu deaktivieren."
#: src/Admin/SettingsController.php:283
msgid "Running on localhost - license validation bypassed."
msgstr "Läuft auf localhost - Lizenzvalidierung übersprungen."
#: src/Admin/SettingsController.php:291
msgid "License is valid and active."
msgstr "Lizenz ist gültig und aktiv."
#: src/Admin/SettingsController.php:297
msgid "License is not valid. Frontend features are disabled."
msgstr "Lizenz ist ungültig. Frontend-Funktionen sind deaktiviert."
#: src/Admin/SettingsController.php:308 src/Admin/SettingsController.php:344
msgid "Verify License"
msgstr "Lizenz überprüfen"
#: src/Admin/SettingsController.php:322
msgid "Verifying..."
msgstr "Überprüfe..."
#: src/Admin/SettingsController.php:341
msgid "Request failed."
msgstr "Anfrage fehlgeschlagen."
#: src/Admin/SettingsController.php:454 src/Admin/AdminController.php:428
#: src/Admin/AdminController.php:448 src/Admin/AdminController.php:466
#: src/Admin/AdminController.php:484 src/Admin/AdminController.php:504
#: src/Admin/AdminController.php:522 src/Admin/AdminController.php:589
#: src/Admin/AdminController.php:779 src/Frontend/AccountController.php:326
msgid "Security check failed."
msgstr "Sicherheitsüberprüfung fehlgeschlagen."
#: src/Admin/SettingsController.php:458
msgid "Insufficient permissions."
msgstr "Unzureichende Berechtigungen."
#: src/Admin/SettingsController.php:467
msgid "License verified successfully!"
msgstr "Lizenz erfolgreich überprüft!"
#: src/Admin/SettingsController.php:469
msgid "License validation failed."
msgstr "Lizenzvalidierung fehlgeschlagen."
#: src/Admin/OrderLicenseController.php:56 #: src/Admin/OrderLicenseController.php:56
msgid "Product Licenses" msgid "Product Licenses"
msgstr "Produktlizenzen" msgstr "Produktlizenzen"
@@ -266,6 +79,12 @@ msgstr ""
"Lizenzen werden generiert, sobald die Bestellung als bezahlt/abgeschlossen " "Lizenzen werden generiert, sobald die Bestellung als bezahlt/abgeschlossen "
"markiert wird." "markiert wird."
#: src/Admin/OrderLicenseController.php:144 src/Admin/AdminController.php:1253
#: src/Admin/AdminController.php:1391 src/Admin/SettingsController.php:142
#: src/Email/LicenseEmailController.php:230
msgid "License Key"
msgstr "Lizenzschlüssel"
#: src/Admin/OrderLicenseController.php:145 src/Admin/AdminController.php:1254 #: src/Admin/OrderLicenseController.php:145 src/Admin/AdminController.php:1254
#: src/Admin/AdminController.php:1392 src/Email/LicenseEmailController.php:229 #: src/Admin/AdminController.php:1392 src/Email/LicenseEmailController.php:229
msgid "Product" msgid "Product"
@@ -306,6 +125,13 @@ msgstr "Domain bearbeiten"
msgid "Cancel" msgid "Cancel"
msgstr "Abbrechen" msgstr "Abbrechen"
#: src/Admin/OrderLicenseController.php:201 src/Admin/AdminController.php:148
#: src/Admin/AdminController.php:263 src/Admin/AdminController.php:1335
#: src/Admin/SettingsController.php:192 src/Product/LicensedProductType.php:104
#: src/Product/LicensedProductType.php:152
msgid "Lifetime"
msgstr "Lebenslang"
#: src/Admin/OrderLicenseController.php:208 #: src/Admin/OrderLicenseController.php:208
msgid "View in Licenses" msgid "View in Licenses"
msgstr "In Lizenzen anzeigen" msgstr "In Lizenzen anzeigen"
@@ -498,6 +324,14 @@ msgstr "Lizenz erfolgreich widerrufen."
msgid "Failed to revoke license." msgid "Failed to revoke license."
msgstr "Lizenz konnte nicht widerrufen werden." msgstr "Lizenz konnte nicht widerrufen werden."
#: src/Admin/AdminController.php:428 src/Admin/AdminController.php:448
#: src/Admin/AdminController.php:466 src/Admin/AdminController.php:484
#: src/Admin/AdminController.php:504 src/Admin/AdminController.php:522
#: src/Admin/AdminController.php:589 src/Admin/AdminController.php:779
#: src/Admin/SettingsController.php:454 src/Frontend/AccountController.php:326
msgid "Security check failed."
msgstr "Sicherheitsüberprüfung fehlgeschlagen."
#: src/Admin/AdminController.php:549 #: src/Admin/AdminController.php:549
msgid "You do not have permission to export licenses." msgid "You do not have permission to export licenses."
msgstr "Sie haben keine Berechtigung, Lizenzen zu exportieren." msgstr "Sie haben keine Berechtigung, Lizenzen zu exportieren."
@@ -899,6 +733,171 @@ msgstr "Lizenz"
msgid "No domain specified" msgid "No domain specified"
msgstr "Keine Domain angegeben" msgstr "Keine Domain angegeben"
#: src/Admin/SettingsController.php:54
msgid "Licensed Products"
msgstr "Lizensierte Produkte"
#: src/Admin/SettingsController.php:64 src/Admin/SettingsController.php:128
msgid "Plugin License"
msgstr "Plugin-Lizenz"
#: src/Admin/SettingsController.php:65
msgid "Default Settings"
msgstr "Standardeinstellungen"
#: src/Admin/SettingsController.php:66
msgid "Notifications"
msgstr "Benachrichtigungen"
#: src/Admin/SettingsController.php:130
msgid ""
"Configure the license for this plugin. A valid license is required for "
"frontend features to work."
msgstr ""
"Konfigurieren Sie die Lizenz für dieses Plugin. Eine gültige Lizenz ist "
"erforderlich, damit die Frontend-Funktionen funktionieren."
#: src/Admin/SettingsController.php:134
msgid "License Server URL"
msgstr "Lizenzserver-URL"
#: src/Admin/SettingsController.php:136
msgid "The URL of the license server (e.g., https://shop.example.com)."
msgstr "Die URL des Lizenzservers (z.B. https://shop.example.com)."
#: src/Admin/SettingsController.php:144
msgid "Your license key in XXXX-XXXX-XXXX-XXXX format."
msgstr "Ihr Lizenzschlüssel im Format XXXX-XXXX-XXXX-XXXX."
#: src/Admin/SettingsController.php:150
msgid "Server Secret (Optional)"
msgstr "Server-Secret (Optional)"
#: src/Admin/SettingsController.php:152
msgid ""
"If the license server uses signed responses, enter the shared secret here "
"for enhanced security."
msgstr ""
"Falls der Lizenzserver signierte Antworten verwendet, geben Sie hier das "
"gemeinsame Secret für erhöhte Sicherheit ein."
#: src/Admin/SettingsController.php:170
msgid "Default License Settings"
msgstr "Standard Lizenz-Einstellungen"
#: src/Admin/SettingsController.php:172
msgid ""
"These settings serve as defaults for new licensed products. Individual "
"product settings override these defaults."
msgstr ""
"Diese Einstellungen dienen als Standard für neue lizensierte Produkte. "
"Individuelle Produkteinstellungen überschreiben diese Standards."
#: src/Admin/SettingsController.php:176
msgid "Default Max Activations"
msgstr "Standard Max. Aktivierungen"
#: src/Admin/SettingsController.php:178
msgid "Default maximum number of domain activations per license."
msgstr "Standard maximale Anzahl der Domain-Aktivierungen pro Lizenz."
#: src/Admin/SettingsController.php:187
msgid "Default License Validity (Days)"
msgstr "Standard Lizenz-Gültigkeit (Tage)"
#: src/Admin/SettingsController.php:189
msgid ""
"Default number of days a license is valid. Leave empty or set to 0 for "
"lifetime licenses."
msgstr ""
"Standard Anzahl Tage, die eine Lizenz gültig ist. Leer lassen oder auf 0 "
"setzen für lebenslange Lizenzen."
#: src/Admin/SettingsController.php:199
msgid "Default Bind to Major Version"
msgstr "Standard An Hauptversion binden"
#: src/Admin/SettingsController.php:201
msgid ""
"If enabled, licenses are bound to the major version at purchase time by "
"default."
msgstr ""
"Falls aktiviert, werden Lizenzen standardmässig an die Hauptversion zum "
"Kaufzeitpunkt gebunden."
#: src/Admin/SettingsController.php:219
msgid "Expiration Warning Schedule"
msgstr "Ablaufwarnung Zeitplan"
#: src/Admin/SettingsController.php:223
#, php-format
msgid ""
"Configure when expiration warning emails are sent. To customize the email "
"template, enable/disable, or change the subject, go to %s."
msgstr ""
"Konfigurieren Sie, wann Ablaufwarnungs-E-Mails gesendet werden. Um die E-"
"Mail-Vorlage anzupassen, zu aktivieren/deaktivieren oder den Betreff zu "
"ändern, gehen Sie zu %s."
#: src/Admin/SettingsController.php:225
msgid "WooCommerce > Settings > Emails > License Expiration Warning"
msgstr "WooCommerce > Einstellungen > E-Mails > Lizenzablauf-Warnung"
#: src/Admin/SettingsController.php:230
msgid "First Warning (Days Before)"
msgstr "Erste Warnung (Tage vorher)"
#: src/Admin/SettingsController.php:232
msgid "Days before expiration to send the first warning email."
msgstr "Tage vor Ablauf, um die erste Warn-E-Mail zu senden."
#: src/Admin/SettingsController.php:241
msgid "Second Warning (Days Before)"
msgstr "Zweite Warnung (Tage vorher)"
#: src/Admin/SettingsController.php:243
msgid ""
"Days before expiration to send the second warning email. Set to 0 to disable."
msgstr ""
"Tage vor Ablauf, um die zweite Warn-E-Mail zu senden. Setzen Sie auf 0, um "
"sie zu deaktivieren."
#: src/Admin/SettingsController.php:283
msgid "Running on localhost - license validation bypassed."
msgstr "Läuft auf localhost - Lizenzvalidierung übersprungen."
#: src/Admin/SettingsController.php:291
msgid "License is valid and active."
msgstr "Lizenz ist gültig und aktiv."
#: src/Admin/SettingsController.php:297
msgid "License is not valid. Frontend features are disabled."
msgstr "Lizenz ist ungültig. Frontend-Funktionen sind deaktiviert."
#: src/Admin/SettingsController.php:308 src/Admin/SettingsController.php:344
msgid "Verify License"
msgstr "Lizenz überprüfen"
#: src/Admin/SettingsController.php:322
msgid "Verifying..."
msgstr "Überprüfe..."
#: src/Admin/SettingsController.php:341
msgid "Request failed."
msgstr "Anfrage fehlgeschlagen."
#: src/Admin/SettingsController.php:458
msgid "Insufficient permissions."
msgstr "Unzureichende Berechtigungen."
#: src/Admin/SettingsController.php:467
msgid "License verified successfully!"
msgstr "Lizenz erfolgreich überprüft!"
#: src/Admin/SettingsController.php:469
msgid "License validation failed."
msgstr "Lizenzvalidierung fehlgeschlagen."
#: src/Admin/VersionAdminController.php:58 #: src/Admin/VersionAdminController.php:58
msgid "Product Versions" msgid "Product Versions"
msgstr "Produktversionen" msgstr "Produktversionen"

View File

@@ -6,9 +6,9 @@
#, fuzzy #, fuzzy
msgid "" msgid ""
msgstr "" msgstr ""
"Project-Id-Version: WC Licensed Product 0.3.1\n" "Project-Id-Version: WC Licensed Product 0.3.2\n"
"Report-Msgid-Bugs-To: magdev3.0@gmail.com\n" "Report-Msgid-Bugs-To: magdev3.0@gmail.com\n"
"POT-Creation-Date: 2026-01-22 18:30+0100\n" "POT-Creation-Date: 2026-01-22 19:11+0100\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n" "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n" "Language-Team: LANGUAGE <LL@li.org>\n"
@@ -18,178 +18,6 @@ msgstr ""
"Content-Transfer-Encoding: 8bit\n" "Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=INTEGER; plural=EXPRESSION;\n" "Plural-Forms: nplurals=INTEGER; plural=EXPRESSION;\n"
#: src/Admin/SettingsController.php:54
msgid "Licensed Products"
msgstr ""
#: src/Admin/SettingsController.php:64 src/Admin/SettingsController.php:128
msgid "Plugin License"
msgstr ""
#: src/Admin/SettingsController.php:65
msgid "Default Settings"
msgstr ""
#: src/Admin/SettingsController.php:66
msgid "Notifications"
msgstr ""
#: src/Admin/SettingsController.php:130
msgid ""
"Configure the license for this plugin. A valid license is required for "
"frontend features to work."
msgstr ""
#: src/Admin/SettingsController.php:134
msgid "License Server URL"
msgstr ""
#: src/Admin/SettingsController.php:136
msgid "The URL of the license server (e.g., https://shop.example.com)."
msgstr ""
#: src/Admin/SettingsController.php:142
#: src/Admin/OrderLicenseController.php:144 src/Admin/AdminController.php:1253
#: src/Admin/AdminController.php:1391 src/Email/LicenseEmailController.php:230
msgid "License Key"
msgstr ""
#: src/Admin/SettingsController.php:144
msgid "Your license key in XXXX-XXXX-XXXX-XXXX format."
msgstr ""
#: src/Admin/SettingsController.php:150
msgid "Server Secret (Optional)"
msgstr ""
#: src/Admin/SettingsController.php:152
msgid ""
"If the license server uses signed responses, enter the shared secret here "
"for enhanced security."
msgstr ""
#: src/Admin/SettingsController.php:170
msgid "Default License Settings"
msgstr ""
#: src/Admin/SettingsController.php:172
msgid ""
"These settings serve as defaults for new licensed products. Individual "
"product settings override these defaults."
msgstr ""
#: src/Admin/SettingsController.php:176
msgid "Default Max Activations"
msgstr ""
#: src/Admin/SettingsController.php:178
msgid "Default maximum number of domain activations per license."
msgstr ""
#: src/Admin/SettingsController.php:187
msgid "Default License Validity (Days)"
msgstr ""
#: src/Admin/SettingsController.php:189
msgid ""
"Default number of days a license is valid. Leave empty or set to 0 for "
"lifetime licenses."
msgstr ""
#: src/Admin/SettingsController.php:192
#: src/Admin/OrderLicenseController.php:201 src/Admin/AdminController.php:148
#: src/Admin/AdminController.php:263 src/Admin/AdminController.php:1335
#: src/Product/LicensedProductType.php:104
#: src/Product/LicensedProductType.php:152
msgid "Lifetime"
msgstr ""
#: src/Admin/SettingsController.php:199
msgid "Default Bind to Major Version"
msgstr ""
#: src/Admin/SettingsController.php:201
msgid ""
"If enabled, licenses are bound to the major version at purchase time by "
"default."
msgstr ""
#: src/Admin/SettingsController.php:219
msgid "Expiration Warning Schedule"
msgstr ""
#: src/Admin/SettingsController.php:223
#, php-format
msgid ""
"Configure when expiration warning emails are sent. To customize the email "
"template, enable/disable, or change the subject, go to %s."
msgstr ""
#: src/Admin/SettingsController.php:225
msgid "WooCommerce > Settings > Emails > License Expiration Warning"
msgstr ""
#: src/Admin/SettingsController.php:230
msgid "First Warning (Days Before)"
msgstr ""
#: src/Admin/SettingsController.php:232
msgid "Days before expiration to send the first warning email."
msgstr ""
#: src/Admin/SettingsController.php:241
msgid "Second Warning (Days Before)"
msgstr ""
#: src/Admin/SettingsController.php:243
msgid ""
"Days before expiration to send the second warning email. Set to 0 to disable."
msgstr ""
#: src/Admin/SettingsController.php:283
msgid "Running on localhost - license validation bypassed."
msgstr ""
#: src/Admin/SettingsController.php:291
msgid "License is valid and active."
msgstr ""
#: src/Admin/SettingsController.php:297
msgid "License is not valid. Frontend features are disabled."
msgstr ""
#: src/Admin/SettingsController.php:308 src/Admin/SettingsController.php:344
msgid "Verify License"
msgstr ""
#: src/Admin/SettingsController.php:322
msgid "Verifying..."
msgstr ""
#: src/Admin/SettingsController.php:341
msgid "Request failed."
msgstr ""
#: src/Admin/SettingsController.php:454 src/Admin/AdminController.php:428
#: src/Admin/AdminController.php:448 src/Admin/AdminController.php:466
#: src/Admin/AdminController.php:484 src/Admin/AdminController.php:504
#: src/Admin/AdminController.php:522 src/Admin/AdminController.php:589
#: src/Admin/AdminController.php:779 src/Frontend/AccountController.php:326
msgid "Security check failed."
msgstr ""
#: src/Admin/SettingsController.php:458
msgid "Insufficient permissions."
msgstr ""
#: src/Admin/SettingsController.php:467
msgid "License verified successfully!"
msgstr ""
#: src/Admin/SettingsController.php:469
msgid "License validation failed."
msgstr ""
#: src/Admin/OrderLicenseController.php:56 #: src/Admin/OrderLicenseController.php:56
msgid "Product Licenses" msgid "Product Licenses"
msgstr "" msgstr ""
@@ -247,6 +75,12 @@ msgstr ""
msgid "Licenses will be generated when the order is marked as paid/completed." msgid "Licenses will be generated when the order is marked as paid/completed."
msgstr "" msgstr ""
#: src/Admin/OrderLicenseController.php:144 src/Admin/AdminController.php:1253
#: src/Admin/AdminController.php:1391 src/Admin/SettingsController.php:142
#: src/Email/LicenseEmailController.php:230
msgid "License Key"
msgstr ""
#: src/Admin/OrderLicenseController.php:145 src/Admin/AdminController.php:1254 #: src/Admin/OrderLicenseController.php:145 src/Admin/AdminController.php:1254
#: src/Admin/AdminController.php:1392 src/Email/LicenseEmailController.php:229 #: src/Admin/AdminController.php:1392 src/Email/LicenseEmailController.php:229
msgid "Product" msgid "Product"
@@ -287,6 +121,13 @@ msgstr ""
msgid "Cancel" msgid "Cancel"
msgstr "" msgstr ""
#: src/Admin/OrderLicenseController.php:201 src/Admin/AdminController.php:148
#: src/Admin/AdminController.php:263 src/Admin/AdminController.php:1335
#: src/Admin/SettingsController.php:192 src/Product/LicensedProductType.php:104
#: src/Product/LicensedProductType.php:152
msgid "Lifetime"
msgstr ""
#: src/Admin/OrderLicenseController.php:208 #: src/Admin/OrderLicenseController.php:208
msgid "View in Licenses" msgid "View in Licenses"
msgstr "" msgstr ""
@@ -475,6 +316,14 @@ msgstr ""
msgid "Failed to revoke license." msgid "Failed to revoke license."
msgstr "" msgstr ""
#: src/Admin/AdminController.php:428 src/Admin/AdminController.php:448
#: src/Admin/AdminController.php:466 src/Admin/AdminController.php:484
#: src/Admin/AdminController.php:504 src/Admin/AdminController.php:522
#: src/Admin/AdminController.php:589 src/Admin/AdminController.php:779
#: src/Admin/SettingsController.php:454 src/Frontend/AccountController.php:326
msgid "Security check failed."
msgstr ""
#: src/Admin/AdminController.php:549 #: src/Admin/AdminController.php:549
msgid "You do not have permission to export licenses." msgid "You do not have permission to export licenses."
msgstr "" msgstr ""
@@ -869,6 +718,156 @@ msgstr ""
msgid "No domain specified" msgid "No domain specified"
msgstr "" msgstr ""
#: src/Admin/SettingsController.php:54
msgid "Licensed Products"
msgstr ""
#: src/Admin/SettingsController.php:64 src/Admin/SettingsController.php:128
msgid "Plugin License"
msgstr ""
#: src/Admin/SettingsController.php:65
msgid "Default Settings"
msgstr ""
#: src/Admin/SettingsController.php:66
msgid "Notifications"
msgstr ""
#: src/Admin/SettingsController.php:130
msgid ""
"Configure the license for this plugin. A valid license is required for "
"frontend features to work."
msgstr ""
#: src/Admin/SettingsController.php:134
msgid "License Server URL"
msgstr ""
#: src/Admin/SettingsController.php:136
msgid "The URL of the license server (e.g., https://shop.example.com)."
msgstr ""
#: src/Admin/SettingsController.php:144
msgid "Your license key in XXXX-XXXX-XXXX-XXXX format."
msgstr ""
#: src/Admin/SettingsController.php:150
msgid "Server Secret (Optional)"
msgstr ""
#: src/Admin/SettingsController.php:152
msgid ""
"If the license server uses signed responses, enter the shared secret here "
"for enhanced security."
msgstr ""
#: src/Admin/SettingsController.php:170
msgid "Default License Settings"
msgstr ""
#: src/Admin/SettingsController.php:172
msgid ""
"These settings serve as defaults for new licensed products. Individual "
"product settings override these defaults."
msgstr ""
#: src/Admin/SettingsController.php:176
msgid "Default Max Activations"
msgstr ""
#: src/Admin/SettingsController.php:178
msgid "Default maximum number of domain activations per license."
msgstr ""
#: src/Admin/SettingsController.php:187
msgid "Default License Validity (Days)"
msgstr ""
#: src/Admin/SettingsController.php:189
msgid ""
"Default number of days a license is valid. Leave empty or set to 0 for "
"lifetime licenses."
msgstr ""
#: src/Admin/SettingsController.php:199
msgid "Default Bind to Major Version"
msgstr ""
#: src/Admin/SettingsController.php:201
msgid ""
"If enabled, licenses are bound to the major version at purchase time by "
"default."
msgstr ""
#: src/Admin/SettingsController.php:219
msgid "Expiration Warning Schedule"
msgstr ""
#: src/Admin/SettingsController.php:223
#, php-format
msgid ""
"Configure when expiration warning emails are sent. To customize the email "
"template, enable/disable, or change the subject, go to %s."
msgstr ""
#: src/Admin/SettingsController.php:225
msgid "WooCommerce > Settings > Emails > License Expiration Warning"
msgstr ""
#: src/Admin/SettingsController.php:230
msgid "First Warning (Days Before)"
msgstr ""
#: src/Admin/SettingsController.php:232
msgid "Days before expiration to send the first warning email."
msgstr ""
#: src/Admin/SettingsController.php:241
msgid "Second Warning (Days Before)"
msgstr ""
#: src/Admin/SettingsController.php:243
msgid ""
"Days before expiration to send the second warning email. Set to 0 to disable."
msgstr ""
#: src/Admin/SettingsController.php:283
msgid "Running on localhost - license validation bypassed."
msgstr ""
#: src/Admin/SettingsController.php:291
msgid "License is valid and active."
msgstr ""
#: src/Admin/SettingsController.php:297
msgid "License is not valid. Frontend features are disabled."
msgstr ""
#: src/Admin/SettingsController.php:308 src/Admin/SettingsController.php:344
msgid "Verify License"
msgstr ""
#: src/Admin/SettingsController.php:322
msgid "Verifying..."
msgstr ""
#: src/Admin/SettingsController.php:341
msgid "Request failed."
msgstr ""
#: src/Admin/SettingsController.php:458
msgid "Insufficient permissions."
msgstr ""
#: src/Admin/SettingsController.php:467
msgid "License verified successfully!"
msgstr ""
#: src/Admin/SettingsController.php:469
msgid "License validation failed."
msgstr ""
#: src/Admin/VersionAdminController.php:58 #: src/Admin/VersionAdminController.php:58
msgid "Product Versions" msgid "Product Versions"
msgstr "" msgstr ""

View File

@@ -2,8 +2,8 @@
"openapi": "3.1.0", "openapi": "3.1.0",
"info": { "info": {
"title": "WooCommerce Licensed Product API", "title": "WooCommerce Licensed Product API",
"description": "REST API for validating and managing software licenses bound to domains. This API allows external applications to validate license keys, check license status, and activate licenses on specific domains.", "description": "REST API for validating and managing software licenses bound to domains. This API allows external applications to validate license keys, check license status, and activate licenses on specific domains.\n\n## Response Signing (Optional)\n\nWhen the server is configured with `WC_LICENSE_SERVER_SECRET`, all API responses include cryptographic signatures for tamper protection:\n\n- `X-License-Signature`: HMAC-SHA256 signature of the response\n- `X-License-Timestamp`: Unix timestamp when the response was generated\n\nSignature verification prevents man-in-the-middle attacks and ensures response integrity. Use the `magdev/wc-licensed-product-client` library's `SecureLicenseClient` class to automatically verify signatures.",
"version": "0.0.7", "version": "0.3.2",
"contact": { "contact": {
"name": "Marco Graetsch", "name": "Marco Graetsch",
"url": "https://src.bundespruefstelle.ch/magdev", "url": "https://src.bundespruefstelle.ch/magdev",
@@ -55,6 +55,14 @@
"responses": { "responses": {
"200": { "200": {
"description": "License is valid for the specified domain", "description": "License is valid for the specified domain",
"headers": {
"X-License-Signature": {
"$ref": "#/components/headers/X-License-Signature"
},
"X-License-Timestamp": {
"$ref": "#/components/headers/X-License-Timestamp"
}
},
"content": { "content": {
"application/json": { "application/json": {
"schema": { "schema": {
@@ -156,6 +164,14 @@
"responses": { "responses": {
"200": { "200": {
"description": "License status retrieved successfully", "description": "License status retrieved successfully",
"headers": {
"X-License-Signature": {
"$ref": "#/components/headers/X-License-Signature"
},
"X-License-Timestamp": {
"$ref": "#/components/headers/X-License-Timestamp"
}
},
"content": { "content": {
"application/json": { "application/json": {
"schema": { "schema": {
@@ -221,6 +237,14 @@
"responses": { "responses": {
"200": { "200": {
"description": "License activated successfully or already activated", "description": "License activated successfully or already activated",
"headers": {
"X-License-Signature": {
"$ref": "#/components/headers/X-License-Signature"
},
"X-License-Timestamp": {
"$ref": "#/components/headers/X-License-Timestamp"
}
},
"content": { "content": {
"application/json": { "application/json": {
"schema": { "schema": {
@@ -519,6 +543,26 @@
} }
} }
} }
},
"headers": {
"X-License-Signature": {
"description": "HMAC-SHA256 signature of the response body for tamper protection. Only present when server is configured with WC_LICENSE_SERVER_SECRET. Signature format: hex-encoded HMAC-SHA256 of (timestamp + ':' + canonical_json_body) using a per-license derived key.",
"schema": {
"type": "string",
"pattern": "^[a-f0-9]{64}$",
"example": "a1b2c3d4e5f6789012345678901234567890abcdef1234567890abcdef123456"
},
"required": false
},
"X-License-Timestamp": {
"description": "Unix timestamp when the response was generated. Used together with X-License-Signature to prevent replay attacks. Only present when server is configured with WC_LICENSE_SERVER_SECRET.",
"schema": {
"type": "string",
"pattern": "^[0-9]+$",
"example": "1737550000"
},
"required": false
}
} }
}, },
"tags": [ "tags": [

View File

@@ -3,7 +3,7 @@
* Plugin Name: WooCommerce Licensed Product * Plugin Name: WooCommerce Licensed Product
* Plugin URI: https://src.bundespruefstelle.ch/magdev/wc-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. * Description: WooCommerce plugin to sell software products using license keys with domain-based validation.
* Version: 0.3.1 * Version: 0.3.2
* Author: Marco Graetsch * Author: Marco Graetsch
* Author URI: https://src.bundespruefstelle.ch/magdev * Author URI: https://src.bundespruefstelle.ch/magdev
* License: GPL-2.0-or-later * License: GPL-2.0-or-later
@@ -28,7 +28,7 @@ if (!defined('ABSPATH')) {
} }
// Plugin constants // Plugin constants
define('WC_LICENSED_PRODUCT_VERSION', '0.3.1'); define('WC_LICENSED_PRODUCT_VERSION', '0.3.2');
define('WC_LICENSED_PRODUCT_PLUGIN_FILE', __FILE__); define('WC_LICENSED_PRODUCT_PLUGIN_FILE', __FILE__);
define('WC_LICENSED_PRODUCT_PLUGIN_DIR', plugin_dir_path(__FILE__)); define('WC_LICENSED_PRODUCT_PLUGIN_DIR', plugin_dir_path(__FILE__));
define('WC_LICENSED_PRODUCT_PLUGIN_URL', plugin_dir_url(__FILE__)); define('WC_LICENSED_PRODUCT_PLUGIN_URL', plugin_dir_url(__FILE__));