Sync current dev state
This commit is contained in:
142
api/cors.config.php
Normal file
142
api/cors.config.php
Normal file
@@ -0,0 +1,142 @@
|
||||
<?php
|
||||
/**
|
||||
* CORS Configuration for EasyStream API
|
||||
*
|
||||
* This file handles Cross-Origin Resource Sharing (CORS) headers
|
||||
* for all API endpoints in a secure and centralized manner.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Set CORS headers based on environment configuration
|
||||
*
|
||||
* @param array $options Optional CORS configuration
|
||||
*/
|
||||
function setAPICorsHeaders($options = []) {
|
||||
// Get allowed origins from environment or use defaults
|
||||
$allowedOrigins = [];
|
||||
|
||||
// Check if we're in development or production
|
||||
$isDevelopment = (defined('_DEVEL') && _DEVEL === true) ||
|
||||
(isset($_ENV['APP_ENV']) && $_ENV['APP_ENV'] === 'development');
|
||||
|
||||
if ($isDevelopment) {
|
||||
// Development: Allow localhost and common development ports
|
||||
$allowedOrigins = [
|
||||
'http://localhost',
|
||||
'http://localhost:3000',
|
||||
'http://localhost:8080',
|
||||
'http://127.0.0.1',
|
||||
'http://127.0.0.1:3000',
|
||||
'http://127.0.0.1:8080',
|
||||
];
|
||||
} else {
|
||||
// Production: Get from environment variable
|
||||
if (isset($_ENV['CORS_ALLOWED_ORIGINS'])) {
|
||||
$allowedOrigins = explode(',', $_ENV['CORS_ALLOWED_ORIGINS']);
|
||||
} elseif (isset($_SERVER['HTTP_HOST'])) {
|
||||
// Default to same origin
|
||||
$protocol = isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] === 'on' ? 'https' : 'http';
|
||||
$allowedOrigins = [$protocol . '://' . $_SERVER['HTTP_HOST']];
|
||||
}
|
||||
}
|
||||
|
||||
// Get the origin from the request
|
||||
$origin = isset($_SERVER['HTTP_ORIGIN']) ? $_SERVER['HTTP_ORIGIN'] : '';
|
||||
|
||||
// Check if origin is allowed
|
||||
$isAllowedOrigin = false;
|
||||
foreach ($allowedOrigins as $allowedOrigin) {
|
||||
$allowedOrigin = trim($allowedOrigin);
|
||||
if ($origin === $allowedOrigin || fnmatch($allowedOrigin, $origin)) {
|
||||
$isAllowedOrigin = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Set CORS headers
|
||||
if ($isAllowedOrigin) {
|
||||
header('Access-Control-Allow-Origin: ' . $origin);
|
||||
header('Access-Control-Allow-Credentials: true');
|
||||
} elseif ($isDevelopment) {
|
||||
// In development, be more permissive but log it
|
||||
header('Access-Control-Allow-Origin: *');
|
||||
error_log('CORS: Allowing all origins in development mode');
|
||||
}
|
||||
|
||||
// Set other CORS headers
|
||||
$allowedMethods = isset($options['methods'])
|
||||
? $options['methods']
|
||||
: 'GET, POST, PUT, DELETE, OPTIONS';
|
||||
header('Access-Control-Allow-Methods: ' . $allowedMethods);
|
||||
|
||||
$allowedHeaders = isset($options['headers'])
|
||||
? $options['headers']
|
||||
: 'Content-Type, Authorization, X-Requested-With, X-CSRF-Token';
|
||||
header('Access-Control-Allow-Headers: ' . $allowedHeaders);
|
||||
|
||||
$maxAge = isset($options['max_age']) ? $options['max_age'] : 86400; // 24 hours
|
||||
header('Access-Control-Max-Age: ' . $maxAge);
|
||||
|
||||
// Expose headers that the client can access
|
||||
$exposedHeaders = isset($options['expose_headers'])
|
||||
? $options['expose_headers']
|
||||
: 'Content-Length, X-JSON';
|
||||
header('Access-Control-Expose-Headers: ' . $exposedHeaders);
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle preflight OPTIONS request
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
function handleCorsPreflightRequest() {
|
||||
if ($_SERVER['REQUEST_METHOD'] === 'OPTIONS') {
|
||||
setAPICorsHeaders();
|
||||
http_response_code(200);
|
||||
exit;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Validate origin for sensitive operations
|
||||
*
|
||||
* @return bool True if origin is valid, false otherwise
|
||||
*/
|
||||
function validateCorsOrigin() {
|
||||
$origin = isset($_SERVER['HTTP_ORIGIN']) ? $_SERVER['HTTP_ORIGIN'] : '';
|
||||
|
||||
if (empty($origin)) {
|
||||
return true; // Same-origin requests don't have an Origin header
|
||||
}
|
||||
|
||||
// Get server's own origin
|
||||
$protocol = isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] === 'on' ? 'https' : 'http';
|
||||
$serverOrigin = $protocol . '://' . $_SERVER['HTTP_HOST'];
|
||||
|
||||
// Check if it's the same origin
|
||||
if ($origin === $serverOrigin) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// Check against allowed origins
|
||||
$isDevelopment = (defined('_DEVEL') && _DEVEL === true) ||
|
||||
(isset($_ENV['APP_ENV']) && $_ENV['APP_ENV'] === 'development');
|
||||
|
||||
if ($isDevelopment) {
|
||||
// More permissive in development
|
||||
return strpos($origin, 'localhost') !== false ||
|
||||
strpos($origin, '127.0.0.1') !== false;
|
||||
}
|
||||
|
||||
// Check environment variable
|
||||
if (isset($_ENV['CORS_ALLOWED_ORIGINS'])) {
|
||||
$allowedOrigins = explode(',', $_ENV['CORS_ALLOWED_ORIGINS']);
|
||||
return in_array($origin, array_map('trim', $allowedOrigins));
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
// Automatically set CORS headers and handle preflight when this file is included
|
||||
setAPICorsHeaders();
|
||||
handleCorsPreflightRequest();
|
||||
Reference in New Issue
Block a user