Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 5 additions & 2 deletions .github/workflows/run-tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -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 }}

Expand Down
3 changes: 1 addition & 2 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@
build
composer.lock
coverage
docs
phpunit.xml
phpstan.neon
testbench.yaml
Expand All @@ -15,4 +14,4 @@ sign.sh
test.sig
test
hash-key
gen_key.sh
gen_key.sh
20 changes: 10 additions & 10 deletions composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -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": {
Expand Down Expand Up @@ -47,7 +47,7 @@
},
"config": {
"platform": {
"php": "8.2"
"php": "8.3"
},
"sort-packages": true,
"allow-plugins": {
Expand Down
160 changes: 160 additions & 0 deletions docs/README.md
Original file line number Diff line number Diff line change
@@ -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.
Loading