From 213f0ea8f1ff1bff7b394de7405eaa06a2af49f6 Mon Sep 17 00:00:00 2001 From: DoarMihai Date: Mon, 31 Mar 2025 23:49:32 +0300 Subject: [PATCH] lots of progress --- .../Controllers/IPGeolocationController.php | 83 +++++++++ app/Http/Controllers/PacFileController.php | 60 +++++++ .../Controllers/ProxyCheckerController.php | 79 +++++++++ .../Controllers/SubscriptionController.php | 51 +++++- app/Models/Subscription.php | 36 ++++ app/Models/User.php | 13 ++ app/Models/UserSubscription.php | 40 +++++ ...3_21_000001_create_subscriptions_table.php | 29 ++++ ...000002_create_user_subscriptions_table.php | 27 +++ database/seeders/SubscriptionSeeder.php | 67 ++++++++ .../views/ip-geolocation/index.blade.php | 161 ++++++++++++++++++ resources/views/layouts/navigation.blade.php | 15 ++ resources/views/pac-file.blade.php | 151 ++++++++++++++++ resources/views/proxy-checker/index.blade.php | 146 ++++++++++++++++ resources/views/subscriptions/index.blade.php | 100 +++++++++-- .../vendor/pagination/bootstrap-5.blade.php | 53 ------ routes/web.php | 24 ++- 17 files changed, 1067 insertions(+), 68 deletions(-) create mode 100644 app/Http/Controllers/IPGeolocationController.php create mode 100644 app/Http/Controllers/PacFileController.php create mode 100644 app/Http/Controllers/ProxyCheckerController.php create mode 100644 app/Models/Subscription.php create mode 100644 app/Models/UserSubscription.php create mode 100644 database/migrations/2024_03_21_000001_create_subscriptions_table.php create mode 100644 database/migrations/2024_03_21_000002_create_user_subscriptions_table.php create mode 100644 database/seeders/SubscriptionSeeder.php create mode 100644 resources/views/ip-geolocation/index.blade.php create mode 100644 resources/views/pac-file.blade.php create mode 100644 resources/views/proxy-checker/index.blade.php delete mode 100644 resources/views/vendor/pagination/bootstrap-5.blade.php diff --git a/app/Http/Controllers/IPGeolocationController.php b/app/Http/Controllers/IPGeolocationController.php new file mode 100644 index 0000000..dd93584 --- /dev/null +++ b/app/Http/Controllers/IPGeolocationController.php @@ -0,0 +1,83 @@ +client = new Client([ + 'timeout' => 10, + 'verify' => false + ]); + } + + public function index() + { + return view('ip-geolocation.index'); + } + + public function lookup(Request $request) + { + Log::info('IP Lookup request received', ['ip' => $request->ip]); + + $request->validate([ + 'ip' => 'required|ip' + ]); + + try { + Log::info('Making request to IP-API', ['ip' => $request->ip]); + + $response = $this->client->get("http://ip-api.com/json/{$request->ip}"); + + Log::info('IP-API response received', [ + 'status' => $response->getStatusCode(), + 'body' => (string) $response->getBody() + ]); + + if ($response->getStatusCode() === 200) { + $data = json_decode($response->getBody(), true); + + if ($data['status'] === 'success') { + return response()->json([ + 'success' => true, + 'data' => [ + 'country' => $data['country'], + 'city' => $data['city'], + 'region' => $data['regionName'], + 'timezone' => $data['timezone'], + 'isp' => $data['isp'], + 'org' => $data['org'], + 'as' => $data['as'], + 'latitude' => $data['lat'], + 'longitude' => $data['lon'], + 'zip' => $data['zip'] + ] + ]); + } + } + + return response()->json([ + 'success' => false, + 'message' => 'Could not find location information for this IP.' + ], 404); + + } catch (\Exception $e) { + Log::error('IP Lookup error', [ + 'ip' => $request->ip, + 'error' => $e->getMessage() + ]); + + return response()->json([ + 'success' => false, + 'message' => 'An error occurred while looking up the IP: ' . $e->getMessage() + ], 500); + } + } +} \ No newline at end of file diff --git a/app/Http/Controllers/PacFileController.php b/app/Http/Controllers/PacFileController.php new file mode 100644 index 0000000..efab264 --- /dev/null +++ b/app/Http/Controllers/PacFileController.php @@ -0,0 +1,60 @@ +orderBy('score', 'desc') + ->limit(10) + ->get(); + + // Generate PAC file content + $pacContent = $this->generatePacContent($proxies); + + // Return the PAC file with proper headers + return response($pacContent) + ->header('Content-Type', 'application/x-ns-proxy-autoconfig') + ->header('Content-Disposition', 'attachment; filename="proxy.pac"'); + } + + protected function generatePacContent($proxies) + { + // Start with the PAC file header + $content = "function FindProxyForURL(url, host) {\n"; + $content .= " // List of proxy servers\n"; + $content .= " var proxyList = [\n"; + + // Add proxy servers to the list + foreach ($proxies as $proxy) { + $content .= " 'PROXY {$proxy->ip}:{$proxy->port}',\n"; + } + + // Add fallback to DIRECT if no proxies are available + $content .= " 'DIRECT'\n"; + $content .= " ];\n\n"; + + // Add proxy selection logic + $content .= " // Don't proxy localhost\n"; + $content .= " if (isPlainHostName(host) ||\n"; + $content .= " shExpMatch(host, '*.local') ||\n"; + $content .= " isInNet(dnsResolve(host), '10.0.0.0', '255.0.0.0') ||\n"; + $content .= " isInNet(dnsResolve(host), '172.16.0.0', '255.240.0.0') ||\n"; + $content .= " isInNet(dnsResolve(host), '192.168.0.0', '255.255.0.0') ||\n"; + $content .= " isInNet(dnsResolve(host), '127.0.0.0', '255.0.0.0'))\n"; + $content .= " return 'DIRECT';\n\n"; + + // Add proxy selection based on URL + $content .= " // Use proxy for all other URLs\n"; + $content .= " return proxyList.join('; ');\n"; + $content .= "}\n"; + + return $content; + } +} \ No newline at end of file diff --git a/app/Http/Controllers/ProxyCheckerController.php b/app/Http/Controllers/ProxyCheckerController.php new file mode 100644 index 0000000..18173f1 --- /dev/null +++ b/app/Http/Controllers/ProxyCheckerController.php @@ -0,0 +1,79 @@ +proxyService = $proxyService; + } + + public function index() + { + return view('proxy-checker.index'); + } + + public function check(Request $request) + { + $request->validate([ + 'ip' => 'required|ip', + 'port' => 'required|integer|min:1|max:65535', + 'type' => 'required|in:http,https,socks4,socks5', + 'test_url' => 'required|url' + ]); + + $proxy = [ + 'ip' => $request->ip, + 'port' => $request->port, + 'type' => $request->type, + 'url' => $request->test_url + ]; + + try { + $client = new Client([ + 'timeout' => 10, + 'verify' => false, + 'proxy' => [ + 'http' => "{$proxy['type']}://{$proxy['ip']}:{$proxy['port']}", + 'https' => "{$proxy['type']}://{$proxy['ip']}:{$proxy['port']}" + ] + ]); + + $startTime = microtime(true); + $response = $client->get($proxy['url']); + $endTime = microtime(true); + + $speed = round(($endTime - $startTime) * 1000, 2); // Convert to milliseconds + + return response()->json([ + 'success' => true, + 'message' => 'Proxy is working!', + 'data' => [ + 'status_code' => $response->getStatusCode(), + 'speed' => $speed, + 'headers' => $response->getHeaders(), + 'content_type' => $response->getHeaderLine('Content-Type') + ] + ]); + } catch (RequestException $e) { + return response()->json([ + 'success' => false, + 'message' => 'Proxy check failed: ' . $e->getMessage(), + 'error' => $e->getCode() + ], 400); + } catch (\Exception $e) { + return response()->json([ + 'success' => false, + 'message' => 'An error occurred: ' . $e->getMessage() + ], 500); + } + } +} \ No newline at end of file diff --git a/app/Http/Controllers/SubscriptionController.php b/app/Http/Controllers/SubscriptionController.php index 4a512b6..742e491 100644 --- a/app/Http/Controllers/SubscriptionController.php +++ b/app/Http/Controllers/SubscriptionController.php @@ -2,12 +2,61 @@ namespace App\Http\Controllers; +use App\Models\Subscription; +use App\Models\UserSubscription; use Illuminate\Http\Request; +use Illuminate\Support\Facades\Auth; class SubscriptionController extends Controller { public function index() { - return view('subscriptions.index'); + $subscriptions = Subscription::where('is_active', true)->get(); + $userSubscription = Auth::user()->subscriptions()->where('status', 'active')->first(); + + return view('subscriptions.index', compact('subscriptions', 'userSubscription')); + } + + public function subscribe(Request $request, Subscription $subscription) + { + // Check if user already has an active subscription + $activeSubscription = Auth::user()->subscriptions() + ->where('status', 'active') + ->where('expires_at', '>', now()) + ->first(); + + if ($activeSubscription) { + return back()->with('error', 'You already have an active subscription.'); + } + + // Create new subscription + $userSubscription = UserSubscription::create([ + 'user_id' => Auth::id(), + 'subscription_id' => $subscription->id, + 'started_at' => now(), + 'expires_at' => now()->addDays($subscription->duration_days), + 'status' => 'active' + ]); + + // Here you would typically integrate with a payment processor + // For now, we'll just create the subscription + + return redirect()->route('subscriptions.index') + ->with('success', 'Successfully subscribed to ' . $subscription->name . ' plan!'); + } + + public function cancel(UserSubscription $userSubscription) + { + if ($userSubscription->user_id !== Auth::id()) { + return back()->with('error', 'Unauthorized action.'); + } + + $userSubscription->update([ + 'status' => 'cancelled', + 'expires_at' => now() + ]); + + return redirect()->route('subscriptions.index') + ->with('success', 'Subscription cancelled successfully.'); } } \ No newline at end of file diff --git a/app/Models/Subscription.php b/app/Models/Subscription.php new file mode 100644 index 0000000..da8acf2 --- /dev/null +++ b/app/Models/Subscription.php @@ -0,0 +1,36 @@ + 'array', + 'is_active' => 'boolean', + 'price' => 'decimal:2', + 'duration_days' => 'integer', + 'min_score' => 'integer', + 'verification_interval_minutes' => 'integer' + ]; + + public function users() + { + return $this->hasMany(UserSubscription::class); + } +} \ No newline at end of file diff --git a/app/Models/User.php b/app/Models/User.php index 749c7b7..58e76fc 100644 --- a/app/Models/User.php +++ b/app/Models/User.php @@ -45,4 +45,17 @@ class User extends Authenticatable 'password' => 'hashed', ]; } + + public function subscriptions() + { + return $this->hasMany(UserSubscription::class); + } + + public function activeSubscription() + { + return $this->subscriptions() + ->where('status', 'active') + ->where('expires_at', '>', now()) + ->first(); + } } diff --git a/app/Models/UserSubscription.php b/app/Models/UserSubscription.php new file mode 100644 index 0000000..0abc922 --- /dev/null +++ b/app/Models/UserSubscription.php @@ -0,0 +1,40 @@ + 'datetime', + 'expires_at' => 'datetime' + ]; + + public function user() + { + return $this->belongsTo(User::class); + } + + public function subscription() + { + return $this->belongsTo(Subscription::class); + } + + public function isActive() + { + return $this->status === 'active' && $this->expires_at->isFuture(); + } +} \ No newline at end of file diff --git a/database/migrations/2024_03_21_000001_create_subscriptions_table.php b/database/migrations/2024_03_21_000001_create_subscriptions_table.php new file mode 100644 index 0000000..59a4dcb --- /dev/null +++ b/database/migrations/2024_03_21_000001_create_subscriptions_table.php @@ -0,0 +1,29 @@ +id(); + $table->string('name'); + $table->text('description'); + $table->decimal('price', 10, 2); + $table->integer('duration_days'); + $table->json('features'); + $table->integer('min_score'); + $table->integer('verification_interval_minutes'); + $table->boolean('is_active')->default(true); + $table->timestamps(); + }); + } + + public function down() + { + Schema::dropIfExists('subscriptions'); + } +}; \ No newline at end of file diff --git a/database/migrations/2024_03_21_000002_create_user_subscriptions_table.php b/database/migrations/2024_03_21_000002_create_user_subscriptions_table.php new file mode 100644 index 0000000..e45f343 --- /dev/null +++ b/database/migrations/2024_03_21_000002_create_user_subscriptions_table.php @@ -0,0 +1,27 @@ +id(); + $table->foreignId('user_id')->constrained()->onDelete('cascade'); + $table->foreignId('subscription_id')->constrained()->onDelete('cascade'); + $table->timestamp('started_at'); + $table->timestamp('expires_at'); + $table->string('status')->default('active'); + $table->string('payment_id')->nullable(); + $table->timestamps(); + }); + } + + public function down() + { + Schema::dropIfExists('user_subscriptions'); + } +}; \ No newline at end of file diff --git a/database/seeders/SubscriptionSeeder.php b/database/seeders/SubscriptionSeeder.php new file mode 100644 index 0000000..9169d70 --- /dev/null +++ b/database/seeders/SubscriptionSeeder.php @@ -0,0 +1,67 @@ + 'Free', + 'description' => 'Basic access to free proxies', + 'price' => 0, + 'duration_days' => 30, + 'features' => [ + 'Access to basic proxies', + 'Standard verification interval', + 'Basic support' + ], + 'min_score' => 50, + 'verification_interval_minutes' => 60, + 'is_active' => true + ], + [ + 'name' => 'Pro', + 'description' => 'Enhanced access to high-quality proxies', + 'price' => 9.99, + 'duration_days' => 30, + 'features' => [ + 'Access to premium proxies', + 'Faster verification interval', + 'Priority support', + 'Higher minimum score', + 'API access' + ], + 'min_score' => 80, + 'verification_interval_minutes' => 30, + 'is_active' => true + ], + [ + 'name' => 'Enterprise', + 'description' => 'Full access to all premium features', + 'price' => 29.99, + 'duration_days' => 30, + 'features' => [ + 'Access to all proxies', + 'Fastest verification interval', + '24/7 priority support', + 'Highest minimum score', + 'API access', + 'Custom proxy filtering', + 'Dedicated support' + ], + 'min_score' => 90, + 'verification_interval_minutes' => 15, + 'is_active' => true + ] + ]; + + foreach ($subscriptions as $subscription) { + Subscription::create($subscription); + } + } +} \ No newline at end of file diff --git a/resources/views/ip-geolocation/index.blade.php b/resources/views/ip-geolocation/index.blade.php new file mode 100644 index 0000000..3a64b35 --- /dev/null +++ b/resources/views/ip-geolocation/index.blade.php @@ -0,0 +1,161 @@ +@extends('layouts.app') + +@section('content') +
+
+
+
+
+
IP Geolocation Lookup
+
+
+
+ @csrf +
+ +
+ + +
+
+
+ + + + +
+
+
+
+
+ +@push('scripts') + +@endpush +@endsection \ No newline at end of file diff --git a/resources/views/layouts/navigation.blade.php b/resources/views/layouts/navigation.blade.php index 574870f..eab4a5d 100644 --- a/resources/views/layouts/navigation.blade.php +++ b/resources/views/layouts/navigation.blade.php @@ -29,6 +29,21 @@ {{ __('Port Scanner') }} + + +