Skip to content

Commit

Permalink
Merge pull request #58 from shopperlabs/replace-auth-with-ui-by-auth-…
Browse files Browse the repository at this point in the history
…with-fortify

Fix error when user logging with two-factor authentication
  • Loading branch information
mckenziearts authored Aug 3, 2021
2 parents 563297d + 2ca79a2 commit a440ffb
Show file tree
Hide file tree
Showing 14 changed files with 100 additions and 154 deletions.
18 changes: 18 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
# Release Notes

## v0.0.2 (2021-07-22)

### Update
- Laravel Livewire to v2.5
- Laravel UI Modal to v1.0.0

### Fixed
- Installation version error on guzzle
- Fix error on Shopper prefix `Shopper::prefix()` return value before installation of the package ([#54](https://github.com/shopperlabs/framework/pull/54))
- Fix error on publishing for vendor files
- Fix error on `LaravelUIModal() not defined`
- Fix error on mapbox configuration when setting up your store for the first time

## v0.0.1 (2021-07-07)

Initial release.
4 changes: 2 additions & 2 deletions contributing.md → CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,13 @@

Contributions are welcome and will be fully credited.

Contributions are accepted via Pull Requests on [Github](https://github.com/shopper/framework).
Contributions are accepted via Pull Requests on [Github](https://github.com/shopperlabs/framework).

# Things you could do
If you want to contribute but do not know where to start, this list provides some starting points.
- Add license text
- Remove rewriteRules.php
- Set up TravisCI, StyleCI, ScrutinizerCI
- Set up TravisCI, StyleCI, GithubActions
- Write a comprehensive ReadMe

## Pull Requests
Expand Down
13 changes: 9 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,9 @@
<a href="https://github.com/shopperlabs/framework/actions">
<img src="https://github.com/shopperlabs/framework/workflows/tests/badge.svg" alt="Build Status">
</a>
<a href="https://laravel.com">
<img alt="Laravel v8.x" src="https://img.shields.io/badge/Laravel-v8.x-FF2D20">
</a>
<a href="https://packagist.org/packages/shopper/framework">
<img src="https://img.shields.io/packagist/dt/shopper/framework" alt="Total Downloads">
</a>
Expand Down Expand Up @@ -61,7 +64,7 @@ Shopper Framework can provide premium support for a monthly fee. Find out more v

## Contributing

Please see [contributing.md](contributing.md) for details and a todolist.
Please see [contributing.md](CONTRIBUTING.md) for details and a todolist.

## Security

Expand All @@ -72,9 +75,11 @@ We send an email about 3-4 emails per year. Sometimes less.

## Credits

- [Arthur Monney][link-author]
- [Jean-Vincent QUILICHINI][link-author-2]
- [All Contributors][link-contributors]
- [Arthur Monney][link-author]
- [Jean-Vincent QUILICHINI][link-author-2]
- [Laravel Fortify](https://github.com/laravel/fortify)
- [MailEclipse](https://github.com/Qoraiche/laravel-mail-editor)
- [All Contributors][link-contributors]

And a special thanks to [Caneco](https://twitter.com/caneco) for the logo ✨

Expand Down
83 changes: 0 additions & 83 deletions changelog.md

This file was deleted.

2 changes: 1 addition & 1 deletion src/Actions/AttemptToAuthenticate.php
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ public function __construct(StatefulGuard $guard, LoginRateLimiter $limiter)
/**
* Handle the incoming request.
*
* @param callable $next
* @throws ValidationException
*/
public function handle(Request $request, $next)
{
Expand Down
2 changes: 0 additions & 2 deletions src/Actions/RedirectIfTwoFactorAuthenticatable.php
Original file line number Diff line number Diff line change
Expand Up @@ -85,8 +85,6 @@ protected function throwFailedAuthenticationException(Request $request)

/**
* Get the two factor authentication enabled response.
*
* @return \Symfony\Component\HttpFoundation\Response
*/
protected function twoFactorChallengeResponse(Request $request, $user)
{
Expand Down
9 changes: 9 additions & 0 deletions src/Contracts/FailedTwoFactorLoginResponse.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
<?php

namespace Shopper\Framework\Contracts;

use Illuminate\Contracts\Support\Responsable;

interface FailedTwoFactorLoginResponse extends Responsable
{
}
10 changes: 4 additions & 6 deletions src/FrameworkServiceProvider.php
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,9 @@
use Shopper\Framework\Events\Handlers\RegisterOrderSidebar;
use Shopper\Framework\Http\Middleware\RedirectIfAuthenticated;
use Shopper\Framework\Events\Handlers\RegisterDashboardSidebar;
use Shopper\Framework\Http\Responses\FailedTwoFactorLoginResponse;
use Shopper\Framework\Services\TwoFactor\TwoFactorAuthenticationProvider;
use Shopper\Framework\Contracts\FailedTwoFactorLoginResponse as FailedTwoFactorLoginResponseContract;
use Shopper\Framework\Contracts\TwoFactorAuthenticationProvider as TwoFactorAuthenticationProviderContract;

class FrameworkServiceProvider extends ServiceProvider
Expand Down Expand Up @@ -102,13 +104,9 @@ public function register()

// Register the service the package provides.
$this->app->singleton('shopper', fn () => new Shopper());

$this->app->singleton('gravatar', fn () => new Gravatar());

$this->app->singleton(
TwoFactorAuthenticationProviderContract::class,
TwoFactorAuthenticationProvider::class
);
$this->app->singleton(TwoFactorAuthenticationProviderContract::class, TwoFactorAuthenticationProvider::class);
$this->app->singleton(FailedTwoFactorLoginResponseContract::class, FailedTwoFactorLoginResponse::class);

$this->app->bind(
\Illuminate\Contracts\Debug\ExceptionHandler::class,
Expand Down
22 changes: 1 addition & 21 deletions src/Http/Controllers/Auth/LoginController.php
Original file line number Diff line number Diff line change
Expand Up @@ -36,21 +36,11 @@ public function __construct()
$this->middleware('shopper.guest')->except('logout');
}

/**
* Show the application's login form.
*
* @return \Illuminate\View\View
*/
public function showLoginForm()
{
return view('shopper::auth.login');
}

/**
* Log the user out of the application.
*
* @return \Illuminate\Http\RedirectResponse
*/
public function logout(Request $request)
{
$this->guard()->logout();
Expand All @@ -62,12 +52,7 @@ public function logout(Request $request)
return redirect($this->redirectPath());
}

/**
* Get the post register / login redirect path.
*
* @return string
*/
public function redirectPath()
public function redirectPath(): string
{
return route('shopper.dashboard');
}
Expand Down Expand Up @@ -138,11 +123,6 @@ protected function sendLoginResponse(Request $request)
: redirect()->intended($this->redirectPath());
}

/**
* Get the guard to be used during authentication.
*
* @return \Illuminate\Contracts\Auth\StatefulGuard
*/
protected function guard()
{
return Auth::guard(config('shopper.auth.guard'));
Expand Down
23 changes: 10 additions & 13 deletions src/Http/Controllers/Auth/TwoFactorAuthenticatedController.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,9 @@
use Illuminate\Routing\Controller;
use Illuminate\Contracts\Auth\StatefulGuard;
use Illuminate\Validation\ValidationException;
use Illuminate\Http\Exceptions\HttpResponseException;
use Shopper\Framework\Http\Requests\TwoFactorLoginRequest;
use Shopper\Framework\Http\Responses\FailedTwoFactorLoginResponse;

class TwoFactorAuthenticatedController extends Controller
{
Expand All @@ -28,13 +30,12 @@ public function __construct(StatefulGuard $guard)
$this->middleware('shopper.guest');
}

/**
* Show the two factor authentication login view.
*
* @return \Illuminate\View\View
*/
public function create()
public function create(TwoFactorLoginRequest $request)
{
if (! $request->hasChallengedUser()) {
throw new HttpResponseException(redirect()->route('shopper.login'));
}

return view('shopper::auth.two-factor-login');
}

Expand All @@ -50,17 +51,13 @@ public function store(TwoFactorLoginRequest $request)
if ($code = $request->validRecoveryCode()) {
$user->replaceRecoveryCode($code);
} elseif (! $request->hasValidCode()) {
$message = __('The provided two factor authentication code was invalid.');

if ($request->wantsJson()) {
throw ValidationException::withMessages(['code' => [$message], ]);
}

return redirect()->route('shopper.login')->withErrors(['email' => $message]);
return app(FailedTwoFactorLoginResponse::class);
}

$this->guard->login($user, $request->remember());

$request->session()->regenerate();

return $request->wantsJson()
? new JsonResponse([], 204)
: redirect(route('shopper.dashboard'));
Expand Down
25 changes: 16 additions & 9 deletions src/Http/Requests/TwoFactorLoginRequest.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,9 @@
use Illuminate\Foundation\Http\FormRequest;
use Illuminate\Contracts\Auth\StatefulGuard;
use Illuminate\Validation\ValidationException;
use Illuminate\Http\Exceptions\HttpResponseException;
use Shopper\Framework\Contracts\TwoFactorAuthenticationProvider;
use Shopper\Framework\Http\Responses\FailedTwoFactorLoginResponse;

class TwoFactorLoginRequest extends FormRequest
{
Expand Down Expand Up @@ -67,6 +69,17 @@ public function validRecoveryCode(): ?string
return collect($this->challengedUser()->recoveryCodes())->first(fn ($code) => hash_equals($this->recovery_code, $code) ? $code : null);
}

/**
* Determine if there is a challenged user in the current session.
*/
public function hasChallengedUser(): bool
{
$model = app(StatefulGuard::class)->getProvider()->getModel();

return $this->session()->has('login.id') &&
$model::find($this->session()->get('login.id'));
}

/**
* Get the user that is attempting the two factor challenge.
*
Expand All @@ -79,16 +92,10 @@ public function challengedUser()
}

$model = app(StatefulGuard::class)->getProvider()->getModel();
$user = $model::find($this->session()->pull('login.id'));

if (! $this->session()->has('login.id') || ! $user) {
$message = __('The provided two factor authentication code was invalid.');

if ($this->wantsJson()) {
throw ValidationException::withMessages(['code' => [$message], ]);
}

return redirect()->route('shopper.login')->withErrors(['email' => $message]);
if (! $this->session()->has('login.id') ||
! $user = $model::find($this->session()->pull('login.id'))) {
throw new HttpResponseException(app(FailedTwoFactorLoginResponse::class)->toResponse($this));
}

return $this->challengedUser = $user;
Expand Down
25 changes: 25 additions & 0 deletions src/Http/Responses/FailedTwoFactorLoginResponse.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
<?php

namespace Shopper\Framework\Http\Responses;

use Illuminate\Validation\ValidationException;
use Shopper\Framework\Contracts\FailedTwoFactorLoginResponse as FailedTwoFactorLoginResponseContract;

class FailedTwoFactorLoginResponse implements FailedTwoFactorLoginResponseContract
{
/**
* Create an HTTP response that represents the object.
*
* @throws ValidationException
*/
public function toResponse($request)
{
$message = __('The provided two factor authentication code was invalid.');

if ($request->wantsJson()) {
throw ValidationException::withMessages(['code' => [$message]]);
}

return redirect()->route('shopper.login')->withErrors(['email' => $message]);
}
}
Loading

0 comments on commit a440ffb

Please sign in to comment.