mirror of
https://github.com/usmannasir/cyberpanel.git
synced 2026-01-28 18:29:05 +01:00
Remove to-do folder and documentation files
This commit is contained in:
@@ -1,214 +0,0 @@
|
||||
# Paid Plugins Support for CyberPanel
|
||||
|
||||
## Overview
|
||||
|
||||
CyberPanel now supports paid plugins that require Patreon subscription. Users can install paid plugins, but they cannot run them without an active Patreon subscription to the specified tier.
|
||||
|
||||
## Features
|
||||
|
||||
- ✅ Paid plugin detection from `meta.xml`
|
||||
- ✅ Patreon subscription verification
|
||||
- ✅ Installable but non-functional without subscription
|
||||
- ✅ Visual indicators (badges) for paid plugins in all views:
|
||||
- Grid View: Green "Free" or Yellow "Paid" badge next to version
|
||||
- Table View: Green "Free" or Yellow "Paid" badge next to version
|
||||
- Store View: Separate "Pricing" column with Free/Paid badges
|
||||
- ✅ Subscription required page when accessing without subscription
|
||||
- ✅ "Subscribe on Patreon" button in subscription warning
|
||||
- ✅ API endpoint for checking subscription status
|
||||
|
||||
## Plugin Structure
|
||||
|
||||
### Meta.xml for Paid Plugins
|
||||
|
||||
Add the following fields to your plugin's `meta.xml`:
|
||||
|
||||
```xml
|
||||
<paid>true</paid>
|
||||
<patreon_tier>CyberPanel Paid Plugin</patreon_tier>
|
||||
<patreon_url>https://www.patreon.com/membership/27789984</patreon_url>
|
||||
```
|
||||
|
||||
### Example meta.xml
|
||||
|
||||
```xml
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<plugin>
|
||||
<name>Premium Plugin Example</name>
|
||||
<type>Utility</type>
|
||||
<version>1.0.0</version>
|
||||
<description>An example paid plugin</description>
|
||||
<author>master3395</author>
|
||||
<paid>true</paid>
|
||||
<patreon_tier>CyberPanel Paid Plugin</patreon_tier>
|
||||
<patreon_url>https://www.patreon.com/membership/27789984</patreon_url>
|
||||
<url>/plugins/premiumPlugin/</url>
|
||||
<settings_url>/plugins/premiumPlugin/settings/</settings_url>
|
||||
</plugin>
|
||||
```
|
||||
|
||||
## Implementation in Plugin Views
|
||||
|
||||
### Using the Premium Plugin Decorator
|
||||
|
||||
```python
|
||||
from pluginHolder.plugin_access import check_plugin_access
|
||||
|
||||
def premium_plugin_required(view_func):
|
||||
"""
|
||||
Decorator that checks if user has Patreon subscription
|
||||
"""
|
||||
@wraps(view_func)
|
||||
def _wrapped_view(request, *args, **kwargs):
|
||||
# Check login first
|
||||
try:
|
||||
userID = request.session['userID']
|
||||
except KeyError:
|
||||
from loginSystem.views import loadLoginPage
|
||||
return redirect(loadLoginPage)
|
||||
|
||||
# Check plugin access
|
||||
plugin_meta = {
|
||||
'is_paid': True,
|
||||
'patreon_tier': 'CyberPanel Paid Plugin',
|
||||
'patreon_url': 'https://www.patreon.com/c/newstargeted/membership'
|
||||
}
|
||||
|
||||
access_check = check_plugin_access(request, 'yourPluginName', plugin_meta)
|
||||
|
||||
if not access_check['has_access']:
|
||||
# Show subscription required page
|
||||
context = {
|
||||
'plugin_name': 'Your Plugin Name',
|
||||
'is_paid': True,
|
||||
'patreon_tier': access_check.get('patreon_tier', 'CyberPanel Paid Plugin'),
|
||||
'patreon_url': access_check.get('patreon_url'),
|
||||
'message': access_check.get('message', 'Patreon subscription required')
|
||||
}
|
||||
proc = httpProc(request, 'yourPlugin/subscription_required.html', context, 'admin')
|
||||
return proc.render()
|
||||
|
||||
# User has access - proceed
|
||||
return view_func(request, *args, **kwargs)
|
||||
|
||||
return _wrapped_view
|
||||
|
||||
@cyberpanel_login_required
|
||||
@premium_plugin_required
|
||||
def your_view(request):
|
||||
# Your view code here
|
||||
pass
|
||||
```
|
||||
|
||||
## Patreon Configuration
|
||||
|
||||
### Environment Variables
|
||||
|
||||
Set the following environment variables in CyberPanel:
|
||||
|
||||
```bash
|
||||
export PATREON_CLIENT_ID="your_client_id"
|
||||
export PATREON_CLIENT_SECRET="your_client_secret"
|
||||
export PATREON_CREATOR_ID="your_creator_id"
|
||||
```
|
||||
|
||||
Or add them to `/usr/local/CyberCP/CyberCP/settings.py`:
|
||||
|
||||
```python
|
||||
import os
|
||||
|
||||
PATREON_CLIENT_ID = os.environ.get('PATREON_CLIENT_ID', '')
|
||||
PATREON_CLIENT_SECRET = os.environ.get('PATREON_CLIENT_SECRET', '')
|
||||
PATREON_CREATOR_ID = os.environ.get('PATREON_CREATOR_ID', '')
|
||||
```
|
||||
|
||||
### User Token Storage
|
||||
|
||||
Users need to authorize CyberPanel to check their Patreon membership. Tokens are stored in:
|
||||
|
||||
```
|
||||
/home/cyberpanel/patreon_tokens/{user_email}.token
|
||||
```
|
||||
|
||||
## API Endpoints
|
||||
|
||||
### Check Subscription Status
|
||||
|
||||
```
|
||||
GET /plugins/api/check-subscription/<plugin_name>/
|
||||
```
|
||||
|
||||
Response:
|
||||
```json
|
||||
{
|
||||
"success": true,
|
||||
"has_access": true,
|
||||
"is_paid": true,
|
||||
"message": "Access granted",
|
||||
"patreon_url": null
|
||||
}
|
||||
```
|
||||
|
||||
## Example Plugin
|
||||
|
||||
A complete example paid plugin is available at:
|
||||
|
||||
```
|
||||
/home/cyberpanel-plugins/premiumPlugin/
|
||||
```
|
||||
|
||||
This plugin demonstrates:
|
||||
- Paid plugin meta.xml structure
|
||||
- Subscription verification
|
||||
- Subscription required page
|
||||
- Protected views
|
||||
|
||||
## User Experience
|
||||
|
||||
### For Users Without Subscription
|
||||
|
||||
1. Plugin appears in installed plugins list with "Premium" badge and "Paid" pricing badge
|
||||
2. Plugin appears in CyberPanel Plugin Store with "Paid" badge in the Pricing column
|
||||
3. Plugin can be installed
|
||||
4. When accessing plugin, subscription required page is shown
|
||||
5. Link to Patreon subscription page is provided with "Subscribe on Patreon" button
|
||||
|
||||
### For Users With Subscription
|
||||
|
||||
1. Plugin works normally
|
||||
2. All features are accessible
|
||||
3. Settings page is available
|
||||
4. No restrictions
|
||||
|
||||
## Files Created/Modified
|
||||
|
||||
### New Files
|
||||
|
||||
- `/home/cyberpanel-repo/pluginHolder/patreon_verifier.py` - Patreon API integration
|
||||
- `/home/cyberpanel-repo/pluginHolder/plugin_access.py` - Plugin access control
|
||||
- `/home/cyberpanel-plugins/premiumPlugin/` - Example paid plugin
|
||||
|
||||
### Modified Files
|
||||
|
||||
- `/home/cyberpanel-repo/pluginHolder/views.py` - Added paid plugin parsing and subscription check API
|
||||
- `/home/cyberpanel-repo/pluginHolder/templates/pluginHolder/plugins.html` - Added paid plugin badges and warnings
|
||||
- `/home/cyberpanel-repo/pluginHolder/urls.py` - Added subscription check endpoint
|
||||
|
||||
## Testing
|
||||
|
||||
1. Install the example premium plugin
|
||||
2. Try accessing it without subscription (should show subscription required page)
|
||||
3. Subscribe to Patreon tier "CyberPanel Paid Plugin"
|
||||
4. Authorize CyberPanel to check membership
|
||||
5. Access plugin again (should work normally)
|
||||
|
||||
## Notes
|
||||
|
||||
- Subscription checks are cached for 5 minutes to reduce API calls
|
||||
- Users must authorize CyberPanel to check their Patreon membership
|
||||
- The system checks for the exact tier name specified in `patreon_tier`
|
||||
- Free plugins work normally without any changes
|
||||
|
||||
## Author
|
||||
|
||||
master3395
|
||||
@@ -1,58 +0,0 @@
|
||||
# Patreon Configuration for CyberPanel Paid Plugins
|
||||
|
||||
## Configuration Complete
|
||||
|
||||
Patreon credentials have been configured in CyberPanel settings.
|
||||
|
||||
### Credentials Configuration
|
||||
|
||||
**SECURITY WARNING**: Never commit secrets to the repository!
|
||||
|
||||
Set these via environment variables:
|
||||
|
||||
```bash
|
||||
export PATREON_CLIENT_ID="your_client_id_here"
|
||||
export PATREON_CLIENT_SECRET="your_client_secret_here"
|
||||
export PATREON_MEMBERSHIP_TIER_ID="your_tier_id_here"
|
||||
export PATREON_CREATOR_ACCESS_TOKEN="your_access_token_here"
|
||||
export PATREON_CREATOR_REFRESH_TOKEN="your_refresh_token_here"
|
||||
```
|
||||
|
||||
Or add to `/etc/environment` or systemd service file.
|
||||
|
||||
### Location
|
||||
|
||||
Credentials are stored in:
|
||||
- `/usr/local/CyberCP/CyberCP/settings.py` (or `/home/cyberpanel-repo/CyberCP/settings.py`)
|
||||
|
||||
### How It Works
|
||||
|
||||
1. Users install paid plugins (no subscription required)
|
||||
2. When accessing the plugin, system checks for Patreon membership
|
||||
3. If user has active subscription to tier `27789984`, access is granted
|
||||
4. If not, subscription required page is shown
|
||||
|
||||
### Testing
|
||||
|
||||
To test the configuration:
|
||||
|
||||
1. Install the `premiumPlugin` example plugin
|
||||
2. Try accessing it without subscription (should show subscription page)
|
||||
3. Subscribe to Patreon tier "CyberPanel Paid Plugin" (ID: 27789984)
|
||||
4. Authorize CyberPanel to check membership
|
||||
5. Access plugin again (should work)
|
||||
|
||||
### Membership Verification
|
||||
|
||||
The system checks for:
|
||||
- Tier ID: `27789984`
|
||||
- Tier Name: "CyberPanel Paid Plugin" (fallback)
|
||||
- Active patron status
|
||||
- Currently entitled amount > 0
|
||||
|
||||
### Notes
|
||||
|
||||
- Membership checks are cached for 5 minutes
|
||||
- Users must authorize CyberPanel via OAuth to check membership
|
||||
- Creator access token can be used for server-side verification
|
||||
|
||||
@@ -1,115 +0,0 @@
|
||||
# Secure Patreon Configuration Setup
|
||||
|
||||
## ⚠️ SECURITY WARNING
|
||||
|
||||
**NEVER commit Patreon secrets to the repository!**
|
||||
|
||||
All secrets must be configured via environment variables on the production server.
|
||||
|
||||
## Setup Instructions
|
||||
|
||||
### 1. Get Your Patreon Credentials
|
||||
|
||||
From your Patreon Developer Dashboard:
|
||||
- Client ID
|
||||
- Client Secret
|
||||
- Membership Tier ID (e.g., `27789984`)
|
||||
- Creator Access Token (optional, for server-side verification)
|
||||
- Creator Refresh Token (optional)
|
||||
|
||||
### 2. Configure Environment Variables
|
||||
|
||||
#### Option A: Systemd Service (Recommended)
|
||||
|
||||
Edit `/etc/systemd/system/lscpd.service`:
|
||||
|
||||
```ini
|
||||
[Service]
|
||||
Environment="PATREON_CLIENT_ID=your_client_id"
|
||||
Environment="PATREON_CLIENT_SECRET=your_client_secret"
|
||||
Environment="PATREON_MEMBERSHIP_TIER_ID=your_tier_id"
|
||||
Environment="PATREON_CREATOR_ACCESS_TOKEN=your_access_token"
|
||||
Environment="PATREON_CREATOR_REFRESH_TOKEN=your_refresh_token"
|
||||
```
|
||||
|
||||
Then reload and restart:
|
||||
```bash
|
||||
systemctl daemon-reload
|
||||
systemctl restart lscpd
|
||||
```
|
||||
|
||||
#### Option B: /etc/environment
|
||||
|
||||
Add to `/etc/environment`:
|
||||
```bash
|
||||
PATREON_CLIENT_ID=your_client_id
|
||||
PATREON_CLIENT_SECRET=your_client_secret
|
||||
PATREON_MEMBERSHIP_TIER_ID=your_tier_id
|
||||
PATREON_CREATOR_ACCESS_TOKEN=your_access_token
|
||||
PATREON_CREATOR_REFRESH_TOKEN=your_refresh_token
|
||||
```
|
||||
|
||||
#### Option C: Secure Config File (Not in Repo)
|
||||
|
||||
Create `/usr/local/CyberCP/patreon_config.py` (add to .gitignore):
|
||||
|
||||
```python
|
||||
# Patreon Configuration - DO NOT COMMIT TO REPOSITORY
|
||||
PATREON_CLIENT_ID = 'your_client_id'
|
||||
PATREON_CLIENT_SECRET = 'your_client_secret'
|
||||
PATREON_MEMBERSHIP_TIER_ID = 'your_tier_id'
|
||||
PATREON_CREATOR_ACCESS_TOKEN = 'your_access_token'
|
||||
PATREON_CREATOR_REFRESH_TOKEN = 'your_refresh_token'
|
||||
```
|
||||
|
||||
Then import in settings.py:
|
||||
```python
|
||||
try:
|
||||
from .patreon_config import *
|
||||
except ImportError:
|
||||
pass # Use environment variables instead
|
||||
```
|
||||
|
||||
### 3. Verify Configuration
|
||||
|
||||
Test that secrets are loaded:
|
||||
```bash
|
||||
python3 -c "
|
||||
import os
|
||||
print('Client ID:', 'SET' if os.environ.get('PATREON_CLIENT_ID') else 'NOT SET')
|
||||
print('Client Secret:', 'SET' if os.environ.get('PATREON_CLIENT_SECRET') else 'NOT SET')
|
||||
print('Tier ID:', os.environ.get('PATREON_MEMBERSHIP_TIER_ID', 'NOT SET'))
|
||||
"
|
||||
```
|
||||
|
||||
### 4. Security Checklist
|
||||
|
||||
- [ ] Secrets removed from repository
|
||||
- [ ] Environment variables set on production server
|
||||
- [ ] `/usr/local/CyberCP/patreon_config.py` added to .gitignore (if used)
|
||||
- [ ] CyberPanel service restarted
|
||||
- [ ] Configuration verified working
|
||||
|
||||
## For Plugin Developers
|
||||
|
||||
When creating paid plugins:
|
||||
|
||||
1. **Never hardcode secrets** in plugin code
|
||||
2. **Use environment variables** or Django settings
|
||||
3. **Document required variables** in README
|
||||
4. **Provide example** with placeholder values only
|
||||
|
||||
Example meta.xml:
|
||||
```xml
|
||||
<paid>true</paid>
|
||||
<patreon_tier>Your Tier Name</patreon_tier>
|
||||
<patreon_url>https://www.patreon.com/c/yourname/membership</patreon_url>
|
||||
```
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
If membership checks fail:
|
||||
1. Verify environment variables are set: `env | grep PATREON`
|
||||
2. Check CyberPanel logs: `/home/lscp/logs/error.log`
|
||||
3. Verify tier ID matches your Patreon tier
|
||||
4. Ensure user has authorized OAuth access
|
||||
@@ -1,89 +0,0 @@
|
||||
# Remote Verification Architecture for Paid Plugins
|
||||
|
||||
## Problem
|
||||
|
||||
When users install plugins, they can see all files on their system, which could expose:
|
||||
- Patreon API credentials
|
||||
- Verification logic
|
||||
- Access tokens
|
||||
|
||||
## Solution: Remote Verification Server
|
||||
|
||||
Move all Patreon verification to **YOUR server** (not the user's server).
|
||||
|
||||
### Architecture
|
||||
|
||||
```
|
||||
User's Server (Plugin) Your Server Patreon API
|
||||
| | |
|
||||
|-- Verify Request ----------->| |
|
||||
| |-- Check Membership --->|
|
||||
| |<-- Membership Status --|
|
||||
|<-- Access Granted/Denied ----| |
|
||||
```
|
||||
|
||||
### Benefits
|
||||
|
||||
1. **No secrets on user's server** - All credentials stay on your server
|
||||
2. **Users can't intercept** - Verification happens server-to-server
|
||||
3. **Centralized control** - You can revoke access, update logic, etc.
|
||||
4. **Plugin code can be public** - Only makes API calls, no secrets
|
||||
|
||||
## Implementation
|
||||
|
||||
### 1. Your Verification Server
|
||||
|
||||
Create an API endpoint on your server (e.g., `api.newstargeted.com`):
|
||||
|
||||
```python
|
||||
# Your server endpoint: /api/verify-patreon-membership
|
||||
POST /api/verify-patreon-membership
|
||||
{
|
||||
"user_email": "user@example.com",
|
||||
"plugin_name": "premiumPlugin",
|
||||
"tier_id": "27789984"
|
||||
}
|
||||
|
||||
Response:
|
||||
{
|
||||
"has_access": true,
|
||||
"expires_at": "2026-02-25T00:00:00Z"
|
||||
}
|
||||
```
|
||||
|
||||
### 2. Plugin Code (Public, No Secrets)
|
||||
|
||||
The plugin only makes HTTP requests to your server:
|
||||
|
||||
```python
|
||||
def check_remote_membership(user_email, plugin_name):
|
||||
response = requests.post(
|
||||
'https://api.newstargeted.com/api/verify-patreon-membership',
|
||||
json={
|
||||
'user_email': user_email,
|
||||
'plugin_name': plugin_name,
|
||||
'tier_id': '27789984'
|
||||
},
|
||||
headers={'X-Plugin-Version': '1.0.0'}
|
||||
)
|
||||
return response.json()
|
||||
```
|
||||
|
||||
### 3. Security Measures
|
||||
|
||||
- **Rate limiting** - Prevent abuse
|
||||
- **IP whitelisting** - Only allow from CyberPanel servers (optional)
|
||||
- **Plugin signature** - Verify requests come from legitimate plugins
|
||||
- **Caching** - Reduce API calls to Patreon
|
||||
- **HTTPS only** - Encrypt all communication
|
||||
|
||||
## Alternative: Encrypted Plugin Package
|
||||
|
||||
If you want to encrypt the entire plugin:
|
||||
|
||||
1. **Encrypt plugin files** before distribution
|
||||
2. **Decrypt on install** using a license key
|
||||
3. **License key** tied to user's Patreon subscription
|
||||
4. **Your server** generates license keys
|
||||
|
||||
This is more complex but provides stronger protection.
|
||||
@@ -1,115 +0,0 @@
|
||||
# Remote Verification Setup Complete ✅
|
||||
|
||||
## Summary
|
||||
|
||||
All components are now set up for secure remote verification of paid plugins. Users can install plugins and see all code, but **NO secrets are exposed** because all Patreon API calls happen on YOUR server.
|
||||
|
||||
## ✅ What Was Completed
|
||||
|
||||
### 1. Remote Verification API
|
||||
- **Endpoint**: `https://api.newstargeted.com/api/verify-patreon-membership`
|
||||
- **Location**: `/home/newstargeted.com/api.newstargeted.com/api/verify-patreon-membership.php`
|
||||
- **Status**: ✅ Working and tested
|
||||
- **Permissions**: ✅ newst3922:newst3922 (644)
|
||||
|
||||
### 2. Plugin Updated
|
||||
- **File**: `/home/cyberpanel-plugins/premiumPlugin/views.py`
|
||||
- **Method**: Remote verification (no secrets)
|
||||
- **Status**: ✅ Updated and tested
|
||||
- **Permissions**: ✅ newst3922:newst3922 (644)
|
||||
|
||||
### 3. Configuration
|
||||
- **Patreon credentials**: Added to `/home/newstargeted.com/api.newstargeted.com/config.php`
|
||||
- **Permissions**: ✅ 600 (secure, readable only by owner)
|
||||
- **Owner**: ✅ newst3922:newst3922
|
||||
|
||||
### 4. Routing
|
||||
- **.htaccess**: Updated with API routing rules
|
||||
- **API Router**: Created at `/api/index.php`
|
||||
- **Status**: ✅ Working
|
||||
|
||||
## 🔒 Security Features
|
||||
|
||||
✅ **No secrets in plugin** - All code is public-safe
|
||||
✅ **Credentials on your server only** - Never exposed to users
|
||||
✅ **Rate limiting** - 60 requests/hour per IP
|
||||
✅ **Caching** - 5 minute cache to reduce API calls
|
||||
✅ **HTTPS only** - All communication encrypted
|
||||
✅ **Proper permissions** - Config files protected (600)
|
||||
|
||||
## 📁 File Permissions Summary
|
||||
|
||||
### API Files
|
||||
- `/home/newstargeted.com/api.newstargeted.com/api/verify-patreon-membership.php`: 644, newst3922:newst3922
|
||||
- `/home/newstargeted.com/api.newstargeted.com/api/index.php`: 644, newst3922:newst3922
|
||||
- `/home/newstargeted.com/api.newstargeted.com/config.php`: 600, newst3922:newst3922 (secure)
|
||||
- `/home/newstargeted.com/api.newstargeted.com/.htaccess`: 644, newst3922:newst3922
|
||||
|
||||
### Plugin Files
|
||||
- `/home/cyberpanel-plugins/premiumPlugin/`: All files 644, directories 755, newst3922:newst3922
|
||||
- `/home/cyberpanel/plugins/premiumPlugin/`: All files 644, directories 755, newst3922:newst3922
|
||||
|
||||
## 🧪 Testing
|
||||
|
||||
### API Endpoint Test
|
||||
```bash
|
||||
curl -X POST https://api.newstargeted.com/api/verify-patreon-membership \
|
||||
-H "Content-Type: application/json" \
|
||||
-d '{"user_email":"test@example.com","plugin_name":"premiumPlugin","tier_id":"27789984"}'
|
||||
```
|
||||
|
||||
**Result**: ✅ Returns proper JSON response
|
||||
|
||||
### Plugin Test
|
||||
1. Install plugin from CyberPanel
|
||||
2. Try accessing plugin
|
||||
3. Should show subscription required page (if not subscribed)
|
||||
4. Plugin makes API call to your server (no secrets exposed)
|
||||
|
||||
## 📋 Next Steps
|
||||
|
||||
1. **Implement OAuth Flow** (optional but recommended)
|
||||
- Users authorize CyberPanel via Patreon OAuth
|
||||
- Store access tokens securely (database recommended)
|
||||
- Link tokens to user emails
|
||||
|
||||
2. **Test Full Flow**
|
||||
- Subscribe to Patreon tier
|
||||
- Authorize CyberPanel
|
||||
- Access plugin (should work)
|
||||
|
||||
3. **Monitor**
|
||||
- Check API logs for errors
|
||||
- Monitor rate limiting
|
||||
- Verify caching is working
|
||||
|
||||
## 🎯 Plugin is Safe to Publish
|
||||
|
||||
The `premiumPlugin` can now be:
|
||||
- ✅ Published to public repositories
|
||||
- ✅ Shared with users
|
||||
- ✅ Installed on any server
|
||||
- ✅ Code reviewed by anyone
|
||||
|
||||
**No secrets will be exposed** because all verification happens on your server!
|
||||
|
||||
## 📝 Files Created/Modified
|
||||
|
||||
### Created
|
||||
- `/home/newstargeted.com/api.newstargeted.com/api/verify-patreon-membership.php`
|
||||
- `/home/newstargeted.com/api.newstargeted.com/api/index.php`
|
||||
- `/home/cyberpanel-plugins/premiumPlugin/views.py` (remote version)
|
||||
- `/home/cyberpanel-plugins/premiumPlugin/SECURITY.md`
|
||||
|
||||
### Modified
|
||||
- `/home/newstargeted.com/api.newstargeted.com/config.php` (added Patreon credentials)
|
||||
- `/home/newstargeted.com/api.newstargeted.com/.htaccess` (added API routing)
|
||||
- `/home/cyberpanel-plugins/premiumPlugin/views.py` (updated to remote verification)
|
||||
|
||||
## ✨ Benefits
|
||||
|
||||
1. **Security**: Secrets never leave your server
|
||||
2. **Control**: You can revoke access, update logic centrally
|
||||
3. **Transparency**: Plugin code can be open source
|
||||
4. **Scalability**: Centralized verification handles all requests
|
||||
5. **Maintenance**: Update verification logic in one place
|
||||
@@ -1,86 +0,0 @@
|
||||
# Remote Verification Setup Complete ✅
|
||||
|
||||
## What Was Done
|
||||
|
||||
### 1. Remote Verification API Created
|
||||
- **Location**: `/home/newstargeted.com/api.newstargeted.com/modules/patreon/verify-membership.php`
|
||||
- **URL**: `https://api.newstargeted.com/api/verify-patreon-membership`
|
||||
- **Route**: Added to `.htaccess` for clean URL routing
|
||||
|
||||
### 2. Plugin Updated to Use Remote Verification
|
||||
- **File**: `/home/cyberpanel-plugins/premiumPlugin/views.py`
|
||||
- **Method**: All Patreon checks now go through your server
|
||||
- **No Secrets**: Plugin code contains zero credentials
|
||||
|
||||
### 3. Configuration Added
|
||||
- **Patreon credentials** added to `/home/newstargeted.com/api.newstargeted.com/config.php`
|
||||
- **Secure permissions**: config.php set to 600 (readable only by owner)
|
||||
|
||||
### 4. File Permissions Set
|
||||
- ✅ API files: `newst3922:newst3922` (644 for files, 755 for directories)
|
||||
- ✅ Plugin files: `newst3922:newst3922` (644 for files, 755 for directories)
|
||||
- ✅ Config file: `newst3922:newst3922` (600 - secure)
|
||||
|
||||
## Security Features
|
||||
|
||||
✅ **No secrets in plugin** - Users can see all code
|
||||
✅ **All credentials on your server** - Never exposed
|
||||
✅ **Rate limiting** - 60 requests/hour per IP
|
||||
✅ **Caching** - 5 minute cache to reduce API calls
|
||||
✅ **HTTPS only** - All communication encrypted
|
||||
✅ **Error handling** - Graceful failures
|
||||
|
||||
## How It Works
|
||||
|
||||
1. User installs plugin (no subscription needed)
|
||||
2. User tries to access plugin
|
||||
3. Plugin makes API call to YOUR server
|
||||
4. Your server checks Patreon API (credentials stay on your server)
|
||||
5. Your server returns access status
|
||||
6. Plugin shows content or subscription page
|
||||
|
||||
## Testing
|
||||
|
||||
### Test API Endpoint
|
||||
```bash
|
||||
curl -X POST https://api.newstargeted.com/api/verify-patreon-membership \
|
||||
-H "Content-Type: application/json" \
|
||||
-d '{
|
||||
"user_email": "test@example.com",
|
||||
"plugin_name": "premiumPlugin",
|
||||
"tier_id": "27789984"
|
||||
}'
|
||||
```
|
||||
|
||||
### Expected Response
|
||||
```json
|
||||
{
|
||||
"success": true,
|
||||
"has_access": false,
|
||||
"patreon_tier": "CyberPanel Paid Plugin",
|
||||
"patreon_url": "https://www.patreon.com/c/newstargeted/membership",
|
||||
"message": "Patreon subscription required..."
|
||||
}
|
||||
```
|
||||
|
||||
## Next Steps
|
||||
|
||||
1. **Test the API endpoint** - Verify it's accessible
|
||||
2. **Implement OAuth flow** - For users to authorize Patreon access
|
||||
3. **Store user tokens** - Link Patreon tokens to user emails
|
||||
4. **Test full flow** - Install plugin and verify access control
|
||||
|
||||
## Files Modified
|
||||
|
||||
- `/home/newstargeted.com/api.newstargeted.com/config.php` - Added Patreon credentials
|
||||
- `/home/newstargeted.com/api.newstargeted.com/.htaccess` - Added API route
|
||||
- `/home/newstargeted.com/api.newstargeted.com/modules/patreon/verify-membership.php` - Created
|
||||
- `/home/cyberpanel-plugins/premiumPlugin/views.py` - Updated to use remote verification
|
||||
- `/home/cyberpanel/plugins/premiumPlugin/views.py` - Updated (installed version)
|
||||
|
||||
## Plugin is Now Safe to Publish
|
||||
|
||||
✅ No secrets in code
|
||||
✅ All verification happens on your server
|
||||
✅ Users can see all plugin files without security risk
|
||||
✅ Centralized control and updates
|
||||
@@ -1,132 +0,0 @@
|
||||
# CyberPanel v2.5.5-dev Installation Fixes
|
||||
|
||||
## Issues Identified
|
||||
|
||||
### Issue 1: install.sh Module Loading Failure
|
||||
**Problem**: When executing `install.sh` via `sh <(curl ...)`, the script tries to load modules from `/dev/fd/.../modules/` which doesn't exist because the script is executed directly from stdin.
|
||||
|
||||
**Error Message**:
|
||||
```
|
||||
❌ Module not found: /dev/fd/modules/os/detect.sh
|
||||
❌ Failed to load OS detection module
|
||||
```
|
||||
|
||||
**Root Cause**: The script assumes it's running from a cloned repository directory, but when executed via curl, `SCRIPT_DIR` becomes `/dev/fd/...` which doesn't contain the modules.
|
||||
|
||||
### Issue 2: MariaDB 10.x to 12.x Upgrade Blocked
|
||||
**Problem**: The installer attempts to install MariaDB 12.1 on systems that already have MariaDB 10.11.15 installed. MariaDB's package pre-installation script blocks the upgrade because direct upgrades from 10.x to 12.x are not safe without manual dump/restore.
|
||||
|
||||
**Error Message**:
|
||||
```
|
||||
error: %prein(MariaDB-server-12.1.2-1.el9.x86_64) scriptlet failed, exit status 1
|
||||
Error in PREIN scriptlet in rpm package MariaDB-server
|
||||
```
|
||||
|
||||
**Root Cause**: The installer doesn't check for existing MariaDB installations before attempting to install MariaDB 12.1.
|
||||
|
||||
## Fixes Implemented
|
||||
|
||||
### Fix 1: install.sh - Handle Curl/Wget Execution
|
||||
|
||||
**Location**: `install/install.sh`
|
||||
|
||||
**Changes**:
|
||||
1. Added detection for curl/wget execution (checks if `SCRIPT_DIR` is `/dev/fd/*` or modules directory doesn't exist)
|
||||
2. When detected, the script now:
|
||||
- Clones the CyberPanel repository to a temporary directory
|
||||
- Extracts branch name from command-line arguments
|
||||
- Falls back to legacy installer if git clone fails
|
||||
3. Properly handles branch argument parsing for both `-b` and `--branch` flags
|
||||
|
||||
**Code Added**:
|
||||
```bash
|
||||
# Check if script is being executed via curl/wget
|
||||
if [[ "$SCRIPT_DIR" == /dev/fd/* ]] || [[ ! -d "$SCRIPT_DIR/modules" ]]; then
|
||||
# Clone repository first
|
||||
# ... (see install.sh for full implementation)
|
||||
fi
|
||||
```
|
||||
|
||||
### Fix 2: install.py - MariaDB Installation Detection and Upgrade Attempt
|
||||
|
||||
**Location**: `install/install.py`
|
||||
|
||||
**Changes**:
|
||||
1. Added `checkExistingMariaDB()` method that:
|
||||
- Checks for installed MariaDB/MySQL server packages (RPM or DEB)
|
||||
- Detects MariaDB data directory existence
|
||||
- Extracts version information from `mysql --version` output
|
||||
- Returns version info including major.minor version
|
||||
|
||||
2. Added `_attemptMariaDBUpgrade()` method that:
|
||||
- Attempts to install MariaDB 12.1 on systems with MariaDB 10.x
|
||||
- Sets up MariaDB 12.1 repository
|
||||
- Attempts installation with appropriate flags (`--allowerasing` for RHEL)
|
||||
- Returns `True` if successful, `False` if blocked or fails
|
||||
- Handles upgrade restriction errors gracefully
|
||||
|
||||
3. Modified `installMySQL()` method to:
|
||||
- Check for existing MariaDB installation before attempting install
|
||||
- **If MariaDB 10.x is detected**: Attempt to upgrade to 12.1 first
|
||||
- If upgrade succeeds: Use new MariaDB 12.1 installation
|
||||
- If upgrade fails/blocked: Fall back to existing MariaDB 10.x
|
||||
- If MariaDB 12.x or higher is detected: Skip installation and use existing
|
||||
- Only attempt new installation if no MariaDB is found
|
||||
|
||||
**Key Logic**:
|
||||
```python
|
||||
# Check if MariaDB is already installed
|
||||
is_installed, installed_version, major_minor = self.checkExistingMariaDB()
|
||||
|
||||
if is_installed:
|
||||
if major_minor and major_minor != "unknown":
|
||||
major_ver = float(major_minor)
|
||||
if major_ver < 12.0:
|
||||
# Try to upgrade to 12.1 first
|
||||
upgrade_success = self._attemptMariaDBUpgrade()
|
||||
if upgrade_success:
|
||||
# Use new MariaDB 12.1
|
||||
return True
|
||||
else:
|
||||
# Fall back to existing MariaDB 10.x
|
||||
self.startMariaDB()
|
||||
return True
|
||||
# Use existing MariaDB 12.x+ installation
|
||||
self.startMariaDB()
|
||||
return True
|
||||
```
|
||||
|
||||
## Testing Recommendations
|
||||
|
||||
1. **Test install.sh with curl**:
|
||||
```bash
|
||||
sh <(curl -s https://raw.githubusercontent.com/master3395/cyberpanel/v2.5.5-dev/install.sh)
|
||||
```
|
||||
|
||||
2. **Test on AlmaLinux 9 with existing MariaDB 10.x**:
|
||||
- System should detect existing MariaDB 10.x
|
||||
- Should attempt to upgrade to MariaDB 12.1 first
|
||||
- If upgrade is blocked, should fall back to using existing MariaDB 10.x
|
||||
- Should log appropriate messages about upgrade attempt and fallback
|
||||
|
||||
3. **Test on clean AlmaLinux 9 system**:
|
||||
- Should install MariaDB 12.1 successfully
|
||||
- Should complete full installation
|
||||
|
||||
## Files Modified
|
||||
|
||||
1. `install/install.sh` - Added curl/wget execution handling
|
||||
2. `install/install.py` - Added MariaDB detection and existing installation handling
|
||||
|
||||
## Notes
|
||||
|
||||
- The installer now **attempts to upgrade MariaDB 10.x to 12.1 first**, and only falls back to using existing 10.x if the upgrade is blocked by the package manager
|
||||
- This provides the best of both worlds: tries to get the latest version, but safely falls back if upgrade restrictions prevent it
|
||||
- The upgrade attempt uses `--allowerasing` flag for RHEL-based systems to allow package replacements
|
||||
- If MariaDB's pre-installation scriptlet blocks the upgrade (as it does for 10.x to 12.x), the installer gracefully falls back to the existing installation
|
||||
- The curl/wget execution now properly clones the repository before attempting to load modules
|
||||
|
||||
## Related Issues
|
||||
|
||||
- MariaDB 10.x to 12.x upgrades require manual dump/restore per MariaDB documentation
|
||||
- The installer now respects existing installations to prevent data loss
|
||||
Reference in New Issue
Block a user