Files
easystream-main/setup.php
SamiAhmed7777 d22b3e1c0d feat: Add complete Docker deployment with web-based setup wizard
Major additions:
- Web-based setup wizard (setup.php, setup_wizard.php, setup-wizard.js)
- Production Docker configuration (docker-compose.prod.yml, .env.production)
- Database initialization SQL files (deploy/init_settings.sql)
- Template builder system with drag-and-drop UI
- Advanced features (OAuth, CDN, enhanced analytics, monetization)
- Comprehensive documentation (deployment guides, quick start, feature docs)
- Design system with accessibility and responsive layout
- Deployment automation scripts (deploy.ps1, generate-secrets.ps1)

Setup wizard allows customization of:
- Platform name and branding
- Domain configuration
- Membership tiers and pricing
- Admin credentials
- Feature toggles

Database includes 270+ tables for complete video streaming platform with
advanced features for analytics, moderation, template building, and monetization.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-10-26 01:42:31 -07:00

704 lines
26 KiB
PHP

<?php
/*******************************************************************************************************************
| Software Name : EasyStream - Setup Wizard
| Software Description : Interactive setup wizard for first-time installation
| Software Author : (c) Sami Ahmed
|*******************************************************************************************************************/
// Suppress warnings/notices to keep JSON responses clean
error_reporting(E_ERROR | E_PARSE);
ini_set('display_errors', '0');
// Prevent access after setup is complete
if (file_exists('.setup_complete')) {
header('Location: /');
exit;
}
// Check if database connection exists
$db_configured = false;
if (file_exists('.env') || (getenv('DB_HOST') && getenv('DB_NAME'))) {
try {
$db_host = getenv('DB_HOST') ?: 'db';
$db_name = getenv('DB_NAME') ?: 'easystream';
$db_user = getenv('DB_USER') ?: 'easystream';
$db_pass = getenv('DB_PASS') ?: 'easystream';
$pdo = new PDO("mysql:host=$db_host;dbname=$db_name", $db_user, $db_pass);
$db_configured = true;
} catch (Exception $e) {
$db_configured = false;
}
}
// Handle AJAX requests
if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['action'])) {
header('Content-Type: application/json');
require_once 'setup_wizard.php';
$wizard = new SetupWizard();
switch ($_POST['action']) {
case 'test_database':
echo json_encode($wizard->testDatabaseConnection($_POST));
break;
case 'save_configuration':
echo json_encode($wizard->saveConfiguration($_POST));
break;
case 'create_admin':
echo json_encode($wizard->createAdminUser($_POST));
break;
case 'finalize':
echo json_encode($wizard->finalizeSetup($_POST));
break;
default:
echo json_encode(['success' => false, 'error' => 'Invalid action']);
}
exit;
}
// Load the setup wizard template
?>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>EasyStream Setup Wizard</title>
<style>
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
body {
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, sans-serif;
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
min-height: 100vh;
display: flex;
align-items: center;
justify-content: center;
padding: 20px;
}
.wizard-container {
background: white;
border-radius: 16px;
box-shadow: 0 20px 60px rgba(0, 0, 0, 0.3);
max-width: 800px;
width: 100%;
overflow: hidden;
}
.wizard-header {
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
color: white;
padding: 40px;
text-align: center;
}
.wizard-header h1 {
font-size: 32px;
margin-bottom: 10px;
}
.wizard-header p {
opacity: 0.9;
font-size: 16px;
}
.progress-bar {
background: rgba(255, 255, 255, 0.2);
height: 8px;
margin-top: 30px;
border-radius: 4px;
overflow: hidden;
}
.progress-fill {
background: white;
height: 100%;
width: 0%;
transition: width 0.3s ease;
}
.wizard-body {
padding: 40px;
}
.step {
display: none;
}
.step.active {
display: block;
animation: fadeIn 0.3s;
}
@keyframes fadeIn {
from { opacity: 0; transform: translateY(10px); }
to { opacity: 1; transform: translateY(0); }
}
.form-group {
margin-bottom: 24px;
}
.form-group label {
display: block;
margin-bottom: 8px;
font-weight: 600;
color: #333;
}
.form-group input,
.form-group select,
.form-group textarea {
width: 100%;
padding: 12px 16px;
border: 2px solid #e2e8f0;
border-radius: 8px;
font-size: 15px;
transition: border-color 0.2s;
}
.form-group input:focus,
.form-group select:focus,
.form-group textarea:focus {
outline: none;
border-color: #667eea;
}
.form-group small {
display: block;
margin-top: 6px;
color: #718096;
font-size: 13px;
}
.form-row {
display: grid;
grid-template-columns: 1fr 1fr;
gap: 20px;
}
.btn {
padding: 14px 28px;
border: none;
border-radius: 8px;
font-size: 16px;
font-weight: 600;
cursor: pointer;
transition: all 0.2s;
}
.btn-primary {
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
color: white;
}
.btn-primary:hover {
transform: translateY(-2px);
box-shadow: 0 8px 20px rgba(102, 126, 234, 0.4);
}
.btn-secondary {
background: #e2e8f0;
color: #4a5568;
}
.btn-secondary:hover {
background: #cbd5e0;
}
.wizard-footer {
padding: 20px 40px;
background: #f7fafc;
display: flex;
justify-content: space-between;
border-top: 1px solid #e2e8f0;
}
.alert {
padding: 14px 18px;
border-radius: 8px;
margin-bottom: 20px;
display: none;
}
.alert.show {
display: block;
animation: slideDown 0.3s;
}
@keyframes slideDown {
from { opacity: 0; transform: translateY(-10px); }
to { opacity: 1; transform: translateY(0); }
}
.alert-success {
background: #c6f6d5;
color: #22543d;
border: 1px solid #9ae6b4;
}
.alert-error {
background: #fed7d7;
color: #742a2a;
border: 1px solid #fc8181;
}
.alert-info {
background: #bee3f8;
color: #2c5282;
border: 1px solid #90cdf4;
}
.spinner {
border: 3px solid #f3f3f3;
border-top: 3px solid #667eea;
border-radius: 50%;
width: 20px;
height: 20px;
animation: spin 1s linear infinite;
display: inline-block;
margin-left: 10px;
}
@keyframes spin {
0% { transform: rotate(0deg); }
100% { transform: rotate(360deg); }
}
.feature-grid {
display: grid;
grid-template-columns: repeat(2, 1fr);
gap: 16px;
margin-top: 20px;
}
.feature-card {
padding: 16px;
background: #f7fafc;
border-radius: 8px;
border: 2px solid #e2e8f0;
}
.feature-card h4 {
color: #667eea;
margin-bottom: 8px;
}
.feature-card p {
color: #718096;
font-size: 14px;
}
.checkbox-group {
display: flex;
align-items: center;
margin-bottom: 12px;
}
.checkbox-group input[type="checkbox"] {
width: auto;
margin-right: 10px;
}
.color-picker-group {
display: flex;
gap: 12px;
align-items: center;
}
.color-picker-group input[type="color"] {
width: 80px;
height: 48px;
border: none;
cursor: pointer;
}
.membership-tier {
background: #f7fafc;
padding: 20px;
border-radius: 8px;
margin-bottom: 16px;
border: 2px solid #e2e8f0;
}
.membership-tier h4 {
margin-bottom: 16px;
color: #667eea;
}
.success-icon {
width: 80px;
height: 80px;
margin: 0 auto 24px;
background: #48bb78;
border-radius: 50%;
display: flex;
align-items: center;
justify-content: center;
color: white;
font-size: 48px;
}
.text-center {
text-align: center;
}
</style>
</head>
<body>
<div class="wizard-container">
<div class="wizard-header">
<h1>🎬 EasyStream Setup Wizard</h1>
<p>Let's configure your video streaming platform in just a few steps</p>
<div class="progress-bar">
<div class="progress-fill" id="progressBar"></div>
</div>
</div>
<div class="wizard-body">
<div class="alert" id="alert"></div>
<!-- Step 1: Welcome & System Check -->
<div class="step active" id="step1">
<h2>Welcome to EasyStream!</h2>
<p style="margin: 20px 0; color: #718096;">Before we begin, let's make sure everything is ready for installation.</p>
<div class="feature-grid">
<div class="feature-card">
<h4>✓ Video Streaming</h4>
<p>Upload, transcode, and stream videos in multiple formats</p>
</div>
<div class="feature-card">
<h4>✓ Live Streaming</h4>
<p>RTMP ingest with HLS delivery for live broadcasts</p>
</div>
<div class="feature-card">
<h4>✓ User Management</h4>
<p>Complete membership system with subscriptions</p>
</div>
<div class="feature-card">
<h4>✓ Monetization</h4>
<p>Multiple revenue streams and payment integration</p>
</div>
</div>
<div style="margin-top: 30px; padding: 20px; background: #fef5e7; border-radius: 8px; border: 1px solid #f9e79f;">
<strong>📋 Prerequisites:</strong>
<ul style="margin-top: 10px; margin-left: 20px; color: #856404;">
<li>Docker and Docker Compose installed</li>
<li>Ports 80, 443, 1935, 3306, 6379 available</li>
<li>At least 4GB RAM and 20GB disk space</li>
</ul>
</div>
</div>
<!-- Step 2: Platform Configuration -->
<div class="step" id="step2">
<h2>Platform Configuration</h2>
<p style="margin-bottom: 24px; color: #718096;">Customize your platform's basic information</p>
<div class="form-group">
<label for="platformName">Platform Name *</label>
<input type="text" id="platformName" placeholder="e.g., MyVideo, StreamHub" required>
<small>This will be displayed in the site header and browser title</small>
</div>
<div class="form-group">
<label for="platformTagline">Tagline / Description</label>
<input type="text" id="platformTagline" placeholder="e.g., Your Video Streaming Platform">
<small>A short description of your platform</small>
</div>
<div class="form-group">
<label for="domainName">Domain Name *</label>
<input type="text" id="domainName" placeholder="e.g., streaming.example.com" required>
<small>Your full domain name (with subdomain if applicable)</small>
</div>
<div class="form-row">
<div class="form-group">
<label for="contactEmail">Contact Email *</label>
<input type="email" id="contactEmail" placeholder="contact@example.com" required>
</div>
<div class="form-group">
<label for="timezone">Timezone</label>
<select id="timezone">
<option value="UTC">UTC</option>
<option value="America/New_York">Eastern Time</option>
<option value="America/Chicago">Central Time</option>
<option value="America/Denver">Mountain Time</option>
<option value="America/Los_Angeles">Pacific Time</option>
<option value="Europe/London">London</option>
<option value="Europe/Paris">Paris</option>
<option value="Asia/Tokyo">Tokyo</option>
<option value="Australia/Sydney">Sydney</option>
</select>
</div>
</div>
</div>
<!-- Step 3: Branding & Theme -->
<div class="step" id="step3">
<h2>Branding & Theme</h2>
<p style="margin-bottom: 24px; color: #718096;">Customize the look and feel of your platform</p>
<div class="form-row">
<div class="form-group">
<label>Primary Color</label>
<div class="color-picker-group">
<input type="color" id="primaryColor" value="#667eea">
<span id="primaryColorHex">#667eea</span>
</div>
<small>Main brand color for buttons, links, etc.</small>
</div>
<div class="form-group">
<label>Secondary Color</label>
<div class="color-picker-group">
<input type="color" id="secondaryColor" value="#764ba2">
<span id="secondaryColorHex">#764ba2</span>
</div>
<small>Accent color for highlights and gradients</small>
</div>
</div>
<div class="form-group">
<label>Default Theme</label>
<select id="defaultTheme">
<option value="light">Light Mode</option>
<option value="dark">Dark Mode</option>
<option value="auto">Auto (System Preference)</option>
</select>
</div>
<div class="form-group">
<label style="display: flex; align-items: center;">
<input type="checkbox" id="enableTheming" checked style="width: auto; margin-right: 10px;">
Allow users to switch between light and dark themes
</label>
</div>
</div>
<!-- Step 4: Membership Tiers -->
<div class="step" id="step4">
<h2>Membership Tiers</h2>
<p style="margin-bottom: 24px; color: #718096;">Configure your membership levels and features</p>
<div class="membership-tier">
<h4>Free Tier</h4>
<div class="form-group">
<label for="tier1Name">Tier Name *</label>
<input type="text" id="tier1Name" placeholder="e.g., Basic, Free Member" value="Free">
</div>
<div class="form-row">
<div class="form-group">
<label for="tier1Upload">Upload Limit (MB)</label>
<input type="number" id="tier1Upload" value="100">
</div>
<div class="form-group">
<label for="tier1Storage">Storage Limit (GB)</label>
<input type="number" id="tier1Storage" value="5">
</div>
</div>
</div>
<div class="membership-tier">
<h4>Premium Tier</h4>
<div class="form-group">
<label for="tier2Name">Tier Name *</label>
<input type="text" id="tier2Name" placeholder="e.g., Pro, Premium Member" value="Premium">
</div>
<div class="form-row">
<div class="form-group">
<label for="tier2Upload">Upload Limit (MB)</label>
<input type="number" id="tier2Upload" value="500">
</div>
<div class="form-group">
<label for="tier2Storage">Storage Limit (GB)</label>
<input type="number" id="tier2Storage" value="50">
</div>
</div>
<div class="form-group">
<label for="tier2Price">Monthly Price ($)</label>
<input type="number" id="tier2Price" value="9.99" step="0.01">
</div>
</div>
<div class="membership-tier">
<h4>Enterprise Tier</h4>
<div class="form-group">
<label for="tier3Name">Tier Name *</label>
<input type="text" id="tier3Name" placeholder="e.g., Business, Enterprise" value="Enterprise">
</div>
<div class="form-row">
<div class="form-group">
<label for="tier3Upload">Upload Limit (MB)</label>
<input type="number" id="tier3Upload" value="2048">
</div>
<div class="form-group">
<label for="tier3Storage">Storage Limit (GB)</label>
<input type="number" id="tier3Storage" value="500">
</div>
</div>
<div class="form-group">
<label for="tier3Price">Monthly Price ($)</label>
<input type="number" id="tier3Price" value="49.99" step="0.01">
</div>
</div>
</div>
<!-- Step 5: Admin Account -->
<div class="step" id="step5">
<h2>Create Admin Account</h2>
<p style="margin-bottom: 24px; color: #718096;">Set up your administrator account</p>
<div class="form-group">
<label for="adminUsername">Username *</label>
<input type="text" id="adminUsername" placeholder="admin" required>
<small>Must be 4-20 characters, alphanumeric only</small>
</div>
<div class="form-group">
<label for="adminEmail">Email *</label>
<input type="email" id="adminEmail" placeholder="admin@example.com" required>
</div>
<div class="form-group">
<label for="adminPassword">Password *</label>
<input type="password" id="adminPassword" required>
<small>Minimum 8 characters, include uppercase, lowercase, and numbers</small>
</div>
<div class="form-group">
<label for="adminPasswordConfirm">Confirm Password *</label>
<input type="password" id="adminPasswordConfirm" required>
</div>
<div class="form-group">
<label for="adminDisplayName">Display Name</label>
<input type="text" id="adminDisplayName" placeholder="Administrator">
</div>
</div>
<!-- Step 6: Features & Options -->
<div class="step" id="step6">
<h2>Features & Options</h2>
<p style="margin-bottom: 24px; color: #718096;">Enable or disable platform features</p>
<div class="checkbox-group">
<input type="checkbox" id="enableRegistration" checked>
<label for="enableRegistration">Allow new user registration</label>
</div>
<div class="checkbox-group">
<input type="checkbox" id="enableEmailVerification" checked>
<label for="enableEmailVerification">Require email verification</label>
</div>
<div class="checkbox-group">
<input type="checkbox" id="enableLiveStreaming" checked>
<label for="enableLiveStreaming">Enable live streaming (RTMP)</label>
</div>
<div class="checkbox-group">
<input type="checkbox" id="enableComments" checked>
<label for="enableComments">Enable video comments</label>
</div>
<div class="checkbox-group">
<input type="checkbox" id="enableDownloads">
<label for="enableDownloads">Allow video downloads</label>
</div>
<div class="checkbox-group">
<input type="checkbox" id="enableMonetization">
<label for="enableMonetization">Enable monetization features</label>
</div>
<div class="checkbox-group">
<input type="checkbox" id="enableTemplateBuilder" checked>
<label for="enableTemplateBuilder">Enable template builder (drag & drop)</label>
</div>
<div class="checkbox-group">
<input type="checkbox" id="enableAnalytics" checked>
<label for="enableAnalytics">Enable analytics and tracking</label>
</div>
</div>
<!-- Step 7: Review & Install -->
<div class="step" id="step7">
<h2>Review & Install</h2>
<p style="margin-bottom: 24px; color: #718096;">Review your configuration and start the installation</p>
<div id="reviewSummary" style="background: #f7fafc; padding: 24px; border-radius: 8px;">
<!-- Summary will be populated by JavaScript -->
</div>
<div style="margin-top: 24px; padding: 16px; background: #fef5e7; border-radius: 8px; border: 1px solid #f9e79f;">
<strong>⚠️ Note:</strong> The installation process will:
<ul style="margin-top: 10px; margin-left: 20px; color: #856404;">
<li>Configure the database with your settings</li>
<li>Create necessary tables and indexes</li>
<li>Set up your admin account</li>
<li>Generate configuration files</li>
<li>This process may take 2-3 minutes</li>
</ul>
</div>
</div>
<!-- Step 8: Installation Progress -->
<div class="step" id="step8">
<div class="text-center">
<div class="spinner" style="width: 60px; height: 60px; border-width: 6px; margin: 40px auto;"></div>
<h2 id="installStatus">Installing EasyStream...</h2>
<p id="installStep" style="margin-top: 12px; color: #718096;">Initializing database...</p>
<div id="installProgress" style="margin-top: 40px; text-align: left; max-width: 500px; margin-left: auto; margin-right: auto;">
<!-- Progress items will be added here -->
</div>
</div>
</div>
<!-- Step 9: Success -->
<div class="step" id="step9">
<div class="text-center">
<div class="success-icon">✓</div>
<h2>🎉 Installation Complete!</h2>
<p style="margin: 20px 0; color: #718096;">Your EasyStream platform is ready to use!</p>
<div style="background: #f7fafc; padding: 24px; border-radius: 8px; margin: 30px 0; text-align: left;">
<h3 style="margin-bottom: 16px; color: #667eea;">Your Platform Details:</h3>
<p><strong>Platform:</strong> <span id="finalPlatformName"></span></p>
<p><strong>URL:</strong> <span id="finalDomainName"></span></p>
<p><strong>Admin Username:</strong> <span id="finalAdminUsername"></span></p>
<p style="margin-top: 16px; color: #e53e3e;"><strong>⚠️ Important:</strong> Save your login credentials securely!</p>
</div>
<div style="margin-top: 30px;">
<a href="/" class="btn btn-primary" style="display: inline-block; text-decoration: none;">Go to Your Platform →</a>
</div>
</div>
</div>
</div>
<div class="wizard-footer">
<button class="btn btn-secondary" id="prevBtn" onclick="changeStep(-1)" style="display: none;">← Previous</button>
<button class="btn btn-primary" id="nextBtn" onclick="changeStep(1)">Next →</button>
</div>
</div>
<script src="f_scripts/fe/js/setup-wizard.js"></script>
</body>
</html>