diff --git a/app/Http/Controllers/Auth/LoginController.php b/app/Http/Controllers/Auth/LoginController.php index 5f15918a92..d6d4eb24b5 100644 --- a/app/Http/Controllers/Auth/LoginController.php +++ b/app/Http/Controllers/Auth/LoginController.php @@ -358,7 +358,6 @@ class LoginController extends Controller $secret = Google2FA::generateSecretKey(); $user->two_factor_secret = $secret; - $user->save(); $barcode = new Barcode(); $barcode_obj = @@ -376,6 +375,8 @@ class LoginController extends Controller [-2, -2, -2, -2] ); + $user->save(); // make sure to save *AFTER* displaying the barcode, or else we might save a two_factor_secret that we never actually displayed to the user if the barcode fails + return view('auth.two_factor_enroll')->with('barcode_obj', $barcode_obj); } @@ -420,7 +421,7 @@ class LoginController extends Controller return redirect()->route('two-factor')->with('error', trans('auth/message.two_factor.code_required')); } - if (! $request->has('two_factor_secret')) { + if (! $request->has('two_factor_secret')) { // TODO this seems almost the same as above? return redirect()->route('two-factor')->with('error', 'Two-factor code is required.'); } diff --git a/app/Http/Middleware/CheckForTwoFactor.php b/app/Http/Middleware/CheckForTwoFactor.php index 51ad9c7507..fd630ef10c 100644 --- a/app/Http/Middleware/CheckForTwoFactor.php +++ b/app/Http/Middleware/CheckForTwoFactor.php @@ -24,7 +24,13 @@ class CheckForTwoFactor public function handle($request, Closure $next) { // Skip the logic if the user is on the two factor pages or the setup pages - if (in_array($request->route()->getName(), self::IGNORE_ROUTES)) { + + // TODO - what we have below only works because our ROUTE uri's look _exactly_ like the route *names*. + // The problem is that, in the new(-ish) Laravel routing system, the route-name doesn't match if the route _verb_ is wrong. + // so we can have a blade that POST's to a route('two-factor') - but that route *name* is only matched when the method is GET + // because we attached the name to the GET, not to the POST (as route names *SHOULD* be unique in Laravel) + // there has got to be a better way to do this, but this is the best I could come up with for now. + if (in_array($request->route()->getName(), self::IGNORE_ROUTES) || in_array($request->route()->uri(), self::IGNORE_ROUTES)) { return $next($request); } diff --git a/config/google2fa.php b/config/google2fa.php new file mode 100644 index 0000000000..08c942375a --- /dev/null +++ b/config/google2fa.php @@ -0,0 +1,84 @@ + env('OTP_ENABLED', true), + + /* + * Lifetime in minutes. + * + * In case you need your users to be asked for a new one time passwords from time to time. + */ + 'lifetime' => env('OTP_LIFETIME', 0), // 0 = eternal + + /* + * Renew lifetime at every new request. + */ + 'keep_alive' => env('OTP_KEEP_ALIVE', true), + + /* + * Auth container binding. + */ + 'auth' => 'auth', + + /* + * Guard. + */ + 'guard' => '', + + /* + * 2FA verified session var. + */ + + 'session_var' => 'google2fa', + + /* + * One Time Password request input name. + */ + 'otp_input' => 'one_time_password', //should this be 'two_factor_secret'? + + /* + * One Time Password Window. + */ + 'window' => 1, + + /* + * Forbid user to reuse One Time Passwords. + */ + 'forbid_old_passwords' => false, + + /* + * User's table column for google2fa secret. + */ + 'otp_secret_column' => 'google2fa_secret', + + /* + * One Time Password View. + */ + 'view' => 'google2fa.index', //should this be 'auth.two_factor_enroll'? + + /* + * One Time Password error message. + */ + 'error_messages' => [ + 'wrong_otp' => "The 'One Time Password' typed was wrong.", + 'cannot_be_empty' => 'One Time Password cannot be empty.', + 'unknown' => 'An unknown error has occurred. Please try again.', + ], + + /* + * Throw exceptions or just fire events? + */ + 'throw_exceptions' => env('OTP_THROW_EXCEPTION', true), + + /* + * Which image backend to use for generating QR codes? + * + * Supports imagemagick, svg and eps + */ + 'qrcode_image_backend' => \PragmaRX\Google2FALaravel\Support\Constants::QRCODE_IMAGE_BACKEND_SVG, + +];