diff --git a/app/Http/Controllers/Auth/AuthController.php b/app/Http/Controllers/Auth/AuthController.php index aa320e234..9609ec89a 100644 --- a/app/Http/Controllers/Auth/AuthController.php +++ b/app/Http/Controllers/Auth/AuthController.php @@ -8,6 +8,7 @@ use Validator; use Auth; use Pterodactyl\Http\Controllers\Controller; +use PragmaRX\Google2FA\Google2FA; use Illuminate\Http\Request; use Illuminate\Foundation\Auth\ThrottlesLogins; use Illuminate\Foundation\Auth\AuthenticatesAndRegistersUsers; @@ -27,6 +28,73 @@ class AuthController extends Controller use AuthenticatesAndRegistersUsers, ThrottlesLogins; + /** + * Handle a login request to the application. + * + * @param \Illuminate\Http\Request $request + * @return \Illuminate\Http\Response + */ + public function postLogin(Request $request) + { + $this->validate($request, [ + $this->loginUsername() => 'required', 'password' => 'required', + ]); + + $throttles = $this->isUsingThrottlesLoginsTrait(); + + if ($throttles && $this->hasTooManyLoginAttempts($request)) { + return $this->sendLockoutResponse($request); + } + + $credentials = $this->getCredentials($request); + + if (Auth::attempt($credentials, $request->has('remember'))) { + if(User::select('id')->where('email', $request->input('email'))->where('use_totp', 1)->exists()) { + $validator = Validator::make($request->all(), [ + 'totp_token' => 'required|numeric' + ]); + + if($validator->fails()) { + Auth::logout(); + return redirect('auth/login')->withErrors($validator)->withInput(); + } + + $google2fa = new Google2FA(); + + if($google2fa->verifyKey(User::where('email', $request->input('email'))->first()->totp_secret, $request->input('totp_token'))) { + return $this->handleUserWasAuthenticated($request, $throttles); + } else { + Auth::logout(); + $validator->errors()->add('field', trans('validation.welcome')); + return redirect('auth/login')->withErrors($validator)->withInput(); + } + } else { + return $this->handleUserWasAuthenticated($request, $throttles); + } + } + + if ($throttles) { + $this->incrementLoginAttempts($request); + } + + return redirect($this->loginPath()) + ->withInput($request->only($this->loginUsername(), 'remember')) + ->withErrors([ + $this->loginUsername() => $this->getFailedLoginMessage(), + ]); + } + + /** + * Check if the provided user has TOTP enabled. + * + * @param \Illuminate\Http\Request $request + * @return \Illuminate\Http\Response + */ + public function checkTotp(Request $request) + { + return response()->json(User::select('id')->where('email', $request->input('email'))->where('use_totp', 1)->first()); + } + /** * Post-Authentication redirect location. * diff --git a/app/Http/Middleware/RedirectIfAuthenticated.php b/app/Http/Middleware/RedirectIfAuthenticated.php index ff8496f1f..4c8f8c3b4 100644 --- a/app/Http/Middleware/RedirectIfAuthenticated.php +++ b/app/Http/Middleware/RedirectIfAuthenticated.php @@ -35,7 +35,7 @@ class RedirectIfAuthenticated public function handle($request, Closure $next) { if ($this->auth->check()) { - return redirect('/home'); + return redirect('/'); } return $next($request); diff --git a/app/Http/Routes/AuthRoutes.php b/app/Http/Routes/AuthRoutes.php index 8f6f0d081..027ec809f 100644 --- a/app/Http/Routes/AuthRoutes.php +++ b/app/Http/Routes/AuthRoutes.php @@ -3,12 +3,15 @@ namespace Pterodactyl\Http\Routes; use Illuminate\Routing\Router; +use Request; +use Pterodactyl\Models\User as User; class AuthRoutes { public function map(Router $router) { $router->group(['prefix' => 'auth'], function () use ($router) { $router->get('login', [ 'as' => 'auth.login', 'uses' => 'Auth\AuthController@getLogin' ]); + $router->post('login/totp', [ 'as' => 'auth.login.totp', 'uses' => 'Auth\AuthController@checkTotp' ]); $router->post('login', [ 'as' => 'auth.login.submit', 'uses' => 'Auth\AuthController@postLogin' ]); $router->get('password', [ 'as' => 'auth.password', 'uses' => 'Auth\PasswordController@getEmail' ]); diff --git a/resources/lang/en/strings.php b/resources/lang/en/strings.php index 6b452c4a6..9ccb615d2 100644 --- a/resources/lang/en/strings.php +++ b/resources/lang/en/strings.php @@ -12,6 +12,7 @@ return [ 'password' => 'Password', 'email' => 'Email', 'whoops' => 'Whoops', + 'failed' => 'Your request could not be processed. Please try again later.', 'success' => 'Success', 'location' => 'Location', 'node' => 'Node', diff --git a/resources/lang/en/validation.php b/resources/lang/en/validation.php index c7a1ecf0a..74c0e7c2f 100644 --- a/resources/lang/en/validation.php +++ b/resources/lang/en/validation.php @@ -72,6 +72,7 @@ return [ 'array' => 'The :attribute must contain :size items.', ], 'string' => 'The :attribute must be a string.', + 'totp' => 'The totp token is invalid. Did it expire?', 'timezone' => 'The :attribute must be a valid zone.', 'unique' => 'The :attribute has already been taken.', 'url' => 'The :attribute format is invalid.', diff --git a/resources/views/auth/login.blade.php b/resources/views/auth/login.blade.php index 0202ad0cd..971d56415 100644 --- a/resources/views/auth/login.blade.php +++ b/resources/views/auth/login.blade.php @@ -75,31 +75,34 @@
@endsection