# 🔐 Laravel License Server API

```
╔══════════════════════════════════════════════════════════════╗
║                                                              ║
║   ██╗     ██╗ ██████╗███████╗███╗   ██╗███████╗███████╗     ║
║   ██║     ██║██╔════╝██╔════╝████╗  ██║██╔════╝██╔════╝     ║
║   ██║     ██║██║     █████╗  ██╔██╗ ██║███████╗█████╗       ║
║   ██║     ██║██║     ██╔══╝  ██║╚██╗██║╚════██║██╔══╝       ║
║   ███████╗██║╚██████╗███████╗██║ ╚████║███████║███████╗     ║
║   ╚══════╝╚═╝ ╚═════╝╚══════╝╚═╝  ╚═══╝╚══════╝╚══════╝     ║
║                                                              ║
║        🚀 Complete License Management System 🚀              ║
║                                                              ║
╚══════════════════════════════════════════════════════════════╝
```

## 🎯 **SISTEM SUDAH 100% BERFUNGSI!**

✅ **Admin Dashboard** - Full-featured management panel  
✅ **API Endpoints** - Ready for client integration  
✅ **Client Examples** - Copy-paste implementation  
✅ **Documentation** - Complete guides  
✅ **Real Data** - No dummy data  

---

## 📚 **QUICK LINKS**

| Document | Description |
|----------|-------------|
| [**QUICK_START.md**](QUICK_START.md) | ⚡ Start here! Quick setup guide |
| [**FINAL_SUMMARY.md**](FINAL_SUMMARY.md) | 📊 Complete system overview |
| [**API_DOCUMENTATION.md**](API_DOCUMENTATION.md) | 📖 API reference |
| [**FEATURES_DOCUMENTATION.md**](FEATURES_DOCUMENTATION.md) | 🎯 Features guide |
| [**CLIENT_INTEGRATION_GUIDE.md**](CLIENT_INTEGRATION_GUIDE.md) | 🔧 Client integration |
| [**client-example/**](client-example/) | 💻 Ready-to-use client files |

---

## 🌟 **NEW FEATURES (v2.0)**

### **Admin Panel:**
- 📊 **Dashboard** - Real-time statistics, charts, recent licenses
- 🔑 **Licenses Management** - CRUD operations, search, filter, export CSV
- 👥 **Customers** - Customer list, license history
- 📈 **Analytics** - 12-month trend, top customers, revenue reports
- ⚙️ **Settings** - System configuration, API status

### **Client Integration:**
- ✅ Ready-to-use PHP helper class
- ✅ Beautiful activation page
- ✅ Protected area implementation
- ✅ API testing tool
- ✅ Security configuration

---

A complete Laravel-based license server system for managing and validating software licenses. This API allows you to verify, activate, and manage software licenses for your applications.

## 📋 Features

- ✅ License key validation
- ✅ Domain-based license activation
- ✅ License expiration management
- ✅ License status control (active, inactive, suspended)
- ✅ IP address tracking
- ✅ Rate limiting (60 requests/minute per IP)
- ✅ RESTful API endpoints
- ✅ Request validation
- ✅ Comprehensive error handling

## 🛠 Requirements

- PHP >= 8.2
- Composer
- MySQL/MariaDB or PostgreSQL
- Laravel 12

## 📦 Installation

### 1. Install Dependencies

```bash
composer install
```

### 2. Environment Setup

Copy `.env.example` to `.env`:

```bash
cp .env.example .env
```

Configure your database in `.env`:

```env
DB_CONNECTION=mysql
DB_HOST=127.0.0.1
DB_PORT=3306
DB_DATABASE=license_server
DB_USERNAME=root
DB_PASSWORD=yourpassword
```

Generate application key:

```bash
php artisan key:generate
```

### 3. Database Setup

Create the database:

```sql
CREATE DATABASE license_server;
```

Run migrations:

```bash
php artisan migrate
```

### 4. Start the Server

```bash
php artisan serve
```

Your API will be available at: `http://localhost:8000`

## 🚀 API Endpoints

### Base URL

```
http://your-domain.com/api
```

### 1. Verify License

**Endpoint:** `GET /api/verify`

**Description:** Verify if a license key is valid for a specific domain.

**Parameters:**
- `key` (required) - License key string
- `domain` (required) - Domain name to verify

**Example Request:**

```bash
curl -X GET "http://localhost:8000/api/verify?key=XXXX-YYYY-ZZZZ&domain=example.com"
```

**Response Examples:**

✅ Valid License:
```json
{
  "status": "valid",
  "msg": "License is valid",
  "data": {
    "license_key": "XXXX-YYYY-ZZZZ",
    "domain": "example.com",
    "status": "active",
    "expired_at": "2025-12-31"
  }
}
```

❌ Invalid License:
```json
{
  "status": "invalid",
  "msg": "license key not found"
}
```

❌ Domain Mismatch:
```json
{
  "status": "invalid",
  "msg": "domain mismatch"
}
```

❌ Expired:
```json
{
  "status": "expired",
  "msg": "License has expired"
}
```

❌ Suspended:
```json
{
  "status": "suspended",
  "msg": "License is suspended"
}
```

### 2. Activate License

**Endpoint:** `POST /api/activate`

**Description:** Activate a license key for a specific domain (first-time activation only).

**Parameters:**
- `key` (required) - License key string
- `domain` (required) - Domain name to activate

**Example Request:**

```bash
curl -X POST "http://localhost:8000/api/activate" \
  -H "Content-Type: application/json" \
  -d '{
    "key": "XXXX-YYYY-ZZZZ",
    "domain": "example.com"
  }'
```

**Response Examples:**

✅ Activated:
```json
{
  "status": "activated",
  "msg": "License activated successfully",
  "data": {
    "license_key": "XXXX-YYYY-ZZZZ",
    "domain": "example.com",
    "status": "active",
    "activated_at": "2025-11-23 12:00:00"
  }
}
```

❌ Already Assigned:
```json
{
  "status": "already_assigned",
  "msg": "License already assigned to: example.com"
}
```

❌ Invalid License:
```json
{
  "status": "invalid",
  "msg": "License key not found"
}
```

## 💾 Database Schema

### licenses Table

| Column | Type | Description |
|--------|------|-------------|
| id | bigint | Primary key |
| license_key | string | Unique license key |
| domain | string (nullable) | Assigned domain |
| ip_address | string (nullable) | Client IP address |
| status | enum | License status: active, inactive, suspended |
| expired_at | date (nullable) | Expiration date |
| created_at | timestamp | Creation timestamp |
| updated_at | timestamp | Last update timestamp |

## 🎯 Usage Examples

### Client-Side Integration (PHP Example)

```php
<?php

class LicenseValidator
{
    private $serverUrl = 'https://your-license-server.com/api';
    private $licenseKey;
    private $domain;

    public function __construct($licenseKey, $domain)
    {
        $this->licenseKey = $licenseKey;
        $this->domain = $domain;
    }

    public function verify()
    {
        $url = $this->serverUrl . '/verify?' . http_build_query([
            'key' => $this->licenseKey,
            'domain' => $this->domain
        ]);

        $response = file_get_contents($url);
        $data = json_decode($response, true);

        return $data['status'] === 'valid';
    }

    public function activate()
    {
        $url = $this->serverUrl . '/activate';
        
        $options = [
            'http' => [
                'header'  => "Content-type: application/json\r\n",
                'method'  => 'POST',
                'content' => json_encode([
                    'key' => $this->licenseKey,
                    'domain' => $this->domain
                ])
            ]
        ];

        $context  = stream_context_create($options);
        $response = file_get_contents($url, false, $context);
        $data = json_decode($response, true);

        return $data['status'] === 'activated';
    }
}

// Usage
$license = new LicenseValidator('XXXX-YYYY-ZZZZ', 'example.com');

if (!$license->verify()) {
    die('Invalid or expired license!');
}

echo 'License is valid!';
```

### JavaScript/Node.js Example

```javascript
const axios = require('axios');

class LicenseValidator {
    constructor(licenseKey, domain) {
        this.serverUrl = 'https://your-license-server.com/api';
        this.licenseKey = licenseKey;
        this.domain = domain;
    }

    async verify() {
        try {
            const response = await axios.get(`${this.serverUrl}/verify`, {
                params: {
                    key: this.licenseKey,
                    domain: this.domain
                }
            });
            return response.data.status === 'valid';
        } catch (error) {
            console.error('License verification failed:', error);
            return false;
        }
    }

    async activate() {
        try {
            const response = await axios.post(`${this.serverUrl}/activate`, {
                key: this.licenseKey,
                domain: this.domain
            });
            return response.data.status === 'activated';
        } catch (error) {
            console.error('License activation failed:', error);
            return false;
        }
    }
}

// Usage
const license = new LicenseValidator('XXXX-YYYY-ZZZZ', 'example.com');

license.verify().then(isValid => {
    if (isValid) {
        console.log('License is valid!');
    } else {
        console.log('Invalid or expired license!');
    }
});
```

## 🔐 Security Features

### 1. Rate Limiting

The API implements rate limiting to prevent abuse:
- **Limit:** 60 requests per minute per IP address
- **Middleware:** Applied to all API routes
- **Response:** HTTP 429 (Too Many Requests) when limit exceeded

### 2. Request Validation

All endpoints validate input parameters:
- Required fields checking
- Data type validation
- SQL injection prevention via Eloquent ORM

### 3. CORS (Optional)

To enable CORS for your API, add to `config/cors.php`:

```php
'paths' => ['api/*'],
'allowed_methods' => ['*'],
'allowed_origins' => ['https://your-client-domain.com'],
```

### 4. Additional Security Recommendations

#### A. HMAC Signature Verification

Add signature-based authentication:

```php
// In controller
$signature = hash_hmac('sha256', $domain . $key, config('app.license_secret'));
if ($request->signature !== $signature) {
    return response()->json(['status' => 'invalid_signature'], 401);
}
```

#### B. IP Lock

Enable IP address validation:

```php
if ($license->ip_address && $license->ip_address !== $ip) {
    return response()->json(['status' => 'invalid_ip'], 403);
}
```

#### C. HTTPS Only

In production, always use HTTPS. Add to `.env`:

```env
APP_URL=https://your-license-server.com
```

## 🗄 Managing Licenses

### Creating Licenses Manually

You can create licenses using Laravel Tinker:

```bash
php artisan tinker
```

```php
use App\Models\License;

License::create([
    'license_key' => 'XXXX-YYYY-ZZZZ-AAAA',
    'status' => 'inactive',
    'expired_at' => now()->addYear()
]);
```

### Using Database Seeder

Create a seeder:

```bash
php artisan make:seeder LicenseSeeder
```

Edit `database/seeders/LicenseSeeder.php`:

```php
use App\Models\License;
use Illuminate\Support\Str;

public function run()
{
    for ($i = 0; $i < 10; $i++) {
        License::create([
            'license_key' => strtoupper(Str::random(4) . '-' . Str::random(4) . '-' . Str::random(4)),
            'status' => 'inactive',
            'expired_at' => now()->addYear()
        ]);
    }
}
```

Run the seeder:

```bash
php artisan db:seed --class=LicenseSeeder
```

## 🎨 Admin Panel (Optional)

You can add an admin panel using Laravel Filament:

```bash
composer require filament/filament:"^3.0"
php artisan filament:install --panels
php artisan make:filament-user
php artisan make:filament-resource License --generate
```

Access admin panel at: `http://your-domain.com/admin`

## 🧪 Testing

### Manual Testing with cURL

**Test Verify Endpoint:**

```bash
curl -X GET "http://localhost:8000/api/verify?key=TEST-KEY-1234&domain=example.com"
```

**Test Activate Endpoint:**

```bash
curl -X POST "http://localhost:8000/api/activate" \
  -H "Content-Type: application/json" \
  -d '{"key":"TEST-KEY-1234","domain":"example.com"}'
```

### Using Postman

1. Import the API endpoints into Postman
2. Set base URL: `http://localhost:8000/api`
3. Test GET `/verify` with query parameters
4. Test POST `/activate` with JSON body

## 📝 License Status Values

| Status | Description |
|--------|-------------|
| active | License is active and usable |
| inactive | License exists but not yet activated |
| suspended | License has been suspended by admin |

## 🔄 Workflow

1. **Create License:** Admin creates a license key in the database with status `inactive`
2. **Distribute:** License key is sent to customer
3. **Activate:** Customer activates license on their domain via `/activate` endpoint
4. **Verify:** Customer's application regularly checks license validity via `/verify` endpoint

## 🐛 Troubleshooting

### Issue: "could not find driver"

**Solution:** Enable PDO extension in `php.ini`:

```ini
extension=pdo_mysql
```

### Issue: 404 Not Found on API routes

**Solution:** Clear route cache:

```bash
php artisan route:clear
php artisan optimize:clear
```

### Issue: Rate limit too restrictive

**Solution:** Adjust in `app/Providers/AppServiceProvider.php`:

```php
RateLimiter::for('api', function (Request $request) {
    return Limit::perMinute(120)->by($request->ip()); // Changed to 120
});
```

## 📚 Additional Resources

- [Laravel Documentation](https://laravel.com/docs)
- [Laravel API Resources](https://laravel.com/docs/eloquent-resources)
- [Laravel Rate Limiting](https://laravel.com/docs/routing#rate-limiting)

## 🤝 Contributing

Feel free to submit issues and enhancement requests!

## 📄 License

This project is open-sourced software licensed under the [MIT license](https://opensource.org/licenses/MIT).

## 👨‍💻 Author

Created for license management and software protection.

---

**Note:** Remember to change default configurations and add additional security measures before deploying to production!
