You've already forked wc-licensed-product-client
240 lines
10 KiB
Markdown
240 lines
10 KiB
Markdown
# License-Client for WooCommerce Licensed Product Plugin
|
|
|
|
**Author:** Marco Graetsch
|
|
**Author URL:** <https://src.bundespruefstelle.ch/magdev>
|
|
**Author Email:** <magdev3.0@gmail.com>
|
|
**Repository URL:** <https://src.bundespruefstelle.ch/magdev/wc-licensed-product-client>
|
|
**Issues URL:** <https://src.bundespruefstelle.ch/magdev/wc-licensed-product-client/issues>
|
|
**Package-Name:** `magdev/wc-licensed-product-client`
|
|
|
|
## Project Overview
|
|
|
|
This composer package implements a Client for the WooCommerce Licensed Product Plugin. It uses the REST API as described in `tmp/openapi.json` to activate, validate and check the status of licenses.
|
|
|
|
## Features
|
|
|
|
- Easy integration in licensed software packages
|
|
- Defines a PHP constant if a licensed is valid or not
|
|
- Obfuscate the security critical code parts using plain PHP tools as best as possible
|
|
|
|
### Key Fact: 100% AI-Generated
|
|
|
|
This project is proudly **"vibe-coded"** using Claude.AI - the entire codebase was created through AI assistance.
|
|
|
|
## Temporary Roadmap
|
|
|
|
**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.
|
|
|
|
### Known Bugs
|
|
|
|
No known bugs at the moment
|
|
|
|
### Version 0.2.1
|
|
|
|
No pending tasks at the moment.
|
|
|
|
### Version 0.3.0
|
|
|
|
No pending tasks at the moment.
|
|
|
|
## Technical Stack
|
|
|
|
- **Language:** PHP 8.3.x
|
|
- **PHP-Standards:** PSR-3, PSR-4, PSR-6, PSR-18
|
|
- **Coding-Style:** Symfony
|
|
- **HTTP-Client-Library:** symfony/http-client
|
|
- **Dependency Management:** Composer
|
|
- **OpenAPI Description:** `tmp/openapi.json`
|
|
|
|
---
|
|
|
|
**For AI Assistants:**
|
|
|
|
When starting a new session on this project:
|
|
|
|
1. Read this CLAUDE.md file first
|
|
2. Semantic versioning follows the `MAJOR.MINOR.BUGFIX` pattern
|
|
3. Check git log for recent changes
|
|
4. Verify you're on the `dev` branch before making changes
|
|
5. Run `composer install` if vendor/ is missing
|
|
6. Test changes before committing
|
|
7. Follow commit message format with Claude Code attribution
|
|
8. Update this session history section with learnings
|
|
9. Always update the `README.md` on related changes
|
|
10. Keep changes in a single `CHANGELOG.md`
|
|
11. Follow markdown linting rules (see below)
|
|
|
|
Always refer to this document when starting work on this project.
|
|
|
|
### Markdown Linting Rules
|
|
|
|
When editing CLAUDE.md or other markdown files, follow these rules to avoid linting errors:
|
|
|
|
1. **MD031 - Blank lines around fenced code blocks**: Always add a blank line before and after fenced code blocks, even when they follow list items. Example of correct format:
|
|
|
|
- **Item label**:
|
|
|
|
(blank line here)
|
|
\`\`\`php
|
|
code example
|
|
\`\`\`
|
|
(blank line here)
|
|
|
|
2. **MD056 - Table column count**: Table separators must have matching column counts and proper spacing. Use consistent dash lengths that match column header widths.
|
|
|
|
3. **MD009 - No trailing spaces**: Remove trailing whitespace from lines
|
|
|
|
4. **MD012 - No multiple consecutive blank lines**: Use only single blank lines between sections
|
|
|
|
5. **MD040 - Fenced code blocks should have a language specified**: Always add a language identifier to code blocks (e.g., `txt`, `bash`, `php`). For shortcode examples, use `txt`.
|
|
|
|
6. **MD032 - Lists should be surrounded by blank lines**: Add a blank line before AND after list blocks, including after bold labels like `**Attributes:**`.
|
|
|
|
7. **MD034 - Bare URLs**: Wrap URLs in angle brackets (e.g., `<https://example.com>`) or use markdown link syntax `[text](url)`.
|
|
|
|
8. **Author section formatting**: Use a heading (`### Name`) instead of bold (`**Name**`) for the author name to maintain consistent document structure.
|
|
|
|
---
|
|
|
|
## Session History
|
|
|
|
### 2026-01-22 - Version 0.0.1
|
|
|
|
**Completed:**
|
|
|
|
- Initialized composer project of type `library`
|
|
- Configured package metadata (name, description, license, author)
|
|
- Set up PSR-4 autoloading for `Magdev\WcLicensedProductClient` namespace
|
|
- Added symfony/http-client ^7.0 as HTTP client dependency
|
|
- Created project structure (src/, tests/)
|
|
- Added README.md, CHANGELOG.md, and .gitignore
|
|
- Initialized git repository on `dev` branch
|
|
- Pushed initial commit to origin
|
|
|
|
**Learnings:**
|
|
|
|
- OpenAPI spec (tmp/openapi.json) defines 3 POST endpoints: `/validate`, `/status`, `/activate`
|
|
- API base path: `{baseUrl}/wp-json/wc-licensed-product/v1`
|
|
- Git remote configured via SSH: `ssh://git@src.bundespruefstelle.ch:2022/magdev/wc-licensed-product-client.git`
|
|
|
|
### 2026-01-22 - Version 0.1.0
|
|
|
|
**Completed:**
|
|
|
|
- Created `LicenseClientInterface` as public API contract
|
|
- Implemented `LicenseClient` with PSR-3 logging and PSR-6 caching support
|
|
- Added DTO classes: `LicenseInfo`, `LicenseStatus`, `ActivationResult`
|
|
- Added `LicenseState` enum for license status values (active, inactive, expired, revoked)
|
|
- Created comprehensive exception hierarchy (10 exception classes)
|
|
- Added PSR dependencies: `psr/log` ^3.0, `psr/cache` ^3.0, `psr/http-client` ^1.0
|
|
- Updated README with usage examples for basic usage, logging, caching, and exception handling
|
|
- Merged dev to main branch
|
|
|
|
**Learnings:**
|
|
|
|
- Architecture follows separation: Interface (public API) → Client (implementation) → DTOs (data) → Exceptions (errors)
|
|
- Cache keys use SHA256 hashes of license keys to avoid exposing sensitive data
|
|
- `LicenseClient` designed for obfuscation: all sensitive logic contained in single class
|
|
- Symfony HttpClient works well with PSR interfaces via `symfony/http-client-contracts`
|
|
- Keep a Changelog format allows duplicate headings per version (MD024 warning can be ignored)
|
|
|
|
### 2026-01-22 - Version 0.1.0 (Security Layer)
|
|
|
|
**Completed:**
|
|
|
|
- Added PHPUnit ^11.0 test framework with 66 tests total
|
|
- Implemented `SecureLicenseClient` with response signature verification
|
|
- Created `ResponseSignature` class for HMAC-SHA256 signing/verification
|
|
- Created `StringEncoder` for XOR-based string obfuscation
|
|
- Created `IntegrityChecker` for source file hash verification
|
|
- Added `SignatureException` and `IntegrityException` for security errors
|
|
- Documented server-side implementation in `docs/server-implementation.md`
|
|
- Merged all changes to main branch
|
|
|
|
**Learnings:**
|
|
|
|
- Response signature verification (HMAC) is more secure than code obfuscation alone
|
|
- Per-license key derivation prevents cross-license signature reuse
|
|
- Timestamp validation (5-minute tolerance) prevents replay attacks
|
|
- Server must sign responses with matching algorithm for client verification
|
|
- IntegrityChecker normalizes line endings for cross-platform hash consistency
|
|
- StringEncoder uses XOR with expanded key for simple obfuscation (not encryption)
|
|
- PHPUnit 11 uses PHP 8 attributes (`#[Test]`, `#[CoversClass]`) instead of annotations
|
|
- OpenAPI spec (tmp/openapi.json) updated to v0.3.2 with signature header definitions
|
|
|
|
### 2026-01-23 - Client Documentation
|
|
|
|
**Completed:**
|
|
|
|
- Created comprehensive `docs/client-implementation.md` documentation
|
|
- Documented all classes: LicenseClient, SecureLicenseClient, DTOs, Exceptions, Security classes
|
|
- Added integration guides for: Basic PHP, WordPress plugins, Laravel, Symfony
|
|
- Documented constructor parameters, method signatures, and return types
|
|
- Added complete exception hierarchy reference with error codes
|
|
- Included best practices section for production use
|
|
- Added API reference with endpoints and request/response formats
|
|
- Added troubleshooting section for common issues
|
|
- Updated README.md with documentation links section
|
|
|
|
**Learnings:**
|
|
|
|
- Client documentation complements server documentation for complete integration guide
|
|
- Integration examples for major PHP frameworks help adoption
|
|
- Error code mapping to exception classes aids programmatic error handling
|
|
|
|
### 2026-01-24 - Security Audit and Fixes
|
|
|
|
**Completed:**
|
|
|
|
- Performed comprehensive security audit of entire codebase
|
|
- Fixed JSON encoding error handling in `ResponseSignature::buildSignaturePayload()`
|
|
- Sanitized exception messages in both client classes to prevent information disclosure
|
|
- Fixed header normalization to treat empty values as null in `SecureLicenseClient`
|
|
- Added SSRF protection with URL validation and private IP range blocking
|
|
- Replaced custom key derivation with RFC 5869 compliant `hash_hkdf()`
|
|
- Added input validation in all DTO `fromArray()` methods
|
|
- Added DateTime exception handling in DTOs to prevent uncaught exceptions
|
|
- Added new `allowInsecureHttp` constructor parameter for development environments
|
|
|
|
**Learnings:**
|
|
|
|
- Security audit identified 7 fixable issues across critical, high, and medium priority
|
|
- `hash_hkdf()` is PHP's native RFC 5869 implementation - prefer it over custom HKDF
|
|
- SSRF protection requires: URL scheme validation, private IP blocking, DNS resolution checks
|
|
- Exception messages should never expose internal details to end users
|
|
- DTO validation should check both existence (`isset`) and type (`is_int`, `is_bool`, etc.)
|
|
- Empty header values should be treated as missing (null) not empty strings
|
|
- Constructor parameters added: `allowInsecureHttp` for HTTP on non-localhost in dev mode
|
|
- Private IP ranges to block: 10.0.0.0/8, 172.16.0.0/12, 192.168.0.0/16, 127.0.0.0/8, 169.254.0.0/16, 0.0.0.0/8
|
|
|
|
### 2026-01-26 - Server Implementation Alignment
|
|
|
|
**Completed:**
|
|
|
|
- Verified client implementation against server documentation
|
|
- Updated server docs to use RFC 5869 `hash_hkdf()` for key derivation (matching client)
|
|
- Added recursive key sorting (`sortKeysRecursive()`) to client `ResponseSignature`
|
|
- Client and server now use identical signature algorithms
|
|
|
|
**Learnings:**
|
|
|
|
- Server and client must use identical key derivation and JSON canonicalization
|
|
- Recursive key sorting is essential for nested objects like the `license` object in validate responses
|
|
- When updating cryptographic implementations, both client and server documentation must be aligned
|
|
- The remote server documentation URL was 404 - local `docs/server-implementation.md` is the source of truth
|
|
|
|
### 2026-01-26 - Version 0.2.0 Release
|
|
|
|
**Completed:**
|
|
|
|
- Released version 0.2.0 with security improvements and server alignment
|
|
- Created annotated git tag `v0.2.0`
|
|
- Updated CHANGELOG.md with all changes since 0.1.0
|
|
- Updated roadmap for versions 0.2.1 and 0.3.0
|
|
|
|
**Learnings:**
|
|
|
|
- Version tagging with `git tag -a` creates annotated tags with messages
|
|
- CHANGELOG.md follows Keep a Changelog format (MD024 duplicate headings are expected)
|
|
- Roadmap in CLAUDE.md should be updated after each release to reflect next versions
|