Skip to content

Commit

Permalink
Merge branch 'release/3.1.0' into master
Browse files Browse the repository at this point in the history
  • Loading branch information
michaeldzjap committed Oct 16, 2020
2 parents 250b7e2 + 09ad408 commit 2fb43f8
Show file tree
Hide file tree
Showing 5 changed files with 100 additions and 26 deletions.
41 changes: 39 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,10 @@ A two-factor authentication package for _Laravel_ >= 8 (for Laravel 5 to 7 you w

- [Description](#description)
- [Important](#important)
- [Optional Correction](#optional-correction)
- [Installation](#installation)
- [Changes to the Login Process](#changes-to-the-login-process)
- [Failed Verification Attempt Handling](#failed-verification-attempt-handling)
- [Using a Custom Provider](#using-a-custom-provider)
- [Errors and Exceptions](#errors-and-exceptions)
- [Testing](#testing)
Expand All @@ -30,7 +32,7 @@ From _Laravel_ 5.8 and onwards, the default is to use `bigIncrements` instead of

Publishing the package's migration files allows for more flexibility with regards to customising your database structure. However, it could also cause complications if you already have ran migrations as part of installing previous versions of this package. In this case you simply might want to bypass running the migrations again or only run them when in a specific environment. The `Schema::hasColumn()` and `Schema::hasTable()` methods should be of use here.

### Optional correction
### Optional Correction
Versions of this package prior to v2.3.0 incorrectly created the `user_id` column on the `two_factor_auths` table using `increments` instead of `unsignedInteger`. Practically speaking, this error is of no concern. Although there is no need to have a _primary_ key for the `user_id` column, it doesn't cause any problems either. However, if for some reason you don't like this idea, it is safe to remove the _primary_ key using a migration of the form

```php
Expand Down Expand Up @@ -216,6 +218,7 @@ The first route is the route the user will be redirected to once the two-factor
namespace App\Http\Controllers\Auth;

use App\Http\Controllers\Controller;
use App\Providers\RouteServiceProvider;
use MichaelDzjap\TwoFactorAuth\Http\Controllers\TwoFactorAuthenticatesUsers;

class TwoFactorAuthController extends Controller
Expand All @@ -241,7 +244,7 @@ The first route is the route the user will be redirected to once the two-factor
*
* @var string
*/
protected $redirectTo = '/home';
protected $redirectTo = RouteServiceProvider::HOME;
}
```
3. If you want to give textual feedback to the user when two-factor authentication fails due to an expired token or when throttling kicks in you may want to add this to `resources/views/auth/login.blade.php`:
Expand All @@ -262,6 +265,40 @@ The first route is the route the user will be redirected to once the two-factor
...
```

### Failed Verification Attempt Handling
The default behaviour is to redirect to the previous view with an error message in case token verification fails. However, there most likely are instances where you would like to handle a failed token verification attempt differently. For instance, in the case of _MessageBird_ a token can only be verified once. Any attempt with the same token after a first failed attempt will always throw a `TokenAlreadyProcessedException` and hence, it would make more sense to either redirect to the _/login_ route again to start the entire authentication process from scratch or to redirect to a view where a new token can be requested.

In order to change the default behaviour it is possible to specify either a `$redirectToAfterFailure` property or a protected `redirectToAfterFailure` method on your `TwoFactorAuthController`. If one of these is present (the method taking precedence over the property), the default behaviour is bypassed and the user will be redirected to the specified route. To give a simple example, suppose you simply want to redirect to the _/login_ route after a failed verification attempt you would structure your `TwoFactorAuthController` like:
```php
<?php

namespace App\Http\Controllers\Auth;

use App\Http\Controllers\Controller;
use App\Providers\RouteServiceProvider;
use MichaelDzjap\TwoFactorAuth\Http\Controllers\TwoFactorAuthenticatesUsers;

class TwoFactorAuthController extends Controller
{
use TwoFactorAuthenticatesUsers;

/**
* Where to redirect users after two-factor authentication passes.
*
* @var string
*/
protected $redirectTo = RouteServiceProvider::HOME;

/**
* Where to redirect users after two-factor authentication fails.
*
* @var string
*/
protected $redirectToAfterFailure = '/login';
}
```
Redirecting a user to a route for generating a fresh authentication token would require a bit more work, but certainly is possible this way.

## Using a Custom Provider
Since the v2.1.0 release it is possible to user your own custom provider. To do so your provider needs to implement `MichaelDzjap\TwoFactorAuth\Contracts\TwoFactorProvider` (and possibly `MichaelDzjap\TwoFactorAuth\Contracts\SMSToken` if you want to send the authentication token via SMS).

Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<?php

namespace MichaelDzjap\TwoFactorAuth\Database\Factories;
namespace MichaelDzjap\TwoFactorAuth\Factories;

use Illuminate\Database\Eloquent\Factories\Factory;
use MichaelDzjap\TwoFactorAuth\Models\TwoFactorAuth;
Expand Down
51 changes: 44 additions & 7 deletions src/Http/Controllers/TwoFactorAuthenticatesUsers.php
Original file line number Diff line number Diff line change
Expand Up @@ -58,13 +58,7 @@ public function verifyToken(VerifySMSToken $request)
return $this->sendTwoFactorAuthResponse($request);
}

// If the two-factor authentication attempt was unsuccessful we will increment
// the number of attempts to two-factor authenticate and redirect the user
// back to the two-factor authentication form. Of course, when this user
// surpasses their maximum number of attempts they will get locked out.
$this->incrementTwoFactorAuthAttempts($request);

return $this->sendFailedTwoFactorAuthResponse($request);
return $this->handleFailedAttempt($request);
}

/**
Expand Down Expand Up @@ -122,6 +116,49 @@ protected function authenticated(Request $request, $user)
//
}

/**
* Handle the case where a user has submitted an invalid token.
*
* Default: If the two-factor authentication attempt was unsuccessful we
* will increment the number of attempts to two-factor authenticate and
* redirect the user back to the two-factor authentication form. Of course,
* when this user surpasses their maximum number of attempts they will get
* locked out.
*
* @param \Illuminate\Http\Request $request
* @return \Illuminate\Http\Response
*/
protected function handleFailedAttempt(Request $request)
{
$this->incrementTwoFactorAuthAttempts($request);

if ($path = $this->redirectAfterFailurePath()) {
return redirect()->to($path)->withErrors([
'token' => __('twofactor-auth::twofactor-auth.failed'),
]);
}

return $this->sendFailedTwoFactorAuthResponse($request);
}

/**
* Get the post two-factor authentication failure redirect path.
*
* @return null|string
*/
protected function redirectAfterFailurePath(): ?string
{
if (method_exists($this, 'redirectToAfterFailure')) {
return $this->redirectToAfterFailure();
}

if (property_exists($this, 'redirectToAfterFailure')) {
return $this->redirectToAfterFailure;
}

return null;
}

/**
* Throw a validation exception when two-factor authentication attempt fails.
* NOTE: Throwing a validation exception is cleaner than redirecting, but
Expand Down
2 changes: 1 addition & 1 deletion src/Models/TwoFactorAuth.php
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,6 @@ private function model(): string
*/
protected static function newFactory(): Factory
{
return \MichaelDzjap\TwoFactorAuth\Database\Factories\TwoFactorAuthFactory::new();
return \MichaelDzjap\TwoFactorAuth\Factories\TwoFactorAuthFactory::new();
}
}
30 changes: 15 additions & 15 deletions src/config/twofactor-auth.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,21 +2,6 @@

return [

/*
|--------------------------------------------------------------------------
| Enabled
|--------------------------------------------------------------------------
|
| Options:
|
| - 'always': Always require two-factor authentication.
| - 'never': Never require two-factor authentication.
| - 'user': Specify manually for which users to enable 2fa.
|
*/

'enabled' => 'user',

/*
|--------------------------------------------------------------------------
| Default Two-Factor Authentication Provider
Expand Down Expand Up @@ -61,6 +46,21 @@

],

/*
|--------------------------------------------------------------------------
| Enabled Mode
|--------------------------------------------------------------------------
|
| Options:
|
| 'always': Always require two-factor authentication.
| 'never': Never require two-factor authentication.
| 'user': Specify manually for which users to enable 2fa.
|
*/

'enabled' => 'user',

/*
|--------------------------------------------------------------------------
| Routes Configuration + Naming
Expand Down

0 comments on commit 2fb43f8

Please sign in to comment.