feature: authentication using fortify and sanctum's cookie based SPA authentication
This commit is contained in:
parent
b538bf8fee
commit
19a05a1a5b
6
.idea/neoban.iml
generated
6
.idea/neoban.iml
generated
@ -34,7 +34,6 @@
|
|||||||
<excludeFolder url="file://$MODULE_DIR$/backend/vendor/laravel/ai" />
|
<excludeFolder url="file://$MODULE_DIR$/backend/vendor/laravel/ai" />
|
||||||
<excludeFolder url="file://$MODULE_DIR$/backend/vendor/laravel/framework" />
|
<excludeFolder url="file://$MODULE_DIR$/backend/vendor/laravel/framework" />
|
||||||
<excludeFolder url="file://$MODULE_DIR$/backend/vendor/laravel/pail" />
|
<excludeFolder url="file://$MODULE_DIR$/backend/vendor/laravel/pail" />
|
||||||
<excludeFolder url="file://$MODULE_DIR$/backend/vendor/laravel/pint" />
|
|
||||||
<excludeFolder url="file://$MODULE_DIR$/backend/vendor/laravel/prompts" />
|
<excludeFolder url="file://$MODULE_DIR$/backend/vendor/laravel/prompts" />
|
||||||
<excludeFolder url="file://$MODULE_DIR$/backend/vendor/laravel/sanctum" />
|
<excludeFolder url="file://$MODULE_DIR$/backend/vendor/laravel/sanctum" />
|
||||||
<excludeFolder url="file://$MODULE_DIR$/backend/vendor/laravel/serializable-closure" />
|
<excludeFolder url="file://$MODULE_DIR$/backend/vendor/laravel/serializable-closure" />
|
||||||
@ -139,6 +138,11 @@
|
|||||||
<excludeFolder url="file://$MODULE_DIR$/backend/vendor/webmozart/assert" />
|
<excludeFolder url="file://$MODULE_DIR$/backend/vendor/webmozart/assert" />
|
||||||
<excludeFolder url="file://$MODULE_DIR$/backend/storage/app" />
|
<excludeFolder url="file://$MODULE_DIR$/backend/storage/app" />
|
||||||
<excludeFolder url="file://$MODULE_DIR$/backend/storage/framework" />
|
<excludeFolder url="file://$MODULE_DIR$/backend/storage/framework" />
|
||||||
|
<excludeFolder url="file://$MODULE_DIR$/backend/vendor/bacon/bacon-qr-code" />
|
||||||
|
<excludeFolder url="file://$MODULE_DIR$/backend/vendor/dasprid/enum" />
|
||||||
|
<excludeFolder url="file://$MODULE_DIR$/backend/vendor/laravel/fortify" />
|
||||||
|
<excludeFolder url="file://$MODULE_DIR$/backend/vendor/paragonie/constant_time_encoding" />
|
||||||
|
<excludeFolder url="file://$MODULE_DIR$/backend/vendor/pragmarx/google2fa" />
|
||||||
</content>
|
</content>
|
||||||
<orderEntry type="inheritedJdk" />
|
<orderEntry type="inheritedJdk" />
|
||||||
<orderEntry type="sourceFolder" forTests="false" />
|
<orderEntry type="sourceFolder" forTests="false" />
|
||||||
|
|||||||
14
.idea/php.xml
generated
14
.idea/php.xml
generated
@ -1,5 +1,10 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<project version="4">
|
<project version="4">
|
||||||
|
<component name="LaravelPint">
|
||||||
|
<laravel_pint_settings>
|
||||||
|
<LaravelPintConfiguration tool_path="$PROJECT_DIR$/../.config/composer/vendor/bin/pint" />
|
||||||
|
</laravel_pint_settings>
|
||||||
|
</component>
|
||||||
<component name="MessDetectorOptionsConfiguration">
|
<component name="MessDetectorOptionsConfiguration">
|
||||||
<option name="transferred" value="true" />
|
<option name="transferred" value="true" />
|
||||||
</component>
|
</component>
|
||||||
@ -10,6 +15,9 @@
|
|||||||
<option name="highlightLevel" value="WARNING" />
|
<option name="highlightLevel" value="WARNING" />
|
||||||
<option name="transferred" value="true" />
|
<option name="transferred" value="true" />
|
||||||
</component>
|
</component>
|
||||||
|
<component name="PhpExternalFormatter">
|
||||||
|
<option name="externalFormatter" value="LARAVEL_PINT" />
|
||||||
|
</component>
|
||||||
<component name="PhpIncludePathManager">
|
<component name="PhpIncludePathManager">
|
||||||
<include_path>
|
<include_path>
|
||||||
<path value="$PROJECT_DIR$/backend/vendor/nikic/php-parser" />
|
<path value="$PROJECT_DIR$/backend/vendor/nikic/php-parser" />
|
||||||
@ -50,7 +58,6 @@
|
|||||||
<path value="$PROJECT_DIR$/backend/vendor/laravel/prompts" />
|
<path value="$PROJECT_DIR$/backend/vendor/laravel/prompts" />
|
||||||
<path value="$PROJECT_DIR$/backend/vendor/laravel/framework" />
|
<path value="$PROJECT_DIR$/backend/vendor/laravel/framework" />
|
||||||
<path value="$PROJECT_DIR$/backend/vendor/graham-campbell/result-type" />
|
<path value="$PROJECT_DIR$/backend/vendor/graham-campbell/result-type" />
|
||||||
<path value="$PROJECT_DIR$/backend/vendor/laravel/pint" />
|
|
||||||
<path value="$PROJECT_DIR$/backend/vendor/ta-tikoma/phpunit-architecture-test" />
|
<path value="$PROJECT_DIR$/backend/vendor/ta-tikoma/phpunit-architecture-test" />
|
||||||
<path value="$PROJECT_DIR$/backend/vendor/doctrine/deprecations" />
|
<path value="$PROJECT_DIR$/backend/vendor/doctrine/deprecations" />
|
||||||
<path value="$PROJECT_DIR$/backend/vendor/psr/container" />
|
<path value="$PROJECT_DIR$/backend/vendor/psr/container" />
|
||||||
@ -141,6 +148,11 @@
|
|||||||
<path value="$PROJECT_DIR$/backend/vendor/laravel/ai" />
|
<path value="$PROJECT_DIR$/backend/vendor/laravel/ai" />
|
||||||
<path value="$PROJECT_DIR$/backend/vendor/aws/aws-sdk-php" />
|
<path value="$PROJECT_DIR$/backend/vendor/aws/aws-sdk-php" />
|
||||||
<path value="$PROJECT_DIR$/backend/vendor/aws/aws-crt-php" />
|
<path value="$PROJECT_DIR$/backend/vendor/aws/aws-crt-php" />
|
||||||
|
<path value="$PROJECT_DIR$/backend/vendor/laravel/fortify" />
|
||||||
|
<path value="$PROJECT_DIR$/backend/vendor/dasprid/enum" />
|
||||||
|
<path value="$PROJECT_DIR$/backend/vendor/paragonie/constant_time_encoding" />
|
||||||
|
<path value="$PROJECT_DIR$/backend/vendor/pragmarx/google2fa" />
|
||||||
|
<path value="$PROJECT_DIR$/backend/vendor/bacon/bacon-qr-code" />
|
||||||
</include_path>
|
</include_path>
|
||||||
</component>
|
</component>
|
||||||
<component name="PhpProjectSharedConfiguration" php_language_level="8.3">
|
<component name="PhpProjectSharedConfiguration" php_language_level="8.3">
|
||||||
|
|||||||
@ -3,6 +3,7 @@ APP_ENV=local
|
|||||||
APP_KEY=
|
APP_KEY=
|
||||||
APP_DEBUG=true
|
APP_DEBUG=true
|
||||||
APP_URL=http://localhost
|
APP_URL=http://localhost
|
||||||
|
FRONTEND_URL="http://localhost:4200,http://127.0.0.1:4200"
|
||||||
|
|
||||||
APP_LOCALE=en
|
APP_LOCALE=en
|
||||||
APP_FALLBACK_LOCALE=en
|
APP_FALLBACK_LOCALE=en
|
||||||
@ -31,7 +32,7 @@ SESSION_DRIVER=database
|
|||||||
SESSION_LIFETIME=120
|
SESSION_LIFETIME=120
|
||||||
SESSION_ENCRYPT=false
|
SESSION_ENCRYPT=false
|
||||||
SESSION_PATH=/
|
SESSION_PATH=/
|
||||||
SESSION_DOMAIN=null
|
SESSION_DOMAIN=localhost
|
||||||
|
|
||||||
BROADCAST_CONNECTION=log
|
BROADCAST_CONNECTION=log
|
||||||
FILESYSTEM_DISK=local
|
FILESYSTEM_DISK=local
|
||||||
|
|||||||
43
backend/app/Actions/Fortify/CreateNewUser.php
Normal file
43
backend/app/Actions/Fortify/CreateNewUser.php
Normal file
@ -0,0 +1,43 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Actions\Fortify;
|
||||||
|
|
||||||
|
use App\Models\User;
|
||||||
|
use Illuminate\Support\Facades\Hash;
|
||||||
|
use Illuminate\Support\Facades\Validator;
|
||||||
|
use Illuminate\Validation\Rule;
|
||||||
|
use Illuminate\Validation\ValidationException;
|
||||||
|
use Laravel\Fortify\Contracts\CreatesNewUsers;
|
||||||
|
|
||||||
|
class CreateNewUser implements CreatesNewUsers
|
||||||
|
{
|
||||||
|
use PasswordValidationRules;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Validate and create a newly registered user.
|
||||||
|
*
|
||||||
|
* @param array<string, string> $input
|
||||||
|
*
|
||||||
|
* @throws ValidationException
|
||||||
|
*/
|
||||||
|
public function create(array $input): User
|
||||||
|
{
|
||||||
|
Validator::make($input, [
|
||||||
|
'name' => ['required', 'string', 'max:255'],
|
||||||
|
'email' => [
|
||||||
|
'required',
|
||||||
|
'string',
|
||||||
|
'email',
|
||||||
|
'max:255',
|
||||||
|
Rule::unique(User::class),
|
||||||
|
],
|
||||||
|
'password' => $this->passwordRules(),
|
||||||
|
])->validate();
|
||||||
|
|
||||||
|
return User::create([
|
||||||
|
'name' => $input['name'],
|
||||||
|
'email' => $input['email'],
|
||||||
|
'password' => Hash::make($input['password']),
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
}
|
||||||
19
backend/app/Actions/Fortify/PasswordValidationRules.php
Normal file
19
backend/app/Actions/Fortify/PasswordValidationRules.php
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Actions\Fortify;
|
||||||
|
|
||||||
|
use Illuminate\Contracts\Validation\Rule;
|
||||||
|
use Illuminate\Validation\Rules\Password;
|
||||||
|
|
||||||
|
trait PasswordValidationRules
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Get the validation rules used to validate passwords.
|
||||||
|
*
|
||||||
|
* @return array<int, Rule|array<mixed>|string>
|
||||||
|
*/
|
||||||
|
protected function passwordRules(): array
|
||||||
|
{
|
||||||
|
return ['required', 'string', Password::default(), 'confirmed'];
|
||||||
|
}
|
||||||
|
}
|
||||||
32
backend/app/Actions/Fortify/ResetUserPassword.php
Normal file
32
backend/app/Actions/Fortify/ResetUserPassword.php
Normal file
@ -0,0 +1,32 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Actions\Fortify;
|
||||||
|
|
||||||
|
use App\Models\User;
|
||||||
|
use Illuminate\Support\Facades\Hash;
|
||||||
|
use Illuminate\Support\Facades\Validator;
|
||||||
|
use Illuminate\Validation\ValidationException;
|
||||||
|
use Laravel\Fortify\Contracts\ResetsUserPasswords;
|
||||||
|
|
||||||
|
class ResetUserPassword implements ResetsUserPasswords
|
||||||
|
{
|
||||||
|
use PasswordValidationRules;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Validate and reset the user's forgotten password.
|
||||||
|
*
|
||||||
|
* @param array<string, string> $input
|
||||||
|
*
|
||||||
|
* @throws ValidationException
|
||||||
|
*/
|
||||||
|
public function reset(User $user, array $input): void
|
||||||
|
{
|
||||||
|
Validator::make($input, [
|
||||||
|
'password' => $this->passwordRules(),
|
||||||
|
])->validate();
|
||||||
|
|
||||||
|
$user->forceFill([
|
||||||
|
'password' => Hash::make($input['password']),
|
||||||
|
])->save();
|
||||||
|
}
|
||||||
|
}
|
||||||
35
backend/app/Actions/Fortify/UpdateUserPassword.php
Normal file
35
backend/app/Actions/Fortify/UpdateUserPassword.php
Normal file
@ -0,0 +1,35 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Actions\Fortify;
|
||||||
|
|
||||||
|
use App\Models\User;
|
||||||
|
use Illuminate\Support\Facades\Hash;
|
||||||
|
use Illuminate\Support\Facades\Validator;
|
||||||
|
use Illuminate\Validation\ValidationException;
|
||||||
|
use Laravel\Fortify\Contracts\UpdatesUserPasswords;
|
||||||
|
|
||||||
|
class UpdateUserPassword implements UpdatesUserPasswords
|
||||||
|
{
|
||||||
|
use PasswordValidationRules;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Validate and update the user's password.
|
||||||
|
*
|
||||||
|
* @param array<string, string> $input
|
||||||
|
*
|
||||||
|
* @throws ValidationException
|
||||||
|
*/
|
||||||
|
public function update(User $user, array $input): void
|
||||||
|
{
|
||||||
|
Validator::make($input, [
|
||||||
|
'current_password' => ['required', 'string', 'current_password:web'],
|
||||||
|
'password' => $this->passwordRules(),
|
||||||
|
], [
|
||||||
|
'current_password.current_password' => __('The provided password does not match your current password.'),
|
||||||
|
])->validateWithBag('updatePassword');
|
||||||
|
|
||||||
|
$user->forceFill([
|
||||||
|
'password' => Hash::make($input['password']),
|
||||||
|
])->save();
|
||||||
|
}
|
||||||
|
}
|
||||||
61
backend/app/Actions/Fortify/UpdateUserProfileInformation.php
Normal file
61
backend/app/Actions/Fortify/UpdateUserProfileInformation.php
Normal file
@ -0,0 +1,61 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Actions\Fortify;
|
||||||
|
|
||||||
|
use App\Models\User;
|
||||||
|
use Illuminate\Contracts\Auth\MustVerifyEmail;
|
||||||
|
use Illuminate\Support\Facades\Validator;
|
||||||
|
use Illuminate\Validation\Rule;
|
||||||
|
use Illuminate\Validation\ValidationException;
|
||||||
|
use Laravel\Fortify\Contracts\UpdatesUserProfileInformation;
|
||||||
|
|
||||||
|
class UpdateUserProfileInformation implements UpdatesUserProfileInformation
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Validate and update the given user's profile information.
|
||||||
|
*
|
||||||
|
* @param array<string, string> $input
|
||||||
|
*
|
||||||
|
* @throws ValidationException
|
||||||
|
*/
|
||||||
|
public function update(User $user, array $input): void
|
||||||
|
{
|
||||||
|
Validator::make($input, [
|
||||||
|
'name' => ['required', 'string', 'max:255'],
|
||||||
|
|
||||||
|
'email' => [
|
||||||
|
'required',
|
||||||
|
'string',
|
||||||
|
'email',
|
||||||
|
'max:255',
|
||||||
|
Rule::unique('users')->ignore($user->id),
|
||||||
|
],
|
||||||
|
])->validateWithBag('updateProfileInformation');
|
||||||
|
|
||||||
|
if ($input['email'] !== $user->email &&
|
||||||
|
$user instanceof MustVerifyEmail) {
|
||||||
|
$this->updateVerifiedUser($user, $input);
|
||||||
|
} else {
|
||||||
|
$user->forceFill([
|
||||||
|
'name' => $input['name'],
|
||||||
|
'email' => $input['email'],
|
||||||
|
])->save();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Update the given verified user's profile information.
|
||||||
|
*
|
||||||
|
* @param array<string, string> $input
|
||||||
|
*/
|
||||||
|
protected function updateVerifiedUser(User $user, array $input): void
|
||||||
|
{
|
||||||
|
$user->forceFill([
|
||||||
|
'name' => $input['name'],
|
||||||
|
'email' => $input['email'],
|
||||||
|
'email_verified_at' => null,
|
||||||
|
])->save();
|
||||||
|
|
||||||
|
$user->sendEmailVerificationNotification();
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -5,7 +5,9 @@
|
|||||||
use App\Http\Requests\SocialMediaPostRequest;
|
use App\Http\Requests\SocialMediaPostRequest;
|
||||||
use App\Services\SocialMediaService;
|
use App\Services\SocialMediaService;
|
||||||
use Illuminate\Http\JsonResponse;
|
use Illuminate\Http\JsonResponse;
|
||||||
|
use Illuminate\Routing\Attributes\Controllers\Middleware;
|
||||||
|
|
||||||
|
#[Middleware('auth:sanctum')]
|
||||||
class SocialMediaPostController extends Controller
|
class SocialMediaPostController extends Controller
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
@ -17,6 +19,7 @@ public function generate(
|
|||||||
): JsonResponse {
|
): JsonResponse {
|
||||||
$prompt = $request->input('prompt');
|
$prompt = $request->input('prompt');
|
||||||
$response = $socialMediaService->generatePostWithImage($prompt);
|
$response = $socialMediaService->generatePostWithImage($prompt);
|
||||||
|
|
||||||
return response()->json([
|
return response()->json([
|
||||||
'post' => $response->post,
|
'post' => $response->post,
|
||||||
'image_prompt' => $response->image,
|
'image_prompt' => $response->image,
|
||||||
|
|||||||
@ -16,7 +16,7 @@
|
|||||||
class User extends Authenticatable
|
class User extends Authenticatable
|
||||||
{
|
{
|
||||||
/** @use HasFactory<UserFactory> */
|
/** @use HasFactory<UserFactory> */
|
||||||
use HasFactory, Notifiable, HasApiTokens;
|
use HasApiTokens, HasFactory, Notifiable;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the attributes that should be cast.
|
* Get the attributes that should be cast.
|
||||||
|
|||||||
@ -2,7 +2,11 @@
|
|||||||
|
|
||||||
namespace App\Providers;
|
namespace App\Providers;
|
||||||
|
|
||||||
|
use Carbon\CarbonImmutable;
|
||||||
|
use Illuminate\Support\Facades\Date;
|
||||||
|
use Illuminate\Support\Facades\DB;
|
||||||
use Illuminate\Support\ServiceProvider;
|
use Illuminate\Support\ServiceProvider;
|
||||||
|
use Illuminate\Validation\Rules\Password;
|
||||||
|
|
||||||
class AppServiceProvider extends ServiceProvider
|
class AppServiceProvider extends ServiceProvider
|
||||||
{
|
{
|
||||||
@ -19,6 +23,28 @@ public function register(): void
|
|||||||
*/
|
*/
|
||||||
public function boot(): void
|
public function boot(): void
|
||||||
{
|
{
|
||||||
//
|
$this->configureDefaults();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Configure default behaviors for production-ready applications.
|
||||||
|
*/
|
||||||
|
protected function configureDefaults(): void
|
||||||
|
{
|
||||||
|
Date::use(CarbonImmutable::class);
|
||||||
|
|
||||||
|
DB::prohibitDestructiveCommands(
|
||||||
|
app()->isProduction(),
|
||||||
|
);
|
||||||
|
|
||||||
|
Password::defaults(fn (): ?Password => app()->isProduction()
|
||||||
|
? Password::min(12)
|
||||||
|
->mixedCase()
|
||||||
|
->letters()
|
||||||
|
->numbers()
|
||||||
|
->symbols()
|
||||||
|
->uncompromised()
|
||||||
|
: null,
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
48
backend/app/Providers/FortifyServiceProvider.php
Normal file
48
backend/app/Providers/FortifyServiceProvider.php
Normal file
@ -0,0 +1,48 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Providers;
|
||||||
|
|
||||||
|
use App\Actions\Fortify\CreateNewUser;
|
||||||
|
use App\Actions\Fortify\ResetUserPassword;
|
||||||
|
use App\Actions\Fortify\UpdateUserPassword;
|
||||||
|
use App\Actions\Fortify\UpdateUserProfileInformation;
|
||||||
|
use Illuminate\Cache\RateLimiting\Limit;
|
||||||
|
use Illuminate\Http\Request;
|
||||||
|
use Illuminate\Support\Facades\RateLimiter;
|
||||||
|
use Illuminate\Support\ServiceProvider;
|
||||||
|
use Illuminate\Support\Str;
|
||||||
|
use Laravel\Fortify\Actions\RedirectIfTwoFactorAuthenticatable;
|
||||||
|
use Laravel\Fortify\Fortify;
|
||||||
|
|
||||||
|
class FortifyServiceProvider extends ServiceProvider
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Register any application services.
|
||||||
|
*/
|
||||||
|
public function register(): void
|
||||||
|
{
|
||||||
|
//
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Bootstrap any application services.
|
||||||
|
*/
|
||||||
|
public function boot(): void
|
||||||
|
{
|
||||||
|
Fortify::createUsersUsing(CreateNewUser::class);
|
||||||
|
Fortify::updateUserProfileInformationUsing(UpdateUserProfileInformation::class);
|
||||||
|
Fortify::updateUserPasswordsUsing(UpdateUserPassword::class);
|
||||||
|
Fortify::resetUserPasswordsUsing(ResetUserPassword::class);
|
||||||
|
Fortify::redirectUserForTwoFactorAuthenticationUsing(RedirectIfTwoFactorAuthenticatable::class);
|
||||||
|
|
||||||
|
RateLimiter::for('login', function (Request $request) {
|
||||||
|
$throttleKey = Str::transliterate(Str::lower($request->input(Fortify::username())).'|'.$request->ip());
|
||||||
|
|
||||||
|
return Limit::perMinute(5)->by($throttleKey);
|
||||||
|
});
|
||||||
|
|
||||||
|
RateLimiter::for('two-factor', function (Request $request) {
|
||||||
|
return Limit::perMinute(5)->by($request->session()->get('login.id'));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -12,8 +12,15 @@
|
|||||||
health: '/up',
|
health: '/up',
|
||||||
)
|
)
|
||||||
->withMiddleware(function (Middleware $middleware): void {
|
->withMiddleware(function (Middleware $middleware): void {
|
||||||
//
|
$middleware->statefulApi();
|
||||||
})
|
})
|
||||||
->withExceptions(function (Exceptions $exceptions): void {
|
->withExceptions(function (Exceptions $exceptions): void {
|
||||||
//
|
$exceptions->shouldRenderJsonWhen(function (Request $request, Throwable $e) {
|
||||||
|
// Force JSON for all API routes AND Fortify authentication routes
|
||||||
|
if ($request->is('api/*') || $request->is('register') || $request->is('login') || $request->is('logout')) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return $request->expectsJson();
|
||||||
|
});
|
||||||
})->create();
|
})->create();
|
||||||
|
|||||||
@ -1,7 +1,9 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
use App\Providers\AppServiceProvider;
|
use App\Providers\AppServiceProvider;
|
||||||
|
use App\Providers\FortifyServiceProvider;
|
||||||
|
|
||||||
return [
|
return [
|
||||||
AppServiceProvider::class,
|
AppServiceProvider::class,
|
||||||
|
FortifyServiceProvider::class,
|
||||||
];
|
];
|
||||||
|
|||||||
@ -11,6 +11,7 @@
|
|||||||
"require": {
|
"require": {
|
||||||
"php": "^8.3",
|
"php": "^8.3",
|
||||||
"laravel/ai": "^0.6.3",
|
"laravel/ai": "^0.6.3",
|
||||||
|
"laravel/fortify": "^1.36",
|
||||||
"laravel/framework": "^13.0",
|
"laravel/framework": "^13.0",
|
||||||
"laravel/sanctum": "^4.0",
|
"laravel/sanctum": "^4.0",
|
||||||
"laravel/tinker": "^3.0"
|
"laravel/tinker": "^3.0"
|
||||||
@ -18,7 +19,6 @@
|
|||||||
"require-dev": {
|
"require-dev": {
|
||||||
"fakerphp/faker": "^1.23",
|
"fakerphp/faker": "^1.23",
|
||||||
"laravel/pail": "^1.2.5",
|
"laravel/pail": "^1.2.5",
|
||||||
"laravel/pint": "^1.27",
|
|
||||||
"mockery/mockery": "^1.6",
|
"mockery/mockery": "^1.6",
|
||||||
"nunomaduro/collision": "^8.6",
|
"nunomaduro/collision": "^8.6",
|
||||||
"pestphp/pest": "^4.6",
|
"pestphp/pest": "^4.6",
|
||||||
|
|||||||
359
backend/composer.lock
generated
359
backend/composer.lock
generated
@ -4,7 +4,7 @@
|
|||||||
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
|
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
|
||||||
"This file is @generated automatically"
|
"This file is @generated automatically"
|
||||||
],
|
],
|
||||||
"content-hash": "31337405f959f523455e59893a55ca54",
|
"content-hash": "ce000f2979a5d252cefadab87899a5fc",
|
||||||
"packages": [
|
"packages": [
|
||||||
{
|
{
|
||||||
"name": "aws/aws-crt-php",
|
"name": "aws/aws-crt-php",
|
||||||
@ -157,6 +157,61 @@
|
|||||||
},
|
},
|
||||||
"time": "2026-04-23T18:11:11+00:00"
|
"time": "2026-04-23T18:11:11+00:00"
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"name": "bacon/bacon-qr-code",
|
||||||
|
"version": "v3.1.1",
|
||||||
|
"source": {
|
||||||
|
"type": "git",
|
||||||
|
"url": "https://github.com/Bacon/BaconQrCode.git",
|
||||||
|
"reference": "4da2233e72eeecd9be3b62e0dc2cc9ed8e2e31c2"
|
||||||
|
},
|
||||||
|
"dist": {
|
||||||
|
"type": "zip",
|
||||||
|
"url": "https://api.github.com/repos/Bacon/BaconQrCode/zipball/4da2233e72eeecd9be3b62e0dc2cc9ed8e2e31c2",
|
||||||
|
"reference": "4da2233e72eeecd9be3b62e0dc2cc9ed8e2e31c2",
|
||||||
|
"shasum": ""
|
||||||
|
},
|
||||||
|
"require": {
|
||||||
|
"dasprid/enum": "^1.0.3",
|
||||||
|
"ext-iconv": "*",
|
||||||
|
"php": "^8.1"
|
||||||
|
},
|
||||||
|
"require-dev": {
|
||||||
|
"phly/keep-a-changelog": "^2.12",
|
||||||
|
"phpunit/phpunit": "^10.5.11 || ^11.0.4",
|
||||||
|
"spatie/phpunit-snapshot-assertions": "^5.1.5",
|
||||||
|
"spatie/pixelmatch-php": "^1.2.0",
|
||||||
|
"squizlabs/php_codesniffer": "^3.9"
|
||||||
|
},
|
||||||
|
"suggest": {
|
||||||
|
"ext-imagick": "to generate QR code images"
|
||||||
|
},
|
||||||
|
"type": "library",
|
||||||
|
"autoload": {
|
||||||
|
"psr-4": {
|
||||||
|
"BaconQrCode\\": "src/"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"notification-url": "https://packagist.org/downloads/",
|
||||||
|
"license": [
|
||||||
|
"BSD-2-Clause"
|
||||||
|
],
|
||||||
|
"authors": [
|
||||||
|
{
|
||||||
|
"name": "Ben Scholzen 'DASPRiD'",
|
||||||
|
"email": "mail@dasprids.de",
|
||||||
|
"homepage": "https://dasprids.de/",
|
||||||
|
"role": "Developer"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"description": "BaconQrCode is a QR code generator for PHP.",
|
||||||
|
"homepage": "https://github.com/Bacon/BaconQrCode",
|
||||||
|
"support": {
|
||||||
|
"issues": "https://github.com/Bacon/BaconQrCode/issues",
|
||||||
|
"source": "https://github.com/Bacon/BaconQrCode/tree/v3.1.1"
|
||||||
|
},
|
||||||
|
"time": "2026-04-05T21:06:35+00:00"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"name": "brick/math",
|
"name": "brick/math",
|
||||||
"version": "0.14.8",
|
"version": "0.14.8",
|
||||||
@ -286,6 +341,56 @@
|
|||||||
],
|
],
|
||||||
"time": "2024-02-09T16:56:22+00:00"
|
"time": "2024-02-09T16:56:22+00:00"
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"name": "dasprid/enum",
|
||||||
|
"version": "1.0.7",
|
||||||
|
"source": {
|
||||||
|
"type": "git",
|
||||||
|
"url": "https://github.com/DASPRiD/Enum.git",
|
||||||
|
"reference": "b5874fa9ed0043116c72162ec7f4fb50e02e7cce"
|
||||||
|
},
|
||||||
|
"dist": {
|
||||||
|
"type": "zip",
|
||||||
|
"url": "https://api.github.com/repos/DASPRiD/Enum/zipball/b5874fa9ed0043116c72162ec7f4fb50e02e7cce",
|
||||||
|
"reference": "b5874fa9ed0043116c72162ec7f4fb50e02e7cce",
|
||||||
|
"shasum": ""
|
||||||
|
},
|
||||||
|
"require": {
|
||||||
|
"php": ">=7.1 <9.0"
|
||||||
|
},
|
||||||
|
"require-dev": {
|
||||||
|
"phpunit/phpunit": "^7 || ^8 || ^9 || ^10 || ^11",
|
||||||
|
"squizlabs/php_codesniffer": "*"
|
||||||
|
},
|
||||||
|
"type": "library",
|
||||||
|
"autoload": {
|
||||||
|
"psr-4": {
|
||||||
|
"DASPRiD\\Enum\\": "src/"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"notification-url": "https://packagist.org/downloads/",
|
||||||
|
"license": [
|
||||||
|
"BSD-2-Clause"
|
||||||
|
],
|
||||||
|
"authors": [
|
||||||
|
{
|
||||||
|
"name": "Ben Scholzen 'DASPRiD'",
|
||||||
|
"email": "mail@dasprids.de",
|
||||||
|
"homepage": "https://dasprids.de/",
|
||||||
|
"role": "Developer"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"description": "PHP 7.1 enum implementation",
|
||||||
|
"keywords": [
|
||||||
|
"enum",
|
||||||
|
"map"
|
||||||
|
],
|
||||||
|
"support": {
|
||||||
|
"issues": "https://github.com/DASPRiD/Enum/issues",
|
||||||
|
"source": "https://github.com/DASPRiD/Enum/tree/1.0.7"
|
||||||
|
},
|
||||||
|
"time": "2025-09-16T12:23:56+00:00"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"name": "dflydev/dot-access-data",
|
"name": "dflydev/dot-access-data",
|
||||||
"version": "v3.0.3",
|
"version": "v3.0.3",
|
||||||
@ -1272,6 +1377,69 @@
|
|||||||
},
|
},
|
||||||
"time": "2026-04-22T21:16:19+00:00"
|
"time": "2026-04-22T21:16:19+00:00"
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"name": "laravel/fortify",
|
||||||
|
"version": "v1.36.2",
|
||||||
|
"source": {
|
||||||
|
"type": "git",
|
||||||
|
"url": "https://github.com/laravel/fortify.git",
|
||||||
|
"reference": "b36e0782e6f5f6cfbab34327895a63b7c4c031f9"
|
||||||
|
},
|
||||||
|
"dist": {
|
||||||
|
"type": "zip",
|
||||||
|
"url": "https://api.github.com/repos/laravel/fortify/zipball/b36e0782e6f5f6cfbab34327895a63b7c4c031f9",
|
||||||
|
"reference": "b36e0782e6f5f6cfbab34327895a63b7c4c031f9",
|
||||||
|
"shasum": ""
|
||||||
|
},
|
||||||
|
"require": {
|
||||||
|
"bacon/bacon-qr-code": "^3.0",
|
||||||
|
"ext-json": "*",
|
||||||
|
"illuminate/console": "^10.0|^11.0|^12.0|^13.0",
|
||||||
|
"illuminate/support": "^10.0|^11.0|^12.0|^13.0",
|
||||||
|
"php": "^8.1",
|
||||||
|
"pragmarx/google2fa": "^9.0"
|
||||||
|
},
|
||||||
|
"require-dev": {
|
||||||
|
"orchestra/testbench": "^8.36|^9.15|^10.8|^11.0",
|
||||||
|
"phpstan/phpstan": "^1.10"
|
||||||
|
},
|
||||||
|
"type": "library",
|
||||||
|
"extra": {
|
||||||
|
"laravel": {
|
||||||
|
"providers": [
|
||||||
|
"Laravel\\Fortify\\FortifyServiceProvider"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"branch-alias": {
|
||||||
|
"dev-master": "1.x-dev"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"autoload": {
|
||||||
|
"psr-4": {
|
||||||
|
"Laravel\\Fortify\\": "src/"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"notification-url": "https://packagist.org/downloads/",
|
||||||
|
"license": [
|
||||||
|
"MIT"
|
||||||
|
],
|
||||||
|
"authors": [
|
||||||
|
{
|
||||||
|
"name": "Taylor Otwell",
|
||||||
|
"email": "taylor@laravel.com"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"description": "Backend controllers and scaffolding for Laravel authentication.",
|
||||||
|
"keywords": [
|
||||||
|
"auth",
|
||||||
|
"laravel"
|
||||||
|
],
|
||||||
|
"support": {
|
||||||
|
"issues": "https://github.com/laravel/fortify/issues",
|
||||||
|
"source": "https://github.com/laravel/fortify"
|
||||||
|
},
|
||||||
|
"time": "2026-03-20T20:13:51+00:00"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"name": "laravel/framework",
|
"name": "laravel/framework",
|
||||||
"version": "v13.6.0",
|
"version": "v13.6.0",
|
||||||
@ -2883,6 +3051,75 @@
|
|||||||
],
|
],
|
||||||
"time": "2026-02-16T23:10:27+00:00"
|
"time": "2026-02-16T23:10:27+00:00"
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"name": "paragonie/constant_time_encoding",
|
||||||
|
"version": "v3.1.3",
|
||||||
|
"source": {
|
||||||
|
"type": "git",
|
||||||
|
"url": "https://github.com/paragonie/constant_time_encoding.git",
|
||||||
|
"reference": "d5b01a39b3415c2cd581d3bd3a3575c1ebbd8e77"
|
||||||
|
},
|
||||||
|
"dist": {
|
||||||
|
"type": "zip",
|
||||||
|
"url": "https://api.github.com/repos/paragonie/constant_time_encoding/zipball/d5b01a39b3415c2cd581d3bd3a3575c1ebbd8e77",
|
||||||
|
"reference": "d5b01a39b3415c2cd581d3bd3a3575c1ebbd8e77",
|
||||||
|
"shasum": ""
|
||||||
|
},
|
||||||
|
"require": {
|
||||||
|
"php": "^8"
|
||||||
|
},
|
||||||
|
"require-dev": {
|
||||||
|
"infection/infection": "^0",
|
||||||
|
"nikic/php-fuzzer": "^0",
|
||||||
|
"phpunit/phpunit": "^9|^10|^11",
|
||||||
|
"vimeo/psalm": "^4|^5|^6"
|
||||||
|
},
|
||||||
|
"type": "library",
|
||||||
|
"autoload": {
|
||||||
|
"psr-4": {
|
||||||
|
"ParagonIE\\ConstantTime\\": "src/"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"notification-url": "https://packagist.org/downloads/",
|
||||||
|
"license": [
|
||||||
|
"MIT"
|
||||||
|
],
|
||||||
|
"authors": [
|
||||||
|
{
|
||||||
|
"name": "Paragon Initiative Enterprises",
|
||||||
|
"email": "security@paragonie.com",
|
||||||
|
"homepage": "https://paragonie.com",
|
||||||
|
"role": "Maintainer"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Steve 'Sc00bz' Thomas",
|
||||||
|
"email": "steve@tobtu.com",
|
||||||
|
"homepage": "https://www.tobtu.com",
|
||||||
|
"role": "Original Developer"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"description": "Constant-time Implementations of RFC 4648 Encoding (Base-64, Base-32, Base-16)",
|
||||||
|
"keywords": [
|
||||||
|
"base16",
|
||||||
|
"base32",
|
||||||
|
"base32_decode",
|
||||||
|
"base32_encode",
|
||||||
|
"base64",
|
||||||
|
"base64_decode",
|
||||||
|
"base64_encode",
|
||||||
|
"bin2hex",
|
||||||
|
"encoding",
|
||||||
|
"hex",
|
||||||
|
"hex2bin",
|
||||||
|
"rfc4648"
|
||||||
|
],
|
||||||
|
"support": {
|
||||||
|
"email": "info@paragonie.com",
|
||||||
|
"issues": "https://github.com/paragonie/constant_time_encoding/issues",
|
||||||
|
"source": "https://github.com/paragonie/constant_time_encoding"
|
||||||
|
},
|
||||||
|
"time": "2025-09-24T15:06:41+00:00"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"name": "phpoption/phpoption",
|
"name": "phpoption/phpoption",
|
||||||
"version": "1.9.5",
|
"version": "1.9.5",
|
||||||
@ -2958,6 +3195,58 @@
|
|||||||
],
|
],
|
||||||
"time": "2025-12-27T19:41:33+00:00"
|
"time": "2025-12-27T19:41:33+00:00"
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"name": "pragmarx/google2fa",
|
||||||
|
"version": "v9.0.0",
|
||||||
|
"source": {
|
||||||
|
"type": "git",
|
||||||
|
"url": "https://github.com/antonioribeiro/google2fa.git",
|
||||||
|
"reference": "e6bc62dd6ae83acc475f57912e27466019a1f2cf"
|
||||||
|
},
|
||||||
|
"dist": {
|
||||||
|
"type": "zip",
|
||||||
|
"url": "https://api.github.com/repos/antonioribeiro/google2fa/zipball/e6bc62dd6ae83acc475f57912e27466019a1f2cf",
|
||||||
|
"reference": "e6bc62dd6ae83acc475f57912e27466019a1f2cf",
|
||||||
|
"shasum": ""
|
||||||
|
},
|
||||||
|
"require": {
|
||||||
|
"paragonie/constant_time_encoding": "^1.0|^2.0|^3.0",
|
||||||
|
"php": "^7.1|^8.0"
|
||||||
|
},
|
||||||
|
"require-dev": {
|
||||||
|
"phpstan/phpstan": "^1.9",
|
||||||
|
"phpunit/phpunit": "^7.5.15|^8.5|^9.0"
|
||||||
|
},
|
||||||
|
"type": "library",
|
||||||
|
"autoload": {
|
||||||
|
"psr-4": {
|
||||||
|
"PragmaRX\\Google2FA\\": "src/"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"notification-url": "https://packagist.org/downloads/",
|
||||||
|
"license": [
|
||||||
|
"MIT"
|
||||||
|
],
|
||||||
|
"authors": [
|
||||||
|
{
|
||||||
|
"name": "Antonio Carlos Ribeiro",
|
||||||
|
"email": "acr@antoniocarlosribeiro.com",
|
||||||
|
"role": "Creator & Designer"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"description": "A One Time Password Authentication package, compatible with Google Authenticator.",
|
||||||
|
"keywords": [
|
||||||
|
"2fa",
|
||||||
|
"Authentication",
|
||||||
|
"Two Factor Authentication",
|
||||||
|
"google2fa"
|
||||||
|
],
|
||||||
|
"support": {
|
||||||
|
"issues": "https://github.com/antonioribeiro/google2fa/issues",
|
||||||
|
"source": "https://github.com/antonioribeiro/google2fa/tree/v9.0.0"
|
||||||
|
},
|
||||||
|
"time": "2025-09-19T22:51:08+00:00"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"name": "psr/clock",
|
"name": "psr/clock",
|
||||||
"version": "1.0.0",
|
"version": "1.0.0",
|
||||||
@ -6833,74 +7122,6 @@
|
|||||||
},
|
},
|
||||||
"time": "2026-02-09T13:44:54+00:00"
|
"time": "2026-02-09T13:44:54+00:00"
|
||||||
},
|
},
|
||||||
{
|
|
||||||
"name": "laravel/pint",
|
|
||||||
"version": "v1.29.1",
|
|
||||||
"source": {
|
|
||||||
"type": "git",
|
|
||||||
"url": "https://github.com/laravel/pint.git",
|
|
||||||
"reference": "0770e9b7fafd50d4586881d456d6eb41c9247a80"
|
|
||||||
},
|
|
||||||
"dist": {
|
|
||||||
"type": "zip",
|
|
||||||
"url": "https://api.github.com/repos/laravel/pint/zipball/0770e9b7fafd50d4586881d456d6eb41c9247a80",
|
|
||||||
"reference": "0770e9b7fafd50d4586881d456d6eb41c9247a80",
|
|
||||||
"shasum": ""
|
|
||||||
},
|
|
||||||
"require": {
|
|
||||||
"ext-json": "*",
|
|
||||||
"ext-mbstring": "*",
|
|
||||||
"ext-tokenizer": "*",
|
|
||||||
"ext-xml": "*",
|
|
||||||
"php": "^8.2.0"
|
|
||||||
},
|
|
||||||
"require-dev": {
|
|
||||||
"friendsofphp/php-cs-fixer": "^3.95.1",
|
|
||||||
"illuminate/view": "^12.56.0",
|
|
||||||
"larastan/larastan": "^3.9.6",
|
|
||||||
"laravel-zero/framework": "^12.1.0",
|
|
||||||
"mockery/mockery": "^1.6.12",
|
|
||||||
"nunomaduro/termwind": "^2.4.0",
|
|
||||||
"pestphp/pest": "^3.8.6",
|
|
||||||
"shipfastlabs/agent-detector": "^1.1.3"
|
|
||||||
},
|
|
||||||
"bin": [
|
|
||||||
"builds/pint"
|
|
||||||
],
|
|
||||||
"type": "project",
|
|
||||||
"autoload": {
|
|
||||||
"psr-4": {
|
|
||||||
"App\\": "app/",
|
|
||||||
"Database\\Seeders\\": "database/seeders/",
|
|
||||||
"Database\\Factories\\": "database/factories/"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"notification-url": "https://packagist.org/downloads/",
|
|
||||||
"license": [
|
|
||||||
"MIT"
|
|
||||||
],
|
|
||||||
"authors": [
|
|
||||||
{
|
|
||||||
"name": "Nuno Maduro",
|
|
||||||
"email": "enunomaduro@gmail.com"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"description": "An opinionated code formatter for PHP.",
|
|
||||||
"homepage": "https://laravel.com",
|
|
||||||
"keywords": [
|
|
||||||
"dev",
|
|
||||||
"format",
|
|
||||||
"formatter",
|
|
||||||
"lint",
|
|
||||||
"linter",
|
|
||||||
"php"
|
|
||||||
],
|
|
||||||
"support": {
|
|
||||||
"issues": "https://github.com/laravel/pint/issues",
|
|
||||||
"source": "https://github.com/laravel/pint"
|
|
||||||
},
|
|
||||||
"time": "2026-04-20T15:26:14+00:00"
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"name": "mockery/mockery",
|
"name": "mockery/mockery",
|
||||||
"version": "1.6.12",
|
"version": "1.6.12",
|
||||||
|
|||||||
34
backend/config/cors.php
Normal file
34
backend/config/cors.php
Normal file
@ -0,0 +1,34 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
return [
|
||||||
|
|
||||||
|
/*
|
||||||
|
|--------------------------------------------------------------------------
|
||||||
|
| Cross-Origin Resource Sharing (CORS) Configuration
|
||||||
|
|--------------------------------------------------------------------------
|
||||||
|
|
|
||||||
|
| Here you may configure your settings for cross-origin resource sharing
|
||||||
|
| or "CORS". This determines what cross-origin operations may execute
|
||||||
|
| in web browsers. You are free to adjust these settings as needed.
|
||||||
|
|
|
||||||
|
| To learn more: https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS
|
||||||
|
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
'paths' => ['api/*', 'sanctum/csrf-cookie', 'login', 'logout', 'register'],
|
||||||
|
|
||||||
|
'allowed_methods' => ['*'],
|
||||||
|
|
||||||
|
'allowed_origins' => explode(',', env('FRONTEND_URL', 'http://localhost:4200')),
|
||||||
|
|
||||||
|
'allowed_origins_patterns' => [],
|
||||||
|
|
||||||
|
'allowed_headers' => ['*'],
|
||||||
|
|
||||||
|
'exposed_headers' => [],
|
||||||
|
|
||||||
|
'max_age' => 0,
|
||||||
|
|
||||||
|
'supports_credentials' => true,
|
||||||
|
|
||||||
|
];
|
||||||
159
backend/config/fortify.php
Normal file
159
backend/config/fortify.php
Normal file
@ -0,0 +1,159 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
use Laravel\Fortify\Features;
|
||||||
|
|
||||||
|
return [
|
||||||
|
|
||||||
|
/*
|
||||||
|
|--------------------------------------------------------------------------
|
||||||
|
| Fortify Guard
|
||||||
|
|--------------------------------------------------------------------------
|
||||||
|
|
|
||||||
|
| Here you may specify which authentication guard Fortify will use while
|
||||||
|
| authenticating users. This value should correspond with one of your
|
||||||
|
| guards that is already present in your "auth" configuration file.
|
||||||
|
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
'guard' => 'web',
|
||||||
|
|
||||||
|
/*
|
||||||
|
|--------------------------------------------------------------------------
|
||||||
|
| Fortify Password Broker
|
||||||
|
|--------------------------------------------------------------------------
|
||||||
|
|
|
||||||
|
| Here you may specify which password broker Fortify can use when a user
|
||||||
|
| is resetting their password. This configured value should match one
|
||||||
|
| of your password brokers setup in your "auth" configuration file.
|
||||||
|
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
'passwords' => 'users',
|
||||||
|
|
||||||
|
/*
|
||||||
|
|--------------------------------------------------------------------------
|
||||||
|
| Username / Email
|
||||||
|
|--------------------------------------------------------------------------
|
||||||
|
|
|
||||||
|
| This value defines which model attribute should be considered as your
|
||||||
|
| application's "username" field. Typically, this might be the email
|
||||||
|
| address of the users but you are free to change this value here.
|
||||||
|
|
|
||||||
|
| Out of the box, Fortify expects forgot password and reset password
|
||||||
|
| requests to have a field named 'email'. If the application uses
|
||||||
|
| another name for the field you may define it below as needed.
|
||||||
|
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
'username' => 'email',
|
||||||
|
|
||||||
|
'email' => 'email',
|
||||||
|
|
||||||
|
/*
|
||||||
|
|--------------------------------------------------------------------------
|
||||||
|
| Lowercase Usernames
|
||||||
|
|--------------------------------------------------------------------------
|
||||||
|
|
|
||||||
|
| This value defines whether usernames should be lowercased before saving
|
||||||
|
| them in the database, as some database system string fields are case
|
||||||
|
| sensitive. You may disable this for your application if necessary.
|
||||||
|
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
'lowercase_usernames' => true,
|
||||||
|
|
||||||
|
/*
|
||||||
|
|--------------------------------------------------------------------------
|
||||||
|
| Home Path
|
||||||
|
|--------------------------------------------------------------------------
|
||||||
|
|
|
||||||
|
| Here you may configure the path where users will get redirected during
|
||||||
|
| authentication or password reset when the operations are successful
|
||||||
|
| and the user is authenticated. You are free to change this value.
|
||||||
|
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
'home' => '/home',
|
||||||
|
|
||||||
|
/*
|
||||||
|
|--------------------------------------------------------------------------
|
||||||
|
| Fortify Routes Prefix / Subdomain
|
||||||
|
|--------------------------------------------------------------------------
|
||||||
|
|
|
||||||
|
| Here you may specify which prefix Fortify will assign to all the routes
|
||||||
|
| that it registers with the application. If necessary, you may change
|
||||||
|
| subdomain under which all of the Fortify routes will be available.
|
||||||
|
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
'prefix' => '',
|
||||||
|
|
||||||
|
'domain' => null,
|
||||||
|
|
||||||
|
/*
|
||||||
|
|--------------------------------------------------------------------------
|
||||||
|
| Fortify Routes Middleware
|
||||||
|
|--------------------------------------------------------------------------
|
||||||
|
|
|
||||||
|
| Here you may specify which middleware Fortify will assign to the routes
|
||||||
|
| that it registers with the application. If necessary, you may change
|
||||||
|
| these middleware but typically this provided default is preferred.
|
||||||
|
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
'middleware' => ['web'],
|
||||||
|
|
||||||
|
/*
|
||||||
|
|--------------------------------------------------------------------------
|
||||||
|
| Rate Limiting
|
||||||
|
|--------------------------------------------------------------------------
|
||||||
|
|
|
||||||
|
| By default, Fortify will throttle logins to five requests per minute for
|
||||||
|
| every email and IP address combination. However, if you would like to
|
||||||
|
| specify a custom rate limiter to call then you may specify it here.
|
||||||
|
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
'limiters' => [
|
||||||
|
'login' => 'login',
|
||||||
|
'two-factor' => 'two-factor',
|
||||||
|
],
|
||||||
|
|
||||||
|
/*
|
||||||
|
|--------------------------------------------------------------------------
|
||||||
|
| Register View Routes
|
||||||
|
|--------------------------------------------------------------------------
|
||||||
|
|
|
||||||
|
| Here you may specify if the routes returning views should be disabled as
|
||||||
|
| you may not need them when building your own application. This may be
|
||||||
|
| especially true if you're writing a custom single-page application.
|
||||||
|
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
'views' => false,
|
||||||
|
|
||||||
|
/*
|
||||||
|
|--------------------------------------------------------------------------
|
||||||
|
| Features
|
||||||
|
|--------------------------------------------------------------------------
|
||||||
|
|
|
||||||
|
| Some of the Fortify features are optional. You may disable the features
|
||||||
|
| by removing them from this array. You're free to only remove some of
|
||||||
|
| these features or you can even remove all of these if you need to.
|
||||||
|
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
'features' => [
|
||||||
|
Features::registration(),
|
||||||
|
Features::resetPasswords(),
|
||||||
|
// Features::emailVerification(),
|
||||||
|
Features::updateProfileInformation(),
|
||||||
|
Features::updatePasswords(),
|
||||||
|
Features::twoFactorAuthentication([
|
||||||
|
'confirm' => true,
|
||||||
|
'confirmPassword' => true,
|
||||||
|
// 'window' => 0,
|
||||||
|
]),
|
||||||
|
],
|
||||||
|
|
||||||
|
];
|
||||||
@ -1,5 +1,8 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
|
use Illuminate\Cookie\Middleware\EncryptCookies;
|
||||||
|
use Illuminate\Foundation\Http\Middleware\ValidateCsrfToken;
|
||||||
|
use Laravel\Sanctum\Http\Middleware\AuthenticateSession;
|
||||||
use Laravel\Sanctum\Sanctum;
|
use Laravel\Sanctum\Sanctum;
|
||||||
|
|
||||||
return [
|
return [
|
||||||
@ -76,9 +79,9 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
'middleware' => [
|
'middleware' => [
|
||||||
'authenticate_session' => Laravel\Sanctum\Http\Middleware\AuthenticateSession::class,
|
'authenticate_session' => AuthenticateSession::class,
|
||||||
'encrypt_cookies' => Illuminate\Cookie\Middleware\EncryptCookies::class,
|
'encrypt_cookies' => EncryptCookies::class,
|
||||||
'validate_csrf_token' => Illuminate\Foundation\Http\Middleware\ValidateCsrfToken::class,
|
'validate_csrf_token' => ValidateCsrfToken::class,
|
||||||
],
|
],
|
||||||
|
|
||||||
];
|
];
|
||||||
|
|||||||
@ -0,0 +1,42 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
use Illuminate\Database\Migrations\Migration;
|
||||||
|
use Illuminate\Database\Schema\Blueprint;
|
||||||
|
use Illuminate\Support\Facades\Schema;
|
||||||
|
|
||||||
|
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();
|
||||||
|
|
||||||
|
$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([
|
||||||
|
'two_factor_secret',
|
||||||
|
'two_factor_recovery_codes',
|
||||||
|
'two_factor_confirmed_at',
|
||||||
|
]);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
};
|
||||||
@ -4,7 +4,7 @@
|
|||||||
use Illuminate\Http\Request;
|
use Illuminate\Http\Request;
|
||||||
use Illuminate\Support\Facades\Route;
|
use Illuminate\Support\Facades\Route;
|
||||||
|
|
||||||
Route::get('/user', function (Request $request) {
|
Route::get('/me', function (Request $request) {
|
||||||
return $request->user();
|
return $request->user();
|
||||||
})->middleware('auth:sanctum');
|
})->middleware('auth:sanctum');
|
||||||
|
|
||||||
|
|||||||
@ -4,5 +4,9 @@ export const routes: Routes = [
|
|||||||
{
|
{
|
||||||
path: '',
|
path: '',
|
||||||
loadComponent: () => import('./chat/chat').then(m => m.Chat)
|
loadComponent: () => import('./chat/chat').then(m => m.Chat)
|
||||||
|
},
|
||||||
|
{
|
||||||
|
path: 'user',
|
||||||
|
loadChildren: () => import('./auth/auth.routes').then(m => m.authRoutes)
|
||||||
}
|
}
|
||||||
];
|
];
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user