Skip to content

Instantly share code, notes, and snippets.

@DarkGhostHunter
Last active March 12, 2022 04:39
Show Gist options
  • Save DarkGhostHunter/3a9d02883f8f41963d0107b3db61e174 to your computer and use it in GitHub Desktop.
Save DarkGhostHunter/3a9d02883f8f41963d0107b3db61e174 to your computer and use it in GitHub Desktop.
Confirms an action with a password
<?php
namespace App\Http\Middleware;
use Closure;
use Illuminate\Http\Request;
use Illuminate\Validation\ValidationException;
use Illuminate\Support\Facades\Date;
use Illuminate\Support\Facades\Hash;
use Illuminate\Support\Facades\Lang;
use Illuminate\Support\Facades\Redirect;
use Illuminate\Support\Facades\Response;
use Illuminate\Support\Facades\URL;
class ConfirmByPassword
{
/**
* Create a new middleware instance
*
* @param int $hours
* @return void
*/
public function __construct(protected int $hours = 0)
{
//
}
/**
* Handle the incoming request.
*
* @param \Illuminate\Http\Request $request
* @param \Closure $next
* @param string $route
* @param int|null $hours
* @return mixed
*/
public function handle(Request $request, Closure $next, string $route = 'password.confirm', int $hours = null): mixed
{
$hours ??= $this->hours;
if ($this->alreadyConfirmed($request, $hours) || $this->passwordIsCorrect($request, $route)) {
return $return($next);
}
if ($request->expectsJson()) {
return Response::json(['message' => 'Password confirmation required.'], 423);
}
return Redirect::route($route)->withInput();
}
/**
* Determine if the user has confirmed the action.
*
* @param \Illuminate\Http\Request $request
* @param int $hours
* @return bool
*/
protected function alreadyConfirmed(Request $request, int $hours)
{
return $hours
&& Date::now()->getTimestamp() - $request->session()->get('auth.password_confirmed_at', 0) > $hours * 60 * 60;
}
/**
* Check if the issued password is correct.
*
* @param \Illuminate\Http\Request $request
* @param string $route
* @return bool
*/
protected function passwordIsCorrect(Request $request, string $route): bool
{
if ($request->missing('password')) {
return false;
}
if (Hash::check($request->user()->password, $request->input('password'))) {
$this->rememberConfirmation($request, $hours);
$request->request->forget('password');
return true;
}
// At this point the passwowrd was issued but was incorrect.
throw ValidationException::withMessages([
'password' => Lang::get('validation.password')
])->redirectTo(URL::route($route));
}
/**
* Remember the password confirmation when there is a timeout.
*
* @param \Illuminate\Http\Request $request
* @param int $timeout
* @return void
*/
protected function rememberConfirmation(Request $request, int $timeout): void
{
if ($timeout) {
$request->session()->passwordConfirmed();
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment