feat: Implement OAuth license activation flow
- Add LicenseConnect.tsx focused OAuth confirmation page in customer SPA - Add /licenses/oauth/validate and /licenses/oauth/confirm API endpoints - Update App.tsx to render license-connect outside BaseLayout (no header/footer) - Add license_activation_method field to product settings in Admin SPA - Create LICENSING_MODULE.md with comprehensive OAuth flow documentation - Update API_ROUTES.md with license module endpoints
This commit is contained in:
284
LICENSING_MODULE.md
Normal file
284
LICENSING_MODULE.md
Normal file
@@ -0,0 +1,284 @@
|
||||
# Licensing Module Documentation
|
||||
|
||||
## Overview
|
||||
|
||||
WooNooW's Licensing Module provides software license management for digital products. It supports two activation methods:
|
||||
|
||||
1. **Simple API** - Direct license key validation via API
|
||||
2. **Secure OAuth** - User verification via vendor portal before activation
|
||||
|
||||
---
|
||||
|
||||
## API Endpoints
|
||||
|
||||
### Admin Endpoints (Authenticated Admin)
|
||||
|
||||
```
|
||||
GET /licenses # List all licenses (with pagination, search)
|
||||
GET /licenses/{id} # Get single license
|
||||
POST /licenses # Create license
|
||||
PUT /licenses/{id} # Update license
|
||||
DELETE /licenses/{id} # Delete license
|
||||
```
|
||||
|
||||
### Public Endpoints (For Client Software)
|
||||
|
||||
```
|
||||
POST /licenses/validate # Validate license key
|
||||
POST /licenses/activate # Activate license on domain
|
||||
POST /licenses/deactivate # Deactivate license from domain
|
||||
```
|
||||
|
||||
### OAuth Endpoints (Authenticated User)
|
||||
|
||||
```
|
||||
GET /licenses/oauth/validate # Validate OAuth state and license ownership
|
||||
POST /licenses/oauth/confirm # Confirm activation and get token
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Activation Flows
|
||||
|
||||
### 1. Simple API Flow
|
||||
|
||||
Direct license activation without user verification. Suitable for trusted environments.
|
||||
|
||||
```
|
||||
Client Vendor API
|
||||
| |
|
||||
|-- POST /licenses/activate -|
|
||||
| {license_key, domain} |
|
||||
| |
|
||||
|<-- {success, activation_id}|
|
||||
```
|
||||
|
||||
**Example Request:**
|
||||
```bash
|
||||
curl -X POST "https://vendor.com/wp-json/woonoow/v1/licenses/activate" \
|
||||
-H "Content-Type: application/json" \
|
||||
-d '{
|
||||
"license_key": "XXXX-YYYY-ZZZZ-WWWW",
|
||||
"domain": "https://customer-site.com",
|
||||
"machine_id": "optional-unique-id"
|
||||
}'
|
||||
```
|
||||
|
||||
**Example Response:**
|
||||
```json
|
||||
{
|
||||
"success": true,
|
||||
"activation_id": 123,
|
||||
"license_key": "XXXX-YYYY-ZZZZ-WWWW",
|
||||
"status": "active",
|
||||
"expires_at": "2025-01-31T00:00:00Z",
|
||||
"activation_limit": 3,
|
||||
"activation_count": 1
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### 2. Secure OAuth Flow (Recommended)
|
||||
|
||||
User must verify ownership on vendor portal before activation. More secure.
|
||||
|
||||
```
|
||||
Client Vendor Portal Vendor API
|
||||
| | |
|
||||
|-- POST /licenses/activate -| |
|
||||
| {license_key, domain} | |
|
||||
| | |
|
||||
|<-- {oauth_redirect, state}-| |
|
||||
| | |
|
||||
|== User redirects browser ==| |
|
||||
| | |
|
||||
|-------- BROWSER ---------->| |
|
||||
| /my-account/license-connect?license_key=...&state=...|
|
||||
| | |
|
||||
| [User logs in if needed] |
|
||||
| [User sees confirmation page] |
|
||||
| [User clicks "Authorize"] |
|
||||
| | |
|
||||
| |-- POST /oauth/confirm -->|
|
||||
| |<-- {token} --------------|
|
||||
| | |
|
||||
|<------- REDIRECT ----------| |
|
||||
| {return_url}?activation_token=xxx |
|
||||
| | |
|
||||
|-- POST /licenses/activate -----------------------> |
|
||||
| {license_key, activation_token} |
|
||||
| | |
|
||||
|<-- {success, activation_id} --------------------------|
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## OAuth Flow Step by Step
|
||||
|
||||
### Step 1: Client Requests Activation (OAuth Mode)
|
||||
|
||||
```bash
|
||||
curl -X POST "https://vendor.com/wp-json/woonoow/v1/licenses/activate" \
|
||||
-H "Content-Type: application/json" \
|
||||
-d '{
|
||||
"license_key": "XXXX-YYYY-ZZZZ-WWWW",
|
||||
"domain": "https://customer-site.com",
|
||||
"return_url": "https://customer-site.com/activation-callback",
|
||||
"activation_mode": "oauth"
|
||||
}'
|
||||
```
|
||||
|
||||
**Response (OAuth Required):**
|
||||
```json
|
||||
{
|
||||
"success": false,
|
||||
"oauth_required": true,
|
||||
"oauth_redirect": "https://vendor.com/my-account/license-connect/?license_key=XXXX-YYYY-ZZZZ-WWWW&site_url=https://customer-site.com&return_url=https://customer-site.com/activation-callback&state=abc123&nonce=xyz789",
|
||||
"state": "abc123"
|
||||
}
|
||||
```
|
||||
|
||||
### Step 2: User Opens Browser to OAuth URL
|
||||
|
||||
Client opens the `oauth_redirect` URL in user's browser. The user:
|
||||
1. Logs into vendor portal (if not already)
|
||||
2. Sees license activation confirmation page
|
||||
3. Reviews license key and requesting site
|
||||
4. Clicks "Authorize" to confirm
|
||||
|
||||
### Step 3: User Gets Redirected Back
|
||||
|
||||
After authorization, user is redirected to `return_url` with token:
|
||||
|
||||
```
|
||||
https://customer-site.com/activation-callback?activation_token=xyz123&license_key=XXXX-YYYY-ZZZZ-WWWW&nonce=xyz789
|
||||
```
|
||||
|
||||
### Step 4: Client Exchanges Token for Activation
|
||||
|
||||
```bash
|
||||
curl -X POST "https://vendor.com/wp-json/woonoow/v1/licenses/activate" \
|
||||
-H "Content-Type: application/json" \
|
||||
-d '{
|
||||
"license_key": "XXXX-YYYY-ZZZZ-WWWW",
|
||||
"domain": "https://customer-site.com",
|
||||
"activation_token": "xyz123"
|
||||
}'
|
||||
```
|
||||
|
||||
**Response (Success):**
|
||||
```json
|
||||
{
|
||||
"success": true,
|
||||
"activation_id": 456,
|
||||
"license_key": "XXXX-YYYY-ZZZZ-WWWW",
|
||||
"status": "active"
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Configuration
|
||||
|
||||
### Site-Level Settings
|
||||
|
||||
In Admin SPA: **Settings > Licensing**
|
||||
|
||||
| Setting | Description |
|
||||
|---------|-------------|
|
||||
| Default Activation Method | `api` or `oauth` - Default for all products |
|
||||
| License Key Format | Format pattern for generated keys |
|
||||
| Default Validity Period | Days until license expires |
|
||||
| Default Activation Limit | Max activations per license |
|
||||
|
||||
### Per-Product Settings
|
||||
|
||||
In Admin SPA: **Products > Edit Product > General Tab**
|
||||
|
||||
| Setting | Description |
|
||||
|---------|-------------|
|
||||
| Enable Licensing | Toggle to enable license generation |
|
||||
| Activation Method | `Use Site Default`, `Simple API`, or `Secure OAuth` |
|
||||
|
||||
---
|
||||
|
||||
## Database Schema
|
||||
|
||||
### Licenses Table (`wp_woonoow_licenses`)
|
||||
|
||||
| Column | Type | Description |
|
||||
|--------|------|-------------|
|
||||
| id | BIGINT | Primary key |
|
||||
| license_key | VARCHAR(255) | Unique license key |
|
||||
| product_id | BIGINT | WooCommerce product ID |
|
||||
| order_id | BIGINT | WooCommerce order ID |
|
||||
| user_id | BIGINT | Customer user ID |
|
||||
| status | VARCHAR(50) | active, inactive, expired, revoked |
|
||||
| activation_limit | INT | Max allowed activations |
|
||||
| activation_count | INT | Current activation count |
|
||||
| expires_at | DATETIME | Expiration date |
|
||||
| created_at | DATETIME | Created timestamp |
|
||||
| updated_at | DATETIME | Updated timestamp |
|
||||
|
||||
### Activations Table (`wp_woonoow_license_activations`)
|
||||
|
||||
| Column | Type | Description |
|
||||
|--------|------|-------------|
|
||||
| id | BIGINT | Primary key |
|
||||
| license_id | BIGINT | Foreign key to licenses |
|
||||
| domain | VARCHAR(255) | Activated domain |
|
||||
| machine_id | VARCHAR(255) | Optional machine identifier |
|
||||
| status | VARCHAR(50) | active, deactivated, pending |
|
||||
| user_agent | TEXT | Client user agent |
|
||||
| activated_at | DATETIME | Activation timestamp |
|
||||
|
||||
---
|
||||
|
||||
## Customer SPA: License Connect Page
|
||||
|
||||
The OAuth confirmation page is available at:
|
||||
```
|
||||
/my-account/license-connect/
|
||||
```
|
||||
|
||||
### Query Parameters
|
||||
|
||||
| Parameter | Required | Description |
|
||||
|-----------|----------|-------------|
|
||||
| license_key | Yes | License key to activate |
|
||||
| site_url | Yes | Requesting site URL |
|
||||
| return_url | Yes | Callback URL after authorization |
|
||||
| state | Yes | CSRF protection token |
|
||||
| nonce | No | Additional security nonce |
|
||||
|
||||
### UI Features
|
||||
|
||||
- **Focused Layout** - No header/sidebar/footer, just the authorization card
|
||||
- **Brand Display** - Shows vendor site name
|
||||
- **License Details** - Displays license key, site URL, product name
|
||||
- **Security Warning** - Warns user to only authorize trusted sites
|
||||
- **Authorize/Deny Buttons** - Clear actions for user
|
||||
|
||||
---
|
||||
|
||||
## Security Considerations
|
||||
|
||||
1. **State Token** - Prevents CSRF attacks, expires after 5 minutes
|
||||
2. **Activation Token** - Single-use, expires after 5 minutes
|
||||
3. **User Verification** - OAuth ensures license owner authorizes activation
|
||||
4. **Domain Validation** - Tracks activated domains for audit
|
||||
5. **Rate Limiting** - Consider implementing on activation endpoints
|
||||
|
||||
---
|
||||
|
||||
## Files Reference
|
||||
|
||||
| File | Purpose |
|
||||
|------|---------|
|
||||
| `includes/Modules/Licensing/LicensingModule.php` | Module registration, endpoint handlers |
|
||||
| `includes/Modules/Licensing/LicenseManager.php` | Core license operations |
|
||||
| `includes/Api/LicensesController.php` | REST API endpoints |
|
||||
| `customer-spa/src/pages/Account/LicenseConnect.tsx` | OAuth confirmation UI |
|
||||
| `customer-spa/src/pages/Account/index.tsx` | Routing for license pages |
|
||||
| `customer-spa/src/App.tsx` | Top-level routing (license-connect outside BaseLayout) |
|
||||
Reference in New Issue
Block a user