id; // 4. تحسين: تسجيل وقت بدء التحميل في الـ Session // هذا السطر مهم لكي يعمل التحقق في دالة process() بشكل صحيح if (!Session::has('download_start_time')) { Session::put('download_start_time', now()); if (!Session::has($sessionKey)) { Session::put($sessionKey, now()); } return view('download.wait', [ 'app' => $app, 'title' => __('Download :app_name', ['app_name' => $app->getTranslatedName()]), // استخدام الثابت المُعرّف 'waitTime' => self::DOWNLOAD_WAIT_TIME, ]); } /** * Process the actual download. */ public function process(Request $request, App $app): RedirectResponse { $startTime = Session::get('download_start_time'); $sessionKey = 'download_start_time.' . $app->id; $startTime = Session::get($sessionKey); // 2. استخدام الثابت لضمان التناسق if (!$startTime || (now()->diffInSeconds($startTime) < self::DOWNLOAD_WAIT_TIME)) { return redirect()->route('download.show', $app->slug) ->with('error', __('Please wait for the countdown to complete.')); } // Clear the session Session::forget('download_start_time'); Session::forget($sessionKey); if (!$this->hasDirectDownloadUrl($app)) { // Redirect back with a message without incrementing downloads return redirect()->route('apps.show', $app->slug) ->with('info', __('Download link is not available at the moment.')); } $app->increment('downloads_count'); return redirect($app->download_url); } protected function hasDirectDownloadUrl(App $app): bool { return $app->download_url && $app->download_url !== '#'; } /** * API endpoint for download information. */ public function apiInfo(App $app): JsonResponse { return response()->json([ 'success' => true, 'data' => [ 'package_name' => $app->package_name, 'name' => $app->getTranslatedName(), 'version' => $app->latest_version, 'size' => $app->formatted_size, 'download_url' => route('download.show', $app->slug), 'direct_url' => $app->download_url, ], ]); } /** * Helper function to generate the secure token. */ protected function generateSecureToken(App $app, string $ipAddress): string { // 3. تحسين: استخدام SHA256 بدلاً من md5 $baseString = $app->package_name . $ipAddress . date('Y-m-d'); return hash(self::TOKEN_HASH_ALGORITHM, $baseString); } /** * Verify download access token. */ public function verifyToken(Request $request, App $app): JsonResponse { $token = $request->get('token'); // استخدام الدالة المساعدة $expectedToken = $this->generateSecureToken($app, $request->ip()); if ($token !== $expectedToken) { return response()->json([ 'success' => false, 'message' => 'Invalid token', ], 403); } return response()->json([ 'success' => true, 'download_url' => $app->download_url, ]); } /** * Generate download token. */ public function generateToken(App $app): JsonResponse { // استخدام الدالة المساعدة $token = $this->generateSecureToken($app, request()->ip()); return response()->json([ 'success' => true, 'token' => $token, // من الأفضل إرجاع الوقت المنتهي الصلاحية ككائن Carbon 'expires_at' => now()->addDay()->toISOString(), ]); }