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
+21
View File
@@ -0,0 +1,21 @@
The MIT License (MIT)
Copyright (c) Taylor Otwell
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
+40
View File
@@ -0,0 +1,40 @@
<p align="center"><img src="/art/logo.svg" alt="Logo Laravel Fortify"></p>
<p align="center">
<a href="https://github.com/laravel/fortify/actions">
<img src="https://github.com/laravel/fortify/workflows/tests/badge.svg" alt="Build Status">
</a>
<a href="https://packagist.org/packages/laravel/fortify">
<img src="https://img.shields.io/packagist/dt/laravel/fortify" alt="Total Downloads">
</a>
<a href="https://packagist.org/packages/laravel/fortify">
<img src="https://img.shields.io/packagist/v/laravel/fortify" alt="Latest Stable Version">
</a>
<a href="https://packagist.org/packages/laravel/fortify">
<img src="https://img.shields.io/packagist/l/laravel/fortify" alt="License">
</a>
</p>
## Introduction
Laravel Fortify is a frontend agnostic authentication backend for Laravel. Fortify powers the registration, authentication, and two-factor authentication features of [Laravel Jetstream](https://github.com/laravel/jetstream).
## Official Documentation
Documentation for Fortify can be found on the [Laravel website](https://laravel.com/docs/fortify).
## Contributing
Thank you for considering contributing to Fortify! You can read the contribution guide [here](.github/CONTRIBUTING.md).
## Code of Conduct
In order to ensure that the Laravel community is welcoming to all, please review and abide by the [Code of Conduct](https://laravel.com/docs/contributions#code-of-conduct).
## Security Vulnerabilities
Please review [our security policy](https://github.com/laravel/fortify/security/policy) on how to report security vulnerabilities.
## License
Laravel Fortify is open-sourced software licensed under the [MIT license](LICENSE.md).
+64
View File
@@ -0,0 +1,64 @@
{
"name": "laravel/fortify",
"description": "Backend controllers and scaffolding for Laravel authentication.",
"keywords": ["laravel", "auth"],
"license": "MIT",
"support": {
"issues": "https://github.com/laravel/fortify/issues",
"source": "https://github.com/laravel/fortify"
},
"authors": [
{
"name": "Taylor Otwell",
"email": "taylor@laravel.com"
}
],
"require": {
"php": "^8.1",
"ext-json": "*",
"bacon/bacon-qr-code": "^3.0",
"illuminate/support": "^10.0|^11.0",
"symfony/console": "^6.0|^7.0",
"pragmarx/google2fa": "^8.0"
},
"require-dev": {
"mockery/mockery": "^1.0",
"orchestra/testbench": "^8.16|^9.0",
"phpstan/phpstan": "^1.10",
"phpunit/phpunit": "^10.4"
},
"autoload": {
"psr-4": {
"Laravel\\Fortify\\": "src/"
}
},
"autoload-dev": {
"psr-4": {
"Laravel\\Fortify\\Tests\\": "tests/",
"App\\": "workbench/app/",
"Database\\Factories\\": "workbench/database/factories/"
},
"classmap": ["stubs/"]
},
"extra": {
"branch-alias": {
"dev-master": "1.x-dev"
},
"laravel": {
"providers": [
"Laravel\\Fortify\\FortifyServiceProvider"
]
}
},
"config": {
"sort-packages": true
},
"minimum-stability": "dev",
"prefer-stable": true,
"scripts": {
"post-autoload-dump": "@prepare",
"prepare": "@php vendor/bin/testbench package:discover --ansi",
"lint": "@php vendor/bin/phpstan analyse",
"test": "@php vendor/bin/phpunit"
}
}
+69
View File
@@ -0,0 +1,69 @@
<?php
use Laravel\Fortify\Features;
return [
'guard' => 'web',
'middleware' => ['web'],
'auth_middleware' => 'auth',
'passwords' => 'users',
'username' => 'email',
'email' => 'email',
'views' => true,
'home' => '/home',
'prefix' => '',
'domain' => null,
'lowercase_usernames' => false,
'limiters' => [
'login' => null,
],
'paths' => [
'login' => null,
'logout' => null,
'password' => [
'request' => null,
'reset' => null,
'email' => null,
'update' => null,
'confirm' => null,
'confirmation' => null,
],
'register' => null,
'verification' => [
'notice' => null,
'verify' => null,
'send' => null,
],
'user-profile-information' => [
'update' => null,
],
'user-password' => [
'update' => null,
],
'two-factor' => [
'login' => null,
'enable' => null,
'confirm' => null,
'disable' => null,
'qr-code' => null,
'secret-key' => null,
'recovery-codes' => null,
],
],
'redirects' => [
'login' => null,
'logout' => null,
'password-confirmation' => null,
'register' => null,
'email-verification' => null,
'password-reset' => null,
],
'features' => [
Features::registration(),
Features::resetPasswords(),
Features::emailVerification(),
Features::updateProfileInformation(),
Features::updatePasswords(),
Features::twoFactorAuthentication(),
],
];
@@ -0,0 +1,46 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
use Laravel\Fortify\Fortify;
return new class extends Migration
{
/**
* Run the migrations.
*/
public function up(): void
{
Schema::table('users', function (Blueprint $table) {
$table->text('two_factor_secret')
->after('password')
->nullable();
$table->text('two_factor_recovery_codes')
->after('two_factor_secret')
->nullable();
if (Fortify::confirmsTwoFactorAuthentication()) {
$table->timestamp('two_factor_confirmed_at')
->after('two_factor_recovery_codes')
->nullable();
}
});
}
/**
* Reverse the migrations.
*/
public function down(): void
{
Schema::table('users', function (Blueprint $table) {
$table->dropColumn(array_merge([
'two_factor_secret',
'two_factor_recovery_codes',
], Fortify::confirmsTwoFactorAuthentication() ? [
'two_factor_confirmed_at',
] : []));
});
}
};
+171
View File
@@ -0,0 +1,171 @@
<?php
use Illuminate\Support\Facades\Route;
use Laravel\Fortify\Features;
use Laravel\Fortify\Http\Controllers\AuthenticatedSessionController;
use Laravel\Fortify\Http\Controllers\ConfirmablePasswordController;
use Laravel\Fortify\Http\Controllers\ConfirmedPasswordStatusController;
use Laravel\Fortify\Http\Controllers\ConfirmedTwoFactorAuthenticationController;
use Laravel\Fortify\Http\Controllers\EmailVerificationNotificationController;
use Laravel\Fortify\Http\Controllers\EmailVerificationPromptController;
use Laravel\Fortify\Http\Controllers\NewPasswordController;
use Laravel\Fortify\Http\Controllers\PasswordController;
use Laravel\Fortify\Http\Controllers\PasswordResetLinkController;
use Laravel\Fortify\Http\Controllers\ProfileInformationController;
use Laravel\Fortify\Http\Controllers\RecoveryCodeController;
use Laravel\Fortify\Http\Controllers\RegisteredUserController;
use Laravel\Fortify\Http\Controllers\TwoFactorAuthenticatedSessionController;
use Laravel\Fortify\Http\Controllers\TwoFactorAuthenticationController;
use Laravel\Fortify\Http\Controllers\TwoFactorQrCodeController;
use Laravel\Fortify\Http\Controllers\TwoFactorSecretKeyController;
use Laravel\Fortify\Http\Controllers\VerifyEmailController;
use Laravel\Fortify\RoutePath;
Route::group(['middleware' => config('fortify.middleware', ['web'])], function () {
$enableViews = config('fortify.views', true);
// Authentication...
if ($enableViews) {
Route::get(RoutePath::for('login', '/login'), [AuthenticatedSessionController::class, 'create'])
->middleware(['guest:'.config('fortify.guard')])
->name('login');
}
$limiter = config('fortify.limiters.login');
$twoFactorLimiter = config('fortify.limiters.two-factor');
$verificationLimiter = config('fortify.limiters.verification', '6,1');
Route::post(RoutePath::for('login', '/login'), [AuthenticatedSessionController::class, 'store'])
->middleware(array_filter([
'guest:'.config('fortify.guard'),
$limiter ? 'throttle:'.$limiter : null,
]));
Route::post(RoutePath::for('logout', '/logout'), [AuthenticatedSessionController::class, 'destroy'])
->middleware([config('fortify.auth_middleware', 'auth').':'.config('fortify.guard')])
->name('logout');
// Password Reset...
if (Features::enabled(Features::resetPasswords())) {
if ($enableViews) {
Route::get(RoutePath::for('password.request', '/forgot-password'), [PasswordResetLinkController::class, 'create'])
->middleware(['guest:'.config('fortify.guard')])
->name('password.request');
Route::get(RoutePath::for('password.reset', '/reset-password/{token}'), [NewPasswordController::class, 'create'])
->middleware(['guest:'.config('fortify.guard')])
->name('password.reset');
}
Route::post(RoutePath::for('password.email', '/forgot-password'), [PasswordResetLinkController::class, 'store'])
->middleware(['guest:'.config('fortify.guard')])
->name('password.email');
Route::post(RoutePath::for('password.update', '/reset-password'), [NewPasswordController::class, 'store'])
->middleware(['guest:'.config('fortify.guard')])
->name('password.update');
}
// Registration...
if (Features::enabled(Features::registration())) {
if ($enableViews) {
Route::get(RoutePath::for('register', '/register'), [RegisteredUserController::class, 'create'])
->middleware(['guest:'.config('fortify.guard')])
->name('register');
}
Route::post(RoutePath::for('register', '/register'), [RegisteredUserController::class, 'store'])
->middleware(['guest:'.config('fortify.guard')]);
}
// Email Verification...
if (Features::enabled(Features::emailVerification())) {
if ($enableViews) {
Route::get(RoutePath::for('verification.notice', '/email/verify'), [EmailVerificationPromptController::class, '__invoke'])
->middleware([config('fortify.auth_middleware', 'auth').':'.config('fortify.guard')])
->name('verification.notice');
}
Route::get(RoutePath::for('verification.verify', '/email/verify/{id}/{hash}'), [VerifyEmailController::class, '__invoke'])
->middleware([config('fortify.auth_middleware', 'auth').':'.config('fortify.guard'), 'signed', 'throttle:'.$verificationLimiter])
->name('verification.verify');
Route::post(RoutePath::for('verification.send', '/email/verification-notification'), [EmailVerificationNotificationController::class, 'store'])
->middleware([config('fortify.auth_middleware', 'auth').':'.config('fortify.guard'), 'throttle:'.$verificationLimiter])
->name('verification.send');
}
// Profile Information...
if (Features::enabled(Features::updateProfileInformation())) {
Route::put(RoutePath::for('user-profile-information.update', '/user/profile-information'), [ProfileInformationController::class, 'update'])
->middleware([config('fortify.auth_middleware', 'auth').':'.config('fortify.guard')])
->name('user-profile-information.update');
}
// Passwords...
if (Features::enabled(Features::updatePasswords())) {
Route::put(RoutePath::for('user-password.update', '/user/password'), [PasswordController::class, 'update'])
->middleware([config('fortify.auth_middleware', 'auth').':'.config('fortify.guard')])
->name('user-password.update');
}
// Password Confirmation...
if ($enableViews) {
Route::get(RoutePath::for('password.confirm', '/user/confirm-password'), [ConfirmablePasswordController::class, 'show'])
->middleware([config('fortify.auth_middleware', 'auth').':'.config('fortify.guard')]);
}
Route::get(RoutePath::for('password.confirmation', '/user/confirmed-password-status'), [ConfirmedPasswordStatusController::class, 'show'])
->middleware([config('fortify.auth_middleware', 'auth').':'.config('fortify.guard')])
->name('password.confirmation');
Route::post(RoutePath::for('password.confirm', '/user/confirm-password'), [ConfirmablePasswordController::class, 'store'])
->middleware([config('fortify.auth_middleware', 'auth').':'.config('fortify.guard')])
->name('password.confirm');
// Two Factor Authentication...
if (Features::enabled(Features::twoFactorAuthentication())) {
if ($enableViews) {
Route::get(RoutePath::for('two-factor.login', '/two-factor-challenge'), [TwoFactorAuthenticatedSessionController::class, 'create'])
->middleware(['guest:'.config('fortify.guard')])
->name('two-factor.login');
}
Route::post(RoutePath::for('two-factor.login', '/two-factor-challenge'), [TwoFactorAuthenticatedSessionController::class, 'store'])
->middleware(array_filter([
'guest:'.config('fortify.guard'),
$twoFactorLimiter ? 'throttle:'.$twoFactorLimiter : null,
]));
$twoFactorMiddleware = Features::optionEnabled(Features::twoFactorAuthentication(), 'confirmPassword')
? [config('fortify.auth_middleware', 'auth').':'.config('fortify.guard'), 'password.confirm']
: [config('fortify.auth_middleware', 'auth').':'.config('fortify.guard')];
Route::post(RoutePath::for('two-factor.enable', '/user/two-factor-authentication'), [TwoFactorAuthenticationController::class, 'store'])
->middleware($twoFactorMiddleware)
->name('two-factor.enable');
Route::post(RoutePath::for('two-factor.confirm', '/user/confirmed-two-factor-authentication'), [ConfirmedTwoFactorAuthenticationController::class, 'store'])
->middleware($twoFactorMiddleware)
->name('two-factor.confirm');
Route::delete(RoutePath::for('two-factor.disable', '/user/two-factor-authentication'), [TwoFactorAuthenticationController::class, 'destroy'])
->middleware($twoFactorMiddleware)
->name('two-factor.disable');
Route::get(RoutePath::for('two-factor.qr-code', '/user/two-factor-qr-code'), [TwoFactorQrCodeController::class, 'show'])
->middleware($twoFactorMiddleware)
->name('two-factor.qr-code');
Route::get(RoutePath::for('two-factor.secret-key', '/user/two-factor-secret-key'), [TwoFactorSecretKeyController::class, 'show'])
->middleware($twoFactorMiddleware)
->name('two-factor.secret-key');
Route::get(RoutePath::for('two-factor.recovery-codes', '/user/two-factor-recovery-codes'), [RecoveryCodeController::class, 'index'])
->middleware($twoFactorMiddleware)
->name('two-factor.recovery-codes');
Route::post(RoutePath::for('two-factor.recovery-codes', '/user/two-factor-recovery-codes'), [RecoveryCodeController::class, 'store'])
->middleware($twoFactorMiddleware);
}
});
@@ -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);
}
}

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