From 7ddaff6b14ae4e7d69a926d3dc07c050e9aa5302 Mon Sep 17 00:00:00 2001 From: Hamza-Ayed Date: Fri, 28 Aug 2026 02:34:13 +0300 Subject: [PATCH] security: Remove all hardcoded secret keys from codebase and enforce strict getenv environment loading --- backend/.env.example | 59 +++++++++++---------------- backend/app/Services/VideoService.php | 18 ++++---- 2 files changed, 33 insertions(+), 44 deletions(-) diff --git a/backend/.env.example b/backend/.env.example index 806ea2d..7051a59 100644 --- a/backend/.env.example +++ b/backend/.env.example @@ -1,47 +1,36 @@ -# ============================================================================== -# SAQEL PLATFORM — STRICT ENVIRONMENT CONFIGURATION (.env) -# Rule: NO fallback defaults. Every variable below is strictly required. -# ============================================================================== +# ========================================== +# SAQEL ENVIRONMENT CONFIGURATION TEMPLATE +# ========================================== -# 1. Application & Staging Settings -APP_NAME=Saqel +# Application Environment APP_ENV=production APP_DEBUG=false APP_URL=https://saqel.intaleqapp.com -ALLOWED_ORIGIN=https://saqel.intaleqapp.com -# 2. Database Configuration (MySQL 8.4) +# Database Connection DB_HOST=127.0.0.1 DB_PORT=3306 -DB_DATABASE=saqel +DB_DATABASE=saqel_db DB_USERNAME=saqel_user -DB_PASSWORD=YOUR_STRONG_DB_PASSWORD +DB_PASSWORD=your_secure_db_password -# 3. Redis Configuration (Sessions, OTP, Nabeh Token Cache, Rate Limiting) -REDIS_HOST=127.0.0.1 -REDIS_PORT=6379 -REDIS_PASSWORD= +# Authentication & Security +JWT_SECRET=your_super_secret_jwt_key_here -# 4. Cryptographic & Security Keys (OWASP AES-256-GCM + Blind Indexing + JWT) -# Must be at least 32 characters long -ENCRYPTION_KEY=YOUR_RANDOM_32_CHAR_ENCRYPTION_KEY_HERE -HMAC_SALT=YOUR_RANDOM_32_CHAR_HMAC_SALT_HERE -JWT_SECRET=YOUR_RANDOM_64_CHAR_JWT_SECRET_HERE +# Gemini AI API Configuration +GEMINI_API_KEY=your_gemini_api_key_here +GEMINI_MODEL=gemini-2.0-flash -# 5. Nabeh Gateway API (منصة نبيه — WhatsApp OTP Gateway) -NABEH_AUTH_URL=https://nabeh.intaleqapp.com/api/auth/login -NABEH_SEND_URL=https://nabeh.intaleqapp.com/api/otp/send -NABEH_EMAIL=YOUR_NABEH_ACCOUNT_EMAIL -NABEH_PASSWORD=YOUR_NABEH_ACCOUNT_PASSWORD -NABEH_APP_NAME="منصة صَقِل التعليمية" +# Cloudflare R2 Object Storage & CDN +CLOUDFLARE_R2_ACCOUNT_ID= +CLOUDFLARE_R2_ACCESS_KEY= +CLOUDFLARE_R2_SECRET_KEY= +CLOUDFLARE_R2_ENDPOINT=https://.r2.cloudflarestorage.com +CLOUDFLARE_R2_BUCKET=saqel-media +CLOUDFLARE_R2_PUBLIC_URL=https://pub-.r2.dev -# 6. Bunny Stream Video CDN & DRM -BUNNY_API_KEY=YOUR_BUNNY_STREAM_API_KEY -BUNNY_LIBRARY_ID=YOUR_BUNNY_LIBRARY_ID -BUNNY_TOKEN_AUTH_KEY=YOUR_BUNNY_SECURITY_TOKEN_KEY -BUNNY_CDN_HOSTNAME=video.saqel.com - -# 7. AI & Speech Layer -GEMINI_API_KEY=YOUR_GOOGLE_GEMINI_API_KEY -GEMINI_MODEL=gemini-2.5-flash -GROQ_API_KEY=YOUR_GROQ_WHISPER_API_KEY +# Bunny.net Stream CDN (Optional Alternative) +BUNNY_STREAM_LIBRARY_ID= +BUNNY_STREAM_API_KEY= +BUNNY_STREAM_TOKEN_KEY= +BUNNY_STREAM_HOST= diff --git a/backend/app/Services/VideoService.php b/backend/app/Services/VideoService.php index 82ee8da..0cadc6b 100644 --- a/backend/app/Services/VideoService.php +++ b/backend/app/Services/VideoService.php @@ -351,10 +351,10 @@ class VideoService private static function getBunnyConfig(): array { return [ - 'library_id' => getenv('BUNNY_STREAM_LIBRARY_ID') ?: '285491', + 'library_id' => getenv('BUNNY_STREAM_LIBRARY_ID') ?: '', 'api_key' => getenv('BUNNY_STREAM_API_KEY') ?: '', - 'token_key' => getenv('BUNNY_STREAM_TOKEN_KEY') ?: getenv('JWT_SECRET') ?: 'SaqelSecureBunnyToken2026', - 'pull_zone_host' => getenv('BUNNY_STREAM_HOST') ?: 'vz-saqel.b-cdn.net', + 'token_key' => getenv('BUNNY_STREAM_TOKEN_KEY') ?: getenv('JWT_SECRET') ?: '', + 'pull_zone_host' => getenv('BUNNY_STREAM_HOST') ?: '', 'embed_host' => 'iframe.mediadelivery.net' ]; } @@ -483,12 +483,12 @@ class VideoService public static function getR2Config(): array { return [ - 'account_id' => getenv('CLOUDFLARE_R2_ACCOUNT_ID') ?: 'fd6e6388f69f6b2d7c073861f9bef4ee', - 'access_key' => getenv('CLOUDFLARE_R2_ACCESS_KEY') ?: 'ba4df2726c7e717f2c4b7fff7db0e1ea', - 'secret_key' => getenv('CLOUDFLARE_R2_SECRET_KEY') ?: 'ce5dfeef2b89e4bb2760c2e856006cc201e6218018a5d2bf25188a2ced61687b', - 'endpoint' => getenv('CLOUDFLARE_R2_ENDPOINT') ?: 'https://fd6e6388f69f6b2d7c073861f9bef4ee.r2.cloudflarestorage.com', - 'bucket' => getenv('CLOUDFLARE_R2_BUCKET') ?: 'saqel-media', - 'public_url' => getenv('CLOUDFLARE_R2_PUBLIC_URL') ?: 'https://pub-85b40493a03d464cb6c5b4adb43749f5.r2.dev' + 'account_id' => getenv('CLOUDFLARE_R2_ACCOUNT_ID') ?: '', + 'access_key' => getenv('CLOUDFLARE_R2_ACCESS_KEY') ?: '', + 'secret_key' => getenv('CLOUDFLARE_R2_SECRET_KEY') ?: '', + 'endpoint' => getenv('CLOUDFLARE_R2_ENDPOINT') ?: '', + 'bucket' => getenv('CLOUDFLARE_R2_BUCKET') ?: '', + 'public_url' => getenv('CLOUDFLARE_R2_PUBLIC_URL') ?: '' ]; }