diff --git a/.github/workflows/run-tests.yml b/.github/workflows/run-tests.yml index c40e569..5840acb 100644 --- a/.github/workflows/run-tests.yml +++ b/.github/workflows/run-tests.yml @@ -17,13 +17,16 @@ jobs: fail-fast: true matrix: os: [ubuntu-latest, windows-latest] - php: [8.3, 8.2] - laravel: [11.*] + php: [8.3, 8.4] + laravel: [11.*, 12.*] stability: [prefer-lowest, prefer-stable] include: - laravel: 11.* testbench: 9.* carbon: ^2.63 + - laravel: 12.* + testbench: 10.* + carbon: ^3.0 name: P${{ matrix.php }} - L${{ matrix.laravel }} - ${{ matrix.stability }} - ${{ matrix.os }} diff --git a/.gitignore b/.gitignore index fee0ddd..3559403 100644 --- a/.gitignore +++ b/.gitignore @@ -3,7 +3,6 @@ build composer.lock coverage -docs phpunit.xml phpstan.neon testbench.yaml @@ -15,4 +14,4 @@ sign.sh test.sig test hash-key -gen_key.sh \ No newline at end of file +gen_key.sh diff --git a/composer.json b/composer.json index d0a5cce..0f9bcee 100644 --- a/composer.json +++ b/composer.json @@ -4,18 +4,18 @@ "homepage": "https://github.com/LycheeOrg/verify", "license": "MIT", "require": { - "php": "^8.2", - "illuminate/contracts": "^11.0", - "thecodingmachine/safe": "^2.5" + "php": "^8.3", + "illuminate/contracts": "^12.0||^11.0", + "thecodingmachine/safe": "^3.3" }, "require-dev": { - "nunomaduro/collision": "^8.3", - "larastan/larastan": "^2.9", - "orchestra/testbench": "^9.0.0||^8.22.0", + "nunomaduro/collision": "^8.8", + "larastan/larastan": "^3.6", + "orchestra/testbench": "^10.0.0||^9.0.0||^8.22.0", "friendsofphp/php-cs-fixer": "^3.3", - "lychee-org/phpstan-lychee": "^v1.0.1", - "php-parallel-lint/php-parallel-lint": "^1.3", - "phpunit/phpunit": "^10.0" + "lychee-org/phpstan-lychee": "^v2.0.2", + "php-parallel-lint/php-parallel-lint": "^1.4", + "phpunit/phpunit": "^10.0||^11.0" }, "autoload": { "psr-4": { @@ -47,7 +47,7 @@ }, "config": { "platform": { - "php": "8.2" + "php": "8.3" }, "sort-packages": true, "allow-plugins": { diff --git a/docs/README.md b/docs/README.md new file mode 100644 index 0000000..b1509ae --- /dev/null +++ b/docs/README.md @@ -0,0 +1,160 @@ +# Verify - Architecture Documentation + +Verify is the License management system used by Lychee to validate license keys. It provides a flexible architecture for validating licenses through either hash-based validation or cryptographic signature validation. + +## Core Architecture + +### Overall Structure + +``` +src/ +├── Contract/ # Core interfaces and enums +│ ├── Status.php # License status types +│ ├── ValidatorInterface.php # Validator contract +│ └── VerifyInterface.php # Core verification contract +├── Exceptions/ # Custom exceptions +│ ├── BaseVerifyException.php +│ └── SupporterOnlyOperationException.php +├── Facades/ # Laravel facades +│ └── VerifyFacade.php +├── Http/ # HTTP components +│ └── Middleware/ # Middleware for route protection +├── Validators/ # License validation implementations +│ ├── ValidateHash.php # Hash-based validation +│ └── ValidateSignature.php # Cryptographic signature validation +├── Verify.php # Main verification class +└── VerifyServiceProvider.php # Laravel service provider +``` + +### Component Description + +#### 1. Status System + +The license status is represented by the `Status` enum, which defines three levels: + +- `FREE_EDITION` - Basic features, no license required +- `SUPPORTER_EDITION` - Standard supporter features +- `PLUS_EDITION` - Premium features with extended capabilities + +#### 2. Validation Mechanism + +The plugin implements a strategy pattern for license validation through the `ValidatorInterface`: + +```php +interface ValidatorInterface +{ + public function validate(string $verifiable, string $license): bool; + public function grant(): Status; +} +``` + +Two concrete validators are provided: + +1. **ValidateHash** - Uses password hashing to validate a static license key + - Returns `SUPPORTER_EDITION` status when valid + - Simple validation mechanism for standard supporters + +2. **ValidateSignature** - Uses cryptographic signatures for validation + - Returns `PLUS_EDITION` status when valid + - More secure mechanism for premium users + - Uses asymmetric cryptography (ECDSA) for verification + +#### 3. Core Verify Class + +The `Verify` class serves as the central hub and implements `VerifyInterface`. It: + +- Coordinates between different validators +- Provides convenience methods for checking license status +- Handles authorization logic +- Provides conditional execution based on license status + +#### 4. Service Provider & Integration + +The `VerifyServiceProvider` handles Laravel integration by: +- Registering the Verify service in the Laravel container +- Merging configuration files +- Making the service available through the facade + +#### 5. Facade + +The `VerifyFacade` provides a static interface to access the Verify functionality, following the Laravel facade pattern. + +## Usage Examples + +### Basic Verification + +```php +// Check if the user is a supporter +if ($verify->is_supporter()) { + // Provide supporter features +} + +// Check if the user has premium status +if ($verify->is_plus()) { + // Provide premium features +} +``` + +### Authorization + +```php +// Will throw SupporterOnlyOperationException if not a supporter +$verify->authorize(); + +// Will throw exception if not a plus user +$verify->authorize(Status::PLUS_EDITION); +``` + +### Conditional Execution + +```php +$result = $verify->when( + fn() => 'Supporter feature enabled!', + fn() => 'Please upgrade to supporter edition.', + Status::SUPPORTER_EDITION +); +``` + +## Configuration + +Configuration is stored in `config/verify.php`, which includes: + +- Validation configuration for integrity checks +- Public keys and hash settings (in the actual implementation) + +## Database Integration + +The plugin uses the database to store: +- License keys +- User emails associated with licenses + +These are stored in the `configs` table with dedicated migration files. + +## Security Considerations + +The plugin implements multiple layers of security: +1. Hash-based validation for supporter licenses +2. Cryptographic signature validation for premium licenses +3. Server-side validation to prevent client-side tampering +4. Integrity checking of core verification files + +## Extension Points + +The architecture allows extending the system by: +1. Creating new validators implementing `ValidatorInterface` +2. Adding additional status levels to the `Status` enum +3. Creating custom middleware for specific route protection + +## Integrity Validation + +The system includes a self-validation mechanism that verifies the integrity of core verification files to detect tampering: + +```php +if ($verify->validate()) { + // System is intact +} else { + // Core files have been tampered with +} +``` + +This system compares file checksums against expected values to ensure the verification system itself hasn't been compromised.