vendor and env first commit

This commit is contained in:
2025-03-28 08:52:46 +01:00
parent f8388bc81b
commit 8f26283832
10976 changed files with 1349952 additions and 2 deletions
@@ -0,0 +1,115 @@
<?php
namespace Laravel\Fortify\Actions;
use Illuminate\Auth\Events\Failed;
use Illuminate\Contracts\Auth\StatefulGuard;
use Illuminate\Validation\ValidationException;
use Laravel\Fortify\Fortify;
use Laravel\Fortify\LoginRateLimiter;
class AttemptToAuthenticate
{
/**
* The guard implementation.
*
* @var \Illuminate\Contracts\Auth\StatefulGuard
*/
protected $guard;
/**
* The login rate limiter instance.
*
* @var \Laravel\Fortify\LoginRateLimiter
*/
protected $limiter;
/**
* Create a new controller instance.
*
* @param \Illuminate\Contracts\Auth\StatefulGuard $guard
* @param \Laravel\Fortify\LoginRateLimiter $limiter
* @return void
*/
public function __construct(StatefulGuard $guard, LoginRateLimiter $limiter)
{
$this->guard = $guard;
$this->limiter = $limiter;
}
/**
* Handle the incoming request.
*
* @param \Illuminate\Http\Request $request
* @param callable $next
* @return mixed
*/
public function handle($request, $next)
{
if (Fortify::$authenticateUsingCallback) {
return $this->handleUsingCustomCallback($request, $next);
}
if ($this->guard->attempt(
$request->only(Fortify::username(), 'password'),
$request->boolean('remember'))
) {
return $next($request);
}
$this->throwFailedAuthenticationException($request);
}
/**
* Attempt to authenticate using a custom callback.
*
* @param \Illuminate\Http\Request $request
* @param callable $next
* @return mixed
*/
protected function handleUsingCustomCallback($request, $next)
{
$user = call_user_func(Fortify::$authenticateUsingCallback, $request);
if (! $user) {
$this->fireFailedEvent($request);
return $this->throwFailedAuthenticationException($request);
}
$this->guard->login($user, $request->boolean('remember'));
return $next($request);
}
/**
* Throw a failed authentication validation exception.
*
* @param \Illuminate\Http\Request $request
* @return void
*
* @throws \Illuminate\Validation\ValidationException
*/
protected function throwFailedAuthenticationException($request)
{
$this->limiter->increment($request);
throw ValidationException::withMessages([
Fortify::username() => [trans('auth.failed')],
]);
}
/**
* Fire the failed authentication attempt event with the given arguments.
*
* @param \Illuminate\Http\Request $request
* @return void
*/
protected function fireFailedEvent($request)
{
event(new Failed($this->guard?->name ?? config('fortify.guard'), null, [
Fortify::username() => $request->{Fortify::username()},
'password' => $request->password,
]));
}
}
@@ -0,0 +1,25 @@
<?php
namespace Laravel\Fortify\Actions;
use Illuminate\Support\Str;
use Laravel\Fortify\Fortify;
class CanonicalizeUsername
{
/**
* Handle the incoming request.
*
* @param \Illuminate\Http\Request $request
* @param callable $next
* @return mixed
*/
public function handle($request, $next)
{
$request->merge([
Fortify::username() => Str::lower($request->{Fortify::username()}),
]);
return $next($request);
}
}
@@ -0,0 +1,26 @@
<?php
namespace Laravel\Fortify\Actions;
use Illuminate\Auth\Events\PasswordReset;
use Illuminate\Contracts\Auth\StatefulGuard;
use Illuminate\Support\Str;
class CompletePasswordReset
{
/**
* Complete the password reset process for the given user.
*
* @param \Illuminate\Contracts\Auth\StatefulGuard $guard
* @param mixed $user
* @return void
*/
public function __invoke(StatefulGuard $guard, $user)
{
$user->setRememberToken(Str::random(60));
$user->save();
event(new PasswordReset($user));
}
}
+43
View File
@@ -0,0 +1,43 @@
<?php
namespace Laravel\Fortify\Actions;
use Illuminate\Contracts\Auth\StatefulGuard;
use Laravel\Fortify\Fortify;
class ConfirmPassword
{
/**
* Confirm that the given password is valid for the given user.
*
* @param \Illuminate\Contracts\Auth\StatefulGuard $guard
* @param mixed $user
* @param string|null $password
* @return bool
*/
public function __invoke(StatefulGuard $guard, $user, ?string $password = null)
{
$username = Fortify::username();
return is_null(Fortify::$confirmPasswordsUsingCallback) ? $guard->validate([
$username => $user->{$username},
'password' => $password,
]) : $this->confirmPasswordUsingCustomCallback($user, $password);
}
/**
* Confirm the user's password using a custom callback.
*
* @param mixed $user
* @param string|null $password
* @return bool
*/
protected function confirmPasswordUsingCustomCallback($user, ?string $password = null)
{
return call_user_func(
Fortify::$confirmPasswordsUsingCallback,
$user,
$password
);
}
}
@@ -0,0 +1,52 @@
<?php
namespace Laravel\Fortify\Actions;
use Illuminate\Validation\ValidationException;
use Laravel\Fortify\Contracts\TwoFactorAuthenticationProvider;
use Laravel\Fortify\Events\TwoFactorAuthenticationConfirmed;
class ConfirmTwoFactorAuthentication
{
/**
* The two factor authentication provider.
*
* @var \Laravel\Fortify\Contracts\TwoFactorAuthenticationProvider
*/
protected $provider;
/**
* Create a new action instance.
*
* @param \Laravel\Fortify\Contracts\TwoFactorAuthenticationProvider $provider
* @return void
*/
public function __construct(TwoFactorAuthenticationProvider $provider)
{
$this->provider = $provider;
}
/**
* Confirm the two factor authentication configuration for the user.
*
* @param mixed $user
* @param string $code
* @return void
*/
public function __invoke($user, $code)
{
if (empty($user->two_factor_secret) ||
empty($code) ||
! $this->provider->verify(decrypt($user->two_factor_secret), $code)) {
throw ValidationException::withMessages([
'code' => [__('The provided two factor authentication code was invalid.')],
])->errorBag('confirmTwoFactorAuthentication');
}
$user->forceFill([
'two_factor_confirmed_at' => now(),
])->save();
TwoFactorAuthenticationConfirmed::dispatch($user);
}
}
@@ -0,0 +1,31 @@
<?php
namespace Laravel\Fortify\Actions;
use Laravel\Fortify\Events\TwoFactorAuthenticationDisabled;
use Laravel\Fortify\Fortify;
class DisableTwoFactorAuthentication
{
/**
* Disable two factor authentication for the user.
*
* @param mixed $user
* @return void
*/
public function __invoke($user)
{
if (! is_null($user->two_factor_secret) ||
! is_null($user->two_factor_recovery_codes) ||
! is_null($user->two_factor_confirmed_at)) {
$user->forceFill([
'two_factor_secret' => null,
'two_factor_recovery_codes' => null,
] + (Fortify::confirmsTwoFactorAuthentication() ? [
'two_factor_confirmed_at' => null,
] : []))->save();
TwoFactorAuthenticationDisabled::dispatch($user);
}
}
}
@@ -0,0 +1,50 @@
<?php
namespace Laravel\Fortify\Actions;
use Illuminate\Support\Collection;
use Laravel\Fortify\Contracts\TwoFactorAuthenticationProvider;
use Laravel\Fortify\Events\TwoFactorAuthenticationEnabled;
use Laravel\Fortify\RecoveryCode;
class EnableTwoFactorAuthentication
{
/**
* The two factor authentication provider.
*
* @var \Laravel\Fortify\Contracts\TwoFactorAuthenticationProvider
*/
protected $provider;
/**
* Create a new action instance.
*
* @param \Laravel\Fortify\Contracts\TwoFactorAuthenticationProvider $provider
* @return void
*/
public function __construct(TwoFactorAuthenticationProvider $provider)
{
$this->provider = $provider;
}
/**
* Enable two factor authentication for the user.
*
* @param mixed $user
* @param bool $force
* @return void
*/
public function __invoke($user, $force = false)
{
if (empty($user->two_factor_secret) || $force === true) {
$user->forceFill([
'two_factor_secret' => encrypt($this->provider->generateSecretKey()),
'two_factor_recovery_codes' => encrypt(json_encode(Collection::times(8, function () {
return RecoveryCode::generate();
})->all())),
])->save();
TwoFactorAuthenticationEnabled::dispatch($user);
}
}
}
@@ -0,0 +1,46 @@
<?php
namespace Laravel\Fortify\Actions;
use Illuminate\Auth\Events\Lockout;
use Laravel\Fortify\Contracts\LockoutResponse;
use Laravel\Fortify\LoginRateLimiter;
class EnsureLoginIsNotThrottled
{
/**
* The login rate limiter instance.
*
* @var \Laravel\Fortify\LoginRateLimiter
*/
protected $limiter;
/**
* Create a new class instance.
*
* @param \Laravel\Fortify\LoginRateLimiter $limiter
* @return void
*/
public function __construct(LoginRateLimiter $limiter)
{
$this->limiter = $limiter;
}
/**
* Handle the incoming request.
*
* @param \Illuminate\Http\Request $request
* @param callable $next
* @return mixed
*/
public function handle($request, $next)
{
if (! $this->limiter->tooManyAttempts($request)) {
return $next($request);
}
event(new Lockout($request));
return app(LockoutResponse::class);
}
}
@@ -0,0 +1,27 @@
<?php
namespace Laravel\Fortify\Actions;
use Illuminate\Support\Collection;
use Laravel\Fortify\Events\RecoveryCodesGenerated;
use Laravel\Fortify\RecoveryCode;
class GenerateNewRecoveryCodes
{
/**
* Generate new recovery codes for the user.
*
* @param mixed $user
* @return void
*/
public function __invoke($user)
{
$user->forceFill([
'two_factor_recovery_codes' => encrypt(json_encode(Collection::times(8, function () {
return RecoveryCode::generate();
})->all())),
])->save();
RecoveryCodesGenerated::dispatch($user);
}
}
@@ -0,0 +1,44 @@
<?php
namespace Laravel\Fortify\Actions;
use Laravel\Fortify\LoginRateLimiter;
class PrepareAuthenticatedSession
{
/**
* The login rate limiter instance.
*
* @var \Laravel\Fortify\LoginRateLimiter
*/
protected $limiter;
/**
* Create a new class instance.
*
* @param \Laravel\Fortify\LoginRateLimiter $limiter
* @return void
*/
public function __construct(LoginRateLimiter $limiter)
{
$this->limiter = $limiter;
}
/**
* Handle the incoming request.
*
* @param \Illuminate\Http\Request $request
* @param callable $next
* @return mixed
*/
public function handle($request, $next)
{
if ($request->hasSession()) {
$request->session()->regenerate();
}
$this->limiter->clear($request);
return $next($request);
}
}
@@ -0,0 +1,156 @@
<?php
namespace Laravel\Fortify\Actions;
use Illuminate\Auth\Events\Failed;
use Illuminate\Contracts\Auth\StatefulGuard;
use Illuminate\Validation\ValidationException;
use Laravel\Fortify\Events\TwoFactorAuthenticationChallenged;
use Laravel\Fortify\Fortify;
use Laravel\Fortify\LoginRateLimiter;
use Laravel\Fortify\TwoFactorAuthenticatable;
class RedirectIfTwoFactorAuthenticatable
{
/**
* The guard implementation.
*
* @var \Illuminate\Contracts\Auth\StatefulGuard
*/
protected $guard;
/**
* The login rate limiter instance.
*
* @var \Laravel\Fortify\LoginRateLimiter
*/
protected $limiter;
/**
* Create a new controller instance.
*
* @param \Illuminate\Contracts\Auth\StatefulGuard $guard
* @param \Laravel\Fortify\LoginRateLimiter $limiter
* @return void
*/
public function __construct(StatefulGuard $guard, LoginRateLimiter $limiter)
{
$this->guard = $guard;
$this->limiter = $limiter;
}
/**
* Handle the incoming request.
*
* @param \Illuminate\Http\Request $request
* @param callable $next
* @return mixed
*/
public function handle($request, $next)
{
$user = $this->validateCredentials($request);
if (Fortify::confirmsTwoFactorAuthentication()) {
if (optional($user)->two_factor_secret &&
! is_null(optional($user)->two_factor_confirmed_at) &&
in_array(TwoFactorAuthenticatable::class, class_uses_recursive($user))) {
return $this->twoFactorChallengeResponse($request, $user);
} else {
return $next($request);
}
}
if (optional($user)->two_factor_secret &&
in_array(TwoFactorAuthenticatable::class, class_uses_recursive($user))) {
return $this->twoFactorChallengeResponse($request, $user);
}
return $next($request);
}
/**
* Attempt to validate the incoming credentials.
*
* @param \Illuminate\Http\Request $request
* @return mixed
*/
protected function validateCredentials($request)
{
if (Fortify::$authenticateUsingCallback) {
return tap(call_user_func(Fortify::$authenticateUsingCallback, $request), function ($user) use ($request) {
if (! $user) {
$this->fireFailedEvent($request);
$this->throwFailedAuthenticationException($request);
}
});
}
$model = $this->guard->getProvider()->getModel();
return tap($model::where(Fortify::username(), $request->{Fortify::username()})->first(), function ($user) use ($request) {
if (! $user || ! $this->guard->getProvider()->validateCredentials($user, ['password' => $request->password])) {
$this->fireFailedEvent($request, $user);
$this->throwFailedAuthenticationException($request);
}
if (config('hashing.rehash_on_login', true) && method_exists($this->guard->getProvider(), 'rehashPasswordIfRequired')) {
$this->guard->getProvider()->rehashPasswordIfRequired($user, ['password' => $request->password]);
}
});
}
/**
* Throw a failed authentication validation exception.
*
* @param \Illuminate\Http\Request $request
* @return void
*
* @throws \Illuminate\Validation\ValidationException
*/
protected function throwFailedAuthenticationException($request)
{
$this->limiter->increment($request);
throw ValidationException::withMessages([
Fortify::username() => [trans('auth.failed')],
]);
}
/**
* Fire the failed authentication attempt event with the given arguments.
*
* @param \Illuminate\Http\Request $request
* @param \Illuminate\Contracts\Auth\Authenticatable|null $user
* @return void
*/
protected function fireFailedEvent($request, $user = null)
{
event(new Failed($this->guard?->name ?? config('fortify.guard'), $user, [
Fortify::username() => $request->{Fortify::username()},
'password' => $request->password,
]));
}
/**
* Get the two factor authentication enabled response.
*
* @param \Illuminate\Http\Request $request
* @param mixed $user
* @return \Symfony\Component\HttpFoundation\Response
*/
protected function twoFactorChallengeResponse($request, $user)
{
$request->session()->put([
'login.id' => $user->getKey(),
'login.remember' => $request->boolean('remember'),
]);
TwoFactorAuthenticationChallenged::dispatch($user);
return $request->wantsJson()
? response()->json(['two_factor' => true])
: redirect()->route('two-factor.login');
}
}
+54
View File
@@ -0,0 +1,54 @@
<?php
namespace Laravel\Fortify\Console;
use Illuminate\Console\Command;
use Illuminate\Support\ServiceProvider;
use Laravel\Fortify\FortifyServiceProvider;
use Symfony\Component\Console\Attribute\AsCommand;
#[AsCommand(name: 'fortify:install')]
class InstallCommand extends Command
{
/**
* The name and signature of the console command.
*
* @var string
*/
protected $signature = 'fortify:install';
/**
* The console command description.
*
* @var string
*/
protected $description = 'Install all of the Fortify resources';
/**
* Execute the console command.
*
* @return void
*/
public function handle()
{
$this->callSilent('vendor:publish', [
'--provider' => FortifyServiceProvider::class,
]);
$this->registerFortifyServiceProvider();
$this->components->info('Fortify scaffolding installed successfully.');
}
/**
* Register the Fortify service provider in the application configuration file.
*/
protected function registerFortifyServiceProvider(): void
{
if (! method_exists(ServiceProvider::class, 'addProviderToBootstrapFile')) {
return;
}
ServiceProvider::addProviderToBootstrapFile(\App\Providers\FortifyServiceProvider::class);
}
}
@@ -0,0 +1,10 @@
<?php
namespace Laravel\Fortify\Contracts;
use Illuminate\Contracts\Support\Responsable;
interface ConfirmPasswordViewResponse extends Responsable
{
//
}
@@ -0,0 +1,14 @@
<?php
namespace Laravel\Fortify\Contracts;
interface CreatesNewUsers
{
/**
* Validate and create a newly registered user.
*
* @param array $input
* @return \Illuminate\Foundation\Auth\User
*/
public function create(array $input);
}
@@ -0,0 +1,10 @@
<?php
namespace Laravel\Fortify\Contracts;
use Illuminate\Contracts\Support\Responsable;
interface EmailVerificationNotificationSentResponse extends Responsable
{
//
}
@@ -0,0 +1,10 @@
<?php
namespace Laravel\Fortify\Contracts;
use Illuminate\Contracts\Support\Responsable;
interface FailedPasswordConfirmationResponse extends Responsable
{
//
}
@@ -0,0 +1,10 @@
<?php
namespace Laravel\Fortify\Contracts;
use Illuminate\Contracts\Support\Responsable;
interface FailedPasswordResetLinkRequestResponse extends Responsable
{
//
}
@@ -0,0 +1,10 @@
<?php
namespace Laravel\Fortify\Contracts;
use Illuminate\Contracts\Support\Responsable;
interface FailedPasswordResetResponse extends Responsable
{
//
}
@@ -0,0 +1,10 @@
<?php
namespace Laravel\Fortify\Contracts;
use Illuminate\Contracts\Support\Responsable;
interface FailedTwoFactorLoginResponse extends Responsable
{
//
}
@@ -0,0 +1,10 @@
<?php
namespace Laravel\Fortify\Contracts;
use Illuminate\Contracts\Support\Responsable;
interface LockoutResponse extends Responsable
{
//
}
+10
View File
@@ -0,0 +1,10 @@
<?php
namespace Laravel\Fortify\Contracts;
use Illuminate\Contracts\Support\Responsable;
interface LoginResponse extends Responsable
{
//
}
@@ -0,0 +1,10 @@
<?php
namespace Laravel\Fortify\Contracts;
use Illuminate\Contracts\Support\Responsable;
interface LoginViewResponse extends Responsable
{
//
}
+10
View File
@@ -0,0 +1,10 @@
<?php
namespace Laravel\Fortify\Contracts;
use Illuminate\Contracts\Support\Responsable;
interface LogoutResponse extends Responsable
{
//
}
@@ -0,0 +1,10 @@
<?php
namespace Laravel\Fortify\Contracts;
use Illuminate\Contracts\Support\Responsable;
interface PasswordConfirmedResponse extends Responsable
{
//
}
@@ -0,0 +1,10 @@
<?php
namespace Laravel\Fortify\Contracts;
use Illuminate\Contracts\Support\Responsable;
interface PasswordResetResponse extends Responsable
{
//
}
@@ -0,0 +1,10 @@
<?php
namespace Laravel\Fortify\Contracts;
use Illuminate\Contracts\Support\Responsable;
interface PasswordUpdateResponse extends Responsable
{
//
}
@@ -0,0 +1,10 @@
<?php
namespace Laravel\Fortify\Contracts;
use Illuminate\Contracts\Support\Responsable;
interface ProfileInformationUpdatedResponse extends Responsable
{
//
}
@@ -0,0 +1,10 @@
<?php
namespace Laravel\Fortify\Contracts;
use Illuminate\Contracts\Support\Responsable;
interface RecoveryCodesGeneratedResponse extends Responsable
{
//
}
@@ -0,0 +1,10 @@
<?php
namespace Laravel\Fortify\Contracts;
use Illuminate\Contracts\Support\Responsable;
interface RegisterResponse extends Responsable
{
//
}
@@ -0,0 +1,10 @@
<?php
namespace Laravel\Fortify\Contracts;
use Illuminate\Contracts\Support\Responsable;
interface RegisterViewResponse extends Responsable
{
//
}
@@ -0,0 +1,10 @@
<?php
namespace Laravel\Fortify\Contracts;
use Illuminate\Contracts\Support\Responsable;
interface RequestPasswordResetLinkViewResponse extends Responsable
{
//
}
@@ -0,0 +1,10 @@
<?php
namespace Laravel\Fortify\Contracts;
use Illuminate\Contracts\Support\Responsable;
interface ResetPasswordViewResponse extends Responsable
{
//
}
@@ -0,0 +1,11 @@
<?php
namespace Laravel\Fortify\Contracts;
/**
* @method void reset(\Illuminate\Foundation\Auth\User $user, array $input)
*/
interface ResetsUserPasswords
{
//
}
@@ -0,0 +1,10 @@
<?php
namespace Laravel\Fortify\Contracts;
use Illuminate\Contracts\Support\Responsable;
interface SuccessfulPasswordResetLinkRequestResponse extends Responsable
{
//
}
@@ -0,0 +1,32 @@
<?php
namespace Laravel\Fortify\Contracts;
interface TwoFactorAuthenticationProvider
{
/**
* Generate a new secret key.
*
* @return string
*/
public function generateSecretKey();
/**
* Get the two factor authentication QR code URL.
*
* @param string $companyName
* @param string $companyEmail
* @param string $secret
* @return string
*/
public function qrCodeUrl($companyName, $companyEmail, $secret);
/**
* Verify the given token.
*
* @param string $secret
* @param string $code
* @return bool
*/
public function verify($secret, $code);
}
@@ -0,0 +1,10 @@
<?php
namespace Laravel\Fortify\Contracts;
use Illuminate\Contracts\Support\Responsable;
interface TwoFactorChallengeViewResponse extends Responsable
{
//
}
@@ -0,0 +1,10 @@
<?php
namespace Laravel\Fortify\Contracts;
use Illuminate\Contracts\Support\Responsable;
interface TwoFactorConfirmedResponse extends Responsable
{
//
}
@@ -0,0 +1,10 @@
<?php
namespace Laravel\Fortify\Contracts;
use Illuminate\Contracts\Support\Responsable;
interface TwoFactorDisabledResponse extends Responsable
{
//
}
@@ -0,0 +1,10 @@
<?php
namespace Laravel\Fortify\Contracts;
use Illuminate\Contracts\Support\Responsable;
interface TwoFactorEnabledResponse extends Responsable
{
//
}
@@ -0,0 +1,10 @@
<?php
namespace Laravel\Fortify\Contracts;
use Illuminate\Contracts\Support\Responsable;
interface TwoFactorLoginResponse extends Responsable
{
//
}
@@ -0,0 +1,11 @@
<?php
namespace Laravel\Fortify\Contracts;
/**
* @method void update(\Illuminate\Foundation\Auth\User $user, array $input)
*/
interface UpdatesUserPasswords
{
//
}
@@ -0,0 +1,11 @@
<?php
namespace Laravel\Fortify\Contracts;
/**
* @method void update(\Illuminate\Foundation\Auth\User $user, array $input)
*/
interface UpdatesUserProfileInformation
{
//
}
@@ -0,0 +1,10 @@
<?php
namespace Laravel\Fortify\Contracts;
use Illuminate\Contracts\Support\Responsable;
interface VerifyEmailResponse extends Responsable
{
//
}
@@ -0,0 +1,10 @@
<?php
namespace Laravel\Fortify\Contracts;
use Illuminate\Contracts\Support\Responsable;
interface VerifyEmailViewResponse extends Responsable
{
//
}
@@ -0,0 +1,28 @@
<?php
namespace Laravel\Fortify\Events;
use Illuminate\Foundation\Events\Dispatchable;
class PasswordUpdatedViaController
{
use Dispatchable;
/**
* The user instance.
*
* @var \App\Models\User
*/
public $user;
/**
* Create a new event instance.
*
* @param \App\Models\User $user
* @return void
*/
public function __construct($user)
{
$this->user = $user;
}
}
@@ -0,0 +1,37 @@
<?php
namespace Laravel\Fortify\Events;
use Illuminate\Queue\SerializesModels;
class RecoveryCodeReplaced
{
use SerializesModels;
/**
* The authenticated user.
*
* @var \Illuminate\Contracts\Auth\Authenticatable
*/
public $user;
/**
* The recovery code.
*
* @var string
*/
public $code;
/**
* Create a new event instance.
*
* @param \Illuminate\Contracts\Auth\Authenticatable $user
* @param string $code
* @return void
*/
public function __construct($user, $code)
{
$this->user = $user;
$this->code = $code;
}
}
@@ -0,0 +1,28 @@
<?php
namespace Laravel\Fortify\Events;
use Illuminate\Foundation\Events\Dispatchable;
class RecoveryCodesGenerated
{
use Dispatchable;
/**
* The user instance.
*
* @var \App\Models\User
*/
public $user;
/**
* Create a new event instance.
*
* @param \App\Models\User $user
* @return void
*/
public function __construct($user)
{
$this->user = $user;
}
}
@@ -0,0 +1,8 @@
<?php
namespace Laravel\Fortify\Events;
class TwoFactorAuthenticationChallenged extends TwoFactorAuthenticationEvent
{
//
}
@@ -0,0 +1,8 @@
<?php
namespace Laravel\Fortify\Events;
class TwoFactorAuthenticationConfirmed extends TwoFactorAuthenticationEvent
{
//
}
@@ -0,0 +1,8 @@
<?php
namespace Laravel\Fortify\Events;
class TwoFactorAuthenticationDisabled extends TwoFactorAuthenticationEvent
{
//
}
@@ -0,0 +1,8 @@
<?php
namespace Laravel\Fortify\Events;
class TwoFactorAuthenticationEnabled extends TwoFactorAuthenticationEvent
{
//
}
@@ -0,0 +1,28 @@
<?php
namespace Laravel\Fortify\Events;
use Illuminate\Foundation\Events\Dispatchable;
abstract class TwoFactorAuthenticationEvent
{
use Dispatchable;
/**
* The user instance.
*
* @var \App\Models\User
*/
public $user;
/**
* Create a new event instance.
*
* @param \App\Models\User $user
* @return void
*/
public function __construct($user)
{
$this->user = $user;
}
}
@@ -0,0 +1,8 @@
<?php
namespace Laravel\Fortify\Events;
class TwoFactorAuthenticationFailed extends TwoFactorAuthenticationEvent
{
//
}
+138
View File
@@ -0,0 +1,138 @@
<?php
namespace Laravel\Fortify;
class Features
{
/**
* Determine if the given feature is enabled.
*
* @param string $feature
* @return bool
*/
public static function enabled(string $feature)
{
return in_array($feature, config('fortify.features', []));
}
/**
* Determine if the feature is enabled and has a given option enabled.
*
* @param string $feature
* @param string $option
* @return bool
*/
public static function optionEnabled(string $feature, string $option)
{
return static::enabled($feature) &&
config("fortify-options.{$feature}.{$option}") === true;
}
/**
* Determine if the application is using any features that require "profile" management.
*
* @return bool
*/
public static function hasProfileFeatures()
{
return static::enabled(static::updateProfileInformation()) ||
static::enabled(static::updatePasswords()) ||
static::enabled(static::twoFactorAuthentication());
}
/**
* Determine if the application can update a user's profile information.
*
* @return bool
*/
public static function canUpdateProfileInformation()
{
return static::enabled(static::updateProfileInformation());
}
/**
* Determine if the application is using any security profile features.
*
* @return bool
*/
public static function hasSecurityFeatures()
{
return static::enabled(static::updatePasswords()) ||
static::canManageTwoFactorAuthentication();
}
/**
* Determine if the application can manage two factor authentication.
*
* @return bool
*/
public static function canManageTwoFactorAuthentication()
{
return static::enabled(static::twoFactorAuthentication());
}
/**
* Enable the registration feature.
*
* @return string
*/
public static function registration()
{
return 'registration';
}
/**
* Enable the password reset feature.
*
* @return string
*/
public static function resetPasswords()
{
return 'reset-passwords';
}
/**
* Enable the email verification feature.
*
* @return string
*/
public static function emailVerification()
{
return 'email-verification';
}
/**
* Enable the update profile information feature.
*
* @return string
*/
public static function updateProfileInformation()
{
return 'update-profile-information';
}
/**
* Enable the update password feature.
*
* @return string
*/
public static function updatePasswords()
{
return 'update-passwords';
}
/**
* Enable the two factor authentication feature.
*
* @param array $options
* @return string
*/
public static function twoFactorAuthentication(array $options = [])
{
if (! empty($options)) {
config(['fortify-options.two-factor-authentication' => $options]);
}
return 'two-factor-authentication';
}
}
+316
View File
@@ -0,0 +1,316 @@
<?php
namespace Laravel\Fortify;
use Laravel\Fortify\Contracts\ConfirmPasswordViewResponse;
use Laravel\Fortify\Contracts\CreatesNewUsers;
use Laravel\Fortify\Contracts\LoginViewResponse;
use Laravel\Fortify\Contracts\RegisterViewResponse;
use Laravel\Fortify\Contracts\RequestPasswordResetLinkViewResponse;
use Laravel\Fortify\Contracts\ResetPasswordViewResponse;
use Laravel\Fortify\Contracts\ResetsUserPasswords;
use Laravel\Fortify\Contracts\TwoFactorChallengeViewResponse;
use Laravel\Fortify\Contracts\UpdatesUserPasswords;
use Laravel\Fortify\Contracts\UpdatesUserProfileInformation;
use Laravel\Fortify\Contracts\VerifyEmailViewResponse;
use Laravel\Fortify\Http\Responses\SimpleViewResponse;
class Fortify
{
/**
* The callback that is responsible for building the authentication pipeline array, if applicable.
*
* @var callable|null
*/
public static $authenticateThroughCallback;
/**
* The callback that is responsible for validating authentication credentials, if applicable.
*
* @var callable|null
*/
public static $authenticateUsingCallback;
/**
* The callback that is responsible for confirming user passwords.
*
* @var callable|null
*/
public static $confirmPasswordsUsingCallback;
/**
* Indicates if Fortify routes will be registered.
*
* @var bool
*/
public static $registersRoutes = true;
const PASSWORD_UPDATED = 'password-updated';
const PROFILE_INFORMATION_UPDATED = 'profile-information-updated';
const RECOVERY_CODES_GENERATED = 'recovery-codes-generated';
const TWO_FACTOR_AUTHENTICATION_CONFIRMED = 'two-factor-authentication-confirmed';
const TWO_FACTOR_AUTHENTICATION_DISABLED = 'two-factor-authentication-disabled';
const TWO_FACTOR_AUTHENTICATION_ENABLED = 'two-factor-authentication-enabled';
const VERIFICATION_LINK_SENT = 'verification-link-sent';
/**
* Get the username used for authentication.
*
* @return string
*/
public static function username()
{
return config('fortify.username', 'email');
}
/**
* Get the name of the email address request variable / field.
*
* @return string
*/
public static function email()
{
return config('fortify.email', 'email');
}
/**
* Get a completion redirect path for a specific feature.
*
* @param string $redirect
* @return string
*/
public static function redirects(string $redirect, $default = null)
{
return config('fortify.redirects.'.$redirect) ?? $default ?? config('fortify.home');
}
/**
* Register the views for Fortify using conventional names under the given namespace.
*
* @param string $namespace
* @return void
*/
public static function viewNamespace(string $namespace)
{
static::viewPrefix($namespace.'::');
}
/**
* Register the views for Fortify using conventional names under the given prefix.
*
* @param string $prefix
* @return void
*/
public static function viewPrefix(string $prefix)
{
static::loginView($prefix.'login');
static::twoFactorChallengeView($prefix.'two-factor-challenge');
static::registerView($prefix.'register');
static::requestPasswordResetLinkView($prefix.'forgot-password');
static::resetPasswordView($prefix.'reset-password');
static::verifyEmailView($prefix.'verify-email');
static::confirmPasswordView($prefix.'confirm-password');
}
/**
* Specify which view should be used as the login view.
*
* @param callable|string $view
* @return void
*/
public static function loginView($view)
{
app()->singleton(LoginViewResponse::class, function () use ($view) {
return new SimpleViewResponse($view);
});
}
/**
* Specify which view should be used as the two factor authentication challenge view.
*
* @param callable|string $view
* @return void
*/
public static function twoFactorChallengeView($view)
{
app()->singleton(TwoFactorChallengeViewResponse::class, function () use ($view) {
return new SimpleViewResponse($view);
});
}
/**
* Specify which view should be used as the new password view.
*
* @param callable|string $view
* @return void
*/
public static function resetPasswordView($view)
{
app()->singleton(ResetPasswordViewResponse::class, function () use ($view) {
return new SimpleViewResponse($view);
});
}
/**
* Specify which view should be used as the registration view.
*
* @param callable|string $view
* @return void
*/
public static function registerView($view)
{
app()->singleton(RegisterViewResponse::class, function () use ($view) {
return new SimpleViewResponse($view);
});
}
/**
* Specify which view should be used as the email verification prompt.
*
* @param callable|string $view
* @return void
*/
public static function verifyEmailView($view)
{
app()->singleton(VerifyEmailViewResponse::class, function () use ($view) {
return new SimpleViewResponse($view);
});
}
/**
* Specify which view should be used as the password confirmation prompt.
*
* @param callable|string $view
* @return void
*/
public static function confirmPasswordView($view)
{
app()->singleton(ConfirmPasswordViewResponse::class, function () use ($view) {
return new SimpleViewResponse($view);
});
}
/**
* Specify which view should be used as the request password reset link view.
*
* @param callable|string $view
* @return void
*/
public static function requestPasswordResetLinkView($view)
{
app()->singleton(RequestPasswordResetLinkViewResponse::class, function () use ($view) {
return new SimpleViewResponse($view);
});
}
/**
* Register a callback that is responsible for building the authentication pipeline array.
*
* @param callable $callback
* @return void
*/
public static function loginThrough(callable $callback)
{
static::authenticateThrough($callback);
}
/**
* Register a callback that is responsible for building the authentication pipeline array.
*
* @param callable $callback
* @return void
*/
public static function authenticateThrough(callable $callback)
{
static::$authenticateThroughCallback = $callback;
}
/**
* Register a callback that is responsible for validating incoming authentication credentials.
*
* @param callable $callback
* @return void
*/
public static function authenticateUsing(callable $callback)
{
static::$authenticateUsingCallback = $callback;
}
/**
* Register a callback that is responsible for confirming existing user passwords as valid.
*
* @param callable $callback
* @return void
*/
public static function confirmPasswordsUsing(callable $callback)
{
static::$confirmPasswordsUsingCallback = $callback;
}
/**
* Register a class / callback that should be used to create new users.
*
* @param string $callback
* @return void
*/
public static function createUsersUsing(string $callback)
{
app()->singleton(CreatesNewUsers::class, $callback);
}
/**
* Register a class / callback that should be used to update user profile information.
*
* @param string $callback
* @return void
*/
public static function updateUserProfileInformationUsing(string $callback)
{
app()->singleton(UpdatesUserProfileInformation::class, $callback);
}
/**
* Register a class / callback that should be used to update user passwords.
*
* @param string $callback
* @return void
*/
public static function updateUserPasswordsUsing(string $callback)
{
app()->singleton(UpdatesUserPasswords::class, $callback);
}
/**
* Register a class / callback that should be used to reset user passwords.
*
* @param string $callback
* @return void
*/
public static function resetUserPasswordsUsing(string $callback)
{
app()->singleton(ResetsUserPasswords::class, $callback);
}
/**
* Determine if Fortify is confirming two factor authentication configurations.
*
* @return bool
*/
public static function confirmsTwoFactorAuthentication()
{
return Features::enabled(Features::twoFactorAuthentication()) &&
Features::optionEnabled(Features::twoFactorAuthentication(), 'confirm');
}
/**
* Configure Fortify to not register its routes.
*
* @return static
*/
public static function ignoreRoutes()
{
static::$registersRoutes = false;
return new static;
}
}
+177
View File
@@ -0,0 +1,177 @@
<?php
namespace Laravel\Fortify;
use Illuminate\Contracts\Auth\StatefulGuard;
use Illuminate\Contracts\Cache\Repository;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\Route;
use Illuminate\Support\ServiceProvider;
use Laravel\Fortify\Contracts\EmailVerificationNotificationSentResponse as EmailVerificationNotificationSentResponseContract;
use Laravel\Fortify\Contracts\FailedPasswordConfirmationResponse as FailedPasswordConfirmationResponseContract;
use Laravel\Fortify\Contracts\FailedPasswordResetLinkRequestResponse as FailedPasswordResetLinkRequestResponseContract;
use Laravel\Fortify\Contracts\FailedPasswordResetResponse as FailedPasswordResetResponseContract;
use Laravel\Fortify\Contracts\FailedTwoFactorLoginResponse as FailedTwoFactorLoginResponseContract;
use Laravel\Fortify\Contracts\LockoutResponse as LockoutResponseContract;
use Laravel\Fortify\Contracts\LoginResponse as LoginResponseContract;
use Laravel\Fortify\Contracts\LogoutResponse as LogoutResponseContract;
use Laravel\Fortify\Contracts\PasswordConfirmedResponse as PasswordConfirmedResponseContract;
use Laravel\Fortify\Contracts\PasswordResetResponse as PasswordResetResponseContract;
use Laravel\Fortify\Contracts\PasswordUpdateResponse as PasswordUpdateResponseContract;
use Laravel\Fortify\Contracts\ProfileInformationUpdatedResponse as ProfileInformationUpdatedResponseContract;
use Laravel\Fortify\Contracts\RecoveryCodesGeneratedResponse as RecoveryCodesGeneratedResponseContract;
use Laravel\Fortify\Contracts\RegisterResponse as RegisterResponseContract;
use Laravel\Fortify\Contracts\SuccessfulPasswordResetLinkRequestResponse as SuccessfulPasswordResetLinkRequestResponseContract;
use Laravel\Fortify\Contracts\TwoFactorAuthenticationProvider as TwoFactorAuthenticationProviderContract;
use Laravel\Fortify\Contracts\TwoFactorConfirmedResponse as TwoFactorConfirmedResponseContract;
use Laravel\Fortify\Contracts\TwoFactorDisabledResponse as TwoFactorDisabledResponseContract;
use Laravel\Fortify\Contracts\TwoFactorEnabledResponse as TwoFactorEnabledResponseContract;
use Laravel\Fortify\Contracts\TwoFactorLoginResponse as TwoFactorLoginResponseContract;
use Laravel\Fortify\Contracts\VerifyEmailResponse as VerifyEmailResponseContract;
use Laravel\Fortify\Http\Responses\EmailVerificationNotificationSentResponse;
use Laravel\Fortify\Http\Responses\FailedPasswordConfirmationResponse;
use Laravel\Fortify\Http\Responses\FailedPasswordResetLinkRequestResponse;
use Laravel\Fortify\Http\Responses\FailedPasswordResetResponse;
use Laravel\Fortify\Http\Responses\FailedTwoFactorLoginResponse;
use Laravel\Fortify\Http\Responses\LockoutResponse;
use Laravel\Fortify\Http\Responses\LoginResponse;
use Laravel\Fortify\Http\Responses\LogoutResponse;
use Laravel\Fortify\Http\Responses\PasswordConfirmedResponse;
use Laravel\Fortify\Http\Responses\PasswordResetResponse;
use Laravel\Fortify\Http\Responses\PasswordUpdateResponse;
use Laravel\Fortify\Http\Responses\ProfileInformationUpdatedResponse;
use Laravel\Fortify\Http\Responses\RecoveryCodesGeneratedResponse;
use Laravel\Fortify\Http\Responses\RegisterResponse;
use Laravel\Fortify\Http\Responses\SuccessfulPasswordResetLinkRequestResponse;
use Laravel\Fortify\Http\Responses\TwoFactorConfirmedResponse;
use Laravel\Fortify\Http\Responses\TwoFactorDisabledResponse;
use Laravel\Fortify\Http\Responses\TwoFactorEnabledResponse;
use Laravel\Fortify\Http\Responses\TwoFactorLoginResponse;
use Laravel\Fortify\Http\Responses\VerifyEmailResponse;
use PragmaRX\Google2FA\Google2FA;
class FortifyServiceProvider extends ServiceProvider
{
/**
* Register any application services.
*
* @return void
*/
public function register()
{
$this->mergeConfigFrom(__DIR__.'/../config/fortify.php', 'fortify');
$this->registerResponseBindings();
$this->app->singleton(TwoFactorAuthenticationProviderContract::class, function ($app) {
return new TwoFactorAuthenticationProvider(
$app->make(Google2FA::class),
$app->make(Repository::class)
);
});
$this->app->bind(StatefulGuard::class, function () {
return Auth::guard(config('fortify.guard', null));
});
}
/**
* Register the response bindings.
*
* @return void
*/
protected function registerResponseBindings()
{
$this->app->singleton(FailedPasswordConfirmationResponseContract::class, FailedPasswordConfirmationResponse::class);
$this->app->singleton(FailedPasswordResetLinkRequestResponseContract::class, FailedPasswordResetLinkRequestResponse::class);
$this->app->singleton(FailedPasswordResetResponseContract::class, FailedPasswordResetResponse::class);
$this->app->singleton(FailedTwoFactorLoginResponseContract::class, FailedTwoFactorLoginResponse::class);
$this->app->singleton(LockoutResponseContract::class, LockoutResponse::class);
$this->app->singleton(LoginResponseContract::class, LoginResponse::class);
$this->app->singleton(LogoutResponseContract::class, LogoutResponse::class);
$this->app->singleton(PasswordConfirmedResponseContract::class, PasswordConfirmedResponse::class);
$this->app->singleton(PasswordResetResponseContract::class, PasswordResetResponse::class);
$this->app->singleton(PasswordUpdateResponseContract::class, PasswordUpdateResponse::class);
$this->app->singleton(ProfileInformationUpdatedResponseContract::class, ProfileInformationUpdatedResponse::class);
$this->app->singleton(RecoveryCodesGeneratedResponseContract::class, RecoveryCodesGeneratedResponse::class);
$this->app->singleton(RegisterResponseContract::class, RegisterResponse::class);
$this->app->singleton(EmailVerificationNotificationSentResponseContract::class, EmailVerificationNotificationSentResponse::class);
$this->app->singleton(SuccessfulPasswordResetLinkRequestResponseContract::class, SuccessfulPasswordResetLinkRequestResponse::class);
$this->app->singleton(TwoFactorConfirmedResponseContract::class, TwoFactorConfirmedResponse::class);
$this->app->singleton(TwoFactorDisabledResponseContract::class, TwoFactorDisabledResponse::class);
$this->app->singleton(TwoFactorEnabledResponseContract::class, TwoFactorEnabledResponse::class);
$this->app->singleton(TwoFactorLoginResponseContract::class, TwoFactorLoginResponse::class);
$this->app->singleton(VerifyEmailResponseContract::class, VerifyEmailResponse::class);
}
/**
* Bootstrap any application services.
*
* @return void
*/
public function boot()
{
$this->configurePublishing();
$this->configureRoutes();
$this->registerCommands();
}
/**
* Configure the publishable resources offered by the package.
*
* @return void
*/
protected function configurePublishing()
{
if ($this->app->runningInConsole()) {
$this->publishes([
__DIR__.'/../stubs/fortify.php' => config_path('fortify.php'),
], 'fortify-config');
$this->publishes([
__DIR__.'/../stubs/CreateNewUser.php' => app_path('Actions/Fortify/CreateNewUser.php'),
__DIR__.'/../stubs/FortifyServiceProvider.php' => app_path('Providers/FortifyServiceProvider.php'),
__DIR__.'/../stubs/PasswordValidationRules.php' => app_path('Actions/Fortify/PasswordValidationRules.php'),
__DIR__.'/../stubs/ResetUserPassword.php' => app_path('Actions/Fortify/ResetUserPassword.php'),
__DIR__.'/../stubs/UpdateUserProfileInformation.php' => app_path('Actions/Fortify/UpdateUserProfileInformation.php'),
__DIR__.'/../stubs/UpdateUserPassword.php' => app_path('Actions/Fortify/UpdateUserPassword.php'),
], 'fortify-support');
$method = method_exists($this, 'publishesMigrations') ? 'publishesMigrations' : 'publishes';
$this->{$method}([
__DIR__.'/../database/migrations' => database_path('migrations'),
], 'fortify-migrations');
}
}
/**
* Configure the routes offered by the application.
*
* @return void
*/
protected function configureRoutes()
{
if (Fortify::$registersRoutes) {
Route::group([
'namespace' => 'Laravel\Fortify\Http\Controllers',
'domain' => config('fortify.domain', null),
'prefix' => config('fortify.prefix'),
], function () {
$this->loadRoutesFrom(__DIR__.'/../routes/routes.php');
});
}
}
/**
* Register the package's commands.
*/
protected function registerCommands(): void
{
if ($this->app->runningInConsole()) {
$this->commands([
Console\InstallCommand::class,
]);
}
}
}
@@ -0,0 +1,111 @@
<?php
namespace Laravel\Fortify\Http\Controllers;
use Illuminate\Contracts\Auth\StatefulGuard;
use Illuminate\Http\Request;
use Illuminate\Routing\Controller;
use Illuminate\Routing\Pipeline;
use Laravel\Fortify\Actions\AttemptToAuthenticate;
use Laravel\Fortify\Actions\CanonicalizeUsername;
use Laravel\Fortify\Actions\EnsureLoginIsNotThrottled;
use Laravel\Fortify\Actions\PrepareAuthenticatedSession;
use Laravel\Fortify\Actions\RedirectIfTwoFactorAuthenticatable;
use Laravel\Fortify\Contracts\LoginResponse;
use Laravel\Fortify\Contracts\LoginViewResponse;
use Laravel\Fortify\Contracts\LogoutResponse;
use Laravel\Fortify\Features;
use Laravel\Fortify\Fortify;
use Laravel\Fortify\Http\Requests\LoginRequest;
class AuthenticatedSessionController extends Controller
{
/**
* The guard implementation.
*
* @var \Illuminate\Contracts\Auth\StatefulGuard
*/
protected $guard;
/**
* Create a new controller instance.
*
* @param \Illuminate\Contracts\Auth\StatefulGuard $guard
* @return void
*/
public function __construct(StatefulGuard $guard)
{
$this->guard = $guard;
}
/**
* Show the login view.
*
* @param \Illuminate\Http\Request $request
* @return \Laravel\Fortify\Contracts\LoginViewResponse
*/
public function create(Request $request): LoginViewResponse
{
return app(LoginViewResponse::class);
}
/**
* Attempt to authenticate a new session.
*
* @param \Laravel\Fortify\Http\Requests\LoginRequest $request
* @return mixed
*/
public function store(LoginRequest $request)
{
return $this->loginPipeline($request)->then(function ($request) {
return app(LoginResponse::class);
});
}
/**
* Get the authentication pipeline instance.
*
* @param \Laravel\Fortify\Http\Requests\LoginRequest $request
* @return \Illuminate\Pipeline\Pipeline
*/
protected function loginPipeline(LoginRequest $request)
{
if (Fortify::$authenticateThroughCallback) {
return (new Pipeline(app()))->send($request)->through(array_filter(
call_user_func(Fortify::$authenticateThroughCallback, $request)
));
}
if (is_array(config('fortify.pipelines.login'))) {
return (new Pipeline(app()))->send($request)->through(array_filter(
config('fortify.pipelines.login')
));
}
return (new Pipeline(app()))->send($request)->through(array_filter([
config('fortify.limiters.login') ? null : EnsureLoginIsNotThrottled::class,
config('fortify.lowercase_usernames') ? CanonicalizeUsername::class : null,
Features::enabled(Features::twoFactorAuthentication()) ? RedirectIfTwoFactorAuthenticatable::class : null,
AttemptToAuthenticate::class,
PrepareAuthenticatedSession::class,
]));
}
/**
* Destroy an authenticated session.
*
* @param \Illuminate\Http\Request $request
* @return \Laravel\Fortify\Contracts\LogoutResponse
*/
public function destroy(Request $request): LogoutResponse
{
$this->guard->logout();
if ($request->hasSession()) {
$request->session()->invalidate();
$request->session()->regenerateToken();
}
return app(LogoutResponse::class);
}
}
@@ -0,0 +1,65 @@
<?php
namespace Laravel\Fortify\Http\Controllers;
use Illuminate\Contracts\Auth\StatefulGuard;
use Illuminate\Http\Request;
use Illuminate\Routing\Controller;
use Illuminate\Support\Facades\Date;
use Laravel\Fortify\Actions\ConfirmPassword;
use Laravel\Fortify\Contracts\ConfirmPasswordViewResponse;
use Laravel\Fortify\Contracts\FailedPasswordConfirmationResponse;
use Laravel\Fortify\Contracts\PasswordConfirmedResponse;
class ConfirmablePasswordController extends Controller
{
/**
* The guard implementation.
*
* @var \Illuminate\Contracts\Auth\StatefulGuard
*/
protected $guard;
/**
* Create a new controller instance.
*
* @param \Illuminate\Contracts\Auth\StatefulGuard $guard
* @return void
*/
public function __construct(StatefulGuard $guard)
{
$this->guard = $guard;
}
/**
* Show the confirm password view.
*
* @param \Illuminate\Http\Request $request
* @return \Laravel\Fortify\Contracts\ConfirmPasswordViewResponse
*/
public function show(Request $request)
{
return app(ConfirmPasswordViewResponse::class);
}
/**
* Confirm the user's password.
*
* @param \Illuminate\Http\Request $request
* @return \Illuminate\Contracts\Support\Responsable
*/
public function store(Request $request)
{
$confirmed = app(ConfirmPassword::class)(
$this->guard, $request->user(), $request->input('password')
);
if ($confirmed) {
$request->session()->put('auth.password_confirmed_at', Date::now()->unix());
}
return $confirmed
? app(PasswordConfirmedResponse::class)
: app(FailedPasswordConfirmationResponse::class);
}
}
@@ -0,0 +1,22 @@
<?php
namespace Laravel\Fortify\Http\Controllers;
use Illuminate\Http\Request;
use Illuminate\Routing\Controller;
class ConfirmedPasswordStatusController extends Controller
{
/**
* Get the password confirmation status.
*
* @param \Illuminate\Http\Request $request
* @return \Illuminate\Http\JsonResponse
*/
public function show(Request $request)
{
return response()->json([
'confirmed' => (time() - $request->session()->get('auth.password_confirmed_at', 0)) < $request->input('seconds', config('auth.password_timeout', 900)),
]);
}
}
@@ -0,0 +1,25 @@
<?php
namespace Laravel\Fortify\Http\Controllers;
use Illuminate\Http\Request;
use Illuminate\Routing\Controller;
use Laravel\Fortify\Actions\ConfirmTwoFactorAuthentication;
use Laravel\Fortify\Contracts\TwoFactorConfirmedResponse;
class ConfirmedTwoFactorAuthenticationController extends Controller
{
/**
* Enable two factor authentication for the user.
*
* @param \Illuminate\Http\Request $request
* @param \Laravel\Fortify\Actions\ConfirmTwoFactorAuthentication $confirm
* @return \Laravel\Fortify\Contracts\TwoFactorConfirmedResponse
*/
public function store(Request $request, ConfirmTwoFactorAuthentication $confirm)
{
$confirm($request->user(), $request->input('code'));
return app(TwoFactorConfirmedResponse::class);
}
}
@@ -0,0 +1,31 @@
<?php
namespace Laravel\Fortify\Http\Controllers;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
use Illuminate\Routing\Controller;
use Laravel\Fortify\Contracts\EmailVerificationNotificationSentResponse;
use Laravel\Fortify\Http\Responses\RedirectAsIntended;
class EmailVerificationNotificationController extends Controller
{
/**
* Send a new email verification notification.
*
* @param \Illuminate\Http\Request $request
* @return \Illuminate\Http\Response
*/
public function store(Request $request)
{
if ($request->user()->hasVerifiedEmail()) {
return $request->wantsJson()
? new JsonResponse('', 204)
: app(RedirectAsIntended::class, ['name' => 'email-verification']);
}
$request->user()->sendEmailVerificationNotification();
return app(EmailVerificationNotificationSentResponse::class);
}
}
@@ -0,0 +1,24 @@
<?php
namespace Laravel\Fortify\Http\Controllers;
use Illuminate\Http\Request;
use Illuminate\Routing\Controller;
use Laravel\Fortify\Contracts\VerifyEmailViewResponse;
use Laravel\Fortify\Http\Responses\RedirectAsIntended;
class EmailVerificationPromptController extends Controller
{
/**
* Display the email verification prompt.
*
* @param \Illuminate\Http\Request $request
* @return \Laravel\Fortify\Contracts\VerifyEmailViewResponse
*/
public function __invoke(Request $request)
{
return $request->user()->hasVerifiedEmail()
? app(RedirectAsIntended::class, ['name' => 'email-verification'])
: app(VerifyEmailViewResponse::class);
}
}
@@ -0,0 +1,92 @@
<?php
namespace Laravel\Fortify\Http\Controllers;
use Illuminate\Contracts\Auth\PasswordBroker;
use Illuminate\Contracts\Auth\StatefulGuard;
use Illuminate\Contracts\Support\Responsable;
use Illuminate\Http\Request;
use Illuminate\Routing\Controller;
use Illuminate\Support\Facades\Password;
use Laravel\Fortify\Actions\CompletePasswordReset;
use Laravel\Fortify\Contracts\FailedPasswordResetResponse;
use Laravel\Fortify\Contracts\PasswordResetResponse;
use Laravel\Fortify\Contracts\ResetPasswordViewResponse;
use Laravel\Fortify\Contracts\ResetsUserPasswords;
use Laravel\Fortify\Fortify;
class NewPasswordController extends Controller
{
/**
* The guard implementation.
*
* @var \Illuminate\Contracts\Auth\StatefulGuard
*/
protected $guard;
/**
* Create a new controller instance.
*
* @param \Illuminate\Contracts\Auth\StatefulGuard $guard
* @return void
*/
public function __construct(StatefulGuard $guard)
{
$this->guard = $guard;
}
/**
* Show the new password view.
*
* @param \Illuminate\Http\Request $request
* @return \Laravel\Fortify\Contracts\ResetPasswordViewResponse
*/
public function create(Request $request): ResetPasswordViewResponse
{
return app(ResetPasswordViewResponse::class);
}
/**
* Reset the user's password.
*
* @param \Illuminate\Http\Request $request
* @return \Illuminate\Contracts\Support\Responsable
*/
public function store(Request $request): Responsable
{
$request->validate([
'token' => 'required',
Fortify::email() => 'required|email',
'password' => 'required',
]);
// Here we will attempt to reset the user's password. If it is successful we
// will update the password on an actual user model and persist it to the
// database. Otherwise we will parse the error and return the response.
$status = $this->broker()->reset(
$request->only(Fortify::email(), 'password', 'password_confirmation', 'token'),
function ($user) use ($request) {
app(ResetsUserPasswords::class)->reset($user, $request->all());
app(CompletePasswordReset::class)($this->guard, $user);
}
);
// If the password was successfully reset, we will redirect the user back to
// the application's home authenticated view. If there is an error we can
// redirect them back to where they came from with their error message.
return $status == Password::PASSWORD_RESET
? app(PasswordResetResponse::class, ['status' => $status])
: app(FailedPasswordResetResponse::class, ['status' => $status]);
}
/**
* Get the broker to be used during password reset.
*
* @return \Illuminate\Contracts\Auth\PasswordBroker
*/
protected function broker(): PasswordBroker
{
return Password::broker(config('fortify.passwords'));
}
}
@@ -0,0 +1,28 @@
<?php
namespace Laravel\Fortify\Http\Controllers;
use Illuminate\Http\Request;
use Illuminate\Routing\Controller;
use Laravel\Fortify\Contracts\PasswordUpdateResponse;
use Laravel\Fortify\Contracts\UpdatesUserPasswords;
use Laravel\Fortify\Events\PasswordUpdatedViaController;
class PasswordController extends Controller
{
/**
* Update the user's password.
*
* @param \Illuminate\Http\Request $request
* @param \Laravel\Fortify\Contracts\UpdatesUserPasswords $updater
* @return \Laravel\Fortify\Contracts\PasswordUpdateResponse
*/
public function update(Request $request, UpdatesUserPasswords $updater)
{
$updater->update($request->user(), $request->all());
event(new PasswordUpdatedViaController($request->user()));
return app(PasswordUpdateResponse::class);
}
}
@@ -0,0 +1,59 @@
<?php
namespace Laravel\Fortify\Http\Controllers;
use Illuminate\Contracts\Auth\PasswordBroker;
use Illuminate\Contracts\Support\Responsable;
use Illuminate\Http\Request;
use Illuminate\Routing\Controller;
use Illuminate\Support\Facades\Password;
use Laravel\Fortify\Contracts\FailedPasswordResetLinkRequestResponse;
use Laravel\Fortify\Contracts\RequestPasswordResetLinkViewResponse;
use Laravel\Fortify\Contracts\SuccessfulPasswordResetLinkRequestResponse;
use Laravel\Fortify\Fortify;
class PasswordResetLinkController extends Controller
{
/**
* Show the reset password link request view.
*
* @param \Illuminate\Http\Request $request
* @return \Laravel\Fortify\Contracts\RequestPasswordResetLinkViewResponse
*/
public function create(Request $request): RequestPasswordResetLinkViewResponse
{
return app(RequestPasswordResetLinkViewResponse::class);
}
/**
* Send a reset link to the given user.
*
* @param \Illuminate\Http\Request $request
* @return \Illuminate\Contracts\Support\Responsable
*/
public function store(Request $request): Responsable
{
$request->validate([Fortify::email() => 'required|email']);
// We will send the password reset link to this user. Once we have attempted
// to send the link, we will examine the response then see the message we
// need to show to the user. Finally, we'll send out a proper response.
$status = $this->broker()->sendResetLink(
$request->only(Fortify::email())
);
return $status == Password::RESET_LINK_SENT
? app(SuccessfulPasswordResetLinkRequestResponse::class, ['status' => $status])
: app(FailedPasswordResetLinkRequestResponse::class, ['status' => $status]);
}
/**
* Get the broker to be used during password reset.
*
* @return \Illuminate\Contracts\Auth\PasswordBroker
*/
protected function broker(): PasswordBroker
{
return Password::broker(config('fortify.passwords'));
}
}
@@ -0,0 +1,34 @@
<?php
namespace Laravel\Fortify\Http\Controllers;
use Illuminate\Http\Request;
use Illuminate\Routing\Controller;
use Illuminate\Support\Str;
use Laravel\Fortify\Contracts\ProfileInformationUpdatedResponse;
use Laravel\Fortify\Contracts\UpdatesUserProfileInformation;
use Laravel\Fortify\Fortify;
class ProfileInformationController extends Controller
{
/**
* Update the user's profile information.
*
* @param \Illuminate\Http\Request $request
* @param \Laravel\Fortify\Contracts\UpdatesUserProfileInformation $updater
* @return \Laravel\Fortify\Contracts\ProfileInformationUpdatedResponse
*/
public function update(Request $request,
UpdatesUserProfileInformation $updater)
{
if (config('fortify.lowercase_usernames')) {
$request->merge([
Fortify::username() => Str::lower($request->{Fortify::username()}),
]);
}
$updater->update($request->user(), $request->all());
return app(ProfileInformationUpdatedResponse::class);
}
}
@@ -0,0 +1,43 @@
<?php
namespace Laravel\Fortify\Http\Controllers;
use Illuminate\Http\Request;
use Illuminate\Routing\Controller;
use Laravel\Fortify\Actions\GenerateNewRecoveryCodes;
use Laravel\Fortify\Contracts\RecoveryCodesGeneratedResponse;
class RecoveryCodeController extends Controller
{
/**
* Get the two factor authentication recovery codes for authenticated user.
*
* @param \Illuminate\Http\Request $request
* @return \Illuminate\Http\Response
*/
public function index(Request $request)
{
if (! $request->user()->two_factor_secret ||
! $request->user()->two_factor_recovery_codes) {
return [];
}
return response()->json(json_decode(decrypt(
$request->user()->two_factor_recovery_codes
), true));
}
/**
* Generate a fresh set of two factor authentication recovery codes.
*
* @param \Illuminate\Http\Request $request
* @param \Laravel\Fortify\Actions\GenerateNewRecoveryCodes $generate
* @return \Laravel\Fortify\Contracts\RecoveryCodesGeneratedResponse
*/
public function store(Request $request, GenerateNewRecoveryCodes $generate)
{
$generate($request->user());
return app(RecoveryCodesGeneratedResponse::class);
}
}
@@ -0,0 +1,68 @@
<?php
namespace Laravel\Fortify\Http\Controllers;
use Illuminate\Auth\Events\Registered;
use Illuminate\Contracts\Auth\StatefulGuard;
use Illuminate\Http\Request;
use Illuminate\Routing\Controller;
use Illuminate\Support\Str;
use Laravel\Fortify\Contracts\CreatesNewUsers;
use Laravel\Fortify\Contracts\RegisterResponse;
use Laravel\Fortify\Contracts\RegisterViewResponse;
use Laravel\Fortify\Fortify;
class RegisteredUserController extends Controller
{
/**
* The guard implementation.
*
* @var \Illuminate\Contracts\Auth\StatefulGuard
*/
protected $guard;
/**
* Create a new controller instance.
*
* @param \Illuminate\Contracts\Auth\StatefulGuard $guard
* @return void
*/
public function __construct(StatefulGuard $guard)
{
$this->guard = $guard;
}
/**
* Show the registration view.
*
* @param \Illuminate\Http\Request $request
* @return \Laravel\Fortify\Contracts\RegisterViewResponse
*/
public function create(Request $request): RegisterViewResponse
{
return app(RegisterViewResponse::class);
}
/**
* Create a new registered user.
*
* @param \Illuminate\Http\Request $request
* @param \Laravel\Fortify\Contracts\CreatesNewUsers $creator
* @return \Laravel\Fortify\Contracts\RegisterResponse
*/
public function store(Request $request,
CreatesNewUsers $creator): RegisterResponse
{
if (config('fortify.lowercase_usernames')) {
$request->merge([
Fortify::username() => Str::lower($request->{Fortify::username()}),
]);
}
event(new Registered($user = $creator->create($request->all())));
$this->guard->login($user);
return app(RegisterResponse::class);
}
}
@@ -0,0 +1,76 @@
<?php
namespace Laravel\Fortify\Http\Controllers;
use Illuminate\Contracts\Auth\StatefulGuard;
use Illuminate\Http\Exceptions\HttpResponseException;
use Illuminate\Routing\Controller;
use Laravel\Fortify\Contracts\FailedTwoFactorLoginResponse;
use Laravel\Fortify\Contracts\TwoFactorChallengeViewResponse;
use Laravel\Fortify\Contracts\TwoFactorLoginResponse;
use Laravel\Fortify\Events\RecoveryCodeReplaced;
use Laravel\Fortify\Events\TwoFactorAuthenticationFailed;
use Laravel\Fortify\Http\Requests\TwoFactorLoginRequest;
class TwoFactorAuthenticatedSessionController extends Controller
{
/**
* The guard implementation.
*
* @var \Illuminate\Contracts\Auth\StatefulGuard
*/
protected $guard;
/**
* Create a new controller instance.
*
* @param \Illuminate\Contracts\Auth\StatefulGuard $guard
* @return void
*/
public function __construct(StatefulGuard $guard)
{
$this->guard = $guard;
}
/**
* Show the two factor authentication challenge view.
*
* @param \Laravel\Fortify\Http\Requests\TwoFactorLoginRequest $request
* @return \Laravel\Fortify\Contracts\TwoFactorChallengeViewResponse
*/
public function create(TwoFactorLoginRequest $request): TwoFactorChallengeViewResponse
{
if (! $request->hasChallengedUser()) {
throw new HttpResponseException(redirect()->route('login'));
}
return app(TwoFactorChallengeViewResponse::class);
}
/**
* Attempt to authenticate a new session using the two factor authentication code.
*
* @param \Laravel\Fortify\Http\Requests\TwoFactorLoginRequest $request
* @return mixed
*/
public function store(TwoFactorLoginRequest $request)
{
$user = $request->challengedUser();
if ($code = $request->validRecoveryCode()) {
$user->replaceRecoveryCode($code);
event(new RecoveryCodeReplaced($user, $code));
} elseif (! $request->hasValidCode()) {
event(new TwoFactorAuthenticationFailed($user));
return app(FailedTwoFactorLoginResponse::class)->toResponse($request);
}
$this->guard->login($user, $request->remember());
$request->session()->regenerate();
return app(TwoFactorLoginResponse::class);
}
}
@@ -0,0 +1,41 @@
<?php
namespace Laravel\Fortify\Http\Controllers;
use Illuminate\Http\Request;
use Illuminate\Routing\Controller;
use Laravel\Fortify\Actions\DisableTwoFactorAuthentication;
use Laravel\Fortify\Actions\EnableTwoFactorAuthentication;
use Laravel\Fortify\Contracts\TwoFactorDisabledResponse;
use Laravel\Fortify\Contracts\TwoFactorEnabledResponse;
class TwoFactorAuthenticationController extends Controller
{
/**
* Enable two factor authentication for the user.
*
* @param \Illuminate\Http\Request $request
* @param \Laravel\Fortify\Actions\EnableTwoFactorAuthentication $enable
* @return \Laravel\Fortify\Contracts\TwoFactorEnabledResponse
*/
public function store(Request $request, EnableTwoFactorAuthentication $enable)
{
$enable($request->user(), $request->boolean('force', false));
return app(TwoFactorEnabledResponse::class);
}
/**
* Disable two factor authentication for the user.
*
* @param \Illuminate\Http\Request $request
* @param \Laravel\Fortify\Actions\DisableTwoFactorAuthentication $disable
* @return \Laravel\Fortify\Contracts\TwoFactorDisabledResponse
*/
public function destroy(Request $request, DisableTwoFactorAuthentication $disable)
{
$disable($request->user());
return app(TwoFactorDisabledResponse::class);
}
}
@@ -0,0 +1,27 @@
<?php
namespace Laravel\Fortify\Http\Controllers;
use Illuminate\Http\Request;
use Illuminate\Routing\Controller;
class TwoFactorQrCodeController extends Controller
{
/**
* Get the SVG element for the user's two factor authentication QR code.
*
* @param \Illuminate\Http\Request $request
* @return \Symfony\Component\HttpFoundation\Response
*/
public function show(Request $request)
{
if (is_null($request->user()->two_factor_secret)) {
return [];
}
return response()->json([
'svg' => $request->user()->twoFactorQrCodeSvg(),
'url' => $request->user()->twoFactorQrCodeUrl(),
]);
}
}
@@ -0,0 +1,26 @@
<?php
namespace Laravel\Fortify\Http\Controllers;
use Illuminate\Http\Request;
use Illuminate\Routing\Controller;
class TwoFactorSecretKeyController extends Controller
{
/**
* Get the current user's two factor authentication setup / secret key.
*
* @param \Illuminate\Http\Request $request
* @return \Symfony\Component\HttpFoundation\Response
*/
public function show(Request $request)
{
if (is_null($request->user()->two_factor_secret)) {
abort(404, 'Two factor authentication has not been enabled.');
}
return response()->json([
'secretKey' => decrypt($request->user()->two_factor_secret),
]);
}
}
@@ -0,0 +1,30 @@
<?php
namespace Laravel\Fortify\Http\Controllers;
use Illuminate\Auth\Events\Verified;
use Illuminate\Routing\Controller;
use Laravel\Fortify\Contracts\VerifyEmailResponse;
use Laravel\Fortify\Http\Requests\VerifyEmailRequest;
class VerifyEmailController extends Controller
{
/**
* Mark the authenticated user's email address as verified.
*
* @param \Laravel\Fortify\Http\Requests\VerifyEmailRequest $request
* @return \Laravel\Fortify\Contracts\VerifyEmailResponse
*/
public function __invoke(VerifyEmailRequest $request)
{
if ($request->user()->hasVerifiedEmail()) {
return app(VerifyEmailResponse::class);
}
if ($request->user()->markEmailAsVerified()) {
event(new Verified($request->user()));
}
return app(VerifyEmailResponse::class);
}
}
@@ -0,0 +1,32 @@
<?php
namespace Laravel\Fortify\Http\Requests;
use Illuminate\Foundation\Http\FormRequest;
use Laravel\Fortify\Fortify;
class LoginRequest extends FormRequest
{
/**
* Determine if the user is authorized to make this request.
*
* @return bool
*/
public function authorize()
{
return true;
}
/**
* Get the validation rules that apply to the request.
*
* @return array
*/
public function rules()
{
return [
Fortify::username() => 'required|string',
'password' => 'required|string',
];
}
}
@@ -0,0 +1,139 @@
<?php
namespace Laravel\Fortify\Http\Requests;
use Illuminate\Contracts\Auth\StatefulGuard;
use Illuminate\Foundation\Http\FormRequest;
use Illuminate\Http\Exceptions\HttpResponseException;
use Laravel\Fortify\Contracts\FailedTwoFactorLoginResponse;
use Laravel\Fortify\Contracts\TwoFactorAuthenticationProvider;
class TwoFactorLoginRequest extends FormRequest
{
/**
* The user attempting the two factor challenge.
*
* @var mixed
*/
protected $challengedUser;
/**
* Indicates if the user wished to be remembered after login.
*
* @var bool
*/
protected $remember;
/**
* Determine if the user is authorized to make this request.
*
* @return bool
*/
public function authorize()
{
return true;
}
/**
* Get the validation rules that apply to the request.
*
* @return array
*/
public function rules()
{
return [
'code' => 'nullable|string',
'recovery_code' => 'nullable|string',
];
}
/**
* Determine if the request has a valid two factor code.
*
* @return bool
*/
public function hasValidCode()
{
return $this->code && tap(app(TwoFactorAuthenticationProvider::class)->verify(
decrypt($this->challengedUser()->two_factor_secret), $this->code
), function ($result) {
if ($result) {
$this->session()->forget('login.id');
}
});
}
/**
* Get the valid recovery code if one exists on the request.
*
* @return string|null
*/
public function validRecoveryCode()
{
if (! $this->recovery_code) {
return;
}
return tap(collect($this->challengedUser()->recoveryCodes())->first(function ($code) {
return hash_equals($code, $this->recovery_code) ? $code : null;
}), function ($code) {
if ($code) {
$this->session()->forget('login.id');
}
});
}
/**
* Determine if there is a challenged user in the current session.
*
* @return bool
*/
public function hasChallengedUser()
{
if ($this->challengedUser) {
return true;
}
$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.
*
* @return mixed
*/
public function challengedUser()
{
if ($this->challengedUser) {
return $this->challengedUser;
}
$model = app(StatefulGuard::class)->getProvider()->getModel();
if (! $this->session()->has('login.id') ||
! $user = $model::find($this->session()->get('login.id'))) {
throw new HttpResponseException(
app(FailedTwoFactorLoginResponse::class)->toResponse($this)
);
}
return $this->challengedUser = $user;
}
/**
* Determine if the user wanted to be remembered after login.
*
* @return bool
*/
public function remember()
{
if (! $this->remember) {
$this->remember = $this->session()->pull('login.remember', false);
}
return $this->remember;
}
}
@@ -0,0 +1,36 @@
<?php
namespace Laravel\Fortify\Http\Requests;
use Illuminate\Foundation\Http\FormRequest;
class VerifyEmailRequest extends FormRequest
{
/**
* Determine if the user is authorized to make this request.
*
* @return bool
*/
public function authorize()
{
if (! hash_equals((string) $this->user()->getKey(), (string) $this->route('id'))) {
return false;
}
if (! hash_equals(sha1($this->user()->getEmailForVerification()), (string) $this->route('hash'))) {
return false;
}
return true;
}
/**
* Get the validation rules that apply to the request.
*
* @return array
*/
public function rules()
{
return [];
}
}
@@ -0,0 +1,23 @@
<?php
namespace Laravel\Fortify\Http\Responses;
use Illuminate\Http\JsonResponse;
use Laravel\Fortify\Contracts\EmailVerificationNotificationSentResponse as EmailVerificationNotificationSentResponseContract;
use Laravel\Fortify\Fortify;
class EmailVerificationNotificationSentResponse implements EmailVerificationNotificationSentResponseContract
{
/**
* Create an HTTP response that represents the object.
*
* @param \Illuminate\Http\Request $request
* @return \Symfony\Component\HttpFoundation\Response
*/
public function toResponse($request)
{
return $request->wantsJson()
? new JsonResponse('', 202)
: back()->with('status', Fortify::VERIFICATION_LINK_SENT);
}
}
@@ -0,0 +1,28 @@
<?php
namespace Laravel\Fortify\Http\Responses;
use Illuminate\Validation\ValidationException;
use Laravel\Fortify\Contracts\FailedPasswordConfirmationResponse as FailedPasswordConfirmationResponseContract;
class FailedPasswordConfirmationResponse implements FailedPasswordConfirmationResponseContract
{
/**
* Create an HTTP response that represents the object.
*
* @param \Illuminate\Http\Request $request
* @return \Symfony\Component\HttpFoundation\Response
*/
public function toResponse($request)
{
$message = __('The provided password was incorrect.');
if ($request->wantsJson()) {
throw ValidationException::withMessages([
'password' => [$message],
]);
}
return back()->withErrors(['password' => $message]);
}
}
@@ -0,0 +1,46 @@
<?php
namespace Laravel\Fortify\Http\Responses;
use Illuminate\Validation\ValidationException;
use Laravel\Fortify\Contracts\FailedPasswordResetLinkRequestResponse as FailedPasswordResetLinkRequestResponseContract;
class FailedPasswordResetLinkRequestResponse implements FailedPasswordResetLinkRequestResponseContract
{
/**
* The response status language key.
*
* @var string
*/
protected $status;
/**
* Create a new response instance.
*
* @param string $status
* @return void
*/
public function __construct(string $status)
{
$this->status = $status;
}
/**
* Create an HTTP response that represents the object.
*
* @param \Illuminate\Http\Request $request
* @return \Symfony\Component\HttpFoundation\Response
*/
public function toResponse($request)
{
if ($request->wantsJson()) {
throw ValidationException::withMessages([
'email' => [trans($this->status)],
]);
}
return back()
->withInput($request->only('email'))
->withErrors(['email' => trans($this->status)]);
}
}
@@ -0,0 +1,46 @@
<?php
namespace Laravel\Fortify\Http\Responses;
use Illuminate\Validation\ValidationException;
use Laravel\Fortify\Contracts\FailedPasswordResetResponse as FailedPasswordResetResponseContract;
class FailedPasswordResetResponse implements FailedPasswordResetResponseContract
{
/**
* The response status language key.
*
* @var string
*/
protected $status;
/**
* Create a new response instance.
*
* @param string $status
* @return void
*/
public function __construct(string $status)
{
$this->status = $status;
}
/**
* Create an HTTP response that represents the object.
*
* @param \Illuminate\Http\Request $request
* @return \Symfony\Component\HttpFoundation\Response
*/
public function toResponse($request)
{
if ($request->wantsJson()) {
throw ValidationException::withMessages([
'email' => [trans($this->status)],
]);
}
return back()
->withInput($request->only('email'))
->withErrors(['email' => trans($this->status)]);
}
}
@@ -0,0 +1,30 @@
<?php
namespace Laravel\Fortify\Http\Responses;
use Illuminate\Validation\ValidationException;
use Laravel\Fortify\Contracts\FailedTwoFactorLoginResponse as FailedTwoFactorLoginResponseContract;
class FailedTwoFactorLoginResponse implements FailedTwoFactorLoginResponseContract
{
/**
* Create an HTTP response that represents the object.
*
* @param \Illuminate\Http\Request $request
* @return \Symfony\Component\HttpFoundation\Response
*/
public function toResponse($request)
{
[$key, $message] = $request->filled('recovery_code')
? ['recovery_code', __('The provided two factor recovery code was invalid.')]
: ['code', __('The provided two factor authentication code was invalid.')];
if ($request->wantsJson()) {
throw ValidationException::withMessages([
$key => [$message],
]);
}
return redirect()->route('two-factor.login')->withErrors([$key => $message]);
}
}
@@ -0,0 +1,50 @@
<?php
namespace Laravel\Fortify\Http\Responses;
use Illuminate\Http\Response;
use Illuminate\Validation\ValidationException;
use Laravel\Fortify\Contracts\LockoutResponse as LockoutResponseContract;
use Laravel\Fortify\Fortify;
use Laravel\Fortify\LoginRateLimiter;
class LockoutResponse implements LockoutResponseContract
{
/**
* The login rate limiter instance.
*
* @var \Laravel\Fortify\LoginRateLimiter
*/
protected $limiter;
/**
* Create a new response instance.
*
* @param \Laravel\Fortify\LoginRateLimiter $limiter
* @return void
*/
public function __construct(LoginRateLimiter $limiter)
{
$this->limiter = $limiter;
}
/**
* Create an HTTP response that represents the object.
*
* @param \Illuminate\Http\Request $request
* @return \Symfony\Component\HttpFoundation\Response
*/
public function toResponse($request)
{
return with($this->limiter->availableIn($request), function ($seconds) {
throw ValidationException::withMessages([
Fortify::username() => [
trans('auth.throttle', [
'seconds' => $seconds,
'minutes' => ceil($seconds / 60),
]),
],
])->status(Response::HTTP_TOO_MANY_REQUESTS);
});
}
}
@@ -0,0 +1,22 @@
<?php
namespace Laravel\Fortify\Http\Responses;
use Laravel\Fortify\Contracts\LoginResponse as LoginResponseContract;
use Laravel\Fortify\Fortify;
class LoginResponse implements LoginResponseContract
{
/**
* Create an HTTP response that represents the object.
*
* @param \Illuminate\Http\Request $request
* @return \Symfony\Component\HttpFoundation\Response
*/
public function toResponse($request)
{
return $request->wantsJson()
? response()->json(['two_factor' => false])
: redirect()->intended(Fortify::redirects('login'));
}
}
@@ -0,0 +1,23 @@
<?php
namespace Laravel\Fortify\Http\Responses;
use Illuminate\Http\JsonResponse;
use Laravel\Fortify\Contracts\LogoutResponse as LogoutResponseContract;
use Laravel\Fortify\Fortify;
class LogoutResponse implements LogoutResponseContract
{
/**
* Create an HTTP response that represents the object.
*
* @param \Illuminate\Http\Request $request
* @return \Symfony\Component\HttpFoundation\Response
*/
public function toResponse($request)
{
return $request->wantsJson()
? new JsonResponse('', 204)
: redirect(Fortify::redirects('logout', '/'));
}
}
@@ -0,0 +1,23 @@
<?php
namespace Laravel\Fortify\Http\Responses;
use Illuminate\Http\JsonResponse;
use Laravel\Fortify\Contracts\PasswordConfirmedResponse as PasswordConfirmedResponseContract;
use Laravel\Fortify\Fortify;
class PasswordConfirmedResponse implements PasswordConfirmedResponseContract
{
/**
* Create an HTTP response that represents the object.
*
* @param \Illuminate\Http\Request $request
* @return \Symfony\Component\HttpFoundation\Response
*/
public function toResponse($request)
{
return $request->wantsJson()
? new JsonResponse('', 201)
: redirect()->intended(Fortify::redirects('password-confirmation'));
}
}
@@ -0,0 +1,41 @@
<?php
namespace Laravel\Fortify\Http\Responses;
use Illuminate\Http\JsonResponse;
use Laravel\Fortify\Contracts\PasswordResetResponse as PasswordResetResponseContract;
use Laravel\Fortify\Fortify;
class PasswordResetResponse implements PasswordResetResponseContract
{
/**
* The response status language key.
*
* @var string
*/
protected $status;
/**
* Create a new response instance.
*
* @param string $status
* @return void
*/
public function __construct(string $status)
{
$this->status = $status;
}
/**
* Create an HTTP response that represents the object.
*
* @param \Illuminate\Http\Request $request
* @return \Symfony\Component\HttpFoundation\Response
*/
public function toResponse($request)
{
return $request->wantsJson()
? new JsonResponse(['message' => trans($this->status)], 200)
: redirect(Fortify::redirects('password-reset', config('fortify.views', true) ? route('login') : null))->with('status', trans($this->status));
}
}
@@ -0,0 +1,23 @@
<?php
namespace Laravel\Fortify\Http\Responses;
use Illuminate\Http\JsonResponse;
use Laravel\Fortify\Contracts\PasswordUpdateResponse as PasswordUpdateResponseContract;
use Laravel\Fortify\Fortify;
class PasswordUpdateResponse implements PasswordUpdateResponseContract
{
/**
* Create an HTTP response that represents the object.
*
* @param \Illuminate\Http\Request $request
* @return \Symfony\Component\HttpFoundation\Response
*/
public function toResponse($request)
{
return $request->wantsJson()
? new JsonResponse('', 200)
: back()->with('status', Fortify::PASSWORD_UPDATED);
}
}
@@ -0,0 +1,23 @@
<?php
namespace Laravel\Fortify\Http\Responses;
use Illuminate\Http\JsonResponse;
use Laravel\Fortify\Contracts\ProfileInformationUpdatedResponse as ProfileInformationUpdatedResponseContract;
use Laravel\Fortify\Fortify;
class ProfileInformationUpdatedResponse implements ProfileInformationUpdatedResponseContract
{
/**
* Create an HTTP response that represents the object.
*
* @param \Illuminate\Http\Request $request
* @return \Symfony\Component\HttpFoundation\Response
*/
public function toResponse($request)
{
return $request->wantsJson()
? new JsonResponse('', 200)
: back()->with('status', Fortify::PROFILE_INFORMATION_UPDATED);
}
}
@@ -0,0 +1,23 @@
<?php
namespace Laravel\Fortify\Http\Responses;
use Illuminate\Http\JsonResponse;
use Laravel\Fortify\Contracts\RecoveryCodesGeneratedResponse as RecoveryCodesGeneratedResponseContract;
use Laravel\Fortify\Fortify;
class RecoveryCodesGeneratedResponse implements RecoveryCodesGeneratedResponseContract
{
/**
* Create an HTTP response that represents the object.
*
* @param \Illuminate\Http\Request $request
* @return \Symfony\Component\HttpFoundation\Response
*/
public function toResponse($request)
{
return $request->wantsJson()
? new JsonResponse('', 200)
: back()->with('status', Fortify::RECOVERY_CODES_GENERATED);
}
}
@@ -0,0 +1,31 @@
<?php
namespace Laravel\Fortify\Http\Responses;
use Illuminate\Contracts\Support\Responsable;
use Laravel\Fortify\Fortify;
class RedirectAsIntended implements Responsable
{
/**
* Create a new class instance.
*
* @param string $name
* @return void
*/
public function __construct(public string $name)
{
//
}
/**
* Create an HTTP response that represents the object.
*
* @param \Illuminate\Http\Request $request
* @return \Symfony\Component\HttpFoundation\Response
*/
public function toResponse($request)
{
return redirect()->intended(Fortify::redirects($this->name));
}
}
@@ -0,0 +1,23 @@
<?php
namespace Laravel\Fortify\Http\Responses;
use Illuminate\Http\JsonResponse;
use Laravel\Fortify\Contracts\RegisterResponse as RegisterResponseContract;
use Laravel\Fortify\Fortify;
class RegisterResponse implements RegisterResponseContract
{
/**
* Create an HTTP response that represents the object.
*
* @param \Illuminate\Http\Request $request
* @return \Symfony\Component\HttpFoundation\Response
*/
public function toResponse($request)
{
return $request->wantsJson()
? new JsonResponse('', 201)
: redirect()->intended(Fortify::redirects('register'));
}
}
@@ -0,0 +1,61 @@
<?php
namespace Laravel\Fortify\Http\Responses;
use Illuminate\Contracts\Support\Responsable;
use Laravel\Fortify\Contracts\ConfirmPasswordViewResponse;
use Laravel\Fortify\Contracts\LoginViewResponse;
use Laravel\Fortify\Contracts\RegisterViewResponse;
use Laravel\Fortify\Contracts\RequestPasswordResetLinkViewResponse;
use Laravel\Fortify\Contracts\ResetPasswordViewResponse;
use Laravel\Fortify\Contracts\TwoFactorChallengeViewResponse;
use Laravel\Fortify\Contracts\VerifyEmailViewResponse;
class SimpleViewResponse implements
LoginViewResponse,
ResetPasswordViewResponse,
RegisterViewResponse,
RequestPasswordResetLinkViewResponse,
TwoFactorChallengeViewResponse,
VerifyEmailViewResponse,
ConfirmPasswordViewResponse
{
/**
* The name of the view or the callable used to generate the view.
*
* @var callable|string
*/
protected $view;
/**
* Create a new response instance.
*
* @param callable|string $view
* @return void
*/
public function __construct($view)
{
$this->view = $view;
}
/**
* Create an HTTP response that represents the object.
*
* @param \Illuminate\Http\Request $request
* @return \Symfony\Component\HttpFoundation\Response
*/
public function toResponse($request)
{
if (! is_callable($this->view) || is_string($this->view)) {
return view($this->view, ['request' => $request]);
}
$response = call_user_func($this->view, $request);
if ($response instanceof Responsable) {
return $response->toResponse($request);
}
return $response;
}
}
@@ -0,0 +1,40 @@
<?php
namespace Laravel\Fortify\Http\Responses;
use Illuminate\Http\JsonResponse;
use Laravel\Fortify\Contracts\SuccessfulPasswordResetLinkRequestResponse as SuccessfulPasswordResetLinkRequestResponseContract;
class SuccessfulPasswordResetLinkRequestResponse implements SuccessfulPasswordResetLinkRequestResponseContract
{
/**
* The response status language key.
*
* @var string
*/
protected $status;
/**
* Create a new response instance.
*
* @param string $status
* @return void
*/
public function __construct(string $status)
{
$this->status = $status;
}
/**
* Create an HTTP response that represents the object.
*
* @param \Illuminate\Http\Request $request
* @return \Symfony\Component\HttpFoundation\Response
*/
public function toResponse($request)
{
return $request->wantsJson()
? new JsonResponse(['message' => trans($this->status)], 200)
: back()->with('status', trans($this->status));
}
}
@@ -0,0 +1,23 @@
<?php
namespace Laravel\Fortify\Http\Responses;
use Illuminate\Http\JsonResponse;
use Laravel\Fortify\Contracts\TwoFactorConfirmedResponse as TwoFactorConfirmedResponseContract;
use Laravel\Fortify\Fortify;
class TwoFactorConfirmedResponse implements TwoFactorConfirmedResponseContract
{
/**
* Create an HTTP response that represents the object.
*
* @param \Illuminate\Http\Request $request
* @return \Symfony\Component\HttpFoundation\Response
*/
public function toResponse($request)
{
return $request->wantsJson()
? new JsonResponse('', 200)
: back()->with('status', Fortify::TWO_FACTOR_AUTHENTICATION_CONFIRMED);
}
}
@@ -0,0 +1,23 @@
<?php
namespace Laravel\Fortify\Http\Responses;
use Illuminate\Http\JsonResponse;
use Laravel\Fortify\Contracts\TwoFactorLoginResponse as TwoFactorLoginResponseContract;
use Laravel\Fortify\Fortify;
class TwoFactorDisabledResponse implements TwoFactorLoginResponseContract
{
/**
* Create an HTTP response that represents the object.
*
* @param \Illuminate\Http\Request $request
* @return \Symfony\Component\HttpFoundation\Response
*/
public function toResponse($request)
{
return $request->wantsJson()
? new JsonResponse('', 200)
: back()->with('status', Fortify::TWO_FACTOR_AUTHENTICATION_DISABLED);
}
}
@@ -0,0 +1,23 @@
<?php
namespace Laravel\Fortify\Http\Responses;
use Illuminate\Http\JsonResponse;
use Laravel\Fortify\Contracts\TwoFactorLoginResponse as TwoFactorLoginResponseContract;
use Laravel\Fortify\Fortify;
class TwoFactorEnabledResponse implements TwoFactorLoginResponseContract
{
/**
* Create an HTTP response that represents the object.
*
* @param \Illuminate\Http\Request $request
* @return \Symfony\Component\HttpFoundation\Response
*/
public function toResponse($request)
{
return $request->wantsJson()
? new JsonResponse('', 200)
: back()->with('status', Fortify::TWO_FACTOR_AUTHENTICATION_ENABLED);
}
}
@@ -0,0 +1,23 @@
<?php
namespace Laravel\Fortify\Http\Responses;
use Illuminate\Http\JsonResponse;
use Laravel\Fortify\Contracts\TwoFactorLoginResponse as TwoFactorLoginResponseContract;
use Laravel\Fortify\Fortify;
class TwoFactorLoginResponse implements TwoFactorLoginResponseContract
{
/**
* Create an HTTP response that represents the object.
*
* @param \Illuminate\Http\Request $request
* @return \Symfony\Component\HttpFoundation\Response
*/
public function toResponse($request)
{
return $request->wantsJson()
? new JsonResponse('', 204)
: redirect()->intended(Fortify::redirects('login'));
}
}
@@ -0,0 +1,23 @@
<?php
namespace Laravel\Fortify\Http\Responses;
use Illuminate\Http\JsonResponse;
use Laravel\Fortify\Contracts\VerifyEmailResponse as VerifyEmailResponseContract;
use Laravel\Fortify\Fortify;
class VerifyEmailResponse implements VerifyEmailResponseContract
{
/**
* Create an HTTP response that represents the object.
*
* @param \Illuminate\Http\Request $request
* @return \Symfony\Component\HttpFoundation\Response
*/
public function toResponse($request)
{
return $request->wantsJson()
? new JsonResponse('', 204)
: redirect()->intended(Fortify::redirects('email-verification').'?verified=1');
}
}
+94
View File
@@ -0,0 +1,94 @@
<?php
namespace Laravel\Fortify;
use Illuminate\Cache\RateLimiter;
use Illuminate\Http\Request;
use Illuminate\Support\Str;
class LoginRateLimiter
{
/**
* The login rate limiter instance.
*
* @var \Illuminate\Cache\RateLimiter
*/
protected $limiter;
/**
* Create a new login rate limiter instance.
*
* @param \Illuminate\Cache\RateLimiter $limiter
* @return void
*/
public function __construct(RateLimiter $limiter)
{
$this->limiter = $limiter;
}
/**
* Get the number of attempts for the given key.
*
* @param \Illuminate\Http\Request $request
* @return mixed
*/
public function attempts(Request $request)
{
return $this->limiter->attempts($this->throttleKey($request));
}
/**
* Determine if the user has too many failed login attempts.
*
* @param \Illuminate\Http\Request $request
* @return bool
*/
public function tooManyAttempts(Request $request)
{
return $this->limiter->tooManyAttempts($this->throttleKey($request), 5);
}
/**
* Increment the login attempts for the user.
*
* @param \Illuminate\Http\Request $request
* @return void
*/
public function increment(Request $request)
{
$this->limiter->hit($this->throttleKey($request), 60);
}
/**
* Determine the number of seconds until logging in is available again.
*
* @param \Illuminate\Http\Request $request
* @return int
*/
public function availableIn(Request $request)
{
return $this->limiter->availableIn($this->throttleKey($request));
}
/**
* Clear the login locks for the given user credentials.
*
* @param \Illuminate\Http\Request $request
* @return void
*/
public function clear(Request $request)
{
$this->limiter->clear($this->throttleKey($request));
}
/**
* Get the throttle key for the given request.
*
* @param \Illuminate\Http\Request $request
* @return string
*/
protected function throttleKey(Request $request)
{
return Str::transliterate(Str::lower($request->input(Fortify::username())).'|'.$request->ip());
}
}
+18
View File
@@ -0,0 +1,18 @@
<?php
namespace Laravel\Fortify;
use Illuminate\Support\Str;
class RecoveryCode
{
/**
* Generate a new recovery code.
*
* @return string
*/
public static function generate()
{
return Str::random(10).'-'.Str::random(10);
}
}

Some files were not shown because too many files have changed in this diff Show More