feat: Add comprehensive documentation suite and reorganize project structure
- Created complete documentation in docs/ directory - Added PROJECT_OVERVIEW.md with feature highlights and getting started guide - Added ARCHITECTURE.md with system design and technical details - Added SECURITY.md with comprehensive security implementation guide - Added DEVELOPMENT.md with development workflows and best practices - Added DEPLOYMENT.md with production deployment instructions - Added API.md with complete REST API documentation - Added CONTRIBUTING.md with contribution guidelines - Added CHANGELOG.md with version history and migration notes - Reorganized all documentation files into docs/ directory for better organization - Updated README.md with proper documentation links and quick navigation - Enhanced project structure with professional documentation standards
This commit is contained in:
215
f_core/f_classes/class.streamkey.php
Normal file
215
f_core/f_classes/class.streamkey.php
Normal file
@@ -0,0 +1,215 @@
|
||||
<?php
|
||||
/*******************************************************************************************************************
|
||||
| Software Name : EasyStream
|
||||
| Software Description : High End YouTube Clone Script with Videos, Shorts, Streams, Images, Audio, Documents, Blogs
|
||||
| Software Author : (c) Sami Ahmed
|
||||
|*******************************************************************************************************************
|
||||
|
|
||||
|*******************************************************************************************************************
|
||||
| This source file is subject to the EasyStream Proprietary License Agreement.
|
||||
|
|
||||
| By using this software, you acknowledge having read this Agreement and agree to be bound thereby.
|
||||
|*******************************************************************************************************************
|
||||
| Copyright (c) 2025 Sami Ahmed. All rights reserved.
|
||||
|*******************************************************************************************************************/
|
||||
|
||||
defined('_ISVALID') or header('Location: /error');
|
||||
|
||||
/**
|
||||
* Stream Key Manager
|
||||
* Handles user-level stream key generation, activation, and revocation.
|
||||
*/
|
||||
class VStreamKeyManager
|
||||
{
|
||||
private static $instance = null;
|
||||
|
||||
private $db;
|
||||
private $logger;
|
||||
|
||||
private function __construct()
|
||||
{
|
||||
$this->db = VDatabase::getInstance();
|
||||
$this->logger = VLogger::getInstance();
|
||||
}
|
||||
|
||||
public static function getInstance()
|
||||
{
|
||||
if (self::$instance === null) {
|
||||
self::$instance = new self();
|
||||
}
|
||||
|
||||
return self::$instance;
|
||||
}
|
||||
|
||||
/**
|
||||
* Ensure the user has streaming enabled and a stream key assigned.
|
||||
* @param int $userId
|
||||
* @return string Stream key
|
||||
* @throws Exception when streaming is disabled or user not found
|
||||
*/
|
||||
public function ensureActiveStreamKey($userId)
|
||||
{
|
||||
$record = $this->getUserStreamingRecord($userId);
|
||||
|
||||
if (!$record) {
|
||||
throw new Exception('User not found');
|
||||
}
|
||||
|
||||
if ((int)$record['streaming_enabled'] !== 1) {
|
||||
throw new Exception('Streaming is disabled for this user');
|
||||
}
|
||||
|
||||
if (empty($record['live_key'])) {
|
||||
return $this->generateAndPersistKey($userId, $record);
|
||||
}
|
||||
|
||||
return $record['live_key'];
|
||||
}
|
||||
|
||||
/**
|
||||
* Activate streaming for a user and ensure a stream key exists.
|
||||
* @param int $userId
|
||||
* @return string Stream key
|
||||
* @throws Exception
|
||||
*/
|
||||
public function activateStreaming($userId)
|
||||
{
|
||||
$record = $this->getUserStreamingRecord($userId);
|
||||
if (!$record) {
|
||||
throw new Exception('User not found');
|
||||
}
|
||||
|
||||
$updates = [
|
||||
'streaming_enabled' => 1
|
||||
];
|
||||
|
||||
$createdNewKey = false;
|
||||
if (empty($record['live_key'])) {
|
||||
$updates['live_key'] = $this->generateStreamKeyValue($userId);
|
||||
$updates['stream_key_regenerated_at'] = date('Y-m-d H:i:s');
|
||||
$createdNewKey = true;
|
||||
}
|
||||
|
||||
// Only perform update if necessary
|
||||
if ((int)$record['streaming_enabled'] !== 1 || $createdNewKey) {
|
||||
$this->db->doUpdate('db_accountuser', 'usr_id', $updates, $userId);
|
||||
|
||||
$this->logger->info('Streaming enabled for user', [
|
||||
'user_id' => $userId,
|
||||
'key_generated' => $createdNewKey
|
||||
]);
|
||||
}
|
||||
|
||||
return $createdNewKey ? $updates['live_key'] : $record['live_key'];
|
||||
}
|
||||
|
||||
/**
|
||||
* Regenerate and persist a new stream key for the user.
|
||||
* @param int $userId
|
||||
* @return string New stream key
|
||||
* @throws Exception
|
||||
*/
|
||||
public function regenerateStreamKey($userId)
|
||||
{
|
||||
$record = $this->getUserStreamingRecord($userId);
|
||||
if (!$record) {
|
||||
throw new Exception('User not found');
|
||||
}
|
||||
|
||||
if ((int)$record['streaming_enabled'] !== 1) {
|
||||
throw new Exception('Streaming is disabled for this user');
|
||||
}
|
||||
|
||||
$newKey = $this->generateStreamKeyValue($userId);
|
||||
$this->db->doUpdate('db_accountuser', 'usr_id', [
|
||||
'live_key' => $newKey,
|
||||
'stream_key_regenerated_at' => date('Y-m-d H:i:s')
|
||||
], $userId);
|
||||
|
||||
$this->logger->info('Stream key regenerated', [
|
||||
'user_id' => $userId
|
||||
]);
|
||||
|
||||
return $newKey;
|
||||
}
|
||||
|
||||
/**
|
||||
* Deactivate streaming for user and clear stream key.
|
||||
* @param int $userId
|
||||
*/
|
||||
public function deactivateStreaming($userId)
|
||||
{
|
||||
$record = $this->getUserStreamingRecord($userId);
|
||||
if (!$record) {
|
||||
return;
|
||||
}
|
||||
|
||||
$updates = [
|
||||
'streaming_enabled' => 0,
|
||||
'live_key' => '',
|
||||
'stream_key_regenerated_at' => date('Y-m-d H:i:s')
|
||||
];
|
||||
|
||||
$this->db->doUpdate('db_accountuser', 'usr_id', $updates, $userId);
|
||||
|
||||
$this->logger->info('Streaming disabled for user', [
|
||||
'user_id' => $userId
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine if streaming is currently enabled for a user.
|
||||
* @param int $userId
|
||||
* @return bool
|
||||
*/
|
||||
public function isStreamingEnabled($userId)
|
||||
{
|
||||
$record = $this->getUserStreamingRecord($userId);
|
||||
return $record ? (int)$record['streaming_enabled'] === 1 : false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve current stream key without side effects.
|
||||
* @param int $userId
|
||||
* @return string|null
|
||||
*/
|
||||
public function getCurrentStreamKey($userId)
|
||||
{
|
||||
$record = $this->getUserStreamingRecord($userId);
|
||||
if (!$record) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return $record['live_key'] ?: null;
|
||||
}
|
||||
|
||||
private function generateAndPersistKey($userId, array $record)
|
||||
{
|
||||
$newKey = $this->generateStreamKeyValue($userId);
|
||||
|
||||
$this->db->doUpdate('db_accountuser', 'usr_id', [
|
||||
'live_key' => $newKey,
|
||||
'stream_key_regenerated_at' => date('Y-m-d H:i:s')
|
||||
], $userId);
|
||||
|
||||
$this->logger->info('Stream key generated for user', [
|
||||
'user_id' => $userId
|
||||
]);
|
||||
|
||||
return $newKey;
|
||||
}
|
||||
|
||||
private function generateStreamKeyValue($userId)
|
||||
{
|
||||
// Ensure high-entropy stream keys using hex encoding
|
||||
$random = bin2hex(random_bytes(16));
|
||||
return 'es_' . $userId . '_' . $random;
|
||||
}
|
||||
|
||||
private function getUserStreamingRecord($userId)
|
||||
{
|
||||
$query = "SELECT usr_id, live_key, streaming_enabled FROM db_accountuser WHERE usr_id = ? LIMIT 1";
|
||||
$result = $this->db->doQuery($query, [$userId]);
|
||||
return $this->db->doFetch($result);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user