mirror of
				https://github.com/pelican-dev/panel.git
				synced 2025-10-31 03:16:52 +01:00 
			
		
		
		
	
		
			
				
	
	
		
			99 lines
		
	
	
		
			2.7 KiB
		
	
	
	
		
			PHP
		
	
	
	
	
	
			
		
		
	
	
			99 lines
		
	
	
		
			2.7 KiB
		
	
	
	
		
			PHP
		
	
	
	
	
	
| <?php
 | |
| 
 | |
| namespace Pterodactyl\Http\Middleware;
 | |
| 
 | |
| use Closure;
 | |
| use stdClass;
 | |
| use GuzzleHttp\Client;
 | |
| use Illuminate\Http\Request;
 | |
| use Illuminate\Http\Response;
 | |
| use Pterodactyl\Events\Auth\FailedCaptcha;
 | |
| use Illuminate\Contracts\Config\Repository;
 | |
| use Illuminate\Contracts\Events\Dispatcher;
 | |
| use Symfony\Component\HttpKernel\Exception\HttpException;
 | |
| 
 | |
| class VerifyReCaptcha
 | |
| {
 | |
|     /**
 | |
|      * @var \Illuminate\Contracts\Config\Repository
 | |
|      */
 | |
|     private $config;
 | |
| 
 | |
|     /**
 | |
|      * @var \Illuminate\Contracts\Events\Dispatcher
 | |
|      */
 | |
|     private $dispatcher;
 | |
| 
 | |
|     /**
 | |
|      * VerifyReCaptcha constructor.
 | |
|      *
 | |
|      * @param \Illuminate\Contracts\Events\Dispatcher $dispatcher
 | |
|      * @param \Illuminate\Contracts\Config\Repository $config
 | |
|      */
 | |
|     public function __construct(Dispatcher $dispatcher, Repository $config)
 | |
|     {
 | |
|         $this->config = $config;
 | |
|         $this->dispatcher = $dispatcher;
 | |
|     }
 | |
| 
 | |
|     /**
 | |
|      * Handle an incoming request.
 | |
|      *
 | |
|      * @param \Illuminate\Http\Request $request
 | |
|      * @param \Closure $next
 | |
|      * @return \Illuminate\Http\RedirectResponse|mixed
 | |
|      */
 | |
|     public function handle($request, Closure $next)
 | |
|     {
 | |
|         if (! $this->config->get('recaptcha.enabled')) {
 | |
|             return $next($request);
 | |
|         }
 | |
| 
 | |
|         if ($request->filled('g-recaptcha-response')) {
 | |
|             $client = new Client();
 | |
|             $res = $client->post($this->config->get('recaptcha.domain'), [
 | |
|                 'form_params' => [
 | |
|                     'secret' => $this->config->get('recaptcha.secret_key'),
 | |
|                     'response' => $request->input('g-recaptcha-response'),
 | |
|                 ],
 | |
|             ]);
 | |
| 
 | |
|             if ($res->getStatusCode() === 200) {
 | |
|                 $result = json_decode($res->getBody());
 | |
| 
 | |
|                 if ($result->success && (! $this->config->get('recaptcha.verify_domain') || $this->isResponseVerified($result, $request))) {
 | |
|                     return $next($request);
 | |
|                 }
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         $this->dispatcher->dispatch(
 | |
|             new FailedCaptcha(
 | |
|                 $request->ip(), ! empty($result) ? ($result->hostname ?? null) : null
 | |
|             )
 | |
|         );
 | |
| 
 | |
|         throw new HttpException(
 | |
|             Response::HTTP_BAD_REQUEST, 'Failed to validate reCAPTCHA data.'
 | |
|         );
 | |
|     }
 | |
| 
 | |
|     /**
 | |
|      * Determine if the response from the recaptcha servers was valid.
 | |
|      *
 | |
|      * @param stdClass $result
 | |
|      * @param \Illuminate\Http\Request $request
 | |
|      * @return bool
 | |
|      */
 | |
|     private function isResponseVerified(stdClass $result, Request $request): bool
 | |
|     {
 | |
|         if (! $this->config->get('recaptcha.verify_domain')) {
 | |
|             return false;
 | |
|         }
 | |
| 
 | |
|         $url = parse_url($request->url());
 | |
| 
 | |
|         return $result->hostname === array_get($url, 'host');
 | |
|     }
 | |
| }
 | 
